win32: pe dwarf sections & option -g.pdb
[tinycc.git] / tccelf.c
blob2e3d8aca7c4b79d825229388201df981a752486e
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_noabort("%s not defined", name);
510 return (addr_t)-1;
512 return sym->st_value;
515 /* return elf symbol value */
516 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
518 addr_t addr = get_sym_addr(s, name, 0, 1);
519 return addr == -1 ? NULL : (void*)(uintptr_t)addr;
522 /* list elf symbol names and values */
523 ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
524 void (*symbol_cb)(void *ctx, const char *name, const void *val))
526 ElfW(Sym) *sym;
527 Section *symtab;
528 int sym_index, end_sym;
529 const char *name;
530 unsigned char sym_vis, sym_bind;
532 symtab = s->symtab;
533 end_sym = symtab->data_offset / sizeof (ElfSym);
534 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
535 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
536 if (sym->st_value) {
537 name = (char *) symtab->link->data + sym->st_name;
538 sym_bind = ELFW(ST_BIND)(sym->st_info);
539 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
540 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
541 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
546 /* list elf symbol names and values */
547 LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
548 void (*symbol_cb)(void *ctx, const char *name, const void *val))
550 list_elf_symbols(s, ctx, symbol_cb);
553 #ifndef ELF_OBJ_ONLY
554 static void
555 version_add (TCCState *s1)
557 int i;
558 ElfW(Sym) *sym;
559 ElfW(Verneed) *vn = NULL;
560 Section *symtab;
561 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
562 ElfW(Half) *versym;
563 const char *name;
565 if (0 == nb_sym_versions)
566 return;
567 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
568 versym_section->sh_entsize = sizeof(ElfW(Half));
569 versym_section->link = s1->dynsym;
571 /* add needed symbols */
572 symtab = s1->dynsym;
573 end_sym = symtab->data_offset / sizeof (ElfSym);
574 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
575 for (sym_index = 1; sym_index < end_sym; ++sym_index) {
576 int dllindex, verndx;
577 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
578 if (sym->st_shndx != SHN_UNDEF)
579 continue; /* defined symbol doesn't need library version */
580 name = (char *) symtab->link->data + sym->st_name;
581 dllindex = find_elf_sym(s1->dynsymtab_section, name);
582 verndx = (dllindex && dllindex < nb_sym_to_version)
583 ? sym_to_version[dllindex] : -1;
584 if (verndx >= 0) {
585 if (!sym_versions[verndx].out_index)
586 sym_versions[verndx].out_index = nb_versions++;
587 versym[sym_index] = sym_versions[verndx].out_index;
590 /* generate verneed section, but not when it will be empty. Some
591 dynamic linkers look at their contents even when DTVERNEEDNUM and
592 section size is zero. */
593 if (nb_versions > 2) {
594 verneed_section = new_section(s1, ".gnu.version_r",
595 SHT_GNU_verneed, SHF_ALLOC);
596 verneed_section->link = s1->dynsym->link;
597 for (i = nb_sym_versions; i-- > 0;) {
598 struct sym_version *sv = &sym_versions[i];
599 int n_same_libs = 0, prev;
600 size_t vnofs;
601 ElfW(Vernaux) *vna = 0;
602 if (sv->out_index < 1)
603 continue;
605 /* make sure that a DT_NEEDED tag is put */
606 /* abitest-tcc fails on older i386-linux with "ld-linux.so.2" DT_NEEDED
607 ret_int_test... Inconsistency detected by ld.so: dl-minimal.c: 148:
608 realloc: Assertion `ptr == alloc_last_block' failed! */
609 if (strcmp(sv->lib, "ld-linux.so.2"))
610 tcc_add_dllref(s1, sv->lib, 0);
612 vnofs = section_add(verneed_section, sizeof(*vn), 1);
613 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
614 vn->vn_version = 1;
615 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
616 vn->vn_aux = sizeof (*vn);
617 do {
618 prev = sv->prev_same_lib;
619 if (sv->out_index > 0) {
620 vna = section_ptr_add(verneed_section, sizeof(*vna));
621 vna->vna_hash = elf_hash ((const unsigned char *)sv->version);
622 vna->vna_flags = 0;
623 vna->vna_other = sv->out_index;
624 sv->out_index = -2;
625 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
626 vna->vna_next = sizeof (*vna);
627 n_same_libs++;
629 if (prev >= 0)
630 sv = &sym_versions[prev];
631 } while(prev >= 0);
632 vna->vna_next = 0;
633 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
634 vn->vn_cnt = n_same_libs;
635 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
636 nb_entries++;
638 if (vn)
639 vn->vn_next = 0;
640 verneed_section->sh_info = nb_entries;
642 dt_verneednum = nb_entries;
644 #endif /* ndef ELF_OBJ_ONLY */
646 /* add an elf symbol : check if it is already defined and patch
647 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
648 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
649 int info, int other, int shndx, const char *name)
651 TCCState *s1 = s->s1;
652 ElfW(Sym) *esym;
653 int sym_bind, sym_index, sym_type, esym_bind;
654 unsigned char sym_vis, esym_vis, new_vis;
656 sym_bind = ELFW(ST_BIND)(info);
657 sym_type = ELFW(ST_TYPE)(info);
658 sym_vis = ELFW(ST_VISIBILITY)(other);
660 if (sym_bind != STB_LOCAL) {
661 /* we search global or weak symbols */
662 sym_index = find_elf_sym(s, name);
663 if (!sym_index)
664 goto do_def;
665 esym = &((ElfW(Sym) *)s->data)[sym_index];
666 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
667 && esym->st_other == other && esym->st_shndx == shndx)
668 return sym_index;
669 if (esym->st_shndx != SHN_UNDEF) {
670 esym_bind = ELFW(ST_BIND)(esym->st_info);
671 /* propagate the most constraining visibility */
672 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
673 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
674 if (esym_vis == STV_DEFAULT) {
675 new_vis = sym_vis;
676 } else if (sym_vis == STV_DEFAULT) {
677 new_vis = esym_vis;
678 } else {
679 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
681 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
682 | new_vis;
683 if (shndx == SHN_UNDEF) {
684 /* ignore adding of undefined symbol if the
685 corresponding symbol is already defined */
686 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
687 /* global overrides weak, so patch */
688 goto do_patch;
689 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
690 /* weak is ignored if already global */
691 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
692 /* keep first-found weak definition, ignore subsequents */
693 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
694 /* ignore hidden symbols after */
695 } else if ((esym->st_shndx == SHN_COMMON
696 || esym->st_shndx == bss_section->sh_num)
697 && (shndx < SHN_LORESERVE
698 && shndx != bss_section->sh_num)) {
699 /* data symbol gets precedence over common/bss */
700 goto do_patch;
701 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
702 /* data symbol keeps precedence over common/bss */
703 } else if (s->sh_flags & SHF_DYNSYM) {
704 /* we accept that two DLL define the same symbol */
705 } else if (esym->st_other & ST_ASM_SET) {
706 /* If the existing symbol came from an asm .set
707 we can override. */
708 goto do_patch;
709 } else {
710 #if 0
711 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
712 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
713 #endif
714 tcc_error_noabort("'%s' defined twice", name);
716 } else {
717 esym->st_other = other;
718 do_patch:
719 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
720 esym->st_shndx = shndx;
721 s1->new_undef_sym = 1;
722 esym->st_value = value;
723 esym->st_size = size;
725 } else {
726 do_def:
727 sym_index = put_elf_sym(s, value, size,
728 ELFW(ST_INFO)(sym_bind, sym_type), other,
729 shndx, name);
731 return sym_index;
734 /* put relocation */
735 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
736 int type, int symbol, addr_t addend)
738 TCCState *s1 = s->s1;
739 char buf[256];
740 Section *sr;
741 ElfW_Rel *rel;
743 sr = s->reloc;
744 if (!sr) {
745 /* if no relocation section, create it */
746 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
747 /* if the symtab is allocated, then we consider the relocation
748 are also */
749 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
750 sr->sh_entsize = sizeof(ElfW_Rel);
751 sr->link = symtab;
752 sr->sh_info = s->sh_num;
753 s->reloc = sr;
755 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
756 rel->r_offset = offset;
757 rel->r_info = ELFW(R_INFO)(symbol, type);
758 #if SHT_RELX == SHT_RELA
759 rel->r_addend = addend;
760 #endif
761 if (SHT_RELX != SHT_RELA && addend)
762 tcc_error_noabort("non-zero addend on REL architecture");
765 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
766 int type, int symbol)
768 put_elf_reloca(symtab, s, offset, type, symbol, 0);
771 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
773 int n;
774 struct sym_attr *tab;
776 if (index >= s1->nb_sym_attrs) {
777 if (!alloc)
778 return s1->sym_attrs;
779 /* find immediately bigger power of 2 and reallocate array */
780 n = 1;
781 while (index >= n)
782 n *= 2;
783 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
784 s1->sym_attrs = tab;
785 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
786 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
787 s1->nb_sym_attrs = n;
789 return &s1->sym_attrs[index];
792 static void 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_noabort ("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_noabort ("Unknown relocation type for got: %d", type);
1369 continue;
1371 sym_index = ELFW(R_SYM)(rel->r_info);
1372 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1374 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1375 continue;
1378 /* Automatically create PLT/GOT [entry] if it is an undefined
1379 reference (resolved at runtime), or the symbol is absolute,
1380 probably created by tcc_add_symbol, and thus on 64-bit
1381 targets might be too far from application code. */
1382 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1383 if (sym->st_shndx == SHN_UNDEF) {
1384 ElfW(Sym) *esym;
1385 int dynindex;
1386 if (!PCRELATIVE_DLLPLT
1387 && (s1->output_type & TCC_OUTPUT_DYN))
1388 continue;
1389 /* Relocations for UNDEF symbols would normally need
1390 to be transferred into the executable or shared object.
1391 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1392 But TCC doesn't do that (at least for exes), so we
1393 need to resolve all such relocs locally. And that
1394 means PLT slots for functions in DLLs and COPY relocs for
1395 data symbols. COPY relocs were generated in
1396 bind_exe_dynsyms (and the symbol adjusted to be defined),
1397 and for functions we were generated a dynamic symbol
1398 of function type. */
1399 if (s1->dynsym) {
1400 /* dynsym isn't set for -run :-/ */
1401 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1402 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1403 if (dynindex
1404 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1405 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1406 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1407 goto jmp_slot;
1409 } else if (sym->st_shndx == SHN_ABS) {
1410 if (sym->st_value == 0) /* from tcc_add_btstub() */
1411 continue;
1412 #ifndef TCC_TARGET_ARM
1413 if (PTR_SIZE != 8)
1414 continue;
1415 #endif
1416 /* from tcc_add_symbol(): on 64 bit platforms these
1417 need to go through .got */
1418 } else
1419 continue;
1422 #ifdef TCC_TARGET_X86_64
1423 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1424 sym->st_shndx != SHN_UNDEF &&
1425 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1426 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1427 s1->output_type & TCC_OUTPUT_EXE)) {
1428 if (pass != 0)
1429 continue;
1430 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1431 continue;
1433 #endif
1434 reloc_type = code_reloc(type);
1435 if (reloc_type == -1) {
1436 tcc_error_noabort ("Unknown relocation type: %d", type);
1437 continue;
1440 if (reloc_type != 0) {
1441 jmp_slot:
1442 if (pass != 0)
1443 continue;
1444 reloc_type = R_JMP_SLOT;
1445 } else {
1446 if (pass != 1)
1447 continue;
1448 reloc_type = R_GLOB_DAT;
1451 if (!s1->got)
1452 got_sym = build_got(s1);
1454 if (gotplt_entry == BUILD_GOT_ONLY)
1455 continue;
1457 attr = put_got_entry(s1, reloc_type, sym_index);
1459 if (reloc_type == R_JMP_SLOT)
1460 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1463 if (++pass < 2)
1464 goto redo;
1465 /* .rel.plt refers to .got actually */
1466 if (s1->plt && s1->plt->reloc)
1467 s1->plt->reloc->sh_info = s1->got->sh_num;
1468 if (got_sym) /* set size */
1469 ((ElfW(Sym)*)symtab_section->data)[got_sym].st_size = s1->got->data_offset;
1471 #endif /* def NEED_BUILD_GOT */
1473 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
1475 int shn = sec ? sec->sh_num : offs || !name ? SHN_ABS : SHN_UNDEF;
1476 if (sec && offs == -1)
1477 offs = sec->data_offset;
1478 return set_elf_sym(symtab_section, offs, 0,
1479 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1482 static void add_init_array_defines(TCCState *s1, const char *section_name)
1484 Section *s;
1485 addr_t end_offset;
1486 char buf[1024];
1487 s = have_section(s1, section_name);
1488 if (!s || !(s->sh_flags & SHF_ALLOC)) {
1489 end_offset = 0;
1490 s = data_section;
1491 } else {
1492 end_offset = s->data_offset;
1494 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1495 set_global_sym(s1, buf, s, 0);
1496 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1497 set_global_sym(s1, buf, s, end_offset);
1500 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1502 Section *s;
1503 s = find_section(s1, sec);
1504 s->sh_flags = shf_RELRO;
1505 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1506 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1507 section_ptr_add(s, PTR_SIZE);
1510 #ifdef CONFIG_TCC_BCHECK
1511 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1513 if (0 == s1->do_bounds_check)
1514 return;
1515 section_ptr_add(bounds_section, sizeof(addr_t));
1517 #endif
1519 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1520 a dynamic symbol to allow so's to have one each with a different value. */
1521 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1523 int c = find_elf_sym(s1->symtab, name);
1524 if (c) {
1525 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1526 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1527 esym->st_value = offset;
1528 esym->st_shndx = s->sh_num;
1532 /* avoid generating debug/test_coverage code for stub functions */
1533 static void tcc_compile_string_no_debug(TCCState *s, const char *str)
1535 int save_do_debug = s->do_debug;
1536 int save_test_coverage = s->test_coverage;
1538 s->do_debug = 0;
1539 s->test_coverage = 0;
1540 tcc_compile_string(s, str);
1541 s->do_debug = save_do_debug;
1542 s->test_coverage = save_test_coverage;
1545 #ifdef CONFIG_TCC_BACKTRACE
1546 static void put_ptr(TCCState *s1, Section *s, int offs)
1548 int c;
1549 c = set_global_sym(s1, NULL, s, offs);
1550 s = data_section;
1551 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1552 section_ptr_add(s, PTR_SIZE);
1555 ST_FUNC void tcc_add_btstub(TCCState *s1)
1557 Section *s;
1558 int n, o;
1559 CString cstr;
1561 s = data_section;
1562 /* Align to PTR_SIZE */
1563 section_ptr_add(s, -s->data_offset & (PTR_SIZE - 1));
1564 o = s->data_offset;
1565 /* create (part of) a struct rt_context (see tccrun.c) */
1566 if (s1->dwarf) {
1567 put_ptr(s1, dwarf_line_section, 0);
1568 put_ptr(s1, dwarf_line_section, -1);
1569 if (s1->dwarf >= 5)
1570 put_ptr(s1, dwarf_line_str_section, 0);
1571 else
1572 put_ptr(s1, dwarf_str_section, 0);
1574 else
1576 put_ptr(s1, stab_section, 0);
1577 put_ptr(s1, stab_section, -1);
1578 put_ptr(s1, stab_section->link, 0);
1580 *(addr_t *)section_ptr_add(s, PTR_SIZE) = s1->dwarf;
1581 /* skip esym_start/esym_end/elf_str (not loaded) */
1582 section_ptr_add(s, 3 * PTR_SIZE);
1583 /* prog_base : local nameless symbol with offset 0 at SHN_ABS */
1584 put_ptr(s1, NULL, 0);
1585 #if defined TCC_TARGET_MACHO
1586 /* adjust for __PAGEZERO */
1587 if (s1->dwarf == 0 && s1->output_type == TCC_OUTPUT_EXE)
1588 write64le(data_section->data + data_section->data_offset - PTR_SIZE,
1589 (uint64_t)1 << 32);
1590 #endif
1591 n = 2 * PTR_SIZE;
1592 #ifdef CONFIG_TCC_BCHECK
1593 if (s1->do_bounds_check) {
1594 put_ptr(s1, bounds_section, 0);
1595 n -= PTR_SIZE;
1597 #endif
1598 section_ptr_add(s, n);
1599 cstr_new(&cstr);
1600 cstr_printf(&cstr,
1601 "extern void __bt_init(),__bt_exit(),__bt_init_dll();"
1602 "static void *__rt_info[];"
1603 "__attribute__((constructor)) static void __bt_init_rt(){");
1604 #ifdef TCC_TARGET_PE
1605 if (s1->output_type == TCC_OUTPUT_DLL)
1606 #ifdef CONFIG_TCC_BCHECK
1607 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1608 #else
1609 cstr_printf(&cstr, "__bt_init_dll(0);");
1610 #endif
1611 #endif
1612 cstr_printf(&cstr, "__bt_init(__rt_info,%d);}",
1613 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1614 /* In case dlcose is called by application */
1615 cstr_printf(&cstr,
1616 "__attribute__((destructor)) static void __bt_exit_rt(){"
1617 "__bt_exit(__rt_info);}");
1618 tcc_compile_string_no_debug(s1, cstr.data);
1619 cstr_free(&cstr);
1620 set_local_sym(s1, &"___rt_info"[!s1->leading_underscore], s, o);
1622 #endif /* def CONFIG_TCC_BACKTRACE */
1624 static void tcc_tcov_add_file(TCCState *s1, const char *filename)
1626 CString cstr;
1627 void *ptr;
1628 char wd[1024];
1630 if (tcov_section == NULL)
1631 return;
1632 section_ptr_add(tcov_section, 1);
1633 write32le (tcov_section->data, tcov_section->data_offset);
1635 cstr_new (&cstr);
1636 if (filename[0] == '/')
1637 cstr_printf (&cstr, "%s.tcov", filename);
1638 else {
1639 getcwd (wd, sizeof(wd));
1640 cstr_printf (&cstr, "%s/%s.tcov", wd, filename);
1642 ptr = section_ptr_add(tcov_section, cstr.size + 1);
1643 strcpy((char *)ptr, cstr.data);
1644 unlink((char *)ptr);
1645 #ifdef _WIN32
1646 normalize_slashes((char *)ptr);
1647 #endif
1648 cstr_free (&cstr);
1650 cstr_new(&cstr);
1651 cstr_printf(&cstr,
1652 "extern char *__tcov_data[];"
1653 "extern void __store_test_coverage ();"
1654 "__attribute__((destructor)) static void __tcov_exit() {"
1655 "__store_test_coverage(__tcov_data);"
1656 "}");
1657 tcc_compile_string_no_debug(s1, cstr.data);
1658 cstr_free(&cstr);
1659 set_local_sym(s1, &"___tcov_data"[!s1->leading_underscore], tcov_section, 0);
1662 #ifndef TCC_TARGET_PE
1663 /* add tcc runtime libraries */
1664 ST_FUNC void tcc_add_runtime(TCCState *s1)
1666 s1->filetype = 0;
1668 #ifdef CONFIG_TCC_BCHECK
1669 tcc_add_bcheck(s1);
1670 #endif
1671 tcc_add_pragma_libs(s1);
1673 /* add libc */
1674 if (!s1->nostdlib) {
1675 int lpthread = s1->option_pthread;
1677 #ifdef CONFIG_TCC_BCHECK
1678 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1679 tcc_add_support(s1, "bcheck.o");
1680 # if !(TARGETOS_OpenBSD || TARGETOS_NetBSD)
1681 tcc_add_library_err(s1, "dl");
1682 # endif
1683 lpthread = 1;
1685 #endif
1686 #ifdef CONFIG_TCC_BACKTRACE
1687 if (s1->do_backtrace) {
1688 if (s1->output_type & TCC_OUTPUT_EXE)
1689 tcc_add_support(s1, "bt-exe.o");
1690 if (s1->output_type != TCC_OUTPUT_DLL)
1691 tcc_add_support(s1, "bt-log.o");
1692 if (s1->output_type != TCC_OUTPUT_MEMORY)
1693 tcc_add_btstub(s1);
1695 #endif
1696 if (lpthread)
1697 tcc_add_library_err(s1, "pthread");
1698 tcc_add_library_err(s1, "c");
1699 #ifdef TCC_LIBGCC
1700 if (!s1->static_link) {
1701 if (TCC_LIBGCC[0] == '/')
1702 tcc_add_file(s1, TCC_LIBGCC);
1703 else
1704 tcc_add_dll(s1, TCC_LIBGCC, 0);
1706 #endif
1707 #if defined TCC_TARGET_ARM && TARGETOS_FreeBSD
1708 tcc_add_library_err(s1, "gcc_s"); // unwind code
1709 #endif
1710 if (TCC_LIBTCC1[0])
1711 tcc_add_support(s1, TCC_LIBTCC1);
1713 /* add crt end if not memory output */
1714 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1715 #if defined TCC_TARGET_MACHO
1716 /* nothing to do */
1717 #elif TARGETOS_FreeBSD || TARGETOS_NetBSD
1718 if (s1->output_type & TCC_OUTPUT_DYN)
1719 tcc_add_crt(s1, "crtendS.o");
1720 else
1721 tcc_add_crt(s1, "crtend.o");
1722 tcc_add_crt(s1, "crtn.o");
1723 #elif TARGETOS_OpenBSD
1724 if (s1->output_type == TCC_OUTPUT_DLL)
1725 tcc_add_crt(s1, "crtendS.o");
1726 else
1727 tcc_add_crt(s1, "crtend.o");
1728 #elif TARGETOS_ANDROID
1729 if (s1->output_type == TCC_OUTPUT_DLL)
1730 tcc_add_crt(s1, "crtend_so.o");
1731 else
1732 tcc_add_crt(s1, "crtend_android.o");
1733 #else
1734 tcc_add_crt(s1, "crtn.o");
1735 #endif
1739 #endif /* ndef TCC_TARGET_PE */
1741 /* add various standard linker symbols (must be done after the
1742 sections are filled (for example after allocating common
1743 symbols)) */
1744 static void tcc_add_linker_symbols(TCCState *s1)
1746 char buf[1024];
1747 int i;
1748 Section *s;
1750 set_global_sym(s1, "_etext", text_section, -1);
1751 set_global_sym(s1, "_edata", data_section, -1);
1752 set_global_sym(s1, "_end", bss_section, -1);
1753 #if TARGETOS_OpenBSD
1754 set_global_sym(s1, "__executable_start", NULL, ELF_START_ADDR);
1755 #endif
1756 #ifdef TCC_TARGET_RISCV64
1757 /* XXX should be .sdata+0x800, not .data+0x800 */
1758 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1759 #endif
1760 /* horrible new standard ldscript defines */
1761 add_init_array_defines(s1, ".preinit_array");
1762 add_init_array_defines(s1, ".init_array");
1763 add_init_array_defines(s1, ".fini_array");
1764 /* add start and stop symbols for sections whose name can be
1765 expressed in C */
1766 for(i = 1; i < s1->nb_sections; i++) {
1767 s = s1->sections[i];
1768 if ((s->sh_flags & SHF_ALLOC)
1769 && (s->sh_type == SHT_PROGBITS
1770 || s->sh_type == SHT_STRTAB)) {
1771 const char *p;
1772 /* check if section name can be expressed in C */
1773 p = s->name;
1774 for(;;) {
1775 int c = *p;
1776 if (!c)
1777 break;
1778 if (!isid(c) && !isnum(c))
1779 goto next_sec;
1780 p++;
1782 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1783 set_global_sym(s1, buf, s, 0);
1784 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1785 set_global_sym(s1, buf, s, -1);
1787 next_sec: ;
1791 ST_FUNC void resolve_common_syms(TCCState *s1)
1793 ElfW(Sym) *sym;
1795 /* Allocate common symbols in BSS. */
1796 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1797 if (sym->st_shndx == SHN_COMMON) {
1798 /* symbol alignment is in st_value for SHN_COMMONs */
1799 sym->st_value = section_add(bss_section, sym->st_size,
1800 sym->st_value);
1801 sym->st_shndx = bss_section->sh_num;
1805 /* Now assign linker provided symbols their value. */
1806 tcc_add_linker_symbols(s1);
1809 #ifndef ELF_OBJ_ONLY
1810 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1812 int sym_index = ELFW(R_SYM) (rel->r_info);
1813 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1814 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1815 unsigned offset = attr->got_offset;
1817 if (0 == offset)
1818 return;
1819 section_reserve(s1->got, offset + PTR_SIZE);
1820 #if PTR_SIZE == 8
1821 write64le(s1->got->data + offset, sym->st_value);
1822 #else
1823 write32le(s1->got->data + offset, sym->st_value);
1824 #endif
1827 /* Perform relocation to GOT or PLT entries */
1828 ST_FUNC void fill_got(TCCState *s1)
1830 Section *s;
1831 ElfW_Rel *rel;
1832 int i;
1834 for(i = 1; i < s1->nb_sections; i++) {
1835 s = s1->sections[i];
1836 if (s->sh_type != SHT_RELX)
1837 continue;
1838 /* no need to handle got relocations */
1839 if (s->link != symtab_section)
1840 continue;
1841 for_each_elem(s, 0, rel, ElfW_Rel) {
1842 switch (ELFW(R_TYPE) (rel->r_info)) {
1843 case R_X86_64_GOT32:
1844 case R_X86_64_GOTPCREL:
1845 case R_X86_64_GOTPCRELX:
1846 case R_X86_64_REX_GOTPCRELX:
1847 case R_X86_64_PLT32:
1848 fill_got_entry(s1, rel);
1849 break;
1855 /* See put_got_entry for a description. This is the second stage
1856 where GOT references to local defined symbols are rewritten. */
1857 static void fill_local_got_entries(TCCState *s1)
1859 ElfW_Rel *rel;
1860 if (!s1->got->reloc)
1861 return;
1862 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1863 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1864 int sym_index = ELFW(R_SYM) (rel->r_info);
1865 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1866 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1867 unsigned offset = attr->got_offset;
1868 if (offset != rel->r_offset - s1->got->sh_addr)
1869 tcc_error_noabort("fill_local_got_entries: huh?");
1870 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1871 #if SHT_RELX == SHT_RELA
1872 rel->r_addend = sym->st_value;
1873 #else
1874 /* All our REL architectures also happen to be 32bit LE. */
1875 write32le(s1->got->data + offset, sym->st_value);
1876 #endif
1881 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1882 in shared libraries */
1883 static void bind_exe_dynsyms(TCCState *s1, int is_PIE)
1885 const char *name;
1886 int sym_index, index;
1887 ElfW(Sym) *sym, *esym;
1888 int type;
1890 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1891 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1892 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1893 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1894 if (sym->st_shndx == SHN_UNDEF) {
1895 name = (char *) symtab_section->link->data + sym->st_name;
1896 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1897 if (sym_index) {
1898 if (is_PIE)
1899 continue;
1900 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1901 type = ELFW(ST_TYPE)(esym->st_info);
1902 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1903 /* Indirect functions shall have STT_FUNC type in executable
1904 * dynsym section. Indeed, a dlsym call following a lazy
1905 * resolution would pick the symbol value from the
1906 * executable dynsym entry which would contain the address
1907 * of the function wanted by the caller of dlsym instead of
1908 * the address of the function that would return that
1909 * address */
1910 int dynindex
1911 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1912 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1913 name);
1914 int index = sym - (ElfW(Sym) *) symtab_section->data;
1915 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1916 } else if (type == STT_OBJECT) {
1917 unsigned long offset;
1918 ElfW(Sym) *dynsym;
1919 offset = bss_section->data_offset;
1920 /* XXX: which alignment ? */
1921 offset = (offset + 16 - 1) & -16;
1922 set_elf_sym (s1->symtab, offset, esym->st_size,
1923 esym->st_info, 0, bss_section->sh_num, name);
1924 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1925 esym->st_info, 0, bss_section->sh_num,
1926 name);
1928 /* Ensure R_COPY works for weak symbol aliases */
1929 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1930 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1931 if ((dynsym->st_value == esym->st_value)
1932 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1933 char *dynname = (char *) s1->dynsymtab_section->link->data
1934 + dynsym->st_name;
1935 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1936 dynsym->st_info, 0,
1937 bss_section->sh_num, dynname);
1938 break;
1943 put_elf_reloc(s1->dynsym, bss_section,
1944 offset, R_COPY, index);
1945 offset += esym->st_size;
1946 bss_section->data_offset = offset;
1948 } else {
1949 /* STB_WEAK undefined symbols are accepted */
1950 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1951 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1952 !strcmp(name, "_fp_hw")) {
1953 } else {
1954 tcc_error_noabort("undefined symbol '%s'", name);
1961 /* Bind symbols of libraries: export all non local symbols of executable that
1962 are referenced by shared libraries. The reason is that the dynamic loader
1963 search symbol first in executable and then in libraries. Therefore a
1964 reference to a symbol already defined by a library can still be resolved by
1965 a symbol in the executable. With -rdynamic, export all defined symbols */
1966 static void bind_libs_dynsyms(TCCState *s1)
1968 const char *name;
1969 int dynsym_index;
1970 ElfW(Sym) *sym, *esym;
1972 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1973 name = (char *)symtab_section->link->data + sym->st_name;
1974 dynsym_index = find_elf_sym(s1->dynsymtab_section, name);
1975 if (sym->st_shndx != SHN_UNDEF) {
1976 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL
1977 && (dynsym_index || s1->rdynamic))
1978 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1979 sym->st_info, 0, sym->st_shndx, name);
1980 } else if (dynsym_index) {
1981 esym = (ElfW(Sym) *)s1->dynsymtab_section->data + dynsym_index;
1982 if (esym->st_shndx == SHN_UNDEF) {
1983 /* weak symbols can stay undefined */
1984 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1985 tcc_warning("undefined dynamic symbol '%s'", name);
1991 /* Export all non local symbols. This is used by shared libraries so that the
1992 non local symbols they define can resolve a reference in another shared
1993 library or in the executable. Correspondingly, it allows undefined local
1994 symbols to be resolved by other shared libraries or by the executable. */
1995 static void export_global_syms(TCCState *s1)
1997 int dynindex, index;
1998 const char *name;
1999 ElfW(Sym) *sym;
2000 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
2001 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2002 name = (char *) symtab_section->link->data + sym->st_name;
2003 dynindex = set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
2004 sym->st_info, 0, sym->st_shndx, name);
2005 index = sym - (ElfW(Sym) *) symtab_section->data;
2006 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
2011 /* decide if an unallocated section should be output. */
2012 static int set_sec_sizes(TCCState *s1)
2014 int i;
2015 Section *s;
2016 int textrel = 0;
2017 int file_type = s1->output_type;
2019 /* Allocate strings for section names */
2020 for(i = 1; i < s1->nb_sections; i++) {
2021 s = s1->sections[i];
2022 if (s->sh_type == SHT_RELX && !(s->sh_flags & SHF_ALLOC)) {
2023 /* when generating a DLL, we include relocations but
2024 we may patch them */
2025 if ((file_type & TCC_OUTPUT_DYN)
2026 && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) {
2027 int count = prepare_dynamic_rel(s1, s);
2028 if (count) {
2029 /* allocate the section */
2030 s->sh_flags |= SHF_ALLOC;
2031 s->sh_size = count * sizeof(ElfW_Rel);
2032 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
2033 textrel += count;
2036 } else if ((s->sh_flags & SHF_ALLOC)
2037 #ifdef TCC_TARGET_ARM
2038 || s->sh_type == SHT_ARM_ATTRIBUTES
2039 #endif
2040 || s1->do_debug) {
2041 s->sh_size = s->data_offset;
2044 #ifdef TCC_TARGET_ARM
2045 /* XXX: Suppress stack unwinding section. */
2046 if (s->sh_type == SHT_ARM_EXIDX) {
2047 s->sh_flags = 0;
2048 s->sh_size = 0;
2050 #endif
2053 return textrel;
2056 /* various data used under elf_output_file() */
2057 struct dyn_inf {
2058 Section *dynamic;
2059 Section *dynstr;
2060 struct {
2061 /* Info to be copied in dynamic section */
2062 unsigned long data_offset;
2063 addr_t rel_addr;
2064 addr_t rel_size;
2067 ElfW(Phdr) *phdr;
2068 int phnum;
2069 Section *interp;
2070 Section *note;
2071 Section *gnu_hash;
2073 /* read only segment mapping for GNU_RELRO */
2074 Section _roinf, *roinf;
2077 /* Decide the layout of sections loaded in memory. This must be done before
2078 program headers are filled since they contain info about the layout.
2079 We do the following ordering: interp, symbol tables, relocations, progbits,
2080 nobits */
2081 static int sort_sections(TCCState *s1, int *sec_order, Section *interp)
2083 Section *s;
2084 int i, j, k, f, f0, n;
2085 int nb_sections = s1->nb_sections;
2086 int *sec_cls = sec_order + nb_sections;
2088 for (i = 1; i < nb_sections; i++) {
2089 s = s1->sections[i];
2090 if (s->sh_flags & SHF_ALLOC) {
2091 j = 0x100;
2092 if (s->sh_flags & SHF_WRITE)
2093 j = 0x200;
2094 if (s->sh_flags & SHF_TLS)
2095 j += 0x200;
2096 } else if (s->sh_name) {
2097 j = 0x700;
2098 } else {
2099 j = 0x900; /* no sh_name: won't go to file */
2101 if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_DYNSYM) {
2102 k = 0x10;
2103 } else if (s->sh_type == SHT_STRTAB && strcmp(s->name, ".stabstr")) {
2104 k = 0x11;
2105 if (i == nb_sections - 1) /* ".shstrtab" assumed to remain last */
2106 k = 0xff;
2107 } else if (s->sh_type == SHT_HASH || s->sh_type == SHT_GNU_HASH) {
2108 k = 0x12;
2109 } else if (s->sh_type == SHT_RELX) {
2110 k = 0x20;
2111 if (s1->plt && s == s1->plt->reloc)
2112 k = 0x21;
2113 } else if (s->sh_type == SHT_PREINIT_ARRAY) {
2114 k = 0x41;
2115 } else if (s->sh_type == SHT_INIT_ARRAY) {
2116 k = 0x42;
2117 } else if (s->sh_type == SHT_FINI_ARRAY) {
2118 k = 0x43;
2119 #ifdef CONFIG_TCC_BCHECK
2120 } else if (s == bounds_section || s == lbounds_section) {
2121 k = 0x44;
2122 #endif
2123 } else if (s == rodata_section || 0 == strcmp(s->name, ".data.rel.ro")) {
2124 k = 0x45;
2125 } else if (s->sh_type == SHT_DYNAMIC) {
2126 k = 0x46;
2127 } else if (s == s1->got) {
2128 k = 0x47; /* .got as RELRO needs BIND_NOW in DT_FLAGS */
2129 } else {
2130 k = 0x50;
2131 if (s->sh_type == SHT_NOTE)
2132 k = 0x60;
2133 if (s->sh_flags & SHF_EXECINSTR)
2134 k = 0x70;
2135 if (s->sh_type == SHT_NOBITS)
2136 k = 0x80;
2137 if (s == interp)
2138 k = 0x00;
2140 k += j;
2142 for (n = i; n > 1 && k < (f = sec_cls[n - 1]); --n)
2143 sec_cls[n] = f, sec_order[n] = sec_order[n - 1];
2144 sec_cls[n] = k, sec_order[n] = i;
2146 sec_order[0] = 0;
2148 /* count PT_LOAD headers needed */
2149 n = f0 = 0;
2150 for (i = 1; i < nb_sections; i++) {
2151 s = s1->sections[sec_order[i]];
2152 k = sec_cls[i];
2153 f = 0;
2154 if (k < 0x700) {
2155 f = s->sh_flags & (SHF_ALLOC|SHF_WRITE|SHF_EXECINSTR|SHF_TLS);
2156 #if TARGETOS_NetBSD
2157 /* NetBSD only supports 2 PT_LOAD sections.
2158 See: https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */
2159 if ((f & SHF_WRITE) == 0) f |= SHF_EXECINSTR;
2160 #else
2161 if ((k & 0xfff0) == 0x240) /* RELRO sections */
2162 f |= 1<<4;
2163 #endif
2164 if (f != f0) /* start new header when flags changed or relro */
2165 f0 = f, ++n, f |= 1<<8;
2167 sec_cls[i] = f;
2168 //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);
2170 return n;
2173 static ElfW(Phdr) *fill_phdr(ElfW(Phdr) *ph, int type, Section *s)
2175 if (s) {
2176 ph->p_offset = s->sh_offset;
2177 ph->p_vaddr = s->sh_addr;
2178 ph->p_filesz = s->sh_size;
2179 ph->p_align = s->sh_addralign;
2181 ph->p_type = type;
2182 ph->p_flags = PF_R;
2183 ph->p_paddr = ph->p_vaddr;
2184 ph->p_memsz = ph->p_filesz;
2185 return ph;
2188 /* Assign sections to segments and decide how are sections laid out when loaded
2189 in memory. This function also fills corresponding program headers. */
2190 static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
2192 Section *s;
2193 addr_t addr, tmp, align, s_align, base;
2194 ElfW(Phdr) *ph = NULL;
2195 int i, f, n, phnum, phfill;
2196 int file_offset;
2198 /* compute number of program headers */
2199 phnum = sort_sections(s1, sec_order, d->interp);
2200 phfill = 0; /* set to 1 to have dll's with a PT_PHDR */
2201 if (d->interp)
2202 phfill = 2;
2203 phnum += phfill;
2204 if (d->note)
2205 ++phnum;
2206 if (d->dynamic)
2207 ++phnum;
2208 if (d->roinf)
2209 ++phnum;
2210 d->phnum = phnum;
2211 d->phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2213 file_offset = 0;
2214 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2215 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2217 s_align = ELF_PAGE_SIZE;
2218 if (s1->section_align)
2219 s_align = s1->section_align;
2221 addr = ELF_START_ADDR;
2222 if (s1->output_type & TCC_OUTPUT_DYN)
2223 addr = 0;
2225 if (s1->has_text_addr) {
2226 addr = s1->text_addr;
2227 if (0) {
2228 int a_offset, p_offset;
2229 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
2230 ELF_PAGE_SIZE */
2231 a_offset = (int) (addr & (s_align - 1));
2232 p_offset = file_offset & (s_align - 1);
2233 if (a_offset < p_offset)
2234 a_offset += s_align;
2235 file_offset += (a_offset - p_offset);
2238 base = addr;
2239 /* compute address after headers */
2240 addr = addr + (file_offset & (s_align - 1));
2242 n = 0;
2243 for(i = 1; i < s1->nb_sections; i++) {
2244 s = s1->sections[sec_order[i]];
2245 f = sec_order[i + s1->nb_sections];
2246 align = s->sh_addralign - 1;
2248 if (f == 0) { /* no alloc */
2249 file_offset = (file_offset + align) & ~align;
2250 s->sh_offset = file_offset;
2251 if (s->sh_type != SHT_NOBITS)
2252 file_offset += s->sh_size;
2253 continue;
2256 if ((f & 1<<8) && n) {
2257 /* different rwx section flags */
2258 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
2259 /* if in the middle of a page, w e duplicate the page in
2260 memory so that one copy is RX and the other is RW */
2261 if ((addr & (s_align - 1)) != 0)
2262 addr += s_align;
2263 } else {
2264 align = s_align - 1;
2268 tmp = addr;
2269 addr = (addr + align) & ~align;
2270 file_offset += (int)(addr - tmp);
2271 s->sh_offset = file_offset;
2272 s->sh_addr = addr;
2274 if (f & 1<<8) {
2275 /* set new program header */
2276 ph = &d->phdr[phfill + n];
2277 ph->p_type = PT_LOAD;
2278 ph->p_align = s_align;
2279 ph->p_flags = PF_R;
2280 if (f & SHF_WRITE)
2281 ph->p_flags |= PF_W;
2282 if (f & SHF_EXECINSTR)
2283 ph->p_flags |= PF_X;
2284 if (f & SHF_TLS) {
2285 ph->p_type = PT_TLS;
2286 ph->p_align = align + 1;
2289 ph->p_offset = file_offset;
2290 ph->p_vaddr = addr;
2291 if (n == 0) {
2292 /* Make the first PT_LOAD segment include the program
2293 headers itself (and the ELF header as well), it'll
2294 come out with same memory use but will make various
2295 tools like binutils strip work better. */
2296 ph->p_offset = 0;
2297 ph->p_vaddr = base;
2299 ph->p_paddr = ph->p_vaddr;
2300 ++n;
2303 if (f & 1<<4) {
2304 Section *roinf = &d->_roinf;
2305 if (roinf->sh_size == 0) {
2306 roinf->sh_offset = s->sh_offset;
2307 roinf->sh_addr = s->sh_addr;
2308 roinf->sh_addralign = 1;
2310 roinf->sh_size = (addr - roinf->sh_addr) + s->sh_size;
2313 addr += s->sh_size;
2314 if (s->sh_type != SHT_NOBITS)
2315 file_offset += s->sh_size;
2317 ph->p_filesz = file_offset - ph->p_offset;
2318 ph->p_memsz = addr - ph->p_vaddr;
2321 /* Fill other headers */
2322 if (d->note)
2323 fill_phdr(++ph, PT_NOTE, d->note);
2324 if (d->dynamic)
2325 fill_phdr(++ph, PT_DYNAMIC, d->dynamic)->p_flags |= PF_W;
2326 if (d->roinf)
2327 fill_phdr(++ph, PT_GNU_RELRO, d->roinf)->p_flags |= PF_W;
2328 if (d->interp)
2329 fill_phdr(&d->phdr[1], PT_INTERP, d->interp);
2330 if (phfill) {
2331 ph = &d->phdr[0];
2332 ph->p_offset = sizeof(ElfW(Ehdr));
2333 ph->p_vaddr = base + ph->p_offset;
2334 ph->p_filesz = phnum * sizeof(ElfW(Phdr));
2335 ph->p_align = 4;
2336 fill_phdr(ph, PT_PHDR, NULL);
2338 return file_offset;
2341 /* put dynamic tag */
2342 static void put_dt(Section *dynamic, int dt, addr_t val)
2344 ElfW(Dyn) *dyn;
2345 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
2346 dyn->d_tag = dt;
2347 dyn->d_un.d_val = val;
2350 /* Fill the dynamic section with tags describing the address and size of
2351 sections */
2352 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2354 Section *dynamic = dyninf->dynamic;
2355 Section *s;
2357 /* put dynamic section entries */
2358 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2359 put_dt(dynamic, DT_GNU_HASH, dyninf->gnu_hash->sh_addr);
2360 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2361 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2362 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2363 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2364 #if PTR_SIZE == 8
2365 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2366 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2367 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2368 if (s1->plt && s1->plt->reloc) {
2369 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2370 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2371 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2372 put_dt(dynamic, DT_PLTREL, DT_RELA);
2374 put_dt(dynamic, DT_RELACOUNT, 0);
2375 #else
2376 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2377 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2378 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2379 if (s1->plt && s1->plt->reloc) {
2380 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2381 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2382 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2383 put_dt(dynamic, DT_PLTREL, DT_REL);
2385 put_dt(dynamic, DT_RELCOUNT, 0);
2386 #endif
2387 if (versym_section && verneed_section) {
2388 /* The dynamic linker can not handle VERSYM without VERNEED */
2389 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2390 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2391 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2393 s = have_section(s1, ".preinit_array");
2394 if (s && s->data_offset) {
2395 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2396 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2398 s = have_section(s1, ".init_array");
2399 if (s && s->data_offset) {
2400 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2401 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2403 s = have_section(s1, ".fini_array");
2404 if (s && s->data_offset) {
2405 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2406 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2408 s = have_section(s1, ".init");
2409 if (s && s->data_offset) {
2410 put_dt(dynamic, DT_INIT, s->sh_addr);
2412 s = have_section(s1, ".fini");
2413 if (s && s->data_offset) {
2414 put_dt(dynamic, DT_FINI, s->sh_addr);
2416 if (s1->do_debug)
2417 put_dt(dynamic, DT_DEBUG, 0);
2418 put_dt(dynamic, DT_NULL, 0);
2421 /* Remove gaps between RELX sections.
2422 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2423 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2424 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2425 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2426 static void update_reloc_sections(TCCState *s1, struct dyn_inf *dyninf)
2428 int i;
2429 unsigned long file_offset = 0;
2430 Section *s;
2431 Section *relocplt = s1->plt ? s1->plt->reloc : NULL;
2433 /* dynamic relocation table information, for .dynamic section */
2434 dyninf->rel_addr = dyninf->rel_size = 0;
2436 for(i = 1; i < s1->nb_sections; i++) {
2437 s = s1->sections[i];
2438 if (s->sh_type == SHT_RELX && s != relocplt) {
2439 if (dyninf->rel_size == 0) {
2440 dyninf->rel_addr = s->sh_addr;
2441 file_offset = s->sh_offset;
2443 else {
2444 s->sh_addr = dyninf->rel_addr + dyninf->rel_size;
2445 s->sh_offset = file_offset + dyninf->rel_size;
2447 dyninf->rel_size += s->sh_size;
2452 static int tidy_section_headers(TCCState *s1, int *sec_order);
2453 #endif /* ndef ELF_OBJ_ONLY */
2455 /* Create an ELF file on disk.
2456 This function handle ELF specific layout requirements */
2457 static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2458 int file_offset, int *sec_order)
2460 int i, shnum, offset, size, file_type;
2461 Section *s;
2462 ElfW(Ehdr) ehdr;
2463 ElfW(Shdr) shdr, *sh;
2465 file_type = s1->output_type;
2466 shnum = s1->nb_sections;
2468 memset(&ehdr, 0, sizeof(ehdr));
2470 if (phnum > 0) {
2471 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2472 ehdr.e_phnum = phnum;
2473 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2474 #ifndef ELF_OBJ_ONLY
2475 shnum = tidy_section_headers(s1, sec_order);
2476 #endif
2479 /* align to 4 */
2480 file_offset = (file_offset + 3) & -4;
2482 /* fill header */
2483 ehdr.e_ident[0] = ELFMAG0;
2484 ehdr.e_ident[1] = ELFMAG1;
2485 ehdr.e_ident[2] = ELFMAG2;
2486 ehdr.e_ident[3] = ELFMAG3;
2487 ehdr.e_ident[4] = ELFCLASSW;
2488 ehdr.e_ident[5] = ELFDATA2LSB;
2489 ehdr.e_ident[6] = EV_CURRENT;
2491 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2492 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2493 #elif defined TCC_TARGET_ARM && defined TCC_ARM_EABI
2494 ehdr.e_flags = EF_ARM_EABI_VER5;
2495 ehdr.e_flags |= s1->float_abi == ARM_HARD_FLOAT
2496 ? EF_ARM_VFP_FLOAT : EF_ARM_SOFT_FLOAT;
2497 #elif defined TCC_TARGET_ARM
2498 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2499 #elif defined TCC_TARGET_RISCV64
2500 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2501 #endif
2503 if (file_type == TCC_OUTPUT_OBJ) {
2504 ehdr.e_type = ET_REL;
2505 } else {
2506 if (file_type & TCC_OUTPUT_DYN)
2507 ehdr.e_type = ET_DYN;
2508 else
2509 ehdr.e_type = ET_EXEC;
2510 if (s1->elf_entryname)
2511 ehdr.e_entry = get_sym_addr(s1, s1->elf_entryname, 1, 0);
2512 else
2513 ehdr.e_entry = get_sym_addr(s1, "_start", !!(file_type & TCC_OUTPUT_EXE), 0);
2514 if (ehdr.e_entry == (addr_t)-1)
2515 ehdr.e_entry = text_section->sh_addr;
2516 if (s1->nb_errors)
2517 return -1;
2520 ehdr.e_machine = EM_TCC_TARGET;
2521 ehdr.e_version = EV_CURRENT;
2522 ehdr.e_shoff = file_offset;
2523 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2524 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2525 ehdr.e_shnum = shnum;
2526 ehdr.e_shstrndx = shnum - 1;
2528 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2529 if (phdr)
2530 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2531 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2533 sort_syms(s1, symtab_section);
2535 for(i = 1; i < shnum; i++) {
2536 s = s1->sections[sec_order ? sec_order[i] : i];
2537 if (s->sh_type != SHT_NOBITS) {
2538 while (offset < s->sh_offset) {
2539 fputc(0, f);
2540 offset++;
2542 size = s->sh_size;
2543 if (size)
2544 fwrite(s->data, 1, size, f);
2545 offset += size;
2549 /* output section headers */
2550 while (offset < ehdr.e_shoff) {
2551 fputc(0, f);
2552 offset++;
2555 for(i = 0; i < shnum; i++) {
2556 sh = &shdr;
2557 memset(sh, 0, sizeof(ElfW(Shdr)));
2558 s = s1->sections[i];
2559 if (s) {
2560 sh->sh_name = s->sh_name;
2561 sh->sh_type = s->sh_type;
2562 sh->sh_flags = s->sh_flags;
2563 sh->sh_entsize = s->sh_entsize;
2564 sh->sh_info = s->sh_info;
2565 if (s->link)
2566 sh->sh_link = s->link->sh_num;
2567 sh->sh_addralign = s->sh_addralign;
2568 sh->sh_addr = s->sh_addr;
2569 sh->sh_offset = s->sh_offset;
2570 sh->sh_size = s->sh_size;
2572 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2574 return 0;
2577 static int tcc_output_binary(TCCState *s1, FILE *f,
2578 const int *sec_order)
2580 Section *s;
2581 int i, offset, size;
2583 offset = 0;
2584 for(i=1;i<s1->nb_sections;i++) {
2585 s = s1->sections[sec_order[i]];
2586 if (s->sh_type != SHT_NOBITS &&
2587 (s->sh_flags & SHF_ALLOC)) {
2588 while (offset < s->sh_offset) {
2589 fputc(0, f);
2590 offset++;
2592 size = s->sh_size;
2593 fwrite(s->data, 1, size, f);
2594 offset += size;
2597 return 0;
2600 /* Write an elf, coff or "binary" file */
2601 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2602 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2604 int fd, mode, file_type, ret;
2605 FILE *f;
2607 file_type = s1->output_type;
2608 if (file_type == TCC_OUTPUT_OBJ)
2609 mode = 0666;
2610 else
2611 mode = 0777;
2612 unlink(filename);
2613 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2614 if (fd < 0 || (f = fdopen(fd, "wb")) == NULL)
2615 return tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno));
2616 if (s1->verbose)
2617 printf("<- %s\n", filename);
2618 #ifdef TCC_TARGET_COFF
2619 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2620 tcc_output_coff(s1, f);
2621 else
2622 #endif
2623 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2624 ret = tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2625 else
2626 ret = tcc_output_binary(s1, f, sec_order);
2627 fclose(f);
2629 return ret;
2632 #ifndef ELF_OBJ_ONLY
2633 /* Sort section headers by assigned sh_addr, remove sections
2634 that we aren't going to output. */
2635 static int tidy_section_headers(TCCState *s1, int *sec_order)
2637 int i, nnew, l, *backmap;
2638 Section **snew, *s;
2639 ElfW(Sym) *sym;
2641 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2642 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2643 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2644 s = s1->sections[sec_order[i]];
2645 if (!i || s->sh_name) {
2646 backmap[sec_order[i]] = nnew;
2647 snew[nnew] = s;
2648 ++nnew;
2649 } else {
2650 backmap[sec_order[i]] = 0;
2651 snew[--l] = s;
2654 for (i = 0; i < nnew; i++) {
2655 s = snew[i];
2656 if (s) {
2657 s->sh_num = i;
2658 if (s->sh_type == SHT_RELX)
2659 s->sh_info = backmap[s->sh_info];
2663 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2664 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2665 sym->st_shndx = backmap[sym->st_shndx];
2666 if ( !s1->static_link ) {
2667 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2668 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2669 sym->st_shndx = backmap[sym->st_shndx];
2671 for (i = 0; i < s1->nb_sections; i++)
2672 sec_order[i] = i;
2673 tcc_free(s1->sections);
2674 s1->sections = snew;
2675 tcc_free(backmap);
2676 return nnew;
2679 #ifdef TCC_TARGET_ARM
2680 static void create_arm_attribute_section(TCCState *s1)
2682 // Needed for DLL support.
2683 static const unsigned char arm_attr[] = {
2684 0x41, // 'A'
2685 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2686 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2687 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2688 0x05, 0x36, 0x00, // 'CPU_name', "6"
2689 0x06, 0x06, // 'CPU_arch', 'v6'
2690 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2691 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2692 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2693 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2694 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2695 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2696 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2697 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2698 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2699 0x1a, 0x02, // 'ABI_enum_size', 'int'
2700 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2701 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2703 Section *attr = new_section(s1, ".ARM.attributes", SHT_ARM_ATTRIBUTES, 0);
2704 unsigned char *ptr = section_ptr_add(attr, sizeof(arm_attr));
2705 attr->sh_addralign = 1;
2706 memcpy(ptr, arm_attr, sizeof(arm_attr));
2707 if (s1->float_abi != ARM_HARD_FLOAT) {
2708 ptr[26] = 0x00; // 'FP_arch', 'No'
2709 ptr[41] = 0x1e; // 'ABI_optimization_goals'
2710 ptr[42] = 0x06; // 'Aggressive Debug'
2713 #endif
2715 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2716 static Section *create_bsd_note_section(TCCState *s1,
2717 const char *name,
2718 const char *value)
2720 Section *s = find_section (s1, name);
2722 if (s->data_offset == 0) {
2723 char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
2724 ElfW(Nhdr) *note = (ElfW(Nhdr) *) ptr;
2726 s->sh_type = SHT_NOTE;
2727 note->n_namesz = 8;
2728 note->n_descsz = 4;
2729 note->n_type = ELF_NOTE_OS_GNU;
2730 strcpy (ptr + sizeof(ElfW(Nhdr)), value);
2732 return s;
2734 #endif
2736 static void alloc_sec_names(TCCState *s1, int is_obj);
2738 /* Output an elf, coff or binary file */
2739 /* XXX: suppress unneeded sections */
2740 static int elf_output_file(TCCState *s1, const char *filename)
2742 int i, ret, file_type, file_offset, *sec_order;
2743 struct dyn_inf dyninf = {0};
2744 Section *interp, *dynstr, *dynamic;
2745 int textrel, got_sym, dt_flags_1;
2747 file_type = s1->output_type;
2748 s1->nb_errors = 0;
2749 ret = -1;
2750 interp = dynstr = dynamic = NULL;
2751 sec_order = NULL;
2752 dyninf.roinf = &dyninf._roinf;
2754 #ifdef TCC_TARGET_ARM
2755 create_arm_attribute_section (s1);
2756 #endif
2758 #if TARGETOS_OpenBSD
2759 dyninf.note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
2760 #endif
2762 #if TARGETOS_NetBSD
2763 dyninf.note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD");
2764 #endif
2766 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
2767 dyninf.roinf = NULL;
2768 #endif
2769 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2770 tcc_add_runtime(s1);
2771 resolve_common_syms(s1);
2773 if (!s1->static_link) {
2774 if (file_type & TCC_OUTPUT_EXE) {
2775 char *ptr;
2776 /* allow override the dynamic loader */
2777 const char *elfint = getenv("LD_SO");
2778 if (elfint == NULL)
2779 elfint = DEFAULT_ELFINTERP(s1);
2780 /* add interpreter section only if executable */
2781 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2782 interp->sh_addralign = 1;
2783 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2784 strcpy(ptr, elfint);
2785 dyninf.interp = interp;
2788 /* add dynamic symbol table */
2789 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2790 ".dynstr",
2791 ".hash", SHF_ALLOC);
2792 /* Number of local symbols (readelf complains if not set) */
2793 s1->dynsym->sh_info = 1;
2794 dynstr = s1->dynsym->link;
2795 /* add dynamic section */
2796 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2797 SHF_ALLOC | SHF_WRITE);
2798 dynamic->link = dynstr;
2799 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2801 got_sym = build_got(s1);
2802 if (file_type & TCC_OUTPUT_EXE) {
2803 bind_exe_dynsyms(s1, file_type & TCC_OUTPUT_DYN);
2804 if (s1->nb_errors)
2805 goto the_end;
2807 build_got_entries(s1, got_sym);
2808 if (file_type & TCC_OUTPUT_EXE) {
2809 bind_libs_dynsyms(s1);
2810 } else {
2811 /* shared library case: simply export all global symbols */
2812 export_global_syms(s1);
2814 dyninf.gnu_hash = create_gnu_hash(s1);
2815 } else {
2816 build_got_entries(s1, 0);
2818 version_add (s1);
2820 textrel = set_sec_sizes(s1);
2821 alloc_sec_names(s1, 0);
2823 if (!s1->static_link) {
2824 /* add a list of needed dlls */
2825 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2826 DLLReference *dllref = s1->loaded_dlls[i];
2827 if (dllref->level == 0)
2828 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2831 if (s1->rpath)
2832 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2833 put_elf_str(dynstr, s1->rpath));
2835 dt_flags_1 = DF_1_NOW;
2836 if (file_type & TCC_OUTPUT_DYN) {
2837 if (s1->soname)
2838 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2839 /* XXX: currently, since we do not handle PIC code, we
2840 must relocate the readonly segments */
2841 if (textrel)
2842 put_dt(dynamic, DT_TEXTREL, 0);
2843 if (file_type & TCC_OUTPUT_EXE)
2844 dt_flags_1 = DF_1_NOW | DF_1_PIE;
2846 put_dt(dynamic, DT_FLAGS, DF_BIND_NOW);
2847 put_dt(dynamic, DT_FLAGS_1, dt_flags_1);
2848 if (s1->symbolic)
2849 put_dt(dynamic, DT_SYMBOLIC, 0);
2851 dyninf.dynamic = dynamic;
2852 dyninf.dynstr = dynstr;
2853 /* remember offset and reserve space for 2nd call below */
2854 dyninf.data_offset = dynamic->data_offset;
2855 fill_dynamic(s1, &dyninf);
2856 dynamic->sh_size = dynamic->data_offset;
2857 dynstr->sh_size = dynstr->data_offset;
2860 /* this array is used to reorder sections in the output file */
2861 sec_order = tcc_malloc(sizeof(int) * 2 * s1->nb_sections);
2862 /* compute section to program header mapping */
2863 file_offset = layout_sections(s1, sec_order, &dyninf);
2865 if (dynamic) {
2866 /* put in GOT the dynamic section address and relocate PLT */
2867 write32le(s1->got->data, dynamic->sh_addr);
2868 if (file_type == TCC_OUTPUT_EXE
2869 || (RELOCATE_DLLPLT && (file_type & TCC_OUTPUT_DYN)))
2870 relocate_plt(s1);
2871 /* relocate symbols in .dynsym now that final addresses are known */
2872 relocate_syms(s1, s1->dynsym, 2);
2875 /* if building executable or DLL, then relocate each section
2876 except the GOT which is already relocated */
2877 relocate_syms(s1, s1->symtab, 0);
2878 if (s1->nb_errors != 0)
2879 goto the_end;
2880 relocate_sections(s1);
2881 if (dynamic) {
2882 update_reloc_sections (s1, &dyninf);
2883 dynamic->data_offset = dyninf.data_offset;
2884 fill_dynamic(s1, &dyninf);
2886 /* Perform relocation to GOT or PLT entries */
2887 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2888 fill_got(s1);
2889 else if (s1->got)
2890 fill_local_got_entries(s1);
2892 if (dyninf.gnu_hash)
2893 update_gnu_hash(s1, dyninf.gnu_hash);
2895 /* Create the ELF file with name 'filename' */
2896 ret = tcc_write_elf_file(s1, filename, dyninf.phnum, dyninf.phdr, file_offset, sec_order);
2897 the_end:
2898 tcc_free(sec_order);
2899 tcc_free(dyninf.phdr);
2900 return ret;
2902 #endif /* ndef ELF_OBJ_ONLY */
2904 /* Allocate strings for section names */
2905 static void alloc_sec_names(TCCState *s1, int is_obj)
2907 int i;
2908 Section *s, *strsec;
2910 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2911 put_elf_str(strsec, "");
2912 for(i = 1; i < s1->nb_sections; i++) {
2913 s = s1->sections[i];
2914 if (is_obj)
2915 s->sh_size = s->data_offset;
2916 if (s == strsec || s->sh_size || (s->sh_flags & SHF_ALLOC))
2917 s->sh_name = put_elf_str(strsec, s->name);
2919 strsec->sh_size = strsec->data_offset;
2922 /* Output an elf .o file */
2923 static int elf_output_obj(TCCState *s1, const char *filename)
2925 Section *s;
2926 int i, ret, file_offset;
2927 s1->nb_errors = 0;
2928 /* Allocate strings for section names */
2929 alloc_sec_names(s1, 1);
2930 file_offset = sizeof (ElfW(Ehdr));
2931 for(i = 1; i < s1->nb_sections; i++) {
2932 s = s1->sections[i];
2933 file_offset = (file_offset + 15) & -16;
2934 s->sh_offset = file_offset;
2935 if (s->sh_type != SHT_NOBITS)
2936 file_offset += s->sh_size;
2938 /* Create the ELF file with name 'filename' */
2939 ret = tcc_write_elf_file(s1, filename, 0, NULL, file_offset, NULL);
2940 return ret;
2943 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2945 if (s->test_coverage)
2946 tcc_tcov_add_file(s, filename);
2947 if (s->output_type == TCC_OUTPUT_OBJ)
2948 return elf_output_obj(s, filename);
2949 #ifdef TCC_TARGET_PE
2950 return pe_output_file(s, filename);
2951 #elif TCC_TARGET_MACHO
2952 return macho_output_file(s, filename);
2953 #else
2954 return elf_output_file(s, filename);
2955 #endif
2958 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
2959 char *cbuf = buf;
2960 size_t rnum = 0;
2961 while (1) {
2962 ssize_t num = read(fd, cbuf, count-rnum);
2963 if (num < 0) return num;
2964 if (num == 0) return rnum;
2965 rnum += num;
2966 cbuf += num;
2970 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
2972 void *data;
2974 data = tcc_malloc(size);
2975 lseek(fd, file_offset, SEEK_SET);
2976 full_read(fd, data, size);
2977 return data;
2980 typedef struct SectionMergeInfo {
2981 Section *s; /* corresponding existing section */
2982 unsigned long offset; /* offset of the new section in the existing section */
2983 uint8_t new_section; /* true if section 's' was added */
2984 uint8_t link_once; /* true if link once section */
2985 } SectionMergeInfo;
2987 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2989 int size = full_read(fd, h, sizeof *h);
2990 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2991 if (h->e_type == ET_REL)
2992 return AFF_BINTYPE_REL;
2993 if (h->e_type == ET_DYN)
2994 return AFF_BINTYPE_DYN;
2995 } else if (size >= 8) {
2996 if (0 == memcmp(h, ARMAG, 8))
2997 return AFF_BINTYPE_AR;
2998 #ifdef TCC_TARGET_COFF
2999 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
3000 return AFF_BINTYPE_C67;
3001 #endif
3003 return 0;
3006 /* load an object file and merge it with current files */
3007 /* XXX: handle correctly stab (debug) info */
3008 ST_FUNC int tcc_load_object_file(TCCState *s1,
3009 int fd, unsigned long file_offset)
3011 ElfW(Ehdr) ehdr;
3012 ElfW(Shdr) *shdr, *sh;
3013 unsigned long size, offset, offseti;
3014 int i, j, nb_syms, sym_index, ret, seencompressed;
3015 char *strsec, *strtab;
3016 int stab_index, stabstr_index;
3017 int *old_to_new_syms;
3018 char *sh_name, *name;
3019 SectionMergeInfo *sm_table, *sm;
3020 ElfW(Sym) *sym, *symtab;
3021 ElfW_Rel *rel;
3022 Section *s;
3024 lseek(fd, file_offset, SEEK_SET);
3025 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
3026 goto invalid;
3027 /* test CPU specific stuff */
3028 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3029 ehdr.e_machine != EM_TCC_TARGET) {
3030 invalid:
3031 return tcc_error_noabort("invalid object file");
3033 /* read sections */
3034 shdr = load_data(fd, file_offset + ehdr.e_shoff,
3035 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3036 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
3038 /* load section names */
3039 sh = &shdr[ehdr.e_shstrndx];
3040 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3042 /* load symtab and strtab */
3043 old_to_new_syms = NULL;
3044 symtab = NULL;
3045 strtab = NULL;
3046 nb_syms = 0;
3047 seencompressed = 0;
3048 stab_index = stabstr_index = 0;
3049 ret = -1;
3051 for(i = 1; i < ehdr.e_shnum; i++) {
3052 sh = &shdr[i];
3053 if (sh->sh_type == SHT_SYMTAB) {
3054 if (symtab) {
3055 tcc_error_noabort("object must contain only one symtab");
3056 goto the_end;
3058 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3059 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3060 sm_table[i].s = symtab_section;
3062 /* now load strtab */
3063 sh = &shdr[sh->sh_link];
3064 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3066 if (sh->sh_flags & SHF_COMPRESSED)
3067 seencompressed = 1;
3070 /* now examine each section and try to merge its content with the
3071 ones in memory */
3072 for(i = 1; i < ehdr.e_shnum; i++) {
3073 /* no need to examine section name strtab */
3074 if (i == ehdr.e_shstrndx)
3075 continue;
3076 sh = &shdr[i];
3077 if (sh->sh_type == SHT_RELX)
3078 sh = &shdr[sh->sh_info];
3079 /* ignore sections types we do not handle (plus relocs to those) */
3080 if (sh->sh_type != SHT_PROGBITS &&
3081 #ifdef TCC_ARM_EABI
3082 sh->sh_type != SHT_ARM_EXIDX &&
3083 #endif
3084 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3085 sh->sh_type != SHT_X86_64_UNWIND &&
3086 #endif
3087 sh->sh_type != SHT_NOTE &&
3088 sh->sh_type != SHT_NOBITS &&
3089 sh->sh_type != SHT_PREINIT_ARRAY &&
3090 sh->sh_type != SHT_INIT_ARRAY &&
3091 sh->sh_type != SHT_FINI_ARRAY &&
3092 strcmp(strsec + sh->sh_name, ".stabstr")
3094 continue;
3095 if (seencompressed && 0 == strncmp(strsec + sh->sh_name, ".debug_", 7))
3096 continue;
3098 sh = &shdr[i];
3099 sh_name = strsec + sh->sh_name;
3100 if (sh->sh_addralign < 1)
3101 sh->sh_addralign = 1;
3102 /* find corresponding section, if any */
3103 for(j = 1; j < s1->nb_sections;j++) {
3104 s = s1->sections[j];
3105 if (!strcmp(s->name, sh_name)) {
3106 if (!strncmp(sh_name, ".gnu.linkonce",
3107 sizeof(".gnu.linkonce") - 1)) {
3108 /* if a 'linkonce' section is already present, we
3109 do not add it again. It is a little tricky as
3110 symbols can still be defined in
3111 it. */
3112 sm_table[i].link_once = 1;
3113 goto next;
3115 if (stab_section) {
3116 if (s == stab_section)
3117 stab_index = i;
3118 if (s == stab_section->link)
3119 stabstr_index = i;
3121 goto found;
3124 /* not found: create new section */
3125 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
3126 /* take as much info as possible from the section. sh_link and
3127 sh_info will be updated later */
3128 s->sh_addralign = sh->sh_addralign;
3129 s->sh_entsize = sh->sh_entsize;
3130 sm_table[i].new_section = 1;
3131 found:
3132 if (sh->sh_type != s->sh_type
3133 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3134 && strcmp (s->name, ".eh_frame")
3135 #endif
3137 tcc_error_noabort("invalid section type");
3138 goto the_end;
3140 /* align start of section */
3141 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
3142 if (sh->sh_addralign > s->sh_addralign)
3143 s->sh_addralign = sh->sh_addralign;
3144 sm_table[i].offset = s->data_offset;
3145 sm_table[i].s = s;
3146 /* concatenate sections */
3147 size = sh->sh_size;
3148 if (sh->sh_type != SHT_NOBITS) {
3149 unsigned char *ptr;
3150 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
3151 ptr = section_ptr_add(s, size);
3152 full_read(fd, ptr, size);
3153 } else {
3154 s->data_offset += size;
3156 next: ;
3159 /* gr relocate stab strings */
3160 if (stab_index && stabstr_index) {
3161 Stab_Sym *a, *b;
3162 unsigned o;
3163 s = sm_table[stab_index].s;
3164 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
3165 b = (Stab_Sym *)(s->data + s->data_offset);
3166 o = sm_table[stabstr_index].offset;
3167 while (a < b) {
3168 if (a->n_strx)
3169 a->n_strx += o;
3170 a++;
3174 /* second short pass to update sh_link and sh_info fields of new
3175 sections */
3176 for(i = 1; i < ehdr.e_shnum; i++) {
3177 s = sm_table[i].s;
3178 if (!s || !sm_table[i].new_section)
3179 continue;
3180 sh = &shdr[i];
3181 if (sh->sh_link > 0)
3182 s->link = sm_table[sh->sh_link].s;
3183 if (sh->sh_type == SHT_RELX) {
3184 s->sh_info = sm_table[sh->sh_info].s->sh_num;
3185 /* update backward link */
3186 s1->sections[s->sh_info]->reloc = s;
3190 /* resolve symbols */
3191 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
3193 sym = symtab + 1;
3194 for(i = 1; i < nb_syms; i++, sym++) {
3195 if (sym->st_shndx != SHN_UNDEF &&
3196 sym->st_shndx < SHN_LORESERVE) {
3197 sm = &sm_table[sym->st_shndx];
3198 if (sm->link_once) {
3199 /* if a symbol is in a link once section, we use the
3200 already defined symbol. It is very important to get
3201 correct relocations */
3202 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
3203 name = strtab + sym->st_name;
3204 sym_index = find_elf_sym(symtab_section, name);
3205 if (sym_index)
3206 old_to_new_syms[i] = sym_index;
3208 continue;
3210 /* if no corresponding section added, no need to add symbol */
3211 if (!sm->s)
3212 continue;
3213 /* convert section number */
3214 sym->st_shndx = sm->s->sh_num;
3215 /* offset value */
3216 sym->st_value += sm->offset;
3218 /* add symbol */
3219 name = strtab + sym->st_name;
3220 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
3221 sym->st_info, sym->st_other,
3222 sym->st_shndx, name);
3223 old_to_new_syms[i] = sym_index;
3226 /* third pass to patch relocation entries */
3227 for(i = 1; i < ehdr.e_shnum; i++) {
3228 s = sm_table[i].s;
3229 if (!s)
3230 continue;
3231 sh = &shdr[i];
3232 offset = sm_table[i].offset;
3233 size = sh->sh_size;
3234 switch(s->sh_type) {
3235 case SHT_RELX:
3236 /* take relocation offset information */
3237 offseti = sm_table[sh->sh_info].offset;
3238 for (rel = (ElfW_Rel *) s->data + (offset / sizeof(*rel));
3239 rel < (ElfW_Rel *) s->data + ((offset + size) / sizeof(*rel));
3240 rel++) {
3241 int type;
3242 unsigned sym_index;
3243 /* convert symbol index */
3244 type = ELFW(R_TYPE)(rel->r_info);
3245 sym_index = ELFW(R_SYM)(rel->r_info);
3246 /* NOTE: only one symtab assumed */
3247 if (sym_index >= nb_syms)
3248 goto invalid_reloc;
3249 sym_index = old_to_new_syms[sym_index];
3250 /* ignore link_once in rel section. */
3251 if (!sym_index && !sm_table[sh->sh_info].link_once
3252 #ifdef TCC_TARGET_ARM
3253 && type != R_ARM_V4BX
3254 #elif defined TCC_TARGET_RISCV64
3255 && type != R_RISCV_ALIGN
3256 && type != R_RISCV_RELAX
3257 #endif
3259 invalid_reloc:
3260 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3261 i, strsec + sh->sh_name, (int)rel->r_offset);
3262 goto the_end;
3264 rel->r_info = ELFW(R_INFO)(sym_index, type);
3265 /* offset the relocation offset */
3266 rel->r_offset += offseti;
3267 #ifdef TCC_TARGET_ARM
3268 /* Jumps and branches from a Thumb code to a PLT entry need
3269 special handling since PLT entries are ARM code.
3270 Unconditional bl instructions referencing PLT entries are
3271 handled by converting these instructions into blx
3272 instructions. Other case of instructions referencing a PLT
3273 entry require to add a Thumb stub before the PLT entry to
3274 switch to ARM mode. We set bit plt_thumb_stub of the
3275 attribute of a symbol to indicate such a case. */
3276 if (type == R_ARM_THM_JUMP24)
3277 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
3278 #endif
3280 break;
3281 default:
3282 break;
3286 ret = 0;
3287 the_end:
3288 tcc_free(symtab);
3289 tcc_free(strtab);
3290 tcc_free(old_to_new_syms);
3291 tcc_free(sm_table);
3292 tcc_free(strsec);
3293 tcc_free(shdr);
3294 return ret;
3297 typedef struct ArchiveHeader {
3298 char ar_name[16]; /* name of this member */
3299 char ar_date[12]; /* file mtime */
3300 char ar_uid[6]; /* owner uid; printed as decimal */
3301 char ar_gid[6]; /* owner gid; printed as decimal */
3302 char ar_mode[8]; /* file mode, printed as octal */
3303 char ar_size[10]; /* file size, printed as decimal */
3304 char ar_fmag[2]; /* should contain ARFMAG */
3305 } ArchiveHeader;
3307 #define ARFMAG "`\n"
3309 static unsigned long long get_be(const uint8_t *b, int n)
3311 unsigned long long ret = 0;
3312 while (n)
3313 ret = (ret << 8) | *b++, --n;
3314 return ret;
3317 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
3319 char *p, *e;
3320 int len;
3321 lseek(fd, offset, SEEK_SET);
3322 len = full_read(fd, hdr, sizeof(ArchiveHeader));
3323 if (len != sizeof(ArchiveHeader))
3324 return len ? -1 : 0;
3325 p = hdr->ar_name;
3326 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
3327 --e;
3328 *e = '\0';
3329 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
3330 return len;
3333 /* load only the objects which resolve undefined symbols */
3334 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
3336 int i, bound, nsyms, sym_index, len, ret = -1;
3337 unsigned long long off;
3338 uint8_t *data;
3339 const char *ar_names, *p;
3340 const uint8_t *ar_index;
3341 ElfW(Sym) *sym;
3342 ArchiveHeader hdr;
3344 data = tcc_malloc(size);
3345 if (full_read(fd, data, size) != size)
3346 goto the_end;
3347 nsyms = get_be(data, entrysize);
3348 ar_index = data + entrysize;
3349 ar_names = (char *) ar_index + nsyms * entrysize;
3351 do {
3352 bound = 0;
3353 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
3354 Section *s = symtab_section;
3355 sym_index = find_elf_sym(s, p);
3356 if (!sym_index)
3357 continue;
3358 sym = &((ElfW(Sym) *)s->data)[sym_index];
3359 if(sym->st_shndx != SHN_UNDEF)
3360 continue;
3361 off = get_be(ar_index + i * entrysize, entrysize);
3362 len = read_ar_header(fd, off, &hdr);
3363 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
3364 tcc_error_noabort("invalid archive");
3365 goto the_end;
3367 off += len;
3368 if (s1->verbose == 2)
3369 printf(" -> %s\n", hdr.ar_name);
3370 if (tcc_load_object_file(s1, fd, off) < 0)
3371 goto the_end;
3372 ++bound;
3374 } while(bound);
3375 ret = 0;
3376 the_end:
3377 tcc_free(data);
3378 return ret;
3381 /* load a '.a' file */
3382 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
3384 ArchiveHeader hdr;
3385 /* char magic[8]; */
3386 int size, len;
3387 unsigned long file_offset;
3388 ElfW(Ehdr) ehdr;
3390 /* skip magic which was already checked */
3391 /* full_read(fd, magic, sizeof(magic)); */
3392 file_offset = sizeof ARMAG - 1;
3394 for(;;) {
3395 len = read_ar_header(fd, file_offset, &hdr);
3396 if (len == 0)
3397 return 0;
3398 if (len < 0)
3399 return tcc_error_noabort("invalid archive");
3400 file_offset += len;
3401 size = strtol(hdr.ar_size, NULL, 0);
3402 /* align to even */
3403 size = (size + 1) & ~1;
3404 if (alacarte) {
3405 /* coff symbol table : we handle it */
3406 if (!strcmp(hdr.ar_name, "/"))
3407 return tcc_load_alacarte(s1, fd, size, 4);
3408 if (!strcmp(hdr.ar_name, "/SYM64/"))
3409 return tcc_load_alacarte(s1, fd, size, 8);
3410 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3411 if (s1->verbose == 2)
3412 printf(" -> %s\n", hdr.ar_name);
3413 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3414 return -1;
3416 file_offset += size;
3420 #ifndef ELF_OBJ_ONLY
3421 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3422 LV, maybe create a new entry for (LIB,VERSION). */
3423 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3425 while (i >= *n) {
3426 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3427 (*lv)[(*n)++] = -1;
3429 if ((*lv)[i] == -1) {
3430 int v, prev_same_lib = -1;
3431 for (v = 0; v < nb_sym_versions; v++) {
3432 if (strcmp(sym_versions[v].lib, lib))
3433 continue;
3434 prev_same_lib = v;
3435 if (!strcmp(sym_versions[v].version, version))
3436 break;
3438 if (v == nb_sym_versions) {
3439 sym_versions = tcc_realloc (sym_versions,
3440 (v + 1) * sizeof(*sym_versions));
3441 sym_versions[v].lib = tcc_strdup(lib);
3442 sym_versions[v].version = tcc_strdup(version);
3443 sym_versions[v].out_index = 0;
3444 sym_versions[v].prev_same_lib = prev_same_lib;
3445 nb_sym_versions++;
3447 (*lv)[i] = v;
3451 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3452 VERNDX. */
3453 static void
3454 set_sym_version(TCCState *s1, int sym_index, int verndx)
3456 if (sym_index >= nb_sym_to_version) {
3457 int newelems = sym_index ? sym_index * 2 : 1;
3458 sym_to_version = tcc_realloc(sym_to_version,
3459 newelems * sizeof(*sym_to_version));
3460 memset(sym_to_version + nb_sym_to_version, -1,
3461 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3462 nb_sym_to_version = newelems;
3464 if (sym_to_version[sym_index] < 0)
3465 sym_to_version[sym_index] = verndx;
3468 struct versym_info {
3469 int nb_versyms;
3470 ElfW(Verdef) *verdef;
3471 ElfW(Verneed) *verneed;
3472 ElfW(Half) *versym;
3473 int nb_local_ver, *local_ver;
3477 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3479 char *lib, *version;
3480 uint32_t next;
3481 int i;
3483 #define DEBUG_VERSION 0
3485 if (v->versym && v->verdef) {
3486 ElfW(Verdef) *vdef = v->verdef;
3487 lib = NULL;
3488 do {
3489 ElfW(Verdaux) *verdaux =
3490 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3492 #if DEBUG_VERSION
3493 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3494 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3495 vdef->vd_hash);
3496 #endif
3497 if (vdef->vd_cnt) {
3498 version = dynstr + verdaux->vda_name;
3500 if (lib == NULL)
3501 lib = version;
3502 else
3503 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3504 lib, version);
3505 #if DEBUG_VERSION
3506 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3507 #endif
3509 next = vdef->vd_next;
3510 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3511 } while (next);
3513 if (v->versym && v->verneed) {
3514 ElfW(Verneed) *vneed = v->verneed;
3515 do {
3516 ElfW(Vernaux) *vernaux =
3517 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3519 lib = dynstr + vneed->vn_file;
3520 #if DEBUG_VERSION
3521 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3522 #endif
3523 for (i = 0; i < vneed->vn_cnt; i++) {
3524 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3525 version = dynstr + vernaux->vna_name;
3526 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3527 lib, version);
3528 #if DEBUG_VERSION
3529 printf (" vernaux(%u): %u %u %s\n",
3530 vernaux->vna_other, vernaux->vna_hash,
3531 vernaux->vna_flags, version);
3532 #endif
3534 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3536 next = vneed->vn_next;
3537 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3538 } while (next);
3541 #if DEBUG_VERSION
3542 for (i = 0; i < v->nb_local_ver; i++) {
3543 if (v->local_ver[i] > 0) {
3544 printf ("%d: lib: %s, version %s\n",
3545 i, sym_versions[v->local_ver[i]].lib,
3546 sym_versions[v->local_ver[i]].version);
3549 #endif
3552 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3553 is referenced by the user (so it should be added as DT_NEEDED in
3554 the generated ELF file) */
3555 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3557 ElfW(Ehdr) ehdr;
3558 ElfW(Shdr) *shdr, *sh, *sh1;
3559 int i, nb_syms, nb_dts, sym_bind, ret = -1;
3560 ElfW(Sym) *sym, *dynsym;
3561 ElfW(Dyn) *dt, *dynamic;
3563 char *dynstr;
3564 int sym_index;
3565 const char *name, *soname;
3566 struct versym_info v;
3568 full_read(fd, &ehdr, sizeof(ehdr));
3570 /* test CPU specific stuff */
3571 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3572 ehdr.e_machine != EM_TCC_TARGET) {
3573 return tcc_error_noabort("bad architecture");
3576 /* read sections */
3577 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3579 /* load dynamic section and dynamic symbols */
3580 nb_syms = 0;
3581 nb_dts = 0;
3582 dynamic = NULL;
3583 dynsym = NULL; /* avoid warning */
3584 dynstr = NULL; /* avoid warning */
3585 memset(&v, 0, sizeof v);
3587 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3588 switch(sh->sh_type) {
3589 case SHT_DYNAMIC:
3590 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3591 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3592 break;
3593 case SHT_DYNSYM:
3594 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3595 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3596 sh1 = &shdr[sh->sh_link];
3597 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3598 break;
3599 case SHT_GNU_verdef:
3600 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3601 break;
3602 case SHT_GNU_verneed:
3603 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3604 break;
3605 case SHT_GNU_versym:
3606 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3607 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3608 break;
3609 default:
3610 break;
3614 if (!dynamic)
3615 goto the_end;
3617 /* compute the real library name */
3618 soname = tcc_basename(filename);
3619 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
3620 if (dt->d_tag == DT_SONAME)
3621 soname = dynstr + dt->d_un.d_val;
3623 /* if the dll is already loaded, do not load it */
3624 if (tcc_add_dllref(s1, soname, level)->found)
3625 goto ret_success;
3627 if (v.nb_versyms != nb_syms)
3628 tcc_free (v.versym), v.versym = NULL;
3629 else
3630 store_version(s1, &v, dynstr);
3632 /* add dynamic symbols in dynsym_section */
3633 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3634 sym_bind = ELFW(ST_BIND)(sym->st_info);
3635 if (sym_bind == STB_LOCAL)
3636 continue;
3637 name = dynstr + sym->st_name;
3638 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3639 sym->st_info, sym->st_other, sym->st_shndx, name);
3640 if (v.versym) {
3641 ElfW(Half) vsym = v.versym[i];
3642 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3643 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3647 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
3648 if (dt->d_tag == DT_RPATH)
3649 tcc_add_library_path(s1, dynstr + dt->d_un.d_val);
3651 /* load all referenced DLLs */
3652 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3653 switch(dt->d_tag) {
3654 case DT_NEEDED:
3655 name = dynstr + dt->d_un.d_val;
3656 if (tcc_add_dllref(s1, name, -1))
3657 continue;
3658 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3659 ret = tcc_error_noabort("referenced dll '%s' not found", name);
3660 goto the_end;
3665 ret_success:
3666 ret = 0;
3667 the_end:
3668 tcc_free(dynstr);
3669 tcc_free(dynsym);
3670 tcc_free(dynamic);
3671 tcc_free(shdr);
3672 tcc_free(v.local_ver);
3673 tcc_free(v.verdef);
3674 tcc_free(v.verneed);
3675 tcc_free(v.versym);
3676 return ret;
3679 #define LD_TOK_NAME 256
3680 #define LD_TOK_EOF (-1)
3682 static int ld_inp(TCCState *s1)
3684 char b;
3685 if (s1->cc != -1) {
3686 int c = s1->cc;
3687 s1->cc = -1;
3688 return c;
3690 if (1 == read(s1->fd, &b, 1))
3691 return b;
3692 return CH_EOF;
3695 /* return next ld script token */
3696 static int ld_next(TCCState *s1, char *name, int name_size)
3698 int c, d, ch;
3699 char *q;
3701 redo:
3702 ch = ld_inp(s1);
3703 switch(ch) {
3704 case ' ':
3705 case '\t':
3706 case '\f':
3707 case '\v':
3708 case '\r':
3709 case '\n':
3710 goto redo;
3711 case '/':
3712 ch = ld_inp(s1);
3713 if (ch == '*') { /* comment */
3714 for (d = 0;; d = ch) {
3715 ch = ld_inp(s1);
3716 if (ch == CH_EOF || (ch == '/' && d == '*'))
3717 break;
3719 goto redo;
3720 } else {
3721 q = name;
3722 *q++ = '/';
3723 goto parse_name;
3725 break;
3726 case '\\':
3727 /* case 'a' ... 'z': */
3728 case 'a':
3729 case 'b':
3730 case 'c':
3731 case 'd':
3732 case 'e':
3733 case 'f':
3734 case 'g':
3735 case 'h':
3736 case 'i':
3737 case 'j':
3738 case 'k':
3739 case 'l':
3740 case 'm':
3741 case 'n':
3742 case 'o':
3743 case 'p':
3744 case 'q':
3745 case 'r':
3746 case 's':
3747 case 't':
3748 case 'u':
3749 case 'v':
3750 case 'w':
3751 case 'x':
3752 case 'y':
3753 case 'z':
3754 /* case 'A' ... 'z': */
3755 case 'A':
3756 case 'B':
3757 case 'C':
3758 case 'D':
3759 case 'E':
3760 case 'F':
3761 case 'G':
3762 case 'H':
3763 case 'I':
3764 case 'J':
3765 case 'K':
3766 case 'L':
3767 case 'M':
3768 case 'N':
3769 case 'O':
3770 case 'P':
3771 case 'Q':
3772 case 'R':
3773 case 'S':
3774 case 'T':
3775 case 'U':
3776 case 'V':
3777 case 'W':
3778 case 'X':
3779 case 'Y':
3780 case 'Z':
3781 case '_':
3782 case '.':
3783 case '$':
3784 case '~':
3785 q = name;
3786 parse_name:
3787 for(;;) {
3788 if (!((ch >= 'a' && ch <= 'z') ||
3789 (ch >= 'A' && ch <= 'Z') ||
3790 (ch >= '0' && ch <= '9') ||
3791 strchr("/.-_+=$:\\,~", ch)))
3792 break;
3793 if ((q - name) < name_size - 1) {
3794 *q++ = ch;
3796 ch = ld_inp(s1);
3798 s1->cc = ch;
3799 *q = '\0';
3800 c = LD_TOK_NAME;
3801 break;
3802 case CH_EOF:
3803 c = LD_TOK_EOF;
3804 break;
3805 default:
3806 c = ch;
3807 break;
3809 return c;
3812 static int ld_add_file(TCCState *s1, const char filename[])
3814 if (filename[0] == '/') {
3815 if (CONFIG_SYSROOT[0] == '\0'
3816 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3817 return 0;
3818 filename = tcc_basename(filename);
3820 return tcc_add_dll(s1, filename, 0);
3823 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3825 char filename[1024], libname[1024];
3826 int t, group, nblibs = 0, ret = 0;
3827 char **libs = NULL;
3829 group = !strcmp(cmd, "GROUP");
3830 if (!as_needed)
3831 s1->new_undef_sym = 0;
3832 t = ld_next(s1, filename, sizeof(filename));
3833 if (t != '(') {
3834 ret = tcc_error_noabort("( expected");
3835 goto lib_parse_error;
3837 t = ld_next(s1, filename, sizeof(filename));
3838 for(;;) {
3839 libname[0] = '\0';
3840 if (t == LD_TOK_EOF) {
3841 ret = tcc_error_noabort("unexpected end of file");
3842 goto lib_parse_error;
3843 } else if (t == ')') {
3844 break;
3845 } else if (t == '-') {
3846 t = ld_next(s1, filename, sizeof(filename));
3847 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3848 ret = tcc_error_noabort("library name expected");
3849 goto lib_parse_error;
3851 pstrcpy(libname, sizeof libname, &filename[1]);
3852 if (s1->static_link) {
3853 snprintf(filename, sizeof filename, "lib%s.a", libname);
3854 } else {
3855 snprintf(filename, sizeof filename, "lib%s.so", libname);
3857 } else if (t != LD_TOK_NAME) {
3858 ret = tcc_error_noabort("filename expected");
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 return tcc_error_noabort("( expected");
3924 for(;;) {
3925 t = ld_next(s1, filename, sizeof(filename));
3926 if (t == LD_TOK_EOF) {
3927 return tcc_error_noabort("unexpected end of file");
3928 } else if (t == ')') {
3929 break;
3932 } else {
3933 return -1;
3936 return 0;
3938 #endif /* !ELF_OBJ_ONLY */