With -b, this produces garbage. Code to call __bound_local_new is put at wrong place, overwriting the regparam setup code. Fix copied from x86_64-gen.c. void __attribute__((regparm(3))) fun(int unused) { char local[1]; }
Unified · Split
| @@ -107,6 +107,7 @@ static unsigned long func_sub_sp_offset; · 106 unmodified lines | ||
| 107 | 107 | static int func_ret_sub; |
| 108 | 108 | #ifdef CONFIG_TCC_BCHECK |
| 109 | 109 | static addr_t func_bound_offset; |
| 110 | +static unsigned long func_bound_ind; | |
| 110 | 111 | #endif |
| 111 | 112 | |
| 112 | 113 | /* XXX: make it faster ? */ |
| @@ -611,9 +612,10 @@ ST_FUNC void gfunc_prolog(CType *func_type) · 498 unmodified lines | ||
| 611 | 612 | #ifdef CONFIG_TCC_BCHECK |
| 612 | 613 | /* leave some room for bound checking code */ |
| 613 | 614 | if (tcc_state->do_bounds_check) { |
| 615 | + func_bound_offset = lbounds_section->data_offset; | |
| 616 | + func_bound_ind = ind; | |
| 614 | 617 | oad(0xb8, 0); /* lbound section pointer */ |
| 615 | 618 | oad(0xb8, 0); /* call to function */ |
| 616 | − func_bound_offset = lbounds_section->data_offset; | |
| 617 | 619 | } |
| 618 | 620 | #endif |
| 619 | 621 | } |
| @@ -629,27 +631,27 @@ ST_FUNC void gfunc_epilog(void) · 9 unmodified lines | ||
| 629 | 631 | addr_t saved_ind; |
| 630 | 632 | addr_t *bounds_ptr; |
| 631 | 633 | Sym *sym_data; |
| 634 | + | |
| 632 | 635 | /* add end of table info */ |
| 633 | 636 | bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t)); |
| 634 | 637 | *bounds_ptr = 0; |
| 638 | + | |
| 635 | 639 | /* generate bound local allocation */ |
| 636 | 640 | saved_ind = ind; |
| 637 | − ind = func_sub_sp_offset; | |
| 641 | + ind = func_bound_ind; | |
| 638 | 642 | sym_data = get_sym_ref(&char_pointer_type, lbounds_section, |
| 639 | 643 | func_bound_offset, lbounds_section->data_offset); |
| 640 | 644 | greloc(cur_text_section, sym_data, |
| 641 | 645 | ind + 1, R_386_32); |
| 642 | 646 | oad(0xb8, 0); /* mov %eax, xxx */ |
| 643 | 647 | gen_static_call(TOK___bound_local_new); |
| 644 | − | |
| 645 | 648 | ind = saved_ind; |
| 649 | + | |
| 646 | 650 | /* generate bound check local freeing */ |
| 647 | 651 | o(0x5250); /* save returned value, if any */ |
| 648 | − greloc(cur_text_section, sym_data, | |
| 649 | − ind + 1, R_386_32); | |
| 652 | + greloc(cur_text_section, sym_data, ind + 1, R_386_32); | |
| 650 | 653 | oad(0xb8, 0); /* mov %eax, xxx */ |
| 651 | 654 | gen_static_call(TOK___bound_local_delete); |
| 652 | − | |
| 653 | 655 | o(0x585a); /* restore returned value, if any */ |
| 654 | 656 | } |
| 655 | 657 | #endif |
| @@ -1658,7 +1658,7 @@ void gfunc_epilog(void) · 1657 unmodified lines | ||
| 1658 | 1658 | o(0x5250); /* save returned value, if any */ |
| 1659 | 1659 | greloc(cur_text_section, sym_data, ind + 1, R_386_32); |
| 1660 | 1660 | oad(0xb8, 0); /* mov xxx, %rax */ |
| 1661 | − o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */ | |
| 1661 | + o(0xc78948); /* mov %rax,%rdi # first arg in %rdi, this must be ptr */ | |
| 1662 | 1662 | gen_static_call(TOK___bound_local_delete); |
| 1663 | 1663 | o(0x585a); /* restore returned value, if any */ |
| 1664 | 1664 | } |