tccelf.c: write section headers before sections
[tinycc.git] / tccelf.c
blob7605727545be19b549c09e5f981b2968591710cf
1 /*
2 * ELF file handling for TCC
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "tcc.h"
23 /* Define this to get some debug output during relocation processing. */
24 #undef DEBUG_RELOC
26 /********************************************************/
27 /* global variables */
29 /* elf version information */
30 struct sym_version {
31 char *lib;
32 char *version;
33 int out_index;
34 int prev_same_lib;
37 #define nb_sym_versions s1->nb_sym_versions
38 #define sym_versions s1->sym_versions
39 #define nb_sym_to_version s1->nb_sym_to_version
40 #define sym_to_version s1->sym_to_version
41 #define dt_verneednum s1->dt_verneednum
42 #define versym_section s1->versym_section
43 #define verneed_section s1->verneed_section
45 /* special flag to indicate that the section should not be linked to the other ones */
46 #define SHF_PRIVATE 0x80000000
47 /* section is dynsymtab_section */
48 #define SHF_DYNSYM 0x40000000
50 #ifdef TCC_TARGET_PE
51 #define shf_RELRO SHF_ALLOC
52 static const char rdata[] = ".rdata";
53 #else
54 #define shf_RELRO s1->shf_RELRO
55 static const char rdata[] = ".data.ro";
56 #endif
58 /* ------------------------------------------------------------------------- */
60 ST_FUNC void tccelf_new(TCCState *s)
62 TCCState *s1 = s;
64 #ifndef TCC_TARGET_PE
65 shf_RELRO = SHF_ALLOC;
66 if (s1->output_type != TCC_OUTPUT_MEMORY)
67 shf_RELRO |= SHF_WRITE; /* the ELF loader will set it to RO at runtime */
68 #endif
70 /* no section zero */
71 dynarray_add(&s->sections, &s->nb_sections, NULL);
73 /* create standard sections */
74 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
75 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
76 /* create ro data section (make ro after relocation done with GNU_RELRO) */
77 rodata_section = new_section(s, rdata, SHT_PROGBITS, shf_RELRO);
78 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
79 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
80 common_section->sh_num = SHN_COMMON;
82 /* symbols are always generated for linking stage */
83 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
84 ".strtab",
85 ".hashtab", SHF_PRIVATE);
87 /* private symbol table for dynamic symbols */
88 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
89 ".dynstrtab",
90 ".dynhashtab", SHF_PRIVATE);
91 get_sym_attr(s, 0, 1);
93 if (s->do_debug) {
94 /* add debug sections */
95 tcc_debug_new(s);
98 #ifdef CONFIG_TCC_BCHECK
99 if (s->do_bounds_check) {
100 /* if bound checking, then add corresponding sections */
101 /* (make ro after relocation done with GNU_RELRO) */
102 bounds_section = new_section(s, ".bounds", SHT_PROGBITS, shf_RELRO);
103 lbounds_section = new_section(s, ".lbounds", SHT_PROGBITS, shf_RELRO);
105 #endif
108 ST_FUNC void free_section(Section *s)
110 if (!s)
111 return;
112 tcc_free(s->data);
113 s->data = NULL;
114 s->data_allocated = s->data_offset = 0;
117 ST_FUNC void tccelf_delete(TCCState *s1)
119 int i;
121 #ifndef ELF_OBJ_ONLY
122 /* free symbol versions */
123 for (i = 0; i < nb_sym_versions; i++) {
124 tcc_free(sym_versions[i].version);
125 tcc_free(sym_versions[i].lib);
127 tcc_free(sym_versions);
128 tcc_free(sym_to_version);
129 #endif
131 /* free all sections */
132 for(i = 1; i < s1->nb_sections; i++)
133 free_section(s1->sections[i]);
134 dynarray_reset(&s1->sections, &s1->nb_sections);
136 for(i = 0; i < s1->nb_priv_sections; i++)
137 free_section(s1->priv_sections[i]);
138 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
140 tcc_free(s1->sym_attrs);
141 symtab_section = NULL; /* for tccrun.c:rt_printline() */
144 /* save section data state */
145 ST_FUNC void tccelf_begin_file(TCCState *s1)
147 Section *s; int i;
148 for (i = 1; i < s1->nb_sections; i++) {
149 s = s1->sections[i];
150 s->sh_offset = s->data_offset;
152 /* disable symbol hashing during compilation */
153 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
154 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
155 s1->uw_sym = 0;
156 s1->uw_offs = 0;
157 #endif
160 static void update_relocs(TCCState *s1, Section *s, int *old_to_new_syms, int first_sym);
162 /* At the end of compilation, convert any UNDEF syms to global, and merge
163 with previously existing symbols */
164 ST_FUNC void tccelf_end_file(TCCState *s1)
166 Section *s = s1->symtab;
167 int first_sym, nb_syms, *tr, i;
169 first_sym = s->sh_offset / sizeof (ElfSym);
170 nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
171 s->data_offset = s->sh_offset;
172 s->link->data_offset = s->link->sh_offset;
173 s->hash = s->reloc, s->reloc = NULL;
174 tr = tcc_mallocz(nb_syms * sizeof *tr);
176 for (i = 0; i < nb_syms; ++i) {
177 ElfSym *sym = (ElfSym*)s->data + first_sym + i;
178 if (sym->st_shndx == SHN_UNDEF) {
179 int sym_bind = ELFW(ST_BIND)(sym->st_info);
180 int sym_type = ELFW(ST_TYPE)(sym->st_info);
181 if (sym_bind == STB_LOCAL)
182 sym_bind = STB_GLOBAL;
183 #ifndef TCC_TARGET_PE
184 if (sym_bind == STB_GLOBAL && s1->output_type == TCC_OUTPUT_OBJ) {
185 /* undefined symbols with STT_FUNC are confusing gnu ld when
186 linking statically to STT_GNU_IFUNC */
187 sym_type = STT_NOTYPE;
189 #endif
190 sym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
192 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
193 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
195 /* now update relocations */
196 update_relocs(s1, s, tr, first_sym);
197 tcc_free(tr);
198 /* record text/data/bss output for -bench info */
199 for (i = 0; i < 4; ++i) {
200 s = s1->sections[i + 1];
201 s1->total_output[i] += s->data_offset - s->sh_offset;
205 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
207 Section *sec;
209 sec = tcc_mallocz(sizeof(Section) + strlen(name));
210 sec->s1 = s1;
211 strcpy(sec->name, name);
212 sec->sh_type = sh_type;
213 sec->sh_flags = sh_flags;
214 switch(sh_type) {
215 case SHT_GNU_versym:
216 sec->sh_addralign = 2;
217 break;
218 case SHT_HASH:
219 case SHT_GNU_HASH:
220 case SHT_REL:
221 case SHT_RELA:
222 case SHT_DYNSYM:
223 case SHT_SYMTAB:
224 case SHT_DYNAMIC:
225 case SHT_GNU_verneed:
226 case SHT_GNU_verdef:
227 sec->sh_addralign = PTR_SIZE;
228 break;
229 case SHT_STRTAB:
230 sec->sh_addralign = 1;
231 break;
232 default:
233 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */
234 break;
237 if (sh_flags & SHF_PRIVATE) {
238 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
239 } else {
240 sec->sh_num = s1->nb_sections;
241 dynarray_add(&s1->sections, &s1->nb_sections, sec);
244 return sec;
247 ST_FUNC void init_symtab(Section *s)
249 int *ptr, nb_buckets = 1;
250 put_elf_str(s->link, "");
251 section_ptr_add(s, sizeof (ElfW(Sym)));
252 ptr = section_ptr_add(s->hash, (2 + nb_buckets + 1) * sizeof(int));
253 ptr[0] = nb_buckets;
254 ptr[1] = 1;
255 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
258 ST_FUNC Section *new_symtab(TCCState *s1,
259 const char *symtab_name, int sh_type, int sh_flags,
260 const char *strtab_name,
261 const char *hash_name, int hash_sh_flags)
263 Section *symtab, *strtab, *hash;
264 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
265 symtab->sh_entsize = sizeof(ElfW(Sym));
266 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
267 symtab->link = strtab;
268 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
269 hash->sh_entsize = sizeof(int);
270 symtab->hash = hash;
271 hash->link = symtab;
272 init_symtab(symtab);
273 return symtab;
276 /* realloc section and set its content to zero */
277 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
279 unsigned long size;
280 unsigned char *data;
282 size = sec->data_allocated;
283 if (size == 0)
284 size = 1;
285 while (size < new_size)
286 size = size * 2;
287 data = tcc_realloc(sec->data, size);
288 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
289 sec->data = data;
290 sec->data_allocated = size;
293 /* reserve at least 'size' bytes aligned per 'align' in section
294 'sec' from current offset, and return the aligned offset */
295 ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
297 size_t offset, offset1;
299 offset = (sec->data_offset + align - 1) & -align;
300 offset1 = offset + size;
301 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
302 section_realloc(sec, offset1);
303 sec->data_offset = offset1;
304 if (align > sec->sh_addralign)
305 sec->sh_addralign = align;
306 return offset;
309 /* reserve at least 'size' bytes in section 'sec' from
310 sec->data_offset. */
311 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
313 size_t offset = section_add(sec, size, 1);
314 return sec->data + offset;
317 #ifndef ELF_OBJ_ONLY
318 /* reserve at least 'size' bytes from section start */
319 static void section_reserve(Section *sec, unsigned long size)
321 if (size > sec->data_allocated)
322 section_realloc(sec, size);
323 if (size > sec->data_offset)
324 sec->data_offset = size;
326 #endif
328 static Section *have_section(TCCState *s1, const char *name)
330 Section *sec;
331 int i;
332 for(i = 1; i < s1->nb_sections; i++) {
333 sec = s1->sections[i];
334 if (!strcmp(name, sec->name))
335 return sec;
337 return NULL;
340 /* return a reference to a section, and create it if it does not
341 exists */
342 ST_FUNC Section *find_section(TCCState *s1, const char *name)
344 Section *sec = have_section(s1, name);
345 if (sec)
346 return sec;
347 /* sections are created as PROGBITS */
348 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
351 /* ------------------------------------------------------------------------- */
353 ST_FUNC int put_elf_str(Section *s, const char *sym)
355 int offset, len;
356 char *ptr;
358 len = strlen(sym) + 1;
359 offset = s->data_offset;
360 ptr = section_ptr_add(s, len);
361 memmove(ptr, sym, len);
362 return offset;
365 /* elf symbol hashing function */
366 static ElfW(Word) elf_hash(const unsigned char *name)
368 ElfW(Word) h = 0, g;
370 while (*name) {
371 h = (h << 4) + *name++;
372 g = h & 0xf0000000;
373 if (g)
374 h ^= g >> 24;
375 h &= ~g;
377 return h;
380 /* rebuild hash table of section s */
381 /* NOTE: we do factorize the hash table code to go faster */
382 static void rebuild_hash(Section *s, unsigned int nb_buckets)
384 ElfW(Sym) *sym;
385 int *ptr, *hash, nb_syms, sym_index, h;
386 unsigned char *strtab;
388 strtab = s->link->data;
389 nb_syms = s->data_offset / sizeof(ElfW(Sym));
391 if (!nb_buckets)
392 nb_buckets = ((int*)s->hash->data)[0];
394 s->hash->data_offset = 0;
395 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
396 ptr[0] = nb_buckets;
397 ptr[1] = nb_syms;
398 ptr += 2;
399 hash = ptr;
400 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
401 ptr += nb_buckets + 1;
403 sym = (ElfW(Sym) *)s->data + 1;
404 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
405 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
406 h = elf_hash(strtab + sym->st_name) % nb_buckets;
407 *ptr = hash[h];
408 hash[h] = sym_index;
409 } else {
410 *ptr = 0;
412 ptr++;
413 sym++;
417 /* return the symbol number */
418 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
419 int info, int other, int shndx, const char *name)
421 int name_offset, sym_index;
422 int nbuckets, h;
423 ElfW(Sym) *sym;
424 Section *hs;
426 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
427 if (name && name[0])
428 name_offset = put_elf_str(s->link, name);
429 else
430 name_offset = 0;
431 /* XXX: endianness */
432 sym->st_name = name_offset;
433 sym->st_value = value;
434 sym->st_size = size;
435 sym->st_info = info;
436 sym->st_other = other;
437 sym->st_shndx = shndx;
438 sym_index = sym - (ElfW(Sym) *)s->data;
439 hs = s->hash;
440 if (hs) {
441 int *ptr, *base;
442 ptr = section_ptr_add(hs, sizeof(int));
443 base = (int *)hs->data;
444 /* only add global or weak symbols. */
445 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
446 /* add another hashing entry */
447 nbuckets = base[0];
448 h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
449 *ptr = base[2 + h];
450 base[2 + h] = sym_index;
451 base[1]++;
452 /* we resize the hash table */
453 hs->nb_hashed_syms++;
454 if (hs->nb_hashed_syms > 2 * nbuckets) {
455 rebuild_hash(s, 2 * nbuckets);
457 } else {
458 *ptr = 0;
459 base[1]++;
462 return sym_index;
465 ST_FUNC int find_elf_sym(Section *s, const char *name)
467 ElfW(Sym) *sym;
468 Section *hs;
469 int nbuckets, sym_index, h;
470 const char *name1;
472 hs = s->hash;
473 if (!hs)
474 return 0;
475 nbuckets = ((int *)hs->data)[0];
476 h = elf_hash((unsigned char *) name) % nbuckets;
477 sym_index = ((int *)hs->data)[2 + h];
478 while (sym_index != 0) {
479 sym = &((ElfW(Sym) *)s->data)[sym_index];
480 name1 = (char *) s->link->data + sym->st_name;
481 if (!strcmp(name, name1))
482 return sym_index;
483 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
485 return 0;
488 /* return elf symbol value, signal error if 'err' is nonzero, decorate
489 name if FORC */
490 ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
492 int sym_index;
493 ElfW(Sym) *sym;
494 char buf[256];
495 if (forc && s1->leading_underscore
496 #ifdef TCC_TARGET_PE
497 /* win32-32bit stdcall symbols always have _ already */
498 && !strchr(name, '@')
499 #endif
501 buf[0] = '_';
502 pstrcpy(buf + 1, sizeof(buf) - 1, name);
503 name = buf;
505 sym_index = find_elf_sym(s1->symtab, name);
506 sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
507 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
508 if (err)
509 tcc_error_noabort("%s not defined", name);
510 return (addr_t)-1;
512 return sym->st_value;
515 /* return elf symbol value */
516 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
518 addr_t addr = get_sym_addr(s, name, 0, 1);
519 return addr == -1 ? NULL : (void*)(uintptr_t)addr;
522 /* list elf symbol names and values */
523 ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
524 void (*symbol_cb)(void *ctx, const char *name, const void *val))
526 ElfW(Sym) *sym;
527 Section *symtab;
528 int sym_index, end_sym;
529 const char *name;
530 unsigned char sym_vis, sym_bind;
532 symtab = s->symtab;
533 end_sym = symtab->data_offset / sizeof (ElfSym);
534 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
535 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
536 if (sym->st_value) {
537 name = (char *) symtab->link->data + sym->st_name;
538 sym_bind = ELFW(ST_BIND)(sym->st_info);
539 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
540 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
541 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
546 /* list elf symbol names and values */
547 LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
548 void (*symbol_cb)(void *ctx, const char *name, const void *val))
550 list_elf_symbols(s, ctx, symbol_cb);
553 #ifndef ELF_OBJ_ONLY
554 static void
555 version_add (TCCState *s1)
557 int i;
558 ElfW(Sym) *sym;
559 ElfW(Verneed) *vn = NULL;
560 Section *symtab;
561 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
562 ElfW(Half) *versym;
563 const char *name;
565 if (0 == nb_sym_versions)
566 return;
567 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
568 versym_section->sh_entsize = sizeof(ElfW(Half));
569 versym_section->link = s1->dynsym;
571 /* add needed symbols */
572 symtab = s1->dynsym;
573 end_sym = symtab->data_offset / sizeof (ElfSym);
574 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
575 for (sym_index = 1; sym_index < end_sym; ++sym_index) {
576 int dllindex, verndx;
577 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
578 if (sym->st_shndx != SHN_UNDEF)
579 continue; /* defined symbol doesn't need library version */
580 name = (char *) symtab->link->data + sym->st_name;
581 dllindex = find_elf_sym(s1->dynsymtab_section, name);
582 verndx = (dllindex && dllindex < nb_sym_to_version)
583 ? sym_to_version[dllindex] : -1;
584 if (verndx >= 0) {
585 if (!sym_versions[verndx].out_index)
586 sym_versions[verndx].out_index = nb_versions++;
587 versym[sym_index] = sym_versions[verndx].out_index;
590 /* generate verneed section, but not when it will be empty. Some
591 dynamic linkers look at their contents even when DTVERNEEDNUM and
592 section size is zero. */
593 if (nb_versions > 2) {
594 verneed_section = new_section(s1, ".gnu.version_r",
595 SHT_GNU_verneed, SHF_ALLOC);
596 verneed_section->link = s1->dynsym->link;
597 for (i = nb_sym_versions; i-- > 0;) {
598 struct sym_version *sv = &sym_versions[i];
599 int n_same_libs = 0, prev;
600 size_t vnofs;
601 ElfW(Vernaux) *vna = 0;
602 if (sv->out_index < 1)
603 continue;
605 /* make sure that a DT_NEEDED tag is put */
606 /* abitest-tcc fails on older i386-linux with "ld-linux.so.2" DT_NEEDED
607 ret_int_test... Inconsistency detected by ld.so: dl-minimal.c: 148:
608 realloc: Assertion `ptr == alloc_last_block' failed! */
609 if (strcmp(sv->lib, "ld-linux.so.2"))
610 tcc_add_dllref(s1, sv->lib, 0);
612 vnofs = section_add(verneed_section, sizeof(*vn), 1);
613 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
614 vn->vn_version = 1;
615 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
616 vn->vn_aux = sizeof (*vn);
617 do {
618 prev = sv->prev_same_lib;
619 if (sv->out_index > 0) {
620 vna = section_ptr_add(verneed_section, sizeof(*vna));
621 vna->vna_hash = elf_hash ((const unsigned char *)sv->version);
622 vna->vna_flags = 0;
623 vna->vna_other = sv->out_index;
624 sv->out_index = -2;
625 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
626 vna->vna_next = sizeof (*vna);
627 n_same_libs++;
629 if (prev >= 0)
630 sv = &sym_versions[prev];
631 } while(prev >= 0);
632 vna->vna_next = 0;
633 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
634 vn->vn_cnt = n_same_libs;
635 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
636 nb_entries++;
638 if (vn)
639 vn->vn_next = 0;
640 verneed_section->sh_info = nb_entries;
642 dt_verneednum = nb_entries;
644 #endif /* ndef ELF_OBJ_ONLY */
646 /* add an elf symbol : check if it is already defined and patch
647 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
648 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
649 int info, int other, int shndx, const char *name)
651 TCCState *s1 = s->s1;
652 ElfW(Sym) *esym;
653 int sym_bind, sym_index, sym_type, esym_bind;
654 unsigned char sym_vis, esym_vis, new_vis;
656 sym_bind = ELFW(ST_BIND)(info);
657 sym_type = ELFW(ST_TYPE)(info);
658 sym_vis = ELFW(ST_VISIBILITY)(other);
660 if (sym_bind != STB_LOCAL) {
661 /* we search global or weak symbols */
662 sym_index = find_elf_sym(s, name);
663 if (!sym_index)
664 goto do_def;
665 esym = &((ElfW(Sym) *)s->data)[sym_index];
666 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
667 && esym->st_other == other && esym->st_shndx == shndx)
668 return sym_index;
669 if (esym->st_shndx != SHN_UNDEF) {
670 esym_bind = ELFW(ST_BIND)(esym->st_info);
671 /* propagate the most constraining visibility */
672 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
673 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
674 if (esym_vis == STV_DEFAULT) {
675 new_vis = sym_vis;
676 } else if (sym_vis == STV_DEFAULT) {
677 new_vis = esym_vis;
678 } else {
679 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
681 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
682 | new_vis;
683 if (shndx == SHN_UNDEF) {
684 /* ignore adding of undefined symbol if the
685 corresponding symbol is already defined */
686 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
687 /* global overrides weak, so patch */
688 goto do_patch;
689 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
690 /* weak is ignored if already global */
691 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
692 /* keep first-found weak definition, ignore subsequents */
693 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
694 /* ignore hidden symbols after */
695 } else if ((esym->st_shndx == SHN_COMMON
696 || esym->st_shndx == bss_section->sh_num)
697 && (shndx < SHN_LORESERVE
698 && shndx != bss_section->sh_num)) {
699 /* data symbol gets precedence over common/bss */
700 goto do_patch;
701 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
702 /* data symbol keeps precedence over common/bss */
703 } else if (s->sh_flags & SHF_DYNSYM) {
704 /* we accept that two DLL define the same symbol */
705 } else if (esym->st_other & ST_ASM_SET) {
706 /* If the existing symbol came from an asm .set
707 we can override. */
708 goto do_patch;
709 } else {
710 #if 0
711 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
712 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
713 #endif
714 tcc_error_noabort("'%s' defined twice", name);
716 } else {
717 esym->st_other = other;
718 do_patch:
719 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
720 esym->st_shndx = shndx;
721 s1->new_undef_sym = 1;
722 esym->st_value = value;
723 esym->st_size = size;
725 } else {
726 do_def:
727 sym_index = put_elf_sym(s, value, size,
728 ELFW(ST_INFO)(sym_bind, sym_type), other,
729 shndx, name);
731 return sym_index;
734 /* put relocation */
735 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
736 int type, int symbol, addr_t addend)
738 TCCState *s1 = s->s1;
739 char buf[256];
740 Section *sr;
741 ElfW_Rel *rel;
743 sr = s->reloc;
744 if (!sr) {
745 /* if no relocation section, create it */
746 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
747 /* if the symtab is allocated, then we consider the relocation
748 are also */
749 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
750 sr->sh_entsize = sizeof(ElfW_Rel);
751 sr->link = symtab;
752 sr->sh_info = s->sh_num;
753 s->reloc = sr;
755 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
756 rel->r_offset = offset;
757 rel->r_info = ELFW(R_INFO)(symbol, type);
758 #if SHT_RELX == SHT_RELA
759 rel->r_addend = addend;
760 #endif
761 if (SHT_RELX != SHT_RELA && addend)
762 tcc_error_noabort("non-zero addend on REL architecture");
765 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
766 int type, int symbol)
768 put_elf_reloca(symtab, s, offset, type, symbol, 0);
771 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
773 int n;
774 struct sym_attr *tab;
776 if (index >= s1->nb_sym_attrs) {
777 if (!alloc)
778 return s1->sym_attrs;
779 /* find immediately bigger power of 2 and reallocate array */
780 n = 1;
781 while (index >= n)
782 n *= 2;
783 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
784 s1->sym_attrs = tab;
785 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
786 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
787 s1->nb_sym_attrs = n;
789 return &s1->sym_attrs[index];
792 static void update_relocs(TCCState *s1, Section *s, int *old_to_new_syms, int first_sym)
794 int i, type, sym_index;
795 Section *sr;
796 ElfW_Rel *rel;
798 for(i = 1; i < s1->nb_sections; i++) {
799 sr = s1->sections[i];
800 if (sr->sh_type == SHT_RELX && sr->link == s) {
801 for_each_elem(sr, 0, rel, ElfW_Rel) {
802 sym_index = ELFW(R_SYM)(rel->r_info);
803 type = ELFW(R_TYPE)(rel->r_info);
804 if ((sym_index -= first_sym) < 0)
805 continue; /* zero sym_index in reloc (can happen with asm) */
806 sym_index = old_to_new_syms[sym_index];
807 rel->r_info = ELFW(R_INFO)(sym_index, type);
813 /* In an ELF file symbol table, the local symbols must appear below
814 the global and weak ones. Since TCC cannot sort it while generating
815 the code, we must do it after. All the relocation tables are also
816 modified to take into account the symbol table sorting */
817 static void sort_syms(TCCState *s1, Section *s)
819 int *old_to_new_syms;
820 ElfW(Sym) *new_syms;
821 int nb_syms, i;
822 ElfW(Sym) *p, *q;
824 nb_syms = s->data_offset / sizeof(ElfW(Sym));
825 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
826 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
828 /* first pass for local symbols */
829 p = (ElfW(Sym) *)s->data;
830 q = new_syms;
831 for(i = 0; i < nb_syms; i++) {
832 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
833 old_to_new_syms[i] = q - new_syms;
834 *q++ = *p;
836 p++;
838 /* save the number of local symbols in section header */
839 if( s->sh_size ) /* this 'if' makes IDA happy */
840 s->sh_info = q - new_syms;
842 /* then second pass for non local symbols */
843 p = (ElfW(Sym) *)s->data;
844 for(i = 0; i < nb_syms; i++) {
845 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
846 old_to_new_syms[i] = q - new_syms;
847 *q++ = *p;
849 p++;
852 /* we copy the new symbols to the old */
853 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
854 tcc_free(new_syms);
856 update_relocs(s1, s, old_to_new_syms, 0);
857 tcc_free(old_to_new_syms);
860 #ifndef ELF_OBJ_ONLY
861 /* See: https://flapenguin.me/elf-dt-gnu-hash */
862 #define ELFCLASS_BITS (PTR_SIZE * 8)
864 static Section *create_gnu_hash(TCCState *s1)
866 int nb_syms, i, ndef, nbuckets, symoffset, bloom_size, bloom_shift;
867 ElfW(Sym) *p;
868 Section *gnu_hash;
869 Section *dynsym = s1->dynsym;
870 Elf32_Word *ptr;
872 gnu_hash = new_section(s1, ".gnu.hash", SHT_GNU_HASH, SHF_ALLOC);
873 gnu_hash->link = dynsym->hash->link;
875 nb_syms = dynsym->data_offset / sizeof(ElfW(Sym));
877 /* count def symbols */
878 ndef = 0;
879 p = (ElfW(Sym) *)dynsym->data;
880 for(i = 0; i < nb_syms; i++, p++)
881 ndef += p->st_shndx != SHN_UNDEF;
883 /* calculate gnu hash sizes and fill header */
884 nbuckets = ndef / 4 + 1;
885 symoffset = nb_syms - ndef;
886 bloom_shift = PTR_SIZE == 8 ? 6 : 5;
887 bloom_size = 1; /* must be power of two */
888 while (ndef >= bloom_size * (1 << (bloom_shift - 3)))
889 bloom_size *= 2;
890 ptr = section_ptr_add(gnu_hash, 4 * 4 +
891 PTR_SIZE * bloom_size +
892 nbuckets * 4 +
893 ndef * 4);
894 ptr[0] = nbuckets;
895 ptr[1] = symoffset;
896 ptr[2] = bloom_size;
897 ptr[3] = bloom_shift;
898 return gnu_hash;
901 static Elf32_Word elf_gnu_hash (const unsigned char *name)
903 Elf32_Word h = 5381;
904 unsigned char c;
906 while ((c = *name++))
907 h = h * 33 + c;
908 return h;
911 static void update_gnu_hash(TCCState *s1, Section *gnu_hash)
913 int *old_to_new_syms;
914 ElfW(Sym) *new_syms;
915 int nb_syms, i, nbuckets, bloom_size, bloom_shift;
916 ElfW(Sym) *p, *q;
917 Section *vs;
918 Section *dynsym = s1->dynsym;
919 Elf32_Word *ptr, *buckets, *chain, *hash;
920 unsigned int *nextbuck;
921 addr_t *bloom;
922 unsigned char *strtab;
923 struct { int first, last; } *buck;
925 strtab = dynsym->link->data;
926 nb_syms = dynsym->data_offset / sizeof(ElfW(Sym));
927 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
928 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
929 hash = tcc_malloc(nb_syms * sizeof(Elf32_Word));
930 nextbuck = tcc_malloc(nb_syms * sizeof(int));
932 /* calculate hashes and copy undefs */
933 p = (ElfW(Sym) *)dynsym->data;
934 q = new_syms;
935 for(i = 0; i < nb_syms; i++, p++) {
936 if (p->st_shndx == SHN_UNDEF) {
937 old_to_new_syms[i] = q - new_syms;
938 *q++ = *p;
940 else
941 hash[i] = elf_gnu_hash(strtab + p->st_name);
944 ptr = (Elf32_Word *) gnu_hash->data;
945 nbuckets = ptr[0];
946 bloom_size = ptr[2];
947 bloom_shift = ptr[3];
948 bloom = (addr_t *) (void *) &ptr[4];
949 buckets = (Elf32_Word*) (void *) &bloom[bloom_size];
950 chain = &buckets[nbuckets];
951 buck = tcc_malloc(nbuckets * sizeof(*buck));
953 if (gnu_hash->data_offset != 4 * 4 +
954 PTR_SIZE * bloom_size +
955 nbuckets * 4 +
956 (nb_syms - (q - new_syms)) * 4)
957 tcc_error_noabort ("gnu_hash size incorrect");
959 /* find buckets */
960 for(i = 0; i < nbuckets; i++)
961 buck[i].first = -1;
963 p = (ElfW(Sym) *)dynsym->data;
964 for(i = 0; i < nb_syms; i++, p++)
965 if (p->st_shndx != SHN_UNDEF) {
966 int bucket = hash[i] % nbuckets;
968 if (buck[bucket].first == -1)
969 buck[bucket].first = buck[bucket].last = i;
970 else {
971 nextbuck[buck[bucket].last] = i;
972 buck[bucket].last = i;
976 /* fill buckets/chains/bloom and sort symbols */
977 p = (ElfW(Sym) *)dynsym->data;
978 for(i = 0; i < nbuckets; i++) {
979 int cur = buck[i].first;
981 if (cur != -1) {
982 buckets[i] = q - new_syms;
983 for (;;) {
984 old_to_new_syms[cur] = q - new_syms;
985 *q++ = p[cur];
986 *chain++ = hash[cur] & ~1;
987 bloom[(hash[cur] / ELFCLASS_BITS) % bloom_size] |=
988 (addr_t)1 << (hash[cur] % ELFCLASS_BITS) |
989 (addr_t)1 << ((hash[cur] >> bloom_shift) % ELFCLASS_BITS);
990 if (cur == buck[i].last)
991 break;
992 cur = nextbuck[cur];
994 chain[-1] |= 1;
998 memcpy(dynsym->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
999 tcc_free(new_syms);
1000 tcc_free(hash);
1001 tcc_free(buck);
1002 tcc_free(nextbuck);
1004 update_relocs(s1, dynsym, old_to_new_syms, 0);
1006 /* modify the versions */
1007 vs = versym_section;
1008 if (vs) {
1009 ElfW(Half) *newver, *versym = (ElfW(Half) *)vs->data;
1011 if (1/*versym*/) {
1012 newver = tcc_malloc(nb_syms * sizeof(*newver));
1013 for (i = 0; i < nb_syms; i++)
1014 newver[old_to_new_syms[i]] = versym[i];
1015 memcpy(vs->data, newver, nb_syms * sizeof(*newver));
1016 tcc_free(newver);
1020 tcc_free(old_to_new_syms);
1022 /* rebuild hash */
1023 ptr = (Elf32_Word *) dynsym->hash->data;
1024 rebuild_hash(dynsym, ptr[0]);
1026 #endif /* ELF_OBJ_ONLY */
1028 /* relocate symbol table, resolve undefined symbols if do_resolve is
1029 true and output error if undefined symbol. */
1030 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
1032 ElfW(Sym) *sym;
1033 int sym_bind, sh_num;
1034 const char *name;
1036 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
1037 sh_num = sym->st_shndx;
1038 if (sh_num == SHN_UNDEF) {
1039 if (do_resolve == 2) /* relocating dynsym */
1040 continue;
1041 name = (char *) s1->symtab->link->data + sym->st_name;
1042 /* Use ld.so to resolve symbol for us (for tcc -run) */
1043 if (do_resolve) {
1044 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
1045 /* dlsym() needs the undecorated name. */
1046 void *addr = dlsym(RTLD_DEFAULT, &name[s1->leading_underscore]);
1047 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD || TARGETOS_ANDROID
1048 if (addr == NULL) {
1049 int i;
1050 for (i = 0; i < s1->nb_loaded_dlls; i++)
1051 if ((addr = dlsym(s1->loaded_dlls[i]->handle, name)))
1052 break;
1054 #endif
1055 if (addr) {
1056 sym->st_value = (addr_t) addr;
1057 #ifdef DEBUG_RELOC
1058 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
1059 #endif
1060 goto found;
1062 #endif
1063 /* if dynamic symbol exist, it will be used in relocate_section */
1064 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
1065 goto found;
1066 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1067 it */
1068 if (!strcmp(name, "_fp_hw"))
1069 goto found;
1070 /* only weak symbols are accepted to be undefined. Their
1071 value is zero */
1072 sym_bind = ELFW(ST_BIND)(sym->st_info);
1073 if (sym_bind == STB_WEAK)
1074 sym->st_value = 0;
1075 else
1076 tcc_error_noabort("undefined symbol '%s'", name);
1078 } else if (sh_num < SHN_LORESERVE) {
1079 /* add section base */
1080 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1082 found: ;
1086 /* relocate a given section (CPU dependent) by applying the relocations
1087 in the associated relocation section */
1088 static void relocate_section(TCCState *s1, Section *s, Section *sr)
1090 ElfW_Rel *rel;
1091 ElfW(Sym) *sym;
1092 int type, sym_index;
1093 unsigned char *ptr;
1094 addr_t tgt, addr;
1095 int is_dwarf = s->sh_num >= s1->dwlo && s->sh_num < s1->dwhi;
1097 qrel = (ElfW_Rel *)sr->data;
1098 for_each_elem(sr, 0, rel, ElfW_Rel) {
1099 ptr = s->data + rel->r_offset;
1100 sym_index = ELFW(R_SYM)(rel->r_info);
1101 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1102 type = ELFW(R_TYPE)(rel->r_info);
1103 tgt = sym->st_value;
1104 #if SHT_RELX == SHT_RELA
1105 tgt += rel->r_addend;
1106 #endif
1107 if (is_dwarf && type == R_DATA_32DW
1108 && sym->st_shndx >= s1->dwlo && sym->st_shndx < s1->dwhi) {
1109 /* dwarf section relocation to each other */
1110 add32le(ptr, tgt - s1->sections[sym->st_shndx]->sh_addr);
1111 continue;
1113 addr = s->sh_addr + rel->r_offset;
1114 relocate(s1, rel, type, ptr, addr, tgt);
1116 #ifndef ELF_OBJ_ONLY
1117 /* if the relocation is allocated, we change its symbol table */
1118 if (sr->sh_flags & SHF_ALLOC) {
1119 sr->link = s1->dynsym;
1120 if (s1->output_type & TCC_OUTPUT_DYN) {
1121 size_t r = (uint8_t*)qrel - sr->data;
1122 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
1123 && 0 == strcmp(s->name, ".stab"))
1124 r = 0; /* cannot apply 64bit relocation to 32bit value */
1125 sr->data_offset = sr->sh_size = r;
1126 #ifdef CONFIG_TCC_PIE
1127 if (r && 0 == (s->sh_flags & SHF_WRITE))
1128 tcc_warning("%d relocations to ro-section %s", (unsigned)(r / sizeof *qrel), s->name);
1129 #endif
1132 #endif
1135 /* relocate all sections */
1136 ST_FUNC void relocate_sections(TCCState *s1)
1138 int i;
1139 Section *s, *sr;
1141 for (i = 1; i < s1->nb_sections; ++i) {
1142 sr = s1->sections[i];
1143 if (sr->sh_type != SHT_RELX)
1144 continue;
1145 s = s1->sections[sr->sh_info];
1146 #ifndef TCC_TARGET_MACHO
1147 if (s != s1->got
1148 || s1->static_link
1149 || s1->output_type == TCC_OUTPUT_MEMORY)
1150 #endif
1152 relocate_section(s1, s, sr);
1154 #ifndef ELF_OBJ_ONLY
1155 if (sr->sh_flags & SHF_ALLOC) {
1156 ElfW_Rel *rel;
1157 /* relocate relocation table in 'sr' */
1158 for_each_elem(sr, 0, rel, ElfW_Rel)
1159 rel->r_offset += s->sh_addr;
1161 #endif
1165 #ifndef ELF_OBJ_ONLY
1166 /* count the number of dynamic relocations so that we can reserve
1167 their space */
1168 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
1170 int count = 0;
1171 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1172 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1173 defined(TCC_TARGET_RISCV64)
1174 ElfW_Rel *rel;
1175 for_each_elem(sr, 0, rel, ElfW_Rel) {
1176 int sym_index = ELFW(R_SYM)(rel->r_info);
1177 int type = ELFW(R_TYPE)(rel->r_info);
1178 switch(type) {
1179 #if defined(TCC_TARGET_I386)
1180 case R_386_32:
1181 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
1182 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
1183 /* don't fixup unresolved (weak) symbols */
1184 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
1185 break;
1187 #elif defined(TCC_TARGET_X86_64)
1188 case R_X86_64_32:
1189 case R_X86_64_32S:
1190 case R_X86_64_64:
1191 #elif defined(TCC_TARGET_ARM)
1192 case R_ARM_ABS32:
1193 case R_ARM_TARGET1:
1194 #elif defined(TCC_TARGET_ARM64)
1195 case R_AARCH64_ABS32:
1196 case R_AARCH64_ABS64:
1197 #elif defined(TCC_TARGET_RISCV64)
1198 case R_RISCV_32:
1199 case R_RISCV_64:
1200 #endif
1201 count++;
1202 break;
1203 #if defined(TCC_TARGET_I386)
1204 case R_386_PC32:
1205 #elif defined(TCC_TARGET_X86_64)
1206 case R_X86_64_PC32:
1208 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1209 /* Hidden defined symbols can and must be resolved locally.
1210 We're misusing a PLT32 reloc for this, as that's always
1211 resolved to its address even in shared libs. */
1212 if (sym->st_shndx != SHN_UNDEF &&
1213 ELFW(ST_VISIBILITY)(sym->st_other) == STV_HIDDEN) {
1214 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PLT32);
1215 break;
1218 #elif defined(TCC_TARGET_ARM64)
1219 case R_AARCH64_PREL32:
1220 #endif
1221 if (s1->output_type != TCC_OUTPUT_DLL)
1222 break;
1223 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1224 count++;
1225 break;
1226 default:
1227 break;
1230 #endif
1231 return count;
1233 #endif
1235 #ifdef NEED_BUILD_GOT
1236 static int build_got(TCCState *s1)
1238 /* if no got, then create it */
1239 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1240 s1->got->sh_entsize = 4;
1241 /* keep space for _DYNAMIC pointer and two dummy got entries */
1242 section_ptr_add(s1->got, 3 * PTR_SIZE);
1243 return set_elf_sym(symtab_section, 0, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1244 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1247 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1248 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1249 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1250 Returns the offset of the GOT or (if any) PLT entry. */
1251 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1252 int sym_index)
1254 int need_plt_entry;
1255 const char *name;
1256 ElfW(Sym) *sym;
1257 struct sym_attr *attr;
1258 unsigned got_offset;
1259 char plt_name[200];
1260 int len;
1261 Section *s_rel;
1263 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1264 attr = get_sym_attr(s1, sym_index, 1);
1266 /* In case a function is both called and its address taken 2 GOT entries
1267 are created, one for taking the address (GOT) and the other for the PLT
1268 entry (PLTGOT). */
1269 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1270 return attr;
1272 s_rel = s1->got;
1273 if (need_plt_entry) {
1274 if (!s1->plt) {
1275 s1->plt = new_section(s1, ".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
1276 s1->plt->sh_entsize = 4;
1278 s_rel = s1->plt;
1281 /* create the GOT entry */
1282 got_offset = s1->got->data_offset;
1283 section_ptr_add(s1->got, PTR_SIZE);
1285 /* Create the GOT relocation that will insert the address of the object or
1286 function of interest in the GOT entry. This is a static relocation for
1287 memory output (dlsym will give us the address of symbols) and dynamic
1288 relocation otherwise (executable and DLLs). The relocation should be
1289 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1290 associated to a PLT entry) but is currently done at load time for an
1291 unknown reason. */
1293 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1294 name = (char *) symtab_section->link->data + sym->st_name;
1295 //printf("sym %d %s\n", need_plt_entry, name);
1297 if (s1->dynsym) {
1298 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1299 /* Hack alarm. We don't want to emit dynamic symbols
1300 and symbol based relocs for STB_LOCAL symbols, but rather
1301 want to resolve them directly. At this point the symbol
1302 values aren't final yet, so we must defer this. We will later
1303 have to create a RELATIVE reloc anyway, so we misuse the
1304 relocation slot to smuggle the symbol reference until
1305 fill_local_got_entries. Not that the sym_index is
1306 relative to symtab_section, not s1->dynsym! Nevertheless
1307 we use s1->dyn_sym so that if this is the first call
1308 that got->reloc is correctly created. Also note that
1309 RELATIVE relocs are not normally created for the .got,
1310 so the types serves as a marker for later (and is retained
1311 also for the final output, which is okay because then the
1312 got is just normal data). */
1313 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1314 sym_index);
1315 } else {
1316 if (0 == attr->dyn_index)
1317 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1318 sym->st_size, sym->st_info, 0,
1319 sym->st_shndx, name);
1320 put_elf_reloc(s1->dynsym, s_rel, got_offset, dyn_reloc_type,
1321 attr->dyn_index);
1323 } else {
1324 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1325 sym_index);
1328 if (need_plt_entry) {
1329 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1331 /* create a symbol 'sym@plt' for the PLT jump vector */
1332 len = strlen(name);
1333 if (len > sizeof plt_name - 5)
1334 len = sizeof plt_name - 5;
1335 memcpy(plt_name, name, len);
1336 strcpy(plt_name + len, "@plt");
1337 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, 0,
1338 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1339 } else {
1340 attr->got_offset = got_offset;
1343 return attr;
1346 /* build GOT and PLT entries */
1347 /* Two passes because R_JMP_SLOT should become first. Some targets
1348 (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1349 ST_FUNC void build_got_entries(TCCState *s1, int got_sym)
1351 Section *s;
1352 ElfW_Rel *rel;
1353 ElfW(Sym) *sym;
1354 int i, type, gotplt_entry, reloc_type, sym_index;
1355 struct sym_attr *attr;
1356 int pass = 0;
1357 redo:
1358 for(i = 1; i < s1->nb_sections; i++) {
1359 s = s1->sections[i];
1360 if (s->sh_type != SHT_RELX)
1361 continue;
1362 /* no need to handle got relocations */
1363 if (s->link != symtab_section)
1364 continue;
1365 for_each_elem(s, 0, rel, ElfW_Rel) {
1366 type = ELFW(R_TYPE)(rel->r_info);
1367 gotplt_entry = gotplt_entry_type(type);
1368 if (gotplt_entry == -1) {
1369 tcc_error_noabort ("Unknown relocation type for got: %d", type);
1370 continue;
1372 sym_index = ELFW(R_SYM)(rel->r_info);
1373 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1375 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1376 continue;
1379 /* Automatically create PLT/GOT [entry] if it is an undefined
1380 reference (resolved at runtime), or the symbol is absolute,
1381 probably created by tcc_add_symbol, and thus on 64-bit
1382 targets might be too far from application code. */
1383 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1384 if (sym->st_shndx == SHN_UNDEF) {
1385 ElfW(Sym) *esym;
1386 int dynindex;
1387 if (!PCRELATIVE_DLLPLT
1388 && (s1->output_type & TCC_OUTPUT_DYN))
1389 continue;
1390 /* Relocations for UNDEF symbols would normally need
1391 to be transferred into the executable or shared object.
1392 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1393 But TCC doesn't do that (at least for exes), so we
1394 need to resolve all such relocs locally. And that
1395 means PLT slots for functions in DLLs and COPY relocs for
1396 data symbols. COPY relocs were generated in
1397 bind_exe_dynsyms (and the symbol adjusted to be defined),
1398 and for functions we were generated a dynamic symbol
1399 of function type. */
1400 if (s1->dynsym) {
1401 /* dynsym isn't set for -run :-/ */
1402 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1403 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1404 if (dynindex
1405 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1406 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1407 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1408 goto jmp_slot;
1410 } else if (sym->st_shndx == SHN_ABS) {
1411 if (sym->st_value == 0) /* from tcc_add_btstub() */
1412 continue;
1413 #ifndef TCC_TARGET_ARM
1414 if (PTR_SIZE != 8)
1415 continue;
1416 #endif
1417 /* from tcc_add_symbol(): on 64 bit platforms these
1418 need to go through .got */
1419 } else
1420 continue;
1423 #ifdef TCC_TARGET_X86_64
1424 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1425 sym->st_shndx != SHN_UNDEF &&
1426 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1427 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1428 s1->output_type & TCC_OUTPUT_EXE)) {
1429 if (pass != 0)
1430 continue;
1431 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1432 continue;
1434 #endif
1435 reloc_type = code_reloc(type);
1436 if (reloc_type == -1) {
1437 tcc_error_noabort ("Unknown relocation type: %d", type);
1438 continue;
1441 if (reloc_type != 0) {
1442 jmp_slot:
1443 if (pass != 0)
1444 continue;
1445 reloc_type = R_JMP_SLOT;
1446 } else {
1447 if (pass != 1)
1448 continue;
1449 reloc_type = R_GLOB_DAT;
1452 if (!s1->got)
1453 got_sym = build_got(s1);
1455 if (gotplt_entry == BUILD_GOT_ONLY)
1456 continue;
1458 attr = put_got_entry(s1, reloc_type, sym_index);
1460 if (reloc_type == R_JMP_SLOT)
1461 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1464 if (++pass < 2)
1465 goto redo;
1466 /* .rel.plt refers to .got actually */
1467 if (s1->plt && s1->plt->reloc)
1468 s1->plt->reloc->sh_info = s1->got->sh_num;
1469 if (got_sym) /* set size */
1470 ((ElfW(Sym)*)symtab_section->data)[got_sym].st_size = s1->got->data_offset;
1472 #endif /* def NEED_BUILD_GOT */
1474 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
1476 int shn = sec ? sec->sh_num : offs || !name ? SHN_ABS : SHN_UNDEF;
1477 if (sec && offs == -1)
1478 offs = sec->data_offset;
1479 return set_elf_sym(symtab_section, offs, 0,
1480 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1483 static void add_init_array_defines(TCCState *s1, const char *section_name)
1485 Section *s;
1486 addr_t end_offset;
1487 char buf[1024];
1488 s = have_section(s1, section_name);
1489 if (!s || !(s->sh_flags & SHF_ALLOC)) {
1490 end_offset = 0;
1491 s = text_section;
1492 } else {
1493 end_offset = s->data_offset;
1495 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1496 set_global_sym(s1, buf, s, 0);
1497 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1498 set_global_sym(s1, buf, s, end_offset);
1501 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1503 Section *s;
1504 s = find_section(s1, sec);
1505 s->sh_flags = shf_RELRO;
1506 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1507 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1508 section_ptr_add(s, PTR_SIZE);
1511 #ifdef CONFIG_TCC_BCHECK
1512 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1514 if (0 == s1->do_bounds_check)
1515 return;
1516 section_ptr_add(bounds_section, sizeof(addr_t));
1518 #endif
1520 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1521 a dynamic symbol to allow so's to have one each with a different value. */
1522 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1524 int c = find_elf_sym(s1->symtab, name);
1525 if (c) {
1526 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1527 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1528 esym->st_value = offset;
1529 esym->st_shndx = s->sh_num;
1533 /* avoid generating debug/test_coverage code for stub functions */
1534 static void tcc_compile_string_no_debug(TCCState *s, const char *str)
1536 int save_do_debug = s->do_debug;
1537 int save_test_coverage = s->test_coverage;
1539 s->do_debug = 0;
1540 s->test_coverage = 0;
1541 tcc_compile_string(s, str);
1542 s->do_debug = save_do_debug;
1543 s->test_coverage = save_test_coverage;
1546 #ifdef CONFIG_TCC_BACKTRACE
1547 static void put_ptr(TCCState *s1, Section *s, int offs)
1549 int c;
1550 c = set_global_sym(s1, NULL, s, offs);
1551 s = data_section;
1552 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1553 section_ptr_add(s, PTR_SIZE);
1556 ST_FUNC void tcc_add_btstub(TCCState *s1)
1558 Section *s;
1559 int n, o, *p;
1560 CString cstr;
1561 const char *__rt_info = &"___rt_info"[!s1->leading_underscore];
1563 s = data_section;
1564 /* Align to PTR_SIZE */
1565 section_ptr_add(s, -s->data_offset & (PTR_SIZE - 1));
1566 o = s->data_offset;
1567 /* create a struct rt_context (see tccrun.c) */
1568 if (s1->dwarf) {
1569 put_ptr(s1, dwarf_line_section, 0);
1570 put_ptr(s1, dwarf_line_section, -1);
1571 if (s1->dwarf >= 5)
1572 put_ptr(s1, dwarf_line_str_section, 0);
1573 else
1574 put_ptr(s1, dwarf_str_section, 0);
1576 else
1578 put_ptr(s1, stab_section, 0);
1579 put_ptr(s1, stab_section, -1);
1580 put_ptr(s1, stab_section->link, 0);
1583 /* skip esym_start/esym_end/elf_str (not loaded) */
1584 section_ptr_add(s, 3 * PTR_SIZE);
1586 if (s1->output_type == TCC_OUTPUT_MEMORY && 0 == s1->dwarf) {
1587 put_ptr(s1, text_section, 0);
1588 } else {
1589 /* prog_base : local nameless symbol with offset 0 at SHN_ABS */
1590 put_ptr(s1, NULL, 0);
1591 #if defined TCC_TARGET_MACHO
1592 /* adjust for __PAGEZERO */
1593 if (s1->dwarf == 0 && s1->output_type == TCC_OUTPUT_EXE)
1594 write64le(data_section->data + data_section->data_offset - PTR_SIZE,
1595 (uint64_t)1 << 32);
1596 #endif
1598 n = 3 * PTR_SIZE;
1599 #ifdef CONFIG_TCC_BCHECK
1600 if (s1->do_bounds_check) {
1601 put_ptr(s1, bounds_section, 0);
1602 n -= PTR_SIZE;
1604 #endif
1605 section_ptr_add(s, n);
1606 p = section_ptr_add(s, 2 * sizeof (int));
1607 p[0] = s1->rt_num_callers;
1608 p[1] = s1->dwarf;
1609 // if (s->data_offset - o != 10*PTR_SIZE + 2*sizeof (int)) exit(99);
1611 if (s1->output_type == TCC_OUTPUT_MEMORY) {
1612 set_global_sym(s1, __rt_info, s, o);
1613 return;
1616 cstr_new(&cstr);
1617 cstr_printf(&cstr,
1618 "extern void __bt_init(),__bt_exit(),__bt_init_dll();"
1619 "static void *__rt_info[];"
1620 "__attribute__((constructor)) static void __bt_init_rt(){");
1621 #ifdef TCC_TARGET_PE
1622 if (s1->output_type == TCC_OUTPUT_DLL)
1623 #ifdef CONFIG_TCC_BCHECK
1624 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1625 #else
1626 cstr_printf(&cstr, "__bt_init_dll(0);");
1627 #endif
1628 #endif
1629 cstr_printf(&cstr, "__bt_init(__rt_info,%d);}",
1630 s1->output_type != TCC_OUTPUT_DLL);
1631 /* In case dlcose is called by application */
1632 cstr_printf(&cstr,
1633 "__attribute__((destructor)) static void __bt_exit_rt(){"
1634 "__bt_exit(__rt_info);}");
1635 tcc_compile_string_no_debug(s1, cstr.data);
1636 cstr_free(&cstr);
1637 set_local_sym(s1, __rt_info, s, o);
1639 #endif /* def CONFIG_TCC_BACKTRACE */
1641 static void tcc_tcov_add_file(TCCState *s1, const char *filename)
1643 CString cstr;
1644 void *ptr;
1645 char wd[1024];
1647 if (tcov_section == NULL)
1648 return;
1649 section_ptr_add(tcov_section, 1);
1650 write32le (tcov_section->data, tcov_section->data_offset);
1652 cstr_new (&cstr);
1653 if (filename[0] == '/')
1654 cstr_printf (&cstr, "%s.tcov", filename);
1655 else {
1656 getcwd (wd, sizeof(wd));
1657 cstr_printf (&cstr, "%s/%s.tcov", wd, filename);
1659 ptr = section_ptr_add(tcov_section, cstr.size + 1);
1660 strcpy((char *)ptr, cstr.data);
1661 unlink((char *)ptr);
1662 #ifdef _WIN32
1663 normalize_slashes((char *)ptr);
1664 #endif
1665 cstr_free (&cstr);
1667 cstr_new(&cstr);
1668 cstr_printf(&cstr,
1669 "extern char *__tcov_data[];"
1670 "extern void __store_test_coverage ();"
1671 "__attribute__((destructor)) static void __tcov_exit() {"
1672 "__store_test_coverage(__tcov_data);"
1673 "}");
1674 tcc_compile_string_no_debug(s1, cstr.data);
1675 cstr_free(&cstr);
1676 set_local_sym(s1, &"___tcov_data"[!s1->leading_underscore], tcov_section, 0);
1679 #if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO
1680 /* add libc crt1/crti objects */
1681 ST_FUNC void tccelf_add_crtbegin(TCCState *s1)
1683 #if TARGETOS_OpenBSD
1684 if (s1->output_type != TCC_OUTPUT_DLL)
1685 tcc_add_crt(s1, "crt0.o");
1686 if (s1->output_type == TCC_OUTPUT_DLL)
1687 tcc_add_crt(s1, "crtbeginS.o");
1688 else
1689 tcc_add_crt(s1, "crtbegin.o");
1690 #elif TARGETOS_FreeBSD || TARGETOS_NetBSD
1691 if (s1->output_type != TCC_OUTPUT_DLL)
1692 #if TARGETOS_FreeBSD
1693 tcc_add_crt(s1, "crt1.o");
1694 #else
1695 tcc_add_crt(s1, "crt0.o");
1696 #endif
1697 tcc_add_crt(s1, "crti.o");
1698 if (s1->static_link)
1699 tcc_add_crt(s1, "crtbeginT.o");
1700 else if (s1->output_type == TCC_OUTPUT_DLL)
1701 tcc_add_crt(s1, "crtbeginS.o");
1702 else
1703 tcc_add_crt(s1, "crtbegin.o");
1704 #elif TARGETOS_ANDROID
1705 if (s1->output_type == TCC_OUTPUT_DLL)
1706 tcc_add_crt(s1, "crtbegin_so.o");
1707 else
1708 tcc_add_crt(s1, "crtbegin_dynamic.o");
1709 #else
1710 if (s1->output_type != TCC_OUTPUT_DLL)
1711 tcc_add_crt(s1, "crt1.o");
1712 tcc_add_crt(s1, "crti.o");
1713 #endif
1716 ST_FUNC void tccelf_add_crtend(TCCState *s1)
1718 #if TARGETOS_OpenBSD
1719 if (s1->output_type == TCC_OUTPUT_DLL)
1720 tcc_add_crt(s1, "crtendS.o");
1721 else
1722 tcc_add_crt(s1, "crtend.o");
1723 #elif TARGETOS_FreeBSD || TARGETOS_NetBSD
1724 if (s1->output_type == TCC_OUTPUT_DLL)
1725 tcc_add_crt(s1, "crtendS.o");
1726 else
1727 tcc_add_crt(s1, "crtend.o");
1728 tcc_add_crt(s1, "crtn.o");
1729 #elif TARGETOS_ANDROID
1730 if (s1->output_type == TCC_OUTPUT_DLL)
1731 tcc_add_crt(s1, "crtend_so.o");
1732 else
1733 tcc_add_crt(s1, "crtend_android.o");
1734 #else
1735 tcc_add_crt(s1, "crtn.o");
1736 #endif
1738 #endif /* !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO */
1740 #ifndef TCC_TARGET_PE
1741 /* add tcc runtime libraries */
1742 ST_FUNC void tcc_add_runtime(TCCState *s1)
1744 s1->filetype = 0;
1746 #ifdef CONFIG_TCC_BCHECK
1747 tcc_add_bcheck(s1);
1748 #endif
1749 tcc_add_pragma_libs(s1);
1751 /* add libc */
1752 if (!s1->nostdlib) {
1753 int lpthread = s1->option_pthread;
1755 #ifdef CONFIG_TCC_BCHECK
1756 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1757 tcc_add_support(s1, "bcheck.o");
1758 # if !(TARGETOS_OpenBSD || TARGETOS_NetBSD)
1759 tcc_add_library_err(s1, "dl");
1760 # endif
1761 lpthread = 1;
1763 #endif
1764 #ifdef CONFIG_TCC_BACKTRACE
1765 if (s1->do_backtrace) {
1766 if (s1->output_type & TCC_OUTPUT_EXE)
1767 tcc_add_support(s1, "bt-exe.o");
1768 if (s1->output_type != TCC_OUTPUT_DLL)
1769 tcc_add_support(s1, "bt-log.o");
1770 tcc_add_btstub(s1);
1771 lpthread = 1;
1773 #endif
1774 if (lpthread)
1775 tcc_add_library_err(s1, "pthread");
1776 tcc_add_library_err(s1, "c");
1777 #ifdef TCC_LIBGCC
1778 if (!s1->static_link) {
1779 if (TCC_LIBGCC[0] == '/')
1780 tcc_add_file(s1, TCC_LIBGCC);
1781 else
1782 tcc_add_dll(s1, TCC_LIBGCC, AFF_PRINT_ERROR);
1784 #endif
1785 #if defined TCC_TARGET_ARM && TARGETOS_FreeBSD
1786 tcc_add_library_err(s1, "gcc_s"); // unwind code
1787 #endif
1788 if (TCC_LIBTCC1[0])
1789 tcc_add_support(s1, TCC_LIBTCC1);
1790 #ifndef TCC_TARGET_MACHO
1791 if (s1->output_type != TCC_OUTPUT_MEMORY)
1792 tccelf_add_crtend(s1);
1793 #endif
1796 #endif /* ndef TCC_TARGET_PE */
1798 /* add various standard linker symbols (must be done after the
1799 sections are filled (for example after allocating common
1800 symbols)) */
1801 static void tcc_add_linker_symbols(TCCState *s1)
1803 char buf[1024];
1804 int i;
1805 Section *s;
1807 set_global_sym(s1, "_etext", text_section, -1);
1808 set_global_sym(s1, "_edata", data_section, -1);
1809 set_global_sym(s1, "_end", bss_section, -1);
1810 #if TARGETOS_OpenBSD
1811 set_global_sym(s1, "__executable_start", NULL, ELF_START_ADDR);
1812 #endif
1813 #ifdef TCC_TARGET_RISCV64
1814 /* XXX should be .sdata+0x800, not .data+0x800 */
1815 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1816 #endif
1817 /* horrible new standard ldscript defines */
1818 add_init_array_defines(s1, ".preinit_array");
1819 add_init_array_defines(s1, ".init_array");
1820 add_init_array_defines(s1, ".fini_array");
1821 /* add start and stop symbols for sections whose name can be
1822 expressed in C */
1823 for(i = 1; i < s1->nb_sections; i++) {
1824 s = s1->sections[i];
1825 if ((s->sh_flags & SHF_ALLOC)
1826 && (s->sh_type == SHT_PROGBITS || s->sh_type == SHT_NOBITS
1827 || s->sh_type == SHT_STRTAB)) {
1828 /* check if section name can be expressed in C */
1829 const char *p0, *p;
1830 p0 = s->name;
1831 if (*p0 == '.')
1832 ++p0;
1833 p = p0;
1834 for(;;) {
1835 int c = *p;
1836 if (!c)
1837 break;
1838 if (!isid(c) && !isnum(c))
1839 goto next_sec;
1840 p++;
1842 snprintf(buf, sizeof(buf), "__start_%s", p0);
1843 set_global_sym(s1, buf, s, 0);
1844 snprintf(buf, sizeof(buf), "__stop_%s", p0);
1845 set_global_sym(s1, buf, s, -1);
1847 next_sec: ;
1851 ST_FUNC void resolve_common_syms(TCCState *s1)
1853 ElfW(Sym) *sym;
1855 /* Allocate common symbols in BSS. */
1856 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1857 if (sym->st_shndx == SHN_COMMON) {
1858 /* symbol alignment is in st_value for SHN_COMMONs */
1859 sym->st_value = section_add(bss_section, sym->st_size,
1860 sym->st_value);
1861 sym->st_shndx = bss_section->sh_num;
1865 /* Now assign linker provided symbols their value. */
1866 tcc_add_linker_symbols(s1);
1869 #ifndef ELF_OBJ_ONLY
1870 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1872 int sym_index = ELFW(R_SYM) (rel->r_info);
1873 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1874 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1875 unsigned offset = attr->got_offset;
1877 if (0 == offset)
1878 return;
1879 section_reserve(s1->got, offset + PTR_SIZE);
1880 #if PTR_SIZE == 8
1881 write64le(s1->got->data + offset, sym->st_value);
1882 #else
1883 write32le(s1->got->data + offset, sym->st_value);
1884 #endif
1887 /* Perform relocation to GOT or PLT entries */
1888 ST_FUNC void fill_got(TCCState *s1)
1890 Section *s;
1891 ElfW_Rel *rel;
1892 int i;
1894 for(i = 1; i < s1->nb_sections; i++) {
1895 s = s1->sections[i];
1896 if (s->sh_type != SHT_RELX)
1897 continue;
1898 /* no need to handle got relocations */
1899 if (s->link != symtab_section)
1900 continue;
1901 for_each_elem(s, 0, rel, ElfW_Rel) {
1902 switch (ELFW(R_TYPE) (rel->r_info)) {
1903 case R_X86_64_GOT32:
1904 case R_X86_64_GOTPCREL:
1905 case R_X86_64_GOTPCRELX:
1906 case R_X86_64_REX_GOTPCRELX:
1907 case R_X86_64_PLT32:
1908 fill_got_entry(s1, rel);
1909 break;
1915 /* See put_got_entry for a description. This is the second stage
1916 where GOT references to local defined symbols are rewritten. */
1917 static void fill_local_got_entries(TCCState *s1)
1919 ElfW_Rel *rel;
1920 if (!s1->got->reloc)
1921 return;
1922 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1923 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1924 int sym_index = ELFW(R_SYM) (rel->r_info);
1925 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1926 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1927 unsigned offset = attr->got_offset;
1928 if (offset != rel->r_offset - s1->got->sh_addr)
1929 tcc_error_noabort("fill_local_got_entries: huh?");
1930 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1931 #if SHT_RELX == SHT_RELA
1932 rel->r_addend = sym->st_value;
1933 #else
1934 /* All our REL architectures also happen to be 32bit LE. */
1935 write32le(s1->got->data + offset, sym->st_value);
1936 #endif
1941 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1942 in shared libraries */
1943 static void bind_exe_dynsyms(TCCState *s1, int is_PIE)
1945 const char *name;
1946 int sym_index, index;
1947 ElfW(Sym) *sym, *esym;
1948 int type;
1950 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1951 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1952 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1953 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1954 if (sym->st_shndx == SHN_UNDEF) {
1955 name = (char *) symtab_section->link->data + sym->st_name;
1956 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1957 if (sym_index) {
1958 if (is_PIE)
1959 continue;
1960 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1961 type = ELFW(ST_TYPE)(esym->st_info);
1962 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1963 /* Indirect functions shall have STT_FUNC type in executable
1964 * dynsym section. Indeed, a dlsym call following a lazy
1965 * resolution would pick the symbol value from the
1966 * executable dynsym entry which would contain the address
1967 * of the function wanted by the caller of dlsym instead of
1968 * the address of the function that would return that
1969 * address */
1970 int dynindex
1971 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1972 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1973 name);
1974 int index = sym - (ElfW(Sym) *) symtab_section->data;
1975 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1976 } else if (type == STT_OBJECT) {
1977 unsigned long offset;
1978 ElfW(Sym) *dynsym;
1979 offset = bss_section->data_offset;
1980 /* XXX: which alignment ? */
1981 offset = (offset + 16 - 1) & -16;
1982 set_elf_sym (s1->symtab, offset, esym->st_size,
1983 esym->st_info, 0, bss_section->sh_num, name);
1984 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1985 esym->st_info, 0, bss_section->sh_num,
1986 name);
1988 /* Ensure R_COPY works for weak symbol aliases */
1989 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1990 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1991 if ((dynsym->st_value == esym->st_value)
1992 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1993 char *dynname = (char *) s1->dynsymtab_section->link->data
1994 + dynsym->st_name;
1995 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1996 dynsym->st_info, 0,
1997 bss_section->sh_num, dynname);
1998 break;
2003 put_elf_reloc(s1->dynsym, bss_section,
2004 offset, R_COPY, index);
2005 offset += esym->st_size;
2006 bss_section->data_offset = offset;
2008 } else {
2009 /* STB_WEAK undefined symbols are accepted */
2010 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
2011 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
2012 !strcmp(name, "_fp_hw")) {
2013 } else {
2014 tcc_error_noabort("undefined symbol '%s'", name);
2021 /* Bind symbols of libraries: export all non local symbols of executable that
2022 are referenced by shared libraries. The reason is that the dynamic loader
2023 search symbol first in executable and then in libraries. Therefore a
2024 reference to a symbol already defined by a library can still be resolved by
2025 a symbol in the executable. With -rdynamic, export all defined symbols */
2026 static void bind_libs_dynsyms(TCCState *s1)
2028 const char *name;
2029 int dynsym_index;
2030 ElfW(Sym) *sym, *esym;
2032 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
2033 name = (char *)symtab_section->link->data + sym->st_name;
2034 dynsym_index = find_elf_sym(s1->dynsymtab_section, name);
2035 if (sym->st_shndx != SHN_UNDEF) {
2036 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL
2037 && (dynsym_index || s1->rdynamic))
2038 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
2039 sym->st_info, 0, sym->st_shndx, name);
2040 } else if (dynsym_index) {
2041 esym = (ElfW(Sym) *)s1->dynsymtab_section->data + dynsym_index;
2042 if (esym->st_shndx == SHN_UNDEF) {
2043 /* weak symbols can stay undefined */
2044 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
2045 tcc_warning("undefined dynamic symbol '%s'", name);
2051 /* Export all non local symbols. This is used by shared libraries so that the
2052 non local symbols they define can resolve a reference in another shared
2053 library or in the executable. Correspondingly, it allows undefined local
2054 symbols to be resolved by other shared libraries or by the executable. */
2055 static void export_global_syms(TCCState *s1)
2057 int dynindex, index;
2058 const char *name;
2059 ElfW(Sym) *sym;
2060 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
2061 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2062 name = (char *) symtab_section->link->data + sym->st_name;
2063 dynindex = set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
2064 sym->st_info, 0, sym->st_shndx, name);
2065 index = sym - (ElfW(Sym) *) symtab_section->data;
2066 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
2071 /* decide if an unallocated section should be output. */
2072 static int set_sec_sizes(TCCState *s1)
2074 int i;
2075 Section *s;
2076 int textrel = 0;
2077 int file_type = s1->output_type;
2079 /* Allocate strings for section names */
2080 for(i = 1; i < s1->nb_sections; i++) {
2081 s = s1->sections[i];
2082 if (s->sh_type == SHT_RELX && !(s->sh_flags & SHF_ALLOC)) {
2083 /* when generating a DLL, we include relocations but
2084 we may patch them */
2085 if ((file_type & TCC_OUTPUT_DYN)
2086 && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) {
2087 int count = prepare_dynamic_rel(s1, s);
2088 if (count) {
2089 /* allocate the section */
2090 s->sh_flags |= SHF_ALLOC;
2091 s->sh_size = count * sizeof(ElfW_Rel);
2092 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
2093 textrel += count;
2096 } else if ((s->sh_flags & SHF_ALLOC)
2097 #ifdef TCC_TARGET_ARM
2098 || s->sh_type == SHT_ARM_ATTRIBUTES
2099 #endif
2100 || s1->do_debug) {
2101 s->sh_size = s->data_offset;
2104 #ifdef TCC_TARGET_ARM
2105 /* XXX: Suppress stack unwinding section. */
2106 if (s->sh_type == SHT_ARM_EXIDX) {
2107 s->sh_flags = 0;
2108 s->sh_size = 0;
2110 #endif
2113 return textrel;
2116 /* various data used under elf_output_file() */
2117 struct dyn_inf {
2118 Section *dynamic;
2119 Section *dynstr;
2120 struct {
2121 /* Info to be copied in dynamic section */
2122 unsigned long data_offset;
2123 addr_t rel_addr;
2124 addr_t rel_size;
2127 ElfW(Phdr) *phdr;
2128 int phnum;
2129 int shnum;
2130 Section *interp;
2131 Section *note;
2132 Section *gnu_hash;
2134 /* read only segment mapping for GNU_RELRO */
2135 Section _roinf, *roinf;
2138 /* Decide the layout of sections loaded in memory. This must be done before
2139 program headers are filled since they contain info about the layout.
2140 We do the following ordering: interp, symbol tables, relocations, progbits,
2141 nobits */
2142 static int sort_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
2144 Section *s;
2145 int i, j, k, f, f0, n;
2146 int nb_sections = s1->nb_sections;
2147 int *sec_cls = sec_order + nb_sections;
2149 for (i = 1; i < nb_sections; i++) {
2150 s = s1->sections[i];
2151 if (0 == s->sh_name) {
2152 j = 0x900; /* no sh_name: won't go to file */
2153 } else if (s->sh_flags & SHF_ALLOC) {
2154 j = 0x100;
2155 if (s->sh_flags & SHF_WRITE)
2156 j = 0x200;
2157 if (s->sh_flags & SHF_TLS)
2158 j += 0x200;
2159 } else {
2160 j = 0x700;
2162 if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_DYNSYM) {
2163 k = 0x10;
2164 } else if (s->sh_type == SHT_STRTAB && strcmp(s->name, ".stabstr")) {
2165 k = 0x11;
2166 if (i == nb_sections - 1) /* ".shstrtab" assumed to remain last */
2167 k = 0xff;
2168 } else if (s->sh_type == SHT_HASH || s->sh_type == SHT_GNU_HASH) {
2169 k = 0x12;
2170 } else if (s->sh_type == SHT_RELX) {
2171 k = 0x20;
2172 if (s1->plt && s == s1->plt->reloc)
2173 k = 0x21;
2174 } else if (s->sh_type == SHT_PREINIT_ARRAY) {
2175 k = 0x41;
2176 } else if (s->sh_type == SHT_INIT_ARRAY) {
2177 k = 0x42;
2178 } else if (s->sh_type == SHT_FINI_ARRAY) {
2179 k = 0x43;
2180 #ifdef CONFIG_TCC_BCHECK
2181 } else if (s == bounds_section || s == lbounds_section) {
2182 k = 0x44;
2183 #endif
2184 } else if (s == rodata_section || 0 == strcmp(s->name, ".data.rel.ro")) {
2185 k = 0x45;
2186 } else if (s->sh_type == SHT_DYNAMIC) {
2187 k = 0x46;
2188 } else if (s == s1->got) {
2189 k = 0x47; /* .got as RELRO needs BIND_NOW in DT_FLAGS */
2190 } else {
2191 k = 0x50;
2192 if (s->sh_type == SHT_NOTE)
2193 k = 0x60;
2194 if (s->sh_flags & SHF_EXECINSTR)
2195 k = 0x70;
2196 if (s->sh_type == SHT_NOBITS)
2197 k = 0x80;
2198 if (s == d->interp)
2199 k = 0x00;
2201 k += j;
2203 for (n = i; n > 1 && k < (f = sec_cls[n - 1]); --n)
2204 sec_cls[n] = f, sec_order[n] = sec_order[n - 1];
2205 sec_cls[n] = k, sec_order[n] = i;
2207 sec_order[0] = 0;
2208 d->shnum = 1;
2210 /* count PT_LOAD headers needed */
2211 n = f0 = 0;
2212 for (i = 1; i < nb_sections; i++) {
2213 s = s1->sections[sec_order[i]];
2214 k = sec_cls[i];
2215 f = 0;
2216 if (k < 0x900)
2217 ++d->shnum;
2218 if (k < 0x700) {
2219 f = s->sh_flags & (SHF_ALLOC|SHF_WRITE|SHF_EXECINSTR|SHF_TLS);
2220 #if TARGETOS_NetBSD
2221 /* NetBSD only supports 2 PT_LOAD sections.
2222 See: https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */
2223 if ((f & SHF_WRITE) == 0)
2224 f |= SHF_EXECINSTR;
2225 #else
2226 if ((k & 0xfff0) == 0x240) /* RELRO sections */
2227 f |= 1<<4;
2228 #endif
2229 /* start new header when flags changed or relro, but avoid zero memsz */
2230 if (f != f0 && s->sh_size)
2231 f0 = f, ++n, f |= 1<<8;
2233 sec_cls[i] = f;
2234 //printf("ph %d sec %02d : %3X %3X %8.2X %04X %s\n", (f>0) * n, i, f, k, s->sh_type, s->sh_size, s->name);
2236 return n;
2239 static ElfW(Phdr) *fill_phdr(ElfW(Phdr) *ph, int type, Section *s)
2241 if (s) {
2242 ph->p_offset = s->sh_offset;
2243 ph->p_vaddr = s->sh_addr;
2244 ph->p_filesz = s->sh_size;
2245 ph->p_align = s->sh_addralign;
2247 ph->p_type = type;
2248 ph->p_flags = PF_R;
2249 ph->p_paddr = ph->p_vaddr;
2250 ph->p_memsz = ph->p_filesz;
2251 return ph;
2254 /* Assign sections to segments and decide how are sections laid out when loaded
2255 in memory. This function also fills corresponding program headers. */
2256 static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
2258 Section *s;
2259 addr_t addr, tmp, align, s_align, base;
2260 ElfW(Phdr) *ph = NULL;
2261 int i, f, n, phnum, phfill;
2262 int file_offset;
2264 /* compute number of program headers */
2265 phnum = sort_sections(s1, sec_order, d);
2266 phfill = 0; /* set to 1 to have dll's with a PT_PHDR */
2267 if (d->interp)
2268 phfill = 2;
2269 phnum += phfill;
2270 if (d->note)
2271 ++phnum;
2272 if (d->dynamic)
2273 ++phnum;
2274 if (d->roinf)
2275 ++phnum;
2276 d->phnum = phnum;
2277 d->phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2279 file_offset = 0;
2280 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
2281 file_offset = (sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)) + 3) & -4;
2282 file_offset += d->shnum * sizeof (ElfW(Shdr));
2285 s_align = ELF_PAGE_SIZE;
2286 if (s1->section_align)
2287 s_align = s1->section_align;
2289 addr = ELF_START_ADDR;
2290 if (s1->output_type & TCC_OUTPUT_DYN)
2291 addr = 0;
2293 if (s1->has_text_addr) {
2294 addr = s1->text_addr;
2295 if (0) {
2296 int a_offset, p_offset;
2297 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
2298 ELF_PAGE_SIZE */
2299 a_offset = (int) (addr & (s_align - 1));
2300 p_offset = file_offset & (s_align - 1);
2301 if (a_offset < p_offset)
2302 a_offset += s_align;
2303 file_offset += (a_offset - p_offset);
2306 base = addr;
2307 /* compute address after headers */
2308 addr = addr + (file_offset & (s_align - 1));
2310 n = 0;
2311 for(i = 1; i < s1->nb_sections; i++) {
2312 s = s1->sections[sec_order[i]];
2313 f = sec_order[i + s1->nb_sections];
2314 align = s->sh_addralign - 1;
2316 if (f == 0) { /* no alloc */
2317 file_offset = (file_offset + align) & ~align;
2318 s->sh_offset = file_offset;
2319 if (s->sh_type != SHT_NOBITS)
2320 file_offset += s->sh_size;
2321 continue;
2324 if ((f & 1<<8) && n) {
2325 /* different rwx section flags */
2326 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
2327 /* if in the middle of a page, w e duplicate the page in
2328 memory so that one copy is RX and the other is RW */
2329 if ((addr & (s_align - 1)) != 0)
2330 addr += s_align;
2331 } else {
2332 align = s_align - 1;
2336 tmp = addr;
2337 addr = (addr + align) & ~align;
2338 file_offset += (int)(addr - tmp);
2339 s->sh_offset = file_offset;
2340 s->sh_addr = addr;
2342 if (f & 1<<8) {
2343 /* set new program header */
2344 ph = &d->phdr[phfill + n];
2345 ph->p_type = PT_LOAD;
2346 ph->p_align = s_align;
2347 ph->p_flags = PF_R;
2348 if (f & SHF_WRITE)
2349 ph->p_flags |= PF_W;
2350 if (f & SHF_EXECINSTR)
2351 ph->p_flags |= PF_X;
2352 if (f & SHF_TLS) {
2353 ph->p_type = PT_TLS;
2354 ph->p_align = align + 1;
2357 ph->p_offset = file_offset;
2358 ph->p_vaddr = addr;
2359 if (n == 0) {
2360 /* Make the first PT_LOAD segment include the program
2361 headers itself (and the ELF header as well), it'll
2362 come out with same memory use but will make various
2363 tools like binutils strip work better. */
2364 ph->p_offset = 0;
2365 ph->p_vaddr = base;
2367 ph->p_paddr = ph->p_vaddr;
2368 ++n;
2371 if (f & 1<<4) {
2372 Section *roinf = &d->_roinf;
2373 if (roinf->sh_size == 0) {
2374 roinf->sh_offset = s->sh_offset;
2375 roinf->sh_addr = s->sh_addr;
2376 roinf->sh_addralign = 1;
2378 roinf->sh_size = (addr - roinf->sh_addr) + s->sh_size;
2381 addr += s->sh_size;
2382 if (s->sh_type != SHT_NOBITS)
2383 file_offset += s->sh_size;
2385 ph->p_filesz = file_offset - ph->p_offset;
2386 ph->p_memsz = addr - ph->p_vaddr;
2389 /* Fill other headers */
2390 if (d->note)
2391 fill_phdr(++ph, PT_NOTE, d->note);
2392 if (d->dynamic)
2393 fill_phdr(++ph, PT_DYNAMIC, d->dynamic)->p_flags |= PF_W;
2394 if (d->roinf)
2395 fill_phdr(++ph, PT_GNU_RELRO, d->roinf)->p_flags |= PF_W;
2396 if (d->interp)
2397 fill_phdr(&d->phdr[1], PT_INTERP, d->interp);
2398 if (phfill) {
2399 ph = &d->phdr[0];
2400 ph->p_offset = sizeof(ElfW(Ehdr));
2401 ph->p_vaddr = base + ph->p_offset;
2402 ph->p_filesz = phnum * sizeof(ElfW(Phdr));
2403 ph->p_align = 4;
2404 fill_phdr(ph, PT_PHDR, NULL);
2406 return 0;
2409 /* put dynamic tag */
2410 static void put_dt(Section *dynamic, int dt, addr_t val)
2412 ElfW(Dyn) *dyn;
2413 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
2414 dyn->d_tag = dt;
2415 dyn->d_un.d_val = val;
2418 /* Fill the dynamic section with tags describing the address and size of
2419 sections */
2420 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2422 Section *dynamic = dyninf->dynamic;
2423 Section *s;
2425 /* put dynamic section entries */
2426 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2427 put_dt(dynamic, DT_GNU_HASH, dyninf->gnu_hash->sh_addr);
2428 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2429 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2430 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2431 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2432 #if PTR_SIZE == 8
2433 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2434 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2435 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2436 if (s1->plt && s1->plt->reloc) {
2437 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2438 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2439 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2440 put_dt(dynamic, DT_PLTREL, DT_RELA);
2442 put_dt(dynamic, DT_RELACOUNT, 0);
2443 #else
2444 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2445 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2446 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2447 if (s1->plt && s1->plt->reloc) {
2448 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2449 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2450 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2451 put_dt(dynamic, DT_PLTREL, DT_REL);
2453 put_dt(dynamic, DT_RELCOUNT, 0);
2454 #endif
2455 if (versym_section && verneed_section) {
2456 /* The dynamic linker can not handle VERSYM without VERNEED */
2457 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2458 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2459 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2461 s = have_section(s1, ".preinit_array");
2462 if (s && s->data_offset) {
2463 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2464 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2466 s = have_section(s1, ".init_array");
2467 if (s && s->data_offset) {
2468 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2469 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2471 s = have_section(s1, ".fini_array");
2472 if (s && s->data_offset) {
2473 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2474 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2476 s = have_section(s1, ".init");
2477 if (s && s->data_offset) {
2478 put_dt(dynamic, DT_INIT, s->sh_addr);
2480 s = have_section(s1, ".fini");
2481 if (s && s->data_offset) {
2482 put_dt(dynamic, DT_FINI, s->sh_addr);
2484 if (s1->do_debug)
2485 put_dt(dynamic, DT_DEBUG, 0);
2486 put_dt(dynamic, DT_NULL, 0);
2489 /* Remove gaps between RELX sections.
2490 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2491 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2492 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2493 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2494 static void update_reloc_sections(TCCState *s1, struct dyn_inf *dyninf)
2496 int i;
2497 unsigned long file_offset = 0;
2498 Section *s;
2499 Section *relocplt = s1->plt ? s1->plt->reloc : NULL;
2501 /* dynamic relocation table information, for .dynamic section */
2502 dyninf->rel_addr = dyninf->rel_size = 0;
2504 for(i = 1; i < s1->nb_sections; i++) {
2505 s = s1->sections[i];
2506 if (s->sh_type == SHT_RELX && s != relocplt) {
2507 if (dyninf->rel_size == 0) {
2508 dyninf->rel_addr = s->sh_addr;
2509 file_offset = s->sh_offset;
2511 else {
2512 s->sh_addr = dyninf->rel_addr + dyninf->rel_size;
2513 s->sh_offset = file_offset + dyninf->rel_size;
2515 dyninf->rel_size += s->sh_size;
2519 #endif /* ndef ELF_OBJ_ONLY */
2521 /* Create an ELF file on disk.
2522 This function handle ELF specific layout requirements */
2523 static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr)
2525 int i, shnum, offset, size, file_type;
2526 Section *s;
2527 ElfW(Ehdr) ehdr;
2528 ElfW(Shdr) shdr, *sh;
2530 file_type = s1->output_type;
2531 shnum = s1->nb_sections;
2533 memset(&ehdr, 0, sizeof(ehdr));
2534 if (phnum > 0) {
2535 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2536 ehdr.e_phnum = phnum;
2537 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2540 /* fill header */
2541 ehdr.e_ident[0] = ELFMAG0;
2542 ehdr.e_ident[1] = ELFMAG1;
2543 ehdr.e_ident[2] = ELFMAG2;
2544 ehdr.e_ident[3] = ELFMAG3;
2545 ehdr.e_ident[4] = ELFCLASSW;
2546 ehdr.e_ident[5] = ELFDATA2LSB;
2547 ehdr.e_ident[6] = EV_CURRENT;
2549 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2550 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2551 #elif defined TCC_TARGET_ARM && defined TCC_ARM_EABI
2552 ehdr.e_flags = EF_ARM_EABI_VER5;
2553 ehdr.e_flags |= s1->float_abi == ARM_HARD_FLOAT
2554 ? EF_ARM_VFP_FLOAT : EF_ARM_SOFT_FLOAT;
2555 #elif defined TCC_TARGET_ARM
2556 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2557 #elif defined TCC_TARGET_RISCV64
2558 /* XXX should be configurable */
2559 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2560 #endif
2562 if (file_type == TCC_OUTPUT_OBJ) {
2563 ehdr.e_type = ET_REL;
2564 } else {
2565 if (file_type & TCC_OUTPUT_DYN)
2566 ehdr.e_type = ET_DYN;
2567 else
2568 ehdr.e_type = ET_EXEC;
2569 if (s1->elf_entryname)
2570 ehdr.e_entry = get_sym_addr(s1, s1->elf_entryname, 1, 0);
2571 else
2572 ehdr.e_entry = get_sym_addr(s1, "_start", !!(file_type & TCC_OUTPUT_EXE), 0);
2573 if (ehdr.e_entry == (addr_t)-1)
2574 ehdr.e_entry = text_section->sh_addr;
2575 if (s1->nb_errors)
2576 return -1;
2579 ehdr.e_machine = EM_TCC_TARGET;
2580 ehdr.e_version = EV_CURRENT;
2581 ehdr.e_shoff = (sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr)) + 3) & -4;
2582 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2583 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2584 ehdr.e_shnum = shnum;
2585 ehdr.e_shstrndx = shnum - 1;
2587 offset = fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2588 if (phdr)
2589 offset += fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2591 /* output section headers */
2592 while (offset < ehdr.e_shoff) {
2593 fputc(0, f);
2594 offset++;
2597 for(i = 0; i < shnum; i++) {
2598 sh = &shdr;
2599 memset(sh, 0, sizeof(ElfW(Shdr)));
2600 if (i) {
2601 s = s1->sections[i];
2602 sh->sh_name = s->sh_name;
2603 sh->sh_type = s->sh_type;
2604 sh->sh_flags = s->sh_flags;
2605 sh->sh_entsize = s->sh_entsize;
2606 sh->sh_info = s->sh_info;
2607 if (s->link)
2608 sh->sh_link = s->link->sh_num;
2609 sh->sh_addralign = s->sh_addralign;
2610 sh->sh_addr = s->sh_addr;
2611 sh->sh_offset = s->sh_offset;
2612 sh->sh_size = s->sh_size;
2614 offset += fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2617 sort_syms(s1, s1->symtab);
2619 /* output sections */
2620 for(i = 1; i < s1->nb_sections; i++) {
2621 s = s1->sections[i];
2622 if (s->sh_type != SHT_NOBITS) {
2623 while (offset < s->sh_offset) {
2624 fputc(0, f);
2625 offset++;
2627 size = s->sh_size;
2628 if (size)
2629 offset += fwrite(s->data, 1, size, f);
2632 return 0;
2635 static int tcc_output_binary(TCCState *s1, FILE *f)
2637 Section *s;
2638 int i, offset, size;
2640 offset = 0;
2641 for(i=1;i<s1->nb_sections;i++) {
2642 s = s1->sections[i];
2643 if (s->sh_type != SHT_NOBITS &&
2644 (s->sh_flags & SHF_ALLOC)) {
2645 while (offset < s->sh_offset) {
2646 fputc(0, f);
2647 offset++;
2649 size = s->sh_size;
2650 fwrite(s->data, 1, size, f);
2651 offset += size;
2654 return 0;
2657 /* Write an elf, coff or "binary" file */
2658 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2659 ElfW(Phdr) *phdr)
2661 int fd, mode, file_type, ret;
2662 FILE *f;
2664 file_type = s1->output_type;
2665 if (file_type == TCC_OUTPUT_OBJ)
2666 mode = 0666;
2667 else
2668 mode = 0777;
2669 unlink(filename);
2670 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2671 if (fd < 0 || (f = fdopen(fd, "wb")) == NULL)
2672 return tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno));
2673 if (s1->verbose)
2674 printf("<- %s\n", filename);
2675 #ifdef TCC_TARGET_COFF
2676 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2677 tcc_output_coff(s1, f);
2678 else
2679 #endif
2680 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2681 ret = tcc_output_elf(s1, f, phnum, phdr);
2682 else
2683 ret = tcc_output_binary(s1, f);
2684 fclose(f);
2686 return ret;
2689 #ifndef ELF_OBJ_ONLY
2690 /* order sections according to sec_order, remove sections
2691 that we aren't going to output. */
2692 static void reorder_sections(TCCState *s1, int *sec_order)
2694 int i, nnew, k, *backmap;
2695 Section **snew, *s;
2696 ElfW(Sym) *sym;
2698 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2699 for (i = 0, nnew = 0, snew = NULL; i < s1->nb_sections; i++) {
2700 k = sec_order[i];
2701 s = s1->sections[k];
2702 if (!i || s->sh_name) {
2703 backmap[k] = nnew;
2704 dynarray_add(&snew, &nnew, s);
2705 } else {
2706 backmap[k] = 0;
2707 /* just remember to free them later */
2708 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, s);
2711 for (i = 1; i < nnew; i++) {
2712 s = snew[i];
2713 s->sh_num = i;
2714 if (s->sh_type == SHT_RELX)
2715 s->sh_info = backmap[s->sh_info];
2716 else if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_DYNSYM)
2717 for_each_elem(s, 1, sym, ElfW(Sym))
2718 if (sym->st_shndx < s1->nb_sections)
2719 sym->st_shndx = backmap[sym->st_shndx];
2721 tcc_free(s1->sections);
2722 s1->sections = snew;
2723 s1->nb_sections = nnew;
2724 tcc_free(backmap);
2727 #ifdef TCC_TARGET_ARM
2728 static void create_arm_attribute_section(TCCState *s1)
2730 // Needed for DLL support.
2731 static const unsigned char arm_attr[] = {
2732 0x41, // 'A'
2733 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2734 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2735 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2736 0x05, 0x36, 0x00, // 'CPU_name', "6"
2737 0x06, 0x06, // 'CPU_arch', 'v6'
2738 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2739 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2740 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2741 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2742 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2743 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2744 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2745 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2746 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2747 0x1a, 0x02, // 'ABI_enum_size', 'int'
2748 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2749 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2751 Section *attr = new_section(s1, ".ARM.attributes", SHT_ARM_ATTRIBUTES, 0);
2752 unsigned char *ptr = section_ptr_add(attr, sizeof(arm_attr));
2753 attr->sh_addralign = 1;
2754 memcpy(ptr, arm_attr, sizeof(arm_attr));
2755 if (s1->float_abi != ARM_HARD_FLOAT) {
2756 ptr[26] = 0x00; // 'FP_arch', 'No'
2757 ptr[41] = 0x1e; // 'ABI_optimization_goals'
2758 ptr[42] = 0x06; // 'Aggressive Debug'
2761 #endif
2763 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2764 static Section *create_bsd_note_section(TCCState *s1,
2765 const char *name,
2766 const char *value)
2768 Section *s = find_section (s1, name);
2770 if (s->data_offset == 0) {
2771 char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
2772 ElfW(Nhdr) *note = (ElfW(Nhdr) *) ptr;
2774 s->sh_type = SHT_NOTE;
2775 note->n_namesz = 8;
2776 note->n_descsz = 4;
2777 note->n_type = ELF_NOTE_OS_GNU;
2778 strcpy (ptr + sizeof(ElfW(Nhdr)), value);
2780 return s;
2782 #endif
2784 static void alloc_sec_names(TCCState *s1, int is_obj);
2786 /* Output an elf, coff or binary file */
2787 /* XXX: suppress unneeded sections */
2788 static int elf_output_file(TCCState *s1, const char *filename)
2790 int i, ret, file_type, *sec_order;
2791 struct dyn_inf dyninf = {0};
2792 Section *interp, *dynstr, *dynamic;
2793 int textrel, got_sym, dt_flags_1;
2795 file_type = s1->output_type;
2796 s1->nb_errors = 0;
2797 ret = -1;
2798 interp = dynstr = dynamic = NULL;
2799 sec_order = NULL;
2800 dyninf.roinf = &dyninf._roinf;
2802 #ifdef TCC_TARGET_ARM
2803 create_arm_attribute_section (s1);
2804 #endif
2806 #if TARGETOS_OpenBSD
2807 dyninf.note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
2808 #endif
2810 #if TARGETOS_NetBSD
2811 dyninf.note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD");
2812 #endif
2814 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
2815 dyninf.roinf = NULL;
2816 #endif
2817 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2818 tcc_add_runtime(s1);
2819 resolve_common_syms(s1);
2821 if (!s1->static_link) {
2822 if (file_type & TCC_OUTPUT_EXE) {
2823 char *ptr;
2824 /* allow override the dynamic loader */
2825 const char *elfint = getenv("LD_SO");
2826 if (elfint == NULL)
2827 elfint = DEFAULT_ELFINTERP(s1);
2828 /* add interpreter section only if executable */
2829 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2830 interp->sh_addralign = 1;
2831 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2832 strcpy(ptr, elfint);
2833 dyninf.interp = interp;
2836 /* add dynamic symbol table */
2837 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2838 ".dynstr",
2839 ".hash", SHF_ALLOC);
2840 /* Number of local symbols (readelf complains if not set) */
2841 s1->dynsym->sh_info = 1;
2842 dynstr = s1->dynsym->link;
2843 /* add dynamic section */
2844 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2845 SHF_ALLOC | SHF_WRITE);
2846 dynamic->link = dynstr;
2847 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2849 got_sym = build_got(s1);
2850 if (file_type & TCC_OUTPUT_EXE) {
2851 bind_exe_dynsyms(s1, file_type & TCC_OUTPUT_DYN);
2852 if (s1->nb_errors)
2853 goto the_end;
2855 build_got_entries(s1, got_sym);
2856 if (file_type & TCC_OUTPUT_EXE) {
2857 bind_libs_dynsyms(s1);
2858 } else {
2859 /* shared library case: simply export all global symbols */
2860 export_global_syms(s1);
2862 dyninf.gnu_hash = create_gnu_hash(s1);
2863 } else {
2864 build_got_entries(s1, 0);
2866 version_add (s1);
2868 textrel = set_sec_sizes(s1);
2870 if (!s1->static_link) {
2871 /* add a list of needed dlls */
2872 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2873 DLLReference *dllref = s1->loaded_dlls[i];
2874 if (dllref->level == 0)
2875 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2878 if (s1->rpath)
2879 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2880 put_elf_str(dynstr, s1->rpath));
2882 dt_flags_1 = DF_1_NOW;
2883 if (file_type & TCC_OUTPUT_DYN) {
2884 if (s1->soname)
2885 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2886 /* XXX: currently, since we do not handle PIC code, we
2887 must relocate the readonly segments */
2888 if (textrel)
2889 put_dt(dynamic, DT_TEXTREL, 0);
2890 if (file_type & TCC_OUTPUT_EXE)
2891 dt_flags_1 = DF_1_NOW | DF_1_PIE;
2893 put_dt(dynamic, DT_FLAGS, DF_BIND_NOW);
2894 put_dt(dynamic, DT_FLAGS_1, dt_flags_1);
2895 if (s1->symbolic)
2896 put_dt(dynamic, DT_SYMBOLIC, 0);
2898 dyninf.dynamic = dynamic;
2899 dyninf.dynstr = dynstr;
2900 /* remember offset and reserve space for 2nd call below */
2901 dyninf.data_offset = dynamic->data_offset;
2902 fill_dynamic(s1, &dyninf);
2903 dynamic->sh_size = dynamic->data_offset;
2904 dynstr->sh_size = dynstr->data_offset;
2907 /* create and fill .shstrtab section */
2908 alloc_sec_names(s1, 0);
2909 /* this array is used to reorder sections in the output file */
2910 sec_order = tcc_malloc(sizeof(int) * 2 * s1->nb_sections);
2911 /* compute section to program header mapping */
2912 layout_sections(s1, sec_order, &dyninf);
2914 if (dynamic) {
2915 /* put in GOT the dynamic section address and relocate PLT */
2916 write32le(s1->got->data, dynamic->sh_addr);
2917 if (file_type == TCC_OUTPUT_EXE
2918 || (RELOCATE_DLLPLT && (file_type & TCC_OUTPUT_DYN)))
2919 relocate_plt(s1);
2920 /* relocate symbols in .dynsym now that final addresses are known */
2921 relocate_syms(s1, s1->dynsym, 2);
2924 /* if building executable or DLL, then relocate each section
2925 except the GOT which is already relocated */
2926 relocate_syms(s1, s1->symtab, 0);
2927 if (s1->nb_errors != 0)
2928 goto the_end;
2929 relocate_sections(s1);
2930 if (dynamic) {
2931 update_reloc_sections (s1, &dyninf);
2932 dynamic->data_offset = dyninf.data_offset;
2933 fill_dynamic(s1, &dyninf);
2935 /* Perform relocation to GOT or PLT entries */
2936 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2937 fill_got(s1);
2938 else if (s1->got)
2939 fill_local_got_entries(s1);
2941 if (dyninf.gnu_hash)
2942 update_gnu_hash(s1, dyninf.gnu_hash);
2944 reorder_sections(s1, sec_order);
2946 /* Create the ELF file with name 'filename' */
2947 ret = tcc_write_elf_file(s1, filename, dyninf.phnum, dyninf.phdr);
2948 the_end:
2949 tcc_free(sec_order);
2950 tcc_free(dyninf.phdr);
2951 return ret;
2953 #endif /* ndef ELF_OBJ_ONLY */
2955 /* Allocate strings for section names */
2956 static void alloc_sec_names(TCCState *s1, int is_obj)
2958 int i;
2959 Section *s, *strsec;
2961 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2962 put_elf_str(strsec, "");
2963 for(i = 1; i < s1->nb_sections; i++) {
2964 s = s1->sections[i];
2965 if (is_obj)
2966 s->sh_size = s->data_offset;
2967 if (s->sh_size || s == strsec || (s->sh_flags & SHF_ALLOC) || is_obj)
2968 s->sh_name = put_elf_str(strsec, s->name);
2970 strsec->sh_size = strsec->data_offset;
2973 /* Output an elf .o file */
2974 static int elf_output_obj(TCCState *s1, const char *filename)
2976 Section *s;
2977 int i, ret, file_offset;
2978 s1->nb_errors = 0;
2979 /* Allocate strings for section names */
2980 alloc_sec_names(s1, 1);
2981 file_offset = (sizeof (ElfW(Ehdr)) + 3) & -4;
2982 file_offset += s1->nb_sections * sizeof(ElfW(Shdr));
2983 for(i = 1; i < s1->nb_sections; i++) {
2984 s = s1->sections[i];
2985 file_offset = (file_offset + 15) & -16;
2986 s->sh_offset = file_offset;
2987 if (s->sh_type != SHT_NOBITS)
2988 file_offset += s->sh_size;
2990 /* Create the ELF file with name 'filename' */
2991 ret = tcc_write_elf_file(s1, filename, 0, NULL);
2992 return ret;
2995 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2997 if (s->test_coverage)
2998 tcc_tcov_add_file(s, filename);
2999 if (s->output_type == TCC_OUTPUT_OBJ)
3000 return elf_output_obj(s, filename);
3001 #ifdef TCC_TARGET_PE
3002 return pe_output_file(s, filename);
3003 #elif TCC_TARGET_MACHO
3004 return macho_output_file(s, filename);
3005 #else
3006 return elf_output_file(s, filename);
3007 #endif
3010 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
3011 char *cbuf = buf;
3012 size_t rnum = 0;
3013 while (1) {
3014 ssize_t num = read(fd, cbuf, count-rnum);
3015 if (num < 0) return num;
3016 if (num == 0) return rnum;
3017 rnum += num;
3018 cbuf += num;
3022 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
3024 void *data;
3026 data = tcc_malloc(size);
3027 lseek(fd, file_offset, SEEK_SET);
3028 full_read(fd, data, size);
3029 return data;
3032 typedef struct SectionMergeInfo {
3033 Section *s; /* corresponding existing section */
3034 unsigned long offset; /* offset of the new section in the existing section */
3035 uint8_t new_section; /* true if section 's' was added */
3036 uint8_t link_once; /* true if link once section */
3037 } SectionMergeInfo;
3039 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
3041 int size = full_read(fd, h, sizeof *h);
3042 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
3043 if (h->e_type == ET_REL)
3044 return AFF_BINTYPE_REL;
3045 if (h->e_type == ET_DYN)
3046 return AFF_BINTYPE_DYN;
3047 } else if (size >= 8) {
3048 if (0 == memcmp(h, ARMAG, 8))
3049 return AFF_BINTYPE_AR;
3050 #ifdef TCC_TARGET_COFF
3051 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
3052 return AFF_BINTYPE_C67;
3053 #endif
3055 return 0;
3058 /* load an object file and merge it with current files */
3059 /* XXX: handle correctly stab (debug) info */
3060 ST_FUNC int tcc_load_object_file(TCCState *s1,
3061 int fd, unsigned long file_offset)
3063 ElfW(Ehdr) ehdr;
3064 ElfW(Shdr) *shdr, *sh;
3065 unsigned long size, offset, offseti;
3066 int i, j, nb_syms, sym_index, ret, seencompressed;
3067 char *strsec, *strtab;
3068 int stab_index, stabstr_index;
3069 int *old_to_new_syms;
3070 char *sh_name, *name;
3071 SectionMergeInfo *sm_table, *sm;
3072 ElfW(Sym) *sym, *symtab;
3073 ElfW_Rel *rel;
3074 Section *s;
3076 lseek(fd, file_offset, SEEK_SET);
3077 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
3078 goto invalid;
3079 /* test CPU specific stuff */
3080 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3081 ehdr.e_machine != EM_TCC_TARGET) {
3082 invalid:
3083 return tcc_error_noabort("invalid object file");
3085 /* read sections */
3086 shdr = load_data(fd, file_offset + ehdr.e_shoff,
3087 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3088 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
3090 /* load section names */
3091 sh = &shdr[ehdr.e_shstrndx];
3092 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3094 /* load symtab and strtab */
3095 old_to_new_syms = NULL;
3096 symtab = NULL;
3097 strtab = NULL;
3098 nb_syms = 0;
3099 seencompressed = 0;
3100 stab_index = stabstr_index = 0;
3101 ret = -1;
3103 for(i = 1; i < ehdr.e_shnum; i++) {
3104 sh = &shdr[i];
3105 if (sh->sh_type == SHT_SYMTAB) {
3106 if (symtab) {
3107 tcc_error_noabort("object must contain only one symtab");
3108 goto the_end;
3110 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3111 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3112 sm_table[i].s = symtab_section;
3114 /* now load strtab */
3115 sh = &shdr[sh->sh_link];
3116 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3118 if (sh->sh_flags & SHF_COMPRESSED)
3119 seencompressed = 1;
3122 /* now examine each section and try to merge its content with the
3123 ones in memory */
3124 for(i = 1; i < ehdr.e_shnum; i++) {
3125 /* no need to examine section name strtab */
3126 if (i == ehdr.e_shstrndx)
3127 continue;
3128 sh = &shdr[i];
3129 if (sh->sh_type == SHT_RELX)
3130 sh = &shdr[sh->sh_info];
3131 /* ignore sections types we do not handle (plus relocs to those) */
3132 if (sh->sh_type != SHT_PROGBITS &&
3133 #ifdef TCC_ARM_EABI
3134 sh->sh_type != SHT_ARM_EXIDX &&
3135 #endif
3136 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3137 sh->sh_type != SHT_X86_64_UNWIND &&
3138 #endif
3139 sh->sh_type != SHT_NOTE &&
3140 sh->sh_type != SHT_NOBITS &&
3141 sh->sh_type != SHT_PREINIT_ARRAY &&
3142 sh->sh_type != SHT_INIT_ARRAY &&
3143 sh->sh_type != SHT_FINI_ARRAY &&
3144 strcmp(strsec + sh->sh_name, ".stabstr")
3146 continue;
3147 if (seencompressed && 0 == strncmp(strsec + sh->sh_name, ".debug_", 7))
3148 continue;
3150 sh = &shdr[i];
3151 sh_name = strsec + sh->sh_name;
3152 if (sh->sh_addralign < 1)
3153 sh->sh_addralign = 1;
3154 /* find corresponding section, if any */
3155 for(j = 1; j < s1->nb_sections;j++) {
3156 s = s1->sections[j];
3157 if (!strcmp(s->name, sh_name)) {
3158 if (!strncmp(sh_name, ".gnu.linkonce",
3159 sizeof(".gnu.linkonce") - 1)) {
3160 /* if a 'linkonce' section is already present, we
3161 do not add it again. It is a little tricky as
3162 symbols can still be defined in
3163 it. */
3164 sm_table[i].link_once = 1;
3165 goto next;
3167 if (stab_section) {
3168 if (s == stab_section)
3169 stab_index = i;
3170 if (s == stab_section->link)
3171 stabstr_index = i;
3173 goto found;
3176 /* not found: create new section */
3177 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
3178 /* take as much info as possible from the section. sh_link and
3179 sh_info will be updated later */
3180 s->sh_addralign = sh->sh_addralign;
3181 s->sh_entsize = sh->sh_entsize;
3182 sm_table[i].new_section = 1;
3183 found:
3184 if (sh->sh_type != s->sh_type
3185 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3186 && strcmp (s->name, ".eh_frame")
3187 #endif
3189 tcc_error_noabort("invalid section type");
3190 goto the_end;
3192 /* align start of section */
3193 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
3194 if (sh->sh_addralign > s->sh_addralign)
3195 s->sh_addralign = sh->sh_addralign;
3196 sm_table[i].offset = s->data_offset;
3197 sm_table[i].s = s;
3198 /* concatenate sections */
3199 size = sh->sh_size;
3200 if (sh->sh_type != SHT_NOBITS) {
3201 unsigned char *ptr;
3202 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
3203 ptr = section_ptr_add(s, size);
3204 full_read(fd, ptr, size);
3205 } else {
3206 s->data_offset += size;
3208 next: ;
3211 /* gr relocate stab strings */
3212 if (stab_index && stabstr_index) {
3213 Stab_Sym *a, *b;
3214 unsigned o;
3215 s = sm_table[stab_index].s;
3216 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
3217 b = (Stab_Sym *)(s->data + s->data_offset);
3218 o = sm_table[stabstr_index].offset;
3219 while (a < b) {
3220 if (a->n_strx)
3221 a->n_strx += o;
3222 a++;
3226 /* second short pass to update sh_link and sh_info fields of new
3227 sections */
3228 for(i = 1; i < ehdr.e_shnum; i++) {
3229 s = sm_table[i].s;
3230 if (!s || !sm_table[i].new_section)
3231 continue;
3232 sh = &shdr[i];
3233 if (sh->sh_link > 0)
3234 s->link = sm_table[sh->sh_link].s;
3235 if (sh->sh_type == SHT_RELX) {
3236 s->sh_info = sm_table[sh->sh_info].s->sh_num;
3237 /* update backward link */
3238 s1->sections[s->sh_info]->reloc = s;
3242 /* resolve symbols */
3243 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
3245 sym = symtab + 1;
3246 for(i = 1; i < nb_syms; i++, sym++) {
3247 if (sym->st_shndx != SHN_UNDEF &&
3248 sym->st_shndx < SHN_LORESERVE) {
3249 sm = &sm_table[sym->st_shndx];
3250 if (sm->link_once) {
3251 /* if a symbol is in a link once section, we use the
3252 already defined symbol. It is very important to get
3253 correct relocations */
3254 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
3255 name = strtab + sym->st_name;
3256 sym_index = find_elf_sym(symtab_section, name);
3257 if (sym_index)
3258 old_to_new_syms[i] = sym_index;
3260 continue;
3262 /* if no corresponding section added, no need to add symbol */
3263 if (!sm->s)
3264 continue;
3265 /* convert section number */
3266 sym->st_shndx = sm->s->sh_num;
3267 /* offset value */
3268 sym->st_value += sm->offset;
3270 /* add symbol */
3271 name = strtab + sym->st_name;
3272 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
3273 sym->st_info, sym->st_other,
3274 sym->st_shndx, name);
3275 old_to_new_syms[i] = sym_index;
3278 /* third pass to patch relocation entries */
3279 for(i = 1; i < ehdr.e_shnum; i++) {
3280 s = sm_table[i].s;
3281 if (!s)
3282 continue;
3283 sh = &shdr[i];
3284 offset = sm_table[i].offset;
3285 size = sh->sh_size;
3286 switch(s->sh_type) {
3287 case SHT_RELX:
3288 /* take relocation offset information */
3289 offseti = sm_table[sh->sh_info].offset;
3290 for (rel = (ElfW_Rel *) s->data + (offset / sizeof(*rel));
3291 rel < (ElfW_Rel *) s->data + ((offset + size) / sizeof(*rel));
3292 rel++) {
3293 int type;
3294 unsigned sym_index;
3295 /* convert symbol index */
3296 type = ELFW(R_TYPE)(rel->r_info);
3297 sym_index = ELFW(R_SYM)(rel->r_info);
3298 /* NOTE: only one symtab assumed */
3299 if (sym_index >= nb_syms)
3300 goto invalid_reloc;
3301 sym_index = old_to_new_syms[sym_index];
3302 /* ignore link_once in rel section. */
3303 if (!sym_index && !sm_table[sh->sh_info].link_once
3304 #ifdef TCC_TARGET_ARM
3305 && type != R_ARM_V4BX
3306 #elif defined TCC_TARGET_RISCV64
3307 && type != R_RISCV_ALIGN
3308 && type != R_RISCV_RELAX
3309 #endif
3311 invalid_reloc:
3312 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3313 i, strsec + sh->sh_name, (int)rel->r_offset);
3314 goto the_end;
3316 rel->r_info = ELFW(R_INFO)(sym_index, type);
3317 /* offset the relocation offset */
3318 rel->r_offset += offseti;
3319 #ifdef TCC_TARGET_ARM
3320 /* Jumps and branches from a Thumb code to a PLT entry need
3321 special handling since PLT entries are ARM code.
3322 Unconditional bl instructions referencing PLT entries are
3323 handled by converting these instructions into blx
3324 instructions. Other case of instructions referencing a PLT
3325 entry require to add a Thumb stub before the PLT entry to
3326 switch to ARM mode. We set bit plt_thumb_stub of the
3327 attribute of a symbol to indicate such a case. */
3328 if (type == R_ARM_THM_JUMP24)
3329 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
3330 #endif
3332 break;
3333 default:
3334 break;
3338 ret = 0;
3339 the_end:
3340 tcc_free(symtab);
3341 tcc_free(strtab);
3342 tcc_free(old_to_new_syms);
3343 tcc_free(sm_table);
3344 tcc_free(strsec);
3345 tcc_free(shdr);
3346 return ret;
3349 typedef struct ArchiveHeader {
3350 char ar_name[16]; /* name of this member */
3351 char ar_date[12]; /* file mtime */
3352 char ar_uid[6]; /* owner uid; printed as decimal */
3353 char ar_gid[6]; /* owner gid; printed as decimal */
3354 char ar_mode[8]; /* file mode, printed as octal */
3355 char ar_size[10]; /* file size, printed as decimal */
3356 char ar_fmag[2]; /* should contain ARFMAG */
3357 } ArchiveHeader;
3359 #define ARFMAG "`\n"
3361 static unsigned long long get_be(const uint8_t *b, int n)
3363 unsigned long long ret = 0;
3364 while (n)
3365 ret = (ret << 8) | *b++, --n;
3366 return ret;
3369 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
3371 char *p, *e;
3372 int len;
3373 lseek(fd, offset, SEEK_SET);
3374 len = full_read(fd, hdr, sizeof(ArchiveHeader));
3375 if (len != sizeof(ArchiveHeader))
3376 return len ? -1 : 0;
3377 p = hdr->ar_name;
3378 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
3379 --e;
3380 *e = '\0';
3381 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
3382 return len;
3385 /* load only the objects which resolve undefined symbols */
3386 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
3388 int i, bound, nsyms, sym_index, len, ret = -1;
3389 unsigned long long off;
3390 uint8_t *data;
3391 const char *ar_names, *p;
3392 const uint8_t *ar_index;
3393 ElfW(Sym) *sym;
3394 ArchiveHeader hdr;
3396 data = tcc_malloc(size);
3397 if (full_read(fd, data, size) != size)
3398 goto the_end;
3399 nsyms = get_be(data, entrysize);
3400 ar_index = data + entrysize;
3401 ar_names = (char *) ar_index + nsyms * entrysize;
3403 do {
3404 bound = 0;
3405 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
3406 Section *s = symtab_section;
3407 sym_index = find_elf_sym(s, p);
3408 if (!sym_index)
3409 continue;
3410 sym = &((ElfW(Sym) *)s->data)[sym_index];
3411 if(sym->st_shndx != SHN_UNDEF)
3412 continue;
3413 off = get_be(ar_index + i * entrysize, entrysize);
3414 len = read_ar_header(fd, off, &hdr);
3415 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
3416 tcc_error_noabort("invalid archive");
3417 goto the_end;
3419 off += len;
3420 if (s1->verbose == 2)
3421 printf(" -> %s\n", hdr.ar_name);
3422 if (tcc_load_object_file(s1, fd, off) < 0)
3423 goto the_end;
3424 ++bound;
3426 } while(bound);
3427 ret = 0;
3428 the_end:
3429 tcc_free(data);
3430 return ret;
3433 /* load a '.a' file */
3434 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
3436 ArchiveHeader hdr;
3437 /* char magic[8]; */
3438 int size, len;
3439 unsigned long file_offset;
3440 ElfW(Ehdr) ehdr;
3442 /* skip magic which was already checked */
3443 /* full_read(fd, magic, sizeof(magic)); */
3444 file_offset = sizeof ARMAG - 1;
3446 for(;;) {
3447 len = read_ar_header(fd, file_offset, &hdr);
3448 if (len == 0)
3449 return 0;
3450 if (len < 0)
3451 return tcc_error_noabort("invalid archive");
3452 file_offset += len;
3453 size = strtol(hdr.ar_size, NULL, 0);
3454 /* align to even */
3455 size = (size + 1) & ~1;
3456 if (alacarte) {
3457 /* coff symbol table : we handle it */
3458 if (!strcmp(hdr.ar_name, "/"))
3459 return tcc_load_alacarte(s1, fd, size, 4);
3460 if (!strcmp(hdr.ar_name, "/SYM64/"))
3461 return tcc_load_alacarte(s1, fd, size, 8);
3462 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3463 if (s1->verbose == 2)
3464 printf(" -> %s\n", hdr.ar_name);
3465 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3466 return -1;
3468 file_offset += size;
3472 #ifndef ELF_OBJ_ONLY
3473 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3474 LV, maybe create a new entry for (LIB,VERSION). */
3475 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3477 while (i >= *n) {
3478 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3479 (*lv)[(*n)++] = -1;
3481 if ((*lv)[i] == -1) {
3482 int v, prev_same_lib = -1;
3483 for (v = 0; v < nb_sym_versions; v++) {
3484 if (strcmp(sym_versions[v].lib, lib))
3485 continue;
3486 prev_same_lib = v;
3487 if (!strcmp(sym_versions[v].version, version))
3488 break;
3490 if (v == nb_sym_versions) {
3491 sym_versions = tcc_realloc (sym_versions,
3492 (v + 1) * sizeof(*sym_versions));
3493 sym_versions[v].lib = tcc_strdup(lib);
3494 sym_versions[v].version = tcc_strdup(version);
3495 sym_versions[v].out_index = 0;
3496 sym_versions[v].prev_same_lib = prev_same_lib;
3497 nb_sym_versions++;
3499 (*lv)[i] = v;
3503 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3504 VERNDX. */
3505 static void
3506 set_sym_version(TCCState *s1, int sym_index, int verndx)
3508 if (sym_index >= nb_sym_to_version) {
3509 int newelems = sym_index ? sym_index * 2 : 1;
3510 sym_to_version = tcc_realloc(sym_to_version,
3511 newelems * sizeof(*sym_to_version));
3512 memset(sym_to_version + nb_sym_to_version, -1,
3513 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3514 nb_sym_to_version = newelems;
3516 if (sym_to_version[sym_index] < 0)
3517 sym_to_version[sym_index] = verndx;
3520 struct versym_info {
3521 int nb_versyms;
3522 ElfW(Verdef) *verdef;
3523 ElfW(Verneed) *verneed;
3524 ElfW(Half) *versym;
3525 int nb_local_ver, *local_ver;
3529 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3531 char *lib, *version;
3532 uint32_t next;
3533 int i;
3535 #define DEBUG_VERSION 0
3537 if (v->versym && v->verdef) {
3538 ElfW(Verdef) *vdef = v->verdef;
3539 lib = NULL;
3540 do {
3541 ElfW(Verdaux) *verdaux =
3542 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3544 #if DEBUG_VERSION
3545 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3546 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3547 vdef->vd_hash);
3548 #endif
3549 if (vdef->vd_cnt) {
3550 version = dynstr + verdaux->vda_name;
3552 if (lib == NULL)
3553 lib = version;
3554 else
3555 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3556 lib, version);
3557 #if DEBUG_VERSION
3558 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3559 #endif
3561 next = vdef->vd_next;
3562 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3563 } while (next);
3565 if (v->versym && v->verneed) {
3566 ElfW(Verneed) *vneed = v->verneed;
3567 do {
3568 ElfW(Vernaux) *vernaux =
3569 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3571 lib = dynstr + vneed->vn_file;
3572 #if DEBUG_VERSION
3573 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3574 #endif
3575 for (i = 0; i < vneed->vn_cnt; i++) {
3576 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3577 version = dynstr + vernaux->vna_name;
3578 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3579 lib, version);
3580 #if DEBUG_VERSION
3581 printf (" vernaux(%u): %u %u %s\n",
3582 vernaux->vna_other, vernaux->vna_hash,
3583 vernaux->vna_flags, version);
3584 #endif
3586 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3588 next = vneed->vn_next;
3589 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3590 } while (next);
3593 #if DEBUG_VERSION
3594 for (i = 0; i < v->nb_local_ver; i++) {
3595 if (v->local_ver[i] > 0) {
3596 printf ("%d: lib: %s, version %s\n",
3597 i, sym_versions[v->local_ver[i]].lib,
3598 sym_versions[v->local_ver[i]].version);
3601 #endif
3604 /* load a library / DLL
3605 'level = 0' means that the DLL is referenced by the user
3606 (so it should be added as DT_NEEDED in the generated ELF file) */
3607 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3609 ElfW(Ehdr) ehdr;
3610 ElfW(Shdr) *shdr, *sh, *sh1;
3611 int i, nb_syms, nb_dts, sym_bind, ret = -1;
3612 ElfW(Sym) *sym, *dynsym;
3613 ElfW(Dyn) *dt, *dynamic;
3615 char *dynstr;
3616 int sym_index;
3617 const char *name, *soname;
3618 struct versym_info v;
3620 full_read(fd, &ehdr, sizeof(ehdr));
3622 /* test CPU specific stuff */
3623 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3624 ehdr.e_machine != EM_TCC_TARGET) {
3625 return tcc_error_noabort("bad architecture");
3628 /* read sections */
3629 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3631 /* load dynamic section and dynamic symbols */
3632 nb_syms = 0;
3633 nb_dts = 0;
3634 dynamic = NULL;
3635 dynsym = NULL; /* avoid warning */
3636 dynstr = NULL; /* avoid warning */
3637 memset(&v, 0, sizeof v);
3639 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3640 switch(sh->sh_type) {
3641 case SHT_DYNAMIC:
3642 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3643 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3644 break;
3645 case SHT_DYNSYM:
3646 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3647 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3648 sh1 = &shdr[sh->sh_link];
3649 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3650 break;
3651 case SHT_GNU_verdef:
3652 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3653 break;
3654 case SHT_GNU_verneed:
3655 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3656 break;
3657 case SHT_GNU_versym:
3658 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3659 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3660 break;
3661 default:
3662 break;
3666 if (!dynamic)
3667 goto the_end;
3669 /* compute the real library name */
3670 soname = tcc_basename(filename);
3671 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
3672 if (dt->d_tag == DT_SONAME)
3673 soname = dynstr + dt->d_un.d_val;
3675 /* if the dll is already loaded, do not load it */
3676 if (tcc_add_dllref(s1, soname, level)->found)
3677 goto ret_success;
3679 if (v.nb_versyms != nb_syms)
3680 tcc_free (v.versym), v.versym = NULL;
3681 else
3682 store_version(s1, &v, dynstr);
3684 /* add dynamic symbols in dynsym_section */
3685 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3686 sym_bind = ELFW(ST_BIND)(sym->st_info);
3687 if (sym_bind == STB_LOCAL)
3688 continue;
3689 name = dynstr + sym->st_name;
3690 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3691 sym->st_info, sym->st_other, sym->st_shndx, name);
3692 if (v.versym) {
3693 ElfW(Half) vsym = v.versym[i];
3694 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3695 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3699 /* do not load all referenced libraries
3700 (recursive loading can break linking of libraries) */
3701 /* following DT_NEEDED is needed for the dynamic loader (libdl.so),
3702 but it is no longer needed, when linking a library or a program.
3703 When tcc output mode is OUTPUT_MEM,
3704 tcc calls dlopen, which handles DT_NEEDED for us */
3706 #if 0
3707 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
3708 if (dt->d_tag == DT_RPATH)
3709 tcc_add_library_path(s1, dynstr + dt->d_un.d_val);
3711 /* load all referenced DLLs */
3712 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3713 switch(dt->d_tag) {
3714 case DT_NEEDED:
3715 name = dynstr + dt->d_un.d_val;
3716 if (tcc_add_dllref(s1, name, -1))
3717 continue;
3718 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3719 ret = tcc_error_noabort("referenced dll '%s' not found", name);
3720 goto the_end;
3724 #endif
3726 ret_success:
3727 ret = 0;
3728 the_end:
3729 tcc_free(dynstr);
3730 tcc_free(dynsym);
3731 tcc_free(dynamic);
3732 tcc_free(shdr);
3733 tcc_free(v.local_ver);
3734 tcc_free(v.verdef);
3735 tcc_free(v.verneed);
3736 tcc_free(v.versym);
3737 return ret;
3740 #define LD_TOK_NAME 256
3741 #define LD_TOK_EOF (-1)
3743 static int ld_inp(TCCState *s1)
3745 char b;
3746 if (s1->cc != -1) {
3747 int c = s1->cc;
3748 s1->cc = -1;
3749 return c;
3751 if (1 == read(s1->fd, &b, 1))
3752 return b;
3753 return CH_EOF;
3756 /* return next ld script token */
3757 static int ld_next(TCCState *s1, char *name, int name_size)
3759 int c, d, ch;
3760 char *q;
3762 redo:
3763 ch = ld_inp(s1);
3764 switch(ch) {
3765 case ' ':
3766 case '\t':
3767 case '\f':
3768 case '\v':
3769 case '\r':
3770 case '\n':
3771 goto redo;
3772 case '/':
3773 ch = ld_inp(s1);
3774 if (ch == '*') { /* comment */
3775 for (d = 0;; d = ch) {
3776 ch = ld_inp(s1);
3777 if (ch == CH_EOF || (ch == '/' && d == '*'))
3778 break;
3780 goto redo;
3781 } else {
3782 q = name;
3783 *q++ = '/';
3784 goto parse_name;
3786 break;
3787 case '\\':
3788 /* case 'a' ... 'z': */
3789 case 'a':
3790 case 'b':
3791 case 'c':
3792 case 'd':
3793 case 'e':
3794 case 'f':
3795 case 'g':
3796 case 'h':
3797 case 'i':
3798 case 'j':
3799 case 'k':
3800 case 'l':
3801 case 'm':
3802 case 'n':
3803 case 'o':
3804 case 'p':
3805 case 'q':
3806 case 'r':
3807 case 's':
3808 case 't':
3809 case 'u':
3810 case 'v':
3811 case 'w':
3812 case 'x':
3813 case 'y':
3814 case 'z':
3815 /* case 'A' ... 'z': */
3816 case 'A':
3817 case 'B':
3818 case 'C':
3819 case 'D':
3820 case 'E':
3821 case 'F':
3822 case 'G':
3823 case 'H':
3824 case 'I':
3825 case 'J':
3826 case 'K':
3827 case 'L':
3828 case 'M':
3829 case 'N':
3830 case 'O':
3831 case 'P':
3832 case 'Q':
3833 case 'R':
3834 case 'S':
3835 case 'T':
3836 case 'U':
3837 case 'V':
3838 case 'W':
3839 case 'X':
3840 case 'Y':
3841 case 'Z':
3842 case '_':
3843 case '.':
3844 case '$':
3845 case '~':
3846 q = name;
3847 parse_name:
3848 for(;;) {
3849 if (!((ch >= 'a' && ch <= 'z') ||
3850 (ch >= 'A' && ch <= 'Z') ||
3851 (ch >= '0' && ch <= '9') ||
3852 strchr("/.-_+=$:\\,~", ch)))
3853 break;
3854 if ((q - name) < name_size - 1) {
3855 *q++ = ch;
3857 ch = ld_inp(s1);
3859 s1->cc = ch;
3860 *q = '\0';
3861 c = LD_TOK_NAME;
3862 break;
3863 case CH_EOF:
3864 c = LD_TOK_EOF;
3865 break;
3866 default:
3867 c = ch;
3868 break;
3870 return c;
3873 static int ld_add_file(TCCState *s1, const char filename[])
3875 if (filename[0] == '/') {
3876 if (CONFIG_SYSROOT[0] == '\0'
3877 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3878 return 0;
3879 filename = tcc_basename(filename);
3881 return tcc_add_dll(s1, filename, AFF_PRINT_ERROR);
3884 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3886 char filename[1024], libname[1024];
3887 int t, group, nblibs = 0, ret = 0;
3888 char **libs = NULL;
3890 group = !strcmp(cmd, "GROUP");
3891 if (!as_needed)
3892 s1->new_undef_sym = 0;
3893 t = ld_next(s1, filename, sizeof(filename));
3894 if (t != '(') {
3895 ret = tcc_error_noabort("( expected");
3896 goto lib_parse_error;
3898 t = ld_next(s1, filename, sizeof(filename));
3899 for(;;) {
3900 libname[0] = '\0';
3901 if (t == LD_TOK_EOF) {
3902 ret = tcc_error_noabort("unexpected end of file");
3903 goto lib_parse_error;
3904 } else if (t == ')') {
3905 break;
3906 } else if (t == '-') {
3907 t = ld_next(s1, filename, sizeof(filename));
3908 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3909 ret = tcc_error_noabort("library name expected");
3910 goto lib_parse_error;
3912 pstrcpy(libname, sizeof libname, &filename[1]);
3913 if (s1->static_link) {
3914 snprintf(filename, sizeof filename, "lib%s.a", libname);
3915 } else {
3916 snprintf(filename, sizeof filename, "lib%s.so", libname);
3918 } else if (t != LD_TOK_NAME) {
3919 ret = tcc_error_noabort("filename expected");
3920 goto lib_parse_error;
3922 if (!strcmp(filename, "AS_NEEDED")) {
3923 ret = ld_add_file_list(s1, cmd, 1);
3924 if (ret)
3925 goto lib_parse_error;
3926 } else {
3927 /* TODO: Implement AS_NEEDED support. */
3928 /* DT_NEEDED is not used any more so ignore as_needed */
3929 if (1 || !as_needed) {
3930 ret = ld_add_file(s1, filename);
3931 if (ret)
3932 goto lib_parse_error;
3933 if (group) {
3934 /* Add the filename *and* the libname to avoid future conversions */
3935 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3936 if (libname[0] != '\0')
3937 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3941 t = ld_next(s1, filename, sizeof(filename));
3942 if (t == ',') {
3943 t = ld_next(s1, filename, sizeof(filename));
3946 if (group && !as_needed) {
3947 while (s1->new_undef_sym) {
3948 int i;
3949 s1->new_undef_sym = 0;
3950 for (i = 0; i < nblibs; i ++)
3951 ld_add_file(s1, libs[i]);
3954 lib_parse_error:
3955 dynarray_reset(&libs, &nblibs);
3956 return ret;
3959 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3960 files */
3961 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3963 char cmd[64];
3964 char filename[1024];
3965 int t, ret;
3967 s1->fd = fd;
3968 s1->cc = -1;
3969 for(;;) {
3970 t = ld_next(s1, cmd, sizeof(cmd));
3971 if (t == LD_TOK_EOF)
3972 return 0;
3973 else if (t != LD_TOK_NAME)
3974 return -1;
3975 if (!strcmp(cmd, "INPUT") ||
3976 !strcmp(cmd, "GROUP")) {
3977 ret = ld_add_file_list(s1, cmd, 0);
3978 if (ret)
3979 return ret;
3980 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3981 !strcmp(cmd, "TARGET")) {
3982 /* ignore some commands */
3983 t = ld_next(s1, cmd, sizeof(cmd));
3984 if (t != '(')
3985 return tcc_error_noabort("( expected");
3986 for(;;) {
3987 t = ld_next(s1, filename, sizeof(filename));
3988 if (t == LD_TOK_EOF) {
3989 return tcc_error_noabort("unexpected end of file");
3990 } else if (t == ')') {
3991 break;
3994 } else {
3995 return -1;
3998 return 0;
4000 #endif /* !ELF_OBJ_ONLY */