tccelf: avoid find_section() for known section
[tinycc.git] / tccelf.c
blobdd3d6be6882e6267d66219f3a495f8366a6596bf
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 static const int shf_RELRO = SHF_ALLOC;
52 static const char rdata[] = ".rdata";
53 #else
54 static const int shf_RELRO = SHF_ALLOC | SHF_WRITE;
55 static const char rdata[] = ".data.ro";
56 #endif
58 /* ------------------------------------------------------------------------- */
60 ST_FUNC void tccelf_new(TCCState *s)
62 TCCState *s1 = s;
63 /* no section zero */
64 dynarray_add(&s->sections, &s->nb_sections, NULL);
66 /* create standard sections */
67 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
68 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
69 /* create ro data section (make ro after relocation done with GNU_RELRO) */
70 rodata_section = new_section(s, rdata, SHT_PROGBITS, shf_RELRO);
71 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
72 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
73 common_section->sh_num = SHN_COMMON;
75 /* symbols are always generated for linking stage */
76 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
77 ".strtab",
78 ".hashtab", SHF_PRIVATE);
79 s->symtab = symtab_section;
81 /* private symbol table for dynamic symbols */
82 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
83 ".dynstrtab",
84 ".dynhashtab", SHF_PRIVATE);
85 get_sym_attr(s, 0, 1);
88 #ifdef CONFIG_TCC_BCHECK
89 ST_FUNC void tccelf_bounds_new(TCCState *s)
91 TCCState *s1 = s;
92 /* create bounds sections (make ro after relocation done with GNU_RELRO) */
93 bounds_section = new_section(s, ".bounds", SHT_PROGBITS, shf_RELRO);
94 lbounds_section = new_section(s, ".lbounds", SHT_PROGBITS, shf_RELRO);
96 #endif
98 static void free_section(Section *s)
100 tcc_free(s->data);
103 ST_FUNC void tccelf_delete(TCCState *s1)
105 int i;
107 #ifndef ELF_OBJ_ONLY
108 /* free symbol versions */
109 for (i = 0; i < nb_sym_versions; i++) {
110 tcc_free(sym_versions[i].version);
111 tcc_free(sym_versions[i].lib);
113 tcc_free(sym_versions);
114 tcc_free(sym_to_version);
115 #endif
117 /* free all sections */
118 for(i = 1; i < s1->nb_sections; i++)
119 free_section(s1->sections[i]);
120 dynarray_reset(&s1->sections, &s1->nb_sections);
122 for(i = 0; i < s1->nb_priv_sections; i++)
123 free_section(s1->priv_sections[i]);
124 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
126 /* free any loaded DLLs */
127 #ifdef TCC_IS_NATIVE
128 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
129 DLLReference *ref = s1->loaded_dlls[i];
130 if ( ref->handle )
131 # ifdef _WIN32
132 FreeLibrary((HMODULE)ref->handle);
133 # else
134 dlclose(ref->handle);
135 # endif
137 #endif
138 /* free loaded dlls array */
139 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
140 tcc_free(s1->sym_attrs);
142 symtab_section = NULL; /* for tccrun.c:rt_printline() */
145 /* save section data state */
146 ST_FUNC void tccelf_begin_file(TCCState *s1)
148 Section *s; int i;
149 for (i = 1; i < s1->nb_sections; i++) {
150 s = s1->sections[i];
151 s->sh_offset = s->data_offset;
153 /* disable symbol hashing during compilation */
154 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
155 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
156 s1->uw_sym = 0;
157 #endif
160 /* At the end of compilation, convert any UNDEF syms to global, and merge
161 with previously existing symbols */
162 ST_FUNC void tccelf_end_file(TCCState *s1)
164 Section *s = s1->symtab;
165 int first_sym, nb_syms, *tr, i;
167 first_sym = s->sh_offset / sizeof (ElfSym);
168 nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
169 s->data_offset = s->sh_offset;
170 s->link->data_offset = s->link->sh_offset;
171 s->hash = s->reloc, s->reloc = NULL;
172 tr = tcc_mallocz(nb_syms * sizeof *tr);
174 for (i = 0; i < nb_syms; ++i) {
175 ElfSym *sym = (ElfSym*)s->data + first_sym + i;
176 if (sym->st_shndx == SHN_UNDEF
177 && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
178 sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
179 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
180 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
182 /* now update relocations */
183 for (i = 1; i < s1->nb_sections; i++) {
184 Section *sr = s1->sections[i];
185 if (sr->sh_type == SHT_RELX && sr->link == s) {
186 ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
187 ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
188 for (; rel < rel_end; ++rel) {
189 int n = ELFW(R_SYM)(rel->r_info) - first_sym;
190 if (n < 0) /* zero sym_index in reloc (can happen with asm) */
191 continue;
192 rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
196 tcc_free(tr);
198 /* record text/data/bss output for -bench info */
199 for (i = 0; i < 4; ++i) {
200 s = s1->sections[i + 1];
201 s1->total_output[i] += s->data_offset - s->sh_offset;
205 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
207 Section *sec;
209 sec = tcc_mallocz(sizeof(Section) + strlen(name));
210 sec->s1 = s1;
211 strcpy(sec->name, name);
212 sec->sh_type = sh_type;
213 sec->sh_flags = sh_flags;
214 switch(sh_type) {
215 case SHT_GNU_versym:
216 sec->sh_addralign = 2;
217 break;
218 case SHT_HASH:
219 case SHT_GNU_HASH:
220 case SHT_REL:
221 case SHT_RELA:
222 case SHT_DYNSYM:
223 case SHT_SYMTAB:
224 case SHT_DYNAMIC:
225 case SHT_GNU_verneed:
226 case SHT_GNU_verdef:
227 sec->sh_addralign = PTR_SIZE;
228 break;
229 case SHT_STRTAB:
230 sec->sh_addralign = 1;
231 break;
232 default:
233 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */
234 break;
237 if (sh_flags & SHF_PRIVATE) {
238 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
239 } else {
240 sec->sh_num = s1->nb_sections;
241 dynarray_add(&s1->sections, &s1->nb_sections, sec);
244 return sec;
247 ST_FUNC Section *new_symtab(TCCState *s1,
248 const char *symtab_name, int sh_type, int sh_flags,
249 const char *strtab_name,
250 const char *hash_name, int hash_sh_flags)
252 Section *symtab, *strtab, *hash;
253 int *ptr, nb_buckets;
255 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
256 symtab->sh_entsize = sizeof(ElfW(Sym));
257 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
258 put_elf_str(strtab, "");
259 symtab->link = strtab;
260 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
262 nb_buckets = 1;
264 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
265 hash->sh_entsize = sizeof(int);
266 symtab->hash = hash;
267 hash->link = symtab;
269 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
270 ptr[0] = nb_buckets;
271 ptr[1] = 1;
272 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
273 return symtab;
276 /* realloc section and set its content to zero */
277 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
279 unsigned long size;
280 unsigned char *data;
282 size = sec->data_allocated;
283 if (size == 0)
284 size = 1;
285 while (size < new_size)
286 size = size * 2;
287 data = tcc_realloc(sec->data, size);
288 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
289 sec->data = data;
290 sec->data_allocated = size;
293 /* reserve at least 'size' bytes aligned per 'align' in section
294 'sec' from current offset, and return the aligned offset */
295 ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
297 size_t offset, offset1;
299 offset = (sec->data_offset + align - 1) & -align;
300 offset1 = offset + size;
301 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
302 section_realloc(sec, offset1);
303 sec->data_offset = offset1;
304 if (align > sec->sh_addralign)
305 sec->sh_addralign = align;
306 return offset;
309 /* reserve at least 'size' bytes in section 'sec' from
310 sec->data_offset. */
311 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
313 size_t offset = section_add(sec, size, 1);
314 return sec->data + offset;
317 #ifndef ELF_OBJ_ONLY
318 /* reserve at least 'size' bytes from section start */
319 static void section_reserve(Section *sec, unsigned long size)
321 if (size > sec->data_allocated)
322 section_realloc(sec, size);
323 if (size > sec->data_offset)
324 sec->data_offset = size;
326 #endif
328 static Section *have_section(TCCState *s1, const char *name)
330 Section *sec;
331 int i;
332 for(i = 1; i < s1->nb_sections; i++) {
333 sec = s1->sections[i];
334 if (!strcmp(name, sec->name))
335 return sec;
337 return NULL;
340 /* return a reference to a section, and create it if it does not
341 exists */
342 ST_FUNC Section *find_section(TCCState *s1, const char *name)
344 Section *sec = have_section(s1, name);
345 if (sec)
346 return sec;
347 /* sections are created as PROGBITS */
348 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
351 /* ------------------------------------------------------------------------- */
353 ST_FUNC int put_elf_str(Section *s, const char *sym)
355 int offset, len;
356 char *ptr;
358 len = strlen(sym) + 1;
359 offset = s->data_offset;
360 ptr = section_ptr_add(s, len);
361 memmove(ptr, sym, len);
362 return offset;
365 /* elf symbol hashing function */
366 static ElfW(Word) elf_hash(const unsigned char *name)
368 ElfW(Word) h = 0, g;
370 while (*name) {
371 h = (h << 4) + *name++;
372 g = h & 0xf0000000;
373 if (g)
374 h ^= g >> 24;
375 h &= ~g;
377 return h;
380 /* rebuild hash table of section s */
381 /* NOTE: we do factorize the hash table code to go faster */
382 static void rebuild_hash(Section *s, unsigned int nb_buckets)
384 ElfW(Sym) *sym;
385 int *ptr, *hash, nb_syms, sym_index, h;
386 unsigned char *strtab;
388 strtab = s->link->data;
389 nb_syms = s->data_offset / sizeof(ElfW(Sym));
391 if (!nb_buckets)
392 nb_buckets = ((int*)s->hash->data)[0];
394 s->hash->data_offset = 0;
395 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
396 ptr[0] = nb_buckets;
397 ptr[1] = nb_syms;
398 ptr += 2;
399 hash = ptr;
400 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
401 ptr += nb_buckets + 1;
403 sym = (ElfW(Sym) *)s->data + 1;
404 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
405 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
406 h = elf_hash(strtab + sym->st_name) % nb_buckets;
407 *ptr = hash[h];
408 hash[h] = sym_index;
409 } else {
410 *ptr = 0;
412 ptr++;
413 sym++;
417 /* return the symbol number */
418 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
419 int info, int other, int shndx, const char *name)
421 int name_offset, sym_index;
422 int nbuckets, h;
423 ElfW(Sym) *sym;
424 Section *hs;
426 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
427 if (name && name[0])
428 name_offset = put_elf_str(s->link, name);
429 else
430 name_offset = 0;
431 /* XXX: endianness */
432 sym->st_name = name_offset;
433 sym->st_value = value;
434 sym->st_size = size;
435 sym->st_info = info;
436 sym->st_other = other;
437 sym->st_shndx = shndx;
438 sym_index = sym - (ElfW(Sym) *)s->data;
439 hs = s->hash;
440 if (hs) {
441 int *ptr, *base;
442 ptr = section_ptr_add(hs, sizeof(int));
443 base = (int *)hs->data;
444 /* only add global or weak symbols. */
445 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
446 /* add another hashing entry */
447 nbuckets = base[0];
448 h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
449 *ptr = base[2 + h];
450 base[2 + h] = sym_index;
451 base[1]++;
452 /* we resize the hash table */
453 hs->nb_hashed_syms++;
454 if (hs->nb_hashed_syms > 2 * nbuckets) {
455 rebuild_hash(s, 2 * nbuckets);
457 } else {
458 *ptr = 0;
459 base[1]++;
462 return sym_index;
465 ST_FUNC int find_elf_sym(Section *s, const char *name)
467 ElfW(Sym) *sym;
468 Section *hs;
469 int nbuckets, sym_index, h;
470 const char *name1;
472 hs = s->hash;
473 if (!hs)
474 return 0;
475 nbuckets = ((int *)hs->data)[0];
476 h = elf_hash((unsigned char *) name) % nbuckets;
477 sym_index = ((int *)hs->data)[2 + h];
478 while (sym_index != 0) {
479 sym = &((ElfW(Sym) *)s->data)[sym_index];
480 name1 = (char *) s->link->data + sym->st_name;
481 if (!strcmp(name, name1))
482 return sym_index;
483 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
485 return 0;
488 /* return elf symbol value, signal error if 'err' is nonzero, decorate
489 name if FORC */
490 ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
492 int sym_index;
493 ElfW(Sym) *sym;
494 char buf[256];
495 if (forc && s1->leading_underscore
496 #ifdef TCC_TARGET_PE
497 /* win32-32bit stdcall symbols always have _ already */
498 && !strchr(name, '@')
499 #endif
501 buf[0] = '_';
502 pstrcpy(buf + 1, sizeof(buf) - 1, name);
503 name = buf;
505 sym_index = find_elf_sym(s1->symtab, name);
506 sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
507 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
508 if (err)
509 tcc_error("%s not defined", name);
510 return (addr_t)-1;
512 return sym->st_value;
515 /* return elf symbol value */
516 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
518 addr_t addr = get_sym_addr(s, name, 0, 1);
519 return addr == -1 ? NULL : (void*)(uintptr_t)addr;
522 /* list elf symbol names and values */
523 ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
524 void (*symbol_cb)(void *ctx, const char *name, const void *val))
526 ElfW(Sym) *sym;
527 Section *symtab;
528 int sym_index, end_sym;
529 const char *name;
530 unsigned char sym_vis, sym_bind;
532 symtab = s->symtab;
533 end_sym = symtab->data_offset / sizeof (ElfSym);
534 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
535 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
536 if (sym->st_value) {
537 name = (char *) symtab->link->data + sym->st_name;
538 sym_bind = ELFW(ST_BIND)(sym->st_info);
539 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
540 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
541 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
546 /* list elf symbol names and values */
547 LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
548 void (*symbol_cb)(void *ctx, const char *name, const void *val))
550 list_elf_symbols(s, ctx, symbol_cb);
553 #ifndef ELF_OBJ_ONLY
554 static void
555 version_add (TCCState *s1)
557 int i;
558 ElfW(Sym) *sym;
559 ElfW(Verneed) *vn = NULL;
560 Section *symtab;
561 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
562 ElfW(Half) *versym;
563 const char *name;
565 if (0 == nb_sym_versions)
566 return;
567 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
568 versym_section->sh_entsize = sizeof(ElfW(Half));
569 versym_section->link = s1->dynsym;
571 /* add needed symbols */
572 symtab = s1->dynsym;
573 end_sym = symtab->data_offset / sizeof (ElfSym);
574 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
575 for (sym_index = 1; sym_index < end_sym; ++sym_index) {
576 int dllindex, verndx;
577 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
578 if (sym->st_shndx != SHN_UNDEF)
579 continue; /* defined symbol doesn't need library version */
580 name = (char *) symtab->link->data + sym->st_name;
581 dllindex = find_elf_sym(s1->dynsymtab_section, name);
582 verndx = (dllindex && dllindex < nb_sym_to_version)
583 ? sym_to_version[dllindex] : -1;
584 if (verndx >= 0) {
585 if (!sym_versions[verndx].out_index)
586 sym_versions[verndx].out_index = nb_versions++;
587 versym[sym_index] = sym_versions[verndx].out_index;
590 /* generate verneed section, but not when it will be empty. Some
591 dynamic linkers look at their contents even when DTVERNEEDNUM and
592 section size is zero. */
593 if (nb_versions > 2) {
594 verneed_section = new_section(s1, ".gnu.version_r",
595 SHT_GNU_verneed, SHF_ALLOC);
596 verneed_section->link = s1->dynsym->link;
597 for (i = nb_sym_versions; i-- > 0;) {
598 struct sym_version *sv = &sym_versions[i];
599 int n_same_libs = 0, prev;
600 size_t vnofs;
601 ElfW(Vernaux) *vna = 0;
602 if (sv->out_index < 1)
603 continue;
605 /* make sure that a DT_NEEDED tag is put */
606 /* abitest-tcc fails on older i386-linux with "ld-linux.so.2" DT_NEEDED
607 ret_int_test... Inconsistency detected by ld.so: dl-minimal.c: 148:
608 realloc: Assertion `ptr == alloc_last_block' failed! */
609 if (strcmp(sv->lib, "ld-linux.so.2"))
610 tcc_add_dllref(s1, sv->lib, 0);
612 vnofs = section_add(verneed_section, sizeof(*vn), 1);
613 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
614 vn->vn_version = 1;
615 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
616 vn->vn_aux = sizeof (*vn);
617 do {
618 prev = sv->prev_same_lib;
619 if (sv->out_index > 0) {
620 vna = section_ptr_add(verneed_section, sizeof(*vna));
621 vna->vna_hash = elf_hash ((const unsigned char *)sv->version);
622 vna->vna_flags = 0;
623 vna->vna_other = sv->out_index;
624 sv->out_index = -2;
625 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
626 vna->vna_next = sizeof (*vna);
627 n_same_libs++;
629 if (prev >= 0)
630 sv = &sym_versions[prev];
631 } while(prev >= 0);
632 vna->vna_next = 0;
633 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
634 vn->vn_cnt = n_same_libs;
635 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
636 nb_entries++;
638 if (vn)
639 vn->vn_next = 0;
640 verneed_section->sh_info = nb_entries;
642 dt_verneednum = nb_entries;
644 #endif /* ndef ELF_OBJ_ONLY */
646 /* add an elf symbol : check if it is already defined and patch
647 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
648 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
649 int info, int other, int shndx, const char *name)
651 TCCState *s1 = s->s1;
652 ElfW(Sym) *esym;
653 int sym_bind, sym_index, sym_type, esym_bind;
654 unsigned char sym_vis, esym_vis, new_vis;
656 sym_bind = ELFW(ST_BIND)(info);
657 sym_type = ELFW(ST_TYPE)(info);
658 sym_vis = ELFW(ST_VISIBILITY)(other);
660 if (sym_bind != STB_LOCAL) {
661 /* we search global or weak symbols */
662 sym_index = find_elf_sym(s, name);
663 if (!sym_index)
664 goto do_def;
665 esym = &((ElfW(Sym) *)s->data)[sym_index];
666 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
667 && esym->st_other == other && esym->st_shndx == shndx)
668 return sym_index;
669 if (esym->st_shndx != SHN_UNDEF) {
670 esym_bind = ELFW(ST_BIND)(esym->st_info);
671 /* propagate the most constraining visibility */
672 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
673 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
674 if (esym_vis == STV_DEFAULT) {
675 new_vis = sym_vis;
676 } else if (sym_vis == STV_DEFAULT) {
677 new_vis = esym_vis;
678 } else {
679 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
681 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
682 | new_vis;
683 if (shndx == SHN_UNDEF) {
684 /* ignore adding of undefined symbol if the
685 corresponding symbol is already defined */
686 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
687 /* global overrides weak, so patch */
688 goto do_patch;
689 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
690 /* weak is ignored if already global */
691 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
692 /* keep first-found weak definition, ignore subsequents */
693 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
694 /* ignore hidden symbols after */
695 } else if ((esym->st_shndx == SHN_COMMON
696 || esym->st_shndx == bss_section->sh_num)
697 && (shndx < SHN_LORESERVE
698 && shndx != bss_section->sh_num)) {
699 /* data symbol gets precedence over common/bss */
700 goto do_patch;
701 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
702 /* data symbol keeps precedence over common/bss */
703 } else if (s->sh_flags & SHF_DYNSYM) {
704 /* we accept that two DLL define the same symbol */
705 } else if (esym->st_other & ST_ASM_SET) {
706 /* If the existing symbol came from an asm .set
707 we can override. */
708 goto do_patch;
709 } else {
710 #if 0
711 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
712 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
713 #endif
714 tcc_error_noabort("'%s' defined twice", name);
716 } else {
717 esym->st_other = other;
718 do_patch:
719 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
720 esym->st_shndx = shndx;
721 s1->new_undef_sym = 1;
722 esym->st_value = value;
723 esym->st_size = size;
725 } else {
726 do_def:
727 sym_index = put_elf_sym(s, value, size,
728 ELFW(ST_INFO)(sym_bind, sym_type), other,
729 shndx, name);
731 return sym_index;
734 /* put relocation */
735 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
736 int type, int symbol, addr_t addend)
738 TCCState *s1 = s->s1;
739 char buf[256];
740 Section *sr;
741 ElfW_Rel *rel;
743 sr = s->reloc;
744 if (!sr) {
745 /* if no relocation section, create it */
746 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
747 /* if the symtab is allocated, then we consider the relocation
748 are also */
749 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
750 sr->sh_entsize = sizeof(ElfW_Rel);
751 sr->link = symtab;
752 sr->sh_info = s->sh_num;
753 s->reloc = sr;
755 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
756 rel->r_offset = offset;
757 rel->r_info = ELFW(R_INFO)(symbol, type);
758 #if SHT_RELX == SHT_RELA
759 rel->r_addend = addend;
760 #endif
761 if (SHT_RELX != SHT_RELA && addend)
762 tcc_error("non-zero addend on REL architecture");
765 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
766 int type, int symbol)
768 put_elf_reloca(symtab, s, offset, type, symbol, 0);
771 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
773 int n;
774 struct sym_attr *tab;
776 if (index >= s1->nb_sym_attrs) {
777 if (!alloc)
778 return s1->sym_attrs;
779 /* find immediately bigger power of 2 and reallocate array */
780 n = 1;
781 while (index >= n)
782 n *= 2;
783 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
784 s1->sym_attrs = tab;
785 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
786 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
787 s1->nb_sym_attrs = n;
789 return &s1->sym_attrs[index];
792 static void modify_reloctions_old_to_new(TCCState *s1, Section *s, int *old_to_new_syms)
794 int i, type, sym_index;
795 Section *sr;
796 ElfW_Rel *rel;
798 for(i = 1; i < s1->nb_sections; i++) {
799 sr = s1->sections[i];
800 if (sr->sh_type == SHT_RELX && sr->link == s) {
801 for_each_elem(sr, 0, rel, ElfW_Rel) {
802 sym_index = ELFW(R_SYM)(rel->r_info);
803 type = ELFW(R_TYPE)(rel->r_info);
804 sym_index = old_to_new_syms[sym_index];
805 rel->r_info = ELFW(R_INFO)(sym_index, type);
811 /* In an ELF file symbol table, the local symbols must appear below
812 the global and weak ones. Since TCC cannot sort it while generating
813 the code, we must do it after. All the relocation tables are also
814 modified to take into account the symbol table sorting */
815 static void sort_syms(TCCState *s1, Section *s)
817 int *old_to_new_syms;
818 ElfW(Sym) *new_syms;
819 int nb_syms, i;
820 ElfW(Sym) *p, *q;
822 nb_syms = s->data_offset / sizeof(ElfW(Sym));
823 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
824 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
826 /* first pass for local symbols */
827 p = (ElfW(Sym) *)s->data;
828 q = new_syms;
829 for(i = 0; i < nb_syms; i++) {
830 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
831 old_to_new_syms[i] = q - new_syms;
832 *q++ = *p;
834 p++;
836 /* save the number of local symbols in section header */
837 if( s->sh_size ) /* this 'if' makes IDA happy */
838 s->sh_info = q - new_syms;
840 /* then second pass for non local symbols */
841 p = (ElfW(Sym) *)s->data;
842 for(i = 0; i < nb_syms; i++) {
843 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
844 old_to_new_syms[i] = q - new_syms;
845 *q++ = *p;
847 p++;
850 /* we copy the new symbols to the old */
851 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
852 tcc_free(new_syms);
854 modify_reloctions_old_to_new(s1, s, old_to_new_syms);
856 tcc_free(old_to_new_syms);
859 #ifndef ELF_OBJ_ONLY
860 /* See: https://flapenguin.me/elf-dt-gnu-hash */
861 #define ELFCLASS_BITS (PTR_SIZE * 8)
863 static Section *create_gnu_hash(TCCState *s1)
865 int nb_syms, i, ndef, nbuckets, symoffset, bloom_size, bloom_shift;
866 ElfW(Sym) *p;
867 Section *gnu_hash;
868 Section *dynsym = s1->dynsym;
869 Elf32_Word *ptr;
871 gnu_hash = new_section(s1, ".gnu.hash", SHT_GNU_HASH, SHF_ALLOC);
872 gnu_hash->link = dynsym->hash->link;
874 nb_syms = dynsym->data_offset / sizeof(ElfW(Sym));
876 /* count def symbols */
877 ndef = 0;
878 p = (ElfW(Sym) *)dynsym->data;
879 for(i = 0; i < nb_syms; i++, p++)
880 ndef += p->st_shndx != SHN_UNDEF;
882 /* calculate gnu hash sizes and fill header */
883 nbuckets = ndef / 4 + 1;
884 symoffset = nb_syms - ndef;
885 bloom_shift = PTR_SIZE == 8 ? 6 : 5;
886 bloom_size = 1; /* must be power of two */
887 while (ndef >= bloom_size * (1 << (bloom_shift - 3)))
888 bloom_size *= 2;
889 ptr = section_ptr_add(gnu_hash, 4 * 4 +
890 PTR_SIZE * bloom_size +
891 nbuckets * 4 +
892 ndef * 4);
893 ptr[0] = nbuckets;
894 ptr[1] = symoffset;
895 ptr[2] = bloom_size;
896 ptr[3] = bloom_shift;
897 return gnu_hash;
900 static Elf32_Word elf_gnu_hash (const unsigned char *name)
902 Elf32_Word h = 5381;
903 unsigned char c;
905 while ((c = *name++))
906 h = h * 33 + c;
907 return h;
910 static void update_gnu_hash(TCCState *s1, Section *gnu_hash)
912 int *old_to_new_syms;
913 ElfW(Sym) *new_syms;
914 int nb_syms, i, nbuckets, bloom_size, bloom_shift;
915 ElfW(Sym) *p, *q;
916 Section *vs;
917 Section *dynsym = s1->dynsym;
918 Elf32_Word *ptr, *buckets, *chain, *hash;
919 unsigned int *nextbuck;
920 addr_t *bloom;
921 unsigned char *strtab;
922 struct { int first, last; } *buck;
924 strtab = dynsym->link->data;
925 nb_syms = dynsym->data_offset / sizeof(ElfW(Sym));
926 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
927 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
928 hash = tcc_malloc(nb_syms * sizeof(Elf32_Word));
929 nextbuck = tcc_malloc(nb_syms * sizeof(int));
931 /* calculate hashes and copy undefs */
932 p = (ElfW(Sym) *)dynsym->data;
933 q = new_syms;
934 for(i = 0; i < nb_syms; i++, p++) {
935 if (p->st_shndx == SHN_UNDEF) {
936 old_to_new_syms[i] = q - new_syms;
937 *q++ = *p;
939 else
940 hash[i] = elf_gnu_hash(strtab + p->st_name);
943 ptr = (Elf32_Word *) gnu_hash->data;
944 nbuckets = ptr[0];
945 bloom_size = ptr[2];
946 bloom_shift = ptr[3];
947 bloom = (addr_t *) (void *) &ptr[4];
948 buckets = (Elf32_Word*) (void *) &bloom[bloom_size];
949 chain = &buckets[nbuckets];
950 buck = tcc_malloc(nbuckets * sizeof(*buck));
952 if (gnu_hash->data_offset != 4 * 4 +
953 PTR_SIZE * bloom_size +
954 nbuckets * 4 +
955 (nb_syms - (q - new_syms)) * 4)
956 tcc_error ("gnu_hash size incorrect");
958 /* find buckets */
959 for(i = 0; i < nbuckets; i++)
960 buck[i].first = -1;
962 p = (ElfW(Sym) *)dynsym->data;
963 for(i = 0; i < nb_syms; i++, p++)
964 if (p->st_shndx != SHN_UNDEF) {
965 int bucket = hash[i] % nbuckets;
967 if (buck[bucket].first == -1)
968 buck[bucket].first = buck[bucket].last = i;
969 else {
970 nextbuck[buck[bucket].last] = i;
971 buck[bucket].last = i;
975 /* fill buckets/chains/bloom and sort symbols */
976 p = (ElfW(Sym) *)dynsym->data;
977 for(i = 0; i < nbuckets; i++) {
978 int cur = buck[i].first;
980 if (cur != -1) {
981 buckets[i] = q - new_syms;
982 for (;;) {
983 old_to_new_syms[cur] = q - new_syms;
984 *q++ = p[cur];
985 *chain++ = hash[cur] & ~1;
986 bloom[(hash[cur] / ELFCLASS_BITS) % bloom_size] |=
987 (addr_t)1 << (hash[cur] % ELFCLASS_BITS) |
988 (addr_t)1 << ((hash[cur] >> bloom_shift) % ELFCLASS_BITS);
989 if (cur == buck[i].last)
990 break;
991 cur = nextbuck[cur];
993 chain[-1] |= 1;
997 memcpy(dynsym->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
998 tcc_free(new_syms);
999 tcc_free(hash);
1000 tcc_free(buck);
1001 tcc_free(nextbuck);
1003 modify_reloctions_old_to_new(s1, dynsym, old_to_new_syms);
1005 /* modify the versions */
1006 vs = versym_section;
1007 if (vs) {
1008 ElfW(Half) *newver, *versym = (ElfW(Half) *)vs->data;
1010 if (1/*versym*/) {
1011 newver = tcc_malloc(nb_syms * sizeof(*newver));
1012 for (i = 0; i < nb_syms; i++)
1013 newver[old_to_new_syms[i]] = versym[i];
1014 memcpy(vs->data, newver, nb_syms * sizeof(*newver));
1015 tcc_free(newver);
1019 tcc_free(old_to_new_syms);
1021 /* rebuild hash */
1022 ptr = (Elf32_Word *) dynsym->hash->data;
1023 rebuild_hash(dynsym, ptr[0]);
1025 #endif /* ELF_OBJ_ONLY */
1027 /* relocate symbol table, resolve undefined symbols if do_resolve is
1028 true and output error if undefined symbol. */
1029 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
1031 ElfW(Sym) *sym;
1032 int sym_bind, sh_num;
1033 const char *name;
1035 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
1036 sh_num = sym->st_shndx;
1037 if (sh_num == SHN_UNDEF) {
1038 if (do_resolve == 2) /* relocating dynsym */
1039 continue;
1040 name = (char *) s1->symtab->link->data + sym->st_name;
1041 /* Use ld.so to resolve symbol for us (for tcc -run) */
1042 if (do_resolve) {
1043 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
1044 /* dlsym() needs the undecorated name. */
1045 void *addr = dlsym(RTLD_DEFAULT, &name[s1->leading_underscore]);
1046 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD || TARGETOS_ANDROID
1047 if (addr == NULL) {
1048 int i;
1049 for (i = 0; i < s1->nb_loaded_dlls; i++)
1050 if ((addr = dlsym(s1->loaded_dlls[i]->handle, name)))
1051 break;
1053 #endif
1054 if (addr) {
1055 sym->st_value = (addr_t) addr;
1056 #ifdef DEBUG_RELOC
1057 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
1058 #endif
1059 goto found;
1061 #endif
1062 /* if dynamic symbol exist, it will be used in relocate_section */
1063 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
1064 goto found;
1065 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1066 it */
1067 if (!strcmp(name, "_fp_hw"))
1068 goto found;
1069 /* only weak symbols are accepted to be undefined. Their
1070 value is zero */
1071 sym_bind = ELFW(ST_BIND)(sym->st_info);
1072 if (sym_bind == STB_WEAK)
1073 sym->st_value = 0;
1074 else
1075 tcc_error_noabort("undefined symbol '%s'", name);
1077 } else if (sh_num < SHN_LORESERVE) {
1078 /* add section base */
1079 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1081 found: ;
1085 /* relocate a given section (CPU dependent) by applying the relocations
1086 in the associated relocation section */
1087 static void relocate_section(TCCState *s1, Section *s, Section *sr)
1089 ElfW_Rel *rel;
1090 ElfW(Sym) *sym;
1091 int type, sym_index;
1092 unsigned char *ptr;
1093 addr_t tgt, addr;
1094 int is_dwarf = s->sh_num >= s1->dwlo && s->sh_num < s1->dwhi;
1096 qrel = (ElfW_Rel *)sr->data;
1097 for_each_elem(sr, 0, rel, ElfW_Rel) {
1098 ptr = s->data + rel->r_offset;
1099 sym_index = ELFW(R_SYM)(rel->r_info);
1100 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1101 type = ELFW(R_TYPE)(rel->r_info);
1102 tgt = sym->st_value;
1103 #if SHT_RELX == SHT_RELA
1104 tgt += rel->r_addend;
1105 #endif
1106 if (is_dwarf && type == R_DATA_32DW
1107 && sym->st_shndx >= s1->dwlo && sym->st_shndx < s1->dwhi) {
1108 /* dwarf section relocation to each other */
1109 add32le(ptr, tgt - s1->sections[sym->st_shndx]->sh_addr);
1110 continue;
1112 addr = s->sh_addr + rel->r_offset;
1113 relocate(s1, rel, type, ptr, addr, tgt);
1115 #ifndef ELF_OBJ_ONLY
1116 /* if the relocation is allocated, we change its symbol table */
1117 if (sr->sh_flags & SHF_ALLOC) {
1118 sr->link = s1->dynsym;
1119 if (s1->output_type & TCC_OUTPUT_DYN) {
1120 size_t r = (uint8_t*)qrel - sr->data;
1121 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
1122 && 0 == strcmp(s->name, ".stab"))
1123 r = 0; /* cannot apply 64bit relocation to 32bit value */
1124 sr->data_offset = sr->sh_size = r;
1125 #ifdef CONFIG_TCC_PIE
1126 if (r && 0 == (s->sh_flags & SHF_WRITE))
1127 tcc_warning("%d relocations to ro-section %s", (unsigned)(r / sizeof *qrel), s->name);
1128 #endif
1131 #endif
1134 /* relocate all sections */
1135 ST_FUNC void relocate_sections(TCCState *s1)
1137 int i;
1138 Section *s, *sr;
1140 for (i = 1; i < s1->nb_sections; ++i) {
1141 sr = s1->sections[i];
1142 if (sr->sh_type != SHT_RELX)
1143 continue;
1144 s = s1->sections[sr->sh_info];
1145 #ifndef TCC_TARGET_MACHO
1146 if (s != s1->got
1147 || s1->static_link
1148 || s1->output_type == TCC_OUTPUT_MEMORY)
1149 #endif
1151 relocate_section(s1, s, sr);
1153 #ifndef ELF_OBJ_ONLY
1154 if (sr->sh_flags & SHF_ALLOC) {
1155 ElfW_Rel *rel;
1156 /* relocate relocation table in 'sr' */
1157 for_each_elem(sr, 0, rel, ElfW_Rel)
1158 rel->r_offset += s->sh_addr;
1160 #endif
1164 #ifndef ELF_OBJ_ONLY
1165 /* count the number of dynamic relocations so that we can reserve
1166 their space */
1167 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
1169 int count = 0;
1170 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1171 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1172 defined(TCC_TARGET_RISCV64)
1173 ElfW_Rel *rel;
1174 for_each_elem(sr, 0, rel, ElfW_Rel) {
1175 int sym_index = ELFW(R_SYM)(rel->r_info);
1176 int type = ELFW(R_TYPE)(rel->r_info);
1177 switch(type) {
1178 #if defined(TCC_TARGET_I386)
1179 case R_386_32:
1180 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
1181 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
1182 /* don't fixup unresolved (weak) symbols */
1183 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
1184 break;
1186 #elif defined(TCC_TARGET_X86_64)
1187 case R_X86_64_32:
1188 case R_X86_64_32S:
1189 case R_X86_64_64:
1190 #elif defined(TCC_TARGET_ARM)
1191 case R_ARM_ABS32:
1192 case R_ARM_TARGET1:
1193 #elif defined(TCC_TARGET_ARM64)
1194 case R_AARCH64_ABS32:
1195 case R_AARCH64_ABS64:
1196 #elif defined(TCC_TARGET_RISCV64)
1197 case R_RISCV_32:
1198 case R_RISCV_64:
1199 #endif
1200 count++;
1201 break;
1202 #if defined(TCC_TARGET_I386)
1203 case R_386_PC32:
1204 #elif defined(TCC_TARGET_X86_64)
1205 case R_X86_64_PC32:
1207 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1208 /* Hidden defined symbols can and must be resolved locally.
1209 We're misusing a PLT32 reloc for this, as that's always
1210 resolved to its address even in shared libs. */
1211 if (sym->st_shndx != SHN_UNDEF &&
1212 ELFW(ST_VISIBILITY)(sym->st_other) == STV_HIDDEN) {
1213 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PLT32);
1214 break;
1217 #elif defined(TCC_TARGET_ARM64)
1218 case R_AARCH64_PREL32:
1219 #endif
1220 if (s1->output_type != TCC_OUTPUT_DLL)
1221 break;
1222 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1223 count++;
1224 break;
1225 default:
1226 break;
1229 #endif
1230 return count;
1232 #endif
1234 #ifdef NEED_BUILD_GOT
1235 static int build_got(TCCState *s1)
1237 /* if no got, then create it */
1238 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1239 s1->got->sh_entsize = 4;
1240 /* keep space for _DYNAMIC pointer and two dummy got entries */
1241 section_ptr_add(s1->got, 3 * PTR_SIZE);
1242 return set_elf_sym(symtab_section, 0, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1243 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1246 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1247 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1248 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1249 Returns the offset of the GOT or (if any) PLT entry. */
1250 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1251 int sym_index)
1253 int need_plt_entry;
1254 const char *name;
1255 ElfW(Sym) *sym;
1256 struct sym_attr *attr;
1257 unsigned got_offset;
1258 char plt_name[200];
1259 int len;
1260 Section *s_rel;
1262 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1263 attr = get_sym_attr(s1, sym_index, 1);
1265 /* In case a function is both called and its address taken 2 GOT entries
1266 are created, one for taking the address (GOT) and the other for the PLT
1267 entry (PLTGOT). */
1268 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1269 return attr;
1271 s_rel = s1->got;
1272 if (need_plt_entry) {
1273 if (!s1->plt) {
1274 s1->plt = new_section(s1, ".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
1275 s1->plt->sh_entsize = 4;
1277 s_rel = s1->plt;
1280 /* create the GOT entry */
1281 got_offset = s1->got->data_offset;
1282 section_ptr_add(s1->got, PTR_SIZE);
1284 /* Create the GOT relocation that will insert the address of the object or
1285 function of interest in the GOT entry. This is a static relocation for
1286 memory output (dlsym will give us the address of symbols) and dynamic
1287 relocation otherwise (executable and DLLs). The relocation should be
1288 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1289 associated to a PLT entry) but is currently done at load time for an
1290 unknown reason. */
1292 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1293 name = (char *) symtab_section->link->data + sym->st_name;
1294 //printf("sym %d %s\n", need_plt_entry, name);
1296 if (s1->dynsym) {
1297 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1298 /* Hack alarm. We don't want to emit dynamic symbols
1299 and symbol based relocs for STB_LOCAL symbols, but rather
1300 want to resolve them directly. At this point the symbol
1301 values aren't final yet, so we must defer this. We will later
1302 have to create a RELATIVE reloc anyway, so we misuse the
1303 relocation slot to smuggle the symbol reference until
1304 fill_local_got_entries. Not that the sym_index is
1305 relative to symtab_section, not s1->dynsym! Nevertheless
1306 we use s1->dyn_sym so that if this is the first call
1307 that got->reloc is correctly created. Also note that
1308 RELATIVE relocs are not normally created for the .got,
1309 so the types serves as a marker for later (and is retained
1310 also for the final output, which is okay because then the
1311 got is just normal data). */
1312 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1313 sym_index);
1314 } else {
1315 if (0 == attr->dyn_index)
1316 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1317 sym->st_size, sym->st_info, 0,
1318 sym->st_shndx, name);
1319 put_elf_reloc(s1->dynsym, s_rel, got_offset, dyn_reloc_type,
1320 attr->dyn_index);
1322 } else {
1323 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1324 sym_index);
1327 if (need_plt_entry) {
1328 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1330 /* create a symbol 'sym@plt' for the PLT jump vector */
1331 len = strlen(name);
1332 if (len > sizeof plt_name - 5)
1333 len = sizeof plt_name - 5;
1334 memcpy(plt_name, name, len);
1335 strcpy(plt_name + len, "@plt");
1336 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, 0,
1337 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1338 } else {
1339 attr->got_offset = got_offset;
1342 return attr;
1345 /* build GOT and PLT entries */
1346 /* Two passes because R_JMP_SLOT should become first. Some targets
1347 (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1348 ST_FUNC void build_got_entries(TCCState *s1, int got_sym)
1350 Section *s;
1351 ElfW_Rel *rel;
1352 ElfW(Sym) *sym;
1353 int i, type, gotplt_entry, reloc_type, sym_index;
1354 struct sym_attr *attr;
1355 int pass = 0;
1356 redo:
1357 for(i = 1; i < s1->nb_sections; i++) {
1358 s = s1->sections[i];
1359 if (s->sh_type != SHT_RELX)
1360 continue;
1361 /* no need to handle got relocations */
1362 if (s->link != symtab_section)
1363 continue;
1364 for_each_elem(s, 0, rel, ElfW_Rel) {
1365 type = ELFW(R_TYPE)(rel->r_info);
1366 gotplt_entry = gotplt_entry_type(type);
1367 if (gotplt_entry == -1)
1368 tcc_error ("Unknown relocation type for got: %d", type);
1369 sym_index = ELFW(R_SYM)(rel->r_info);
1370 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1372 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1373 continue;
1376 /* Automatically create PLT/GOT [entry] if it is an undefined
1377 reference (resolved at runtime), or the symbol is absolute,
1378 probably created by tcc_add_symbol, and thus on 64-bit
1379 targets might be too far from application code. */
1380 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1381 if (sym->st_shndx == SHN_UNDEF) {
1382 ElfW(Sym) *esym;
1383 int dynindex;
1384 if (!PCRELATIVE_DLLPLT
1385 && (s1->output_type & TCC_OUTPUT_DYN))
1386 continue;
1387 /* Relocations for UNDEF symbols would normally need
1388 to be transferred into the executable or shared object.
1389 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1390 But TCC doesn't do that (at least for exes), so we
1391 need to resolve all such relocs locally. And that
1392 means PLT slots for functions in DLLs and COPY relocs for
1393 data symbols. COPY relocs were generated in
1394 bind_exe_dynsyms (and the symbol adjusted to be defined),
1395 and for functions we were generated a dynamic symbol
1396 of function type. */
1397 if (s1->dynsym) {
1398 /* dynsym isn't set for -run :-/ */
1399 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1400 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1401 if (dynindex
1402 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1403 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1404 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1405 goto jmp_slot;
1407 } else if (sym->st_shndx == SHN_ABS) {
1408 if (sym->st_value == 0) /* from tcc_add_btstub() */
1409 continue;
1410 #ifndef TCC_TARGET_ARM
1411 if (PTR_SIZE != 8)
1412 continue;
1413 #endif
1414 /* from tcc_add_symbol(): on 64 bit platforms these
1415 need to go through .got */
1416 } else
1417 continue;
1420 #ifdef TCC_TARGET_X86_64
1421 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1422 sym->st_shndx != SHN_UNDEF &&
1423 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1424 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1425 s1->output_type & TCC_OUTPUT_EXE)) {
1426 if (pass != 0)
1427 continue;
1428 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1429 continue;
1431 #endif
1432 reloc_type = code_reloc(type);
1433 if (reloc_type == -1)
1434 tcc_error ("Unknown relocation type: %d", type);
1436 if (reloc_type != 0) {
1437 jmp_slot:
1438 if (pass != 0)
1439 continue;
1440 reloc_type = R_JMP_SLOT;
1441 } else {
1442 if (pass != 1)
1443 continue;
1444 reloc_type = R_GLOB_DAT;
1447 if (!s1->got)
1448 got_sym = build_got(s1);
1450 if (gotplt_entry == BUILD_GOT_ONLY)
1451 continue;
1453 attr = put_got_entry(s1, reloc_type, sym_index);
1455 if (reloc_type == R_JMP_SLOT)
1456 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1459 if (++pass < 2)
1460 goto redo;
1461 /* .rel.plt refers to .got actually */
1462 if (s1->plt && s1->plt->reloc)
1463 s1->plt->reloc->sh_info = s1->got->sh_num;
1464 if (got_sym) /* set size */
1465 ((ElfW(Sym)*)symtab_section->data)[got_sym].st_size = s1->got->data_offset;
1467 #endif /* def NEED_BUILD_GOT */
1469 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
1471 int shn = sec ? sec->sh_num : offs || !name ? SHN_ABS : SHN_UNDEF;
1472 if (sec && offs == -1)
1473 offs = sec->data_offset;
1474 return set_elf_sym(symtab_section, offs, 0,
1475 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1478 static void add_init_array_defines(TCCState *s1, const char *section_name)
1480 Section *s;
1481 addr_t end_offset;
1482 char buf[1024];
1483 s = have_section(s1, section_name);
1484 if (!s || !(s->sh_flags & SHF_ALLOC)) {
1485 end_offset = 0;
1486 s = data_section;
1487 } else {
1488 end_offset = s->data_offset;
1490 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1491 set_global_sym(s1, buf, s, 0);
1492 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1493 set_global_sym(s1, buf, s, end_offset);
1496 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1498 Section *s;
1499 s = find_section(s1, sec);
1500 s->sh_flags = shf_RELRO;
1501 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1502 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1503 section_ptr_add(s, PTR_SIZE);
1506 #ifdef CONFIG_TCC_BCHECK
1507 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1509 if (0 == s1->do_bounds_check)
1510 return;
1511 section_ptr_add(bounds_section, sizeof(addr_t));
1513 #endif
1515 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1516 a dynamic symbol to allow so's to have one each with a different value. */
1517 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1519 int c = find_elf_sym(s1->symtab, name);
1520 if (c) {
1521 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1522 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1523 esym->st_value = offset;
1524 esym->st_shndx = s->sh_num;
1528 /* avoid generating debug/test_coverage code for stub functions */
1529 static void tcc_compile_string_no_debug(TCCState *s, const char *str)
1531 int save_do_debug = s->do_debug;
1532 int save_test_coverage = s->test_coverage;
1534 s->do_debug = 0;
1535 s->test_coverage = 0;
1536 tcc_compile_string(s, str);
1537 s->do_debug = save_do_debug;
1538 s->test_coverage = save_test_coverage;
1541 #ifdef CONFIG_TCC_BACKTRACE
1542 static void put_ptr(TCCState *s1, Section *s, int offs)
1544 int c;
1545 c = set_global_sym(s1, NULL, s, offs);
1546 s = data_section;
1547 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1548 section_ptr_add(s, PTR_SIZE);
1551 ST_FUNC void tcc_add_btstub(TCCState *s1)
1553 Section *s;
1554 int n, o;
1555 CString cstr;
1557 s = data_section;
1558 /* Align to PTR_SIZE */
1559 section_ptr_add(s, -s->data_offset & (PTR_SIZE - 1));
1560 o = s->data_offset;
1561 /* create (part of) a struct rt_context (see tccrun.c) */
1562 if (s1->dwarf) {
1563 put_ptr(s1, dwarf_line_section, 0);
1564 put_ptr(s1, dwarf_line_section, -1);
1565 if (s1->dwarf >= 5)
1566 put_ptr(s1, dwarf_line_str_section, 0);
1567 else
1568 put_ptr(s1, dwarf_str_section, 0);
1570 else
1572 put_ptr(s1, stab_section, 0);
1573 put_ptr(s1, stab_section, -1);
1574 put_ptr(s1, stab_section->link, 0);
1576 *(addr_t *)section_ptr_add(s, PTR_SIZE) = s1->dwarf;
1577 /* skip esym_start/esym_end/elf_str (not loaded) */
1578 section_ptr_add(s, 3 * PTR_SIZE);
1579 /* prog_base : local nameless symbol with offset 0 at SHN_ABS */
1580 put_ptr(s1, NULL, 0);
1581 #if defined TCC_TARGET_MACHO
1582 /* adjust for __PAGEZERO */
1583 write64le(data_section->data + data_section->data_offset - PTR_SIZE,
1584 (uint64_t)1 << 32);
1585 #endif
1586 n = 2 * PTR_SIZE;
1587 #ifdef CONFIG_TCC_BCHECK
1588 if (s1->do_bounds_check) {
1589 put_ptr(s1, bounds_section, 0);
1590 n -= PTR_SIZE;
1592 #endif
1593 section_ptr_add(s, n);
1594 cstr_new(&cstr);
1595 cstr_printf(&cstr,
1596 "extern void __bt_init(),__bt_exit(),__bt_init_dll();"
1597 "static void *__rt_info[];"
1598 "__attribute__((constructor)) static void __bt_init_rt(){");
1599 #ifdef TCC_TARGET_PE
1600 if (s1->output_type == TCC_OUTPUT_DLL)
1601 #ifdef CONFIG_TCC_BCHECK
1602 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1603 #else
1604 cstr_printf(&cstr, "__bt_init_dll(0);");
1605 #endif
1606 #endif
1607 cstr_printf(&cstr, "__bt_init(__rt_info,%d);}",
1608 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1609 /* In case dlcose is called by application */
1610 cstr_printf(&cstr,
1611 "__attribute__((destructor)) static void __bt_exit_rt(){"
1612 "__bt_exit(__rt_info);}");
1613 tcc_compile_string_no_debug(s1, cstr.data);
1614 cstr_free(&cstr);
1615 set_local_sym(s1, &"___rt_info"[!s1->leading_underscore], s, o);
1617 #endif /* def CONFIG_TCC_BACKTRACE */
1619 static void tcc_tcov_add_file(TCCState *s1, const char *filename)
1621 CString cstr;
1622 void *ptr;
1623 char wd[1024];
1625 if (tcov_section == NULL)
1626 return;
1627 section_ptr_add(tcov_section, 1);
1628 write32le (tcov_section->data, tcov_section->data_offset);
1630 cstr_new (&cstr);
1631 if (filename[0] == '/')
1632 cstr_printf (&cstr, "%s.tcov", filename);
1633 else {
1634 getcwd (wd, sizeof(wd));
1635 cstr_printf (&cstr, "%s/%s.tcov", wd, filename);
1637 ptr = section_ptr_add(tcov_section, cstr.size + 1);
1638 strcpy((char *)ptr, cstr.data);
1639 unlink((char *)ptr);
1640 #ifdef _WIN32
1641 normalize_slashes((char *)ptr);
1642 #endif
1643 cstr_free (&cstr);
1645 cstr_new(&cstr);
1646 cstr_printf(&cstr,
1647 "extern char *__tcov_data[];"
1648 "extern void __store_test_coverage ();"
1649 "__attribute__((destructor)) static void __tcov_exit() {"
1650 "__store_test_coverage(__tcov_data);"
1651 "}");
1652 tcc_compile_string_no_debug(s1, cstr.data);
1653 cstr_free(&cstr);
1654 set_local_sym(s1, &"___tcov_data"[!s1->leading_underscore], tcov_section, 0);
1657 #ifndef TCC_TARGET_PE
1658 /* add tcc runtime libraries */
1659 ST_FUNC void tcc_add_runtime(TCCState *s1)
1661 s1->filetype = 0;
1663 #ifdef CONFIG_TCC_BCHECK
1664 tcc_add_bcheck(s1);
1665 #endif
1666 tcc_add_pragma_libs(s1);
1668 /* add libc */
1669 if (!s1->nostdlib) {
1670 int lpthread = s1->option_pthread;
1672 #ifdef CONFIG_TCC_BCHECK
1673 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1674 tcc_add_support(s1, "bcheck.o");
1675 # if !(TARGETOS_OpenBSD || TARGETOS_NetBSD)
1676 tcc_add_library_err(s1, "dl");
1677 # endif
1678 lpthread = 1;
1680 #endif
1681 #ifdef CONFIG_TCC_BACKTRACE
1682 if (s1->do_backtrace) {
1683 if (s1->output_type & TCC_OUTPUT_EXE)
1684 tcc_add_support(s1, "bt-exe.o");
1685 if (s1->output_type != TCC_OUTPUT_DLL)
1686 tcc_add_support(s1, "bt-log.o");
1687 if (s1->output_type != TCC_OUTPUT_MEMORY)
1688 tcc_add_btstub(s1);
1690 #endif
1691 if (lpthread)
1692 tcc_add_library_err(s1, "pthread");
1693 tcc_add_library_err(s1, "c");
1694 #ifdef TCC_LIBGCC
1695 if (!s1->static_link) {
1696 if (TCC_LIBGCC[0] == '/')
1697 tcc_add_file(s1, TCC_LIBGCC);
1698 else
1699 tcc_add_dll(s1, TCC_LIBGCC, 0);
1701 #endif
1702 #if defined TCC_TARGET_ARM && TARGETOS_FreeBSD
1703 tcc_add_library_err(s1, "gcc_s"); // unwind code
1704 #endif
1705 if (TCC_LIBTCC1[0])
1706 tcc_add_support(s1, TCC_LIBTCC1);
1708 /* add crt end if not memory output */
1709 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1710 #if defined TCC_TARGET_MACHO
1711 /* nothing to do */
1712 #elif TARGETOS_FreeBSD || TARGETOS_NetBSD
1713 if (s1->output_type & TCC_OUTPUT_DYN)
1714 tcc_add_crt(s1, "crtendS.o");
1715 else
1716 tcc_add_crt(s1, "crtend.o");
1717 tcc_add_crt(s1, "crtn.o");
1718 #elif TARGETOS_OpenBSD
1719 if (s1->output_type == TCC_OUTPUT_DLL)
1720 tcc_add_crt(s1, "crtendS.o");
1721 else
1722 tcc_add_crt(s1, "crtend.o");
1723 #elif TARGETOS_ANDROID
1724 if (s1->output_type == TCC_OUTPUT_DLL)
1725 tcc_add_crt(s1, "crtend_so.o");
1726 else
1727 tcc_add_crt(s1, "crtend_android.o");
1728 #else
1729 tcc_add_crt(s1, "crtn.o");
1730 #endif
1734 #endif /* ndef TCC_TARGET_PE */
1736 /* add various standard linker symbols (must be done after the
1737 sections are filled (for example after allocating common
1738 symbols)) */
1739 static void tcc_add_linker_symbols(TCCState *s1)
1741 char buf[1024];
1742 int i;
1743 Section *s;
1745 set_global_sym(s1, "_etext", text_section, -1);
1746 set_global_sym(s1, "_edata", data_section, -1);
1747 set_global_sym(s1, "_end", bss_section, -1);
1748 #if TARGETOS_OpenBSD
1749 set_global_sym(s1, "__executable_start", NULL, ELF_START_ADDR);
1750 #endif
1751 #ifdef TCC_TARGET_RISCV64
1752 /* XXX should be .sdata+0x800, not .data+0x800 */
1753 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1754 #endif
1755 /* horrible new standard ldscript defines */
1756 add_init_array_defines(s1, ".preinit_array");
1757 add_init_array_defines(s1, ".init_array");
1758 add_init_array_defines(s1, ".fini_array");
1759 /* add start and stop symbols for sections whose name can be
1760 expressed in C */
1761 for(i = 1; i < s1->nb_sections; i++) {
1762 s = s1->sections[i];
1763 if ((s->sh_flags & SHF_ALLOC)
1764 && (s->sh_type == SHT_PROGBITS
1765 || s->sh_type == SHT_STRTAB)) {
1766 const char *p;
1767 /* check if section name can be expressed in C */
1768 p = s->name;
1769 for(;;) {
1770 int c = *p;
1771 if (!c)
1772 break;
1773 if (!isid(c) && !isnum(c))
1774 goto next_sec;
1775 p++;
1777 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1778 set_global_sym(s1, buf, s, 0);
1779 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1780 set_global_sym(s1, buf, s, -1);
1782 next_sec: ;
1786 ST_FUNC void resolve_common_syms(TCCState *s1)
1788 ElfW(Sym) *sym;
1790 /* Allocate common symbols in BSS. */
1791 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1792 if (sym->st_shndx == SHN_COMMON) {
1793 /* symbol alignment is in st_value for SHN_COMMONs */
1794 sym->st_value = section_add(bss_section, sym->st_size,
1795 sym->st_value);
1796 sym->st_shndx = bss_section->sh_num;
1800 /* Now assign linker provided symbols their value. */
1801 tcc_add_linker_symbols(s1);
1804 #ifndef ELF_OBJ_ONLY
1805 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1807 int sym_index = ELFW(R_SYM) (rel->r_info);
1808 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1809 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1810 unsigned offset = attr->got_offset;
1812 if (0 == offset)
1813 return;
1814 section_reserve(s1->got, offset + PTR_SIZE);
1815 #if PTR_SIZE == 8
1816 write64le(s1->got->data + offset, sym->st_value);
1817 #else
1818 write32le(s1->got->data + offset, sym->st_value);
1819 #endif
1822 /* Perform relocation to GOT or PLT entries */
1823 ST_FUNC void fill_got(TCCState *s1)
1825 Section *s;
1826 ElfW_Rel *rel;
1827 int i;
1829 for(i = 1; i < s1->nb_sections; i++) {
1830 s = s1->sections[i];
1831 if (s->sh_type != SHT_RELX)
1832 continue;
1833 /* no need to handle got relocations */
1834 if (s->link != symtab_section)
1835 continue;
1836 for_each_elem(s, 0, rel, ElfW_Rel) {
1837 switch (ELFW(R_TYPE) (rel->r_info)) {
1838 case R_X86_64_GOT32:
1839 case R_X86_64_GOTPCREL:
1840 case R_X86_64_GOTPCRELX:
1841 case R_X86_64_REX_GOTPCRELX:
1842 case R_X86_64_PLT32:
1843 fill_got_entry(s1, rel);
1844 break;
1850 /* See put_got_entry for a description. This is the second stage
1851 where GOT references to local defined symbols are rewritten. */
1852 static void fill_local_got_entries(TCCState *s1)
1854 ElfW_Rel *rel;
1855 if (!s1->got->reloc)
1856 return;
1857 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1858 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1859 int sym_index = ELFW(R_SYM) (rel->r_info);
1860 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1861 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1862 unsigned offset = attr->got_offset;
1863 if (offset != rel->r_offset - s1->got->sh_addr)
1864 tcc_error_noabort("huh");
1865 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1866 #if SHT_RELX == SHT_RELA
1867 rel->r_addend = sym->st_value;
1868 #else
1869 /* All our REL architectures also happen to be 32bit LE. */
1870 write32le(s1->got->data + offset, sym->st_value);
1871 #endif
1876 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1877 in shared libraries */
1878 static void bind_exe_dynsyms(TCCState *s1)
1880 const char *name;
1881 int sym_index, index;
1882 ElfW(Sym) *sym, *esym;
1883 int type;
1885 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1886 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1887 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1888 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1889 if (sym->st_shndx == SHN_UNDEF) {
1890 name = (char *) symtab_section->link->data + sym->st_name;
1891 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1892 if (sym_index) {
1893 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1894 type = ELFW(ST_TYPE)(esym->st_info);
1895 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1896 /* Indirect functions shall have STT_FUNC type in executable
1897 * dynsym section. Indeed, a dlsym call following a lazy
1898 * resolution would pick the symbol value from the
1899 * executable dynsym entry which would contain the address
1900 * of the function wanted by the caller of dlsym instead of
1901 * the address of the function that would return that
1902 * address */
1903 int dynindex
1904 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1905 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1906 name);
1907 int index = sym - (ElfW(Sym) *) symtab_section->data;
1908 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1909 } else if (type == STT_OBJECT) {
1910 unsigned long offset;
1911 ElfW(Sym) *dynsym;
1912 offset = bss_section->data_offset;
1913 /* XXX: which alignment ? */
1914 offset = (offset + 16 - 1) & -16;
1915 set_elf_sym (s1->symtab, offset, esym->st_size,
1916 esym->st_info, 0, bss_section->sh_num, name);
1917 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1918 esym->st_info, 0, bss_section->sh_num,
1919 name);
1921 /* Ensure R_COPY works for weak symbol aliases */
1922 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1923 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1924 if ((dynsym->st_value == esym->st_value)
1925 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1926 char *dynname = (char *) s1->dynsymtab_section->link->data
1927 + dynsym->st_name;
1928 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1929 dynsym->st_info, 0,
1930 bss_section->sh_num, dynname);
1931 break;
1936 put_elf_reloc(s1->dynsym, bss_section,
1937 offset, R_COPY, index);
1938 offset += esym->st_size;
1939 bss_section->data_offset = offset;
1941 } else {
1942 /* STB_WEAK undefined symbols are accepted */
1943 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1944 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1945 !strcmp(name, "_fp_hw")) {
1946 } else {
1947 tcc_error_noabort("undefined symbol '%s'", name);
1954 /* Bind symbols of libraries: export all non local symbols of executable that
1955 are referenced by shared libraries. The reason is that the dynamic loader
1956 search symbol first in executable and then in libraries. Therefore a
1957 reference to a symbol already defined by a library can still be resolved by
1958 a symbol in the executable. With -rdynamic, export all defined symbols */
1959 static void bind_libs_dynsyms(TCCState *s1)
1961 const char *name;
1962 int dynsym_index;
1963 ElfW(Sym) *sym, *esym;
1965 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1966 name = (char *)symtab_section->link->data + sym->st_name;
1967 dynsym_index = find_elf_sym(s1->dynsymtab_section, name);
1968 if (sym->st_shndx != SHN_UNDEF
1969 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1970 if (dynsym_index || s1->rdynamic)
1971 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1972 sym->st_info, 0, sym->st_shndx, name);
1973 } else if (dynsym_index) {
1974 esym = (ElfW(Sym) *)s1->dynsymtab_section->data + dynsym_index;
1975 if (esym->st_shndx == SHN_UNDEF) {
1976 /* weak symbols can stay undefined */
1977 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1978 tcc_warning("undefined dynamic symbol '%s'", name);
1984 /* Export all non local symbols. This is used by shared libraries so that the
1985 non local symbols they define can resolve a reference in another shared
1986 library or in the executable. Correspondingly, it allows undefined local
1987 symbols to be resolved by other shared libraries or by the executable. */
1988 static void export_global_syms(TCCState *s1)
1990 int dynindex, index;
1991 const char *name;
1992 ElfW(Sym) *sym;
1993 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1994 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1995 name = (char *) symtab_section->link->data + sym->st_name;
1996 dynindex = set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1997 sym->st_info, 0, sym->st_shndx, name);
1998 index = sym - (ElfW(Sym) *) symtab_section->data;
1999 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
2004 /* decide if an unallocated section should be output. */
2005 static int set_sec_sizes(TCCState *s1)
2007 int i;
2008 Section *s;
2009 int textrel = 0;
2010 int file_type = s1->output_type;
2012 /* Allocate strings for section names */
2013 for(i = 1; i < s1->nb_sections; i++) {
2014 s = s1->sections[i];
2015 if (s->sh_type == SHT_RELX && !(s->sh_flags & SHF_ALLOC)) {
2016 /* when generating a DLL, we include relocations but
2017 we may patch them */
2018 if ((file_type & TCC_OUTPUT_DYN)
2019 && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) {
2020 int count = prepare_dynamic_rel(s1, s);
2021 if (count) {
2022 /* allocate the section */
2023 s->sh_flags |= SHF_ALLOC;
2024 s->sh_size = count * sizeof(ElfW_Rel);
2025 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
2026 textrel += count;
2029 } else if ((s->sh_flags & SHF_ALLOC)
2030 #ifdef TCC_TARGET_ARM
2031 || s->sh_type == SHT_ARM_ATTRIBUTES
2032 #endif
2033 || s1->do_debug) {
2034 s->sh_size = s->data_offset;
2037 #ifdef TCC_TARGET_ARM
2038 /* XXX: Suppress stack unwinding section. */
2039 if (s->sh_type == SHT_ARM_EXIDX) {
2040 s->sh_flags = 0;
2041 s->sh_size = 0;
2043 #endif
2046 return textrel;
2049 /* various data used under elf_output_file() */
2050 struct dyn_inf {
2051 Section *dynamic;
2052 Section *dynstr;
2053 struct {
2054 /* Info to be copied in dynamic section */
2055 unsigned long data_offset;
2056 addr_t rel_addr;
2057 addr_t rel_size;
2060 ElfW(Phdr) *phdr;
2061 int phnum;
2062 Section *interp;
2063 Section *note;
2064 Section *gnu_hash;
2066 /* read only segment mapping for GNU_RELRO */
2067 Section _roinf, *roinf;
2070 /* Decide the layout of sections loaded in memory. This must be done before
2071 program headers are filled since they contain info about the layout.
2072 We do the following ordering: interp, symbol tables, relocations, progbits,
2073 nobits */
2074 static int sort_sections(TCCState *s1, int *sec_order, Section *interp)
2076 Section *s;
2077 int i, j, k, f, f0, n;
2078 int nb_sections = s1->nb_sections;
2079 int *sec_cls = sec_order + nb_sections;
2081 for (i = 1; i < nb_sections; i++) {
2082 s = s1->sections[i];
2083 if (s->sh_flags & SHF_ALLOC) {
2084 j = 0x100;
2085 if (s->sh_flags & SHF_WRITE)
2086 j = 0x200;
2087 if (s->sh_flags & SHF_TLS)
2088 j += 0x200;
2089 } else if (s->sh_name) {
2090 j = 0x700;
2091 } else {
2092 j = 0x900; /* no sh_name: won't go to file */
2094 if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_DYNSYM) {
2095 k = 0x10;
2096 } else if (s->sh_type == SHT_STRTAB && strcmp(s->name, ".stabstr")) {
2097 k = 0x11;
2098 if (i == nb_sections - 1) /* ".shstrtab" assumed to remain last */
2099 k = 0xff;
2100 } else if (s->sh_type == SHT_HASH || s->sh_type == SHT_GNU_HASH) {
2101 k = 0x12;
2102 } else if (s->sh_type == SHT_RELX) {
2103 k = 0x20;
2104 if (s1->plt && s == s1->plt->reloc)
2105 k = 0x21;
2106 } else if (s->sh_type == SHT_PREINIT_ARRAY) {
2107 k = 0x41;
2108 } else if (s->sh_type == SHT_INIT_ARRAY) {
2109 k = 0x42;
2110 } else if (s->sh_type == SHT_FINI_ARRAY) {
2111 k = 0x43;
2112 #ifdef CONFIG_TCC_BCHECK
2113 } else if (s == bounds_section || s == lbounds_section) {
2114 k = 0x44;
2115 #endif
2116 } else if (s == rodata_section || 0 == strcmp(s->name, ".data.rel.ro")) {
2117 k = 0x45;
2118 } else if (s->sh_type == SHT_DYNAMIC) {
2119 k = 0x46;
2120 } else if (s == s1->got) {
2121 k = 0x47; /* .got as RELRO needs BIND_NOW in DT_FLAGS */
2122 } else {
2123 k = 0x50;
2124 if (s->sh_type == SHT_NOTE)
2125 k = 0x60;
2126 if (s->sh_flags & SHF_EXECINSTR)
2127 k = 0x70;
2128 if (s->sh_type == SHT_NOBITS)
2129 k = 0x80;
2130 if (s == interp)
2131 k = 0x00;
2133 k += j;
2135 for (n = i; n > 1 && k < (f = sec_cls[n - 1]); --n)
2136 sec_cls[n] = f, sec_order[n] = sec_order[n - 1];
2137 sec_cls[n] = k, sec_order[n] = i;
2139 sec_order[0] = 0;
2141 /* count PT_LOAD headers needed */
2142 n = f0 = 0;
2143 for (i = 1; i < nb_sections; i++) {
2144 s = s1->sections[sec_order[i]];
2145 k = sec_cls[i];
2146 f = 0;
2147 if (k < 0x700) {
2148 f = s->sh_flags & (SHF_ALLOC|SHF_WRITE|SHF_EXECINSTR|SHF_TLS);
2149 #if TARGETOS_NetBSD
2150 /* NetBSD only supports 2 PT_LOAD sections.
2151 See: https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */
2152 if ((f & SHF_WRITE) == 0) f |= SHF_EXECINSTR;
2153 #else
2154 if ((k & 0xfff0) == 0x240) /* RELRO sections */
2155 f |= 1<<4;
2156 #endif
2157 if (f != f0) /* start new header when flags changed or relro */
2158 f0 = f, ++n, f |= 1<<8;
2160 sec_cls[i] = f;
2161 //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);
2163 return n;
2166 static ElfW(Phdr) *fill_phdr(ElfW(Phdr) *ph, int type, Section *s)
2168 if (s) {
2169 ph->p_offset = s->sh_offset;
2170 ph->p_vaddr = s->sh_addr;
2171 ph->p_filesz = s->sh_size;
2172 ph->p_align = s->sh_addralign;
2174 ph->p_type = type;
2175 ph->p_flags = PF_R;
2176 ph->p_paddr = ph->p_vaddr;
2177 ph->p_memsz = ph->p_filesz;
2178 return ph;
2181 /* Assign sections to segments and decide how are sections laid out when loaded
2182 in memory. This function also fills corresponding program headers. */
2183 static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
2185 Section *s;
2186 addr_t addr, tmp, align, s_align, base;
2187 ElfW(Phdr) *ph = NULL;
2188 int i, f, n, phnum, phfill;
2189 int file_offset;
2191 /* compute number of program headers */
2192 phnum = sort_sections(s1, sec_order, d->interp);
2193 phfill = 0; /* set to 1 to have dll's with a PT_PHDR */
2194 if (d->interp)
2195 phfill = 2;
2196 phnum += phfill;
2197 if (d->note)
2198 ++phnum;
2199 if (d->dynamic)
2200 ++phnum;
2201 if (d->roinf)
2202 ++phnum;
2203 d->phnum = phnum;
2204 d->phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2206 file_offset = 0;
2207 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2208 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2210 s_align = ELF_PAGE_SIZE;
2211 if (s1->section_align)
2212 s_align = s1->section_align;
2214 addr = ELF_START_ADDR;
2215 if (s1->output_type & TCC_OUTPUT_DYN)
2216 addr = 0;
2218 if (s1->has_text_addr) {
2219 addr = s1->text_addr;
2220 if (0) {
2221 int a_offset, p_offset;
2222 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
2223 ELF_PAGE_SIZE */
2224 a_offset = (int) (addr & (s_align - 1));
2225 p_offset = file_offset & (s_align - 1);
2226 if (a_offset < p_offset)
2227 a_offset += s_align;
2228 file_offset += (a_offset - p_offset);
2231 base = addr;
2232 /* compute address after headers */
2233 addr = addr + (file_offset & (s_align - 1));
2235 n = 0;
2236 for(i = 1; i < s1->nb_sections; i++) {
2237 s = s1->sections[sec_order[i]];
2238 f = sec_order[i + s1->nb_sections];
2239 align = s->sh_addralign - 1;
2241 if (f == 0) { /* no alloc */
2242 file_offset = (file_offset + align) & ~align;
2243 s->sh_offset = file_offset;
2244 if (s->sh_type != SHT_NOBITS)
2245 file_offset += s->sh_size;
2246 continue;
2249 if ((f & 1<<8) && n) {
2250 /* different rwx section flags */
2251 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
2252 /* if in the middle of a page, w e duplicate the page in
2253 memory so that one copy is RX and the other is RW */
2254 if ((addr & (s_align - 1)) != 0)
2255 addr += s_align;
2256 } else {
2257 align = s_align - 1;
2261 tmp = addr;
2262 addr = (addr + align) & ~align;
2263 file_offset += (int)(addr - tmp);
2264 s->sh_offset = file_offset;
2265 s->sh_addr = addr;
2267 if (f & 1<<8) {
2268 /* set new program header */
2269 ph = &d->phdr[phfill + n];
2270 ph->p_type = PT_LOAD;
2271 ph->p_align = s_align;
2272 ph->p_flags = PF_R;
2273 if (f & SHF_WRITE)
2274 ph->p_flags |= PF_W;
2275 if (f & SHF_EXECINSTR)
2276 ph->p_flags |= PF_X;
2277 if (f & SHF_TLS) {
2278 ph->p_type = PT_TLS;
2279 ph->p_align = 4;
2281 ph->p_offset = file_offset;
2282 ph->p_vaddr = addr;
2283 if (n == 0) {
2284 /* Make the first PT_LOAD segment include the program
2285 headers itself (and the ELF header as well), it'll
2286 come out with same memory use but will make various
2287 tools like binutils strip work better. */
2288 ph->p_offset = 0;
2289 ph->p_vaddr = base;
2291 ph->p_paddr = ph->p_vaddr;
2292 ++n;
2295 if (f & 1<<4) {
2296 Section *roinf = &d->_roinf;
2297 if (roinf->sh_size == 0) {
2298 roinf->sh_offset = s->sh_offset;
2299 roinf->sh_addr = s->sh_addr;
2300 roinf->sh_addralign = 1;
2302 roinf->sh_size = (addr - roinf->sh_addr) + s->sh_size;
2305 addr += s->sh_size;
2306 if (s->sh_type != SHT_NOBITS)
2307 file_offset += s->sh_size;
2309 ph->p_filesz = file_offset - ph->p_offset;
2310 ph->p_memsz = addr - ph->p_vaddr;
2313 /* Fill other headers */
2314 if (d->note)
2315 fill_phdr(++ph, PT_NOTE, d->note);
2316 if (d->dynamic)
2317 fill_phdr(++ph, PT_DYNAMIC, d->dynamic)->p_flags |= PF_W;
2318 if (d->roinf)
2319 fill_phdr(++ph, PT_GNU_RELRO, d->roinf)->p_flags |= PF_W;
2320 if (d->interp)
2321 fill_phdr(&d->phdr[1], PT_INTERP, d->interp);
2322 if (phfill) {
2323 ph = &d->phdr[0];
2324 ph->p_offset = sizeof(ElfW(Ehdr));
2325 ph->p_vaddr = base + ph->p_offset;
2326 ph->p_filesz = phnum * sizeof(ElfW(Phdr));
2327 ph->p_align = 4;
2328 fill_phdr(ph, PT_PHDR, NULL);
2330 return file_offset;
2333 /* put dynamic tag */
2334 static void put_dt(Section *dynamic, int dt, addr_t val)
2336 ElfW(Dyn) *dyn;
2337 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
2338 dyn->d_tag = dt;
2339 dyn->d_un.d_val = val;
2342 /* Fill the dynamic section with tags describing the address and size of
2343 sections */
2344 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2346 Section *dynamic = dyninf->dynamic;
2347 Section *s;
2349 /* put dynamic section entries */
2350 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2351 put_dt(dynamic, DT_GNU_HASH, dyninf->gnu_hash->sh_addr);
2352 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2353 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2354 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2355 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2356 #if PTR_SIZE == 8
2357 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2358 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2359 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2360 if (s1->plt && s1->plt->reloc) {
2361 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2362 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2363 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2364 put_dt(dynamic, DT_PLTREL, DT_RELA);
2366 put_dt(dynamic, DT_RELACOUNT, 0);
2367 #else
2368 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2369 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2370 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2371 if (s1->plt && s1->plt->reloc) {
2372 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2373 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2374 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2375 put_dt(dynamic, DT_PLTREL, DT_REL);
2377 put_dt(dynamic, DT_RELCOUNT, 0);
2378 #endif
2379 if (versym_section && verneed_section) {
2380 /* The dynamic linker can not handle VERSYM without VERNEED */
2381 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2382 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2383 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2385 s = have_section(s1, ".preinit_array");
2386 if (s && s->data_offset) {
2387 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2388 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2390 s = have_section(s1, ".init_array");
2391 if (s && s->data_offset) {
2392 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2393 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2395 s = have_section(s1, ".fini_array");
2396 if (s && s->data_offset) {
2397 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2398 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2400 s = have_section(s1, ".init");
2401 if (s && s->data_offset) {
2402 put_dt(dynamic, DT_INIT, s->sh_addr);
2404 s = have_section(s1, ".fini");
2405 if (s && s->data_offset) {
2406 put_dt(dynamic, DT_FINI, s->sh_addr);
2408 if (s1->do_debug)
2409 put_dt(dynamic, DT_DEBUG, 0);
2410 put_dt(dynamic, DT_NULL, 0);
2413 /* Remove gaps between RELX sections.
2414 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2415 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2416 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2417 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2418 static void update_reloc_sections(TCCState *s1, struct dyn_inf *dyninf)
2420 int i;
2421 unsigned long file_offset = 0;
2422 Section *s;
2423 Section *relocplt = s1->plt ? s1->plt->reloc : NULL;
2425 /* dynamic relocation table information, for .dynamic section */
2426 dyninf->rel_addr = dyninf->rel_size = 0;
2428 for(i = 1; i < s1->nb_sections; i++) {
2429 s = s1->sections[i];
2430 if (s->sh_type == SHT_RELX && s != relocplt) {
2431 if (dyninf->rel_size == 0) {
2432 dyninf->rel_addr = s->sh_addr;
2433 file_offset = s->sh_offset;
2435 else {
2436 s->sh_addr = dyninf->rel_addr + dyninf->rel_size;
2437 s->sh_offset = file_offset + dyninf->rel_size;
2439 dyninf->rel_size += s->sh_size;
2444 static int tidy_section_headers(TCCState *s1, int *sec_order);
2445 #endif /* ndef ELF_OBJ_ONLY */
2447 /* Create an ELF file on disk.
2448 This function handle ELF specific layout requirements */
2449 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2450 int file_offset, int *sec_order)
2452 int i, shnum, offset, size, file_type;
2453 Section *s;
2454 ElfW(Ehdr) ehdr;
2455 ElfW(Shdr) shdr, *sh;
2457 file_type = s1->output_type;
2458 shnum = s1->nb_sections;
2460 memset(&ehdr, 0, sizeof(ehdr));
2462 if (phnum > 0) {
2463 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2464 ehdr.e_phnum = phnum;
2465 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2466 #ifndef ELF_OBJ_ONLY
2467 shnum = tidy_section_headers(s1, sec_order);
2468 #endif
2471 /* align to 4 */
2472 file_offset = (file_offset + 3) & -4;
2474 /* fill header */
2475 ehdr.e_ident[0] = ELFMAG0;
2476 ehdr.e_ident[1] = ELFMAG1;
2477 ehdr.e_ident[2] = ELFMAG2;
2478 ehdr.e_ident[3] = ELFMAG3;
2479 ehdr.e_ident[4] = ELFCLASSW;
2480 ehdr.e_ident[5] = ELFDATA2LSB;
2481 ehdr.e_ident[6] = EV_CURRENT;
2483 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2484 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2485 #elif defined TCC_TARGET_ARM && defined TCC_ARM_EABI
2486 ehdr.e_flags = EF_ARM_EABI_VER5;
2487 ehdr.e_flags |= s1->float_abi == ARM_HARD_FLOAT
2488 ? EF_ARM_VFP_FLOAT : EF_ARM_SOFT_FLOAT;
2489 #elif defined TCC_TARGET_ARM
2490 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2491 #elif defined TCC_TARGET_RISCV64
2492 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2493 #endif
2495 if (file_type == TCC_OUTPUT_OBJ) {
2496 ehdr.e_type = ET_REL;
2497 } else {
2498 if (file_type & TCC_OUTPUT_DYN)
2499 ehdr.e_type = ET_DYN;
2500 else
2501 ehdr.e_type = ET_EXEC;
2502 if (s1->elf_entryname)
2503 ehdr.e_entry = get_sym_addr(s1, s1->elf_entryname, 1, 0);
2504 else
2505 ehdr.e_entry = get_sym_addr(s1, "_start", !!(file_type & TCC_OUTPUT_EXE), 0);
2506 if (ehdr.e_entry == (addr_t)-1)
2507 ehdr.e_entry = text_section->sh_addr;
2510 ehdr.e_machine = EM_TCC_TARGET;
2511 ehdr.e_version = EV_CURRENT;
2512 ehdr.e_shoff = file_offset;
2513 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2514 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2515 ehdr.e_shnum = shnum;
2516 ehdr.e_shstrndx = shnum - 1;
2518 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2519 if (phdr)
2520 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2521 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2523 sort_syms(s1, symtab_section);
2525 for(i = 1; i < shnum; i++) {
2526 s = s1->sections[sec_order ? sec_order[i] : i];
2527 if (s->sh_type != SHT_NOBITS) {
2528 while (offset < s->sh_offset) {
2529 fputc(0, f);
2530 offset++;
2532 size = s->sh_size;
2533 if (size)
2534 fwrite(s->data, 1, size, f);
2535 offset += size;
2539 /* output section headers */
2540 while (offset < ehdr.e_shoff) {
2541 fputc(0, f);
2542 offset++;
2545 for(i = 0; i < shnum; i++) {
2546 sh = &shdr;
2547 memset(sh, 0, sizeof(ElfW(Shdr)));
2548 s = s1->sections[i];
2549 if (s) {
2550 sh->sh_name = s->sh_name;
2551 sh->sh_type = s->sh_type;
2552 sh->sh_flags = s->sh_flags;
2553 sh->sh_entsize = s->sh_entsize;
2554 sh->sh_info = s->sh_info;
2555 if (s->link)
2556 sh->sh_link = s->link->sh_num;
2557 sh->sh_addralign = s->sh_addralign;
2558 sh->sh_addr = s->sh_addr;
2559 sh->sh_offset = s->sh_offset;
2560 sh->sh_size = s->sh_size;
2562 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2566 static void tcc_output_binary(TCCState *s1, FILE *f,
2567 const int *sec_order)
2569 Section *s;
2570 int i, offset, size;
2572 offset = 0;
2573 for(i=1;i<s1->nb_sections;i++) {
2574 s = s1->sections[sec_order[i]];
2575 if (s->sh_type != SHT_NOBITS &&
2576 (s->sh_flags & SHF_ALLOC)) {
2577 while (offset < s->sh_offset) {
2578 fputc(0, f);
2579 offset++;
2581 size = s->sh_size;
2582 fwrite(s->data, 1, size, f);
2583 offset += size;
2588 /* Write an elf, coff or "binary" file */
2589 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2590 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2592 int fd, mode, file_type;
2593 FILE *f;
2595 file_type = s1->output_type;
2596 if (file_type == TCC_OUTPUT_OBJ)
2597 mode = 0666;
2598 else
2599 mode = 0777;
2600 unlink(filename);
2601 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2602 if (fd < 0 || (f = fdopen(fd, "wb")) == NULL) {
2603 tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno));
2604 return -1;
2606 if (s1->verbose)
2607 printf("<- %s\n", filename);
2609 #ifdef TCC_TARGET_COFF
2610 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2611 tcc_output_coff(s1, f);
2612 else
2613 #endif
2614 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2615 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2616 else
2617 tcc_output_binary(s1, f, sec_order);
2618 fclose(f);
2620 return 0;
2623 #ifndef ELF_OBJ_ONLY
2624 /* Sort section headers by assigned sh_addr, remove sections
2625 that we aren't going to output. */
2626 static int tidy_section_headers(TCCState *s1, int *sec_order)
2628 int i, nnew, l, *backmap;
2629 Section **snew, *s;
2630 ElfW(Sym) *sym;
2632 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2633 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2634 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2635 s = s1->sections[sec_order[i]];
2636 if (!i || s->sh_name) {
2637 backmap[sec_order[i]] = nnew;
2638 snew[nnew] = s;
2639 ++nnew;
2640 } else {
2641 backmap[sec_order[i]] = 0;
2642 snew[--l] = s;
2645 for (i = 0; i < nnew; i++) {
2646 s = snew[i];
2647 if (s) {
2648 s->sh_num = i;
2649 if (s->sh_type == SHT_RELX)
2650 s->sh_info = backmap[s->sh_info];
2654 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2655 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2656 sym->st_shndx = backmap[sym->st_shndx];
2657 if ( !s1->static_link ) {
2658 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2659 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2660 sym->st_shndx = backmap[sym->st_shndx];
2662 for (i = 0; i < s1->nb_sections; i++)
2663 sec_order[i] = i;
2664 tcc_free(s1->sections);
2665 s1->sections = snew;
2666 tcc_free(backmap);
2667 return nnew;
2670 #ifdef TCC_TARGET_ARM
2671 static void create_arm_attribute_section(TCCState *s1)
2673 // Needed for DLL support.
2674 static const unsigned char arm_attr[] = {
2675 0x41, // 'A'
2676 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2677 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2678 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2679 0x05, 0x36, 0x00, // 'CPU_name', "6"
2680 0x06, 0x06, // 'CPU_arch', 'v6'
2681 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2682 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2683 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2684 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2685 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2686 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2687 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2688 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2689 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2690 0x1a, 0x02, // 'ABI_enum_size', 'int'
2691 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2692 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2694 Section *attr = new_section(s1, ".ARM.attributes", SHT_ARM_ATTRIBUTES, 0);
2695 unsigned char *ptr = section_ptr_add(attr, sizeof(arm_attr));
2696 attr->sh_addralign = 1;
2697 memcpy(ptr, arm_attr, sizeof(arm_attr));
2698 if (s1->float_abi != ARM_HARD_FLOAT) {
2699 ptr[26] = 0x00; // 'FP_arch', 'No'
2700 ptr[41] = 0x1e; // 'ABI_optimization_goals'
2701 ptr[42] = 0x06; // 'Aggressive Debug'
2704 #endif
2706 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2707 static Section *create_bsd_note_section(TCCState *s1,
2708 const char *name,
2709 const char *value)
2711 Section *s = find_section (s1, name);
2713 if (s->data_offset == 0) {
2714 char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
2715 ElfW(Nhdr) *note = (ElfW(Nhdr) *) ptr;
2717 s->sh_type = SHT_NOTE;
2718 note->n_namesz = 8;
2719 note->n_descsz = 4;
2720 note->n_type = ELF_NOTE_OS_GNU;
2721 strcpy (ptr + sizeof(ElfW(Nhdr)), value);
2723 return s;
2725 #endif
2727 static void alloc_sec_names(TCCState *s1, int is_obj);
2729 /* Output an elf, coff or binary file */
2730 /* XXX: suppress unneeded sections */
2731 static int elf_output_file(TCCState *s1, const char *filename)
2733 int i, ret, file_type, file_offset, *sec_order;
2734 struct dyn_inf dyninf = {0};
2735 Section *interp, *dynstr, *dynamic;
2736 int textrel, got_sym, dt_flags_1;
2738 file_type = s1->output_type;
2739 s1->nb_errors = 0;
2740 ret = -1;
2741 interp = dynstr = dynamic = NULL;
2742 sec_order = NULL;
2743 dyninf.roinf = &dyninf._roinf;
2745 #ifdef TCC_TARGET_ARM
2746 create_arm_attribute_section (s1);
2747 #endif
2749 #if TARGETOS_OpenBSD
2750 dyninf.note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
2751 #endif
2753 #if TARGETOS_NetBSD
2754 dyninf.note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD");
2755 #endif
2757 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
2758 dyninf.roinf = NULL;
2759 #endif
2760 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2761 tcc_add_runtime(s1);
2762 resolve_common_syms(s1);
2764 if (!s1->static_link) {
2765 if (file_type & TCC_OUTPUT_EXE) {
2766 char *ptr;
2767 /* allow override the dynamic loader */
2768 const char *elfint = getenv("LD_SO");
2769 if (elfint == NULL)
2770 elfint = DEFAULT_ELFINTERP(s1);
2771 /* add interpreter section only if executable */
2772 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2773 interp->sh_addralign = 1;
2774 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2775 strcpy(ptr, elfint);
2776 dyninf.interp = interp;
2779 /* add dynamic symbol table */
2780 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2781 ".dynstr",
2782 ".hash", SHF_ALLOC);
2783 /* Number of local symbols (readelf complains if not set) */
2784 s1->dynsym->sh_info = 1;
2785 dynstr = s1->dynsym->link;
2786 /* add dynamic section */
2787 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2788 SHF_ALLOC | SHF_WRITE);
2789 dynamic->link = dynstr;
2790 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2792 got_sym = build_got(s1);
2793 if (file_type == TCC_OUTPUT_EXE) {
2794 bind_exe_dynsyms(s1);
2795 if (s1->nb_errors)
2796 goto the_end;
2798 build_got_entries(s1, got_sym);
2799 if (file_type & TCC_OUTPUT_EXE) {
2800 bind_libs_dynsyms(s1);
2801 } else {
2802 /* shared library case: simply export all global symbols */
2803 export_global_syms(s1);
2805 dyninf.gnu_hash = create_gnu_hash(s1);
2806 } else {
2807 build_got_entries(s1, 0);
2809 version_add (s1);
2811 textrel = set_sec_sizes(s1);
2812 alloc_sec_names(s1, 0);
2814 if (!s1->static_link) {
2815 /* add a list of needed dlls */
2816 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2817 DLLReference *dllref = s1->loaded_dlls[i];
2818 if (dllref->level == 0)
2819 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2822 if (s1->rpath)
2823 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2824 put_elf_str(dynstr, s1->rpath));
2826 dt_flags_1 = DF_1_NOW;
2827 if (file_type & TCC_OUTPUT_DYN) {
2828 if (s1->soname)
2829 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2830 /* XXX: currently, since we do not handle PIC code, we
2831 must relocate the readonly segments */
2832 if (textrel)
2833 put_dt(dynamic, DT_TEXTREL, 0);
2834 if (file_type & TCC_OUTPUT_EXE)
2835 dt_flags_1 = DF_1_NOW | DF_1_PIE;
2837 put_dt(dynamic, DT_FLAGS, DF_BIND_NOW);
2838 put_dt(dynamic, DT_FLAGS_1, dt_flags_1);
2839 if (s1->symbolic)
2840 put_dt(dynamic, DT_SYMBOLIC, 0);
2842 dyninf.dynamic = dynamic;
2843 dyninf.dynstr = dynstr;
2844 /* remember offset and reserve space for 2nd call below */
2845 dyninf.data_offset = dynamic->data_offset;
2846 fill_dynamic(s1, &dyninf);
2847 dynamic->sh_size = dynamic->data_offset;
2848 dynstr->sh_size = dynstr->data_offset;
2851 /* this array is used to reorder sections in the output file */
2852 sec_order = tcc_malloc(sizeof(int) * 2 * s1->nb_sections);
2853 /* compute section to program header mapping */
2854 file_offset = layout_sections(s1, sec_order, &dyninf);
2856 if (dynamic) {
2857 /* put in GOT the dynamic section address and relocate PLT */
2858 write32le(s1->got->data, dynamic->sh_addr);
2859 if (file_type == TCC_OUTPUT_EXE
2860 || (RELOCATE_DLLPLT && (file_type & TCC_OUTPUT_DYN)))
2861 relocate_plt(s1);
2862 /* relocate symbols in .dynsym now that final addresses are known */
2863 relocate_syms(s1, s1->dynsym, 2);
2866 /* if building executable or DLL, then relocate each section
2867 except the GOT which is already relocated */
2868 relocate_syms(s1, s1->symtab, 0);
2869 if (s1->nb_errors != 0)
2870 goto the_end;
2871 relocate_sections(s1);
2872 if (dynamic) {
2873 update_reloc_sections (s1, &dyninf);
2874 dynamic->data_offset = dyninf.data_offset;
2875 fill_dynamic(s1, &dyninf);
2877 /* Perform relocation to GOT or PLT entries */
2878 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2879 fill_got(s1);
2880 else if (s1->got)
2881 fill_local_got_entries(s1);
2883 if (dyninf.gnu_hash)
2884 update_gnu_hash(s1, dyninf.gnu_hash);
2886 /* Create the ELF file with name 'filename' */
2887 ret = tcc_write_elf_file(s1, filename, dyninf.phnum, dyninf.phdr, file_offset, sec_order);
2888 the_end:
2889 tcc_free(sec_order);
2890 tcc_free(dyninf.phdr);
2891 return ret;
2893 #endif /* ndef ELF_OBJ_ONLY */
2895 /* Allocate strings for section names */
2896 static void alloc_sec_names(TCCState *s1, int is_obj)
2898 int i;
2899 Section *s, *strsec;
2901 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2902 put_elf_str(strsec, "");
2903 for(i = 1; i < s1->nb_sections; i++) {
2904 s = s1->sections[i];
2905 if (is_obj)
2906 s->sh_size = s->data_offset;
2907 if (s == strsec || s->sh_size || (s->sh_flags & SHF_ALLOC))
2908 s->sh_name = put_elf_str(strsec, s->name);
2910 strsec->sh_size = strsec->data_offset;
2913 /* Output an elf .o file */
2914 static int elf_output_obj(TCCState *s1, const char *filename)
2916 Section *s;
2917 int i, ret, file_offset;
2918 s1->nb_errors = 0;
2919 /* Allocate strings for section names */
2920 alloc_sec_names(s1, 1);
2921 file_offset = sizeof (ElfW(Ehdr));
2922 for(i = 1; i < s1->nb_sections; i++) {
2923 s = s1->sections[i];
2924 file_offset = (file_offset + 15) & -16;
2925 s->sh_offset = file_offset;
2926 if (s->sh_type != SHT_NOBITS)
2927 file_offset += s->sh_size;
2929 /* Create the ELF file with name 'filename' */
2930 ret = tcc_write_elf_file(s1, filename, 0, NULL, file_offset, NULL);
2931 return ret;
2934 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2936 if (s->test_coverage)
2937 tcc_tcov_add_file(s, filename);
2938 if (s->output_type == TCC_OUTPUT_OBJ)
2939 return elf_output_obj(s, filename);
2940 #ifdef TCC_TARGET_PE
2941 return pe_output_file(s, filename);
2942 #elif TCC_TARGET_MACHO
2943 return macho_output_file(s, filename);
2944 #else
2945 return elf_output_file(s, filename);
2946 #endif
2949 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
2950 char *cbuf = buf;
2951 size_t rnum = 0;
2952 while (1) {
2953 ssize_t num = read(fd, cbuf, count-rnum);
2954 if (num < 0) return num;
2955 if (num == 0) return rnum;
2956 rnum += num;
2957 cbuf += num;
2961 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
2963 void *data;
2965 data = tcc_malloc(size);
2966 lseek(fd, file_offset, SEEK_SET);
2967 full_read(fd, data, size);
2968 return data;
2971 typedef struct SectionMergeInfo {
2972 Section *s; /* corresponding existing section */
2973 unsigned long offset; /* offset of the new section in the existing section */
2974 uint8_t new_section; /* true if section 's' was added */
2975 uint8_t link_once; /* true if link once section */
2976 } SectionMergeInfo;
2978 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2980 int size = full_read(fd, h, sizeof *h);
2981 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2982 if (h->e_type == ET_REL)
2983 return AFF_BINTYPE_REL;
2984 if (h->e_type == ET_DYN)
2985 return AFF_BINTYPE_DYN;
2986 } else if (size >= 8) {
2987 if (0 == memcmp(h, ARMAG, 8))
2988 return AFF_BINTYPE_AR;
2989 #ifdef TCC_TARGET_COFF
2990 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2991 return AFF_BINTYPE_C67;
2992 #endif
2994 return 0;
2997 /* load an object file and merge it with current files */
2998 /* XXX: handle correctly stab (debug) info */
2999 ST_FUNC int tcc_load_object_file(TCCState *s1,
3000 int fd, unsigned long file_offset)
3002 ElfW(Ehdr) ehdr;
3003 ElfW(Shdr) *shdr, *sh;
3004 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
3005 char *strsec, *strtab;
3006 int stab_index, stabstr_index;
3007 int *old_to_new_syms;
3008 char *sh_name, *name;
3009 SectionMergeInfo *sm_table, *sm;
3010 ElfW(Sym) *sym, *symtab;
3011 ElfW_Rel *rel;
3012 Section *s;
3014 lseek(fd, file_offset, SEEK_SET);
3015 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
3016 goto fail1;
3017 /* test CPU specific stuff */
3018 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3019 ehdr.e_machine != EM_TCC_TARGET) {
3020 fail1:
3021 tcc_error_noabort("invalid object file");
3022 return -1;
3024 /* read sections */
3025 shdr = load_data(fd, file_offset + ehdr.e_shoff,
3026 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3027 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
3029 /* load section names */
3030 sh = &shdr[ehdr.e_shstrndx];
3031 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3033 /* load symtab and strtab */
3034 old_to_new_syms = NULL;
3035 symtab = NULL;
3036 strtab = NULL;
3037 nb_syms = 0;
3038 seencompressed = 0;
3039 stab_index = stabstr_index = 0;
3041 for(i = 1; i < ehdr.e_shnum; i++) {
3042 sh = &shdr[i];
3043 if (sh->sh_type == SHT_SYMTAB) {
3044 if (symtab) {
3045 tcc_error_noabort("object must contain only one symtab");
3046 fail:
3047 ret = -1;
3048 goto the_end;
3050 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3051 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3052 sm_table[i].s = symtab_section;
3054 /* now load strtab */
3055 sh = &shdr[sh->sh_link];
3056 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3058 if (sh->sh_flags & SHF_COMPRESSED)
3059 seencompressed = 1;
3062 /* now examine each section and try to merge its content with the
3063 ones in memory */
3064 for(i = 1; i < ehdr.e_shnum; i++) {
3065 /* no need to examine section name strtab */
3066 if (i == ehdr.e_shstrndx)
3067 continue;
3068 sh = &shdr[i];
3069 if (sh->sh_type == SHT_RELX)
3070 sh = &shdr[sh->sh_info];
3071 /* ignore sections types we do not handle (plus relocs to those) */
3072 if (sh->sh_type != SHT_PROGBITS &&
3073 #ifdef TCC_ARM_EABI
3074 sh->sh_type != SHT_ARM_EXIDX &&
3075 #endif
3076 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3077 sh->sh_type != SHT_X86_64_UNWIND &&
3078 #endif
3079 sh->sh_type != SHT_NOTE &&
3080 sh->sh_type != SHT_NOBITS &&
3081 sh->sh_type != SHT_PREINIT_ARRAY &&
3082 sh->sh_type != SHT_INIT_ARRAY &&
3083 sh->sh_type != SHT_FINI_ARRAY &&
3084 strcmp(strsec + sh->sh_name, ".stabstr")
3086 continue;
3087 if (seencompressed && 0 == strncmp(strsec + sh->sh_name, ".debug_", 7))
3088 continue;
3090 sh = &shdr[i];
3091 sh_name = strsec + sh->sh_name;
3092 if (sh->sh_addralign < 1)
3093 sh->sh_addralign = 1;
3094 /* find corresponding section, if any */
3095 for(j = 1; j < s1->nb_sections;j++) {
3096 s = s1->sections[j];
3097 if (!strcmp(s->name, sh_name)) {
3098 if (!strncmp(sh_name, ".gnu.linkonce",
3099 sizeof(".gnu.linkonce") - 1)) {
3100 /* if a 'linkonce' section is already present, we
3101 do not add it again. It is a little tricky as
3102 symbols can still be defined in
3103 it. */
3104 sm_table[i].link_once = 1;
3105 goto next;
3107 if (stab_section) {
3108 if (s == stab_section)
3109 stab_index = i;
3110 if (s == stab_section->link)
3111 stabstr_index = i;
3113 goto found;
3116 /* not found: create new section */
3117 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
3118 /* take as much info as possible from the section. sh_link and
3119 sh_info will be updated later */
3120 s->sh_addralign = sh->sh_addralign;
3121 s->sh_entsize = sh->sh_entsize;
3122 sm_table[i].new_section = 1;
3123 found:
3124 if (sh->sh_type != s->sh_type) {
3125 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3126 if (strcmp (s->name, ".eh_frame"))
3127 #endif
3129 tcc_error_noabort("invalid section type");
3130 goto fail;
3133 /* align start of section */
3134 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
3135 if (sh->sh_addralign > s->sh_addralign)
3136 s->sh_addralign = sh->sh_addralign;
3137 sm_table[i].offset = s->data_offset;
3138 sm_table[i].s = s;
3139 /* concatenate sections */
3140 size = sh->sh_size;
3141 if (sh->sh_type != SHT_NOBITS) {
3142 unsigned char *ptr;
3143 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
3144 ptr = section_ptr_add(s, size);
3145 full_read(fd, ptr, size);
3146 } else {
3147 s->data_offset += size;
3149 next: ;
3152 /* gr relocate stab strings */
3153 if (stab_index && stabstr_index) {
3154 Stab_Sym *a, *b;
3155 unsigned o;
3156 s = sm_table[stab_index].s;
3157 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
3158 b = (Stab_Sym *)(s->data + s->data_offset);
3159 o = sm_table[stabstr_index].offset;
3160 while (a < b) {
3161 if (a->n_strx)
3162 a->n_strx += o;
3163 a++;
3167 /* second short pass to update sh_link and sh_info fields of new
3168 sections */
3169 for(i = 1; i < ehdr.e_shnum; i++) {
3170 s = sm_table[i].s;
3171 if (!s || !sm_table[i].new_section)
3172 continue;
3173 sh = &shdr[i];
3174 if (sh->sh_link > 0)
3175 s->link = sm_table[sh->sh_link].s;
3176 if (sh->sh_type == SHT_RELX) {
3177 s->sh_info = sm_table[sh->sh_info].s->sh_num;
3178 /* update backward link */
3179 s1->sections[s->sh_info]->reloc = s;
3183 /* resolve symbols */
3184 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
3186 sym = symtab + 1;
3187 for(i = 1; i < nb_syms; i++, sym++) {
3188 if (sym->st_shndx != SHN_UNDEF &&
3189 sym->st_shndx < SHN_LORESERVE) {
3190 sm = &sm_table[sym->st_shndx];
3191 if (sm->link_once) {
3192 /* if a symbol is in a link once section, we use the
3193 already defined symbol. It is very important to get
3194 correct relocations */
3195 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
3196 name = strtab + sym->st_name;
3197 sym_index = find_elf_sym(symtab_section, name);
3198 if (sym_index)
3199 old_to_new_syms[i] = sym_index;
3201 continue;
3203 /* if no corresponding section added, no need to add symbol */
3204 if (!sm->s)
3205 continue;
3206 /* convert section number */
3207 sym->st_shndx = sm->s->sh_num;
3208 /* offset value */
3209 sym->st_value += sm->offset;
3211 /* add symbol */
3212 name = strtab + sym->st_name;
3213 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
3214 sym->st_info, sym->st_other,
3215 sym->st_shndx, name);
3216 old_to_new_syms[i] = sym_index;
3219 /* third pass to patch relocation entries */
3220 for(i = 1; i < ehdr.e_shnum; i++) {
3221 s = sm_table[i].s;
3222 if (!s)
3223 continue;
3224 sh = &shdr[i];
3225 offset = sm_table[i].offset;
3226 size = sh->sh_size;
3227 switch(s->sh_type) {
3228 case SHT_RELX:
3229 /* take relocation offset information */
3230 offseti = sm_table[sh->sh_info].offset;
3231 for (rel = (ElfW_Rel *) s->data + (offset / sizeof(*rel));
3232 rel < (ElfW_Rel *) s->data + ((offset + size) / sizeof(*rel));
3233 rel++) {
3234 int type;
3235 unsigned sym_index;
3236 /* convert symbol index */
3237 type = ELFW(R_TYPE)(rel->r_info);
3238 sym_index = ELFW(R_SYM)(rel->r_info);
3239 /* NOTE: only one symtab assumed */
3240 if (sym_index >= nb_syms)
3241 goto invalid_reloc;
3242 sym_index = old_to_new_syms[sym_index];
3243 /* ignore link_once in rel section. */
3244 if (!sym_index && !sm_table[sh->sh_info].link_once
3245 #ifdef TCC_TARGET_ARM
3246 && type != R_ARM_V4BX
3247 #elif defined TCC_TARGET_RISCV64
3248 && type != R_RISCV_ALIGN
3249 && type != R_RISCV_RELAX
3250 #endif
3252 invalid_reloc:
3253 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3254 i, strsec + sh->sh_name, (int)rel->r_offset);
3255 goto fail;
3257 rel->r_info = ELFW(R_INFO)(sym_index, type);
3258 /* offset the relocation offset */
3259 rel->r_offset += offseti;
3260 #ifdef TCC_TARGET_ARM
3261 /* Jumps and branches from a Thumb code to a PLT entry need
3262 special handling since PLT entries are ARM code.
3263 Unconditional bl instructions referencing PLT entries are
3264 handled by converting these instructions into blx
3265 instructions. Other case of instructions referencing a PLT
3266 entry require to add a Thumb stub before the PLT entry to
3267 switch to ARM mode. We set bit plt_thumb_stub of the
3268 attribute of a symbol to indicate such a case. */
3269 if (type == R_ARM_THM_JUMP24)
3270 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
3271 #endif
3273 break;
3274 default:
3275 break;
3279 ret = 0;
3280 the_end:
3281 tcc_free(symtab);
3282 tcc_free(strtab);
3283 tcc_free(old_to_new_syms);
3284 tcc_free(sm_table);
3285 tcc_free(strsec);
3286 tcc_free(shdr);
3287 return ret;
3290 typedef struct ArchiveHeader {
3291 char ar_name[16]; /* name of this member */
3292 char ar_date[12]; /* file mtime */
3293 char ar_uid[6]; /* owner uid; printed as decimal */
3294 char ar_gid[6]; /* owner gid; printed as decimal */
3295 char ar_mode[8]; /* file mode, printed as octal */
3296 char ar_size[10]; /* file size, printed as decimal */
3297 char ar_fmag[2]; /* should contain ARFMAG */
3298 } ArchiveHeader;
3300 #define ARFMAG "`\n"
3302 static unsigned long long get_be(const uint8_t *b, int n)
3304 unsigned long long ret = 0;
3305 while (n)
3306 ret = (ret << 8) | *b++, --n;
3307 return ret;
3310 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
3312 char *p, *e;
3313 int len;
3314 lseek(fd, offset, SEEK_SET);
3315 len = full_read(fd, hdr, sizeof(ArchiveHeader));
3316 if (len != sizeof(ArchiveHeader))
3317 return len ? -1 : 0;
3318 p = hdr->ar_name;
3319 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
3320 --e;
3321 *e = '\0';
3322 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
3323 return len;
3326 /* load only the objects which resolve undefined symbols */
3327 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
3329 int i, bound, nsyms, sym_index, len, ret = -1;
3330 unsigned long long off;
3331 uint8_t *data;
3332 const char *ar_names, *p;
3333 const uint8_t *ar_index;
3334 ElfW(Sym) *sym;
3335 ArchiveHeader hdr;
3337 data = tcc_malloc(size);
3338 if (full_read(fd, data, size) != size)
3339 goto the_end;
3340 nsyms = get_be(data, entrysize);
3341 ar_index = data + entrysize;
3342 ar_names = (char *) ar_index + nsyms * entrysize;
3344 do {
3345 bound = 0;
3346 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
3347 Section *s = symtab_section;
3348 sym_index = find_elf_sym(s, p);
3349 if (!sym_index)
3350 continue;
3351 sym = &((ElfW(Sym) *)s->data)[sym_index];
3352 if(sym->st_shndx != SHN_UNDEF)
3353 continue;
3354 off = get_be(ar_index + i * entrysize, entrysize);
3355 len = read_ar_header(fd, off, &hdr);
3356 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
3357 tcc_error_noabort("invalid archive");
3358 goto the_end;
3360 off += len;
3361 if (s1->verbose == 2)
3362 printf(" -> %s\n", hdr.ar_name);
3363 if (tcc_load_object_file(s1, fd, off) < 0)
3364 goto the_end;
3365 ++bound;
3367 } while(bound);
3368 ret = 0;
3369 the_end:
3370 tcc_free(data);
3371 return ret;
3374 /* load a '.a' file */
3375 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
3377 ArchiveHeader hdr;
3378 /* char magic[8]; */
3379 int size, len;
3380 unsigned long file_offset;
3381 ElfW(Ehdr) ehdr;
3383 /* skip magic which was already checked */
3384 /* full_read(fd, magic, sizeof(magic)); */
3385 file_offset = sizeof ARMAG - 1;
3387 for(;;) {
3388 len = read_ar_header(fd, file_offset, &hdr);
3389 if (len == 0)
3390 return 0;
3391 if (len < 0) {
3392 tcc_error_noabort("invalid archive");
3393 return -1;
3395 file_offset += len;
3396 size = strtol(hdr.ar_size, NULL, 0);
3397 /* align to even */
3398 size = (size + 1) & ~1;
3399 if (alacarte) {
3400 /* coff symbol table : we handle it */
3401 if (!strcmp(hdr.ar_name, "/"))
3402 return tcc_load_alacarte(s1, fd, size, 4);
3403 if (!strcmp(hdr.ar_name, "/SYM64/"))
3404 return tcc_load_alacarte(s1, fd, size, 8);
3405 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3406 if (s1->verbose == 2)
3407 printf(" -> %s\n", hdr.ar_name);
3408 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3409 return -1;
3411 file_offset += size;
3415 #ifndef ELF_OBJ_ONLY
3416 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3417 LV, maybe create a new entry for (LIB,VERSION). */
3418 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3420 while (i >= *n) {
3421 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3422 (*lv)[(*n)++] = -1;
3424 if ((*lv)[i] == -1) {
3425 int v, prev_same_lib = -1;
3426 for (v = 0; v < nb_sym_versions; v++) {
3427 if (strcmp(sym_versions[v].lib, lib))
3428 continue;
3429 prev_same_lib = v;
3430 if (!strcmp(sym_versions[v].version, version))
3431 break;
3433 if (v == nb_sym_versions) {
3434 sym_versions = tcc_realloc (sym_versions,
3435 (v + 1) * sizeof(*sym_versions));
3436 sym_versions[v].lib = tcc_strdup(lib);
3437 sym_versions[v].version = tcc_strdup(version);
3438 sym_versions[v].out_index = 0;
3439 sym_versions[v].prev_same_lib = prev_same_lib;
3440 nb_sym_versions++;
3442 (*lv)[i] = v;
3446 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3447 VERNDX. */
3448 static void
3449 set_sym_version(TCCState *s1, int sym_index, int verndx)
3451 if (sym_index >= nb_sym_to_version) {
3452 int newelems = sym_index ? sym_index * 2 : 1;
3453 sym_to_version = tcc_realloc(sym_to_version,
3454 newelems * sizeof(*sym_to_version));
3455 memset(sym_to_version + nb_sym_to_version, -1,
3456 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3457 nb_sym_to_version = newelems;
3459 if (sym_to_version[sym_index] < 0)
3460 sym_to_version[sym_index] = verndx;
3463 struct versym_info {
3464 int nb_versyms;
3465 ElfW(Verdef) *verdef;
3466 ElfW(Verneed) *verneed;
3467 ElfW(Half) *versym;
3468 int nb_local_ver, *local_ver;
3472 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3474 char *lib, *version;
3475 uint32_t next;
3476 int i;
3478 #define DEBUG_VERSION 0
3480 if (v->versym && v->verdef) {
3481 ElfW(Verdef) *vdef = v->verdef;
3482 lib = NULL;
3483 do {
3484 ElfW(Verdaux) *verdaux =
3485 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3487 #if DEBUG_VERSION
3488 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3489 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3490 vdef->vd_hash);
3491 #endif
3492 if (vdef->vd_cnt) {
3493 version = dynstr + verdaux->vda_name;
3495 if (lib == NULL)
3496 lib = version;
3497 else
3498 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3499 lib, version);
3500 #if DEBUG_VERSION
3501 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3502 #endif
3504 next = vdef->vd_next;
3505 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3506 } while (next);
3508 if (v->versym && v->verneed) {
3509 ElfW(Verneed) *vneed = v->verneed;
3510 do {
3511 ElfW(Vernaux) *vernaux =
3512 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3514 lib = dynstr + vneed->vn_file;
3515 #if DEBUG_VERSION
3516 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3517 #endif
3518 for (i = 0; i < vneed->vn_cnt; i++) {
3519 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3520 version = dynstr + vernaux->vna_name;
3521 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3522 lib, version);
3523 #if DEBUG_VERSION
3524 printf (" vernaux(%u): %u %u %s\n",
3525 vernaux->vna_other, vernaux->vna_hash,
3526 vernaux->vna_flags, version);
3527 #endif
3529 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3531 next = vneed->vn_next;
3532 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3533 } while (next);
3536 #if DEBUG_VERSION
3537 for (i = 0; i < v->nb_local_ver; i++) {
3538 if (v->local_ver[i] > 0) {
3539 printf ("%d: lib: %s, version %s\n",
3540 i, sym_versions[v->local_ver[i]].lib,
3541 sym_versions[v->local_ver[i]].version);
3544 #endif
3547 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3548 is referenced by the user (so it should be added as DT_NEEDED in
3549 the generated ELF file) */
3550 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3552 ElfW(Ehdr) ehdr;
3553 ElfW(Shdr) *shdr, *sh, *sh1;
3554 int i, nb_syms, nb_dts, sym_bind, ret = -1;
3555 ElfW(Sym) *sym, *dynsym;
3556 ElfW(Dyn) *dt, *dynamic;
3558 char *dynstr;
3559 int sym_index;
3560 const char *name, *soname;
3561 struct versym_info v;
3563 full_read(fd, &ehdr, sizeof(ehdr));
3565 /* test CPU specific stuff */
3566 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3567 ehdr.e_machine != EM_TCC_TARGET) {
3568 tcc_error_noabort("bad architecture");
3569 return -1;
3572 /* read sections */
3573 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3575 /* load dynamic section and dynamic symbols */
3576 nb_syms = 0;
3577 nb_dts = 0;
3578 dynamic = NULL;
3579 dynsym = NULL; /* avoid warning */
3580 dynstr = NULL; /* avoid warning */
3581 memset(&v, 0, sizeof v);
3583 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3584 switch(sh->sh_type) {
3585 case SHT_DYNAMIC:
3586 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3587 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3588 break;
3589 case SHT_DYNSYM:
3590 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3591 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3592 sh1 = &shdr[sh->sh_link];
3593 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3594 break;
3595 case SHT_GNU_verdef:
3596 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3597 break;
3598 case SHT_GNU_verneed:
3599 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3600 break;
3601 case SHT_GNU_versym:
3602 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3603 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3604 break;
3605 default:
3606 break;
3610 if (!dynamic)
3611 goto the_end;
3613 /* compute the real library name */
3614 soname = tcc_basename(filename);
3615 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
3616 if (dt->d_tag == DT_SONAME)
3617 soname = dynstr + dt->d_un.d_val;
3619 /* if the dll is already loaded, do not load it */
3620 if (tcc_add_dllref(s1, soname, level)->found)
3621 goto ret_success;
3623 if (v.nb_versyms != nb_syms)
3624 tcc_free (v.versym), v.versym = NULL;
3625 else
3626 store_version(s1, &v, dynstr);
3628 /* add dynamic symbols in dynsym_section */
3629 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3630 sym_bind = ELFW(ST_BIND)(sym->st_info);
3631 if (sym_bind == STB_LOCAL)
3632 continue;
3633 name = dynstr + sym->st_name;
3634 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3635 sym->st_info, sym->st_other, sym->st_shndx, name);
3636 if (v.versym) {
3637 ElfW(Half) vsym = v.versym[i];
3638 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3639 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3643 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
3644 if (dt->d_tag == DT_RPATH)
3645 tcc_add_library_path(s1, dynstr + dt->d_un.d_val);
3647 /* load all referenced DLLs */
3648 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3649 switch(dt->d_tag) {
3650 case DT_NEEDED:
3651 name = dynstr + dt->d_un.d_val;
3652 if (tcc_add_dllref(s1, name, -1))
3653 continue;
3654 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3655 tcc_error_noabort("referenced dll '%s' not found", name);
3656 goto the_end;
3661 ret_success:
3662 ret = 0;
3663 the_end:
3664 tcc_free(dynstr);
3665 tcc_free(dynsym);
3666 tcc_free(dynamic);
3667 tcc_free(shdr);
3668 tcc_free(v.local_ver);
3669 tcc_free(v.verdef);
3670 tcc_free(v.verneed);
3671 tcc_free(v.versym);
3672 return ret;
3675 #define LD_TOK_NAME 256
3676 #define LD_TOK_EOF (-1)
3678 static int ld_inp(TCCState *s1)
3680 char b;
3681 if (s1->cc != -1) {
3682 int c = s1->cc;
3683 s1->cc = -1;
3684 return c;
3686 if (1 == read(s1->fd, &b, 1))
3687 return b;
3688 return CH_EOF;
3691 /* return next ld script token */
3692 static int ld_next(TCCState *s1, char *name, int name_size)
3694 int c, d, ch;
3695 char *q;
3697 redo:
3698 ch = ld_inp(s1);
3699 switch(ch) {
3700 case ' ':
3701 case '\t':
3702 case '\f':
3703 case '\v':
3704 case '\r':
3705 case '\n':
3706 goto redo;
3707 case '/':
3708 ch = ld_inp(s1);
3709 if (ch == '*') { /* comment */
3710 for (d = 0;; d = ch) {
3711 ch = ld_inp(s1);
3712 if (ch == CH_EOF || (ch == '/' && d == '*'))
3713 break;
3715 goto redo;
3716 } else {
3717 q = name;
3718 *q++ = '/';
3719 goto parse_name;
3721 break;
3722 case '\\':
3723 /* case 'a' ... 'z': */
3724 case 'a':
3725 case 'b':
3726 case 'c':
3727 case 'd':
3728 case 'e':
3729 case 'f':
3730 case 'g':
3731 case 'h':
3732 case 'i':
3733 case 'j':
3734 case 'k':
3735 case 'l':
3736 case 'm':
3737 case 'n':
3738 case 'o':
3739 case 'p':
3740 case 'q':
3741 case 'r':
3742 case 's':
3743 case 't':
3744 case 'u':
3745 case 'v':
3746 case 'w':
3747 case 'x':
3748 case 'y':
3749 case 'z':
3750 /* case 'A' ... 'z': */
3751 case 'A':
3752 case 'B':
3753 case 'C':
3754 case 'D':
3755 case 'E':
3756 case 'F':
3757 case 'G':
3758 case 'H':
3759 case 'I':
3760 case 'J':
3761 case 'K':
3762 case 'L':
3763 case 'M':
3764 case 'N':
3765 case 'O':
3766 case 'P':
3767 case 'Q':
3768 case 'R':
3769 case 'S':
3770 case 'T':
3771 case 'U':
3772 case 'V':
3773 case 'W':
3774 case 'X':
3775 case 'Y':
3776 case 'Z':
3777 case '_':
3778 case '.':
3779 case '$':
3780 case '~':
3781 q = name;
3782 parse_name:
3783 for(;;) {
3784 if (!((ch >= 'a' && ch <= 'z') ||
3785 (ch >= 'A' && ch <= 'Z') ||
3786 (ch >= '0' && ch <= '9') ||
3787 strchr("/.-_+=$:\\,~", ch)))
3788 break;
3789 if ((q - name) < name_size - 1) {
3790 *q++ = ch;
3792 ch = ld_inp(s1);
3794 s1->cc = ch;
3795 *q = '\0';
3796 c = LD_TOK_NAME;
3797 break;
3798 case CH_EOF:
3799 c = LD_TOK_EOF;
3800 break;
3801 default:
3802 c = ch;
3803 break;
3805 return c;
3808 static int ld_add_file(TCCState *s1, const char filename[])
3810 if (filename[0] == '/') {
3811 if (CONFIG_SYSROOT[0] == '\0'
3812 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3813 return 0;
3814 filename = tcc_basename(filename);
3816 return tcc_add_dll(s1, filename, 0);
3819 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3821 char filename[1024], libname[1024];
3822 int t, group, nblibs = 0, ret = 0;
3823 char **libs = NULL;
3825 group = !strcmp(cmd, "GROUP");
3826 if (!as_needed)
3827 s1->new_undef_sym = 0;
3828 t = ld_next(s1, filename, sizeof(filename));
3829 if (t != '(') {
3830 tcc_error_noabort("( expected");
3831 ret = -1;
3832 goto lib_parse_error;
3834 t = ld_next(s1, filename, sizeof(filename));
3835 for(;;) {
3836 libname[0] = '\0';
3837 if (t == LD_TOK_EOF) {
3838 tcc_error_noabort("unexpected end of file");
3839 ret = -1;
3840 goto lib_parse_error;
3841 } else if (t == ')') {
3842 break;
3843 } else if (t == '-') {
3844 t = ld_next(s1, filename, sizeof(filename));
3845 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3846 tcc_error_noabort("library name expected");
3847 ret = -1;
3848 goto lib_parse_error;
3850 pstrcpy(libname, sizeof libname, &filename[1]);
3851 if (s1->static_link) {
3852 snprintf(filename, sizeof filename, "lib%s.a", libname);
3853 } else {
3854 snprintf(filename, sizeof filename, "lib%s.so", libname);
3856 } else if (t != LD_TOK_NAME) {
3857 tcc_error_noabort("filename expected");
3858 ret = -1;
3859 goto lib_parse_error;
3861 if (!strcmp(filename, "AS_NEEDED")) {
3862 ret = ld_add_file_list(s1, cmd, 1);
3863 if (ret)
3864 goto lib_parse_error;
3865 } else {
3866 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3867 if (!as_needed) {
3868 ret = ld_add_file(s1, filename);
3869 if (ret)
3870 goto lib_parse_error;
3871 if (group) {
3872 /* Add the filename *and* the libname to avoid future conversions */
3873 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3874 if (libname[0] != '\0')
3875 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3879 t = ld_next(s1, filename, sizeof(filename));
3880 if (t == ',') {
3881 t = ld_next(s1, filename, sizeof(filename));
3884 if (group && !as_needed) {
3885 while (s1->new_undef_sym) {
3886 int i;
3887 s1->new_undef_sym = 0;
3888 for (i = 0; i < nblibs; i ++)
3889 ld_add_file(s1, libs[i]);
3892 lib_parse_error:
3893 dynarray_reset(&libs, &nblibs);
3894 return ret;
3897 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3898 files */
3899 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3901 char cmd[64];
3902 char filename[1024];
3903 int t, ret;
3905 s1->fd = fd;
3906 s1->cc = -1;
3907 for(;;) {
3908 t = ld_next(s1, cmd, sizeof(cmd));
3909 if (t == LD_TOK_EOF)
3910 return 0;
3911 else if (t != LD_TOK_NAME)
3912 return -1;
3913 if (!strcmp(cmd, "INPUT") ||
3914 !strcmp(cmd, "GROUP")) {
3915 ret = ld_add_file_list(s1, cmd, 0);
3916 if (ret)
3917 return ret;
3918 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3919 !strcmp(cmd, "TARGET")) {
3920 /* ignore some commands */
3921 t = ld_next(s1, cmd, sizeof(cmd));
3922 if (t != '(') {
3923 tcc_error_noabort("( expected");
3924 return -1;
3926 for(;;) {
3927 t = ld_next(s1, filename, sizeof(filename));
3928 if (t == LD_TOK_EOF) {
3929 tcc_error_noabort("unexpected end of file");
3930 return -1;
3931 } else if (t == ')') {
3932 break;
3935 } else {
3936 return -1;
3939 return 0;
3941 #endif /* !ELF_OBJ_ONLY */