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 | static int func_ret_sub; | 107 | static int func_ret_sub; |
| 108 | #ifdef CONFIG_TCC_BCHECK | 108 | #ifdef CONFIG_TCC_BCHECK |
| 109 | static addr_t func_bound_offset; | 109 | static addr_t func_bound_offset; |
| 110 | static unsigned long func_bound_ind; | ||
| 110 | #endif | 111 | #endif |
| 111 | 112 | ||
| 112 | /* XXX: make it faster ? */ | 113 | /* XXX: make it faster ? */ |
| @@ -611,9 +612,10 @@ ST_FUNC void gfunc_prolog(CType *func_type) · 498 unmodified lines | |||
| 611 | #ifdef CONFIG_TCC_BCHECK | 612 | #ifdef CONFIG_TCC_BCHECK |
| 612 | /* leave some room for bound checking code */ | 613 | /* leave some room for bound checking code */ |
| 613 | if (tcc_state->do_bounds_check) { | 614 | if (tcc_state->do_bounds_check) { |
| 615 | func_bound_offset = lbounds_section->data_offset; | ||
| 616 | func_bound_ind = ind; | ||
| 614 | oad(0xb8, 0); /* lbound section pointer */ | 617 | oad(0xb8, 0); /* lbound section pointer */ |
| 615 | oad(0xb8, 0); /* call to function */ | 618 | oad(0xb8, 0); /* call to function */ |
| 616 | func_bound_offset = lbounds_section->data_offset; | ||
| 617 | } | 619 | } |
| 618 | #endif | 620 | #endif |
| 619 | } | 621 | } |
| @@ -629,27 +631,27 @@ ST_FUNC void gfunc_epilog(void) · 9 unmodified lines | |||
| 629 | addr_t saved_ind; | 631 | addr_t saved_ind; |
| 630 | addr_t *bounds_ptr; | 632 | addr_t *bounds_ptr; |
| 631 | Sym *sym_data; | 633 | Sym *sym_data; |
| 634 | |||
| 632 | /* add end of table info */ | 635 | /* add end of table info */ |
| 633 | bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t)); | 636 | bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t)); |
| 634 | *bounds_ptr = 0; | 637 | *bounds_ptr = 0; |
| 638 | |||
| 635 | /* generate bound local allocation */ | 639 | /* generate bound local allocation */ |
| 636 | saved_ind = ind; | 640 | saved_ind = ind; |
| 637 | ind = func_sub_sp_offset; | 641 | ind = func_bound_ind; |
| 638 | sym_data = get_sym_ref(&char_pointer_type, lbounds_section, | 642 | sym_data = get_sym_ref(&char_pointer_type, lbounds_section, |
| 639 | func_bound_offset, lbounds_section->data_offset); | 643 | func_bound_offset, lbounds_section->data_offset); |
| 640 | greloc(cur_text_section, sym_data, | 644 | greloc(cur_text_section, sym_data, |
| 641 | ind + 1, R_386_32); | 645 | ind + 1, R_386_32); |
| 642 | oad(0xb8, 0); /* mov %eax, xxx */ | 646 | oad(0xb8, 0); /* mov %eax, xxx */ |
| 643 | gen_static_call(TOK___bound_local_new); | 647 | gen_static_call(TOK___bound_local_new); |
| 644 | |||
| 645 | ind = saved_ind; | 648 | ind = saved_ind; |
| 649 | |||
| 646 | /* generate bound check local freeing */ | 650 | /* generate bound check local freeing */ |
| 647 | o(0x5250); /* save returned value, if any */ | 651 | o(0x5250); /* save returned value, if any */ |
| 648 | greloc(cur_text_section, sym_data, | 652 | greloc(cur_text_section, sym_data, ind + 1, R_386_32); |
| 649 | ind + 1, R_386_32); | ||
| 650 | oad(0xb8, 0); /* mov %eax, xxx */ | 653 | oad(0xb8, 0); /* mov %eax, xxx */ |
| 651 | gen_static_call(TOK___bound_local_delete); | 654 | gen_static_call(TOK___bound_local_delete); |
| 652 | |||
| 653 | o(0x585a); /* restore returned value, if any */ | 655 | o(0x585a); /* restore returned value, if any */ |
| 654 | } | 656 | } |
| 655 | #endif | 657 | #endif |
| @@ -1658,7 +1658,7 @@ void gfunc_epilog(void) · 1657 unmodified lines | |||
| 1658 | o(0x5250); /* save returned value, if any */ | 1658 | o(0x5250); /* save returned value, if any */ |
| 1659 | greloc(cur_text_section, sym_data, ind + 1, R_386_32); | 1659 | greloc(cur_text_section, sym_data, ind + 1, R_386_32); |
| 1660 | oad(0xb8, 0); /* mov xxx, %rax */ | 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 | gen_static_call(TOK___bound_local_delete); | 1662 | gen_static_call(TOK___bound_local_delete); |
| 1663 | o(0x585a); /* restore returned value, if any */ | 1663 | o(0x585a); /* restore returned value, if any */ |
| 1664 | } | 1664 | } |