Still some more tabs to be taken care of. arm-gen.c and tcccoff.c have so many style issues that I'm just going to throw clang-format at them.
Unified · Split
| @@ -30,13 +30,13 @@ typedef int RegArgs; · 29 unmodified lines | |||
| 30 | /* a register can belong to several classes. The classes must be | 30 | /* a register can belong to several classes. The classes must be |
| 31 | sorted from more general to more precise (see gv2() code which does | 31 | sorted from more general to more precise (see gv2() code which does |
| 32 | assumptions on it). */ | 32 | assumptions on it). */ |
| 33 | #define RC_INT 0x0001 /* generic integer register */ | 33 | #define RC_INT 0x0001 /* generic integer register */ |
| 34 | #define RC_FLOAT 0x0002 /* generic float register */ | 34 | #define RC_FLOAT 0x0002 /* generic float register */ |
| 35 | #define RC_EAX 0x0004 | 35 | #define RC_EAX 0x0004 |
| 36 | #define RC_ST0 0x0008 | 36 | #define RC_ST0 0x0008 |
| 37 | #define RC_ECX 0x0010 | 37 | #define RC_ECX 0x0010 |
| 38 | #define RC_EDX 0x0020 | 38 | #define RC_EDX 0x0020 |
| 39 | #define RC_INT_BSIDE 0x00000040 /* generic integer register on b side */ | 39 | #define RC_INT_BSIDE 0x00000040 /* generic integer register on b side */ |
| 40 | #define RC_C67_A4 0x00000100 | 40 | #define RC_C67_A4 0x00000100 |
| 41 | #define RC_C67_A5 0x00000200 | 41 | #define RC_C67_A5 0x00000200 |
| 42 | #define RC_C67_B4 0x00000400 | 42 | #define RC_C67_B4 0x00000400 |
| @@ -204,7 +204,7 @@ void C67_g(int c) · 161 unmodified lines | |||
| 204 | #endif | 204 | #endif |
| 205 | ind1 = ind + 4; | 205 | ind1 = ind + 4; |
| 206 | if (ind1 > (int) cur_text_section->data_allocated) | 206 | if (ind1 > (int) cur_text_section->data_allocated) |
| 207 | section_realloc(cur_text_section, ind1); | 207 | section_realloc(cur_text_section, ind1); |
| 208 | cur_text_section->data[ind] = c & 0xff; | 208 | cur_text_section->data[ind] = c & 0xff; |
| 209 | cur_text_section->data[ind + 1] = (c >> 8) & 0xff; | 209 | cur_text_section->data[ind + 1] = (c >> 8) & 0xff; |
| 210 | cur_text_section->data[ind + 2] = (c >> 16) & 0xff; | 210 | cur_text_section->data[ind + 2] = (c >> 16) & 0xff; |
| @@ -218,26 +218,26 @@ void gsym_addr(int t, int a) · 7 unmodified lines | |||
| 218 | { | 218 | { |
| 219 | int n, *ptr; | 219 | int n, *ptr; |
| 220 | while (t) { | 220 | while (t) { |
| 221 | ptr = (int *) (cur_text_section->data + t); | 221 | ptr = (int *) (cur_text_section->data + t); |
| 222 | { | 222 | { |
| 223 | Sym *sym; | 223 | Sym *sym; |
| 224 | 224 | ||
| 225 | // extract 32 bit address from MVKH/MVKL | 225 | // extract 32 bit address from MVKH/MVKL |
| 226 | n = ((*ptr >> 7) & 0xffff); | 226 | n = ((*ptr >> 7) & 0xffff); |
| 227 | n |= ((*(ptr + 1) >> 7) & 0xffff) << 16; | 227 | n |= ((*(ptr + 1) >> 7) & 0xffff) << 16; |
| 228 | 228 | ||
| 229 | // define a label that will be relocated | 229 | // define a label that will be relocated |
| 230 | 230 | ||
| 231 | sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0); | 231 | sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0); |
| 232 | greloc(cur_text_section, sym, t, R_C60LO16); | 232 | greloc(cur_text_section, sym, t, R_C60LO16); |
| 233 | greloc(cur_text_section, sym, t + 4, R_C60HI16); | 233 | greloc(cur_text_section, sym, t + 4, R_C60HI16); |
| 234 | 234 | ||
| 235 | // clear out where the pointer was | 235 | // clear out where the pointer was |
| 236 | 236 | ||
| 237 | *ptr &= ~(0xffff << 7); | 237 | *ptr &= ~(0xffff << 7); |
| 238 | *(ptr + 1) &= ~(0xffff << 7); | 238 | *(ptr + 1) &= ~(0xffff << 7); |
| 239 | } | 239 | } |
| 240 | t = n; | 240 | t = n; |
| 241 | } | 241 | } |
| 242 | } | 242 | } |
| 243 | 243 | ||
| @@ -370,7 +370,7 @@ struct syment · 369 unmodified lines | |||
| 370 | #define INCREF_COFF(x) ((((x)&~N_BTMASK_COFF)<<N_TSHIFT_COFF)|(DT_PTR<<N_BTSHFT_COFF)|(x&N_BTMASK_COFF)) | 370 | #define INCREF_COFF(x) ((((x)&~N_BTMASK_COFF)<<N_TSHIFT_COFF)|(DT_PTR<<N_BTSHFT_COFF)|(x&N_BTMASK_COFF)) |
| 371 | #define DECREF_COFF(x) ((((x)>>N_TSHIFT_COFF)&~N_BTMASK_COFF)|((x)&N_BTMASK_COFF)) | 371 | #define DECREF_COFF(x) ((((x)>>N_TSHIFT_COFF)&~N_BTMASK_COFF)|((x)&N_BTMASK_COFF)) |
| 372 | 372 | ||
| 373 | 373 | ||
| 374 | /*------------------------------------------------------------------------*/ | 374 | /*------------------------------------------------------------------------*/ |
| 375 | /* AUXILIARY SYMBOL ENTRY */ | 375 | /* AUXILIARY SYMBOL ENTRY */ |
| 376 | /*------------------------------------------------------------------------*/ | 376 | /*------------------------------------------------------------------------*/ |
| @@ -672,7 +672,7 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, · 671 unmodified lines | |||
| 672 | } | 672 | } |
| 673 | #else | 673 | #else |
| 674 | if (! (sym->type.t & VT_STATIC)) | 674 | if (! (sym->type.t & VT_STATIC)) |
| 675 | other = (sym->type.t & VT_VIS_MASK) >> VT_VIS_SHIFT; | 675 | other = (sym->type.t & VT_VIS_MASK) >> VT_VIS_SHIFT; |
| 676 | #endif | 676 | #endif |
| 677 | if (tcc_state->leading_underscore && can_add_underscore) { | 677 | if (tcc_state->leading_underscore && can_add_underscore) { |
| 678 | buf1[0] = '_'; | 678 | buf1[0] = '_'; |
| @@ -2101,11 +2101,11 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 1422 unmodified lines | |||
| 2101 | s->static_link = 1; | 2101 | s->static_link = 1; |
| 2102 | break; | 2102 | break; |
| 2103 | case TCC_OPTION_std: | 2103 | case TCC_OPTION_std: |
| 2104 | /* silently ignore, a current purpose: | 2104 | /* silently ignore, a current purpose: |
| 2105 | allow to use a tcc as a reference compiler for "make test" */ | 2105 | allow to use a tcc as a reference compiler for "make test" */ |
| 2106 | break; | 2106 | break; |
| 2107 | case TCC_OPTION_shared: | 2107 | case TCC_OPTION_shared: |
| 2108 | if (s->output_type) | 2108 | if (s->output_type) |
| 2109 | tcc_warning("-shared: some compiler action already specified (%d)", s->output_type); | 2109 | tcc_warning("-shared: some compiler action already specified (%d)", s->output_type); |
| 2110 | s->output_type = TCC_OUTPUT_DLL; | 2110 | s->output_type = TCC_OUTPUT_DLL; |
| 2111 | break; | 2111 | break; |
| @@ -2124,7 +2124,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 12 unmodified lines | |||
| 2124 | break; | 2124 | break; |
| 2125 | case TCC_OPTION_r: | 2125 | case TCC_OPTION_r: |
| 2126 | /* generate a .o merging several output files */ | 2126 | /* generate a .o merging several output files */ |
| 2127 | if (s->output_type) | 2127 | if (s->output_type) |
| 2128 | tcc_warning("-r: some compiler action already specified (%d)", s->output_type); | 2128 | tcc_warning("-r: some compiler action already specified (%d)", s->output_type); |
| 2129 | s->option_r = 1; | 2129 | s->option_r = 1; |
| 2130 | s->output_type = TCC_OUTPUT_OBJ; | 2130 | s->output_type = TCC_OUTPUT_OBJ; |
| @@ -2163,7 +2163,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 32 unmodified lines | |||
| 2163 | s->print_search_dirs = 1; | 2163 | s->print_search_dirs = 1; |
| 2164 | break; | 2164 | break; |
| 2165 | case TCC_OPTION_run: | 2165 | case TCC_OPTION_run: |
| 2166 | if (s->output_type) | 2166 | if (s->output_type) |
| 2167 | tcc_warning("-run: some compiler action already specified (%d)", s->output_type); | 2167 | tcc_warning("-run: some compiler action already specified (%d)", s->output_type); |
| 2168 | s->output_type = TCC_OUTPUT_MEMORY; | 2168 | s->output_type = TCC_OUTPUT_MEMORY; |
| 2169 | tcc_set_options(s, optarg); | 2169 | tcc_set_options(s, optarg); |
| @@ -2194,7 +2194,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 24 unmodified lines | |||
| 2194 | cstr_ccat(&linker_arg, '\0'); | 2194 | cstr_ccat(&linker_arg, '\0'); |
| 2195 | break; | 2195 | break; |
| 2196 | case TCC_OPTION_E: | 2196 | case TCC_OPTION_E: |
| 2197 | if (s->output_type) | 2197 | if (s->output_type) |
| 2198 | tcc_warning("-E: some compiler action already specified (%d)", s->output_type); | 2198 | tcc_warning("-E: some compiler action already specified (%d)", s->output_type); |
| 2199 | s->output_type = TCC_OUTPUT_PREPROCESS; | 2199 | s->output_type = TCC_OUTPUT_PREPROCESS; |
| 2200 | break; | 2200 | break; |
| @@ -2251,13 +2251,13 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv) · 50 unmodified lines | |||
| 2251 | } | 2251 | } |
| 2252 | 2252 | ||
| 2253 | if (s->output_type == 0) | 2253 | if (s->output_type == 0) |
| 2254 | s->output_type = TCC_OUTPUT_EXE; | 2254 | s->output_type = TCC_OUTPUT_EXE; |
| 2255 | 2255 | ||
| 2256 | if (pthread && s->output_type != TCC_OUTPUT_OBJ) | 2256 | if (pthread && s->output_type != TCC_OUTPUT_OBJ) |
| 2257 | tcc_set_options(s, "-lpthread"); | 2257 | tcc_set_options(s, "-lpthread"); |
| 2258 | 2258 | ||
| 2259 | if (s->output_type == TCC_OUTPUT_EXE) | 2259 | if (s->output_type == TCC_OUTPUT_EXE) |
| 2260 | tcc_set_linker(s, (const char *)linker_arg.data); | 2260 | tcc_set_linker(s, (const char *)linker_arg.data); |
| 2261 | cstr_free(&linker_arg); | 2261 | cstr_free(&linker_arg); |
| 2262 | 2262 | ||
| 2263 | return optind; | 2263 | return optind; |
| @@ -92,10 +92,10 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe) · 91 unmodified lines | |||
| 92 | break; | 92 | break; |
| 93 | case TOK_CCHAR: | 93 | case TOK_CCHAR: |
| 94 | case TOK_LCHAR: | 94 | case TOK_LCHAR: |
| 95 | pe->v = tokc.i; | 95 | pe->v = tokc.i; |
| 96 | pe->sym = NULL; | 96 | pe->sym = NULL; |
| 97 | next(); | 97 | next(); |
| 98 | break; | 98 | break; |
| 99 | case '(': | 99 | case '(': |
| 100 | next(); | 100 | next(); |
| 101 | asm_expr(s1, pe); | 101 | asm_expr(s1, pe); |
| @@ -493,7 +493,7 @@ static void asm_parse_directive(TCCState *s1) · 391 unmodified lines | |||
| 493 | case TOK_ASM_weak: | 493 | case TOK_ASM_weak: |
| 494 | case TOK_ASM_hidden: | 494 | case TOK_ASM_hidden: |
| 495 | tok1 = tok; | 495 | tok1 = tok; |
| 496 | do { | 496 | do { |
| 497 | Sym *sym; | 497 | Sym *sym; |
| 498 | 498 | ||
| 499 | next(); | 499 | next(); |
| @@ -502,15 +502,15 @@ static void asm_parse_directive(TCCState *s1) · 2 unmodified lines | |||
| 502 | sym = label_push(&s1->asm_labels, tok, 0); | 502 | sym = label_push(&s1->asm_labels, tok, 0); |
| 503 | sym->type.t = VT_VOID; | 503 | sym->type.t = VT_VOID; |
| 504 | } | 504 | } |
| 505 | if (tok1 != TOK_ASM_hidden) | 505 | if (tok1 != TOK_ASM_hidden) |
| 506 | sym->type.t &= ~VT_STATIC; | 506 | sym->type.t &= ~VT_STATIC; |
| 507 | if (tok1 == TOK_ASM_weak) | 507 | if (tok1 == TOK_ASM_weak) |
| 508 | sym->type.t |= VT_WEAK; | 508 | sym->type.t |= VT_WEAK; |
| 509 | else if (tok1 == TOK_ASM_hidden) | 509 | else if (tok1 == TOK_ASM_hidden) |
| 510 | sym->type.t |= STV_HIDDEN << VT_VIS_SHIFT; | 510 | sym->type.t |= STV_HIDDEN << VT_VIS_SHIFT; |
| 511 | next(); | 511 | next(); |
| 512 | } while (tok == ','); | 512 | } while (tok == ','); |
| 513 | break; | 513 | break; |
| 514 | case TOK_ASM_string: | 514 | case TOK_ASM_string: |
| 515 | case TOK_ASM_ascii: | 515 | case TOK_ASM_ascii: |
| 516 | case TOK_ASM_asciz: | 516 | case TOK_ASM_asciz: |
| @@ -536,24 +536,24 @@ static void asm_parse_directive(TCCState *s1) · 19 unmodified lines | |||
| 536 | break; | 536 | break; |
| 537 | } | 537 | } |
| 538 | } | 538 | } |
| 539 | } | 539 | } |
| 540 | break; | 540 | break; |
| 541 | case TOK_ASM_text: | 541 | case TOK_ASM_text: |
| 542 | case TOK_ASM_data: | 542 | case TOK_ASM_data: |
| 543 | case TOK_ASM_bss: | 543 | case TOK_ASM_bss: |
| 544 | { | 544 | { |
| 545 | char sname[64]; | 545 | char sname[64]; |
| 546 | tok1 = tok; | 546 | tok1 = tok; |
| 547 | n = 0; | 547 | n = 0; |
| 548 | next(); | 548 | next(); |
| 549 | if (tok != ';' && tok != TOK_LINEFEED) { | 549 | if (tok != ';' && tok != TOK_LINEFEED) { |
| 550 | n = asm_int_expr(s1); | 550 | n = asm_int_expr(s1); |
| 551 | next(); | 551 | next(); |
| 552 | } | 552 | } |
| 553 | sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n); | 553 | sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n); |
| 554 | use_section(s1, sname); | 554 | use_section(s1, sname); |
| 555 | } | 555 | } |
| 556 | break; | 556 | break; |
| 557 | case TOK_ASM_file: | 557 | case TOK_ASM_file: |
| 558 | { | 558 | { |
| 559 | char filename[512]; | 559 | char filename[512]; |
| @@ -451,7 +451,7 @@ ST_FUNC void relocate_syms(TCCState *s1, int do_resolve) · 450 unmodified lines | |||
| 451 | if (addr) { | 451 | if (addr) { |
| 452 | sym->st_value = (addr_t)addr; | 452 | sym->st_value = (addr_t)addr; |
| 453 | #ifdef DEBUG_RELOC | 453 | #ifdef DEBUG_RELOC |
| 454 | printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value); | 454 | printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value); |
| 455 | #endif | 455 | #endif |
| 456 | goto found; | 456 | goto found; |
| 457 | } | 457 | } |
| @@ -580,10 +580,10 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 122 unmodified lines | |||
| 580 | { | 580 | { |
| 581 | int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko; | 581 | int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko; |
| 582 | x = (*(int *) ptr) & 0xffffff; | 582 | x = (*(int *) ptr) & 0xffffff; |
| 583 | if (sym->st_shndx == SHN_UNDEF) | 583 | if (sym->st_shndx == SHN_UNDEF) |
| 584 | val = s1->plt->sh_addr; | 584 | val = s1->plt->sh_addr; |
| 585 | #ifdef DEBUG_RELOC | 585 | #ifdef DEBUG_RELOC |
| 586 | printf ("reloc %d: x=0x%x val=0x%x ", type, x, val); | 586 | printf ("reloc %d: x=0x%x val=0x%x ", type, x, val); |
| 587 | #endif | 587 | #endif |
| 588 | (*(int *)ptr) &= 0xff000000; | 588 | (*(int *)ptr) &= 0xff000000; |
| 589 | if (x & 0x800000) | 589 | if (x & 0x800000) |
| @@ -595,8 +595,8 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 5 unmodified lines | |||
| 595 | is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl)); | 595 | is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl)); |
| 596 | x += val - addr; | 596 | x += val - addr; |
| 597 | #ifdef DEBUG_RELOC | 597 | #ifdef DEBUG_RELOC |
| 598 | printf (" newx=0x%x name=%s\n", x, | 598 | printf (" newx=0x%x name=%s\n", x, |
| 599 | (char *) symtab_section->link->data + sym->st_name); | 599 | (char *) symtab_section->link->data + sym->st_name); |
| 600 | #endif | 600 | #endif |
| 601 | h = x & 2; | 601 | h = x & 2; |
| 602 | th_ko = (x & 3) && (!blx_avail || !is_call); | 602 | th_ko = (x & 3) && (!blx_avail || !is_call); |
| @@ -797,21 +797,21 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 194 unmodified lines | |||
| 797 | break; | 797 | break; |
| 798 | case R_AARCH64_JUMP26: | 798 | case R_AARCH64_JUMP26: |
| 799 | case R_AARCH64_CALL26: | 799 | case R_AARCH64_CALL26: |
| 800 | /* This check must match the one in build_got_entries, testing | 800 | /* This check must match the one in build_got_entries, testing |
| 801 | if we really need a PLT slot. */ | 801 | if we really need a PLT slot. */ |
| 802 | if (sym->st_shndx == SHN_UNDEF) | 802 | if (sym->st_shndx == SHN_UNDEF) |
| 803 | /* We've put the PLT slot offset into r_addend when generating | 803 | /* We've put the PLT slot offset into r_addend when generating |
| 804 | it, and that's what we must use as relocation value (adjusted | 804 | it, and that's what we must use as relocation value (adjusted |
| 805 | by section offset of course). */ | 805 | by section offset of course). */ |
| 806 | val = s1->plt->sh_addr + rel->r_addend; | 806 | val = s1->plt->sh_addr + rel->r_addend; |
| 807 | #ifdef DEBUG_RELOC | 807 | #ifdef DEBUG_RELOC |
| 808 | printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val, | 808 | printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val, |
| 809 | (char *) symtab_section->link->data + sym->st_name); | 809 | (char *) symtab_section->link->data + sym->st_name); |
| 810 | #endif | 810 | #endif |
| 811 | if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc) | 811 | if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc) |
| 812 | { | 812 | { |
| 813 | tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed (val=%lx, addr=%lx)", addr, val); | 813 | tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed (val=%lx, addr=%lx)", addr, val); |
| 814 | } | 814 | } |
| 815 | *(uint32_t *)ptr = 0x14000000 | (type == R_AARCH64_CALL26) << 31 | | 815 | *(uint32_t *)ptr = 0x14000000 | (type == R_AARCH64_CALL26) << 31 | |
| 816 | ((val - addr) >> 2 & 0x3ffffff); | 816 | ((val - addr) >> 2 & 0x3ffffff); |
| 817 | break; | 817 | break; |
| @@ -836,9 +836,9 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 18 unmodified lines | |||
| 836 | case R_AARCH64_JUMP_SLOT: | 836 | case R_AARCH64_JUMP_SLOT: |
| 837 | /* They don't need addend */ | 837 | /* They don't need addend */ |
| 838 | #ifdef DEBUG_RELOC | 838 | #ifdef DEBUG_RELOC |
| 839 | printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, | 839 | printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, |
| 840 | val - rel->r_addend, | 840 | val - rel->r_addend, |
| 841 | (char *) symtab_section->link->data + sym->st_name); | 841 | (char *) symtab_section->link->data + sym->st_name); |
| 842 | #endif | 842 | #endif |
| 843 | *(addr_t *)ptr = val - rel->r_addend; | 843 | *(addr_t *)ptr = val - rel->r_addend; |
| 844 | break; | 844 | break; |
| @@ -879,12 +879,12 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 34 unmodified lines | |||
| 879 | qrel->r_offset = rel->r_offset; | 879 | qrel->r_offset = rel->r_offset; |
| 880 | if (esym_index) { | 880 | if (esym_index) { |
| 881 | qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64); | 881 | qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64); |
| 882 | qrel->r_addend = rel->r_addend; | 882 | qrel->r_addend = rel->r_addend; |
| 883 | qrel++; | 883 | qrel++; |
| 884 | break; | 884 | break; |
| 885 | } else { | 885 | } else { |
| 886 | qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE); | 886 | qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE); |
| 887 | qrel->r_addend = *(long long *)ptr + val; | 887 | qrel->r_addend = *(long long *)ptr + val; |
| 888 | qrel++; | 888 | qrel++; |
| 889 | } | 889 | } |
| 890 | } | 890 | } |
| @@ -917,14 +917,14 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 26 unmodified lines | |||
| 917 | goto plt32pc32; | 917 | goto plt32pc32; |
| 918 | 918 | ||
| 919 | case R_X86_64_PLT32: | 919 | case R_X86_64_PLT32: |
| 920 | /* We've put the PLT slot offset into r_addend when generating | 920 | /* We've put the PLT slot offset into r_addend when generating |
| 921 | it, and that's what we must use as relocation value (adjusted | 921 | it, and that's what we must use as relocation value (adjusted |
| 922 | by section offset of course). */ | 922 | by section offset of course). */ |
| 923 | val = s1->plt->sh_addr + rel->r_addend; | 923 | val = s1->plt->sh_addr + rel->r_addend; |
| 924 | /* fallthrough. */ | 924 | /* fallthrough. */ |
| 925 | 925 | ||
| 926 | plt32pc32: | 926 | plt32pc32: |
| 927 | { | 927 | { |
| 928 | long long diff; | 928 | long long diff; |
| 929 | diff = (long long)val - addr; | 929 | diff = (long long)val - addr; |
| 930 | if (diff < -2147483648LL || diff > 2147483647LL) { | 930 | if (diff < -2147483648LL || diff > 2147483647LL) { |
| @@ -1080,8 +1080,8 @@ static void build_got(TCCState *s1) · 149 unmodified lines | |||
| 1080 | and 'info' can be modifed if more precise info comes from the DLL. | 1080 | and 'info' can be modifed if more precise info comes from the DLL. |
| 1081 | Returns offset of GOT or PLT slot. */ | 1081 | Returns offset of GOT or PLT slot. */ |
| 1082 | static unsigned long put_got_entry(TCCState *s1, | 1082 | static unsigned long put_got_entry(TCCState *s1, |
| 1083 | int reloc_type, unsigned long size, int info, | 1083 | int reloc_type, unsigned long size, int info, |
| 1084 | int sym_index) | 1084 | int sym_index) |
| 1085 | { | 1085 | { |
| 1086 | int index, need_plt_entry; | 1086 | int index, need_plt_entry; |
| 1087 | const char *name; | 1087 | const char *name; |
| @@ -1107,18 +1107,18 @@ static unsigned long put_got_entry(TCCState *s1, · 19 unmodified lines | |||
| 1107 | #endif | 1107 | #endif |
| 1108 | 1108 | ||
| 1109 | if (need_plt_entry && !s1->plt) { | 1109 | if (need_plt_entry && !s1->plt) { |
| 1110 | /* add PLT */ | 1110 | /* add PLT */ |
| 1111 | s1->plt = new_section(s1, ".plt", SHT_PROGBITS, | 1111 | s1->plt = new_section(s1, ".plt", SHT_PROGBITS, |
| 1112 | SHF_ALLOC | SHF_EXECINSTR); | 1112 | SHF_ALLOC | SHF_EXECINSTR); |
| 1113 | s1->plt->sh_entsize = 4; | 1113 | s1->plt->sh_entsize = 4; |
| 1114 | } | 1114 | } |
| 1115 | 1115 | ||
| 1116 | /* If a got/plt entry already exists for that symbol, no need to add one */ | 1116 | /* If a got/plt entry already exists for that symbol, no need to add one */ |
| 1117 | if (sym_index < s1->nb_sym_attrs) { | 1117 | if (sym_index < s1->nb_sym_attrs) { |
| 1118 | if (need_plt_entry && s1->sym_attrs[sym_index].plt_offset) | 1118 | if (need_plt_entry && s1->sym_attrs[sym_index].plt_offset) |
| 1119 | return s1->sym_attrs[sym_index].plt_offset; | 1119 | return s1->sym_attrs[sym_index].plt_offset; |
| 1120 | else if (!need_plt_entry && s1->sym_attrs[sym_index].got_offset) | 1120 | else if (!need_plt_entry && s1->sym_attrs[sym_index].got_offset) |
| 1121 | return s1->sym_attrs[sym_index].got_offset; | 1121 | return s1->sym_attrs[sym_index].got_offset; |
| 1122 | } | 1122 | } |
| 1123 | 1123 | ||
| 1124 | symattr = alloc_sym_attr(s1, sym_index); | 1124 | symattr = alloc_sym_attr(s1, sym_index); |
| @@ -1135,7 +1135,7 @@ static unsigned long put_got_entry(TCCState *s1, · 10 unmodified lines | |||
| 1135 | Section *plt; | 1135 | Section *plt; |
| 1136 | uint8_t *p; | 1136 | uint8_t *p; |
| 1137 | int modrm; | 1137 | int modrm; |
| 1138 | unsigned long relofs; | 1138 | unsigned long relofs; |
| 1139 | 1139 | ||
| 1140 | #if defined(TCC_OUTPUT_DLL_WITH_PLT) | 1140 | #if defined(TCC_OUTPUT_DLL_WITH_PLT) |
| 1141 | modrm = 0x25; | 1141 | modrm = 0x25; |
| @@ -1160,10 +1160,10 @@ static unsigned long put_got_entry(TCCState *s1, · 18 unmodified lines | |||
| 1160 | put32(p + 8, PTR_SIZE * 2); | 1160 | put32(p + 8, PTR_SIZE * 2); |
| 1161 | } | 1161 | } |
| 1162 | 1162 | ||
| 1163 | /* The PLT slot refers to the relocation entry it needs | 1163 | /* The PLT slot refers to the relocation entry it needs |
| 1164 | via offset. The reloc entry is created below, so its | 1164 | via offset. The reloc entry is created below, so its |
| 1165 | offset is the current data_offset. */ | 1165 | offset is the current data_offset. */ |
| 1166 | relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0; | 1166 | relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0; |
| 1167 | symattr->plt_offset = plt->data_offset; | 1167 | symattr->plt_offset = plt->data_offset; |
| 1168 | p = section_ptr_add(plt, 16); | 1168 | p = section_ptr_add(plt, 16); |
| 1169 | p[0] = 0xff; /* jmp *(got + x) */ | 1169 | p[0] = 0xff; /* jmp *(got + x) */ |
| @@ -1171,19 +1171,19 @@ static unsigned long put_got_entry(TCCState *s1, · 1 unmodified line | |||
| 1171 | put32(p + 2, s1->got->data_offset); | 1171 | put32(p + 2, s1->got->data_offset); |
| 1172 | p[6] = 0x68; /* push $xxx */ | 1172 | p[6] = 0x68; /* push $xxx */ |
| 1173 | #ifdef TCC_TARGET_X86_64 | 1173 | #ifdef TCC_TARGET_X86_64 |
| 1174 | /* On x86-64, the relocation is referred to by _index_. */ | 1174 | /* On x86-64, the relocation is referred to by _index_. */ |
| 1175 | put32(p + 7, relofs / sizeof (ElfW_Rel)); | 1175 | put32(p + 7, relofs / sizeof (ElfW_Rel)); |
| 1176 | #else | 1176 | #else |
| 1177 | put32(p + 7, relofs); | 1177 | put32(p + 7, relofs); |
| 1178 | #endif | 1178 | #endif |
| 1179 | p[11] = 0xe9; /* jmp plt_start */ | 1179 | p[11] = 0xe9; /* jmp plt_start */ |
| 1180 | put32(p + 12, -(plt->data_offset)); | 1180 | put32(p + 12, -(plt->data_offset)); |
| 1181 | 1181 | ||
| 1182 | /* If this was an UNDEF symbol set the offset in the | 1182 | /* If this was an UNDEF symbol set the offset in the |
| 1183 | dynsymtab to the PLT slot, so that PC32 relocs to it | 1183 | dynsymtab to the PLT slot, so that PC32 relocs to it |
| 1184 | can be resolved. */ | 1184 | can be resolved. */ |
| 1185 | if (sym->st_shndx == SHN_UNDEF) | 1185 | if (sym->st_shndx == SHN_UNDEF) |
| 1186 | offset = plt->data_offset - 16; | 1186 | offset = plt->data_offset - 16; |
| 1187 | } | 1187 | } |
| 1188 | #elif defined(TCC_TARGET_ARM) | 1188 | #elif defined(TCC_TARGET_ARM) |
| 1189 | if (need_plt_entry) { | 1189 | if (need_plt_entry) { |
| @@ -1220,7 +1220,7 @@ static unsigned long put_got_entry(TCCState *s1, · 30 unmodified lines | |||
| 1220 | 1220 | ||
| 1221 | /* the symbol is modified so that it will be relocated to | 1221 | /* the symbol is modified so that it will be relocated to |
| 1222 | the PLT */ | 1222 | the PLT */ |
| 1223 | if (sym->st_shndx == SHN_UNDEF) | 1223 | if (sym->st_shndx == SHN_UNDEF) |
| 1224 | offset = plt->data_offset - 16; | 1224 | offset = plt->data_offset - 16; |
| 1225 | } | 1225 | } |
| 1226 | #elif defined(TCC_TARGET_ARM64) | 1226 | #elif defined(TCC_TARGET_ARM64) |
| @@ -1250,19 +1250,19 @@ static unsigned long put_got_entry(TCCState *s1, · 23 unmodified lines | |||
| 1250 | #error unsupported CPU | 1250 | #error unsupported CPU |
| 1251 | #endif | 1251 | #endif |
| 1252 | if (s1->dynsym) { | 1252 | if (s1->dynsym) { |
| 1253 | /* XXX This might generate multiple syms for name. */ | 1253 | /* XXX This might generate multiple syms for name. */ |
| 1254 | index = put_elf_sym(s1->dynsym, offset, | 1254 | index = put_elf_sym(s1->dynsym, offset, |
| 1255 | size, info, 0, sym->st_shndx, name); | 1255 | size, info, 0, sym->st_shndx, name); |
| 1256 | /* Create the relocation (it's against the GOT for PLT | 1256 | /* Create the relocation (it's against the GOT for PLT |
| 1257 | and GOT relocs). */ | 1257 | and GOT relocs). */ |
| 1258 | put_elf_reloc(s1->dynsym, s1->got, | 1258 | put_elf_reloc(s1->dynsym, s1->got, |
| 1259 | s1->got->data_offset, | 1259 | s1->got->data_offset, |
| 1260 | reloc_type, index); | 1260 | reloc_type, index); |
| 1261 | } else { | 1261 | } else { |
| 1262 | /* Without .dynsym (i.e. static link or memory output) we | 1262 | /* Without .dynsym (i.e. static link or memory output) we |
| 1263 | still need relocs against the generated got, so as to fill | 1263 | still need relocs against the generated got, so as to fill |
| 1264 | the entries with the symbol values (determined later). */ | 1264 | the entries with the symbol values (determined later). */ |
| 1265 | put_elf_reloc(symtab_section, s1->got, | 1265 | put_elf_reloc(symtab_section, s1->got, |
| 1266 | s1->got->data_offset, | 1266 | s1->got->data_offset, |
| 1267 | reloc_type, sym_index); | 1267 | reloc_type, sym_index); |
| 1268 | } | 1268 | } |
| @@ -1324,8 +1324,8 @@ ST_FUNC void build_got_entries(TCCState *s1) · 55 unmodified lines | |||
| 1324 | build_got(s1); | 1324 | build_got(s1); |
| 1325 | sym_index = ELFW(R_SYM)(rel->r_info); | 1325 | sym_index = ELFW(R_SYM)(rel->r_info); |
| 1326 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; | 1326 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; |
| 1327 | if (type != R_ARM_GOTOFF && type != R_ARM_GOTPC | 1327 | if (type != R_ARM_GOTOFF && type != R_ARM_GOTPC |
| 1328 | && sym->st_shndx == SHN_UNDEF) { | 1328 | && sym->st_shndx == SHN_UNDEF) { |
| 1329 | unsigned long ofs; | 1329 | unsigned long ofs; |
| 1330 | /* look at the symbol got offset. If none, then add one */ | 1330 | /* look at the symbol got offset. If none, then add one */ |
| 1331 | if (type == R_ARM_GOT32) | 1331 | if (type == R_ARM_GOT32) |
| @@ -1333,27 +1333,27 @@ ST_FUNC void build_got_entries(TCCState *s1) · 1 unmodified line | |||
| 1333 | else | 1333 | else |
| 1334 | reloc_type = R_ARM_JUMP_SLOT; | 1334 | reloc_type = R_ARM_JUMP_SLOT; |
| 1335 | ofs = put_got_entry(s1, reloc_type, sym->st_size, | 1335 | ofs = put_got_entry(s1, reloc_type, sym->st_size, |
| 1336 | sym->st_info, sym_index); | 1336 | sym->st_info, sym_index); |
| 1337 | #ifdef DEBUG_RELOC | 1337 | #ifdef DEBUG_RELOC |
| 1338 | printf ("maybegot: %s, %d, %d --> ofs=0x%x\n", | 1338 | printf ("maybegot: %s, %d, %d --> ofs=0x%x\n", |
| 1339 | (char *) symtab_section->link->data + sym->st_name, | 1339 | (char *) symtab_section->link->data + sym->st_name, |
| 1340 | type, sym->st_shndx, ofs); | 1340 | type, sym->st_shndx, ofs); |
| 1341 | #endif | 1341 | #endif |
| 1342 | if (type != R_ARM_GOT32) { | 1342 | if (type != R_ARM_GOT32) { |
| 1343 | addr_t *ptr = (addr_t*)(s1->sections[s->sh_info]->data | 1343 | addr_t *ptr = (addr_t*)(s1->sections[s->sh_info]->data |
| 1344 | + rel->r_offset); | 1344 | + rel->r_offset); |
| 1345 | /* x must be signed! */ | 1345 | /* x must be signed! */ |
| 1346 | int x = *ptr & 0xffffff; | 1346 | int x = *ptr & 0xffffff; |
| 1347 | x = (x << 8) >> 8; | 1347 | x = (x << 8) >> 8; |
| 1348 | x <<= 2; | 1348 | x <<= 2; |
| 1349 | x += ofs; | 1349 | x += ofs; |
| 1350 | x >>= 2; | 1350 | x >>= 2; |
| 1351 | #ifdef DEBUG_RELOC | 1351 | #ifdef DEBUG_RELOC |
| 1352 | printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr, | 1352 | printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr, |
| 1353 | (*ptr & 0xff000000) | x, x); | 1353 | (*ptr & 0xff000000) | x, x); |
| 1354 | #endif | 1354 | #endif |
| 1355 | *ptr = (*ptr & 0xff000000) | x; | 1355 | *ptr = (*ptr & 0xff000000) | x; |
| 1356 | } | 1356 | } |
| 1357 | } | 1357 | } |
| 1358 | break; | 1358 | break; |
| 1359 | case R_ARM_THM_JUMP24: | 1359 | case R_ARM_THM_JUMP24: |
| @@ -1397,22 +1397,22 @@ ST_FUNC void build_got_entries(TCCState *s1) · 37 unmodified lines | |||
| 1397 | sym_index); | 1397 | sym_index); |
| 1398 | break; | 1398 | break; |
| 1399 | 1399 | ||
| 1400 | case R_AARCH64_JUMP26: | 1400 | case R_AARCH64_JUMP26: |
| 1401 | case R_AARCH64_CALL26: | 1401 | case R_AARCH64_CALL26: |
| 1402 | if (!s1->got) | 1402 | if (!s1->got) |
| 1403 | build_got(s1); | 1403 | build_got(s1); |
| 1404 | sym_index = ELFW(R_SYM)(rel->r_info); | 1404 | sym_index = ELFW(R_SYM)(rel->r_info); |
| 1405 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; | 1405 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; |
| 1406 | if (sym->st_shndx == SHN_UNDEF) { | 1406 | if (sym->st_shndx == SHN_UNDEF) { |
| 1407 | unsigned long ofs; | 1407 | unsigned long ofs; |
| 1408 | reloc_type = R_AARCH64_JUMP_SLOT; | 1408 | reloc_type = R_AARCH64_JUMP_SLOT; |
| 1409 | ofs = put_got_entry(s1, reloc_type, sym->st_size, | 1409 | ofs = put_got_entry(s1, reloc_type, sym->st_size, |
| 1410 | sym->st_info, sym_index); | 1410 | sym->st_info, sym_index); |
| 1411 | /* We store the place of the generated PLT slot | 1411 | /* We store the place of the generated PLT slot |
| 1412 | in our addend. */ | 1412 | in our addend. */ |
| 1413 | rel->r_addend += ofs; | 1413 | rel->r_addend += ofs; |
| 1414 | } | 1414 | } |
| 1415 | break; | 1415 | break; |
| 1416 | #elif defined(TCC_TARGET_C67) | 1416 | #elif defined(TCC_TARGET_C67) |
| 1417 | case R_C60_GOT32: | 1417 | case R_C60_GOT32: |
| 1418 | case R_C60_GOTOFF: | 1418 | case R_C60_GOTOFF: |
| @@ -1439,29 +1439,29 @@ ST_FUNC void build_got_entries(TCCState *s1) · 20 unmodified lines | |||
| 1439 | case R_X86_64_PLT32: | 1439 | case R_X86_64_PLT32: |
| 1440 | sym_index = ELFW(R_SYM)(rel->r_info); | 1440 | sym_index = ELFW(R_SYM)(rel->r_info); |
| 1441 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; | 1441 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; |
| 1442 | if (type == R_X86_64_PLT32 && | 1442 | if (type == R_X86_64_PLT32 && |
| 1443 | ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT) | 1443 | ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT) |
| 1444 | { | 1444 | { |
| 1445 | rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32); | 1445 | rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32); |
| 1446 | break; | 1446 | break; |
| 1447 | } | 1447 | } |
| 1448 | 1448 | ||
| 1449 | if (!s1->got) | 1449 | if (!s1->got) |
| 1450 | build_got(s1); | 1450 | build_got(s1); |
| 1451 | if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL || | 1451 | if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL || |
| 1452 | type == R_X86_64_PLT32) { | 1452 | type == R_X86_64_PLT32) { |
| 1453 | unsigned long ofs; | 1453 | unsigned long ofs; |
| 1454 | /* look at the symbol got offset. If none, then add one */ | 1454 | /* look at the symbol got offset. If none, then add one */ |
| 1455 | if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL) | 1455 | if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL) |
| 1456 | reloc_type = R_X86_64_GLOB_DAT; | 1456 | reloc_type = R_X86_64_GLOB_DAT; |
| 1457 | else | 1457 | else |
| 1458 | reloc_type = R_X86_64_JUMP_SLOT; | 1458 | reloc_type = R_X86_64_JUMP_SLOT; |
| 1459 | ofs = put_got_entry(s1, reloc_type, sym->st_size, | 1459 | ofs = put_got_entry(s1, reloc_type, sym->st_size, |
| 1460 | sym->st_info, sym_index); | 1460 | sym->st_info, sym_index); |
| 1461 | if (type == R_X86_64_PLT32) | 1461 | if (type == R_X86_64_PLT32) |
| 1462 | /* We store the place of the generated PLT slot | 1462 | /* We store the place of the generated PLT slot |
| 1463 | in our addend. */ | 1463 | in our addend. */ |
| 1464 | rel->r_addend += ofs; | 1464 | rel->r_addend += ofs; |
| 1465 | } | 1465 | } |
| 1466 | break; | 1466 | break; |
| 1467 | #else | 1467 | #else |
| @@ -1546,21 +1546,21 @@ static int tcc_add_support(TCCState *s1, const char *filename) · 78 unmodified lines | |||
| 1546 | snprintf(buf, sizeof(buf), "%s/%s/%s", s1->tcc_lib_path, | 1546 | snprintf(buf, sizeof(buf), "%s/%s/%s", s1->tcc_lib_path, |
| 1547 | /* an cpu specific path inside tcc_lib_path, mainly for keeping libtcc1.a */ | 1547 | /* an cpu specific path inside tcc_lib_path, mainly for keeping libtcc1.a */ |
| 1548 | #ifdef TCC_TARGET_I386 | 1548 | #ifdef TCC_TARGET_I386 |
| 1549 | "i386" | 1549 | "i386" |
| 1550 | #endif | 1550 | #endif |
| 1551 | #ifdef TCC_TARGET_X86_64 | 1551 | #ifdef TCC_TARGET_X86_64 |
| 1552 | "x86-64" | 1552 | "x86-64" |
| 1553 | #endif | 1553 | #endif |
| 1554 | #ifdef TCC_TARGET_ARM | 1554 | #ifdef TCC_TARGET_ARM |
| 1555 | "arm" | 1555 | "arm" |
| 1556 | #endif | 1556 | #endif |
| 1557 | #ifdef TCC_TARGET_ARM64 | 1557 | #ifdef TCC_TARGET_ARM64 |
| 1558 | "arm64" | 1558 | "arm64" |
| 1559 | #endif | 1559 | #endif |
| 1560 | #ifdef TCC_TARGET_C67 | 1560 | #ifdef TCC_TARGET_C67 |
| 1561 | "C67" | 1561 | "C67" |
| 1562 | #endif | 1562 | #endif |
| 1563 | ,filename); | 1563 | ,filename); |
| 1564 | 1564 | ||
| 1565 | return tcc_add_file(s1, buf, TCC_FILETYPE_BINARY); | 1565 | return tcc_add_file(s1, buf, TCC_FILETYPE_BINARY); |
| 1566 | } | 1566 | } |
| @@ -1587,17 +1587,17 @@ ST_FUNC void tcc_add_bcheck(TCCState *s1) · 20 unmodified lines | |||
| 1587 | when __bound_ptr_add, __bound_new_region, | 1587 | when __bound_ptr_add, __bound_new_region, |
| 1588 | __bound_delete_region called */ | 1588 | __bound_delete_region called */ |
| 1589 | 1589 | ||
| 1590 | int sym_index = find_elf_sym(symtab_section, "__bound_init"); | 1590 | int sym_index = find_elf_sym(symtab_section, "__bound_init"); |
| 1591 | if (sym_index) { | 1591 | if (sym_index) { |
| 1592 | Section *init_section = find_section(s1, ".init"); | 1592 | Section *init_section = find_section(s1, ".init"); |
| 1593 | unsigned char *pinit = section_ptr_add(init_section, 5); | 1593 | unsigned char *pinit = section_ptr_add(init_section, 5); |
| 1594 | pinit[0] = 0xe8; | 1594 | pinit[0] = 0xe8; |
| 1595 | put32(pinit + 1, -4); | 1595 | put32(pinit + 1, -4); |
| 1596 | put_elf_reloc(symtab_section, init_section, | 1596 | put_elf_reloc(symtab_section, init_section, |
| 1597 | init_section->data_offset - 4, R_386_PC32, sym_index); | 1597 | init_section->data_offset - 4, R_386_PC32, sym_index); |
| 1598 | } | 1598 | } |
| 1599 | else | 1599 | else |
| 1600 | tcc_warning("__bound_init not defined"); | 1600 | tcc_warning("__bound_init not defined"); |
| 1601 | } | 1601 | } |
| 1602 | #endif | 1602 | #endif |
| 1603 | } | 1603 | } |
| @@ -1905,11 +1905,11 @@ static void export_global_syms(TCCState *s1) · 301 unmodified lines | |||
| 1905 | s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms); | 1905 | s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms); |
| 1906 | for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { | 1906 | for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { |
| 1907 | if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { | 1907 | if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { |
| 1908 | name = (char *) symtab_section->link->data + sym->st_name; | 1908 | name = (char *) symtab_section->link->data + sym->st_name; |
| 1909 | dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, | 1909 | dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, |
| 1910 | sym->st_info, 0, sym->st_shndx, name); | 1910 | sym->st_info, 0, sym->st_shndx, name); |
| 1911 | index = sym - (ElfW(Sym) *) symtab_section->data; | 1911 | index = sym - (ElfW(Sym) *) symtab_section->data; |
| 1912 | s1->symtab_to_dynsym[index] = dynindex; | 1912 | s1->symtab_to_dynsym[index] = dynindex; |
| 1913 | } | 1913 | } |
| 1914 | } | 1914 | } |
| 1915 | } | 1915 | } |
| @@ -2179,15 +2179,15 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, · 263 unmodified lines | |||
| 2179 | file_offset += s->sh_size; | 2179 | file_offset += s->sh_size; |
| 2180 | } | 2180 | } |
| 2181 | } | 2181 | } |
| 2182 | if (j == 0) { | 2182 | if (j == 0) { |
| 2183 | /* Make the first PT_LOAD segment include the program | 2183 | /* Make the first PT_LOAD segment include the program |
| 2184 | headers itself (and the ELF header as well), it'll | 2184 | headers itself (and the ELF header as well), it'll |
| 2185 | come out with same memory use but will make various | 2185 | come out with same memory use but will make various |
| 2186 | tools like binutils strip work better. */ | 2186 | tools like binutils strip work better. */ |
| 2187 | ph->p_offset &= ~(ph->p_align - 1); | 2187 | ph->p_offset &= ~(ph->p_align - 1); |
| 2188 | ph->p_vaddr &= ~(ph->p_align - 1); | 2188 | ph->p_vaddr &= ~(ph->p_align - 1); |
| 2189 | ph->p_paddr &= ~(ph->p_align - 1); | 2189 | ph->p_paddr &= ~(ph->p_align - 1); |
| 2190 | } | 2190 | } |
| 2191 | ph->p_filesz = file_offset - ph->p_offset; | 2191 | ph->p_filesz = file_offset - ph->p_offset; |
| 2192 | ph->p_memsz = addr - ph->p_vaddr; | 2192 | ph->p_memsz = addr - ph->p_vaddr; |
| 2193 | ph++; | 2193 | ph++; |
| @@ -2662,10 +2662,10 @@ static int elf_output_file(TCCState *s1, const char *filename) · 468 unmodified lines | |||
| 2662 | for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) { | 2662 | for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) { |
| 2663 | if (sym->st_shndx == SHN_UNDEF) { | 2663 | if (sym->st_shndx == SHN_UNDEF) { |
| 2664 | /* relocate to PLT if symbol corresponds to a PLT entry, | 2664 | /* relocate to PLT if symbol corresponds to a PLT entry, |
| 2665 | but not if it's a weak symbol */ | 2665 | but not if it's a weak symbol */ |
| 2666 | if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK) | 2666 | if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK) |
| 2667 | sym->st_value = 0; | 2667 | sym->st_value = 0; |
| 2668 | else if (sym->st_value) | 2668 | else if (sym->st_value) |
| 2669 | sym->st_value += s1->plt->sh_addr; | 2669 | sym->st_value += s1->plt->sh_addr; |
| 2670 | } else if (sym->st_shndx < SHN_LORESERVE) { | 2670 | } else if (sym->st_shndx < SHN_LORESERVE) { |
| 2671 | /* do symbol relocation */ | 2671 | /* do symbol relocation */ |
| @@ -2690,14 +2690,14 @@ static int elf_output_file(TCCState *s1, const char *filename) · 18 unmodified lines | |||
| 2690 | /* Create the ELF file with name 'filename' */ | 2690 | /* Create the ELF file with name 'filename' */ |
| 2691 | ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order); | 2691 | ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order); |
| 2692 | if (s1->do_strip) { | 2692 | if (s1->do_strip) { |
| 2693 | int rc; | 2693 | int rc; |
| 2694 | const char *strip_cmd = "sstrip "; // super strip utility from ELFkickers | 2694 | const char *strip_cmd = "sstrip "; // super strip utility from ELFkickers |
| 2695 | const char *null_dev = " 2> /dev/null"; | 2695 | const char *null_dev = " 2> /dev/null"; |
| 2696 | char buf[1050]; | 2696 | char buf[1050]; |
| 2697 | snprintf(buf, sizeof(buf), "%s%s%s", strip_cmd, filename, null_dev); | 2697 | snprintf(buf, sizeof(buf), "%s%s%s", strip_cmd, filename, null_dev); |
| 2698 | rc = system(buf); | 2698 | rc = system(buf); |
| 2699 | if (rc) | 2699 | if (rc) |
| 2700 | system(buf+1); // call a strip utility from binutils | 2700 | system(buf+1); // call a strip utility from binutils |
| 2701 | } | 2701 | } |
| 2702 | the_end: | 2702 | the_end: |
| 2703 | tcc_free(s1->symtab_to_dynsym); | 2703 | tcc_free(s1->symtab_to_dynsym); |
| @@ -323,7 +323,7 @@ static void apply_visibility(Sym *sym, CType *type) · 322 unmodified lines | |||
| 323 | ElfW(Sym) *esym; | 323 | ElfW(Sym) *esym; |
| 324 | 324 | ||
| 325 | esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; | 325 | esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; |
| 326 | vis >>= VT_VIS_SHIFT; | 326 | vis >>= VT_VIS_SHIFT; |
| 327 | esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis; | 327 | esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis; |
| 328 | } | 328 | } |
| 329 | } | 329 | } |
| @@ -1631,7 +1631,7 @@ static inline int is_null_pointer(SValue *p) · 1301 unmodified lines | |||
| 1631 | return 0; | 1631 | return 0; |
| 1632 | return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) || | 1632 | return ((p->type.t & VT_BTYPE) == VT_INT && p->c.i == 0) || |
| 1633 | ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) || | 1633 | ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.ll == 0) || |
| 1634 | ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr_offset == 0); | 1634 | ((p->type.t & VT_BTYPE) == VT_PTR && p->c.ptr_offset == 0); |
| 1635 | } | 1635 | } |
| 1636 | 1636 | ||
| 1637 | static inline int is_integer_btype(int bt) | 1637 | static inline int is_integer_btype(int bt) |
| @@ -1761,18 +1761,18 @@ ST_FUNC void gen_op(int op) · 123 unmodified lines | |||
| 1761 | #if 0 | 1761 | #if 0 |
| 1762 | /* #ifdef CONFIG_TCC_BCHECK | 1762 | /* #ifdef CONFIG_TCC_BCHECK |
| 1763 | The main reason to removing this code: | 1763 | The main reason to removing this code: |
| 1764 | #include <stdio.h> | 1764 | #include <stdio.h> |
| 1765 | int main () | 1765 | int main () |
| 1766 | { | 1766 | { |
| 1767 | int v[10]; | 1767 | int v[10]; |
| 1768 | int i = 10; | 1768 | int i = 10; |
| 1769 | int j = 9; | 1769 | int j = 9; |
| 1770 | fprintf(stderr, "v+i-j = %p\n", v+i-j); | 1770 | fprintf(stderr, "v+i-j = %p\n", v+i-j); |
| 1771 | fprintf(stderr, "v+(i-j) = %p\n", v+(i-j)); | 1771 | fprintf(stderr, "v+(i-j) = %p\n", v+(i-j)); |
| 1772 | } | 1772 | } |
| 1773 | When this code is on. then the output looks like | 1773 | When this code is on. then the output looks like |
| 1774 | v+i-j = 0xfffffffe | 1774 | v+i-j = 0xfffffffe |
| 1775 | v+(i-j) = 0xbff84000 | 1775 | v+(i-j) = 0xbff84000 |
| 1776 | */ | 1776 | */ |
| 1777 | /* if evaluating constant expression, no code should be | 1777 | /* if evaluating constant expression, no code should be |
| 1778 | generated, so no bound check */ | 1778 | generated, so no bound check */ |
| @@ -2450,18 +2450,18 @@ static void gen_assign_cast(CType *dt) · 671 unmodified lines | |||
| 2450 | dbt = dt->t & VT_BTYPE; | 2450 | dbt = dt->t & VT_BTYPE; |
| 2451 | sbt = st->t & VT_BTYPE; | 2451 | sbt = st->t & VT_BTYPE; |
| 2452 | if (sbt == VT_VOID || dbt == VT_VOID) { | 2452 | if (sbt == VT_VOID || dbt == VT_VOID) { |
| 2453 | if (sbt == VT_VOID && dbt == VT_VOID) | 2453 | if (sbt == VT_VOID && dbt == VT_VOID) |
| 2454 | ; /* | 2454 | ; /* |
| 2455 | It is Ok if both are void | 2455 | It is Ok if both are void |
| 2456 | A test program: | 2456 | A test program: |
| 2457 | void func1() {} | 2457 | void func1() {} |
| 2458 | void func2() { | 2458 | void func2() { |
| 2459 | return func1(); | 2459 | return func1(); |
| 2460 | } | 2460 | } |
| 2461 | gcc accepts this program | 2461 | gcc accepts this program |
| 2462 | */ | 2462 | */ |
| 2463 | else | 2463 | else |
| 2464 | tcc_error("cannot cast from/to void"); | 2464 | tcc_error("cannot cast from/to void"); |
| 2465 | } | 2465 | } |
| 2466 | if (dt->t & VT_CONSTANT) | 2466 | if (dt->t & VT_CONSTANT) |
| 2467 | tcc_warning("assignment of read-only location"); | 2467 | tcc_warning("assignment of read-only location"); |
| @@ -2542,7 +2542,7 @@ ST_FUNC void vstore(void) · 74 unmodified lines | |||
| 2542 | dbt = ft & VT_BTYPE; | 2542 | dbt = ft & VT_BTYPE; |
| 2543 | if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) || | 2543 | if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) || |
| 2544 | (sbt == VT_INT && dbt == VT_SHORT)) | 2544 | (sbt == VT_INT && dbt == VT_SHORT)) |
| 2545 | && !(vtop->type.t & VT_BITFIELD)) { | 2545 | && !(vtop->type.t & VT_BITFIELD)) { |
| 2546 | /* optimize char/short casts */ | 2546 | /* optimize char/short casts */ |
| 2547 | delayed_cast = VT_MUSTCAST; | 2547 | delayed_cast = VT_MUSTCAST; |
| 2548 | vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT))); | 2548 | vtop->type.t = ft & (VT_TYPE & ~(VT_BITFIELD | (-1 << VT_STRUCT_SHIFT))); |
| @@ -2764,20 +2764,20 @@ static void parse_attribute(AttributeDef *ad) · 215 unmodified lines | |||
| 2764 | next(); | 2764 | next(); |
| 2765 | skip(')'); | 2765 | skip(')'); |
| 2766 | break; | 2766 | break; |
| 2767 | case TOK_VISIBILITY1: | 2767 | case TOK_VISIBILITY1: |
| 2768 | case TOK_VISIBILITY2: | 2768 | case TOK_VISIBILITY2: |
| 2769 | skip('('); | 2769 | skip('('); |
| 2770 | if (tok != TOK_STR) | 2770 | if (tok != TOK_STR) |
| 2771 | expect("visibility(\"default|hidden|internal|protected\")"); | 2771 | expect("visibility(\"default|hidden|internal|protected\")"); |
| 2772 | if (!strcmp (tokc.cstr->data, "default")) | 2772 | if (!strcmp (tokc.cstr->data, "default")) |
| 2773 | ad->a.visibility = STV_DEFAULT; | 2773 | ad->a.visibility = STV_DEFAULT; |
| 2774 | else if (!strcmp (tokc.cstr->data, "hidden")) | 2774 | else if (!strcmp (tokc.cstr->data, "hidden")) |
| 2775 | ad->a.visibility = STV_HIDDEN; | 2775 | ad->a.visibility = STV_HIDDEN; |
| 2776 | else if (!strcmp (tokc.cstr->data, "internal")) | 2776 | else if (!strcmp (tokc.cstr->data, "internal")) |
| 2777 | ad->a.visibility = STV_INTERNAL; | 2777 | ad->a.visibility = STV_INTERNAL; |
| 2778 | else if (!strcmp (tokc.cstr->data, "protected")) | 2778 | else if (!strcmp (tokc.cstr->data, "protected")) |
| 2779 | ad->a.visibility = STV_PROTECTED; | 2779 | ad->a.visibility = STV_PROTECTED; |
| 2780 | else | 2780 | else |
| 2781 | expect("visibility(\"default|hidden|internal|protected\")"); | 2781 | expect("visibility(\"default|hidden|internal|protected\")"); |
| 2782 | next(); | 2782 | next(); |
| 2783 | skip(')'); | 2783 | skip(')'); |
| @@ -2973,8 +2973,8 @@ static void struct_decl(CType *type, int u, int tdef) · 189 unmodified lines | |||
| 2973 | while (tok != '}') { | 2973 | while (tok != '}') { |
| 2974 | parse_btype(&btype, &ad); | 2974 | parse_btype(&btype, &ad); |
| 2975 | while (1) { | 2975 | while (1) { |
| 2976 | if (flexible) | 2976 | if (flexible) |
| 2977 | tcc_error("flexible array member '%s' not at the end of struct", | 2977 | tcc_error("flexible array member '%s' not at the end of struct", |
| 2978 | get_tok_str(v, NULL)); | 2978 | get_tok_str(v, NULL)); |
| 2979 | bit_size = -1; | 2979 | bit_size = -1; |
| 2980 | v = 0; | 2980 | v = 0; |
| @@ -2982,21 +2982,21 @@ static void struct_decl(CType *type, int u, int tdef) · 1 unmodified line | |||
| 2982 | if (tok != ':') { | 2982 | if (tok != ':') { |
| 2983 | type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT); | 2983 | type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT); |
| 2984 | if (v == 0) { | 2984 | if (v == 0) { |
| 2985 | if ((type1.t & VT_BTYPE) != VT_STRUCT) | 2985 | if ((type1.t & VT_BTYPE) != VT_STRUCT) |
| 2986 | expect("identifier"); | 2986 | expect("identifier"); |
| 2987 | else { | 2987 | else { |
| 2988 | int v = btype.ref->v; | 2988 | int v = btype.ref->v; |
| 2989 | if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { | 2989 | if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) { |
| 2990 | if (tcc_state->ms_extensions == 0) | 2990 | if (tcc_state->ms_extensions == 0) |
| 2991 | expect("identifier"); | 2991 | expect("identifier"); |
| 2992 | } | 2992 | } |
| 2993 | } | 2993 | } |
| 2994 | } | 2994 | } |
| 2995 | if (type_size(&type1, &align) < 0) { | 2995 | if (type_size(&type1, &align) < 0) { |
| 2996 | if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY) && c) | 2996 | if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY) && c) |
| 2997 | flexible = 1; | 2997 | flexible = 1; |
| 2998 | else | 2998 | else |
| 2999 | tcc_error("field '%s' has incomplete type", | 2999 | tcc_error("field '%s' has incomplete type", |
| 3000 | get_tok_str(v, NULL)); | 3000 | get_tok_str(v, NULL)); |
| 3001 | } | 3001 | } |
| 3002 | if ((type1.t & VT_BTYPE) == VT_FUNC || | 3002 | if ((type1.t & VT_BTYPE) == VT_FUNC || |
| @@ -3807,11 +3807,11 @@ ST_FUNC void unary(void) · 804 unmodified lines | |||
| 3807 | gen_cast(&type); | 3807 | gen_cast(&type); |
| 3808 | } | 3808 | } |
| 3809 | } else if (tok == '{') { | 3809 | } else if (tok == '{') { |
| 3810 | /* | 3810 | /* |
| 3811 | if (nocode_wanted) | 3811 | if (nocode_wanted) |
| 3812 | tcc_error("statement expression in global scope"); */ | 3812 | tcc_error("statement expression in global scope"); */ |
| 3813 | /* this check breaks compilation of the linux 2.4.26 with the meesage: | 3813 | /* this check breaks compilation of the linux 2.4.26 with the meesage: |
| 3814 | linux/include/net/tcp.h:945: error: statement expression in global scope */ | 3814 | linux/include/net/tcp.h:945: error: statement expression in global scope */ |
| 3815 | 3815 | ||
| 3816 | /* save all registers */ | 3816 | /* save all registers */ |
| 3817 | save_regs(0); | 3817 | save_regs(0); |
| @@ -3872,12 +3872,12 @@ ST_FUNC void unary(void) · 54 unmodified lines | |||
| 3872 | if ((vtop->type.t & VT_BTYPE) == VT_PTR) | 3872 | if ((vtop->type.t & VT_BTYPE) == VT_PTR) |
| 3873 | tcc_error("pointer not accepted for unary plus"); | 3873 | tcc_error("pointer not accepted for unary plus"); |
| 3874 | /* In order to force cast, we add zero, except for floating point | 3874 | /* In order to force cast, we add zero, except for floating point |
| 3875 | where we really need an noop (otherwise -0.0 will be transformed | 3875 | where we really need an noop (otherwise -0.0 will be transformed |
| 3876 | into +0.0). */ | 3876 | into +0.0). */ |
| 3877 | if (!is_float(vtop->type.t)) { | 3877 | if (!is_float(vtop->type.t)) { |
| 3878 | vpushi(0); | 3878 | vpushi(0); |
| 3879 | gen_op('+'); | 3879 | gen_op('+'); |
| 3880 | } | 3880 | } |
| 3881 | break; | 3881 | break; |
| 3882 | case TOK_SIZEOF: | 3882 | case TOK_SIZEOF: |
| 3883 | case TOK_ALIGNOF1: | 3883 | case TOK_ALIGNOF1: |
| @@ -4050,20 +4050,20 @@ ST_FUNC void unary(void) · 166 unmodified lines | |||
| 4050 | next(); | 4050 | next(); |
| 4051 | unary(); | 4051 | unary(); |
| 4052 | t = vtop->type.t & VT_BTYPE; | 4052 | t = vtop->type.t & VT_BTYPE; |
| 4053 | if (is_float(t)) { | 4053 | if (is_float(t)) { |
| 4054 | /* In IEEE negate(x) isn't subtract(0,x), but rather | 4054 | /* In IEEE negate(x) isn't subtract(0,x), but rather |
| 4055 | subtract(-0, x). */ | 4055 | subtract(-0, x). */ |
| 4056 | vpush(&vtop->type); | 4056 | vpush(&vtop->type); |
| 4057 | if (t == VT_FLOAT) | 4057 | if (t == VT_FLOAT) |
| 4058 | vtop->c.f = -0.0f; | 4058 | vtop->c.f = -0.0f; |
| 4059 | else if (t == VT_DOUBLE) | 4059 | else if (t == VT_DOUBLE) |
| 4060 | vtop->c.d = -0.0; | 4060 | vtop->c.d = -0.0; |
| 4061 | else | 4061 | else |
| 4062 | vtop->c.ld = -0.0; | 4062 | vtop->c.ld = -0.0; |
| 4063 | } else | 4063 | } else |
| 4064 | vpushi(0); | 4064 | vpushi(0); |
| 4065 | vswap(); | 4065 | vswap(); |
| 4066 | gen_op('-'); | 4066 | gen_op('-'); |
| 4067 | break; | 4067 | break; |
| 4068 | case TOK_LAND: | 4068 | case TOK_LAND: |
| 4069 | if (!gnu_ext) | 4069 | if (!gnu_ext) |
| @@ -4142,7 +4142,7 @@ ST_FUNC void unary(void) · 72 unmodified lines | |||
| 4142 | /* if forward reference, we must point to s */ | 4142 | /* if forward reference, we must point to s */ |
| 4143 | if (vtop->r & VT_SYM) { | 4143 | if (vtop->r & VT_SYM) { |
| 4144 | vtop->sym = s; | 4144 | vtop->sym = s; |
| 4145 | vtop->c.ptr_offset = 0; | 4145 | vtop->c.ptr_offset = 0; |
| 4146 | } | 4146 | } |
| 4147 | break; | 4147 | break; |
| 4148 | } | 4148 | } |
| @@ -4312,10 +4312,10 @@ ST_FUNC void unary(void) · 163 unmodified lines | |||
| 4312 | 4312 | ||
| 4313 | 4313 | ||
| 4314 | size = type_size(&s->type, &align); | 4314 | size = type_size(&s->type, &align); |
| 4315 | /* We're writing whole regs often, make sure there's enough | 4315 | /* We're writing whole regs often, make sure there's enough |
| 4316 | space. Assume register size is power of 2. */ | 4316 | space. Assume register size is power of 2. */ |
| 4317 | if (regsize > align) | 4317 | if (regsize > align) |
| 4318 | align = regsize; | 4318 | align = regsize; |
| 4319 | loc = (loc - size) & -align; | 4319 | loc = (loc - size) & -align; |
| 4320 | addr = loc; | 4320 | addr = loc; |
| 4321 | #if defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_PE) | 4321 | #if defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_PE) |
| @@ -4610,16 +4610,16 @@ static void expr_cond(void) · 288 unmodified lines | |||
| 4610 | (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED)) | 4610 | (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED)) |
| 4611 | type.t |= VT_UNSIGNED; | 4611 | type.t |= VT_UNSIGNED; |
| 4612 | } else if (bt1 == VT_PTR || bt2 == VT_PTR) { | 4612 | } else if (bt1 == VT_PTR || bt2 == VT_PTR) { |
| 4613 | /* If one is a null ptr constant the result type | 4613 | /* If one is a null ptr constant the result type |
| 4614 | is the other. */ | 4614 | is the other. */ |
| 4615 | if (is_null_pointer (vtop)) | 4615 | if (is_null_pointer (vtop)) |
| 4616 | type = type1; | 4616 | type = type1; |
| 4617 | else if (is_null_pointer (&sv)) | 4617 | else if (is_null_pointer (&sv)) |
| 4618 | type = type2; | 4618 | type = type2; |
| 4619 | /* XXX: test pointer compatibility, C99 has more elaborate | 4619 | /* XXX: test pointer compatibility, C99 has more elaborate |
| 4620 | rules here. */ | 4620 | rules here. */ |
| 4621 | else | 4621 | else |
| 4622 | type = type1; | 4622 | type = type1; |
| 4623 | } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) { | 4623 | } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) { |
| 4624 | /* XXX: test function pointer compatibility */ | 4624 | /* XXX: test function pointer compatibility */ |
| 4625 | type = bt1 == VT_FUNC ? type1 : type2; | 4625 | type = bt1 == VT_FUNC ? type1 : type2; |
| @@ -4785,14 +4785,14 @@ static void label_or_decl(int l) · 159 unmodified lines | |||
| 4785 | /* fast test first */ | 4785 | /* fast test first */ |
| 4786 | if (tok >= TOK_UIDENT) | 4786 | if (tok >= TOK_UIDENT) |
| 4787 | { | 4787 | { |
| 4788 | /* no need to save tokc because tok is an identifier */ | 4788 | /* no need to save tokc because tok is an identifier */ |
| 4789 | last_tok = tok; | 4789 | last_tok = tok; |
| 4790 | next(); | 4790 | next(); |
| 4791 | if (tok == ':') { | 4791 | if (tok == ':') { |
| 4792 | unget_tok(last_tok); | 4792 | unget_tok(last_tok); |
| 4793 | return; | 4793 | return; |
| 4794 | } | 4794 | } |
| 4795 | unget_tok(last_tok); | 4795 | unget_tok(last_tok); |
| 4796 | } | 4796 | } |
| 4797 | decl(l); | 4797 | decl(l); |
| 4798 | } | 4798 | } |
| @@ -4891,10 +4891,10 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, · 92 unmodified lines | |||
| 4891 | Sym *p; | 4891 | Sym *p; |
| 4892 | switch(vtop->type.t & VT_BTYPE) { | 4892 | switch(vtop->type.t & VT_BTYPE) { |
| 4893 | /* case VT_PTR: */ | 4893 | /* case VT_PTR: */ |
| 4894 | /* this breaks a compilation of the linux kernel v2.4.26 */ | 4894 | /* this breaks a compilation of the linux kernel v2.4.26 */ |
| 4895 | /* pmd_t *new = ({ __asm__ __volatile__("ud2\n") ; ((pmd_t *)1); }); */ | 4895 | /* pmd_t *new = ({ __asm__ __volatile__("ud2\n") ; ((pmd_t *)1); }); */ |
| 4896 | /* Look a commit a80acab: Display error on statement expressions with complex return type */ | 4896 | /* Look a commit a80acab: Display error on statement expressions with complex return type */ |
| 4897 | /* A pointer is not a complex return type */ | 4897 | /* A pointer is not a complex return type */ |
| 4898 | case VT_STRUCT: | 4898 | case VT_STRUCT: |
| 4899 | case VT_ENUM: | 4899 | case VT_ENUM: |
| 4900 | case VT_FUNC: | 4900 | case VT_FUNC: |
| @@ -5642,38 +5642,38 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 741 unmodified lines | |||
| 5642 | AttributeDef ad1; | 5642 | AttributeDef ad1; |
| 5643 | CType type1; | 5643 | CType type1; |
| 5644 | next(); | 5644 | next(); |
| 5645 | if (tcc_state->old_struct_init_code) { | 5645 | if (tcc_state->old_struct_init_code) { |
| 5646 | /* an old version of struct initialization. | 5646 | /* an old version of struct initialization. |
| 5647 | It have a problems. But with a new version | 5647 | It have a problems. But with a new version |
| 5648 | linux 2.4.26 can't load ramdisk. | 5648 | linux 2.4.26 can't load ramdisk. |
| 5649 | */ | 5649 | */ |
| 5650 | while (tok == '(') { | 5650 | while (tok == '(') { |
| 5651 | par_count++; | 5651 | par_count++; |
| 5652 | next(); | 5652 | next(); |
| 5653 | } | 5653 | } |
| 5654 | if (!parse_btype(&type1, &ad1)) | 5654 | if (!parse_btype(&type1, &ad1)) |
| 5655 | expect("cast"); | 5655 | expect("cast"); |
| 5656 | type_decl(&type1, &ad1, &n, TYPE_ABSTRACT); | 5656 | type_decl(&type1, &ad1, &n, TYPE_ABSTRACT); |
| 5657 | #if 0 | 5657 | #if 0 |
| 5658 | if (!is_assignable_types(type, &type1)) | 5658 | if (!is_assignable_types(type, &type1)) |
| 5659 | tcc_error("invalid type for cast"); | 5659 | tcc_error("invalid type for cast"); |
| 5660 | #endif | 5660 | #endif |
| 5661 | skip(')'); | 5661 | skip(')'); |
| 5662 | } | 5662 | } |
| 5663 | else | 5663 | else |
| 5664 | { | 5664 | { |
| 5665 | if (tok != '(') { | 5665 | if (tok != '(') { |
| 5666 | if (!parse_btype(&type1, &ad1)) | 5666 | if (!parse_btype(&type1, &ad1)) |
| 5667 | expect("cast"); | 5667 | expect("cast"); |
| 5668 | type_decl(&type1, &ad1, &n, TYPE_ABSTRACT); | 5668 | type_decl(&type1, &ad1, &n, TYPE_ABSTRACT); |
| 5669 | #if 0 | 5669 | #if 0 |
| 5670 | if (!is_assignable_types(type, &type1)) | 5670 | if (!is_assignable_types(type, &type1)) |
| 5671 | tcc_error("invalid type for cast"); | 5671 | tcc_error("invalid type for cast"); |
| 5672 | #endif | 5672 | #endif |
| 5673 | skip(')'); | 5673 | skip(')'); |
| 5674 | } else | 5674 | } else |
| 5675 | unget_tok(tok); | 5675 | unget_tok(tok); |
| 5676 | } | 5676 | } |
| 5677 | } | 5677 | } |
| 5678 | 5678 | ||
| 5679 | no_oblock = 1; | 5679 | no_oblock = 1; |
| @@ -5699,28 +5699,28 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 19 unmodified lines | |||
| 5699 | 5699 | ||
| 5700 | /* gr: skip fields from same union - ugly. */ | 5700 | /* gr: skip fields from same union - ugly. */ |
| 5701 | while (f->next) { | 5701 | while (f->next) { |
| 5702 | int align = 0; | 5702 | int align = 0; |
| 5703 | int f_size = type_size(&f->type, &align); | 5703 | int f_size = type_size(&f->type, &align); |
| 5704 | int f_type = (f->type.t & VT_BTYPE); | 5704 | int f_type = (f->type.t & VT_BTYPE); |
| 5705 | 5705 | ||
| 5706 | ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t); | 5706 | ///printf("index: %2d %08x -- %2d %08x\n", f->c, f->type.t, f->next->c, f->next->type.t); |
| 5707 | /* test for same offset */ | 5707 | /* test for same offset */ |
| 5708 | if (f->next->c != f->c) | 5708 | if (f->next->c != f->c) |
| 5709 | break; | 5709 | break; |
| 5710 | if ((f_type == VT_STRUCT) && (f_size == 0)) { | 5710 | if ((f_type == VT_STRUCT) && (f_size == 0)) { |
| 5711 | /* | 5711 | /* |
| 5712 | Lets assume a structure of size 0 can't be a member of the union. | 5712 | Lets assume a structure of size 0 can't be a member of the union. |
| 5713 | This allow to compile the following code from a linux kernel v2.4.26 | 5713 | This allow to compile the following code from a linux kernel v2.4.26 |
| 5714 | typedef struct { } rwlock_t; | 5714 | typedef struct { } rwlock_t; |
| 5715 | struct fs_struct { | 5715 | struct fs_struct { |
| 5716 | int count; | 5716 | int count; |
| 5717 | rwlock_t lock; | 5717 | rwlock_t lock; |
| 5718 | int umask; | 5718 | int umask; |
| 5719 | }; | 5719 | }; |
| 5720 | struct fs_struct init_fs = { { (1) }, (rwlock_t) {}, 0022, }; | 5720 | struct fs_struct init_fs = { { (1) }, (rwlock_t) {}, 0022, }; |
| 5721 | tcc-0.9.23 can succesfully compile this version of the kernel. | 5721 | tcc-0.9.23 can succesfully compile this version of the kernel. |
| 5722 | gcc don't have problems with this code too. | 5722 | gcc don't have problems with this code too. |
| 5723 | */ | 5723 | */ |
| 5724 | break; | 5724 | break; |
| 5725 | } | 5725 | } |
| 5726 | /* if yes, test for bitfield shift */ | 5726 | /* if yes, test for bitfield shift */ |
| @@ -5760,21 +5760,21 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 33 unmodified lines | |||
| 5760 | /* just skip expression */ | 5760 | /* just skip expression */ |
| 5761 | parlevel = parlevel1 = 0; | 5761 | parlevel = parlevel1 = 0; |
| 5762 | while ((parlevel > 0 || parlevel1 > 0 || | 5762 | while ((parlevel > 0 || parlevel1 > 0 || |
| 5763 | (tok != '}' && tok != ',')) && tok != -1) { | 5763 | (tok != '}' && tok != ',')) && tok != -1) { |
| 5764 | if (tok == '(') | 5764 | if (tok == '(') |
| 5765 | parlevel++; | 5765 | parlevel++; |
| 5766 | else if (tok == ')') { | 5766 | else if (tok == ')') { |
| 5767 | if (parlevel == 0 && parlevel1 == 0) | 5767 | if (parlevel == 0 && parlevel1 == 0) |
| 5768 | break; | 5768 | break; |
| 5769 | parlevel--; | 5769 | parlevel--; |
| 5770 | } | 5770 | } |
| 5771 | else if (tok == '{') | 5771 | else if (tok == '{') |
| 5772 | parlevel1++; | 5772 | parlevel1++; |
| 5773 | else if (tok == '}') { | 5773 | else if (tok == '}') { |
| 5774 | if (parlevel == 0 && parlevel1 == 0) | 5774 | if (parlevel == 0 && parlevel1 == 0) |
| 5775 | break; | 5775 | break; |
| 5776 | parlevel1--; | 5776 | parlevel1--; |
| 5777 | } | 5777 | } |
| 5778 | next(); | 5778 | next(); |
| 5779 | } | 5779 | } |
| 5780 | } else { | 5780 | } else { |
| @@ -5995,12 +5995,12 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 214 unmodified lines | |||
| 5995 | } else { | 5995 | } else { |
| 5996 | /* push global reference */ | 5996 | /* push global reference */ |
| 5997 | sym = get_sym_ref(type, sec, addr, size); | 5997 | sym = get_sym_ref(type, sec, addr, size); |
| 5998 | vpushsym(type, sym); | 5998 | vpushsym(type, sym); |
| 5999 | } | 5999 | } |
| 6000 | /* patch symbol weakness */ | 6000 | /* patch symbol weakness */ |
| 6001 | if (type->t & VT_WEAK) | 6001 | if (type->t & VT_WEAK) |
| 6002 | weaken_symbol(sym); | 6002 | weaken_symbol(sym); |
| 6003 | apply_visibility(sym, type); | 6003 | apply_visibility(sym, type); |
| 6004 | #ifdef CONFIG_TCC_BCHECK | 6004 | #ifdef CONFIG_TCC_BCHECK |
| 6005 | /* handles bounds now because the symbol must be defined | 6005 | /* handles bounds now because the symbol must be defined |
| 6006 | before for the relocation */ | 6006 | before for the relocation */ |
| @@ -6236,11 +6236,11 @@ static int decl0(int l, int is_for_loop_init) · 229 unmodified lines | |||
| 6236 | if (((btype.t & VT_BTYPE) == VT_ENUM || | 6236 | if (((btype.t & VT_BTYPE) == VT_ENUM || |
| 6237 | (btype.t & VT_BTYPE) == VT_STRUCT) && | 6237 | (btype.t & VT_BTYPE) == VT_STRUCT) && |
| 6238 | tok == ';') { | 6238 | tok == ';') { |
| 6239 | if ((btype.t & VT_BTYPE) == VT_STRUCT) { | 6239 | if ((btype.t & VT_BTYPE) == VT_STRUCT) { |
| 6240 | int v = btype.ref->v; | 6240 | int v = btype.ref->v; |
| 6241 | if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM) | 6241 | if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM) |
| 6242 | tcc_warning("unnamed struct/union that defines no instances"); | 6242 | tcc_warning("unnamed struct/union that defines no instances"); |
| 6243 | } | 6243 | } |
| 6244 | next(); | 6244 | next(); |
| 6245 | continue; | 6245 | continue; |
| 6246 | } | 6246 | } |
| @@ -6286,7 +6286,7 @@ static int decl0(int l, int is_for_loop_init) · 39 unmodified lines | |||
| 6286 | if (ad.a.func_export) | 6286 | if (ad.a.func_export) |
| 6287 | type.t |= VT_EXPORT; | 6287 | type.t |= VT_EXPORT; |
| 6288 | #endif | 6288 | #endif |
| 6289 | type.t |= ad.a.visibility << VT_VIS_SHIFT; | 6289 | type.t |= ad.a.visibility << VT_VIS_SHIFT; |
| 6290 | 6290 | ||
| 6291 | if (tok == '{') { | 6291 | if (tok == '{') { |
| 6292 | if (l == VT_LOCAL) | 6292 | if (l == VT_LOCAL) |
| @@ -6327,10 +6327,10 @@ static int decl0(int l, int is_for_loop_init) · 34 unmodified lines | |||
| 6327 | if (sym->type.t & VT_STATIC) | 6327 | if (sym->type.t & VT_STATIC) |
| 6328 | type.t = (type.t & ~VT_EXTERN) | VT_STATIC; | 6328 | type.t = (type.t & ~VT_EXTERN) | VT_STATIC; |
| 6329 | 6329 | ||
| 6330 | /* If the definition has no visibility use the | 6330 | /* If the definition has no visibility use the |
| 6331 | one from prototype. */ | 6331 | one from prototype. */ |
| 6332 | if (! (type.t & VT_VIS_MASK)) | 6332 | if (! (type.t & VT_VIS_MASK)) |
| 6333 | type.t |= sym->type.t & VT_VIS_MASK; | 6333 | type.t |= sym->type.t & VT_VIS_MASK; |
| 6334 | 6334 | ||
| 6335 | if (!is_compatible_types(&sym->type, &type)) { | 6335 | if (!is_compatible_types(&sym->type, &type)) { |
| 6336 | func_error1: | 6336 | func_error1: |
| @@ -398,22 +398,22 @@ static int pe_find_import(TCCState * s1, ElfW(Sym) *sym) · 397 unmodified lines | |||
| 398 | s = pe_export_name(s1, sym); | 398 | s = pe_export_name(s1, sym); |
| 399 | if (n) { | 399 | if (n) { |
| 400 | /* second try: */ | 400 | /* second try: */ |
| 401 | if (sym->st_other & ST_PE_STDCALL) { | 401 | if (sym->st_other & ST_PE_STDCALL) { |
| 402 | /* try w/0 stdcall deco (windows API convention) */ | 402 | /* try w/0 stdcall deco (windows API convention) */ |
| 403 | p = strrchr(s, '@'); | 403 | p = strrchr(s, '@'); |
| 404 | if (!p || s[0] != '_') | 404 | if (!p || s[0] != '_') |
| 405 | break; | 405 | break; |
| 406 | strcpy(buffer, s+1)[p-s-1] = 0; | 406 | strcpy(buffer, s+1)[p-s-1] = 0; |
| 407 | } else if (s[0] != '_') { /* try non-ansi function */ | 407 | } else if (s[0] != '_') { /* try non-ansi function */ |
| 408 | buffer[0] = '_', strcpy(buffer + 1, s); | 408 | buffer[0] = '_', strcpy(buffer + 1, s); |
| 409 | } else if (0 == memcmp(s, "__imp__", 7)) { /* mingw 2.0 */ | 409 | } else if (0 == memcmp(s, "__imp__", 7)) { /* mingw 2.0 */ |
| 410 | strcpy(buffer, s + 6); | 410 | strcpy(buffer, s + 6); |
| 411 | } else if (0 == memcmp(s, "_imp___", 7)) { /* mingw 3.7 */ | 411 | } else if (0 == memcmp(s, "_imp___", 7)) { /* mingw 3.7 */ |
| 412 | strcpy(buffer, s + 6); | 412 | strcpy(buffer, s + 6); |
| 413 | } else { | 413 | } else { |
| 414 | break; | 414 | break; |
| 415 | } | 415 | } |
| 416 | s = buffer; | 416 | s = buffer; |
| 417 | } | 417 | } |
| 418 | sym_index = find_elf_sym(s1->dynsymtab_section, s); | 418 | sym_index = find_elf_sym(s1->dynsymtab_section, s); |
| 419 | // printf("find (%d) %d %s\n", n, sym_index, s); | 419 | // printf("find (%d) %d %s\n", n, sym_index, s); |
| @@ -565,9 +565,9 @@ static int pe_write(struct pe_info *pe) · 145 unmodified lines | |||
| 565 | #endif | 565 | #endif |
| 566 | /* NT additional fields. */ | 566 | /* NT additional fields. */ |
| 567 | #if defined(TCC_TARGET_ARM) | 567 | #if defined(TCC_TARGET_ARM) |
| 568 | 0x00100000, /*DWORD ImageBase; */ | 568 | 0x00100000, /*DWORD ImageBase; */ |
| 569 | #else | 569 | #else |
| 570 | 0x00400000, /*DWORD ImageBase; */ | 570 | 0x00400000, /*DWORD ImageBase; */ |
| 571 | #endif | 571 | #endif |
| 572 | 0x00001000, /*DWORD SectionAlignment; */ | 572 | 0x00001000, /*DWORD SectionAlignment; */ |
| 573 | 0x00000200, /*DWORD FileAlignment; */ | 573 | 0x00000200, /*DWORD FileAlignment; */ |
| @@ -1841,13 +1841,13 @@ ST_FUNC int pe_output_file(TCCState * s1, const char *filename) · 1267 unmodified lines | |||
| 1841 | pe.subsystem = s1->pe_subsystem; | 1841 | pe.subsystem = s1->pe_subsystem; |
| 1842 | 1842 | ||
| 1843 | /* set default file/section alignment */ | 1843 | /* set default file/section alignment */ |
| 1844 | if (pe.subsystem == 1) { | 1844 | if (pe.subsystem == 1) { |
| 1845 | pe.section_align = 0x20; | 1845 | pe.section_align = 0x20; |
| 1846 | pe.file_align = 0x20; | 1846 | pe.file_align = 0x20; |
| 1847 | } else { | 1847 | } else { |
| 1848 | pe.section_align = 0x1000; | 1848 | pe.section_align = 0x1000; |
| 1849 | pe.file_align = 0x200; | 1849 | pe.file_align = 0x200; |
| 1850 | } | 1850 | } |
| 1851 | 1851 | ||
| 1852 | if (s1->section_align != 0) | 1852 | if (s1->section_align != 0) |
| 1853 | pe.section_align = s1->section_align; | 1853 | pe.section_align = s1->section_align; |
| @@ -786,7 +786,7 @@ redo_start: · 785 unmodified lines | |||
| 786 | else if (tok == TOK_LINEFEED) | 786 | else if (tok == TOK_LINEFEED) |
| 787 | goto redo_start; | 787 | goto redo_start; |
| 788 | } else if (parse_flags & PARSE_FLAG_ASM_FILE) | 788 | } else if (parse_flags & PARSE_FLAG_ASM_FILE) |
| 789 | p = parse_line_comment(p); | 789 | p = parse_line_comment(p); |
| 790 | break; | 790 | break; |
| 791 | _default: | 791 | _default: |
| 792 | default: | 792 | default: |
| @@ -1786,7 +1786,7 @@ _line_num: · 993 unmodified lines | |||
| 1786 | total_lines += file->line_num - n; | 1786 | total_lines += file->line_num - n; |
| 1787 | file->line_num = n; | 1787 | file->line_num = n; |
| 1788 | if (s1->do_debug) | 1788 | if (s1->do_debug) |
| 1789 | put_stabs(file->filename, N_BINCL, 0, 0, 0); | 1789 | put_stabs(file->filename, N_BINCL, 0, 0, 0); |
| 1790 | break; | 1790 | break; |
| 1791 | case TOK_ERROR: | 1791 | case TOK_ERROR: |
| 1792 | case TOK_WARNING: | 1792 | case TOK_WARNING: |
| @@ -2272,7 +2272,7 @@ static void parse_number(const char *p) · 479 unmodified lines | |||
| 2272 | if (n & 0xffffffff00000000LL || must_64bit) { | 2272 | if (n & 0xffffffff00000000LL || must_64bit) { |
| 2273 | tok = TOK_CLLONG; | 2273 | tok = TOK_CLLONG; |
| 2274 | n1 = n >> 32; | 2274 | n1 = n >> 32; |
| 2275 | } else { | 2275 | } else { |
| 2276 | tok = TOK_CINT; | 2276 | tok = TOK_CINT; |
| 2277 | n1 = n; | 2277 | n1 = n; |
| 2278 | } | 2278 | } |
| @@ -2538,7 +2538,7 @@ maybe_newline: · 259 unmodified lines | |||
| 2538 | } else if (c == '.') { | 2538 | } else if (c == '.') { |
| 2539 | PEEKC(c, p); | 2539 | PEEKC(c, p); |
| 2540 | if (c != '.') | 2540 | if (c != '.') |
| 2541 | expect("'.'"); | 2541 | expect("'.'"); |
| 2542 | PEEKC(c, p); | 2542 | PEEKC(c, p); |
| 2543 | tok = TOK_DOTS; | 2543 | tok = TOK_DOTS; |
| 2544 | } else { | 2544 | } else { |
| @@ -127,7 +127,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 126 unmodified lines | |||
| 127 | for (i=0; i<argc; ++i) | 127 | for (i=0; i<argc; ++i) |
| 128 | bound_new_region(argv[i], strlen(argv[i])); | 128 | bound_new_region(argv[i], strlen(argv[i])); |
| 129 | 129 | ||
| 130 | errno = 0; /* clean errno value */ | 130 | errno = 0; /* clean errno value */ |
| 131 | ret = (*prog_main)(argc, argv); | 131 | ret = (*prog_main)(argc, argv); |
| 132 | 132 | ||
| 133 | /* unmark argv area */ | 133 | /* unmark argv area */ |
| @@ -139,7 +139,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 5 unmodified lines | |||
| 139 | } else | 139 | } else |
| 140 | #endif | 140 | #endif |
| 141 | { | 141 | { |
| 142 | errno = 0; /* clean errno value */ | 142 | errno = 0; /* clean errno value */ |
| 143 | ret = (*prog_main)(argc, argv); | 143 | ret = (*prog_main)(argc, argv); |
| 144 | } | 144 | } |
| 145 | return ret; | 145 | return ret; |
| @@ -652,7 +652,7 @@ static long __stdcall cpu_exception_handler(EXCEPTION_POINTERS *ex_info) · 506 unmodified lines | |||
| 652 | if (rt_bound_error_msg && *rt_bound_error_msg) | 652 | if (rt_bound_error_msg && *rt_bound_error_msg) |
| 653 | rt_error(uc, *rt_bound_error_msg); | 653 | rt_error(uc, *rt_bound_error_msg); |
| 654 | else | 654 | else |
| 655 | rt_error(uc, "access violation"); | 655 | rt_error(uc, "access violation"); |
| 656 | break; | 656 | break; |
| 657 | case EXCEPTION_STACK_OVERFLOW: | 657 | case EXCEPTION_STACK_OVERFLOW: |
| 658 | rt_error(uc, "stack overflow"); | 658 | rt_error(uc, "stack overflow"); |
| @@ -697,12 +697,12 @@ static int rt_get_caller_pc(addr_t *paddr, CONTEXT *uc, int level) · 38 unmodified lines | |||
| 697 | fp = uc->Ebp; | 697 | fp = uc->Ebp; |
| 698 | #endif | 698 | #endif |
| 699 | if (level > 0) { | 699 | if (level > 0) { |
| 700 | for(i=1;i<level;i++) { | 700 | for(i = 1; i < level; i++) { |
| 701 | /* XXX: check address validity with program info */ | 701 | /* XXX: check address validity with program info */ |
| 702 | if (fp <= 0x1000 || fp >= 0xc0000000) | 702 | if (fp <= 0x1000 || fp >= 0xc0000000) |
| 703 | return -1; | 703 | return -1; |
| 704 | fp = ((addr_t*)fp)[0]; | 704 | fp = ((addr_t*)fp)[0]; |
| 705 | } | 705 | } |
| 706 | pc = ((addr_t*)fp)[1]; | 706 | pc = ((addr_t*)fp)[1]; |
| 707 | } | 707 | } |
| 708 | *paddr = pc; | 708 | *paddr = pc; |
| @@ -477,18 +477,17 @@ void load(int r, SValue *sv) · 476 unmodified lines | |||
| 477 | gen_modrm(r, VT_LOCAL, sv->sym, fc); | 477 | gen_modrm(r, VT_LOCAL, sv->sym, fc); |
| 478 | } else if (v == VT_CMP) { | 478 | } else if (v == VT_CMP) { |
| 479 | orex(0,r,0,0); | 479 | orex(0,r,0,0); |
| 480 | if ((fc & ~0x100) != TOK_NE) | 480 | if ((fc & ~0x100) != TOK_NE) |
| 481 | oad(0xb8 + REG_VALUE(r), 0); /* mov $0, r */ | 481 | oad(0xb8 + REG_VALUE(r), 0); /* mov $0, r */ |
| 482 | else | 482 | else |
| 483 | oad(0xb8 + REG_VALUE(r), 1); /* mov $1, r */ | 483 | oad(0xb8 + REG_VALUE(r), 1); /* mov $1, r */ |
| 484 | if (fc & 0x100) | 484 | if (fc & 0x100) { |
| 485 | { | 485 | /* This was a float compare. If the parity bit is |
| 486 | /* This was a float compare. If the parity bit is | 486 | * set the result was unordered, meaning false for everything |
| 487 | set the result was unordered, meaning false for everything | 487 | * except TOK_NE, and true for TOK_NE. */ |
| 488 | except TOK_NE, and true for TOK_NE. */ | 488 | fc &= ~0x100; |
| 489 | fc &= ~0x100; | 489 | o(0x037a + (REX_BASE(r) << 8)); |
| 490 | o(0x037a + (REX_BASE(r) << 8)); | 490 | } |
| 491 | } | ||
| 492 | orex(0,r,0, 0x0f); /* setxx %br */ | 491 | orex(0,r,0, 0x0f); /* setxx %br */ |
| 493 | o(fc); | 492 | o(fc); |
| 494 | o(0xc0 + REG_VALUE(r)); | 493 | o(0xc0 + REG_VALUE(r)); |
| @@ -619,7 +618,7 @@ static void gcall_or_jmp(int is_jmp) · 124 unmodified lines | |||
| 619 | { | 618 | { |
| 620 | int r; | 619 | int r; |
| 621 | if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && | 620 | if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && |
| 622 | ((vtop->r & VT_SYM) || (vtop->c.ll-4) == (int)(vtop->c.ll-4))) { | 621 | ((vtop->r & VT_SYM) || (vtop->c.ll-4) == (int)(vtop->c.ll-4))) { |
| 623 | /* constant case */ | 622 | /* constant case */ |
| 624 | if (vtop->r & VT_SYM) { | 623 | if (vtop->r & VT_SYM) { |
| 625 | /* relocation case */ | 624 | /* relocation case */ |
| @@ -1705,7 +1704,7 @@ void gfunc_prolog(CType *func_type) · 1079 unmodified lines | |||
| 1705 | param_addr = addr; | 1704 | param_addr = addr; |
| 1706 | addr += size; | 1705 | addr += size; |
| 1707 | break; | 1706 | break; |
| 1708 | default: break; /* nothing to be done for x86_64_mode_none */ | 1707 | default: break; /* nothing to be done for x86_64_mode_none */ |
| 1709 | } | 1708 | } |
| 1710 | sym_push(sym->v & ~SYM_FIELD, type, | 1709 | sym_push(sym->v & ~SYM_FIELD, type, |
| 1711 | VT_LOCAL | VT_LVAL, param_addr); | 1710 | VT_LOCAL | VT_LVAL, param_addr); |
| @@ -1717,8 +1716,8 @@ void gfunc_prolog(CType *func_type) · 5 unmodified lines | |||
| 1717 | func_bound_offset = lbounds_section->data_offset; | 1716 | func_bound_offset = lbounds_section->data_offset; |
| 1718 | func_bound_ind = ind; | 1717 | func_bound_ind = ind; |
| 1719 | oad(0xb8, 0); /* lbound section pointer */ | 1718 | oad(0xb8, 0); /* lbound section pointer */ |
| 1720 | o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */ | 1719 | o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */ |
| 1721 | oad(0xb8, 0); /* call to function */ | 1720 | oad(0xb8, 0); /* call to function */ |
| 1722 | } | 1721 | } |
| 1723 | #endif | 1722 | #endif |
| 1724 | } | 1723 | } |
| @@ -1730,7 +1729,7 @@ void gfunc_epilog(void) · 5 unmodified lines | |||
| 1730 | 1729 | ||
| 1731 | #ifdef CONFIG_TCC_BCHECK | 1730 | #ifdef CONFIG_TCC_BCHECK |
| 1732 | if (tcc_state->do_bounds_check | 1731 | if (tcc_state->do_bounds_check |
| 1733 | && func_bound_offset != lbounds_section->data_offset) | 1732 | && func_bound_offset != lbounds_section->data_offset) |
| 1734 | { | 1733 | { |
| 1735 | addr_t saved_ind; | 1734 | addr_t saved_ind; |
| 1736 | addr_t *bounds_ptr; | 1735 | addr_t *bounds_ptr; |
| @@ -1754,7 +1753,7 @@ void gfunc_epilog(void) · 17 unmodified lines | |||
| 1754 | o(0x5250); /* save returned value, if any */ | 1753 | o(0x5250); /* save returned value, if any */ |
| 1755 | greloc(cur_text_section, sym_data, ind + 1, R_386_32); | 1754 | greloc(cur_text_section, sym_data, ind + 1, R_386_32); |
| 1756 | oad(0xb8, 0); /* mov xxx, %rax */ | 1755 | oad(0xb8, 0); /* mov xxx, %rax */ |
| 1757 | o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */ | 1756 | o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */ |
| 1758 | gen_static_call(TOK___bound_local_delete); | 1757 | gen_static_call(TOK___bound_local_delete); |
| 1759 | o(0x585a); /* restore returned value, if any */ | 1758 | o(0x585a); /* restore returned value, if any */ |
| 1760 | } | 1759 | } |
| @@ -1806,24 +1805,24 @@ int gtst(int inv, int t) · 45 unmodified lines | |||
| 1806 | v = vtop->r & VT_VALMASK; | 1805 | v = vtop->r & VT_VALMASK; |
| 1807 | if (v == VT_CMP) { | 1806 | if (v == VT_CMP) { |
| 1808 | /* fast case : can jump directly since flags are set */ | 1807 | /* fast case : can jump directly since flags are set */ |
| 1809 | if (vtop->c.i & 0x100) | 1808 | if (vtop->c.i & 0x100) |
| 1810 | { | 1809 | { |
| 1811 | /* This was a float compare. If the parity flag is set | 1810 | /* This was a float compare. If the parity flag is set |
| 1812 | the result was unordered. For anything except != this | 1811 | the result was unordered. For anything except != this |
| 1813 | means false and we don't jump (anding both conditions). | 1812 | means false and we don't jump (anding both conditions). |
| 1814 | For != this means true (oring both). | 1813 | For != this means true (oring both). |
| 1815 | Take care about inverting the test. We need to jump | 1814 | Take care about inverting the test. We need to jump |
| 1816 | to our target if the result was unordered and test wasn't NE, | 1815 | to our target if the result was unordered and test wasn't NE, |
| 1817 | otherwise if unordered we don't want to jump. */ | 1816 | otherwise if unordered we don't want to jump. */ |
| 1818 | vtop->c.i &= ~0x100; | 1817 | vtop->c.i &= ~0x100; |
| 1819 | if (!inv == (vtop->c.i != TOK_NE)) | 1818 | if (!inv == (vtop->c.i != TOK_NE)) |
| 1820 | o(0x067a); /* jp +6 */ | 1819 | o(0x067a); /* jp +6 */ |
| 1821 | else | 1820 | else |
| 1822 | { | 1821 | { |
| 1823 | g(0x0f); | 1822 | g(0x0f); |
| 1824 | t = psym(0x8a, t); /* jp t */ | 1823 | t = psym(0x8a, t); /* jp t */ |
| 1825 | } | 1824 | } |
| 1826 | } | 1825 | } |
| 1827 | g(0x0f); | 1826 | g(0x0f); |
| 1828 | t = psym((vtop->c.i - 16) ^ inv, t); | 1827 | t = psym((vtop->c.i - 16) ^ inv, t); |
| 1829 | } else if (v == VT_JMP || v == VT_JMPI) { | 1828 | } else if (v == VT_JMP || v == VT_JMPI) { |