History

versym cleanup

get rid of some globals, in the first place. Also, for the PE target, ifdef out ELF executable creation.

grischka committed 6 years ago

Commit df349dd1 parent 4d297d39 files · +187 −168Browse files

Unified · Split

9 files
  1. arm-link.c +0 −3
  2. arm64-link.c +0 −3
  3. c67-link.c +0 −3
  4. i386-link.c +2 −11
  5. riscv64-link.c +0 −6
  6. tcc.h +19 −2
  7. tccelf.c +162 −129
  8. tccrun.c +2 −0
  9. x86_64-link.c +2 −11
arm-link.c+0−3
@@ -165,9 +165,6 @@ ST_FUNC void relocate_plt(TCCState *s1) · 164 unmodified lines
165 }165 }
166}166}
167 167
168void relocate_init(Section *sr) {}
169void relocate_fini(Section *sr) {}
170
171void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)168void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
172{169{
173 ElfW(Sym) *sym;170 ElfW(Sym) *sym;
arm64-link.c+0−3
@@ -152,9 +152,6 @@ ST_FUNC void relocate_plt(TCCState *s1) · 151 unmodified lines
152 }152 }
153}153}
154 154
155void relocate_init(Section *sr) {}
156void relocate_fini(Section *sr) {}
157
158void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)155void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
159{156{
160 int sym_index = ELFW(R_SYM)(rel->r_info);157 int sym_index = ELFW(R_SYM)(rel->r_info);
c67-link.c+0−3
@@ -95,9 +95,6 @@ ST_FUNC void relocate_plt(TCCState *s1) · 94 unmodified lines
95 }95 }
96}96}
97 97
98void relocate_init(Section *sr) {}
99void relocate_fini(Section *sr) {}
100
101void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)98void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
102{99{
103 switch(type) {100 switch(type) {
i386-link.c+2−11
@@ -22,6 +22,7 @@ · 21 unmodified lines
22 22
23#include "tcc.h"23#include "tcc.h"
24 24
25#ifndef ELF_OBJ_ONLY
25/* Returns 1 for a code relocation, 0 for a data relocation. For unknown26/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
26 relocations, returns -1. */27 relocations, returns -1. */
27int code_reloc (int reloc_type)28int code_reloc (int reloc_type)
@@ -152,17 +153,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 124 unmodified lines
152 }153 }
153 }154 }
154}155}
155 156#endif
156static ElfW_Rel *qrel; /* ptr to next reloc entry reused */
157
158void relocate_init(Section *sr)
159{
160 qrel = (ElfW_Rel *) sr->data;
161}
162
163void relocate_fini(Section *sr)
164{
165}
166 157
167void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)158void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
168{159{
riscv64-link.c+0−6
@@ -161,12 +161,6 @@ ST_FUNC void relocate_plt(TCCState *s1) · 160 unmodified lines
161 }161 }
162}162}
163 163
164void relocate_init(Section *sr) {}
165
166void relocate_fini(Section *sr)
167{
168}
169
170struct pcrel_hi {164struct pcrel_hi {
171 addr_t addr, val;165 addr_t addr, val;
172};166};
tcc.h+19−2
@@ -824,6 +824,9 @@ struct TCCState { · 823 unmodified lines
824 /* extra attributes (eg. GOT/PLT value) for symtab symbols */824 /* extra attributes (eg. GOT/PLT value) for symtab symbols */
825 struct sym_attr *sym_attrs;825 struct sym_attr *sym_attrs;
826 int nb_sym_attrs;826 int nb_sym_attrs;
827 /* ptr to next reloc entry reused */
828 ElfW_Rel *qrel;
829# define qrel s1->qrel
827 830
828#ifdef TCC_TARGET_PE831#ifdef TCC_TARGET_PE
829 /* PE info */832 /* PE info */
@@ -837,6 +840,17 @@ struct TCCState { · 7 unmodified lines
837 int uw_sym;840 int uw_sym;
838 unsigned uw_offs;841 unsigned uw_offs;
839# endif842# endif
843# define ELF_OBJ_ONLY
844#endif
845
846#ifndef ELF_OBJ_ONLY
847 int nb_sym_versions;
848 struct sym_version *sym_versions;
849 int nb_sym_to_version;
850 int *sym_to_version;
851 int dt_verneednum;
852 Section *versym_section;
853 Section *verneed_section;
840#endif854#endif
841 855
842#ifdef TCC_IS_NATIVE856#ifdef TCC_IS_NATIVE
@@ -1475,7 +1489,9 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset · 632 unmodified lines
1475ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte);1489ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte);
1476ST_FUNC void tcc_add_runtime(TCCState *s1);1490ST_FUNC void tcc_add_runtime(TCCState *s1);
1477 1491
1492#ifndef ELF_OBJ_ONLY
1478ST_FUNC void build_got_entries(TCCState *s1);1493ST_FUNC void build_got_entries(TCCState *s1);
1494#endif
1479ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc);1495ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc);
1480ST_FUNC void squeeze_multi_relocs(Section *sec, size_t oldrelocoffset);1496ST_FUNC void squeeze_multi_relocs(Section *sec, size_t oldrelocoffset);
1481 1497
@@ -1506,12 +1522,13 @@ enum gotplt_entry { · 24 unmodified lines
1506 ALWAYS_GOTPLT_ENTRY /* always generate (eg. PLTOFF relocs) */1522 ALWAYS_GOTPLT_ENTRY /* always generate (eg. PLTOFF relocs) */
1507};1523};
1508 1524
1525#ifndef ELF_OBJ_ONLY
1509ST_FUNC int code_reloc (int reloc_type);1526ST_FUNC int code_reloc (int reloc_type);
1510ST_FUNC int gotplt_entry_type (int reloc_type);1527ST_FUNC int gotplt_entry_type (int reloc_type);
1511ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr);1528ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr);
1512ST_FUNC void relocate_init(Section *sr);
1513ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val);
1514ST_FUNC void relocate_plt(TCCState *s1);1529ST_FUNC void relocate_plt(TCCState *s1);
1530#endif
1531ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val);
1515 1532
1516/* ------------ xxx-gen.c ------------ */1533/* ------------ xxx-gen.c ------------ */
1517 1534
tccelf.c+162−129
@@ -49,13 +49,14 @@ struct sym_version { · 48 unmodified lines
49 int out_index;49 int out_index;
50 int prev_same_lib;50 int prev_same_lib;
51};51};
52static int nb_sym_versions;52
53static struct sym_version *sym_versions;53#define nb_sym_versions s1->nb_sym_versions
54static int nb_sym_to_version;54#define sym_versions s1->sym_versions
55static int *sym_to_version;55#define nb_sym_to_version s1->nb_sym_to_version
56static int dt_verneednum;56#define sym_to_version s1->sym_to_version
57static Section *versym_section;57#define dt_verneednum s1->dt_verneednum
58static Section *verneed_section;58#define versym_section s1->versym_section
59#define verneed_section s1->verneed_section
59 60
60/* XXX: avoid static variable */61/* XXX: avoid static variable */
61static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */62static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */
@@ -76,9 +77,6 @@ ST_FUNC void tccelf_new(TCCState *s) · 14 unmodified lines
76 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);77 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
77 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);78 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
78 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);79 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
79 versym_section = new_section(s, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
80 versym_section->sh_entsize = sizeof(ElfW(Half));
81 verneed_section = new_section(s, ".gnu.version_r", SHT_GNU_verneed, SHF_ALLOC);
82 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);80 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
83 common_section->sh_num = SHN_COMMON;81 common_section->sh_num = SHN_COMMON;
84 82
@@ -126,17 +124,15 @@ ST_FUNC void tccelf_delete(TCCState *s1) · 41 unmodified lines
126{124{
127 int i;125 int i;
128 126
127#ifndef ELF_OBJ_ONLY
129 /* free symbol versions */128 /* free symbol versions */
130 for (i = 0; i < nb_sym_versions; i++) {129 for (i = 0; i < nb_sym_versions; i++) {
131 tcc_free(sym_versions[i].version);130 tcc_free(sym_versions[i].version);
132 tcc_free(sym_versions[i].lib);131 tcc_free(sym_versions[i].lib);
133 }132 }
134 tcc_free(sym_versions);133 tcc_free(sym_versions);
135 sym_versions = NULL;
136 nb_sym_versions = 0;
137 tcc_free(sym_to_version);134 tcc_free(sym_to_version);
138 sym_to_version = NULL;135#endif
139 nb_sym_to_version = 0;
140 136
141 /* free all sections */137 /* free all sections */
142 for(i = 1; i < s1->nb_sections; i++)138 for(i = 1; i < s1->nb_sections; i++)
@@ -556,6 +552,7 @@ ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name) · 413 unmodified lines
556}552}
557#endif553#endif
558 554
555#ifndef ELF_OBJ_ONLY
559static void556static void
560version_add (TCCState *s)557version_add (TCCState *s)
561{558{
@@ -566,6 +563,15 @@ version_add (TCCState *s) · 4 unmodified lines
566 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;563 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
567 ElfW(Half) *versym;564 ElfW(Half) *versym;
568 const char *name;565 const char *name;
566 TCCState *s1 = s;
567
568 if (0 == nb_sym_versions)
569 return;
570 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
571 versym_section->sh_entsize = sizeof(ElfW(Half));
572 verneed_section = new_section(s1, ".gnu.version_r", SHT_GNU_verneed, SHF_ALLOC);
573 versym_section->link = s1->dynsym;
574 verneed_section->link = s1->dynsym->link;
569 575
570 /* add needed symbols */576 /* add needed symbols */
571 symtab = s->dynsym;577 symtab = s->dynsym;
@@ -590,7 +596,7 @@ version_add (TCCState *s) · 18 unmodified lines
590 struct sym_version *sv = &sym_versions[i];596 struct sym_version *sv = &sym_versions[i];
591 int n_same_libs = 0, prev;597 int n_same_libs = 0, prev;
592 size_t vnofs;598 size_t vnofs;
593 ElfW(Vernaux) *vna = vna;599 ElfW(Vernaux) *vna = 0;
594 if (sv->out_index < 1)600 if (sv->out_index < 1)
595 continue;601 continue;
596 vnofs = section_add(verneed_section, sizeof(*vn), 1);602 vnofs = section_add(verneed_section, sizeof(*vn), 1);
@@ -623,6 +629,7 @@ version_add (TCCState *s) · 26 unmodified lines
623 verneed_section->sh_info = nb_entries;629 verneed_section->sh_info = nb_entries;
624 dt_verneednum = nb_entries;630 dt_verneednum = nb_entries;
625}631}
632#endif
626 633
627/* add an elf symbol : check if it is already defined and patch634/* add an elf symbol : check if it is already defined and patch
628 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */635 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
@@ -970,7 +977,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 341 unmodified lines
970 unsigned char *ptr;977 unsigned char *ptr;
971 addr_t tgt, addr;978 addr_t tgt, addr;
972 979
973 relocate_init(sr);980 qrel = (ElfW_Rel *)sr->data;
974 981
975 for_each_elem(sr, 0, rel, ElfW_Rel) {982 for_each_elem(sr, 0, rel, ElfW_Rel) {
976 ptr = s->data + rel->r_offset;983 ptr = s->data + rel->r_offset;
@@ -989,6 +996,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) · 12 unmodified lines
989 sr->link = s1->dynsym;996 sr->link = s1->dynsym;
990}997}
991 998
999#ifndef ELF_OBJ_ONLY
992/* relocate relocation table in 'sr' */1000/* relocate relocation table in 'sr' */
993static void relocate_rel(TCCState *s1, Section *sr)1001static void relocate_rel(TCCState *s1, Section *sr)
994{1002{
@@ -1255,6 +1263,7 @@ static void put_dt(Section *dynamic, int dt, addr_t val) · 260 unmodified lines
1255 dyn->d_tag = dt;1263 dyn->d_tag = dt;
1256 dyn->d_un.d_val = val;1264 dyn->d_un.d_val = val;
1257}1265}
1266#endif
1258 1267
1259static void add_init_array_defines(TCCState *s1, const char *section_name)1268static void add_init_array_defines(TCCState *s1, const char *section_name)
1260{1269{
@@ -1459,6 +1468,7 @@ static void tcc_output_binary(TCCState *s1, FILE *f, · 198 unmodified lines
1459 }1468 }
1460}1469}
1461 1470
1471#ifndef ELF_OBJ_ONLY
1462ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)1472ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1463{1473{
1464 int sym_index = ELFW(R_SYM) (rel->r_info);1474 int sym_index = ELFW(R_SYM) (rel->r_info);
@@ -1661,6 +1671,7 @@ static void export_global_syms(TCCState *s1) · 196 unmodified lines
1661 }1671 }
1662 }1672 }
1663}1673}
1674#endif
1664 1675
1665/* Allocate strings for section names and decide if an unallocated section1676/* Allocate strings for section names and decide if an unallocated section
1666 should be output.1677 should be output.
@@ -1676,6 +1687,7 @@ static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec) · 9 unmodified lines
1676 s = s1->sections[i];1687 s = s1->sections[i];
1677 /* when generating a DLL, we include relocations but we may1688 /* when generating a DLL, we include relocations but we may
1678 patch them */1689 patch them */
1690#ifndef ELF_OBJ_ONLY
1679 if (file_type == TCC_OUTPUT_DLL &&1691 if (file_type == TCC_OUTPUT_DLL &&
1680 s->sh_type == SHT_RELX &&1692 s->sh_type == SHT_RELX &&
1681 !(s->sh_flags & SHF_ALLOC) &&1693 !(s->sh_flags & SHF_ALLOC) &&
@@ -1683,7 +1695,9 @@ static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec) · 1 unmodified line
1683 prepare_dynamic_rel(s1, s)) {1695 prepare_dynamic_rel(s1, s)) {
1684 if (s1->sections[s->sh_info]->sh_flags & SHF_EXECINSTR)1696 if (s1->sections[s->sh_info]->sh_flags & SHF_EXECINSTR)
1685 textrel = 1;1697 textrel = 1;
1686 } else if ((s1->do_debug && s->sh_type != SHT_RELX) ||1698 } else
1699#endif
1700 if ((s1->do_debug && s->sh_type != SHT_RELX) ||
1687 file_type == TCC_OUTPUT_OBJ ||1701 file_type == TCC_OUTPUT_OBJ ||
1688 (s->sh_flags & SHF_ALLOC) ||1702 (s->sh_flags & SHF_ALLOC) ||
1689 i == (s1->nb_sections - 1)) {1703 i == (s1->nb_sections - 1)) {
@@ -1890,6 +1904,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum, · 200 unmodified lines
1890 return file_offset;1904 return file_offset;
1891}1905}
1892 1906
1907#ifndef ELF_OBJ_ONLY
1893static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,1908static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1894 Section *dynamic)1909 Section *dynamic)
1895{1910{
@@ -1964,9 +1979,11 @@ static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf) · 68 unmodified lines
1964 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));1979 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1965#endif1980#endif
1966#endif1981#endif
1967 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);1982 if (versym_section) {
1968 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);1983 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
1969 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);1984 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
1985 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
1986 }
1970 s = find_section_create (s1, ".preinit_array", 0);1987 s = find_section_create (s1, ".preinit_array", 0);
1971 if (s && s->data_offset) {1988 if (s && s->data_offset) {
1972 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);1989 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
@@ -2026,6 +2043,7 @@ static int final_sections_reloc(TCCState *s1) · 53 unmodified lines
2026 }2043 }
2027 return 0;2044 return 0;
2028}2045}
2046#endif
2029 2047
2030/* Create an ELF file on disk.2048/* Create an ELF file on disk.
2031 This function handle ELF specific layout requirements */2049 This function handle ELF specific layout requirements */
@@ -2183,6 +2201,7 @@ static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum, · 151 unmodified lines
2183 return 0;2201 return 0;
2184}2202}
2185 2203
2204#ifndef ELF_OBJ_ONLY
2186/* Sort section headers by assigned sh_addr, remove sections2205/* Sort section headers by assigned sh_addr, remove sections
2187 that we aren't going to output. */2206 that we aren't going to output. */
2188static void tidy_section_headers(TCCState *s1, int *sec_order)2207static void tidy_section_headers(TCCState *s1, int *sec_order)
@@ -2228,17 +2247,16 @@ static void tidy_section_headers(TCCState *s1, int *sec_order) · 39 unmodified lines
2228 s1->nb_sections = nnew;2247 s1->nb_sections = nnew;
2229 tcc_free(backmap);2248 tcc_free(backmap);
2230}2249}
2250#endif
2231 2251
2232/* Output an elf, coff or binary file */2252/* Output an elf, coff or binary file */
2233/* XXX: suppress unneeded sections */2253/* XXX: suppress unneeded sections */
2234static int elf_output_file(TCCState *s1, const char *filename)2254static int elf_output_file(TCCState *s1, const char *filename)
2235{2255{
2236 int i, ret, phnum, shnum, file_type, file_offset, *sec_order;2256 int ret, phnum, shnum, file_type, file_offset, *sec_order;
2237 struct dyn_inf dyninf = {0};2257 struct dyn_inf dyninf = {0};
2238 ElfW(Phdr) *phdr;2258 ElfW(Phdr) *phdr;
2239 ElfW(Sym) *sym;
2240 Section *strsec, *interp, *dynamic, *dynstr;2259 Section *strsec, *interp, *dynamic, *dynstr;
2241 int textrel;
2242 2260
2243 file_type = s1->output_type;2261 file_type = s1->output_type;
2244 s1->nb_errors = 0;2262 s1->nb_errors = 0;
@@ -2246,8 +2264,8 @@ static int elf_output_file(TCCState *s1, const char *filename) · 1 unmodified line
2246 phdr = NULL;2264 phdr = NULL;
2247 sec_order = NULL;2265 sec_order = NULL;
2248 interp = dynamic = dynstr = NULL; /* avoid warning */2266 interp = dynamic = dynstr = NULL; /* avoid warning */
2249 textrel = 0;
2250 2267
2268#ifndef ELF_OBJ_ONLY
2251 if (file_type != TCC_OUTPUT_OBJ) {2269 if (file_type != TCC_OUTPUT_OBJ) {
2252 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */2270 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2253 tcc_add_runtime(s1);2271 tcc_add_runtime(s1);
@@ -2272,9 +2290,6 @@ static int elf_output_file(TCCState *s1, const char *filename) · 18 unmodified lines
2272 ".dynstr",2290 ".dynstr",
2273 ".hash", SHF_ALLOC);2291 ".hash", SHF_ALLOC);
2274 dynstr = s1->dynsym->link;2292 dynstr = s1->dynsym->link;
2275 versym_section->link = s1->dynsym;
2276 verneed_section->link = dynstr;
2277
2278 /* add dynamic section */2293 /* add dynamic section */
2279 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,2294 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2280 SHF_ALLOC | SHF_WRITE);2295 SHF_ALLOC | SHF_WRITE);
@@ -2296,15 +2311,18 @@ static int elf_output_file(TCCState *s1, const char *filename) · 15 unmodified lines
2296 build_got_entries(s1);2311 build_got_entries(s1);
2297 version_add (s1);2312 version_add (s1);
2298 }2313 }
2314#endif
2299 2315
2300 /* we add a section for symbols */2316 /* we add a section for symbols */
2301 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);2317 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2302 put_elf_str(strsec, "");2318 put_elf_str(strsec, "");
2303 2319
2304 /* Allocate strings for section names */2320 /* Allocate strings for section names */
2305 textrel = alloc_sec_names(s1, file_type, strsec);2321 ret = alloc_sec_names(s1, file_type, strsec);
2306 2322
2323#ifndef ELF_OBJ_ONLY
2307 if (dynamic) {2324 if (dynamic) {
2325 int i;
2308 /* add a list of needed dlls */2326 /* add a list of needed dlls */
2309 for(i = 0; i < s1->nb_loaded_dlls; i++) {2327 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2310 DLLReference *dllref = s1->loaded_dlls[i];2328 DLLReference *dllref = s1->loaded_dlls[i];
@@ -2321,7 +2339,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 10 unmodified lines
2321 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));2339 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2322 /* XXX: currently, since we do not handle PIC code, we2340 /* XXX: currently, since we do not handle PIC code, we
2323 must relocate the readonly segments */2341 must relocate the readonly segments */
2324 if (textrel)2342 if (ret)
2325 put_dt(dynamic, DT_TEXTREL, 0);2343 put_dt(dynamic, DT_TEXTREL, 0);
2326 }2344 }
2327 2345
@@ -2336,6 +2354,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 8 unmodified lines
2336 dynamic->sh_size = dynamic->data_offset;2354 dynamic->sh_size = dynamic->data_offset;
2337 dynstr->sh_size = dynstr->data_offset;2355 dynstr->sh_size = dynstr->data_offset;
2338 }2356 }
2357#endif
2339 2358
2340 /* compute number of program headers */2359 /* compute number of program headers */
2341 if (file_type == TCC_OUTPUT_OBJ)2360 if (file_type == TCC_OUTPUT_OBJ)
@@ -2361,11 +2380,13 @@ static int elf_output_file(TCCState *s1, const char *filename) · 19 unmodified lines
2361 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,2380 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2362 sec_order);2381 sec_order);
2363 2382
2383#ifndef ELF_OBJ_ONLY
2364 /* Fill remaining program header and finalize relocation related to dynamic2384 /* Fill remaining program header and finalize relocation related to dynamic
2365 linking. */2385 linking. */
2366 if (file_type != TCC_OUTPUT_OBJ) {2386 if (file_type != TCC_OUTPUT_OBJ) {
2367 fill_unloadable_phdr(phdr, phnum, interp, dynamic);2387 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2368 if (dynamic) {2388 if (dynamic) {
2389 ElfW(Sym) *sym;
2369 dynamic->data_offset = dyninf.data_offset;2390 dynamic->data_offset = dyninf.data_offset;
2370 fill_dynamic(s1, &dyninf);2391 fill_dynamic(s1, &dyninf);
2371 2392
@@ -2397,10 +2418,12 @@ static int elf_output_file(TCCState *s1, const char *filename) · 25 unmodified lines
2397 else if (s1->got)2418 else if (s1->got)
2398 fill_local_got_entries(s1);2419 fill_local_got_entries(s1);
2399 }2420 }
2421#endif
2400 2422
2401 /* Create the ELF file with name 'filename' */2423 /* Create the ELF file with name 'filename' */
2402 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);2424 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2403 s1->nb_sections = shnum;2425 s1->nb_sections = shnum;
2426 goto the_end;
2404 the_end:2427 the_end:
2405 tcc_free(sec_order);2428 tcc_free(sec_order);
2406 tcc_free(phdr);2429 tcc_free(phdr);
@@ -2885,10 +2908,10 @@ ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte) · 478 unmodified lines
2885 return 0;2908 return 0;
2886}2909}
2887 2910
2888#ifndef TCC_TARGET_PE2911#ifndef ELF_OBJ_ONLY
2889/* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes2912/* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
2890 LV, maybe create a new entry for (LIB,VERSION). */2913 LV, maybe create a new entry for (LIB,VERSION). */
2891static void set_ver_to_ver(int *n, int **lv, int i, char *lib, char *version)2914static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
2892{2915{
2893 while (i >= *n) {2916 while (i >= *n) {
2894 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));2917 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
@@ -2919,7 +2942,7 @@ static void set_ver_to_ver(int *n, int **lv, int i, char *lib, char *version) · 24 unmodified lines
2919/* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index2942/* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
2920 VERNDX. */2943 VERNDX. */
2921static void2944static void
2922set_sym_version(int sym_index, int verndx)2945set_sym_version(TCCState *s1, int sym_index, int verndx)
2923{2946{
2924 if (sym_index >= nb_sym_to_version) {2947 if (sym_index >= nb_sym_to_version) {
2925 int newelems = sym_index ? sym_index * 2 : 1;2948 int newelems = sym_index ? sym_index * 2 : 1;
@@ -2933,6 +2956,90 @@ set_sym_version(int sym_index, int verndx) · 7 unmodified lines
2933 sym_to_version[sym_index] = verndx;2956 sym_to_version[sym_index] = verndx;
2934}2957}
2935 2958
2959struct versym_info {
2960 int nb_versyms;
2961 ElfW(Verdef) *verdef;
2962 ElfW(Verneed) *verneed;
2963 ElfW(Half) *versym;
2964 int nb_local_ver, *local_ver;
2965};
2966
2967
2968static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
2969{
2970 char *lib, *version;
2971 uint32_t next;
2972 int i;
2973
2974#define DEBUG_VERSION 0
2975
2976 if (v->versym && v->verdef) {
2977 ElfW(Verdef) *vdef = v->verdef;
2978 lib = NULL;
2979 do {
2980 ElfW(Verdaux) *verdaux =
2981 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
2982
2983#if DEBUG_VERSION
2984 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
2985 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
2986 vdef->vd_hash);
2987#endif
2988 if (vdef->vd_cnt) {
2989 version = dynstr + verdaux->vda_name;
2990
2991 if (lib == NULL)
2992 lib = version;
2993 else
2994 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
2995 lib, version);
2996#if DEBUG_VERSION
2997 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
2998#endif
2999 }
3000 next = vdef->vd_next;
3001 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3002 } while (next);
3003 }
3004 if (v->versym && v->verneed) {
3005 ElfW(Verneed) *vneed = v->verneed;
3006 do {
3007 ElfW(Vernaux) *vernaux =
3008 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3009
3010 lib = dynstr + vneed->vn_file;
3011#if DEBUG_VERSION
3012 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3013#endif
3014 for (i = 0; i < vneed->vn_cnt; i++) {
3015 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3016 version = dynstr + vernaux->vna_name;
3017 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3018 lib, version);
3019#if DEBUG_VERSION
3020 printf (" vernaux(%u): %u %u %s\n",
3021 vernaux->vna_other, vernaux->vna_hash,
3022 vernaux->vna_flags, version);
3023#endif
3024 }
3025 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3026 }
3027 next = vneed->vn_next;
3028 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3029 } while (next);
3030 }
3031
3032#if DEBUG_VERSION
3033 for (i = 0; i < v->nb_local_ver; i++) {
3034 if (v->local_ver[i] > 0) {
3035 printf ("%d: lib: %s, version %s\n",
3036 i, sym_versions[v->local_ver[i]].lib,
3037 sym_versions[v->local_ver[i]].version);
3038 }
3039 }
3040#endif
3041}
3042
2936/* load a DLL and all referenced DLLs. 'level = 0' means that the DLL3043/* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2937 is referenced by the user (so it should be added as DT_NEEDED in3044 is referenced by the user (so it should be added as DT_NEEDED in
2938 the generated ELF file) */3045 the generated ELF file) */
@@ -2943,17 +3050,12 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) · 4 unmodified lines
2943 int i, j, nb_syms, nb_dts, sym_bind, ret;3050 int i, j, nb_syms, nb_dts, sym_bind, ret;
2944 ElfW(Sym) *sym, *dynsym;3051 ElfW(Sym) *sym, *dynsym;
2945 ElfW(Dyn) *dt, *dynamic;3052 ElfW(Dyn) *dt, *dynamic;
2946 int nb_versyms;3053
2947 ElfW(Verdef) *verdef, *vdef;
2948 ElfW(Verneed) *verneed, *vneed;
2949 ElfW(Half) *versym, *vsym;
2950 char *dynstr;3054 char *dynstr;
2951 uint32_t next;
2952 int sym_index;3055 int sym_index;
2953 char *lib, *version;
2954 int nb_local_ver = 0, *local_ver = NULL;
2955 const char *name, *soname;3056 const char *name, *soname;
2956 DLLReference *dllref;3057 DLLReference *dllref;
3058 struct versym_info v;
2957 3059
2958 full_read(fd, &ehdr, sizeof(ehdr));3060 full_read(fd, &ehdr, sizeof(ehdr));
2959 3061
@@ -2973,10 +3075,8 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) · 13 unmodified lines
2973 dynamic = NULL;3075 dynamic = NULL;
2974 dynsym = NULL; /* avoid warning */3076 dynsym = NULL; /* avoid warning */
2975 dynstr = NULL; /* avoid warning */3077 dynstr = NULL; /* avoid warning */
2976 nb_versyms = 0;3078 memset(&v, 0, sizeof v);
2977 verdef = NULL;3079
2978 verneed = NULL;
2979 versym = NULL;
2980 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {3080 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2981 switch(sh->sh_type) {3081 switch(sh->sh_type) {
2982 case SHT_DYNAMIC:3082 case SHT_DYNAMIC:
@@ -2990,14 +3090,14 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) · 7 unmodified lines
2990 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);3090 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2991 break;3091 break;
2992 case SHT_GNU_verdef:3092 case SHT_GNU_verdef:
2993 verdef = load_data(fd, sh->sh_offset, sh->sh_size);3093 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
2994 break;3094 break;
2995 case SHT_GNU_verneed:3095 case SHT_GNU_verneed:
2996 verneed = load_data(fd, sh->sh_offset, sh->sh_size);3096 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
2997 break;3097 break;
2998 case SHT_GNU_versym:3098 case SHT_GNU_versym:
2999 nb_versyms = sh->sh_size / sizeof(ElfW(Half));3099 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3000 versym = load_data(fd, sh->sh_offset, sh->sh_size);3100 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3001 break;3101 break;
3002 default:3102 default:
3003 break;3103 break;
@@ -3025,78 +3125,10 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) · 21 unmodified lines
3025 }3125 }
3026 }3126 }
3027 3127
3028 if (nb_versyms != nb_syms) {3128 if (v.nb_versyms != nb_syms)
3029 tcc_free (versym);3129 tcc_free (v.versym), v.versym = NULL;
3030 versym = NULL;3130 else
3031 }3131 store_version(s1, &v, dynstr);
3032
3033#define DEBUG_VERSION 0
3034
3035 if (versym && verdef) {
3036 lib = NULL;
3037 vdef = verdef;
3038 do {
3039 ElfW(Verdaux) *verdaux =
3040 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3041
3042#if DEBUG_VERSION
3043 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3044 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3045 vdef->vd_hash);
3046#endif
3047 if (vdef->vd_cnt) {
3048 version = dynstr + verdaux->vda_name;
3049
3050 if (lib == NULL)
3051 lib = version;
3052 else
3053 set_ver_to_ver(&nb_local_ver, &local_ver, vdef->vd_ndx,
3054 lib, version);
3055#if DEBUG_VERSION
3056 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3057#endif
3058 }
3059 next = vdef->vd_next;
3060 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3061 } while (next);
3062 }
3063 if (versym && verneed) {
3064 vneed = verneed;
3065 do {
3066 ElfW(Vernaux) *vernaux =
3067 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3068
3069 lib = dynstr + vneed->vn_file;
3070#if DEBUG_VERSION
3071 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3072#endif
3073 for (i = 0; i < vneed->vn_cnt; i++) {
3074 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3075 version = dynstr + vernaux->vna_name;
3076 set_ver_to_ver(&nb_local_ver, &local_ver, vernaux->vna_other,
3077 lib, version);
3078#if DEBUG_VERSION
3079 printf (" vernaux(%u): %u %u %s\n",
3080 vernaux->vna_other, vernaux->vna_hash,
3081 vernaux->vna_flags, version);
3082#endif
3083 }
3084 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3085 }
3086 next = vneed->vn_next;
3087 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3088 } while (next);
3089 }
3090
3091#if DEBUG_VERSION
3092 for (i = 0; i < nb_local_ver; i++) {
3093 if (local_ver[i] > 0) {
3094 printf ("%d: lib: %s, version %s\n",
3095 i, sym_versions[local_ver[i]].lib,
3096 sym_version[local_ver[i]].version);
3097 }
3098 }
3099#endif
3100 3132
3101 /* add the dll and its level */3133 /* add the dll and its level */
3102 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));3134 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
@@ -3105,17 +3137,18 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) · 2 unmodified lines
3105 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);3137 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
3106 3138
3107 /* add dynamic symbols in dynsym_section */3139 /* add dynamic symbols in dynsym_section */
3108 for(i = 1, sym = dynsym + 1, vsym = versym + 1; i < nb_syms; i++, sym++, vsym++) {3140 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3109 sym_bind = ELFW(ST_BIND)(sym->st_info);3141 sym_bind = ELFW(ST_BIND)(sym->st_info);
3110 if (sym_bind == STB_LOCAL)3142 if (sym_bind == STB_LOCAL)
3111 continue;3143 continue;
3112 name = dynstr + sym->st_name;3144 name = dynstr + sym->st_name;
3113 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,3145 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3114 sym->st_info, sym->st_other, sym->st_shndx, name);3146 sym->st_info, sym->st_other, sym->st_shndx, name);
3115 if (versym && (*vsym & 0x8000) == 0 &&3147 if (v.versym) {
3116 *vsym > 0 && *vsym < nb_local_ver) {3148 ElfW(Half) vsym = v.versym[i];
3117 set_sym_version(sym_index, local_ver[*vsym]);3149 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3118 }3150 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3151 }
3119 }3152 }
3120 3153
3121 /* load all referenced DLLs */3154 /* load all referenced DLLs */
@@ -3139,14 +3172,14 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) · 17 unmodified lines
3139 }3172 }
3140 ret = 0;3173 ret = 0;
3141 the_end:3174 the_end:
3142 tcc_free(local_ver);
3143 tcc_free(dynstr);3175 tcc_free(dynstr);
3144 tcc_free(dynsym);3176 tcc_free(dynsym);
3145 tcc_free(dynamic);3177 tcc_free(dynamic);
3146 tcc_free(verdef);
3147 tcc_free(verneed);
3148 tcc_free(versym);
3149 tcc_free(shdr);3178 tcc_free(shdr);
3179 tcc_free(v.local_ver);
3180 tcc_free(v.verdef);
3181 tcc_free(v.verneed);
3182 tcc_free(v.versym);
3150 return ret;3183 return ret;
3151}3184}
3152 3185
@@ -3406,4 +3439,4 @@ ST_FUNC int tcc_load_ldscript(TCCState *s1) · 253 unmodified lines
3406 }3439 }
3407 return 0;3440 return 0;
3408}3441}
3409#endif /* !TCC_TARGET_PE */3442#endif /* !ELF_OBJ_ONLY */
tccrun.c+2−0
@@ -237,7 +237,9 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff) · 236 unmodified lines
237 if (s->reloc)237 if (s->reloc)
238 relocate_section(s1, s);238 relocate_section(s1, s);
239 }239 }
240#ifndef TCC_TARGET_PE
240 relocate_plt(s1);241 relocate_plt(s1);
242#endif
241 243
242 for(i = 1; i < s1->nb_sections; i++) {244 for(i = 1; i < s1->nb_sections; i++) {
243 s = s1->sections[i];245 s = s1->sections[i];
x86_64-link.c+2−11
@@ -22,6 +22,7 @@ · 21 unmodified lines
22 22
23#include "tcc.h"23#include "tcc.h"
24 24
25#ifndef ELF_OBJ_ONLY
25/* Returns 1 for a code relocation, 0 for a data relocation. For unknown26/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
26 relocations, returns -1. */27 relocations, returns -1. */
27int code_reloc (int reloc_type)28int code_reloc (int reloc_type)
@@ -162,17 +163,7 @@ ST_FUNC void relocate_plt(TCCState *s1) · 134 unmodified lines
162 }163 }
163 }164 }
164}165}
165 166#endif
166static ElfW_Rel *qrel; /* ptr to next reloc entry reused */
167
168void relocate_init(Section *sr)
169{
170 qrel = (ElfW_Rel *) sr->data;
171}
172
173void relocate_fini(Section *sr)
174{
175}
176 167
177void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)168void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
178{169{

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t