tccgen.c: - When __FUNCTION__ is used and no code is generated use symbol len = 0. tccelf.c: - If library is present in verneed it should be in DT_NEEDED. - @plt symbols should have size 0 - set _GLOBAL_OFFSET_TABLE_ st_size correct - Remove version symbol if new value present reported by elflint: __FUNCTION__ problem: section [19] '.symtab': symbol 2134 (L.195) does not fit completely in referenced section [14] '.data.ro' DT_NEEDED problem: section [26] '.gnu.version_r': entry 2 references unknown dependency @plt symbols should have size 0: section [22] '.symtab': symbol 36557 (r_core_config_init@plt) does not fit completely in referenced section [14] '.plt' _GLOBAL_OFFSET_TABLE_ size: section [44] '.symtab': _GLOBAL_OFFSET_TABLE_ symbol size 4 does not match .got section size 736 Remove version symbol: section [25] '.gnu.version': symbol 86: version index 3 is for requested version This happened for example with bounds checking symbol malloc
Unified · Split
| @@ -547,7 +547,7 @@ LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx, · 546 unmodified lines | |||
| 547 | static void | 547 | static void |
| 548 | version_add (TCCState *s1) | 548 | version_add (TCCState *s1) |
| 549 | { | 549 | { |
| 550 | int i; | 550 | int i, j; |
| 551 | ElfW(Sym) *sym; | 551 | ElfW(Sym) *sym; |
| 552 | ElfW(Verneed) *vn = NULL; | 552 | ElfW(Verneed) *vn = NULL; |
| 553 | Section *symtab; | 553 | Section *symtab; |
| @@ -593,6 +593,14 @@ version_add (TCCState *s1) · 39 unmodified lines | |||
| 593 | ElfW(Vernaux) *vna = 0; | 593 | ElfW(Vernaux) *vna = 0; |
| 594 | if (sv->out_index < 1) | 594 | if (sv->out_index < 1) |
| 595 | continue; | 595 | continue; |
| 596 | /* If present in verneed it should be in DT_NEEDED */ | ||
| 597 | for (j = 0; j < s1->nb_loaded_dlls; j++) { | ||
| 598 | DLLReference *dllref = s1->loaded_dlls[j]; | ||
| 599 | if (!strcmp(sv->lib, dllref->name)) { | ||
| 600 | dllref->level = 0; | ||
| 601 | break; | ||
| 602 | } | ||
| 603 | } | ||
| 596 | vnofs = section_add(verneed_section, sizeof(*vn), 1); | 604 | vnofs = section_add(verneed_section, sizeof(*vn), 1); |
| 597 | vn = (ElfW(Verneed)*)(verneed_section->data + vnofs); | 605 | vn = (ElfW(Verneed)*)(verneed_section->data + vnofs); |
| 598 | vn->vn_version = 1; | 606 | vn->vn_version = 1; |
| @@ -1137,7 +1145,7 @@ static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type, · 538 unmodified lines | |||
| 1137 | len = sizeof plt_name - 5; | 1145 | len = sizeof plt_name - 5; |
| 1138 | memcpy(plt_name, name, len); | 1146 | memcpy(plt_name, name, len); |
| 1139 | strcpy(plt_name + len, "@plt"); | 1147 | strcpy(plt_name + len, "@plt"); |
| 1140 | attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size, | 1148 | attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, 0, |
| 1141 | ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name); | 1149 | ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name); |
| 1142 | } else { | 1150 | } else { |
| 1143 | attr->got_offset = got_offset; | 1151 | attr->got_offset = got_offset; |
| @@ -2526,6 +2534,14 @@ static Section *create_bsd_note_section(TCCState *s1, · 1382 unmodified lines | |||
| 2526 | } | 2534 | } |
| 2527 | #endif | 2535 | #endif |
| 2528 | 2536 | ||
| 2537 | static void elf_patch_global_offset_size(TCCState *s1, Section *s) | ||
| 2538 | { | ||
| 2539 | int sym_index; | ||
| 2540 | |||
| 2541 | if ((sym_index = find_elf_sym(s, "_GLOBAL_OFFSET_TABLE_"))) | ||
| 2542 | ((ElfW(Sym) *)s->data)[sym_index].st_size = s1->got->data_offset; | ||
| 2543 | } | ||
| 2544 | |||
| 2529 | /* Output an elf, coff or binary file */ | 2545 | /* Output an elf, coff or binary file */ |
| 2530 | /* XXX: suppress unneeded sections */ | 2546 | /* XXX: suppress unneeded sections */ |
| 2531 | static int elf_output_file(TCCState *s1, const char *filename) | 2547 | static int elf_output_file(TCCState *s1, const char *filename) |
| @@ -2589,7 +2605,8 @@ static int elf_output_file(TCCState *s1, const char *filename) · 57 unmodified lines | |||
| 2589 | dynamic->link = dynstr; | 2605 | dynamic->link = dynstr; |
| 2590 | dynamic->sh_entsize = sizeof(ElfW(Dyn)); | 2606 | dynamic->sh_entsize = sizeof(ElfW(Dyn)); |
| 2591 | 2607 | ||
| 2592 | build_got(s1); | 2608 | if (!s1->got) |
| 2609 | build_got(s1); | ||
| 2593 | 2610 | ||
| 2594 | if (file_type == TCC_OUTPUT_EXE) { | 2611 | if (file_type == TCC_OUTPUT_EXE) { |
| 2595 | bind_exe_dynsyms(s1); | 2612 | bind_exe_dynsyms(s1); |
| @@ -2602,6 +2619,8 @@ static int elf_output_file(TCCState *s1, const char *filename) · 6 unmodified lines | |||
| 2602 | } | 2619 | } |
| 2603 | } | 2620 | } |
| 2604 | build_got_entries(s1); | 2621 | build_got_entries(s1); |
| 2622 | elf_patch_global_offset_size(s1, symtab_section); | ||
| 2623 | elf_patch_global_offset_size(s1, s1->dynsym); | ||
| 2605 | version_add (s1); | 2624 | version_add (s1); |
| 2606 | } | 2625 | } |
| 2607 | 2626 | ||
| @@ -3065,6 +3084,14 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, · 457 unmodified lines | |||
| 3065 | sym->st_info, sym->st_other, | 3084 | sym->st_info, sym->st_other, |
| 3066 | sym->st_shndx, name); | 3085 | sym->st_shndx, name); |
| 3067 | old_to_new_syms[i] = sym_index; | 3086 | old_to_new_syms[i] = sym_index; |
| 3087 | #ifndef ELF_OBJ_ONLY | ||
| 3088 | /* Remove version symbol if new value present */ | ||
| 3089 | sym_index = find_elf_sym(s1->dynsymtab_section, name); | ||
| 3090 | if (sym_index && sym_index < nb_sym_to_version && | ||
| 3091 | sym->st_shndx != SHN_UNDEF && | ||
| 3092 | ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) | ||
| 3093 | sym_to_version[sym_index] = -1; | ||
| 3094 | #endif | ||
| 3068 | } | 3095 | } |
| 3069 | 3096 | ||
| 3070 | /* third pass to patch relocation entries */ | 3097 | /* third pass to patch relocation entries */ |
| @@ -5328,7 +5328,7 @@ ST_FUNC void unary(void) · 5327 unmodified lines | |||
| 5328 | type.t |= VT_ARRAY; | 5328 | type.t |= VT_ARRAY; |
| 5329 | type.ref->c = len; | 5329 | type.ref->c = len; |
| 5330 | sec = rodata_section; | 5330 | sec = rodata_section; |
| 5331 | vpush_ref(&type, sec, sec->data_offset, len); | 5331 | vpush_ref(&type, sec, sec->data_offset, NODATA_WANTED ? 0 : len); |
| 5332 | if (!NODATA_WANTED) | 5332 | if (!NODATA_WANTED) |
| 5333 | memcpy(section_ptr_add(sec, len), funcname, len); | 5333 | memcpy(section_ptr_add(sec, len), funcname, len); |
| 5334 | next(); | 5334 | next(); |