LIBTCCAPI tcc_relocate(s) : REMOVED 2nd argument
[tinycc.git] / tccelf.c
blob1b067262968984e5aa60e3a577864ac8c261fe39
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() */
143 /* free any loaded DLLs */
144 #ifdef TCC_IS_NATIVE
145 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
146 DLLReference *ref = s1->loaded_dlls[i];
147 if ( ref->handle )
148 # ifdef _WIN32
149 FreeLibrary((HMODULE)ref->handle);
150 # else
151 dlclose(ref->handle);
152 # endif
154 #endif
155 /* free loaded dlls array */
156 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
159 /* save section data state */
160 ST_FUNC void tccelf_begin_file(TCCState *s1)
162 Section *s; int i;
163 for (i = 1; i < s1->nb_sections; i++) {
164 s = s1->sections[i];
165 s->sh_offset = s->data_offset;
167 /* disable symbol hashing during compilation */
168 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
169 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
170 s1->uw_sym = 0;
171 #endif
174 /* At the end of compilation, convert any UNDEF syms to global, and merge
175 with previously existing symbols */
176 ST_FUNC void tccelf_end_file(TCCState *s1)
178 Section *s = s1->symtab;
179 int first_sym, nb_syms, *tr, i;
181 first_sym = s->sh_offset / sizeof (ElfSym);
182 nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
183 s->data_offset = s->sh_offset;
184 s->link->data_offset = s->link->sh_offset;
185 s->hash = s->reloc, s->reloc = NULL;
186 tr = tcc_mallocz(nb_syms * sizeof *tr);
188 for (i = 0; i < nb_syms; ++i) {
189 ElfSym *sym = (ElfSym*)s->data + first_sym + i;
191 if (sym->st_shndx == SHN_UNDEF) {
192 int sym_bind = ELFW(ST_BIND)(sym->st_info);
193 int sym_type = ELFW(ST_TYPE)(sym->st_info);
194 if (sym_bind == STB_LOCAL)
195 sym_bind = STB_GLOBAL;
196 #ifndef TCC_TARGET_PE
197 if (sym_bind == STB_GLOBAL && s1->output_type == TCC_OUTPUT_OBJ) {
198 /* undefined symbols with STT_FUNC are confusing gnu ld when
199 linking statically to STT_GNU_IFUNC */
200 sym_type = STT_NOTYPE;
202 #endif
203 sym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
206 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
207 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
209 /* now update relocations */
210 for (i = 1; i < s1->nb_sections; i++) {
211 Section *sr = s1->sections[i];
212 if (sr->sh_type == SHT_RELX && sr->link == s) {
213 ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
214 ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
215 for (; rel < rel_end; ++rel) {
216 int n = ELFW(R_SYM)(rel->r_info) - first_sym;
217 if (n < 0) /* zero sym_index in reloc (can happen with asm) */
218 continue;
219 rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
223 tcc_free(tr);
225 /* record text/data/bss output for -bench info */
226 for (i = 0; i < 4; ++i) {
227 s = s1->sections[i + 1];
228 s1->total_output[i] += s->data_offset - s->sh_offset;
232 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
234 Section *sec;
236 sec = tcc_mallocz(sizeof(Section) + strlen(name));
237 sec->s1 = s1;
238 strcpy(sec->name, name);
239 sec->sh_type = sh_type;
240 sec->sh_flags = sh_flags;
241 switch(sh_type) {
242 case SHT_GNU_versym:
243 sec->sh_addralign = 2;
244 break;
245 case SHT_HASH:
246 case SHT_GNU_HASH:
247 case SHT_REL:
248 case SHT_RELA:
249 case SHT_DYNSYM:
250 case SHT_SYMTAB:
251 case SHT_DYNAMIC:
252 case SHT_GNU_verneed:
253 case SHT_GNU_verdef:
254 sec->sh_addralign = PTR_SIZE;
255 break;
256 case SHT_STRTAB:
257 sec->sh_addralign = 1;
258 break;
259 default:
260 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */
261 break;
264 if (sh_flags & SHF_PRIVATE) {
265 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
266 } else {
267 sec->sh_num = s1->nb_sections;
268 dynarray_add(&s1->sections, &s1->nb_sections, sec);
271 return sec;
274 ST_FUNC void init_symtab(Section *s)
276 int *ptr, nb_buckets = 1;
277 put_elf_str(s->link, "");
278 section_ptr_add(s, sizeof (ElfW(Sym)));
279 ptr = section_ptr_add(s->hash, (2 + nb_buckets + 1) * sizeof(int));
280 ptr[0] = nb_buckets;
281 ptr[1] = 1;
282 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
285 ST_FUNC Section *new_symtab(TCCState *s1,
286 const char *symtab_name, int sh_type, int sh_flags,
287 const char *strtab_name,
288 const char *hash_name, int hash_sh_flags)
290 Section *symtab, *strtab, *hash;
291 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
292 symtab->sh_entsize = sizeof(ElfW(Sym));
293 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
294 symtab->link = strtab;
295 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
296 hash->sh_entsize = sizeof(int);
297 symtab->hash = hash;
298 hash->link = symtab;
299 init_symtab(symtab);
300 return symtab;
303 /* realloc section and set its content to zero */
304 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
306 unsigned long size;
307 unsigned char *data;
309 size = sec->data_allocated;
310 if (size == 0)
311 size = 1;
312 while (size < new_size)
313 size = size * 2;
314 data = tcc_realloc(sec->data, size);
315 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
316 sec->data = data;
317 sec->data_allocated = size;
320 /* reserve at least 'size' bytes aligned per 'align' in section
321 'sec' from current offset, and return the aligned offset */
322 ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
324 size_t offset, offset1;
326 offset = (sec->data_offset + align - 1) & -align;
327 offset1 = offset + size;
328 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
329 section_realloc(sec, offset1);
330 sec->data_offset = offset1;
331 if (align > sec->sh_addralign)
332 sec->sh_addralign = align;
333 return offset;
336 /* reserve at least 'size' bytes in section 'sec' from
337 sec->data_offset. */
338 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
340 size_t offset = section_add(sec, size, 1);
341 return sec->data + offset;
344 #ifndef ELF_OBJ_ONLY
345 /* reserve at least 'size' bytes from section start */
346 static void section_reserve(Section *sec, unsigned long size)
348 if (size > sec->data_allocated)
349 section_realloc(sec, size);
350 if (size > sec->data_offset)
351 sec->data_offset = size;
353 #endif
355 static Section *have_section(TCCState *s1, const char *name)
357 Section *sec;
358 int i;
359 for(i = 1; i < s1->nb_sections; i++) {
360 sec = s1->sections[i];
361 if (!strcmp(name, sec->name))
362 return sec;
364 return NULL;
367 /* return a reference to a section, and create it if it does not
368 exists */
369 ST_FUNC Section *find_section(TCCState *s1, const char *name)
371 Section *sec = have_section(s1, name);
372 if (sec)
373 return sec;
374 /* sections are created as PROGBITS */
375 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
378 /* ------------------------------------------------------------------------- */
380 ST_FUNC int put_elf_str(Section *s, const char *sym)
382 int offset, len;
383 char *ptr;
385 len = strlen(sym) + 1;
386 offset = s->data_offset;
387 ptr = section_ptr_add(s, len);
388 memmove(ptr, sym, len);
389 return offset;
392 /* elf symbol hashing function */
393 static ElfW(Word) elf_hash(const unsigned char *name)
395 ElfW(Word) h = 0, g;
397 while (*name) {
398 h = (h << 4) + *name++;
399 g = h & 0xf0000000;
400 if (g)
401 h ^= g >> 24;
402 h &= ~g;
404 return h;
407 /* rebuild hash table of section s */
408 /* NOTE: we do factorize the hash table code to go faster */
409 static void rebuild_hash(Section *s, unsigned int nb_buckets)
411 ElfW(Sym) *sym;
412 int *ptr, *hash, nb_syms, sym_index, h;
413 unsigned char *strtab;
415 strtab = s->link->data;
416 nb_syms = s->data_offset / sizeof(ElfW(Sym));
418 if (!nb_buckets)
419 nb_buckets = ((int*)s->hash->data)[0];
421 s->hash->data_offset = 0;
422 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
423 ptr[0] = nb_buckets;
424 ptr[1] = nb_syms;
425 ptr += 2;
426 hash = ptr;
427 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
428 ptr += nb_buckets + 1;
430 sym = (ElfW(Sym) *)s->data + 1;
431 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
432 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
433 h = elf_hash(strtab + sym->st_name) % nb_buckets;
434 *ptr = hash[h];
435 hash[h] = sym_index;
436 } else {
437 *ptr = 0;
439 ptr++;
440 sym++;
444 /* return the symbol number */
445 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
446 int info, int other, int shndx, const char *name)
448 int name_offset, sym_index;
449 int nbuckets, h;
450 ElfW(Sym) *sym;
451 Section *hs;
453 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
454 if (name && name[0])
455 name_offset = put_elf_str(s->link, name);
456 else
457 name_offset = 0;
458 /* XXX: endianness */
459 sym->st_name = name_offset;
460 sym->st_value = value;
461 sym->st_size = size;
462 sym->st_info = info;
463 sym->st_other = other;
464 sym->st_shndx = shndx;
465 sym_index = sym - (ElfW(Sym) *)s->data;
466 hs = s->hash;
467 if (hs) {
468 int *ptr, *base;
469 ptr = section_ptr_add(hs, sizeof(int));
470 base = (int *)hs->data;
471 /* only add global or weak symbols. */
472 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
473 /* add another hashing entry */
474 nbuckets = base[0];
475 h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
476 *ptr = base[2 + h];
477 base[2 + h] = sym_index;
478 base[1]++;
479 /* we resize the hash table */
480 hs->nb_hashed_syms++;
481 if (hs->nb_hashed_syms > 2 * nbuckets) {
482 rebuild_hash(s, 2 * nbuckets);
484 } else {
485 *ptr = 0;
486 base[1]++;
489 return sym_index;
492 ST_FUNC int find_elf_sym(Section *s, const char *name)
494 ElfW(Sym) *sym;
495 Section *hs;
496 int nbuckets, sym_index, h;
497 const char *name1;
499 hs = s->hash;
500 if (!hs)
501 return 0;
502 nbuckets = ((int *)hs->data)[0];
503 h = elf_hash((unsigned char *) name) % nbuckets;
504 sym_index = ((int *)hs->data)[2 + h];
505 while (sym_index != 0) {
506 sym = &((ElfW(Sym) *)s->data)[sym_index];
507 name1 = (char *) s->link->data + sym->st_name;
508 if (!strcmp(name, name1))
509 return sym_index;
510 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
512 return 0;
515 /* return elf symbol value, signal error if 'err' is nonzero, decorate
516 name if FORC */
517 ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
519 int sym_index;
520 ElfW(Sym) *sym;
521 char buf[256];
522 if (forc && s1->leading_underscore
523 #ifdef TCC_TARGET_PE
524 /* win32-32bit stdcall symbols always have _ already */
525 && !strchr(name, '@')
526 #endif
528 buf[0] = '_';
529 pstrcpy(buf + 1, sizeof(buf) - 1, name);
530 name = buf;
532 sym_index = find_elf_sym(s1->symtab, name);
533 sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
534 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
535 if (err)
536 tcc_error_noabort("%s not defined", name);
537 return (addr_t)-1;
539 return sym->st_value;
542 /* return elf symbol value */
543 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
545 addr_t addr = get_sym_addr(s, name, 0, 1);
546 return addr == -1 ? NULL : (void*)(uintptr_t)addr;
549 /* list elf symbol names and values */
550 ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
551 void (*symbol_cb)(void *ctx, const char *name, const void *val))
553 ElfW(Sym) *sym;
554 Section *symtab;
555 int sym_index, end_sym;
556 const char *name;
557 unsigned char sym_vis, sym_bind;
559 symtab = s->symtab;
560 end_sym = symtab->data_offset / sizeof (ElfSym);
561 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
562 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
563 if (sym->st_value) {
564 name = (char *) symtab->link->data + sym->st_name;
565 sym_bind = ELFW(ST_BIND)(sym->st_info);
566 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
567 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
568 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
573 /* list elf symbol names and values */
574 LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
575 void (*symbol_cb)(void *ctx, const char *name, const void *val))
577 list_elf_symbols(s, ctx, symbol_cb);
580 #ifndef ELF_OBJ_ONLY
581 static void
582 version_add (TCCState *s1)
584 int i;
585 ElfW(Sym) *sym;
586 ElfW(Verneed) *vn = NULL;
587 Section *symtab;
588 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
589 ElfW(Half) *versym;
590 const char *name;
592 if (0 == nb_sym_versions)
593 return;
594 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
595 versym_section->sh_entsize = sizeof(ElfW(Half));
596 versym_section->link = s1->dynsym;
598 /* add needed symbols */
599 symtab = s1->dynsym;
600 end_sym = symtab->data_offset / sizeof (ElfSym);
601 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
602 for (sym_index = 1; sym_index < end_sym; ++sym_index) {
603 int dllindex, verndx;
604 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
605 if (sym->st_shndx != SHN_UNDEF)
606 continue; /* defined symbol doesn't need library version */
607 name = (char *) symtab->link->data + sym->st_name;
608 dllindex = find_elf_sym(s1->dynsymtab_section, name);
609 verndx = (dllindex && dllindex < nb_sym_to_version)
610 ? sym_to_version[dllindex] : -1;
611 if (verndx >= 0) {
612 if (!sym_versions[verndx].out_index)
613 sym_versions[verndx].out_index = nb_versions++;
614 versym[sym_index] = sym_versions[verndx].out_index;
617 /* generate verneed section, but not when it will be empty. Some
618 dynamic linkers look at their contents even when DTVERNEEDNUM and
619 section size is zero. */
620 if (nb_versions > 2) {
621 verneed_section = new_section(s1, ".gnu.version_r",
622 SHT_GNU_verneed, SHF_ALLOC);
623 verneed_section->link = s1->dynsym->link;
624 for (i = nb_sym_versions; i-- > 0;) {
625 struct sym_version *sv = &sym_versions[i];
626 int n_same_libs = 0, prev;
627 size_t vnofs;
628 ElfW(Vernaux) *vna = 0;
629 if (sv->out_index < 1)
630 continue;
632 /* make sure that a DT_NEEDED tag is put */
633 /* abitest-tcc fails on older i386-linux with "ld-linux.so.2" DT_NEEDED
634 ret_int_test... Inconsistency detected by ld.so: dl-minimal.c: 148:
635 realloc: Assertion `ptr == alloc_last_block' failed! */
636 if (strcmp(sv->lib, "ld-linux.so.2"))
637 tcc_add_dllref(s1, sv->lib, 0);
639 vnofs = section_add(verneed_section, sizeof(*vn), 1);
640 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
641 vn->vn_version = 1;
642 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
643 vn->vn_aux = sizeof (*vn);
644 do {
645 prev = sv->prev_same_lib;
646 if (sv->out_index > 0) {
647 vna = section_ptr_add(verneed_section, sizeof(*vna));
648 vna->vna_hash = elf_hash ((const unsigned char *)sv->version);
649 vna->vna_flags = 0;
650 vna->vna_other = sv->out_index;
651 sv->out_index = -2;
652 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
653 vna->vna_next = sizeof (*vna);
654 n_same_libs++;
656 if (prev >= 0)
657 sv = &sym_versions[prev];
658 } while(prev >= 0);
659 vna->vna_next = 0;
660 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
661 vn->vn_cnt = n_same_libs;
662 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
663 nb_entries++;
665 if (vn)
666 vn->vn_next = 0;
667 verneed_section->sh_info = nb_entries;
669 dt_verneednum = nb_entries;
671 #endif /* ndef ELF_OBJ_ONLY */
673 /* add an elf symbol : check if it is already defined and patch
674 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
675 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
676 int info, int other, int shndx, const char *name)
678 TCCState *s1 = s->s1;
679 ElfW(Sym) *esym;
680 int sym_bind, sym_index, sym_type, esym_bind;
681 unsigned char sym_vis, esym_vis, new_vis;
683 sym_bind = ELFW(ST_BIND)(info);
684 sym_type = ELFW(ST_TYPE)(info);
685 sym_vis = ELFW(ST_VISIBILITY)(other);
687 if (sym_bind != STB_LOCAL) {
688 /* we search global or weak symbols */
689 sym_index = find_elf_sym(s, name);
690 if (!sym_index)
691 goto do_def;
692 esym = &((ElfW(Sym) *)s->data)[sym_index];
693 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
694 && esym->st_other == other && esym->st_shndx == shndx)
695 return sym_index;
696 if (esym->st_shndx != SHN_UNDEF) {
697 esym_bind = ELFW(ST_BIND)(esym->st_info);
698 /* propagate the most constraining visibility */
699 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
700 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
701 if (esym_vis == STV_DEFAULT) {
702 new_vis = sym_vis;
703 } else if (sym_vis == STV_DEFAULT) {
704 new_vis = esym_vis;
705 } else {
706 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
708 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
709 | new_vis;
710 if (shndx == SHN_UNDEF) {
711 /* ignore adding of undefined symbol if the
712 corresponding symbol is already defined */
713 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
714 /* global overrides weak, so patch */
715 goto do_patch;
716 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
717 /* weak is ignored if already global */
718 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
719 /* keep first-found weak definition, ignore subsequents */
720 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
721 /* ignore hidden symbols after */
722 } else if ((esym->st_shndx == SHN_COMMON
723 || esym->st_shndx == bss_section->sh_num)
724 && (shndx < SHN_LORESERVE
725 && shndx != bss_section->sh_num)) {
726 /* data symbol gets precedence over common/bss */
727 goto do_patch;
728 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
729 /* data symbol keeps precedence over common/bss */
730 } else if (s->sh_flags & SHF_DYNSYM) {
731 /* we accept that two DLL define the same symbol */
732 } else if (esym->st_other & ST_ASM_SET) {
733 /* If the existing symbol came from an asm .set
734 we can override. */
735 goto do_patch;
736 } else {
737 #if 0
738 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
739 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
740 #endif
741 tcc_error_noabort("'%s' defined twice", name);
743 } else {
744 esym->st_other = other;
745 do_patch:
746 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
747 esym->st_shndx = shndx;
748 s1->new_undef_sym = 1;
749 esym->st_value = value;
750 esym->st_size = size;
752 } else {
753 do_def:
754 sym_index = put_elf_sym(s, value, size,
755 ELFW(ST_INFO)(sym_bind, sym_type), other,
756 shndx, name);
758 return sym_index;
761 /* put relocation */
762 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
763 int type, int symbol, addr_t addend)
765 TCCState *s1 = s->s1;
766 char buf[256];
767 Section *sr;
768 ElfW_Rel *rel;
770 sr = s->reloc;
771 if (!sr) {
772 /* if no relocation section, create it */
773 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
774 /* if the symtab is allocated, then we consider the relocation
775 are also */
776 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
777 sr->sh_entsize = sizeof(ElfW_Rel);
778 sr->link = symtab;
779 sr->sh_info = s->sh_num;
780 s->reloc = sr;
782 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
783 rel->r_offset = offset;
784 rel->r_info = ELFW(R_INFO)(symbol, type);
785 #if SHT_RELX == SHT_RELA
786 rel->r_addend = addend;
787 #endif
788 if (SHT_RELX != SHT_RELA && addend)
789 tcc_error_noabort("non-zero addend on REL architecture");
792 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
793 int type, int symbol)
795 put_elf_reloca(symtab, s, offset, type, symbol, 0);
798 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
800 int n;
801 struct sym_attr *tab;
803 if (index >= s1->nb_sym_attrs) {
804 if (!alloc)
805 return s1->sym_attrs;
806 /* find immediately bigger power of 2 and reallocate array */
807 n = 1;
808 while (index >= n)
809 n *= 2;
810 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
811 s1->sym_attrs = tab;
812 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
813 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
814 s1->nb_sym_attrs = n;
816 return &s1->sym_attrs[index];
819 static void modify_reloctions_old_to_new(TCCState *s1, Section *s, int *old_to_new_syms)
821 int i, type, sym_index;
822 Section *sr;
823 ElfW_Rel *rel;
825 for(i = 1; i < s1->nb_sections; i++) {
826 sr = s1->sections[i];
827 if (sr->sh_type == SHT_RELX && sr->link == s) {
828 for_each_elem(sr, 0, rel, ElfW_Rel) {
829 sym_index = ELFW(R_SYM)(rel->r_info);
830 type = ELFW(R_TYPE)(rel->r_info);
831 sym_index = old_to_new_syms[sym_index];
832 rel->r_info = ELFW(R_INFO)(sym_index, type);
838 /* In an ELF file symbol table, the local symbols must appear below
839 the global and weak ones. Since TCC cannot sort it while generating
840 the code, we must do it after. All the relocation tables are also
841 modified to take into account the symbol table sorting */
842 static void sort_syms(TCCState *s1, Section *s)
844 int *old_to_new_syms;
845 ElfW(Sym) *new_syms;
846 int nb_syms, i;
847 ElfW(Sym) *p, *q;
849 nb_syms = s->data_offset / sizeof(ElfW(Sym));
850 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
851 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
853 /* first pass for local symbols */
854 p = (ElfW(Sym) *)s->data;
855 q = new_syms;
856 for(i = 0; i < nb_syms; i++) {
857 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
858 old_to_new_syms[i] = q - new_syms;
859 *q++ = *p;
861 p++;
863 /* save the number of local symbols in section header */
864 if( s->sh_size ) /* this 'if' makes IDA happy */
865 s->sh_info = q - new_syms;
867 /* then second pass for non local symbols */
868 p = (ElfW(Sym) *)s->data;
869 for(i = 0; i < nb_syms; i++) {
870 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
871 old_to_new_syms[i] = q - new_syms;
872 *q++ = *p;
874 p++;
877 /* we copy the new symbols to the old */
878 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
879 tcc_free(new_syms);
881 modify_reloctions_old_to_new(s1, s, old_to_new_syms);
883 tcc_free(old_to_new_syms);
886 #ifndef ELF_OBJ_ONLY
887 /* See: https://flapenguin.me/elf-dt-gnu-hash */
888 #define ELFCLASS_BITS (PTR_SIZE * 8)
890 static Section *create_gnu_hash(TCCState *s1)
892 int nb_syms, i, ndef, nbuckets, symoffset, bloom_size, bloom_shift;
893 ElfW(Sym) *p;
894 Section *gnu_hash;
895 Section *dynsym = s1->dynsym;
896 Elf32_Word *ptr;
898 gnu_hash = new_section(s1, ".gnu.hash", SHT_GNU_HASH, SHF_ALLOC);
899 gnu_hash->link = dynsym->hash->link;
901 nb_syms = dynsym->data_offset / sizeof(ElfW(Sym));
903 /* count def symbols */
904 ndef = 0;
905 p = (ElfW(Sym) *)dynsym->data;
906 for(i = 0; i < nb_syms; i++, p++)
907 ndef += p->st_shndx != SHN_UNDEF;
909 /* calculate gnu hash sizes and fill header */
910 nbuckets = ndef / 4 + 1;
911 symoffset = nb_syms - ndef;
912 bloom_shift = PTR_SIZE == 8 ? 6 : 5;
913 bloom_size = 1; /* must be power of two */
914 while (ndef >= bloom_size * (1 << (bloom_shift - 3)))
915 bloom_size *= 2;
916 ptr = section_ptr_add(gnu_hash, 4 * 4 +
917 PTR_SIZE * bloom_size +
918 nbuckets * 4 +
919 ndef * 4);
920 ptr[0] = nbuckets;
921 ptr[1] = symoffset;
922 ptr[2] = bloom_size;
923 ptr[3] = bloom_shift;
924 return gnu_hash;
927 static Elf32_Word elf_gnu_hash (const unsigned char *name)
929 Elf32_Word h = 5381;
930 unsigned char c;
932 while ((c = *name++))
933 h = h * 33 + c;
934 return h;
937 static void update_gnu_hash(TCCState *s1, Section *gnu_hash)
939 int *old_to_new_syms;
940 ElfW(Sym) *new_syms;
941 int nb_syms, i, nbuckets, bloom_size, bloom_shift;
942 ElfW(Sym) *p, *q;
943 Section *vs;
944 Section *dynsym = s1->dynsym;
945 Elf32_Word *ptr, *buckets, *chain, *hash;
946 unsigned int *nextbuck;
947 addr_t *bloom;
948 unsigned char *strtab;
949 struct { int first, last; } *buck;
951 strtab = dynsym->link->data;
952 nb_syms = dynsym->data_offset / sizeof(ElfW(Sym));
953 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
954 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
955 hash = tcc_malloc(nb_syms * sizeof(Elf32_Word));
956 nextbuck = tcc_malloc(nb_syms * sizeof(int));
958 /* calculate hashes and copy undefs */
959 p = (ElfW(Sym) *)dynsym->data;
960 q = new_syms;
961 for(i = 0; i < nb_syms; i++, p++) {
962 if (p->st_shndx == SHN_UNDEF) {
963 old_to_new_syms[i] = q - new_syms;
964 *q++ = *p;
966 else
967 hash[i] = elf_gnu_hash(strtab + p->st_name);
970 ptr = (Elf32_Word *) gnu_hash->data;
971 nbuckets = ptr[0];
972 bloom_size = ptr[2];
973 bloom_shift = ptr[3];
974 bloom = (addr_t *) (void *) &ptr[4];
975 buckets = (Elf32_Word*) (void *) &bloom[bloom_size];
976 chain = &buckets[nbuckets];
977 buck = tcc_malloc(nbuckets * sizeof(*buck));
979 if (gnu_hash->data_offset != 4 * 4 +
980 PTR_SIZE * bloom_size +
981 nbuckets * 4 +
982 (nb_syms - (q - new_syms)) * 4)
983 tcc_error_noabort ("gnu_hash size incorrect");
985 /* find buckets */
986 for(i = 0; i < nbuckets; i++)
987 buck[i].first = -1;
989 p = (ElfW(Sym) *)dynsym->data;
990 for(i = 0; i < nb_syms; i++, p++)
991 if (p->st_shndx != SHN_UNDEF) {
992 int bucket = hash[i] % nbuckets;
994 if (buck[bucket].first == -1)
995 buck[bucket].first = buck[bucket].last = i;
996 else {
997 nextbuck[buck[bucket].last] = i;
998 buck[bucket].last = i;
1002 /* fill buckets/chains/bloom and sort symbols */
1003 p = (ElfW(Sym) *)dynsym->data;
1004 for(i = 0; i < nbuckets; i++) {
1005 int cur = buck[i].first;
1007 if (cur != -1) {
1008 buckets[i] = q - new_syms;
1009 for (;;) {
1010 old_to_new_syms[cur] = q - new_syms;
1011 *q++ = p[cur];
1012 *chain++ = hash[cur] & ~1;
1013 bloom[(hash[cur] / ELFCLASS_BITS) % bloom_size] |=
1014 (addr_t)1 << (hash[cur] % ELFCLASS_BITS) |
1015 (addr_t)1 << ((hash[cur] >> bloom_shift) % ELFCLASS_BITS);
1016 if (cur == buck[i].last)
1017 break;
1018 cur = nextbuck[cur];
1020 chain[-1] |= 1;
1024 memcpy(dynsym->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
1025 tcc_free(new_syms);
1026 tcc_free(hash);
1027 tcc_free(buck);
1028 tcc_free(nextbuck);
1030 modify_reloctions_old_to_new(s1, dynsym, old_to_new_syms);
1032 /* modify the versions */
1033 vs = versym_section;
1034 if (vs) {
1035 ElfW(Half) *newver, *versym = (ElfW(Half) *)vs->data;
1037 if (1/*versym*/) {
1038 newver = tcc_malloc(nb_syms * sizeof(*newver));
1039 for (i = 0; i < nb_syms; i++)
1040 newver[old_to_new_syms[i]] = versym[i];
1041 memcpy(vs->data, newver, nb_syms * sizeof(*newver));
1042 tcc_free(newver);
1046 tcc_free(old_to_new_syms);
1048 /* rebuild hash */
1049 ptr = (Elf32_Word *) dynsym->hash->data;
1050 rebuild_hash(dynsym, ptr[0]);
1052 #endif /* ELF_OBJ_ONLY */
1054 /* relocate symbol table, resolve undefined symbols if do_resolve is
1055 true and output error if undefined symbol. */
1056 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
1058 ElfW(Sym) *sym;
1059 int sym_bind, sh_num;
1060 const char *name;
1062 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
1063 sh_num = sym->st_shndx;
1064 if (sh_num == SHN_UNDEF) {
1065 if (do_resolve == 2) /* relocating dynsym */
1066 continue;
1067 name = (char *) s1->symtab->link->data + sym->st_name;
1068 /* Use ld.so to resolve symbol for us (for tcc -run) */
1069 if (do_resolve) {
1070 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
1071 /* dlsym() needs the undecorated name. */
1072 void *addr = dlsym(RTLD_DEFAULT, &name[s1->leading_underscore]);
1073 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD || TARGETOS_ANDROID
1074 if (addr == NULL) {
1075 int i;
1076 for (i = 0; i < s1->nb_loaded_dlls; i++)
1077 if ((addr = dlsym(s1->loaded_dlls[i]->handle, name)))
1078 break;
1080 #endif
1081 if (addr) {
1082 sym->st_value = (addr_t) addr;
1083 #ifdef DEBUG_RELOC
1084 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
1085 #endif
1086 goto found;
1088 #endif
1089 /* if dynamic symbol exist, it will be used in relocate_section */
1090 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
1091 goto found;
1092 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1093 it */
1094 if (!strcmp(name, "_fp_hw"))
1095 goto found;
1096 /* only weak symbols are accepted to be undefined. Their
1097 value is zero */
1098 sym_bind = ELFW(ST_BIND)(sym->st_info);
1099 if (sym_bind == STB_WEAK)
1100 sym->st_value = 0;
1101 else
1102 tcc_error_noabort("undefined symbol '%s'", name);
1104 } else if (sh_num < SHN_LORESERVE) {
1105 /* add section base */
1106 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1108 found: ;
1112 /* relocate a given section (CPU dependent) by applying the relocations
1113 in the associated relocation section */
1114 static void relocate_section(TCCState *s1, Section *s, Section *sr)
1116 ElfW_Rel *rel;
1117 ElfW(Sym) *sym;
1118 int type, sym_index;
1119 unsigned char *ptr;
1120 addr_t tgt, addr;
1121 int is_dwarf = s->sh_num >= s1->dwlo && s->sh_num < s1->dwhi;
1123 qrel = (ElfW_Rel *)sr->data;
1124 for_each_elem(sr, 0, rel, ElfW_Rel) {
1125 ptr = s->data + rel->r_offset;
1126 sym_index = ELFW(R_SYM)(rel->r_info);
1127 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1128 type = ELFW(R_TYPE)(rel->r_info);
1129 tgt = sym->st_value;
1130 #if SHT_RELX == SHT_RELA
1131 tgt += rel->r_addend;
1132 #endif
1133 if (is_dwarf && type == R_DATA_32DW
1134 && sym->st_shndx >= s1->dwlo && sym->st_shndx < s1->dwhi) {
1135 /* dwarf section relocation to each other */
1136 add32le(ptr, tgt - s1->sections[sym->st_shndx]->sh_addr);
1137 continue;
1139 addr = s->sh_addr + rel->r_offset;
1140 relocate(s1, rel, type, ptr, addr, tgt);
1142 #ifndef ELF_OBJ_ONLY
1143 /* if the relocation is allocated, we change its symbol table */
1144 if (sr->sh_flags & SHF_ALLOC) {
1145 sr->link = s1->dynsym;
1146 if (s1->output_type & TCC_OUTPUT_DYN) {
1147 size_t r = (uint8_t*)qrel - sr->data;
1148 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
1149 && 0 == strcmp(s->name, ".stab"))
1150 r = 0; /* cannot apply 64bit relocation to 32bit value */
1151 sr->data_offset = sr->sh_size = r;
1152 #ifdef CONFIG_TCC_PIE
1153 if (r && 0 == (s->sh_flags & SHF_WRITE))
1154 tcc_warning("%d relocations to ro-section %s", (unsigned)(r / sizeof *qrel), s->name);
1155 #endif
1158 #endif
1161 /* relocate all sections */
1162 ST_FUNC void relocate_sections(TCCState *s1)
1164 int i;
1165 Section *s, *sr;
1167 for (i = 1; i < s1->nb_sections; ++i) {
1168 sr = s1->sections[i];
1169 if (sr->sh_type != SHT_RELX)
1170 continue;
1171 s = s1->sections[sr->sh_info];
1172 #ifndef TCC_TARGET_MACHO
1173 if (s != s1->got
1174 || s1->static_link
1175 || s1->output_type == TCC_OUTPUT_MEMORY)
1176 #endif
1178 relocate_section(s1, s, sr);
1180 #ifndef ELF_OBJ_ONLY
1181 if (sr->sh_flags & SHF_ALLOC) {
1182 ElfW_Rel *rel;
1183 /* relocate relocation table in 'sr' */
1184 for_each_elem(sr, 0, rel, ElfW_Rel)
1185 rel->r_offset += s->sh_addr;
1187 #endif
1191 #ifndef ELF_OBJ_ONLY
1192 /* count the number of dynamic relocations so that we can reserve
1193 their space */
1194 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
1196 int count = 0;
1197 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1198 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1199 defined(TCC_TARGET_RISCV64)
1200 ElfW_Rel *rel;
1201 for_each_elem(sr, 0, rel, ElfW_Rel) {
1202 int sym_index = ELFW(R_SYM)(rel->r_info);
1203 int type = ELFW(R_TYPE)(rel->r_info);
1204 switch(type) {
1205 #if defined(TCC_TARGET_I386)
1206 case R_386_32:
1207 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
1208 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
1209 /* don't fixup unresolved (weak) symbols */
1210 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
1211 break;
1213 #elif defined(TCC_TARGET_X86_64)
1214 case R_X86_64_32:
1215 case R_X86_64_32S:
1216 case R_X86_64_64:
1217 #elif defined(TCC_TARGET_ARM)
1218 case R_ARM_ABS32:
1219 case R_ARM_TARGET1:
1220 #elif defined(TCC_TARGET_ARM64)
1221 case R_AARCH64_ABS32:
1222 case R_AARCH64_ABS64:
1223 #elif defined(TCC_TARGET_RISCV64)
1224 case R_RISCV_32:
1225 case R_RISCV_64:
1226 #endif
1227 count++;
1228 break;
1229 #if defined(TCC_TARGET_I386)
1230 case R_386_PC32:
1231 #elif defined(TCC_TARGET_X86_64)
1232 case R_X86_64_PC32:
1234 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1235 /* Hidden defined symbols can and must be resolved locally.
1236 We're misusing a PLT32 reloc for this, as that's always
1237 resolved to its address even in shared libs. */
1238 if (sym->st_shndx != SHN_UNDEF &&
1239 ELFW(ST_VISIBILITY)(sym->st_other) == STV_HIDDEN) {
1240 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PLT32);
1241 break;
1244 #elif defined(TCC_TARGET_ARM64)
1245 case R_AARCH64_PREL32:
1246 #endif
1247 if (s1->output_type != TCC_OUTPUT_DLL)
1248 break;
1249 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1250 count++;
1251 break;
1252 default:
1253 break;
1256 #endif
1257 return count;
1259 #endif
1261 #ifdef NEED_BUILD_GOT
1262 static int build_got(TCCState *s1)
1264 /* if no got, then create it */
1265 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1266 s1->got->sh_entsize = 4;
1267 /* keep space for _DYNAMIC pointer and two dummy got entries */
1268 section_ptr_add(s1->got, 3 * PTR_SIZE);
1269 return set_elf_sym(symtab_section, 0, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1270 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1273 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1274 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1275 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1276 Returns the offset of the GOT or (if any) PLT entry. */
1277 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1278 int sym_index)
1280 int need_plt_entry;
1281 const char *name;
1282 ElfW(Sym) *sym;
1283 struct sym_attr *attr;
1284 unsigned got_offset;
1285 char plt_name[200];
1286 int len;
1287 Section *s_rel;
1289 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1290 attr = get_sym_attr(s1, sym_index, 1);
1292 /* In case a function is both called and its address taken 2 GOT entries
1293 are created, one for taking the address (GOT) and the other for the PLT
1294 entry (PLTGOT). */
1295 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1296 return attr;
1298 s_rel = s1->got;
1299 if (need_plt_entry) {
1300 if (!s1->plt) {
1301 s1->plt = new_section(s1, ".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
1302 s1->plt->sh_entsize = 4;
1304 s_rel = s1->plt;
1307 /* create the GOT entry */
1308 got_offset = s1->got->data_offset;
1309 section_ptr_add(s1->got, PTR_SIZE);
1311 /* Create the GOT relocation that will insert the address of the object or
1312 function of interest in the GOT entry. This is a static relocation for
1313 memory output (dlsym will give us the address of symbols) and dynamic
1314 relocation otherwise (executable and DLLs). The relocation should be
1315 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1316 associated to a PLT entry) but is currently done at load time for an
1317 unknown reason. */
1319 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1320 name = (char *) symtab_section->link->data + sym->st_name;
1321 //printf("sym %d %s\n", need_plt_entry, name);
1323 if (s1->dynsym) {
1324 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1325 /* Hack alarm. We don't want to emit dynamic symbols
1326 and symbol based relocs for STB_LOCAL symbols, but rather
1327 want to resolve them directly. At this point the symbol
1328 values aren't final yet, so we must defer this. We will later
1329 have to create a RELATIVE reloc anyway, so we misuse the
1330 relocation slot to smuggle the symbol reference until
1331 fill_local_got_entries. Not that the sym_index is
1332 relative to symtab_section, not s1->dynsym! Nevertheless
1333 we use s1->dyn_sym so that if this is the first call
1334 that got->reloc is correctly created. Also note that
1335 RELATIVE relocs are not normally created for the .got,
1336 so the types serves as a marker for later (and is retained
1337 also for the final output, which is okay because then the
1338 got is just normal data). */
1339 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1340 sym_index);
1341 } else {
1342 if (0 == attr->dyn_index)
1343 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1344 sym->st_size, sym->st_info, 0,
1345 sym->st_shndx, name);
1346 put_elf_reloc(s1->dynsym, s_rel, got_offset, dyn_reloc_type,
1347 attr->dyn_index);
1349 } else {
1350 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1351 sym_index);
1354 if (need_plt_entry) {
1355 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1357 /* create a symbol 'sym@plt' for the PLT jump vector */
1358 len = strlen(name);
1359 if (len > sizeof plt_name - 5)
1360 len = sizeof plt_name - 5;
1361 memcpy(plt_name, name, len);
1362 strcpy(plt_name + len, "@plt");
1363 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, 0,
1364 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1365 } else {
1366 attr->got_offset = got_offset;
1369 return attr;
1372 /* build GOT and PLT entries */
1373 /* Two passes because R_JMP_SLOT should become first. Some targets
1374 (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1375 ST_FUNC void build_got_entries(TCCState *s1, int got_sym)
1377 Section *s;
1378 ElfW_Rel *rel;
1379 ElfW(Sym) *sym;
1380 int i, type, gotplt_entry, reloc_type, sym_index;
1381 struct sym_attr *attr;
1382 int pass = 0;
1383 redo:
1384 for(i = 1; i < s1->nb_sections; i++) {
1385 s = s1->sections[i];
1386 if (s->sh_type != SHT_RELX)
1387 continue;
1388 /* no need to handle got relocations */
1389 if (s->link != symtab_section)
1390 continue;
1391 for_each_elem(s, 0, rel, ElfW_Rel) {
1392 type = ELFW(R_TYPE)(rel->r_info);
1393 gotplt_entry = gotplt_entry_type(type);
1394 if (gotplt_entry == -1) {
1395 tcc_error_noabort ("Unknown relocation type for got: %d", type);
1396 continue;
1398 sym_index = ELFW(R_SYM)(rel->r_info);
1399 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1401 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1402 continue;
1405 /* Automatically create PLT/GOT [entry] if it is an undefined
1406 reference (resolved at runtime), or the symbol is absolute,
1407 probably created by tcc_add_symbol, and thus on 64-bit
1408 targets might be too far from application code. */
1409 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1410 if (sym->st_shndx == SHN_UNDEF) {
1411 ElfW(Sym) *esym;
1412 int dynindex;
1413 if (!PCRELATIVE_DLLPLT
1414 && (s1->output_type & TCC_OUTPUT_DYN))
1415 continue;
1416 /* Relocations for UNDEF symbols would normally need
1417 to be transferred into the executable or shared object.
1418 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1419 But TCC doesn't do that (at least for exes), so we
1420 need to resolve all such relocs locally. And that
1421 means PLT slots for functions in DLLs and COPY relocs for
1422 data symbols. COPY relocs were generated in
1423 bind_exe_dynsyms (and the symbol adjusted to be defined),
1424 and for functions we were generated a dynamic symbol
1425 of function type. */
1426 if (s1->dynsym) {
1427 /* dynsym isn't set for -run :-/ */
1428 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1429 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1430 if (dynindex
1431 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1432 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1433 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1434 goto jmp_slot;
1436 } else if (sym->st_shndx == SHN_ABS) {
1437 if (sym->st_value == 0) /* from tcc_add_btstub() */
1438 continue;
1439 #ifndef TCC_TARGET_ARM
1440 if (PTR_SIZE != 8)
1441 continue;
1442 #endif
1443 /* from tcc_add_symbol(): on 64 bit platforms these
1444 need to go through .got */
1445 } else
1446 continue;
1449 #ifdef TCC_TARGET_X86_64
1450 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1451 sym->st_shndx != SHN_UNDEF &&
1452 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1453 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1454 s1->output_type & TCC_OUTPUT_EXE)) {
1455 if (pass != 0)
1456 continue;
1457 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1458 continue;
1460 #endif
1461 reloc_type = code_reloc(type);
1462 if (reloc_type == -1) {
1463 tcc_error_noabort ("Unknown relocation type: %d", type);
1464 continue;
1467 if (reloc_type != 0) {
1468 jmp_slot:
1469 if (pass != 0)
1470 continue;
1471 reloc_type = R_JMP_SLOT;
1472 } else {
1473 if (pass != 1)
1474 continue;
1475 reloc_type = R_GLOB_DAT;
1478 if (!s1->got)
1479 got_sym = build_got(s1);
1481 if (gotplt_entry == BUILD_GOT_ONLY)
1482 continue;
1484 attr = put_got_entry(s1, reloc_type, sym_index);
1486 if (reloc_type == R_JMP_SLOT)
1487 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1490 if (++pass < 2)
1491 goto redo;
1492 /* .rel.plt refers to .got actually */
1493 if (s1->plt && s1->plt->reloc)
1494 s1->plt->reloc->sh_info = s1->got->sh_num;
1495 if (got_sym) /* set size */
1496 ((ElfW(Sym)*)symtab_section->data)[got_sym].st_size = s1->got->data_offset;
1498 #endif /* def NEED_BUILD_GOT */
1500 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
1502 int shn = sec ? sec->sh_num : offs || !name ? SHN_ABS : SHN_UNDEF;
1503 if (sec && offs == -1)
1504 offs = sec->data_offset;
1505 return set_elf_sym(symtab_section, offs, 0,
1506 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1509 static void add_init_array_defines(TCCState *s1, const char *section_name)
1511 Section *s;
1512 addr_t end_offset;
1513 char buf[1024];
1514 s = have_section(s1, section_name);
1515 if (!s || !(s->sh_flags & SHF_ALLOC)) {
1516 end_offset = 0;
1517 s = data_section;
1518 } else {
1519 end_offset = s->data_offset;
1521 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1522 set_global_sym(s1, buf, s, 0);
1523 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1524 set_global_sym(s1, buf, s, end_offset);
1527 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1529 Section *s;
1530 s = find_section(s1, sec);
1531 s->sh_flags = shf_RELRO;
1532 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1533 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1534 section_ptr_add(s, PTR_SIZE);
1537 #ifdef CONFIG_TCC_BCHECK
1538 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1540 if (0 == s1->do_bounds_check)
1541 return;
1542 section_ptr_add(bounds_section, sizeof(addr_t));
1544 #endif
1546 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1547 a dynamic symbol to allow so's to have one each with a different value. */
1548 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1550 int c = find_elf_sym(s1->symtab, name);
1551 if (c) {
1552 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1553 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1554 esym->st_value = offset;
1555 esym->st_shndx = s->sh_num;
1559 /* avoid generating debug/test_coverage code for stub functions */
1560 static void tcc_compile_string_no_debug(TCCState *s, const char *str)
1562 int save_do_debug = s->do_debug;
1563 int save_test_coverage = s->test_coverage;
1565 s->do_debug = 0;
1566 s->test_coverage = 0;
1567 tcc_compile_string(s, str);
1568 s->do_debug = save_do_debug;
1569 s->test_coverage = save_test_coverage;
1572 #ifdef CONFIG_TCC_BACKTRACE
1573 static void put_ptr(TCCState *s1, Section *s, int offs)
1575 int c;
1576 c = set_global_sym(s1, NULL, s, offs);
1577 s = data_section;
1578 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1579 section_ptr_add(s, PTR_SIZE);
1582 ST_FUNC void tcc_add_btstub(TCCState *s1)
1584 Section *s;
1585 int n, o;
1586 CString cstr;
1588 s = data_section;
1589 /* Align to PTR_SIZE */
1590 section_ptr_add(s, -s->data_offset & (PTR_SIZE - 1));
1591 o = s->data_offset;
1592 /* create (part of) a struct rt_context (see tccrun.c) */
1593 if (s1->dwarf) {
1594 put_ptr(s1, dwarf_line_section, 0);
1595 put_ptr(s1, dwarf_line_section, -1);
1596 if (s1->dwarf >= 5)
1597 put_ptr(s1, dwarf_line_str_section, 0);
1598 else
1599 put_ptr(s1, dwarf_str_section, 0);
1601 else
1603 put_ptr(s1, stab_section, 0);
1604 put_ptr(s1, stab_section, -1);
1605 put_ptr(s1, stab_section->link, 0);
1607 *(addr_t *)section_ptr_add(s, PTR_SIZE) = s1->dwarf;
1608 /* skip esym_start/esym_end/elf_str (not loaded) */
1609 section_ptr_add(s, 3 * PTR_SIZE);
1610 /* prog_base : local nameless symbol with offset 0 at SHN_ABS */
1611 put_ptr(s1, NULL, 0);
1612 #if defined TCC_TARGET_MACHO
1613 /* adjust for __PAGEZERO */
1614 if (s1->dwarf == 0 && s1->output_type == TCC_OUTPUT_EXE)
1615 write64le(data_section->data + data_section->data_offset - PTR_SIZE,
1616 (uint64_t)1 << 32);
1617 #endif
1618 n = 2 * PTR_SIZE;
1619 #ifdef CONFIG_TCC_BCHECK
1620 if (s1->do_bounds_check) {
1621 put_ptr(s1, bounds_section, 0);
1622 n -= PTR_SIZE;
1624 #endif
1625 section_ptr_add(s, n);
1626 cstr_new(&cstr);
1627 cstr_printf(&cstr,
1628 "extern void __bt_init(),__bt_exit(),__bt_init_dll();"
1629 "static void *__rt_info[];"
1630 "__attribute__((constructor)) static void __bt_init_rt(){");
1631 #ifdef TCC_TARGET_PE
1632 if (s1->output_type == TCC_OUTPUT_DLL)
1633 #ifdef CONFIG_TCC_BCHECK
1634 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1635 #else
1636 cstr_printf(&cstr, "__bt_init_dll(0);");
1637 #endif
1638 #endif
1639 cstr_printf(&cstr, "__bt_init(__rt_info,%d);}",
1640 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1641 /* In case dlcose is called by application */
1642 cstr_printf(&cstr,
1643 "__attribute__((destructor)) static void __bt_exit_rt(){"
1644 "__bt_exit(__rt_info);}");
1645 tcc_compile_string_no_debug(s1, cstr.data);
1646 cstr_free(&cstr);
1647 set_local_sym(s1, &"___rt_info"[!s1->leading_underscore], s, o);
1649 #endif /* def CONFIG_TCC_BACKTRACE */
1651 static void tcc_tcov_add_file(TCCState *s1, const char *filename)
1653 CString cstr;
1654 void *ptr;
1655 char wd[1024];
1657 if (tcov_section == NULL)
1658 return;
1659 section_ptr_add(tcov_section, 1);
1660 write32le (tcov_section->data, tcov_section->data_offset);
1662 cstr_new (&cstr);
1663 if (filename[0] == '/')
1664 cstr_printf (&cstr, "%s.tcov", filename);
1665 else {
1666 getcwd (wd, sizeof(wd));
1667 cstr_printf (&cstr, "%s/%s.tcov", wd, filename);
1669 ptr = section_ptr_add(tcov_section, cstr.size + 1);
1670 strcpy((char *)ptr, cstr.data);
1671 unlink((char *)ptr);
1672 #ifdef _WIN32
1673 normalize_slashes((char *)ptr);
1674 #endif
1675 cstr_free (&cstr);
1677 cstr_new(&cstr);
1678 cstr_printf(&cstr,
1679 "extern char *__tcov_data[];"
1680 "extern void __store_test_coverage ();"
1681 "__attribute__((destructor)) static void __tcov_exit() {"
1682 "__store_test_coverage(__tcov_data);"
1683 "}");
1684 tcc_compile_string_no_debug(s1, cstr.data);
1685 cstr_free(&cstr);
1686 set_local_sym(s1, &"___tcov_data"[!s1->leading_underscore], tcov_section, 0);
1689 #if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO
1690 /* add libc crt1/crti objects */
1691 ST_FUNC void tccelf_add_crtbegin(TCCState *s1)
1693 #if TARGETOS_OpenBSD
1694 if (s1->output_type != TCC_OUTPUT_DLL)
1695 tcc_add_crt(s1, "crt0.o");
1696 if (s1->output_type == TCC_OUTPUT_DLL)
1697 tcc_add_crt(s1, "crtbeginS.o");
1698 else
1699 tcc_add_crt(s1, "crtbegin.o");
1700 #elif TARGETOS_FreeBSD || TARGETOS_NetBSD
1701 if (s1->output_type != TCC_OUTPUT_DLL)
1702 #if TARGETOS_FreeBSD
1703 tcc_add_crt(s1, "crt1.o");
1704 #else
1705 tcc_add_crt(s1, "crt0.o");
1706 #endif
1707 tcc_add_crt(s1, "crti.o");
1708 if (s1->static_link)
1709 tcc_add_crt(s1, "crtbeginT.o");
1710 else if (s1->output_type == TCC_OUTPUT_DLL)
1711 tcc_add_crt(s1, "crtbeginS.o");
1712 else
1713 tcc_add_crt(s1, "crtbegin.o");
1714 #elif TARGETOS_ANDROID
1715 if (s1->output_type == TCC_OUTPUT_DLL)
1716 tcc_add_crt(s1, "crtbegin_so.o");
1717 else
1718 tcc_add_crt(s1, "crtbegin_dynamic.o");
1719 #else
1720 if (s1->output_type != TCC_OUTPUT_DLL)
1721 tcc_add_crt(s1, "crt1.o");
1722 tcc_add_crt(s1, "crti.o");
1723 #endif
1726 ST_FUNC void tccelf_add_crtend(TCCState *s1)
1728 #if TARGETOS_OpenBSD
1729 if (s1->output_type == TCC_OUTPUT_DLL)
1730 tcc_add_crt(s1, "crtendS.o");
1731 else
1732 tcc_add_crt(s1, "crtend.o");
1733 #elif TARGETOS_FreeBSD || TARGETOS_NetBSD
1734 if (s1->output_type == TCC_OUTPUT_DLL)
1735 tcc_add_crt(s1, "crtendS.o");
1736 else
1737 tcc_add_crt(s1, "crtend.o");
1738 tcc_add_crt(s1, "crtn.o");
1739 #elif TARGETOS_ANDROID
1740 if (s1->output_type == TCC_OUTPUT_DLL)
1741 tcc_add_crt(s1, "crtend_so.o");
1742 else
1743 tcc_add_crt(s1, "crtend_android.o");
1744 #else
1745 tcc_add_crt(s1, "crtn.o");
1746 #endif
1748 #endif /* !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO */
1750 #ifndef TCC_TARGET_PE
1751 /* add tcc runtime libraries */
1752 ST_FUNC void tcc_add_runtime(TCCState *s1)
1754 s1->filetype = 0;
1756 #ifdef CONFIG_TCC_BCHECK
1757 tcc_add_bcheck(s1);
1758 #endif
1759 tcc_add_pragma_libs(s1);
1761 /* add libc */
1762 if (!s1->nostdlib) {
1763 int lpthread = s1->option_pthread;
1765 #ifdef CONFIG_TCC_BCHECK
1766 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1767 tcc_add_support(s1, "bcheck.o");
1768 # if !(TARGETOS_OpenBSD || TARGETOS_NetBSD)
1769 tcc_add_library_err(s1, "dl");
1770 # endif
1771 lpthread = 1;
1773 #endif
1774 #ifdef CONFIG_TCC_BACKTRACE
1775 if (s1->do_backtrace) {
1776 if (s1->output_type & TCC_OUTPUT_EXE)
1777 tcc_add_support(s1, "bt-exe.o");
1778 if (s1->output_type != TCC_OUTPUT_DLL)
1779 tcc_add_support(s1, "bt-log.o");
1780 if (s1->output_type != TCC_OUTPUT_MEMORY)
1781 tcc_add_btstub(s1);
1783 #endif
1784 if (lpthread)
1785 tcc_add_library_err(s1, "pthread");
1786 tcc_add_library_err(s1, "c");
1787 #ifdef TCC_LIBGCC
1788 if (!s1->static_link) {
1789 if (TCC_LIBGCC[0] == '/')
1790 tcc_add_file(s1, TCC_LIBGCC);
1791 else
1792 tcc_add_dll(s1, TCC_LIBGCC, AFF_PRINT_ERROR);
1794 #endif
1795 #if defined TCC_TARGET_ARM && TARGETOS_FreeBSD
1796 tcc_add_library_err(s1, "gcc_s"); // unwind code
1797 #endif
1798 if (TCC_LIBTCC1[0])
1799 tcc_add_support(s1, TCC_LIBTCC1);
1800 #ifndef TCC_TARGET_MACHO
1801 if (s1->output_type != TCC_OUTPUT_MEMORY)
1802 tccelf_add_crtend(s1);
1803 #endif
1806 #endif /* ndef TCC_TARGET_PE */
1808 /* add various standard linker symbols (must be done after the
1809 sections are filled (for example after allocating common
1810 symbols)) */
1811 static void tcc_add_linker_symbols(TCCState *s1)
1813 char buf[1024];
1814 int i;
1815 Section *s;
1817 set_global_sym(s1, "_etext", text_section, -1);
1818 set_global_sym(s1, "_edata", data_section, -1);
1819 set_global_sym(s1, "_end", bss_section, -1);
1820 #if TARGETOS_OpenBSD
1821 set_global_sym(s1, "__executable_start", NULL, ELF_START_ADDR);
1822 #endif
1823 #ifdef TCC_TARGET_RISCV64
1824 /* XXX should be .sdata+0x800, not .data+0x800 */
1825 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1826 #endif
1827 /* horrible new standard ldscript defines */
1828 add_init_array_defines(s1, ".preinit_array");
1829 add_init_array_defines(s1, ".init_array");
1830 add_init_array_defines(s1, ".fini_array");
1831 /* add start and stop symbols for sections whose name can be
1832 expressed in C */
1833 for(i = 1; i < s1->nb_sections; i++) {
1834 s = s1->sections[i];
1835 if ((s->sh_flags & SHF_ALLOC)
1836 && (s->sh_type == SHT_PROGBITS
1837 || s->sh_type == SHT_STRTAB)) {
1838 const char *p;
1839 /* check if section name can be expressed in C */
1840 p = s->name;
1841 for(;;) {
1842 int c = *p;
1843 if (!c)
1844 break;
1845 if (!isid(c) && !isnum(c))
1846 goto next_sec;
1847 p++;
1849 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1850 set_global_sym(s1, buf, s, 0);
1851 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1852 set_global_sym(s1, buf, s, -1);
1854 next_sec: ;
1858 ST_FUNC void resolve_common_syms(TCCState *s1)
1860 ElfW(Sym) *sym;
1862 /* Allocate common symbols in BSS. */
1863 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1864 if (sym->st_shndx == SHN_COMMON) {
1865 /* symbol alignment is in st_value for SHN_COMMONs */
1866 sym->st_value = section_add(bss_section, sym->st_size,
1867 sym->st_value);
1868 sym->st_shndx = bss_section->sh_num;
1872 /* Now assign linker provided symbols their value. */
1873 tcc_add_linker_symbols(s1);
1876 #ifndef ELF_OBJ_ONLY
1877 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1879 int sym_index = ELFW(R_SYM) (rel->r_info);
1880 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1881 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1882 unsigned offset = attr->got_offset;
1884 if (0 == offset)
1885 return;
1886 section_reserve(s1->got, offset + PTR_SIZE);
1887 #if PTR_SIZE == 8
1888 write64le(s1->got->data + offset, sym->st_value);
1889 #else
1890 write32le(s1->got->data + offset, sym->st_value);
1891 #endif
1894 /* Perform relocation to GOT or PLT entries */
1895 ST_FUNC void fill_got(TCCState *s1)
1897 Section *s;
1898 ElfW_Rel *rel;
1899 int i;
1901 for(i = 1; i < s1->nb_sections; i++) {
1902 s = s1->sections[i];
1903 if (s->sh_type != SHT_RELX)
1904 continue;
1905 /* no need to handle got relocations */
1906 if (s->link != symtab_section)
1907 continue;
1908 for_each_elem(s, 0, rel, ElfW_Rel) {
1909 switch (ELFW(R_TYPE) (rel->r_info)) {
1910 case R_X86_64_GOT32:
1911 case R_X86_64_GOTPCREL:
1912 case R_X86_64_GOTPCRELX:
1913 case R_X86_64_REX_GOTPCRELX:
1914 case R_X86_64_PLT32:
1915 fill_got_entry(s1, rel);
1916 break;
1922 /* See put_got_entry for a description. This is the second stage
1923 where GOT references to local defined symbols are rewritten. */
1924 static void fill_local_got_entries(TCCState *s1)
1926 ElfW_Rel *rel;
1927 if (!s1->got->reloc)
1928 return;
1929 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1930 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1931 int sym_index = ELFW(R_SYM) (rel->r_info);
1932 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1933 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1934 unsigned offset = attr->got_offset;
1935 if (offset != rel->r_offset - s1->got->sh_addr)
1936 tcc_error_noabort("fill_local_got_entries: huh?");
1937 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1938 #if SHT_RELX == SHT_RELA
1939 rel->r_addend = sym->st_value;
1940 #else
1941 /* All our REL architectures also happen to be 32bit LE. */
1942 write32le(s1->got->data + offset, sym->st_value);
1943 #endif
1948 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1949 in shared libraries */
1950 static void bind_exe_dynsyms(TCCState *s1, int is_PIE)
1952 const char *name;
1953 int sym_index, index;
1954 ElfW(Sym) *sym, *esym;
1955 int type;
1957 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1958 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1959 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1960 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1961 if (sym->st_shndx == SHN_UNDEF) {
1962 name = (char *) symtab_section->link->data + sym->st_name;
1963 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1964 if (sym_index) {
1965 if (is_PIE)
1966 continue;
1967 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1968 type = ELFW(ST_TYPE)(esym->st_info);
1969 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1970 /* Indirect functions shall have STT_FUNC type in executable
1971 * dynsym section. Indeed, a dlsym call following a lazy
1972 * resolution would pick the symbol value from the
1973 * executable dynsym entry which would contain the address
1974 * of the function wanted by the caller of dlsym instead of
1975 * the address of the function that would return that
1976 * address */
1977 int dynindex
1978 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1979 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1980 name);
1981 int index = sym - (ElfW(Sym) *) symtab_section->data;
1982 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1983 } else if (type == STT_OBJECT) {
1984 unsigned long offset;
1985 ElfW(Sym) *dynsym;
1986 offset = bss_section->data_offset;
1987 /* XXX: which alignment ? */
1988 offset = (offset + 16 - 1) & -16;
1989 set_elf_sym (s1->symtab, offset, esym->st_size,
1990 esym->st_info, 0, bss_section->sh_num, name);
1991 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1992 esym->st_info, 0, bss_section->sh_num,
1993 name);
1995 /* Ensure R_COPY works for weak symbol aliases */
1996 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1997 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1998 if ((dynsym->st_value == esym->st_value)
1999 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
2000 char *dynname = (char *) s1->dynsymtab_section->link->data
2001 + dynsym->st_name;
2002 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
2003 dynsym->st_info, 0,
2004 bss_section->sh_num, dynname);
2005 break;
2010 put_elf_reloc(s1->dynsym, bss_section,
2011 offset, R_COPY, index);
2012 offset += esym->st_size;
2013 bss_section->data_offset = offset;
2015 } else {
2016 /* STB_WEAK undefined symbols are accepted */
2017 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
2018 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
2019 !strcmp(name, "_fp_hw")) {
2020 } else {
2021 tcc_error_noabort("undefined symbol '%s'", name);
2028 /* Bind symbols of libraries: export all non local symbols of executable that
2029 are referenced by shared libraries. The reason is that the dynamic loader
2030 search symbol first in executable and then in libraries. Therefore a
2031 reference to a symbol already defined by a library can still be resolved by
2032 a symbol in the executable. With -rdynamic, export all defined symbols */
2033 static void bind_libs_dynsyms(TCCState *s1)
2035 const char *name;
2036 int dynsym_index;
2037 ElfW(Sym) *sym, *esym;
2039 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
2040 name = (char *)symtab_section->link->data + sym->st_name;
2041 dynsym_index = find_elf_sym(s1->dynsymtab_section, name);
2042 if (sym->st_shndx != SHN_UNDEF) {
2043 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL
2044 && (dynsym_index || s1->rdynamic))
2045 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
2046 sym->st_info, 0, sym->st_shndx, name);
2047 } else if (dynsym_index) {
2048 esym = (ElfW(Sym) *)s1->dynsymtab_section->data + dynsym_index;
2049 if (esym->st_shndx == SHN_UNDEF) {
2050 /* weak symbols can stay undefined */
2051 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
2052 tcc_warning("undefined dynamic symbol '%s'", name);
2058 /* Export all non local symbols. This is used by shared libraries so that the
2059 non local symbols they define can resolve a reference in another shared
2060 library or in the executable. Correspondingly, it allows undefined local
2061 symbols to be resolved by other shared libraries or by the executable. */
2062 static void export_global_syms(TCCState *s1)
2064 int dynindex, index;
2065 const char *name;
2066 ElfW(Sym) *sym;
2067 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
2068 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2069 name = (char *) symtab_section->link->data + sym->st_name;
2070 dynindex = set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
2071 sym->st_info, 0, sym->st_shndx, name);
2072 index = sym - (ElfW(Sym) *) symtab_section->data;
2073 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
2078 /* decide if an unallocated section should be output. */
2079 static int set_sec_sizes(TCCState *s1)
2081 int i;
2082 Section *s;
2083 int textrel = 0;
2084 int file_type = s1->output_type;
2086 /* Allocate strings for section names */
2087 for(i = 1; i < s1->nb_sections; i++) {
2088 s = s1->sections[i];
2089 if (s->sh_type == SHT_RELX && !(s->sh_flags & SHF_ALLOC)) {
2090 /* when generating a DLL, we include relocations but
2091 we may patch them */
2092 if ((file_type & TCC_OUTPUT_DYN)
2093 && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) {
2094 int count = prepare_dynamic_rel(s1, s);
2095 if (count) {
2096 /* allocate the section */
2097 s->sh_flags |= SHF_ALLOC;
2098 s->sh_size = count * sizeof(ElfW_Rel);
2099 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
2100 textrel += count;
2103 } else if ((s->sh_flags & SHF_ALLOC)
2104 #ifdef TCC_TARGET_ARM
2105 || s->sh_type == SHT_ARM_ATTRIBUTES
2106 #endif
2107 || s1->do_debug) {
2108 s->sh_size = s->data_offset;
2111 #ifdef TCC_TARGET_ARM
2112 /* XXX: Suppress stack unwinding section. */
2113 if (s->sh_type == SHT_ARM_EXIDX) {
2114 s->sh_flags = 0;
2115 s->sh_size = 0;
2117 #endif
2120 return textrel;
2123 /* various data used under elf_output_file() */
2124 struct dyn_inf {
2125 Section *dynamic;
2126 Section *dynstr;
2127 struct {
2128 /* Info to be copied in dynamic section */
2129 unsigned long data_offset;
2130 addr_t rel_addr;
2131 addr_t rel_size;
2134 ElfW(Phdr) *phdr;
2135 int phnum;
2136 Section *interp;
2137 Section *note;
2138 Section *gnu_hash;
2140 /* read only segment mapping for GNU_RELRO */
2141 Section _roinf, *roinf;
2144 /* Decide the layout of sections loaded in memory. This must be done before
2145 program headers are filled since they contain info about the layout.
2146 We do the following ordering: interp, symbol tables, relocations, progbits,
2147 nobits */
2148 static int sort_sections(TCCState *s1, int *sec_order, Section *interp)
2150 Section *s;
2151 int i, j, k, f, f0, n;
2152 int nb_sections = s1->nb_sections;
2153 int *sec_cls = sec_order + nb_sections;
2155 for (i = 1; i < nb_sections; i++) {
2156 s = s1->sections[i];
2157 if (s->sh_flags & SHF_ALLOC) {
2158 j = 0x100;
2159 if (s->sh_flags & SHF_WRITE)
2160 j = 0x200;
2161 if (s->sh_flags & SHF_TLS)
2162 j += 0x200;
2163 } else if (s->sh_name) {
2164 j = 0x700;
2165 } else {
2166 j = 0x900; /* no sh_name: won't go to file */
2168 if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_DYNSYM) {
2169 k = 0x10;
2170 } else if (s->sh_type == SHT_STRTAB && strcmp(s->name, ".stabstr")) {
2171 k = 0x11;
2172 if (i == nb_sections - 1) /* ".shstrtab" assumed to remain last */
2173 k = 0xff;
2174 } else if (s->sh_type == SHT_HASH || s->sh_type == SHT_GNU_HASH) {
2175 k = 0x12;
2176 } else if (s->sh_type == SHT_RELX) {
2177 k = 0x20;
2178 if (s1->plt && s == s1->plt->reloc)
2179 k = 0x21;
2180 } else if (s->sh_type == SHT_PREINIT_ARRAY) {
2181 k = 0x41;
2182 } else if (s->sh_type == SHT_INIT_ARRAY) {
2183 k = 0x42;
2184 } else if (s->sh_type == SHT_FINI_ARRAY) {
2185 k = 0x43;
2186 #ifdef CONFIG_TCC_BCHECK
2187 } else if (s == bounds_section || s == lbounds_section) {
2188 k = 0x44;
2189 #endif
2190 } else if (s == rodata_section || 0 == strcmp(s->name, ".data.rel.ro")) {
2191 k = 0x45;
2192 } else if (s->sh_type == SHT_DYNAMIC) {
2193 k = 0x46;
2194 } else if (s == s1->got) {
2195 k = 0x47; /* .got as RELRO needs BIND_NOW in DT_FLAGS */
2196 } else {
2197 k = 0x50;
2198 if (s->sh_type == SHT_NOTE)
2199 k = 0x60;
2200 if (s->sh_flags & SHF_EXECINSTR)
2201 k = 0x70;
2202 if (s->sh_type == SHT_NOBITS)
2203 k = 0x80;
2204 if (s == interp)
2205 k = 0x00;
2207 k += j;
2209 for (n = i; n > 1 && k < (f = sec_cls[n - 1]); --n)
2210 sec_cls[n] = f, sec_order[n] = sec_order[n - 1];
2211 sec_cls[n] = k, sec_order[n] = i;
2213 sec_order[0] = 0;
2215 /* count PT_LOAD headers needed */
2216 n = f0 = 0;
2217 for (i = 1; i < nb_sections; i++) {
2218 s = s1->sections[sec_order[i]];
2219 k = sec_cls[i];
2220 f = 0;
2221 if (k < 0x700) {
2222 f = s->sh_flags & (SHF_ALLOC|SHF_WRITE|SHF_EXECINSTR|SHF_TLS);
2223 #if TARGETOS_NetBSD
2224 /* NetBSD only supports 2 PT_LOAD sections.
2225 See: https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */
2226 if ((f & SHF_WRITE) == 0) f |= SHF_EXECINSTR;
2227 #else
2228 if ((k & 0xfff0) == 0x240) /* RELRO sections */
2229 f |= 1<<4;
2230 #endif
2231 if (f != f0) /* start new header when flags changed or relro */
2232 f0 = f, ++n, f |= 1<<8;
2234 sec_cls[i] = f;
2235 //printf("ph %d sec %02d : %3X %3X %8.2X %04X %s\n", !!f * n, i, f, k, s->sh_type, s->sh_size, s->name);
2237 return n;
2240 static ElfW(Phdr) *fill_phdr(ElfW(Phdr) *ph, int type, Section *s)
2242 if (s) {
2243 ph->p_offset = s->sh_offset;
2244 ph->p_vaddr = s->sh_addr;
2245 ph->p_filesz = s->sh_size;
2246 ph->p_align = s->sh_addralign;
2248 ph->p_type = type;
2249 ph->p_flags = PF_R;
2250 ph->p_paddr = ph->p_vaddr;
2251 ph->p_memsz = ph->p_filesz;
2252 return ph;
2255 /* Assign sections to segments and decide how are sections laid out when loaded
2256 in memory. This function also fills corresponding program headers. */
2257 static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
2259 Section *s;
2260 addr_t addr, tmp, align, s_align, base;
2261 ElfW(Phdr) *ph = NULL;
2262 int i, f, n, phnum, phfill;
2263 int file_offset;
2265 /* compute number of program headers */
2266 phnum = sort_sections(s1, sec_order, d->interp);
2267 phfill = 0; /* set to 1 to have dll's with a PT_PHDR */
2268 if (d->interp)
2269 phfill = 2;
2270 phnum += phfill;
2271 if (d->note)
2272 ++phnum;
2273 if (d->dynamic)
2274 ++phnum;
2275 if (d->roinf)
2276 ++phnum;
2277 d->phnum = phnum;
2278 d->phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2280 file_offset = 0;
2281 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2282 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2284 s_align = ELF_PAGE_SIZE;
2285 if (s1->section_align)
2286 s_align = s1->section_align;
2288 addr = ELF_START_ADDR;
2289 if (s1->output_type & TCC_OUTPUT_DYN)
2290 addr = 0;
2292 if (s1->has_text_addr) {
2293 addr = s1->text_addr;
2294 if (0) {
2295 int a_offset, p_offset;
2296 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
2297 ELF_PAGE_SIZE */
2298 a_offset = (int) (addr & (s_align - 1));
2299 p_offset = file_offset & (s_align - 1);
2300 if (a_offset < p_offset)
2301 a_offset += s_align;
2302 file_offset += (a_offset - p_offset);
2305 base = addr;
2306 /* compute address after headers */
2307 addr = addr + (file_offset & (s_align - 1));
2309 n = 0;
2310 for(i = 1; i < s1->nb_sections; i++) {
2311 s = s1->sections[sec_order[i]];
2312 f = sec_order[i + s1->nb_sections];
2313 align = s->sh_addralign - 1;
2315 if (f == 0) { /* no alloc */
2316 file_offset = (file_offset + align) & ~align;
2317 s->sh_offset = file_offset;
2318 if (s->sh_type != SHT_NOBITS)
2319 file_offset += s->sh_size;
2320 continue;
2323 if ((f & 1<<8) && n) {
2324 /* different rwx section flags */
2325 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
2326 /* if in the middle of a page, w e duplicate the page in
2327 memory so that one copy is RX and the other is RW */
2328 if ((addr & (s_align - 1)) != 0)
2329 addr += s_align;
2330 } else {
2331 align = s_align - 1;
2335 tmp = addr;
2336 addr = (addr + align) & ~align;
2337 file_offset += (int)(addr - tmp);
2338 s->sh_offset = file_offset;
2339 s->sh_addr = addr;
2341 if (f & 1<<8) {
2342 /* set new program header */
2343 ph = &d->phdr[phfill + n];
2344 ph->p_type = PT_LOAD;
2345 ph->p_align = s_align;
2346 ph->p_flags = PF_R;
2347 if (f & SHF_WRITE)
2348 ph->p_flags |= PF_W;
2349 if (f & SHF_EXECINSTR)
2350 ph->p_flags |= PF_X;
2351 if (f & SHF_TLS) {
2352 ph->p_type = PT_TLS;
2353 ph->p_align = align + 1;
2356 ph->p_offset = file_offset;
2357 ph->p_vaddr = addr;
2358 if (n == 0) {
2359 /* Make the first PT_LOAD segment include the program
2360 headers itself (and the ELF header as well), it'll
2361 come out with same memory use but will make various
2362 tools like binutils strip work better. */
2363 ph->p_offset = 0;
2364 ph->p_vaddr = base;
2366 ph->p_paddr = ph->p_vaddr;
2367 ++n;
2370 if (f & 1<<4) {
2371 Section *roinf = &d->_roinf;
2372 if (roinf->sh_size == 0) {
2373 roinf->sh_offset = s->sh_offset;
2374 roinf->sh_addr = s->sh_addr;
2375 roinf->sh_addralign = 1;
2377 roinf->sh_size = (addr - roinf->sh_addr) + s->sh_size;
2380 addr += s->sh_size;
2381 if (s->sh_type != SHT_NOBITS)
2382 file_offset += s->sh_size;
2384 ph->p_filesz = file_offset - ph->p_offset;
2385 ph->p_memsz = addr - ph->p_vaddr;
2388 /* Fill other headers */
2389 if (d->note)
2390 fill_phdr(++ph, PT_NOTE, d->note);
2391 if (d->dynamic)
2392 fill_phdr(++ph, PT_DYNAMIC, d->dynamic)->p_flags |= PF_W;
2393 if (d->roinf)
2394 fill_phdr(++ph, PT_GNU_RELRO, d->roinf)->p_flags |= PF_W;
2395 if (d->interp)
2396 fill_phdr(&d->phdr[1], PT_INTERP, d->interp);
2397 if (phfill) {
2398 ph = &d->phdr[0];
2399 ph->p_offset = sizeof(ElfW(Ehdr));
2400 ph->p_vaddr = base + ph->p_offset;
2401 ph->p_filesz = phnum * sizeof(ElfW(Phdr));
2402 ph->p_align = 4;
2403 fill_phdr(ph, PT_PHDR, NULL);
2405 return file_offset;
2408 /* put dynamic tag */
2409 static void put_dt(Section *dynamic, int dt, addr_t val)
2411 ElfW(Dyn) *dyn;
2412 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
2413 dyn->d_tag = dt;
2414 dyn->d_un.d_val = val;
2417 /* Fill the dynamic section with tags describing the address and size of
2418 sections */
2419 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2421 Section *dynamic = dyninf->dynamic;
2422 Section *s;
2424 /* put dynamic section entries */
2425 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2426 put_dt(dynamic, DT_GNU_HASH, dyninf->gnu_hash->sh_addr);
2427 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2428 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2429 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2430 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2431 #if PTR_SIZE == 8
2432 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2433 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2434 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2435 if (s1->plt && s1->plt->reloc) {
2436 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2437 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2438 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2439 put_dt(dynamic, DT_PLTREL, DT_RELA);
2441 put_dt(dynamic, DT_RELACOUNT, 0);
2442 #else
2443 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2444 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2445 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2446 if (s1->plt && s1->plt->reloc) {
2447 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2448 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2449 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2450 put_dt(dynamic, DT_PLTREL, DT_REL);
2452 put_dt(dynamic, DT_RELCOUNT, 0);
2453 #endif
2454 if (versym_section && verneed_section) {
2455 /* The dynamic linker can not handle VERSYM without VERNEED */
2456 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2457 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2458 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2460 s = have_section(s1, ".preinit_array");
2461 if (s && s->data_offset) {
2462 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2463 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2465 s = have_section(s1, ".init_array");
2466 if (s && s->data_offset) {
2467 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2468 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2470 s = have_section(s1, ".fini_array");
2471 if (s && s->data_offset) {
2472 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2473 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2475 s = have_section(s1, ".init");
2476 if (s && s->data_offset) {
2477 put_dt(dynamic, DT_INIT, s->sh_addr);
2479 s = have_section(s1, ".fini");
2480 if (s && s->data_offset) {
2481 put_dt(dynamic, DT_FINI, s->sh_addr);
2483 if (s1->do_debug)
2484 put_dt(dynamic, DT_DEBUG, 0);
2485 put_dt(dynamic, DT_NULL, 0);
2488 /* Remove gaps between RELX sections.
2489 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2490 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2491 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2492 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2493 static void update_reloc_sections(TCCState *s1, struct dyn_inf *dyninf)
2495 int i;
2496 unsigned long file_offset = 0;
2497 Section *s;
2498 Section *relocplt = s1->plt ? s1->plt->reloc : NULL;
2500 /* dynamic relocation table information, for .dynamic section */
2501 dyninf->rel_addr = dyninf->rel_size = 0;
2503 for(i = 1; i < s1->nb_sections; i++) {
2504 s = s1->sections[i];
2505 if (s->sh_type == SHT_RELX && s != relocplt) {
2506 if (dyninf->rel_size == 0) {
2507 dyninf->rel_addr = s->sh_addr;
2508 file_offset = s->sh_offset;
2510 else {
2511 s->sh_addr = dyninf->rel_addr + dyninf->rel_size;
2512 s->sh_offset = file_offset + dyninf->rel_size;
2514 dyninf->rel_size += s->sh_size;
2519 static int tidy_section_headers(TCCState *s1, int *sec_order);
2520 #endif /* ndef ELF_OBJ_ONLY */
2522 /* Create an ELF file on disk.
2523 This function handle ELF specific layout requirements */
2524 static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2525 int file_offset, int *sec_order)
2527 int i, shnum, offset, size, file_type;
2528 Section *s;
2529 ElfW(Ehdr) ehdr;
2530 ElfW(Shdr) shdr, *sh;
2532 file_type = s1->output_type;
2533 shnum = s1->nb_sections;
2535 memset(&ehdr, 0, sizeof(ehdr));
2537 if (phnum > 0) {
2538 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2539 ehdr.e_phnum = phnum;
2540 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2541 #ifndef ELF_OBJ_ONLY
2542 shnum = tidy_section_headers(s1, sec_order);
2543 #endif
2546 /* align to 4 */
2547 file_offset = (file_offset + 3) & -4;
2549 /* fill header */
2550 ehdr.e_ident[0] = ELFMAG0;
2551 ehdr.e_ident[1] = ELFMAG1;
2552 ehdr.e_ident[2] = ELFMAG2;
2553 ehdr.e_ident[3] = ELFMAG3;
2554 ehdr.e_ident[4] = ELFCLASSW;
2555 ehdr.e_ident[5] = ELFDATA2LSB;
2556 ehdr.e_ident[6] = EV_CURRENT;
2558 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2559 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2560 #elif defined TCC_TARGET_ARM && defined TCC_ARM_EABI
2561 ehdr.e_flags = EF_ARM_EABI_VER5;
2562 ehdr.e_flags |= s1->float_abi == ARM_HARD_FLOAT
2563 ? EF_ARM_VFP_FLOAT : EF_ARM_SOFT_FLOAT;
2564 #elif defined TCC_TARGET_ARM
2565 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2566 #elif defined TCC_TARGET_RISCV64
2567 /* XXX should be configurable */
2568 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2569 #endif
2571 if (file_type == TCC_OUTPUT_OBJ) {
2572 ehdr.e_type = ET_REL;
2573 } else {
2574 if (file_type & TCC_OUTPUT_DYN)
2575 ehdr.e_type = ET_DYN;
2576 else
2577 ehdr.e_type = ET_EXEC;
2578 if (s1->elf_entryname)
2579 ehdr.e_entry = get_sym_addr(s1, s1->elf_entryname, 1, 0);
2580 else
2581 ehdr.e_entry = get_sym_addr(s1, "_start", !!(file_type & TCC_OUTPUT_EXE), 0);
2582 if (ehdr.e_entry == (addr_t)-1)
2583 ehdr.e_entry = text_section->sh_addr;
2584 if (s1->nb_errors)
2585 return -1;
2588 ehdr.e_machine = EM_TCC_TARGET;
2589 ehdr.e_version = EV_CURRENT;
2590 ehdr.e_shoff = file_offset;
2591 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2592 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2593 ehdr.e_shnum = shnum;
2594 ehdr.e_shstrndx = shnum - 1;
2596 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2597 if (phdr)
2598 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2599 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2601 sort_syms(s1, symtab_section);
2603 for(i = 1; i < shnum; i++) {
2604 s = s1->sections[sec_order ? sec_order[i] : i];
2605 if (s->sh_type != SHT_NOBITS) {
2606 while (offset < s->sh_offset) {
2607 fputc(0, f);
2608 offset++;
2610 size = s->sh_size;
2611 if (size)
2612 fwrite(s->data, 1, size, f);
2613 offset += size;
2617 /* output section headers */
2618 while (offset < ehdr.e_shoff) {
2619 fputc(0, f);
2620 offset++;
2623 for(i = 0; i < shnum; i++) {
2624 sh = &shdr;
2625 memset(sh, 0, sizeof(ElfW(Shdr)));
2626 s = s1->sections[i];
2627 if (s) {
2628 sh->sh_name = s->sh_name;
2629 sh->sh_type = s->sh_type;
2630 sh->sh_flags = s->sh_flags;
2631 sh->sh_entsize = s->sh_entsize;
2632 sh->sh_info = s->sh_info;
2633 if (s->link)
2634 sh->sh_link = s->link->sh_num;
2635 sh->sh_addralign = s->sh_addralign;
2636 sh->sh_addr = s->sh_addr;
2637 sh->sh_offset = s->sh_offset;
2638 sh->sh_size = s->sh_size;
2640 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2642 return 0;
2645 static int tcc_output_binary(TCCState *s1, FILE *f,
2646 const int *sec_order)
2648 Section *s;
2649 int i, offset, size;
2651 offset = 0;
2652 for(i=1;i<s1->nb_sections;i++) {
2653 s = s1->sections[sec_order[i]];
2654 if (s->sh_type != SHT_NOBITS &&
2655 (s->sh_flags & SHF_ALLOC)) {
2656 while (offset < s->sh_offset) {
2657 fputc(0, f);
2658 offset++;
2660 size = s->sh_size;
2661 fwrite(s->data, 1, size, f);
2662 offset += size;
2665 return 0;
2668 /* Write an elf, coff or "binary" file */
2669 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2670 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2672 int fd, mode, file_type, ret;
2673 FILE *f;
2675 file_type = s1->output_type;
2676 if (file_type == TCC_OUTPUT_OBJ)
2677 mode = 0666;
2678 else
2679 mode = 0777;
2680 unlink(filename);
2681 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2682 if (fd < 0 || (f = fdopen(fd, "wb")) == NULL)
2683 return tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno));
2684 if (s1->verbose)
2685 printf("<- %s\n", filename);
2686 #ifdef TCC_TARGET_COFF
2687 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2688 tcc_output_coff(s1, f);
2689 else
2690 #endif
2691 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2692 ret = tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2693 else
2694 ret = tcc_output_binary(s1, f, sec_order);
2695 fclose(f);
2697 return ret;
2700 #ifndef ELF_OBJ_ONLY
2701 /* Sort section headers by assigned sh_addr, remove sections
2702 that we aren't going to output. */
2703 static int tidy_section_headers(TCCState *s1, int *sec_order)
2705 int i, nnew, l, *backmap;
2706 Section **snew, *s;
2707 ElfW(Sym) *sym;
2709 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2710 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2711 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2712 s = s1->sections[sec_order[i]];
2713 if (!i || s->sh_name) {
2714 backmap[sec_order[i]] = nnew;
2715 snew[nnew] = s;
2716 ++nnew;
2717 } else {
2718 backmap[sec_order[i]] = 0;
2719 snew[--l] = s;
2722 for (i = 0; i < nnew; i++) {
2723 s = snew[i];
2724 if (s) {
2725 s->sh_num = i;
2726 if (s->sh_type == SHT_RELX)
2727 s->sh_info = backmap[s->sh_info];
2731 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2732 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2733 sym->st_shndx = backmap[sym->st_shndx];
2734 if ( !s1->static_link ) {
2735 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2736 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2737 sym->st_shndx = backmap[sym->st_shndx];
2739 for (i = 0; i < s1->nb_sections; i++)
2740 sec_order[i] = i;
2741 tcc_free(s1->sections);
2742 s1->sections = snew;
2743 tcc_free(backmap);
2744 return nnew;
2747 #ifdef TCC_TARGET_ARM
2748 static void create_arm_attribute_section(TCCState *s1)
2750 // Needed for DLL support.
2751 static const unsigned char arm_attr[] = {
2752 0x41, // 'A'
2753 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2754 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2755 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2756 0x05, 0x36, 0x00, // 'CPU_name', "6"
2757 0x06, 0x06, // 'CPU_arch', 'v6'
2758 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2759 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2760 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2761 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2762 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2763 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2764 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2765 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2766 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2767 0x1a, 0x02, // 'ABI_enum_size', 'int'
2768 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2769 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2771 Section *attr = new_section(s1, ".ARM.attributes", SHT_ARM_ATTRIBUTES, 0);
2772 unsigned char *ptr = section_ptr_add(attr, sizeof(arm_attr));
2773 attr->sh_addralign = 1;
2774 memcpy(ptr, arm_attr, sizeof(arm_attr));
2775 if (s1->float_abi != ARM_HARD_FLOAT) {
2776 ptr[26] = 0x00; // 'FP_arch', 'No'
2777 ptr[41] = 0x1e; // 'ABI_optimization_goals'
2778 ptr[42] = 0x06; // 'Aggressive Debug'
2781 #endif
2783 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2784 static Section *create_bsd_note_section(TCCState *s1,
2785 const char *name,
2786 const char *value)
2788 Section *s = find_section (s1, name);
2790 if (s->data_offset == 0) {
2791 char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
2792 ElfW(Nhdr) *note = (ElfW(Nhdr) *) ptr;
2794 s->sh_type = SHT_NOTE;
2795 note->n_namesz = 8;
2796 note->n_descsz = 4;
2797 note->n_type = ELF_NOTE_OS_GNU;
2798 strcpy (ptr + sizeof(ElfW(Nhdr)), value);
2800 return s;
2802 #endif
2804 static void alloc_sec_names(TCCState *s1, int is_obj);
2806 /* Output an elf, coff or binary file */
2807 /* XXX: suppress unneeded sections */
2808 static int elf_output_file(TCCState *s1, const char *filename)
2810 int i, ret, file_type, file_offset, *sec_order;
2811 struct dyn_inf dyninf = {0};
2812 Section *interp, *dynstr, *dynamic;
2813 int textrel, got_sym, dt_flags_1;
2815 file_type = s1->output_type;
2816 s1->nb_errors = 0;
2817 ret = -1;
2818 interp = dynstr = dynamic = NULL;
2819 sec_order = NULL;
2820 dyninf.roinf = &dyninf._roinf;
2822 #ifdef TCC_TARGET_ARM
2823 create_arm_attribute_section (s1);
2824 #endif
2826 #if TARGETOS_OpenBSD
2827 dyninf.note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
2828 #endif
2830 #if TARGETOS_NetBSD
2831 dyninf.note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD");
2832 #endif
2834 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
2835 dyninf.roinf = NULL;
2836 #endif
2837 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2838 tcc_add_runtime(s1);
2839 resolve_common_syms(s1);
2841 if (!s1->static_link) {
2842 if (file_type & TCC_OUTPUT_EXE) {
2843 char *ptr;
2844 /* allow override the dynamic loader */
2845 const char *elfint = getenv("LD_SO");
2846 if (elfint == NULL)
2847 elfint = DEFAULT_ELFINTERP(s1);
2848 /* add interpreter section only if executable */
2849 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2850 interp->sh_addralign = 1;
2851 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2852 strcpy(ptr, elfint);
2853 dyninf.interp = interp;
2856 /* add dynamic symbol table */
2857 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2858 ".dynstr",
2859 ".hash", SHF_ALLOC);
2860 /* Number of local symbols (readelf complains if not set) */
2861 s1->dynsym->sh_info = 1;
2862 dynstr = s1->dynsym->link;
2863 /* add dynamic section */
2864 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2865 SHF_ALLOC | SHF_WRITE);
2866 dynamic->link = dynstr;
2867 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2869 got_sym = build_got(s1);
2870 if (file_type & TCC_OUTPUT_EXE) {
2871 bind_exe_dynsyms(s1, file_type & TCC_OUTPUT_DYN);
2872 if (s1->nb_errors)
2873 goto the_end;
2875 build_got_entries(s1, got_sym);
2876 if (file_type & TCC_OUTPUT_EXE) {
2877 bind_libs_dynsyms(s1);
2878 } else {
2879 /* shared library case: simply export all global symbols */
2880 export_global_syms(s1);
2882 dyninf.gnu_hash = create_gnu_hash(s1);
2883 } else {
2884 build_got_entries(s1, 0);
2886 version_add (s1);
2888 textrel = set_sec_sizes(s1);
2889 alloc_sec_names(s1, 0);
2891 if (!s1->static_link) {
2892 /* add a list of needed dlls */
2893 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2894 DLLReference *dllref = s1->loaded_dlls[i];
2895 if (dllref->level == 0)
2896 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2899 if (s1->rpath)
2900 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2901 put_elf_str(dynstr, s1->rpath));
2903 dt_flags_1 = DF_1_NOW;
2904 if (file_type & TCC_OUTPUT_DYN) {
2905 if (s1->soname)
2906 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2907 /* XXX: currently, since we do not handle PIC code, we
2908 must relocate the readonly segments */
2909 if (textrel)
2910 put_dt(dynamic, DT_TEXTREL, 0);
2911 if (file_type & TCC_OUTPUT_EXE)
2912 dt_flags_1 = DF_1_NOW | DF_1_PIE;
2914 put_dt(dynamic, DT_FLAGS, DF_BIND_NOW);
2915 put_dt(dynamic, DT_FLAGS_1, dt_flags_1);
2916 if (s1->symbolic)
2917 put_dt(dynamic, DT_SYMBOLIC, 0);
2919 dyninf.dynamic = dynamic;
2920 dyninf.dynstr = dynstr;
2921 /* remember offset and reserve space for 2nd call below */
2922 dyninf.data_offset = dynamic->data_offset;
2923 fill_dynamic(s1, &dyninf);
2924 dynamic->sh_size = dynamic->data_offset;
2925 dynstr->sh_size = dynstr->data_offset;
2928 /* this array is used to reorder sections in the output file */
2929 sec_order = tcc_malloc(sizeof(int) * 2 * s1->nb_sections);
2930 /* compute section to program header mapping */
2931 file_offset = layout_sections(s1, sec_order, &dyninf);
2933 if (dynamic) {
2934 /* put in GOT the dynamic section address and relocate PLT */
2935 write32le(s1->got->data, dynamic->sh_addr);
2936 if (file_type == TCC_OUTPUT_EXE
2937 || (RELOCATE_DLLPLT && (file_type & TCC_OUTPUT_DYN)))
2938 relocate_plt(s1);
2939 /* relocate symbols in .dynsym now that final addresses are known */
2940 relocate_syms(s1, s1->dynsym, 2);
2943 /* if building executable or DLL, then relocate each section
2944 except the GOT which is already relocated */
2945 relocate_syms(s1, s1->symtab, 0);
2946 if (s1->nb_errors != 0)
2947 goto the_end;
2948 relocate_sections(s1);
2949 if (dynamic) {
2950 update_reloc_sections (s1, &dyninf);
2951 dynamic->data_offset = dyninf.data_offset;
2952 fill_dynamic(s1, &dyninf);
2954 /* Perform relocation to GOT or PLT entries */
2955 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2956 fill_got(s1);
2957 else if (s1->got)
2958 fill_local_got_entries(s1);
2960 if (dyninf.gnu_hash)
2961 update_gnu_hash(s1, dyninf.gnu_hash);
2963 /* Create the ELF file with name 'filename' */
2964 ret = tcc_write_elf_file(s1, filename, dyninf.phnum, dyninf.phdr, file_offset, sec_order);
2965 the_end:
2966 tcc_free(sec_order);
2967 tcc_free(dyninf.phdr);
2968 return ret;
2970 #endif /* ndef ELF_OBJ_ONLY */
2972 /* Allocate strings for section names */
2973 static void alloc_sec_names(TCCState *s1, int is_obj)
2975 int i;
2976 Section *s, *strsec;
2978 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2979 put_elf_str(strsec, "");
2980 for(i = 1; i < s1->nb_sections; i++) {
2981 s = s1->sections[i];
2982 if (is_obj)
2983 s->sh_size = s->data_offset;
2984 if (s == strsec || s->sh_size || (s->sh_flags & SHF_ALLOC))
2985 s->sh_name = put_elf_str(strsec, s->name);
2987 strsec->sh_size = strsec->data_offset;
2990 /* Output an elf .o file */
2991 static int elf_output_obj(TCCState *s1, const char *filename)
2993 Section *s;
2994 int i, ret, file_offset;
2995 s1->nb_errors = 0;
2996 /* Allocate strings for section names */
2997 alloc_sec_names(s1, 1);
2998 file_offset = sizeof (ElfW(Ehdr));
2999 for(i = 1; i < s1->nb_sections; i++) {
3000 s = s1->sections[i];
3001 file_offset = (file_offset + 15) & -16;
3002 s->sh_offset = file_offset;
3003 if (s->sh_type != SHT_NOBITS)
3004 file_offset += s->sh_size;
3006 /* Create the ELF file with name 'filename' */
3007 ret = tcc_write_elf_file(s1, filename, 0, NULL, file_offset, NULL);
3008 return ret;
3011 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
3013 if (s->test_coverage)
3014 tcc_tcov_add_file(s, filename);
3015 if (s->output_type == TCC_OUTPUT_OBJ)
3016 return elf_output_obj(s, filename);
3017 #ifdef TCC_TARGET_PE
3018 return pe_output_file(s, filename);
3019 #elif TCC_TARGET_MACHO
3020 return macho_output_file(s, filename);
3021 #else
3022 return elf_output_file(s, filename);
3023 #endif
3026 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
3027 char *cbuf = buf;
3028 size_t rnum = 0;
3029 while (1) {
3030 ssize_t num = read(fd, cbuf, count-rnum);
3031 if (num < 0) return num;
3032 if (num == 0) return rnum;
3033 rnum += num;
3034 cbuf += num;
3038 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
3040 void *data;
3042 data = tcc_malloc(size);
3043 lseek(fd, file_offset, SEEK_SET);
3044 full_read(fd, data, size);
3045 return data;
3048 typedef struct SectionMergeInfo {
3049 Section *s; /* corresponding existing section */
3050 unsigned long offset; /* offset of the new section in the existing section */
3051 uint8_t new_section; /* true if section 's' was added */
3052 uint8_t link_once; /* true if link once section */
3053 } SectionMergeInfo;
3055 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
3057 int size = full_read(fd, h, sizeof *h);
3058 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
3059 if (h->e_type == ET_REL)
3060 return AFF_BINTYPE_REL;
3061 if (h->e_type == ET_DYN)
3062 return AFF_BINTYPE_DYN;
3063 } else if (size >= 8) {
3064 if (0 == memcmp(h, ARMAG, 8))
3065 return AFF_BINTYPE_AR;
3066 #ifdef TCC_TARGET_COFF
3067 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
3068 return AFF_BINTYPE_C67;
3069 #endif
3071 return 0;
3074 /* load an object file and merge it with current files */
3075 /* XXX: handle correctly stab (debug) info */
3076 ST_FUNC int tcc_load_object_file(TCCState *s1,
3077 int fd, unsigned long file_offset)
3079 ElfW(Ehdr) ehdr;
3080 ElfW(Shdr) *shdr, *sh;
3081 unsigned long size, offset, offseti;
3082 int i, j, nb_syms, sym_index, ret, seencompressed;
3083 char *strsec, *strtab;
3084 int stab_index, stabstr_index;
3085 int *old_to_new_syms;
3086 char *sh_name, *name;
3087 SectionMergeInfo *sm_table, *sm;
3088 ElfW(Sym) *sym, *symtab;
3089 ElfW_Rel *rel;
3090 Section *s;
3092 lseek(fd, file_offset, SEEK_SET);
3093 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
3094 goto invalid;
3095 /* test CPU specific stuff */
3096 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3097 ehdr.e_machine != EM_TCC_TARGET) {
3098 invalid:
3099 return tcc_error_noabort("invalid object file");
3101 /* read sections */
3102 shdr = load_data(fd, file_offset + ehdr.e_shoff,
3103 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3104 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
3106 /* load section names */
3107 sh = &shdr[ehdr.e_shstrndx];
3108 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3110 /* load symtab and strtab */
3111 old_to_new_syms = NULL;
3112 symtab = NULL;
3113 strtab = NULL;
3114 nb_syms = 0;
3115 seencompressed = 0;
3116 stab_index = stabstr_index = 0;
3117 ret = -1;
3119 for(i = 1; i < ehdr.e_shnum; i++) {
3120 sh = &shdr[i];
3121 if (sh->sh_type == SHT_SYMTAB) {
3122 if (symtab) {
3123 tcc_error_noabort("object must contain only one symtab");
3124 goto the_end;
3126 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3127 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3128 sm_table[i].s = symtab_section;
3130 /* now load strtab */
3131 sh = &shdr[sh->sh_link];
3132 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3134 if (sh->sh_flags & SHF_COMPRESSED)
3135 seencompressed = 1;
3138 /* now examine each section and try to merge its content with the
3139 ones in memory */
3140 for(i = 1; i < ehdr.e_shnum; i++) {
3141 /* no need to examine section name strtab */
3142 if (i == ehdr.e_shstrndx)
3143 continue;
3144 sh = &shdr[i];
3145 if (sh->sh_type == SHT_RELX)
3146 sh = &shdr[sh->sh_info];
3147 /* ignore sections types we do not handle (plus relocs to those) */
3148 if (sh->sh_type != SHT_PROGBITS &&
3149 #ifdef TCC_ARM_EABI
3150 sh->sh_type != SHT_ARM_EXIDX &&
3151 #endif
3152 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3153 sh->sh_type != SHT_X86_64_UNWIND &&
3154 #endif
3155 sh->sh_type != SHT_NOTE &&
3156 sh->sh_type != SHT_NOBITS &&
3157 sh->sh_type != SHT_PREINIT_ARRAY &&
3158 sh->sh_type != SHT_INIT_ARRAY &&
3159 sh->sh_type != SHT_FINI_ARRAY &&
3160 strcmp(strsec + sh->sh_name, ".stabstr")
3162 continue;
3163 if (seencompressed && 0 == strncmp(strsec + sh->sh_name, ".debug_", 7))
3164 continue;
3166 sh = &shdr[i];
3167 sh_name = strsec + sh->sh_name;
3168 if (sh->sh_addralign < 1)
3169 sh->sh_addralign = 1;
3170 /* find corresponding section, if any */
3171 for(j = 1; j < s1->nb_sections;j++) {
3172 s = s1->sections[j];
3173 if (!strcmp(s->name, sh_name)) {
3174 if (!strncmp(sh_name, ".gnu.linkonce",
3175 sizeof(".gnu.linkonce") - 1)) {
3176 /* if a 'linkonce' section is already present, we
3177 do not add it again. It is a little tricky as
3178 symbols can still be defined in
3179 it. */
3180 sm_table[i].link_once = 1;
3181 goto next;
3183 if (stab_section) {
3184 if (s == stab_section)
3185 stab_index = i;
3186 if (s == stab_section->link)
3187 stabstr_index = i;
3189 goto found;
3192 /* not found: create new section */
3193 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
3194 /* take as much info as possible from the section. sh_link and
3195 sh_info will be updated later */
3196 s->sh_addralign = sh->sh_addralign;
3197 s->sh_entsize = sh->sh_entsize;
3198 sm_table[i].new_section = 1;
3199 found:
3200 if (sh->sh_type != s->sh_type
3201 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3202 && strcmp (s->name, ".eh_frame")
3203 #endif
3205 tcc_error_noabort("invalid section type");
3206 goto the_end;
3208 /* align start of section */
3209 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
3210 if (sh->sh_addralign > s->sh_addralign)
3211 s->sh_addralign = sh->sh_addralign;
3212 sm_table[i].offset = s->data_offset;
3213 sm_table[i].s = s;
3214 /* concatenate sections */
3215 size = sh->sh_size;
3216 if (sh->sh_type != SHT_NOBITS) {
3217 unsigned char *ptr;
3218 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
3219 ptr = section_ptr_add(s, size);
3220 full_read(fd, ptr, size);
3221 } else {
3222 s->data_offset += size;
3224 next: ;
3227 /* gr relocate stab strings */
3228 if (stab_index && stabstr_index) {
3229 Stab_Sym *a, *b;
3230 unsigned o;
3231 s = sm_table[stab_index].s;
3232 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
3233 b = (Stab_Sym *)(s->data + s->data_offset);
3234 o = sm_table[stabstr_index].offset;
3235 while (a < b) {
3236 if (a->n_strx)
3237 a->n_strx += o;
3238 a++;
3242 /* second short pass to update sh_link and sh_info fields of new
3243 sections */
3244 for(i = 1; i < ehdr.e_shnum; i++) {
3245 s = sm_table[i].s;
3246 if (!s || !sm_table[i].new_section)
3247 continue;
3248 sh = &shdr[i];
3249 if (sh->sh_link > 0)
3250 s->link = sm_table[sh->sh_link].s;
3251 if (sh->sh_type == SHT_RELX) {
3252 s->sh_info = sm_table[sh->sh_info].s->sh_num;
3253 /* update backward link */
3254 s1->sections[s->sh_info]->reloc = s;
3258 /* resolve symbols */
3259 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
3261 sym = symtab + 1;
3262 for(i = 1; i < nb_syms; i++, sym++) {
3263 if (sym->st_shndx != SHN_UNDEF &&
3264 sym->st_shndx < SHN_LORESERVE) {
3265 sm = &sm_table[sym->st_shndx];
3266 if (sm->link_once) {
3267 /* if a symbol is in a link once section, we use the
3268 already defined symbol. It is very important to get
3269 correct relocations */
3270 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
3271 name = strtab + sym->st_name;
3272 sym_index = find_elf_sym(symtab_section, name);
3273 if (sym_index)
3274 old_to_new_syms[i] = sym_index;
3276 continue;
3278 /* if no corresponding section added, no need to add symbol */
3279 if (!sm->s)
3280 continue;
3281 /* convert section number */
3282 sym->st_shndx = sm->s->sh_num;
3283 /* offset value */
3284 sym->st_value += sm->offset;
3286 /* add symbol */
3287 name = strtab + sym->st_name;
3288 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
3289 sym->st_info, sym->st_other,
3290 sym->st_shndx, name);
3291 old_to_new_syms[i] = sym_index;
3294 /* third pass to patch relocation entries */
3295 for(i = 1; i < ehdr.e_shnum; i++) {
3296 s = sm_table[i].s;
3297 if (!s)
3298 continue;
3299 sh = &shdr[i];
3300 offset = sm_table[i].offset;
3301 size = sh->sh_size;
3302 switch(s->sh_type) {
3303 case SHT_RELX:
3304 /* take relocation offset information */
3305 offseti = sm_table[sh->sh_info].offset;
3306 for (rel = (ElfW_Rel *) s->data + (offset / sizeof(*rel));
3307 rel < (ElfW_Rel *) s->data + ((offset + size) / sizeof(*rel));
3308 rel++) {
3309 int type;
3310 unsigned sym_index;
3311 /* convert symbol index */
3312 type = ELFW(R_TYPE)(rel->r_info);
3313 sym_index = ELFW(R_SYM)(rel->r_info);
3314 /* NOTE: only one symtab assumed */
3315 if (sym_index >= nb_syms)
3316 goto invalid_reloc;
3317 sym_index = old_to_new_syms[sym_index];
3318 /* ignore link_once in rel section. */
3319 if (!sym_index && !sm_table[sh->sh_info].link_once
3320 #ifdef TCC_TARGET_ARM
3321 && type != R_ARM_V4BX
3322 #elif defined TCC_TARGET_RISCV64
3323 && type != R_RISCV_ALIGN
3324 && type != R_RISCV_RELAX
3325 #endif
3327 invalid_reloc:
3328 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3329 i, strsec + sh->sh_name, (int)rel->r_offset);
3330 goto the_end;
3332 rel->r_info = ELFW(R_INFO)(sym_index, type);
3333 /* offset the relocation offset */
3334 rel->r_offset += offseti;
3335 #ifdef TCC_TARGET_ARM
3336 /* Jumps and branches from a Thumb code to a PLT entry need
3337 special handling since PLT entries are ARM code.
3338 Unconditional bl instructions referencing PLT entries are
3339 handled by converting these instructions into blx
3340 instructions. Other case of instructions referencing a PLT
3341 entry require to add a Thumb stub before the PLT entry to
3342 switch to ARM mode. We set bit plt_thumb_stub of the
3343 attribute of a symbol to indicate such a case. */
3344 if (type == R_ARM_THM_JUMP24)
3345 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
3346 #endif
3348 break;
3349 default:
3350 break;
3354 ret = 0;
3355 the_end:
3356 tcc_free(symtab);
3357 tcc_free(strtab);
3358 tcc_free(old_to_new_syms);
3359 tcc_free(sm_table);
3360 tcc_free(strsec);
3361 tcc_free(shdr);
3362 return ret;
3365 typedef struct ArchiveHeader {
3366 char ar_name[16]; /* name of this member */
3367 char ar_date[12]; /* file mtime */
3368 char ar_uid[6]; /* owner uid; printed as decimal */
3369 char ar_gid[6]; /* owner gid; printed as decimal */
3370 char ar_mode[8]; /* file mode, printed as octal */
3371 char ar_size[10]; /* file size, printed as decimal */
3372 char ar_fmag[2]; /* should contain ARFMAG */
3373 } ArchiveHeader;
3375 #define ARFMAG "`\n"
3377 static unsigned long long get_be(const uint8_t *b, int n)
3379 unsigned long long ret = 0;
3380 while (n)
3381 ret = (ret << 8) | *b++, --n;
3382 return ret;
3385 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
3387 char *p, *e;
3388 int len;
3389 lseek(fd, offset, SEEK_SET);
3390 len = full_read(fd, hdr, sizeof(ArchiveHeader));
3391 if (len != sizeof(ArchiveHeader))
3392 return len ? -1 : 0;
3393 p = hdr->ar_name;
3394 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
3395 --e;
3396 *e = '\0';
3397 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
3398 return len;
3401 /* load only the objects which resolve undefined symbols */
3402 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
3404 int i, bound, nsyms, sym_index, len, ret = -1;
3405 unsigned long long off;
3406 uint8_t *data;
3407 const char *ar_names, *p;
3408 const uint8_t *ar_index;
3409 ElfW(Sym) *sym;
3410 ArchiveHeader hdr;
3412 data = tcc_malloc(size);
3413 if (full_read(fd, data, size) != size)
3414 goto the_end;
3415 nsyms = get_be(data, entrysize);
3416 ar_index = data + entrysize;
3417 ar_names = (char *) ar_index + nsyms * entrysize;
3419 do {
3420 bound = 0;
3421 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
3422 Section *s = symtab_section;
3423 sym_index = find_elf_sym(s, p);
3424 if (!sym_index)
3425 continue;
3426 sym = &((ElfW(Sym) *)s->data)[sym_index];
3427 if(sym->st_shndx != SHN_UNDEF)
3428 continue;
3429 off = get_be(ar_index + i * entrysize, entrysize);
3430 len = read_ar_header(fd, off, &hdr);
3431 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
3432 tcc_error_noabort("invalid archive");
3433 goto the_end;
3435 off += len;
3436 if (s1->verbose == 2)
3437 printf(" -> %s\n", hdr.ar_name);
3438 if (tcc_load_object_file(s1, fd, off) < 0)
3439 goto the_end;
3440 ++bound;
3442 } while(bound);
3443 ret = 0;
3444 the_end:
3445 tcc_free(data);
3446 return ret;
3449 /* load a '.a' file */
3450 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
3452 ArchiveHeader hdr;
3453 /* char magic[8]; */
3454 int size, len;
3455 unsigned long file_offset;
3456 ElfW(Ehdr) ehdr;
3458 /* skip magic which was already checked */
3459 /* full_read(fd, magic, sizeof(magic)); */
3460 file_offset = sizeof ARMAG - 1;
3462 for(;;) {
3463 len = read_ar_header(fd, file_offset, &hdr);
3464 if (len == 0)
3465 return 0;
3466 if (len < 0)
3467 return tcc_error_noabort("invalid archive");
3468 file_offset += len;
3469 size = strtol(hdr.ar_size, NULL, 0);
3470 /* align to even */
3471 size = (size + 1) & ~1;
3472 if (alacarte) {
3473 /* coff symbol table : we handle it */
3474 if (!strcmp(hdr.ar_name, "/"))
3475 return tcc_load_alacarte(s1, fd, size, 4);
3476 if (!strcmp(hdr.ar_name, "/SYM64/"))
3477 return tcc_load_alacarte(s1, fd, size, 8);
3478 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3479 if (s1->verbose == 2)
3480 printf(" -> %s\n", hdr.ar_name);
3481 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3482 return -1;
3484 file_offset += size;
3488 #ifndef ELF_OBJ_ONLY
3489 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3490 LV, maybe create a new entry for (LIB,VERSION). */
3491 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3493 while (i >= *n) {
3494 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3495 (*lv)[(*n)++] = -1;
3497 if ((*lv)[i] == -1) {
3498 int v, prev_same_lib = -1;
3499 for (v = 0; v < nb_sym_versions; v++) {
3500 if (strcmp(sym_versions[v].lib, lib))
3501 continue;
3502 prev_same_lib = v;
3503 if (!strcmp(sym_versions[v].version, version))
3504 break;
3506 if (v == nb_sym_versions) {
3507 sym_versions = tcc_realloc (sym_versions,
3508 (v + 1) * sizeof(*sym_versions));
3509 sym_versions[v].lib = tcc_strdup(lib);
3510 sym_versions[v].version = tcc_strdup(version);
3511 sym_versions[v].out_index = 0;
3512 sym_versions[v].prev_same_lib = prev_same_lib;
3513 nb_sym_versions++;
3515 (*lv)[i] = v;
3519 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3520 VERNDX. */
3521 static void
3522 set_sym_version(TCCState *s1, int sym_index, int verndx)
3524 if (sym_index >= nb_sym_to_version) {
3525 int newelems = sym_index ? sym_index * 2 : 1;
3526 sym_to_version = tcc_realloc(sym_to_version,
3527 newelems * sizeof(*sym_to_version));
3528 memset(sym_to_version + nb_sym_to_version, -1,
3529 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3530 nb_sym_to_version = newelems;
3532 if (sym_to_version[sym_index] < 0)
3533 sym_to_version[sym_index] = verndx;
3536 struct versym_info {
3537 int nb_versyms;
3538 ElfW(Verdef) *verdef;
3539 ElfW(Verneed) *verneed;
3540 ElfW(Half) *versym;
3541 int nb_local_ver, *local_ver;
3545 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3547 char *lib, *version;
3548 uint32_t next;
3549 int i;
3551 #define DEBUG_VERSION 0
3553 if (v->versym && v->verdef) {
3554 ElfW(Verdef) *vdef = v->verdef;
3555 lib = NULL;
3556 do {
3557 ElfW(Verdaux) *verdaux =
3558 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3560 #if DEBUG_VERSION
3561 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3562 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3563 vdef->vd_hash);
3564 #endif
3565 if (vdef->vd_cnt) {
3566 version = dynstr + verdaux->vda_name;
3568 if (lib == NULL)
3569 lib = version;
3570 else
3571 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3572 lib, version);
3573 #if DEBUG_VERSION
3574 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3575 #endif
3577 next = vdef->vd_next;
3578 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3579 } while (next);
3581 if (v->versym && v->verneed) {
3582 ElfW(Verneed) *vneed = v->verneed;
3583 do {
3584 ElfW(Vernaux) *vernaux =
3585 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3587 lib = dynstr + vneed->vn_file;
3588 #if DEBUG_VERSION
3589 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3590 #endif
3591 for (i = 0; i < vneed->vn_cnt; i++) {
3592 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3593 version = dynstr + vernaux->vna_name;
3594 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3595 lib, version);
3596 #if DEBUG_VERSION
3597 printf (" vernaux(%u): %u %u %s\n",
3598 vernaux->vna_other, vernaux->vna_hash,
3599 vernaux->vna_flags, version);
3600 #endif
3602 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3604 next = vneed->vn_next;
3605 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3606 } while (next);
3609 #if DEBUG_VERSION
3610 for (i = 0; i < v->nb_local_ver; i++) {
3611 if (v->local_ver[i] > 0) {
3612 printf ("%d: lib: %s, version %s\n",
3613 i, sym_versions[v->local_ver[i]].lib,
3614 sym_versions[v->local_ver[i]].version);
3617 #endif
3620 /* load a library / DLL
3621 'level = 0' means that the DLL is referenced by the user
3622 (so it should be added as DT_NEEDED in the generated ELF file) */
3623 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3625 ElfW(Ehdr) ehdr;
3626 ElfW(Shdr) *shdr, *sh, *sh1;
3627 int i, nb_syms, nb_dts, sym_bind, ret = -1;
3628 ElfW(Sym) *sym, *dynsym;
3629 ElfW(Dyn) *dt, *dynamic;
3631 char *dynstr;
3632 int sym_index;
3633 const char *name, *soname;
3634 struct versym_info v;
3636 full_read(fd, &ehdr, sizeof(ehdr));
3638 /* test CPU specific stuff */
3639 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3640 ehdr.e_machine != EM_TCC_TARGET) {
3641 return tcc_error_noabort("bad architecture");
3644 /* read sections */
3645 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3647 /* load dynamic section and dynamic symbols */
3648 nb_syms = 0;
3649 nb_dts = 0;
3650 dynamic = NULL;
3651 dynsym = NULL; /* avoid warning */
3652 dynstr = NULL; /* avoid warning */
3653 memset(&v, 0, sizeof v);
3655 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3656 switch(sh->sh_type) {
3657 case SHT_DYNAMIC:
3658 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3659 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3660 break;
3661 case SHT_DYNSYM:
3662 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3663 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3664 sh1 = &shdr[sh->sh_link];
3665 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3666 break;
3667 case SHT_GNU_verdef:
3668 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3669 break;
3670 case SHT_GNU_verneed:
3671 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3672 break;
3673 case SHT_GNU_versym:
3674 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3675 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3676 break;
3677 default:
3678 break;
3682 if (!dynamic)
3683 goto the_end;
3685 /* compute the real library name */
3686 soname = tcc_basename(filename);
3687 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
3688 if (dt->d_tag == DT_SONAME)
3689 soname = dynstr + dt->d_un.d_val;
3691 /* if the dll is already loaded, do not load it */
3692 if (tcc_add_dllref(s1, soname, level)->found)
3693 goto ret_success;
3695 if (v.nb_versyms != nb_syms)
3696 tcc_free (v.versym), v.versym = NULL;
3697 else
3698 store_version(s1, &v, dynstr);
3700 /* add dynamic symbols in dynsym_section */
3701 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3702 sym_bind = ELFW(ST_BIND)(sym->st_info);
3703 if (sym_bind == STB_LOCAL)
3704 continue;
3705 name = dynstr + sym->st_name;
3706 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3707 sym->st_info, sym->st_other, sym->st_shndx, name);
3708 if (v.versym) {
3709 ElfW(Half) vsym = v.versym[i];
3710 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3711 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3715 /* do not load all referenced libraries
3716 (recursive loading can break linking of libraries) */
3717 /* following DT_NEEDED is needed for the dynamic loader (libdl.so),
3718 but it is no longer needed, when linking a library or a program.
3719 When tcc output mode is OUTPUT_MEM,
3720 tcc calls dlopen, which handles DT_NEEDED for us */
3722 #if 0
3723 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
3724 if (dt->d_tag == DT_RPATH)
3725 tcc_add_library_path(s1, dynstr + dt->d_un.d_val);
3727 /* load all referenced DLLs */
3728 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3729 switch(dt->d_tag) {
3730 case DT_NEEDED:
3731 name = dynstr + dt->d_un.d_val;
3732 if (tcc_add_dllref(s1, name, -1))
3733 continue;
3734 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3735 ret = tcc_error_noabort("referenced dll '%s' not found", name);
3736 goto the_end;
3740 #endif
3742 ret_success:
3743 ret = 0;
3744 the_end:
3745 tcc_free(dynstr);
3746 tcc_free(dynsym);
3747 tcc_free(dynamic);
3748 tcc_free(shdr);
3749 tcc_free(v.local_ver);
3750 tcc_free(v.verdef);
3751 tcc_free(v.verneed);
3752 tcc_free(v.versym);
3753 return ret;
3756 #define LD_TOK_NAME 256
3757 #define LD_TOK_EOF (-1)
3759 static int ld_inp(TCCState *s1)
3761 char b;
3762 if (s1->cc != -1) {
3763 int c = s1->cc;
3764 s1->cc = -1;
3765 return c;
3767 if (1 == read(s1->fd, &b, 1))
3768 return b;
3769 return CH_EOF;
3772 /* return next ld script token */
3773 static int ld_next(TCCState *s1, char *name, int name_size)
3775 int c, d, ch;
3776 char *q;
3778 redo:
3779 ch = ld_inp(s1);
3780 switch(ch) {
3781 case ' ':
3782 case '\t':
3783 case '\f':
3784 case '\v':
3785 case '\r':
3786 case '\n':
3787 goto redo;
3788 case '/':
3789 ch = ld_inp(s1);
3790 if (ch == '*') { /* comment */
3791 for (d = 0;; d = ch) {
3792 ch = ld_inp(s1);
3793 if (ch == CH_EOF || (ch == '/' && d == '*'))
3794 break;
3796 goto redo;
3797 } else {
3798 q = name;
3799 *q++ = '/';
3800 goto parse_name;
3802 break;
3803 case '\\':
3804 /* case 'a' ... 'z': */
3805 case 'a':
3806 case 'b':
3807 case 'c':
3808 case 'd':
3809 case 'e':
3810 case 'f':
3811 case 'g':
3812 case 'h':
3813 case 'i':
3814 case 'j':
3815 case 'k':
3816 case 'l':
3817 case 'm':
3818 case 'n':
3819 case 'o':
3820 case 'p':
3821 case 'q':
3822 case 'r':
3823 case 's':
3824 case 't':
3825 case 'u':
3826 case 'v':
3827 case 'w':
3828 case 'x':
3829 case 'y':
3830 case 'z':
3831 /* case 'A' ... 'z': */
3832 case 'A':
3833 case 'B':
3834 case 'C':
3835 case 'D':
3836 case 'E':
3837 case 'F':
3838 case 'G':
3839 case 'H':
3840 case 'I':
3841 case 'J':
3842 case 'K':
3843 case 'L':
3844 case 'M':
3845 case 'N':
3846 case 'O':
3847 case 'P':
3848 case 'Q':
3849 case 'R':
3850 case 'S':
3851 case 'T':
3852 case 'U':
3853 case 'V':
3854 case 'W':
3855 case 'X':
3856 case 'Y':
3857 case 'Z':
3858 case '_':
3859 case '.':
3860 case '$':
3861 case '~':
3862 q = name;
3863 parse_name:
3864 for(;;) {
3865 if (!((ch >= 'a' && ch <= 'z') ||
3866 (ch >= 'A' && ch <= 'Z') ||
3867 (ch >= '0' && ch <= '9') ||
3868 strchr("/.-_+=$:\\,~", ch)))
3869 break;
3870 if ((q - name) < name_size - 1) {
3871 *q++ = ch;
3873 ch = ld_inp(s1);
3875 s1->cc = ch;
3876 *q = '\0';
3877 c = LD_TOK_NAME;
3878 break;
3879 case CH_EOF:
3880 c = LD_TOK_EOF;
3881 break;
3882 default:
3883 c = ch;
3884 break;
3886 return c;
3889 static int ld_add_file(TCCState *s1, const char filename[])
3891 if (filename[0] == '/') {
3892 if (CONFIG_SYSROOT[0] == '\0'
3893 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3894 return 0;
3895 filename = tcc_basename(filename);
3897 return tcc_add_dll(s1, filename, AFF_PRINT_ERROR);
3900 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3902 char filename[1024], libname[1024];
3903 int t, group, nblibs = 0, ret = 0;
3904 char **libs = NULL;
3906 group = !strcmp(cmd, "GROUP");
3907 if (!as_needed)
3908 s1->new_undef_sym = 0;
3909 t = ld_next(s1, filename, sizeof(filename));
3910 if (t != '(') {
3911 ret = tcc_error_noabort("( expected");
3912 goto lib_parse_error;
3914 t = ld_next(s1, filename, sizeof(filename));
3915 for(;;) {
3916 libname[0] = '\0';
3917 if (t == LD_TOK_EOF) {
3918 ret = tcc_error_noabort("unexpected end of file");
3919 goto lib_parse_error;
3920 } else if (t == ')') {
3921 break;
3922 } else if (t == '-') {
3923 t = ld_next(s1, filename, sizeof(filename));
3924 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3925 ret = tcc_error_noabort("library name expected");
3926 goto lib_parse_error;
3928 pstrcpy(libname, sizeof libname, &filename[1]);
3929 if (s1->static_link) {
3930 snprintf(filename, sizeof filename, "lib%s.a", libname);
3931 } else {
3932 snprintf(filename, sizeof filename, "lib%s.so", libname);
3934 } else if (t != LD_TOK_NAME) {
3935 ret = tcc_error_noabort("filename expected");
3936 goto lib_parse_error;
3938 if (!strcmp(filename, "AS_NEEDED")) {
3939 ret = ld_add_file_list(s1, cmd, 1);
3940 if (ret)
3941 goto lib_parse_error;
3942 } else {
3943 /* TODO: Implement AS_NEEDED support. */
3944 /* DT_NEEDED is not used any more so ignore as_needed */
3945 if (1 || !as_needed) {
3946 ret = ld_add_file(s1, filename);
3947 if (ret)
3948 goto lib_parse_error;
3949 if (group) {
3950 /* Add the filename *and* the libname to avoid future conversions */
3951 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3952 if (libname[0] != '\0')
3953 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3957 t = ld_next(s1, filename, sizeof(filename));
3958 if (t == ',') {
3959 t = ld_next(s1, filename, sizeof(filename));
3962 if (group && !as_needed) {
3963 while (s1->new_undef_sym) {
3964 int i;
3965 s1->new_undef_sym = 0;
3966 for (i = 0; i < nblibs; i ++)
3967 ld_add_file(s1, libs[i]);
3970 lib_parse_error:
3971 dynarray_reset(&libs, &nblibs);
3972 return ret;
3975 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3976 files */
3977 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3979 char cmd[64];
3980 char filename[1024];
3981 int t, ret;
3983 s1->fd = fd;
3984 s1->cc = -1;
3985 for(;;) {
3986 t = ld_next(s1, cmd, sizeof(cmd));
3987 if (t == LD_TOK_EOF)
3988 return 0;
3989 else if (t != LD_TOK_NAME)
3990 return -1;
3991 if (!strcmp(cmd, "INPUT") ||
3992 !strcmp(cmd, "GROUP")) {
3993 ret = ld_add_file_list(s1, cmd, 0);
3994 if (ret)
3995 return ret;
3996 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3997 !strcmp(cmd, "TARGET")) {
3998 /* ignore some commands */
3999 t = ld_next(s1, cmd, sizeof(cmd));
4000 if (t != '(')
4001 return tcc_error_noabort("( expected");
4002 for(;;) {
4003 t = ld_next(s1, filename, sizeof(filename));
4004 if (t == LD_TOK_EOF) {
4005 return tcc_error_noabort("unexpected end of file");
4006 } else if (t == ')') {
4007 break;
4010 } else {
4011 return -1;
4014 return 0;
4016 #endif /* !ELF_OBJ_ONLY */