OpenBSD: fix typo in _ANSI_LIBRARY defined symbol
[tinycc/tcc_android_arm.git] / tccelf.c
blob48d7794c212346b5d468320650ecfccef85478ec
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 /* ------------------------------------------------------------------------- */
52 ST_FUNC void tccelf_new(TCCState *s)
54 TCCState *s1 = s;
55 /* no section zero */
56 dynarray_add(&s->sections, &s->nb_sections, NULL);
58 /* create standard sections */
59 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
60 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
61 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
62 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
63 common_section->sh_num = SHN_COMMON;
65 /* symbols are always generated for linking stage */
66 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
67 ".strtab",
68 ".hashtab", SHF_PRIVATE);
69 s->symtab = symtab_section;
71 /* private symbol table for dynamic symbols */
72 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
73 ".dynstrtab",
74 ".dynhashtab", SHF_PRIVATE);
75 get_sym_attr(s, 0, 1);
78 #ifdef CONFIG_TCC_BCHECK
79 ST_FUNC void tccelf_bounds_new(TCCState *s)
81 TCCState *s1 = s;
82 /* create bounds sections */
83 bounds_section = new_section(s, ".bounds",
84 SHT_PROGBITS, SHF_ALLOC);
85 lbounds_section = new_section(s, ".lbounds",
86 SHT_PROGBITS, SHF_ALLOC);
88 #endif
90 ST_FUNC void tccelf_stab_new(TCCState *s)
92 TCCState *s1 = s;
93 int shf = 0;
94 #ifdef CONFIG_TCC_BACKTRACE
95 /* include stab info with standalone backtrace support */
96 if (s->do_backtrace && s->output_type != TCC_OUTPUT_MEMORY)
97 shf = SHF_ALLOC;
98 #endif
99 stab_section = new_section(s, ".stab", SHT_PROGBITS, shf);
100 stab_section->sh_entsize = sizeof(Stab_Sym);
101 stab_section->sh_addralign = sizeof ((Stab_Sym*)0)->n_value;
102 stab_section->link = new_section(s, ".stabstr", SHT_STRTAB, shf);
103 /* put first entry */
104 put_stabs(s, "", 0, 0, 0, 0);
107 static void free_section(Section *s)
109 tcc_free(s->data);
112 ST_FUNC void tccelf_delete(TCCState *s1)
114 int i;
116 #ifndef ELF_OBJ_ONLY
117 /* free symbol versions */
118 for (i = 0; i < nb_sym_versions; i++) {
119 tcc_free(sym_versions[i].version);
120 tcc_free(sym_versions[i].lib);
122 tcc_free(sym_versions);
123 tcc_free(sym_to_version);
124 #endif
126 /* free all sections */
127 for(i = 1; i < s1->nb_sections; i++)
128 free_section(s1->sections[i]);
129 dynarray_reset(&s1->sections, &s1->nb_sections);
131 for(i = 0; i < s1->nb_priv_sections; i++)
132 free_section(s1->priv_sections[i]);
133 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
135 /* free any loaded DLLs */
136 #ifdef TCC_IS_NATIVE
137 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
138 DLLReference *ref = s1->loaded_dlls[i];
139 if ( ref->handle )
140 # ifdef _WIN32
141 FreeLibrary((HMODULE)ref->handle);
142 # else
143 dlclose(ref->handle);
144 # endif
146 #endif
147 /* free loaded dlls array */
148 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
149 tcc_free(s1->sym_attrs);
151 symtab_section = NULL; /* for tccrun.c:rt_printline() */
154 /* save section data state */
155 ST_FUNC void tccelf_begin_file(TCCState *s1)
157 Section *s; int i;
158 for (i = 1; i < s1->nb_sections; i++) {
159 s = s1->sections[i];
160 s->sh_offset = s->data_offset;
162 /* disable symbol hashing during compilation */
163 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
164 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
165 s1->uw_sym = 0;
166 #endif
169 /* At the end of compilation, convert any UNDEF syms to global, and merge
170 with previously existing symbols */
171 ST_FUNC void tccelf_end_file(TCCState *s1)
173 Section *s = s1->symtab;
174 int first_sym, nb_syms, *tr, i;
176 first_sym = s->sh_offset / sizeof (ElfSym);
177 nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
178 s->data_offset = s->sh_offset;
179 s->link->data_offset = s->link->sh_offset;
180 s->hash = s->reloc, s->reloc = NULL;
181 tr = tcc_mallocz(nb_syms * sizeof *tr);
183 for (i = 0; i < nb_syms; ++i) {
184 ElfSym *sym = (ElfSym*)s->data + first_sym + i;
185 if (sym->st_shndx == SHN_UNDEF
186 && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
187 sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
188 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
189 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
191 /* now update relocations */
192 for (i = 1; i < s1->nb_sections; i++) {
193 Section *sr = s1->sections[i];
194 if (sr->sh_type == SHT_RELX && sr->link == s) {
195 ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
196 ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
197 for (; rel < rel_end; ++rel) {
198 int n = ELFW(R_SYM)(rel->r_info) - first_sym;
199 //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
200 rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
204 tcc_free(tr);
206 /* record text/data/bss output for -bench info */
207 for (i = 0; i < 3; ++i) {
208 s = s1->sections[i + 1];
209 s1->total_output[i] += s->data_offset - s->sh_offset;
213 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
215 Section *sec;
217 sec = tcc_mallocz(sizeof(Section) + strlen(name));
218 sec->s1 = s1;
219 strcpy(sec->name, name);
220 sec->sh_type = sh_type;
221 sec->sh_flags = sh_flags;
222 switch(sh_type) {
223 case SHT_GNU_versym:
224 sec->sh_addralign = 2;
225 break;
226 case SHT_HASH:
227 case SHT_REL:
228 case SHT_RELA:
229 case SHT_DYNSYM:
230 case SHT_SYMTAB:
231 case SHT_DYNAMIC:
232 case SHT_GNU_verneed:
233 case SHT_GNU_verdef:
234 sec->sh_addralign = PTR_SIZE;
235 break;
236 case SHT_STRTAB:
237 sec->sh_addralign = 1;
238 break;
239 default:
240 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */
241 break;
244 if (sh_flags & SHF_PRIVATE) {
245 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
246 } else {
247 sec->sh_num = s1->nb_sections;
248 dynarray_add(&s1->sections, &s1->nb_sections, sec);
251 return sec;
254 ST_FUNC Section *new_symtab(TCCState *s1,
255 const char *symtab_name, int sh_type, int sh_flags,
256 const char *strtab_name,
257 const char *hash_name, int hash_sh_flags)
259 Section *symtab, *strtab, *hash;
260 int *ptr, nb_buckets;
262 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
263 symtab->sh_entsize = sizeof(ElfW(Sym));
264 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
265 put_elf_str(strtab, "");
266 symtab->link = strtab;
267 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
269 nb_buckets = 1;
271 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
272 hash->sh_entsize = sizeof(int);
273 symtab->hash = hash;
274 hash->link = symtab;
276 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
277 ptr[0] = nb_buckets;
278 ptr[1] = 1;
279 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
280 return symtab;
283 /* realloc section and set its content to zero */
284 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
286 unsigned long size;
287 unsigned char *data;
289 size = sec->data_allocated;
290 if (size == 0)
291 size = 1;
292 while (size < new_size)
293 size = size * 2;
294 data = tcc_realloc(sec->data, size);
295 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
296 sec->data = data;
297 sec->data_allocated = size;
300 /* reserve at least 'size' bytes aligned per 'align' in section
301 'sec' from current offset, and return the aligned offset */
302 ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
304 size_t offset, offset1;
306 offset = (sec->data_offset + align - 1) & -align;
307 offset1 = offset + size;
308 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
309 section_realloc(sec, offset1);
310 sec->data_offset = offset1;
311 if (align > sec->sh_addralign)
312 sec->sh_addralign = align;
313 return offset;
316 /* reserve at least 'size' bytes in section 'sec' from
317 sec->data_offset. */
318 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
320 size_t offset = section_add(sec, size, 1);
321 return sec->data + offset;
324 #ifndef ELF_OBJ_ONLY
325 /* reserve at least 'size' bytes from section start */
326 static void section_reserve(Section *sec, unsigned long size)
328 if (size > sec->data_allocated)
329 section_realloc(sec, size);
330 if (size > sec->data_offset)
331 sec->data_offset = size;
333 #endif
335 static Section *find_section_create (TCCState *s1, const char *name, int create)
337 Section *sec;
338 int i;
339 for(i = 1; i < s1->nb_sections; i++) {
340 sec = s1->sections[i];
341 if (!strcmp(name, sec->name))
342 return sec;
344 /* sections are created as PROGBITS */
345 return create ? new_section(s1, name, SHT_PROGBITS, SHF_ALLOC) : NULL;
348 /* return a reference to a section, and create it if it does not
349 exists */
350 ST_FUNC Section *find_section(TCCState *s1, const char *name)
352 return find_section_create (s1, name, 1);
355 /* ------------------------------------------------------------------------- */
357 ST_FUNC int put_elf_str(Section *s, const char *sym)
359 int offset, len;
360 char *ptr;
362 len = strlen(sym) + 1;
363 offset = s->data_offset;
364 ptr = section_ptr_add(s, len);
365 memmove(ptr, sym, len);
366 return offset;
369 /* elf symbol hashing function */
370 static unsigned long elf_hash(const unsigned char *name)
372 unsigned long h = 0, g;
374 while (*name) {
375 h = (h << 4) + *name++;
376 g = h & 0xf0000000;
377 if (g)
378 h ^= g >> 24;
379 h &= ~g;
381 return h;
384 /* rebuild hash table of section s */
385 /* NOTE: we do factorize the hash table code to go faster */
386 static void rebuild_hash(Section *s, unsigned int nb_buckets)
388 ElfW(Sym) *sym;
389 int *ptr, *hash, nb_syms, sym_index, h;
390 unsigned char *strtab;
392 strtab = s->link->data;
393 nb_syms = s->data_offset / sizeof(ElfW(Sym));
395 if (!nb_buckets)
396 nb_buckets = ((int*)s->hash->data)[0];
398 s->hash->data_offset = 0;
399 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
400 ptr[0] = nb_buckets;
401 ptr[1] = nb_syms;
402 ptr += 2;
403 hash = ptr;
404 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
405 ptr += nb_buckets + 1;
407 sym = (ElfW(Sym) *)s->data + 1;
408 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
409 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
410 h = elf_hash(strtab + sym->st_name) % nb_buckets;
411 *ptr = hash[h];
412 hash[h] = sym_index;
413 } else {
414 *ptr = 0;
416 ptr++;
417 sym++;
421 /* return the symbol number */
422 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
423 int info, int other, int shndx, const char *name)
425 int name_offset, sym_index;
426 int nbuckets, h;
427 ElfW(Sym) *sym;
428 Section *hs;
430 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
431 if (name && name[0])
432 name_offset = put_elf_str(s->link, name);
433 else
434 name_offset = 0;
435 /* XXX: endianness */
436 sym->st_name = name_offset;
437 sym->st_value = value;
438 sym->st_size = size;
439 sym->st_info = info;
440 sym->st_other = other;
441 sym->st_shndx = shndx;
442 sym_index = sym - (ElfW(Sym) *)s->data;
443 hs = s->hash;
444 if (hs) {
445 int *ptr, *base;
446 ptr = section_ptr_add(hs, sizeof(int));
447 base = (int *)hs->data;
448 /* only add global or weak symbols. */
449 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
450 /* add another hashing entry */
451 nbuckets = base[0];
452 h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
453 *ptr = base[2 + h];
454 base[2 + h] = sym_index;
455 base[1]++;
456 /* we resize the hash table */
457 hs->nb_hashed_syms++;
458 if (hs->nb_hashed_syms > 2 * nbuckets) {
459 rebuild_hash(s, 2 * nbuckets);
461 } else {
462 *ptr = 0;
463 base[1]++;
466 return sym_index;
469 ST_FUNC int find_elf_sym(Section *s, const char *name)
471 ElfW(Sym) *sym;
472 Section *hs;
473 int nbuckets, sym_index, h;
474 const char *name1;
476 hs = s->hash;
477 if (!hs)
478 return 0;
479 nbuckets = ((int *)hs->data)[0];
480 h = elf_hash((unsigned char *) name) % nbuckets;
481 sym_index = ((int *)hs->data)[2 + h];
482 while (sym_index != 0) {
483 sym = &((ElfW(Sym) *)s->data)[sym_index];
484 name1 = (char *) s->link->data + sym->st_name;
485 if (!strcmp(name, name1))
486 return sym_index;
487 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
489 return 0;
492 /* return elf symbol value, signal error if 'err' is nonzero, decorate
493 name if FORC */
494 ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
496 int sym_index;
497 ElfW(Sym) *sym;
498 char buf[256];
499 if (forc && s1->leading_underscore
500 #ifdef TCC_TARGET_PE
501 /* win32-32bit stdcall symbols always have _ already */
502 && !strchr(name, '@')
503 #endif
505 buf[0] = '_';
506 pstrcpy(buf + 1, sizeof(buf) - 1, name);
507 name = buf;
509 sym_index = find_elf_sym(s1->symtab, name);
510 sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
511 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
512 if (err)
513 tcc_error("%s not defined", name);
514 return (addr_t)-1;
516 return sym->st_value;
519 /* return elf symbol value */
520 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
522 addr_t addr = get_sym_addr(s, name, 0, 1);
523 return addr == -1 ? NULL : (void*)(uintptr_t)addr;
526 /* list elf symbol names and values */
527 ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
528 void (*symbol_cb)(void *ctx, const char *name, const void *val))
530 ElfW(Sym) *sym;
531 Section *symtab;
532 int sym_index, end_sym;
533 const char *name;
534 unsigned char sym_vis, sym_bind;
536 symtab = s->symtab;
537 end_sym = symtab->data_offset / sizeof (ElfSym);
538 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
539 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
540 if (sym->st_value) {
541 name = (char *) symtab->link->data + sym->st_name;
542 sym_bind = ELFW(ST_BIND)(sym->st_info);
543 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
544 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
545 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
550 /* list elf symbol names and values */
551 LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
552 void (*symbol_cb)(void *ctx, const char *name, const void *val))
554 list_elf_symbols(s, ctx, symbol_cb);
557 #ifndef ELF_OBJ_ONLY
558 static void
559 version_add (TCCState *s1)
561 int i;
562 ElfW(Sym) *sym;
563 ElfW(Verneed) *vn = NULL;
564 Section *symtab;
565 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
566 ElfW(Half) *versym;
567 const char *name;
569 if (0 == nb_sym_versions)
570 return;
571 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
572 versym_section->sh_entsize = sizeof(ElfW(Half));
573 versym_section->link = s1->dynsym;
575 /* add needed symbols */
576 symtab = s1->dynsym;
577 end_sym = symtab->data_offset / sizeof (ElfSym);
578 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
579 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
580 int dllindex, verndx;
581 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
582 name = (char *) symtab->link->data + sym->st_name;
583 dllindex = find_elf_sym(s1->dynsymtab_section, name);
584 verndx = (dllindex && dllindex < nb_sym_to_version)
585 ? sym_to_version[dllindex] : -1;
586 if (verndx >= 0) {
587 if (!sym_versions[verndx].out_index)
588 sym_versions[verndx].out_index = nb_versions++;
589 versym[sym_index] = sym_versions[verndx].out_index;
590 } else
591 versym[sym_index] = 0;
593 /* generate verneed section, but not when it will be empty. Some
594 dynamic linkers look at their contents even when DTVERNEEDNUM and
595 section size is zero. */
596 if (nb_versions > 2) {
597 verneed_section = new_section(s1, ".gnu.version_r",
598 SHT_GNU_verneed, SHF_ALLOC);
599 verneed_section->link = s1->dynsym->link;
600 for (i = nb_sym_versions; i-- > 0;) {
601 struct sym_version *sv = &sym_versions[i];
602 int n_same_libs = 0, prev;
603 size_t vnofs;
604 ElfW(Vernaux) *vna = 0;
605 if (sv->out_index < 1)
606 continue;
607 vnofs = section_add(verneed_section, sizeof(*vn), 1);
608 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
609 vn->vn_version = 1;
610 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
611 vn->vn_aux = sizeof (*vn);
612 do {
613 prev = sv->prev_same_lib;
614 if (sv->out_index > 0) {
615 vna = section_ptr_add(verneed_section, sizeof(*vna));
616 vna->vna_hash = elf_hash ((const unsigned char *)sv->version);
617 vna->vna_flags = 0;
618 vna->vna_other = sv->out_index;
619 sv->out_index = -2;
620 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
621 vna->vna_next = sizeof (*vna);
622 n_same_libs++;
624 if (prev >= 0)
625 sv = &sym_versions[prev];
626 } while(prev >= 0);
627 vna->vna_next = 0;
628 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
629 vn->vn_cnt = n_same_libs;
630 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
631 nb_entries++;
633 if (vn)
634 vn->vn_next = 0;
635 verneed_section->sh_info = nb_entries;
637 dt_verneednum = nb_entries;
639 #endif
641 /* add an elf symbol : check if it is already defined and patch
642 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
643 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
644 int info, int other, int shndx, const char *name)
646 TCCState *s1 = s->s1;
647 ElfW(Sym) *esym;
648 int sym_bind, sym_index, sym_type, esym_bind;
649 unsigned char sym_vis, esym_vis, new_vis;
651 sym_bind = ELFW(ST_BIND)(info);
652 sym_type = ELFW(ST_TYPE)(info);
653 sym_vis = ELFW(ST_VISIBILITY)(other);
655 if (sym_bind != STB_LOCAL) {
656 /* we search global or weak symbols */
657 sym_index = find_elf_sym(s, name);
658 if (!sym_index)
659 goto do_def;
660 esym = &((ElfW(Sym) *)s->data)[sym_index];
661 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
662 && esym->st_other == other && esym->st_shndx == shndx)
663 return sym_index;
664 if (esym->st_shndx != SHN_UNDEF) {
665 esym_bind = ELFW(ST_BIND)(esym->st_info);
666 /* propagate the most constraining visibility */
667 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
668 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
669 if (esym_vis == STV_DEFAULT) {
670 new_vis = sym_vis;
671 } else if (sym_vis == STV_DEFAULT) {
672 new_vis = esym_vis;
673 } else {
674 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
676 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
677 | new_vis;
678 other = esym->st_other; /* in case we have to patch esym */
679 if (shndx == SHN_UNDEF) {
680 /* ignore adding of undefined symbol if the
681 corresponding symbol is already defined */
682 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
683 /* global overrides weak, so patch */
684 goto do_patch;
685 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
686 /* weak is ignored if already global */
687 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
688 /* keep first-found weak definition, ignore subsequents */
689 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
690 /* ignore hidden symbols after */
691 } else if ((esym->st_shndx == SHN_COMMON
692 || esym->st_shndx == bss_section->sh_num)
693 && (shndx < SHN_LORESERVE
694 && shndx != bss_section->sh_num)) {
695 /* data symbol gets precedence over common/bss */
696 goto do_patch;
697 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
698 /* data symbol keeps precedence over common/bss */
699 } else if (s->sh_flags & SHF_DYNSYM) {
700 /* we accept that two DLL define the same symbol */
701 } else if (esym->st_other & ST_ASM_SET) {
702 /* If the existing symbol came from an asm .set
703 we can override. */
704 goto do_patch;
705 } else {
706 #if 0
707 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
708 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
709 #endif
710 tcc_error_noabort("'%s' defined twice", name);
712 } else {
713 do_patch:
714 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
715 esym->st_shndx = shndx;
716 s1->new_undef_sym = 1;
717 esym->st_value = value;
718 esym->st_size = size;
719 esym->st_other = other;
721 } else {
722 do_def:
723 sym_index = put_elf_sym(s, value, size,
724 ELFW(ST_INFO)(sym_bind, sym_type), other,
725 shndx, name);
727 return sym_index;
730 /* put relocation */
731 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
732 int type, int symbol, addr_t addend)
734 TCCState *s1 = s->s1;
735 char buf[256];
736 Section *sr;
737 ElfW_Rel *rel;
739 sr = s->reloc;
740 if (!sr) {
741 /* if no relocation section, create it */
742 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
743 /* if the symtab is allocated, then we consider the relocation
744 are also */
745 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
746 sr->sh_entsize = sizeof(ElfW_Rel);
747 sr->link = symtab;
748 sr->sh_info = s->sh_num;
749 s->reloc = sr;
751 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
752 rel->r_offset = offset;
753 rel->r_info = ELFW(R_INFO)(symbol, type);
754 #if SHT_RELX == SHT_RELA
755 rel->r_addend = addend;
756 #endif
757 if (SHT_RELX != SHT_RELA && addend)
758 tcc_error("non-zero addend on REL architecture");
761 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
762 int type, int symbol)
764 put_elf_reloca(symtab, s, offset, type, symbol, 0);
767 /* put stab debug information */
768 ST_FUNC void put_stabs(TCCState *s1, const char *str, int type, int other, int desc,
769 unsigned long value)
771 Stab_Sym *sym;
773 unsigned offset;
774 if (type == N_SLINE
775 && (offset = stab_section->data_offset)
776 && (sym = (Stab_Sym*)(stab_section->data + offset) - 1)
777 && sym->n_type == type
778 && sym->n_value == value) {
779 /* just update line_number in previous entry */
780 sym->n_desc = desc;
781 return;
784 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
785 if (str) {
786 sym->n_strx = put_elf_str(stab_section->link, str);
787 } else {
788 sym->n_strx = 0;
790 sym->n_type = type;
791 sym->n_other = other;
792 sym->n_desc = desc;
793 sym->n_value = value;
796 ST_FUNC void put_stabs_r(TCCState *s1, const char *str, int type, int other, int desc,
797 unsigned long value, Section *sec, int sym_index)
799 put_elf_reloc(symtab_section, stab_section,
800 stab_section->data_offset + 8,
801 sizeof ((Stab_Sym*)0)->n_value == PTR_SIZE ? R_DATA_PTR : R_DATA_32,
802 sym_index);
803 put_stabs(s1, str, type, other, desc, value);
806 ST_FUNC void put_stabn(TCCState *s1, int type, int other, int desc, int value)
808 put_stabs(s1, NULL, type, other, desc, value);
811 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
813 int n;
814 struct sym_attr *tab;
816 if (index >= s1->nb_sym_attrs) {
817 if (!alloc)
818 return s1->sym_attrs;
819 /* find immediately bigger power of 2 and reallocate array */
820 n = 1;
821 while (index >= n)
822 n *= 2;
823 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
824 s1->sym_attrs = tab;
825 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
826 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
827 s1->nb_sym_attrs = n;
829 return &s1->sym_attrs[index];
832 /* In an ELF file symbol table, the local symbols must appear below
833 the global and weak ones. Since TCC cannot sort it while generating
834 the code, we must do it after. All the relocation tables are also
835 modified to take into account the symbol table sorting */
836 static void sort_syms(TCCState *s1, Section *s)
838 int *old_to_new_syms;
839 ElfW(Sym) *new_syms;
840 int nb_syms, i;
841 ElfW(Sym) *p, *q;
842 ElfW_Rel *rel;
843 Section *sr;
844 int type, sym_index;
846 nb_syms = s->data_offset / sizeof(ElfW(Sym));
847 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
848 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
850 /* first pass for local symbols */
851 p = (ElfW(Sym) *)s->data;
852 q = new_syms;
853 for(i = 0; i < nb_syms; i++) {
854 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
855 old_to_new_syms[i] = q - new_syms;
856 *q++ = *p;
858 p++;
860 /* save the number of local symbols in section header */
861 if( s->sh_size ) /* this 'if' makes IDA happy */
862 s->sh_info = q - new_syms;
864 /* then second pass for non local symbols */
865 p = (ElfW(Sym) *)s->data;
866 for(i = 0; i < nb_syms; i++) {
867 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
868 old_to_new_syms[i] = q - new_syms;
869 *q++ = *p;
871 p++;
874 /* we copy the new symbols to the old */
875 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
876 tcc_free(new_syms);
878 /* now we modify all the relocations */
879 for(i = 1; i < s1->nb_sections; i++) {
880 sr = s1->sections[i];
881 if (sr->sh_type == SHT_RELX && sr->link == s) {
882 for_each_elem(sr, 0, rel, ElfW_Rel) {
883 sym_index = ELFW(R_SYM)(rel->r_info);
884 type = ELFW(R_TYPE)(rel->r_info);
885 sym_index = old_to_new_syms[sym_index];
886 rel->r_info = ELFW(R_INFO)(sym_index, type);
891 tcc_free(old_to_new_syms);
894 /* relocate symbol table, resolve undefined symbols if do_resolve is
895 true and output error if undefined symbol. */
896 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
898 ElfW(Sym) *sym;
899 int sym_bind, sh_num;
900 const char *name;
902 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
903 sh_num = sym->st_shndx;
904 if (sh_num == SHN_UNDEF) {
905 name = (char *) s1->symtab->link->data + sym->st_name;
906 /* Use ld.so to resolve symbol for us (for tcc -run) */
907 if (do_resolve) {
908 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
909 #ifdef TCC_TARGET_MACHO
910 /* The symbols in the symtables have a prepended '_'
911 but dlsym() needs the undecorated name. */
912 void *addr = dlsym(RTLD_DEFAULT, name + 1);
913 #else
914 void *addr = dlsym(RTLD_DEFAULT, name);
915 #endif
916 if (addr) {
917 sym->st_value = (addr_t) addr;
918 #ifdef DEBUG_RELOC
919 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
920 #endif
921 goto found;
923 #endif
924 /* if dynamic symbol exist, it will be used in relocate_section */
925 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
926 goto found;
927 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
928 it */
929 if (!strcmp(name, "_fp_hw"))
930 goto found;
931 /* only weak symbols are accepted to be undefined. Their
932 value is zero */
933 sym_bind = ELFW(ST_BIND)(sym->st_info);
934 if (sym_bind == STB_WEAK)
935 sym->st_value = 0;
936 else
937 tcc_error_noabort("undefined symbol '%s'", name);
938 } else if (sh_num < SHN_LORESERVE) {
939 /* add section base */
940 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
942 found: ;
946 /* relocate a given section (CPU dependent) by applying the relocations
947 in the associated relocation section */
948 ST_FUNC void relocate_section(TCCState *s1, Section *s)
950 Section *sr = s->reloc;
951 ElfW_Rel *rel;
952 ElfW(Sym) *sym;
953 int type, sym_index;
954 unsigned char *ptr;
955 addr_t tgt, addr;
957 qrel = (ElfW_Rel *)sr->data;
959 for_each_elem(sr, 0, rel, ElfW_Rel) {
960 ptr = s->data + rel->r_offset;
961 sym_index = ELFW(R_SYM)(rel->r_info);
962 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
963 type = ELFW(R_TYPE)(rel->r_info);
964 tgt = sym->st_value;
965 #if SHT_RELX == SHT_RELA
966 tgt += rel->r_addend;
967 #endif
968 addr = s->sh_addr + rel->r_offset;
969 relocate(s1, rel, type, ptr, addr, tgt);
971 /* if the relocation is allocated, we change its symbol table */
972 if (sr->sh_flags & SHF_ALLOC) {
973 sr->link = s1->dynsym;
974 if (s1->output_type == TCC_OUTPUT_DLL) {
975 size_t r = (uint8_t*)qrel - sr->data;
976 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
977 && 0 == strcmp(s->name, ".stab"))
978 r = 0; /* cannot apply 64bit relocation to 32bit value */
979 sr->data_offset = sr->sh_size = r;
984 #ifndef ELF_OBJ_ONLY
985 /* relocate relocation table in 'sr' */
986 static void relocate_rel(TCCState *s1, Section *sr)
988 Section *s;
989 ElfW_Rel *rel;
991 s = s1->sections[sr->sh_info];
992 for_each_elem(sr, 0, rel, ElfW_Rel)
993 rel->r_offset += s->sh_addr;
996 /* count the number of dynamic relocations so that we can reserve
997 their space */
998 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
1000 int count = 0;
1001 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1002 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1003 defined(TCC_TARGET_RISCV64)
1004 ElfW_Rel *rel;
1005 for_each_elem(sr, 0, rel, ElfW_Rel) {
1006 int sym_index = ELFW(R_SYM)(rel->r_info);
1007 int type = ELFW(R_TYPE)(rel->r_info);
1008 switch(type) {
1009 #if defined(TCC_TARGET_I386)
1010 case R_386_32:
1011 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
1012 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
1013 /* don't fixup unresolved (weak) symbols */
1014 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
1015 break;
1017 #elif defined(TCC_TARGET_X86_64)
1018 case R_X86_64_32:
1019 case R_X86_64_32S:
1020 case R_X86_64_64:
1021 #elif defined(TCC_TARGET_ARM)
1022 case R_ARM_ABS32:
1023 #elif defined(TCC_TARGET_ARM64)
1024 case R_AARCH64_ABS32:
1025 case R_AARCH64_ABS64:
1026 #elif defined(TCC_TARGET_RISCV64)
1027 case R_RISCV_32:
1028 case R_RISCV_64:
1029 #endif
1030 count++;
1031 break;
1032 #if defined(TCC_TARGET_I386)
1033 case R_386_PC32:
1034 #elif defined(TCC_TARGET_X86_64)
1035 case R_X86_64_PC32:
1036 #elif defined(TCC_TARGET_ARM64)
1037 case R_AARCH64_PREL32:
1038 #endif
1039 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1040 count++;
1041 break;
1042 default:
1043 break;
1046 if (count) {
1047 /* allocate the section */
1048 sr->sh_flags |= SHF_ALLOC;
1049 sr->sh_size = count * sizeof(ElfW_Rel);
1051 #endif
1052 return count;
1054 #endif
1056 #if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE)
1057 static void build_got(TCCState *s1)
1059 /* if no got, then create it */
1060 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1061 s1->got->sh_entsize = 4;
1062 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1063 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1064 /* keep space for _DYNAMIC pointer and two dummy got entries */
1065 section_ptr_add(s1->got, 3 * PTR_SIZE);
1068 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1069 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1070 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1071 Returns the offset of the GOT or (if any) PLT entry. */
1072 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1073 int sym_index)
1075 int need_plt_entry;
1076 const char *name;
1077 ElfW(Sym) *sym;
1078 struct sym_attr *attr;
1079 unsigned got_offset;
1080 char plt_name[100];
1081 int len;
1083 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1084 attr = get_sym_attr(s1, sym_index, 1);
1086 /* In case a function is both called and its address taken 2 GOT entries
1087 are created, one for taking the address (GOT) and the other for the PLT
1088 entry (PLTGOT). */
1089 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1090 return attr;
1092 /* create the GOT entry */
1093 got_offset = s1->got->data_offset;
1094 section_ptr_add(s1->got, PTR_SIZE);
1096 /* Create the GOT relocation that will insert the address of the object or
1097 function of interest in the GOT entry. This is a static relocation for
1098 memory output (dlsym will give us the address of symbols) and dynamic
1099 relocation otherwise (executable and DLLs). The relocation should be
1100 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1101 associated to a PLT entry) but is currently done at load time for an
1102 unknown reason. */
1104 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1105 name = (char *) symtab_section->link->data + sym->st_name;
1107 if (s1->dynsym) {
1108 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1109 /* Hack alarm. We don't want to emit dynamic symbols
1110 and symbol based relocs for STB_LOCAL symbols, but rather
1111 want to resolve them directly. At this point the symbol
1112 values aren't final yet, so we must defer this. We will later
1113 have to create a RELATIVE reloc anyway, so we misuse the
1114 relocation slot to smuggle the symbol reference until
1115 fill_local_got_entries. Not that the sym_index is
1116 relative to symtab_section, not s1->dynsym! Nevertheless
1117 we use s1->dyn_sym so that if this is the first call
1118 that got->reloc is correctly created. Also note that
1119 RELATIVE relocs are not normally created for the .got,
1120 so the types serves as a marker for later (and is retained
1121 also for the final output, which is okay because then the
1122 got is just normal data). */
1123 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1124 sym_index);
1125 } else {
1126 if (0 == attr->dyn_index)
1127 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1128 sym->st_size, sym->st_info, 0,
1129 sym->st_shndx, name);
1130 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
1131 attr->dyn_index);
1133 } else {
1134 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1135 sym_index);
1138 if (need_plt_entry) {
1139 if (!s1->plt) {
1140 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1141 SHF_ALLOC | SHF_EXECINSTR);
1142 s1->plt->sh_entsize = 4;
1145 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1147 /* create a symbol 'sym@plt' for the PLT jump vector */
1148 len = strlen(name);
1149 if (len > sizeof plt_name - 5)
1150 len = sizeof plt_name - 5;
1151 memcpy(plt_name, name, len);
1152 strcpy(plt_name + len, "@plt");
1153 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
1154 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1156 } else {
1157 attr->got_offset = got_offset;
1160 return attr;
1163 /* build GOT and PLT entries */
1164 ST_FUNC void build_got_entries(TCCState *s1)
1166 Section *s;
1167 ElfW_Rel *rel;
1168 ElfW(Sym) *sym;
1169 int i, type, gotplt_entry, reloc_type, sym_index;
1170 struct sym_attr *attr;
1172 for(i = 1; i < s1->nb_sections; i++) {
1173 s = s1->sections[i];
1174 if (s->sh_type != SHT_RELX)
1175 continue;
1176 /* no need to handle got relocations */
1177 if (s->link != symtab_section)
1178 continue;
1179 for_each_elem(s, 0, rel, ElfW_Rel) {
1180 type = ELFW(R_TYPE)(rel->r_info);
1181 gotplt_entry = gotplt_entry_type(type);
1182 if (gotplt_entry == -1)
1183 tcc_error ("Unknown relocation type for got: %d", type);
1184 sym_index = ELFW(R_SYM)(rel->r_info);
1185 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1187 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1188 continue;
1191 /* Automatically create PLT/GOT [entry] if it is an undefined
1192 reference (resolved at runtime), or the symbol is absolute,
1193 probably created by tcc_add_symbol, and thus on 64-bit
1194 targets might be too far from application code. */
1195 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1196 if (sym->st_shndx == SHN_UNDEF) {
1197 ElfW(Sym) *esym;
1198 int dynindex;
1199 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1200 continue;
1201 /* Relocations for UNDEF symbols would normally need
1202 to be transferred into the executable or shared object.
1203 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1204 But TCC doesn't do that (at least for exes), so we
1205 need to resolve all such relocs locally. And that
1206 means PLT slots for functions in DLLs and COPY relocs for
1207 data symbols. COPY relocs were generated in
1208 bind_exe_dynsyms (and the symbol adjusted to be defined),
1209 and for functions we were generated a dynamic symbol
1210 of function type. */
1211 if (s1->dynsym) {
1212 /* dynsym isn't set for -run :-/ */
1213 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1214 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1215 if (dynindex
1216 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1217 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1218 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1219 goto jmp_slot;
1221 } else if (!(sym->st_shndx == SHN_ABS
1222 #ifndef TCC_TARGET_ARM
1223 && PTR_SIZE == 8
1224 #endif
1226 continue;
1229 #ifdef TCC_TARGET_X86_64
1230 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1231 sym->st_shndx != SHN_UNDEF &&
1232 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1233 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1234 s1->output_type == TCC_OUTPUT_EXE)) {
1235 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1236 continue;
1238 #endif
1239 reloc_type = code_reloc(type);
1240 if (reloc_type == -1)
1241 tcc_error ("Unknown relocation type: %d", type);
1242 else if (reloc_type != 0) {
1243 jmp_slot:
1244 reloc_type = R_JMP_SLOT;
1245 } else
1246 reloc_type = R_GLOB_DAT;
1248 if (!s1->got)
1249 build_got(s1);
1251 if (gotplt_entry == BUILD_GOT_ONLY)
1252 continue;
1254 attr = put_got_entry(s1, reloc_type, sym_index);
1256 if (reloc_type == R_JMP_SLOT)
1257 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1261 #endif
1263 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
1265 int shn = sec ? sec->sh_num : offs ? SHN_ABS : SHN_UNDEF;
1266 if (sec && offs == -1)
1267 offs = sec->data_offset;
1268 return set_elf_sym(symtab_section, offs, 0,
1269 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1272 static void add_init_array_defines(TCCState *s1, const char *section_name)
1274 Section *s;
1275 addr_t end_offset;
1276 char buf[1024];
1277 s = find_section(s1, section_name);
1278 if (!s) {
1279 end_offset = 0;
1280 s = data_section;
1281 } else {
1282 end_offset = s->data_offset;
1284 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1285 set_global_sym(s1, buf, s, 0);
1286 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1287 set_global_sym(s1, buf, s, end_offset);
1290 #ifndef TCC_TARGET_PE
1291 static void tcc_add_support(TCCState *s1, const char *filename)
1293 char buf[1024];
1294 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1295 tcc_add_file(s1, buf);
1297 #endif
1299 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1301 Section *s;
1302 s = find_section(s1, sec);
1303 s->sh_flags |= SHF_WRITE;
1304 #ifndef TCC_TARGET_PE
1305 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1306 #endif
1307 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1308 section_ptr_add(s, PTR_SIZE);
1311 #ifdef CONFIG_TCC_BCHECK
1312 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1314 if (0 == s1->do_bounds_check)
1315 return;
1316 section_ptr_add(bounds_section, sizeof(addr_t));
1318 #endif
1320 #ifdef CONFIG_TCC_BACKTRACE
1321 static void put_ptr(TCCState *s1, Section *s, int offs)
1323 int c;
1324 c = set_global_sym(s1, NULL, s, offs);
1325 s = data_section;
1326 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1327 section_ptr_add(s, PTR_SIZE);
1330 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1331 a dynamic symbol to allow so's to have one each with a different value. */
1332 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1334 int c = find_elf_sym(s1->symtab, name);
1335 if (c) {
1336 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1337 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1338 esym->st_value = offset;
1339 esym->st_shndx = s->sh_num;
1343 ST_FUNC void tcc_add_btstub(TCCState *s1)
1345 Section *s;
1346 int n, o;
1347 CString cstr;
1349 s = data_section;
1350 o = s->data_offset;
1351 /* create (part of) a struct rt_context (see tccrun.c) */
1352 put_ptr(s1, stab_section, 0);
1353 put_ptr(s1, stab_section, -1);
1354 put_ptr(s1, stab_section->link, 0);
1355 section_ptr_add(s, 3 * PTR_SIZE);
1356 /* prog_base */
1357 #ifndef TCC_TARGET_MACHO
1358 /* XXX this relocation is wrong, it uses sym-index 0 (local,undef) */
1359 put_elf_reloc(s1->symtab, s, s->data_offset, R_DATA_PTR, 0);
1360 #endif
1361 section_ptr_add(s, PTR_SIZE);
1362 n = 2 * PTR_SIZE;
1363 #ifdef CONFIG_TCC_BCHECK
1364 if (s1->do_bounds_check) {
1365 put_ptr(s1, bounds_section, 0);
1366 n -= PTR_SIZE;
1368 #endif
1369 section_ptr_add(s, n);
1371 cstr_new(&cstr);
1372 cstr_printf(&cstr,
1373 " extern void __bt_init(),*__rt_info[],__bt_init_dll();"
1374 "__attribute__((constructor)) static void __bt_init_rt(){");
1375 #ifdef TCC_TARGET_PE
1376 if (s1->output_type == TCC_OUTPUT_DLL)
1377 #ifdef CONFIG_TCC_BCHECK
1378 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1379 #else
1380 cstr_printf(&cstr, "__bt_init_dll(0);");
1381 #endif
1382 #endif
1383 cstr_printf(&cstr, "__bt_init(__rt_info,%d, 0);}",
1384 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1385 tcc_compile_string(s1, cstr.data);
1386 cstr_free(&cstr);
1387 set_local_sym(s1, &"___rt_info"[!s1->leading_underscore], s, o);
1389 #endif
1391 #ifndef TCC_TARGET_PE
1392 /* add tcc runtime libraries */
1393 ST_FUNC void tcc_add_runtime(TCCState *s1)
1395 s1->filetype = 0;
1396 #ifdef CONFIG_TCC_BCHECK
1397 tcc_add_bcheck(s1);
1398 #endif
1399 tcc_add_pragma_libs(s1);
1400 /* add libc */
1401 if (!s1->nostdlib) {
1402 if (s1->option_pthread)
1403 tcc_add_library_err(s1, "pthread");
1404 tcc_add_library_err(s1, "c");
1405 #ifdef TCC_LIBGCC
1406 if (!s1->static_link) {
1407 if (TCC_LIBGCC[0] == '/')
1408 tcc_add_file(s1, TCC_LIBGCC);
1409 else
1410 tcc_add_dll(s1, TCC_LIBGCC, 0);
1412 #endif
1413 #ifdef CONFIG_TCC_BCHECK
1414 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1415 tcc_add_library_err(s1, "pthread");
1416 tcc_add_library_err(s1, "dl");
1417 tcc_add_support(s1, "bcheck.o");
1419 #endif
1420 #ifdef CONFIG_TCC_BACKTRACE
1421 if (s1->do_backtrace) {
1422 if (s1->output_type == TCC_OUTPUT_EXE)
1423 tcc_add_support(s1, "bt-exe.o");
1424 if (s1->output_type != TCC_OUTPUT_DLL)
1425 tcc_add_support(s1, "bt-log.o");
1426 if (s1->output_type != TCC_OUTPUT_MEMORY)
1427 tcc_add_btstub(s1);
1429 #endif
1430 if (strlen(TCC_LIBTCC1) > 0)
1431 tcc_add_support(s1, TCC_LIBTCC1);
1432 #if defined(__OpenBSD__)
1433 /* add crt end if not memory output */
1434 if (s1->output_type != TCC_OUTPUT_MEMORY)
1435 tcc_add_crt(s1, "crtend.o");
1436 #elif !defined(TCC_TARGET_MACHO)
1437 /* add crt end if not memory output */
1438 if (s1->output_type != TCC_OUTPUT_MEMORY)
1439 tcc_add_crt(s1, "crtn.o");
1440 #endif
1443 #endif
1445 /* add various standard linker symbols (must be done after the
1446 sections are filled (for example after allocating common
1447 symbols)) */
1448 static void tcc_add_linker_symbols(TCCState *s1)
1450 char buf[1024];
1451 int i;
1452 Section *s;
1454 set_global_sym(s1, "_etext", text_section, -1);
1455 set_global_sym(s1, "_edata", data_section, -1);
1456 set_global_sym(s1, "_end", bss_section, -1);
1457 #ifdef TCC_TARGET_RISCV64
1458 /* XXX should be .sdata+0x800, not .data+0x800 */
1459 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1460 #endif
1461 /* horrible new standard ldscript defines */
1462 add_init_array_defines(s1, ".preinit_array");
1463 add_init_array_defines(s1, ".init_array");
1464 add_init_array_defines(s1, ".fini_array");
1465 /* add start and stop symbols for sections whose name can be
1466 expressed in C */
1467 for(i = 1; i < s1->nb_sections; i++) {
1468 s = s1->sections[i];
1469 if ((s->sh_flags & SHF_ALLOC)
1470 && (s->sh_type == SHT_PROGBITS
1471 || s->sh_type == SHT_STRTAB)) {
1472 const char *p;
1473 /* check if section name can be expressed in C */
1474 p = s->name;
1475 for(;;) {
1476 int c = *p;
1477 if (!c)
1478 break;
1479 if (!isid(c) && !isnum(c))
1480 goto next_sec;
1481 p++;
1483 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1484 set_global_sym(s1, buf, s, 0);
1485 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1486 set_global_sym(s1, buf, s, -1);
1488 next_sec: ;
1492 ST_FUNC void resolve_common_syms(TCCState *s1)
1494 ElfW(Sym) *sym;
1496 /* Allocate common symbols in BSS. */
1497 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1498 if (sym->st_shndx == SHN_COMMON) {
1499 /* symbol alignment is in st_value for SHN_COMMONs */
1500 sym->st_value = section_add(bss_section, sym->st_size,
1501 sym->st_value);
1502 sym->st_shndx = bss_section->sh_num;
1506 /* Now assign linker provided symbols their value. */
1507 tcc_add_linker_symbols(s1);
1510 static void tcc_output_binary(TCCState *s1, FILE *f,
1511 const int *sec_order)
1513 Section *s;
1514 int i, offset, size;
1516 offset = 0;
1517 for(i=1;i<s1->nb_sections;i++) {
1518 s = s1->sections[sec_order[i]];
1519 if (s->sh_type != SHT_NOBITS &&
1520 (s->sh_flags & SHF_ALLOC)) {
1521 while (offset < s->sh_offset) {
1522 fputc(0, f);
1523 offset++;
1525 size = s->sh_size;
1526 fwrite(s->data, 1, size, f);
1527 offset += size;
1532 #ifndef ELF_OBJ_ONLY
1533 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1535 int sym_index = ELFW(R_SYM) (rel->r_info);
1536 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1537 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1538 unsigned offset = attr->got_offset;
1540 if (0 == offset)
1541 return;
1542 section_reserve(s1->got, offset + PTR_SIZE);
1543 #if PTR_SIZE == 8
1544 write64le(s1->got->data + offset, sym->st_value);
1545 #else
1546 write32le(s1->got->data + offset, sym->st_value);
1547 #endif
1550 /* Perform relocation to GOT or PLT entries */
1551 ST_FUNC void fill_got(TCCState *s1)
1553 Section *s;
1554 ElfW_Rel *rel;
1555 int i;
1557 for(i = 1; i < s1->nb_sections; i++) {
1558 s = s1->sections[i];
1559 if (s->sh_type != SHT_RELX)
1560 continue;
1561 /* no need to handle got relocations */
1562 if (s->link != symtab_section)
1563 continue;
1564 for_each_elem(s, 0, rel, ElfW_Rel) {
1565 switch (ELFW(R_TYPE) (rel->r_info)) {
1566 case R_X86_64_GOT32:
1567 case R_X86_64_GOTPCREL:
1568 case R_X86_64_GOTPCRELX:
1569 case R_X86_64_REX_GOTPCRELX:
1570 case R_X86_64_PLT32:
1571 fill_got_entry(s1, rel);
1572 break;
1578 /* See put_got_entry for a description. This is the second stage
1579 where GOT references to local defined symbols are rewritten. */
1580 static void fill_local_got_entries(TCCState *s1)
1582 ElfW_Rel *rel;
1583 if (!s1->got->reloc)
1584 return;
1585 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1586 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1587 int sym_index = ELFW(R_SYM) (rel->r_info);
1588 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1589 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1590 unsigned offset = attr->got_offset;
1591 if (offset != rel->r_offset - s1->got->sh_addr)
1592 tcc_error_noabort("huh");
1593 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1594 #if SHT_RELX == SHT_RELA
1595 rel->r_addend = sym->st_value;
1596 #else
1597 /* All our REL architectures also happen to be 32bit LE. */
1598 write32le(s1->got->data + offset, sym->st_value);
1599 #endif
1604 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1605 in shared libraries and export non local defined symbols to shared libraries
1606 if -rdynamic switch was given on command line */
1607 static void bind_exe_dynsyms(TCCState *s1)
1609 const char *name;
1610 int sym_index, index;
1611 ElfW(Sym) *sym, *esym;
1612 int type;
1614 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1615 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1616 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1617 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1618 if (sym->st_shndx == SHN_UNDEF) {
1619 name = (char *) symtab_section->link->data + sym->st_name;
1620 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1621 if (sym_index) {
1622 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1623 type = ELFW(ST_TYPE)(esym->st_info);
1624 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1625 /* Indirect functions shall have STT_FUNC type in executable
1626 * dynsym section. Indeed, a dlsym call following a lazy
1627 * resolution would pick the symbol value from the
1628 * executable dynsym entry which would contain the address
1629 * of the function wanted by the caller of dlsym instead of
1630 * the address of the function that would return that
1631 * address */
1632 int dynindex
1633 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1634 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1635 name);
1636 int index = sym - (ElfW(Sym) *) symtab_section->data;
1637 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1638 } else if (type == STT_OBJECT) {
1639 unsigned long offset;
1640 ElfW(Sym) *dynsym;
1641 offset = bss_section->data_offset;
1642 /* XXX: which alignment ? */
1643 offset = (offset + 16 - 1) & -16;
1644 set_elf_sym (s1->symtab, offset, esym->st_size,
1645 esym->st_info, 0, bss_section->sh_num, name);
1646 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1647 esym->st_info, 0, bss_section->sh_num,
1648 name);
1650 /* Ensure R_COPY works for weak symbol aliases */
1651 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1652 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1653 if ((dynsym->st_value == esym->st_value)
1654 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1655 char *dynname = (char *) s1->dynsymtab_section->link->data
1656 + dynsym->st_name;
1657 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1658 dynsym->st_info, 0,
1659 bss_section->sh_num, dynname);
1660 break;
1665 put_elf_reloc(s1->dynsym, bss_section,
1666 offset, R_COPY, index);
1667 offset += esym->st_size;
1668 bss_section->data_offset = offset;
1670 } else {
1671 /* STB_WEAK undefined symbols are accepted */
1672 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1673 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1674 !strcmp(name, "_fp_hw")) {
1675 } else {
1676 tcc_error_noabort("undefined symbol '%s'", name);
1679 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1680 /* if -rdynamic option, then export all non local symbols */
1681 name = (char *) symtab_section->link->data + sym->st_name;
1682 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1683 0, sym->st_shndx, name);
1688 /* Bind symbols of libraries: export all non local symbols of executable that
1689 are referenced by shared libraries. The reason is that the dynamic loader
1690 search symbol first in executable and then in libraries. Therefore a
1691 reference to a symbol already defined by a library can still be resolved by
1692 a symbol in the executable. */
1693 static void bind_libs_dynsyms(TCCState *s1)
1695 const char *name;
1696 int sym_index;
1697 ElfW(Sym) *sym, *esym;
1699 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1700 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1701 sym_index = find_elf_sym(symtab_section, name);
1702 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1703 if (sym_index && sym->st_shndx != SHN_UNDEF
1704 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1705 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1706 sym->st_info, 0, sym->st_shndx, name);
1707 } else if (esym->st_shndx == SHN_UNDEF) {
1708 /* weak symbols can stay undefined */
1709 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1710 tcc_warning("undefined dynamic symbol '%s'", name);
1715 /* Export all non local symbols. This is used by shared libraries so that the
1716 non local symbols they define can resolve a reference in another shared
1717 library or in the executable. Correspondingly, it allows undefined local
1718 symbols to be resolved by other shared libraries or by the executable. */
1719 static void export_global_syms(TCCState *s1)
1721 int dynindex, index;
1722 const char *name;
1723 ElfW(Sym) *sym;
1725 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1726 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1727 name = (char *) symtab_section->link->data + sym->st_name;
1728 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1729 sym->st_info, 0, sym->st_shndx, name);
1730 index = sym - (ElfW(Sym) *) symtab_section->data;
1731 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1735 #endif
1737 /* Allocate strings for section names and decide if an unallocated section
1738 should be output.
1739 NOTE: the strsec section comes last, so its size is also correct ! */
1740 static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1742 int i;
1743 Section *s;
1744 int textrel = 0;
1746 /* Allocate strings for section names */
1747 for(i = 1; i < s1->nb_sections; i++) {
1748 s = s1->sections[i];
1749 /* when generating a DLL, we include relocations but we may
1750 patch them */
1751 #ifndef ELF_OBJ_ONLY
1752 if (file_type == TCC_OUTPUT_DLL &&
1753 s->sh_type == SHT_RELX &&
1754 !(s->sh_flags & SHF_ALLOC) &&
1755 (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
1756 prepare_dynamic_rel(s1, s)) {
1757 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1758 textrel = 1;
1759 } else
1760 #endif
1761 if ((s1->do_debug && s->sh_type != SHT_RELX) ||
1762 file_type == TCC_OUTPUT_OBJ ||
1763 (s->sh_flags & SHF_ALLOC) ||
1764 i == (s1->nb_sections - 1)
1765 #ifdef TCC_TARGET_ARM
1766 || s->sh_type == SHT_ARM_ATTRIBUTES
1767 #endif
1769 /* we output all sections if debug or object file */
1770 s->sh_size = s->data_offset;
1772 #ifdef TCC_TARGET_ARM
1773 /* XXX: Suppress stack unwinding section. */
1774 if (s->sh_type == SHT_ARM_EXIDX) {
1775 s->sh_flags = 0;
1776 s->sh_size = 0;
1778 #endif
1779 if (s->sh_size || (s->sh_flags & SHF_ALLOC))
1780 s->sh_name = put_elf_str(strsec, s->name);
1782 strsec->sh_size = strsec->data_offset;
1783 return textrel;
1786 /* Info to be copied in dynamic section */
1787 struct dyn_inf {
1788 Section *dynamic;
1789 Section *dynstr;
1790 unsigned long data_offset;
1791 addr_t rel_addr;
1792 addr_t rel_size;
1793 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1794 addr_t bss_addr;
1795 addr_t bss_size;
1796 #endif
1799 /* Assign sections to segments and decide how are sections laid out when loaded
1800 in memory. This function also fills corresponding program headers. */
1801 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1802 Section *interp, Section* strsec,
1803 struct dyn_inf *dyninf, int *sec_order)
1805 int i, j, k, file_type, sh_order_index, file_offset;
1806 unsigned long s_align;
1807 long long tmp;
1808 addr_t addr;
1809 ElfW(Phdr) *ph;
1810 Section *s;
1812 file_type = s1->output_type;
1813 sh_order_index = 1;
1814 file_offset = 0;
1815 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1816 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1817 s_align = ELF_PAGE_SIZE;
1818 if (s1->section_align)
1819 s_align = s1->section_align;
1821 if (phnum > 0) {
1822 if (s1->has_text_addr) {
1823 int a_offset, p_offset;
1824 addr = s1->text_addr;
1825 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1826 ELF_PAGE_SIZE */
1827 a_offset = (int) (addr & (s_align - 1));
1828 p_offset = file_offset & (s_align - 1);
1829 if (a_offset < p_offset)
1830 a_offset += s_align;
1831 file_offset += (a_offset - p_offset);
1832 } else {
1833 if (file_type == TCC_OUTPUT_DLL)
1834 addr = 0;
1835 else
1836 addr = ELF_START_ADDR;
1837 /* compute address after headers */
1838 addr += (file_offset & (s_align - 1));
1841 ph = &phdr[0];
1842 /* Leave one program headers for the program interpreter and one for
1843 the program header table itself if needed. These are done later as
1844 they require section layout to be done first. */
1845 if (interp)
1846 ph += 2;
1848 /* dynamic relocation table information, for .dynamic section */
1849 dyninf->rel_addr = dyninf->rel_size = 0;
1850 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1851 dyninf->bss_addr = dyninf->bss_size = 0;
1852 #endif
1854 for(j = 0; j < (phnum == 6 ? 3 : 2); j++) {
1855 ph->p_type = j == 2 ? PT_TLS : PT_LOAD;
1856 if (j == 0)
1857 ph->p_flags = PF_R | PF_X;
1858 else
1859 ph->p_flags = PF_R | PF_W;
1860 ph->p_align = j == 2 ? 4 : s_align;
1862 /* Decide the layout of sections loaded in memory. This must
1863 be done before program headers are filled since they contain
1864 info about the layout. We do the following ordering: interp,
1865 symbol tables, relocations, progbits, nobits */
1866 /* XXX: do faster and simpler sorting */
1867 for(k = 0; k < 5; k++) {
1868 for(i = 1; i < s1->nb_sections; i++) {
1869 s = s1->sections[i];
1870 /* compute if section should be included */
1871 if (j == 0) {
1872 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1873 SHF_ALLOC)
1874 continue;
1875 } else if (j == 1) {
1876 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1877 (SHF_ALLOC | SHF_WRITE))
1878 continue;
1879 } else {
1880 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1881 (SHF_ALLOC | SHF_WRITE | SHF_TLS))
1882 continue;
1884 if (s == interp) {
1885 if (k != 0)
1886 continue;
1887 } else if ((s->sh_type == SHT_DYNSYM ||
1888 s->sh_type == SHT_STRTAB ||
1889 s->sh_type == SHT_HASH)
1890 && !strstr(s->name, ".stab")) {
1891 if (k != 1)
1892 continue;
1893 } else if (s->sh_type == SHT_RELX) {
1894 if (k != 2)
1895 continue;
1896 } else if (s->sh_type == SHT_NOBITS) {
1897 if (k != 4)
1898 continue;
1899 } else {
1900 if (k != 3)
1901 continue;
1903 sec_order[sh_order_index++] = i;
1905 /* section matches: we align it and add its size */
1906 tmp = addr;
1907 addr = (addr + s->sh_addralign - 1) &
1908 ~(s->sh_addralign - 1);
1909 file_offset += (int) ( addr - tmp );
1910 s->sh_offset = file_offset;
1911 s->sh_addr = addr;
1913 /* update program header infos */
1914 if (ph->p_offset == 0) {
1915 ph->p_offset = file_offset;
1916 ph->p_vaddr = addr;
1917 ph->p_paddr = ph->p_vaddr;
1919 /* update dynamic relocation infos */
1920 if (s->sh_type == SHT_RELX) {
1921 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1922 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1923 dyninf->rel_addr = addr;
1924 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1926 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1927 dyninf->bss_addr = addr;
1928 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1930 #else
1931 if (dyninf->rel_size == 0)
1932 dyninf->rel_addr = addr;
1933 dyninf->rel_size += s->sh_size;
1934 #endif
1936 addr += s->sh_size;
1937 if (s->sh_type != SHT_NOBITS)
1938 file_offset += s->sh_size;
1941 if (j == 0) {
1942 /* Make the first PT_LOAD segment include the program
1943 headers itself (and the ELF header as well), it'll
1944 come out with same memory use but will make various
1945 tools like binutils strip work better. */
1946 ph->p_offset &= ~(ph->p_align - 1);
1947 ph->p_vaddr &= ~(ph->p_align - 1);
1948 ph->p_paddr &= ~(ph->p_align - 1);
1950 ph->p_filesz = file_offset - ph->p_offset;
1951 ph->p_memsz = addr - ph->p_vaddr;
1952 ph++;
1953 if (j == 0) {
1954 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1955 /* if in the middle of a page, we duplicate the page in
1956 memory so that one copy is RX and the other is RW */
1957 if ((addr & (s_align - 1)) != 0)
1958 addr += s_align;
1959 } else {
1960 addr = (addr + s_align - 1) & ~(s_align - 1);
1961 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1967 /* all other sections come after */
1968 for(i = 1; i < s1->nb_sections; i++) {
1969 s = s1->sections[i];
1970 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1971 continue;
1972 sec_order[sh_order_index++] = i;
1974 file_offset = (file_offset + s->sh_addralign - 1) &
1975 ~(s->sh_addralign - 1);
1976 s->sh_offset = file_offset;
1977 if (s->sh_type != SHT_NOBITS)
1978 file_offset += s->sh_size;
1981 return file_offset;
1984 #ifndef ELF_OBJ_ONLY
1985 /* put dynamic tag */
1986 static void put_dt(Section *dynamic, int dt, addr_t val)
1988 ElfW(Dyn) *dyn;
1989 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1990 dyn->d_tag = dt;
1991 dyn->d_un.d_val = val;
1994 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1995 Section *dynamic)
1997 ElfW(Phdr) *ph;
1999 /* if interpreter, then add corresponding program header */
2000 if (interp) {
2001 ph = &phdr[0];
2003 ph->p_type = PT_PHDR;
2004 ph->p_offset = sizeof(ElfW(Ehdr));
2005 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
2006 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
2007 ph->p_paddr = ph->p_vaddr;
2008 ph->p_flags = PF_R | PF_X;
2009 ph->p_align = 4; /* interp->sh_addralign; */
2010 ph++;
2012 ph->p_type = PT_INTERP;
2013 ph->p_offset = interp->sh_offset;
2014 ph->p_vaddr = interp->sh_addr;
2015 ph->p_paddr = ph->p_vaddr;
2016 ph->p_filesz = interp->sh_size;
2017 ph->p_memsz = interp->sh_size;
2018 ph->p_flags = PF_R;
2019 ph->p_align = interp->sh_addralign;
2022 /* if dynamic section, then add corresponding program header */
2023 if (dynamic) {
2024 ph = &phdr[phnum - 1];
2026 ph->p_type = PT_DYNAMIC;
2027 ph->p_offset = dynamic->sh_offset;
2028 ph->p_vaddr = dynamic->sh_addr;
2029 ph->p_paddr = ph->p_vaddr;
2030 ph->p_filesz = dynamic->sh_size;
2031 ph->p_memsz = dynamic->sh_size;
2032 ph->p_flags = PF_R | PF_W;
2033 ph->p_align = dynamic->sh_addralign;
2037 /* Fill the dynamic section with tags describing the address and size of
2038 sections */
2039 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2041 Section *dynamic = dyninf->dynamic;
2042 Section *s;
2044 /* put dynamic section entries */
2045 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2046 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2047 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2048 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2049 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2050 #if PTR_SIZE == 8
2051 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2052 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2053 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2054 #else
2055 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2056 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2057 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
2058 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2059 put_dt(dynamic, DT_PLTREL, DT_REL);
2060 put_dt(dynamic, DT_REL, dyninf->bss_addr);
2061 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
2062 #else
2063 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2064 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2065 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2066 #endif
2067 #endif
2068 if (versym_section)
2069 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2070 if (verneed_section) {
2071 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2072 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2074 s = find_section_create (s1, ".preinit_array", 0);
2075 if (s && s->data_offset) {
2076 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2077 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2079 s = find_section_create (s1, ".init_array", 0);
2080 if (s && s->data_offset) {
2081 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2082 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2084 s = find_section_create (s1, ".fini_array", 0);
2085 if (s && s->data_offset) {
2086 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2087 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2089 s = find_section_create (s1, ".init", 0);
2090 if (s && s->data_offset) {
2091 put_dt(dynamic, DT_INIT, s->sh_addr);
2093 s = find_section_create (s1, ".fini", 0);
2094 if (s && s->data_offset) {
2095 put_dt(dynamic, DT_FINI, s->sh_addr);
2097 if (s1->do_debug)
2098 put_dt(dynamic, DT_DEBUG, 0);
2099 put_dt(dynamic, DT_NULL, 0);
2102 /* Relocate remaining sections and symbols (that is those not related to
2103 dynamic linking) */
2104 static int final_sections_reloc(TCCState *s1)
2106 int i;
2107 Section *s;
2109 relocate_syms(s1, s1->symtab, 0);
2111 if (s1->nb_errors != 0)
2112 return -1;
2114 /* relocate sections */
2115 /* XXX: ignore sections with allocated relocations ? */
2116 for(i = 1; i < s1->nb_sections; i++) {
2117 s = s1->sections[i];
2118 if (s->reloc && (s != s1->got || s1->static_link))
2119 relocate_section(s1, s);
2122 /* relocate relocation entries if the relocation tables are
2123 allocated in the executable */
2124 for(i = 1; i < s1->nb_sections; i++) {
2125 s = s1->sections[i];
2126 if ((s->sh_flags & SHF_ALLOC) &&
2127 s->sh_type == SHT_RELX) {
2128 relocate_rel(s1, s);
2131 return 0;
2133 #endif
2135 /* Create an ELF file on disk.
2136 This function handle ELF specific layout requirements */
2137 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2138 int file_offset, int *sec_order)
2140 int i, shnum, offset, size, file_type;
2141 Section *s;
2142 ElfW(Ehdr) ehdr;
2143 ElfW(Shdr) shdr, *sh;
2145 file_type = s1->output_type;
2146 shnum = s1->nb_sections;
2148 memset(&ehdr, 0, sizeof(ehdr));
2150 if (phnum > 0) {
2151 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2152 ehdr.e_phnum = phnum;
2153 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2156 /* align to 4 */
2157 file_offset = (file_offset + 3) & -4;
2159 /* fill header */
2160 ehdr.e_ident[0] = ELFMAG0;
2161 ehdr.e_ident[1] = ELFMAG1;
2162 ehdr.e_ident[2] = ELFMAG2;
2163 ehdr.e_ident[3] = ELFMAG3;
2164 ehdr.e_ident[4] = ELFCLASSW;
2165 ehdr.e_ident[5] = ELFDATA2LSB;
2166 ehdr.e_ident[6] = EV_CURRENT;
2167 #if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
2168 /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
2169 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2170 #endif
2171 #ifdef TCC_TARGET_ARM
2172 #ifdef TCC_ARM_EABI
2173 ehdr.e_ident[EI_OSABI] = 0;
2174 ehdr.e_flags = EF_ARM_EABI_VER4;
2175 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2176 ehdr.e_flags |= EF_ARM_HASENTRY;
2177 if (s1->float_abi == ARM_HARD_FLOAT)
2178 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2179 else
2180 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2181 #else
2182 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2183 #endif
2184 #elif defined TCC_TARGET_RISCV64
2185 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2186 #endif
2187 switch(file_type) {
2188 default:
2189 case TCC_OUTPUT_EXE:
2190 ehdr.e_type = ET_EXEC;
2191 ehdr.e_entry = get_sym_addr(s1, "_start", 1, 0);
2192 break;
2193 case TCC_OUTPUT_DLL:
2194 ehdr.e_type = ET_DYN;
2195 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2196 break;
2197 case TCC_OUTPUT_OBJ:
2198 ehdr.e_type = ET_REL;
2199 break;
2201 ehdr.e_machine = EM_TCC_TARGET;
2202 ehdr.e_version = EV_CURRENT;
2203 ehdr.e_shoff = file_offset;
2204 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2205 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2206 ehdr.e_shnum = shnum;
2207 ehdr.e_shstrndx = shnum - 1;
2209 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2210 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2211 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2213 sort_syms(s1, symtab_section);
2214 for(i = 1; i < s1->nb_sections; i++) {
2215 s = s1->sections[sec_order[i]];
2216 if (s->sh_type != SHT_NOBITS) {
2217 while (offset < s->sh_offset) {
2218 fputc(0, f);
2219 offset++;
2221 size = s->sh_size;
2222 if (size)
2223 fwrite(s->data, 1, size, f);
2224 offset += size;
2228 /* output section headers */
2229 while (offset < ehdr.e_shoff) {
2230 fputc(0, f);
2231 offset++;
2234 for(i = 0; i < s1->nb_sections; i++) {
2235 sh = &shdr;
2236 memset(sh, 0, sizeof(ElfW(Shdr)));
2237 s = s1->sections[i];
2238 if (s) {
2239 sh->sh_name = s->sh_name;
2240 sh->sh_type = s->sh_type;
2241 sh->sh_flags = s->sh_flags;
2242 sh->sh_entsize = s->sh_entsize;
2243 sh->sh_info = s->sh_info;
2244 if (s->link)
2245 sh->sh_link = s->link->sh_num;
2246 sh->sh_addralign = s->sh_addralign;
2247 sh->sh_addr = s->sh_addr;
2248 sh->sh_offset = s->sh_offset;
2249 sh->sh_size = s->sh_size;
2251 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2255 /* Write an elf, coff or "binary" file */
2256 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2257 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2259 int fd, mode, file_type;
2260 FILE *f;
2262 file_type = s1->output_type;
2263 if (file_type == TCC_OUTPUT_OBJ)
2264 mode = 0666;
2265 else
2266 mode = 0777;
2267 unlink(filename);
2268 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2269 if (fd < 0) {
2270 tcc_error_noabort("could not write '%s'", filename);
2271 return -1;
2273 f = fdopen(fd, "wb");
2274 if (s1->verbose)
2275 printf("<- %s\n", filename);
2277 #ifdef TCC_TARGET_COFF
2278 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2279 tcc_output_coff(s1, f);
2280 else
2281 #endif
2282 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2283 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2284 else
2285 tcc_output_binary(s1, f, sec_order);
2286 fclose(f);
2288 return 0;
2291 #ifndef ELF_OBJ_ONLY
2292 /* Sort section headers by assigned sh_addr, remove sections
2293 that we aren't going to output. */
2294 static void tidy_section_headers(TCCState *s1, int *sec_order)
2296 int i, nnew, l, *backmap;
2297 Section **snew, *s;
2298 ElfW(Sym) *sym;
2300 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2301 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2302 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2303 s = s1->sections[sec_order[i]];
2304 if (!i || s->sh_name) {
2305 backmap[sec_order[i]] = nnew;
2306 snew[nnew] = s;
2307 ++nnew;
2308 } else {
2309 backmap[sec_order[i]] = 0;
2310 snew[--l] = s;
2313 for (i = 0; i < nnew; i++) {
2314 s = snew[i];
2315 if (s) {
2316 s->sh_num = i;
2317 if (s->sh_type == SHT_RELX)
2318 s->sh_info = backmap[s->sh_info];
2322 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2323 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2324 sym->st_shndx = backmap[sym->st_shndx];
2325 if ( !s1->static_link ) {
2326 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2327 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2328 sym->st_shndx = backmap[sym->st_shndx];
2330 for (i = 0; i < s1->nb_sections; i++)
2331 sec_order[i] = i;
2332 tcc_free(s1->sections);
2333 s1->sections = snew;
2334 s1->nb_sections = nnew;
2335 tcc_free(backmap);
2337 #endif
2339 #ifdef TCC_TARGET_ARM
2340 static void create_arm_attribute_section(TCCState *s1)
2342 // Needed for DLL support.
2343 static const unsigned char arm_attr[] = {
2344 0x41, // 'A'
2345 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2346 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2347 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2348 0x05, 0x36, 0x00, // 'CPU_name', "6"
2349 0x06, 0x06, // 'CPU_arch', 'v6'
2350 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2351 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2352 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2353 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2354 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2355 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2356 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2357 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2358 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2359 0x1a, 0x02, // 'ABI_enum_size', 'int'
2360 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2361 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2363 Section *attr = new_section(s1, ".ARM.attributes", SHT_ARM_ATTRIBUTES, 0);
2364 unsigned char *ptr = section_ptr_add(attr, sizeof(arm_attr));
2365 attr->sh_addralign = 1;
2366 memcpy(ptr, arm_attr, sizeof(arm_attr));
2367 if (s1->float_abi != ARM_HARD_FLOAT) {
2368 ptr[26] = 0x00; // 'FP_arch', 'No'
2369 ptr[41] = 0x1e; // 'ABI_optimization_goals'
2370 ptr[42] = 0x06; // 'Aggressive Debug'
2373 #endif
2375 /* Output an elf, coff or binary file */
2376 /* XXX: suppress unneeded sections */
2377 static int elf_output_file(TCCState *s1, const char *filename)
2379 int ret, phnum, shnum, file_type, file_offset, *sec_order;
2380 struct dyn_inf dyninf = {0};
2381 ElfW(Phdr) *phdr;
2382 Section *strsec, *interp, *dynamic, *dynstr;
2384 #ifdef TCC_TARGET_ARM
2385 create_arm_attribute_section (s1);
2386 #endif
2388 file_type = s1->output_type;
2389 s1->nb_errors = 0;
2390 ret = -1;
2391 phdr = NULL;
2392 sec_order = NULL;
2393 interp = dynamic = dynstr = NULL; /* avoid warning */
2395 #ifndef ELF_OBJ_ONLY
2396 if (file_type != TCC_OUTPUT_OBJ) {
2397 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2398 tcc_add_runtime(s1);
2399 resolve_common_syms(s1);
2401 if (!s1->static_link) {
2402 if (file_type == TCC_OUTPUT_EXE) {
2403 char *ptr;
2404 /* allow override the dynamic loader */
2405 const char *elfint = getenv("LD_SO");
2406 if (elfint == NULL)
2407 elfint = DEFAULT_ELFINTERP(s1);
2408 /* add interpreter section only if executable */
2409 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2410 interp->sh_addralign = 1;
2411 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2412 strcpy(ptr, elfint);
2415 /* add dynamic symbol table */
2416 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2417 ".dynstr",
2418 ".hash", SHF_ALLOC);
2419 dynstr = s1->dynsym->link;
2420 /* add dynamic section */
2421 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2422 SHF_ALLOC | SHF_WRITE);
2423 dynamic->link = dynstr;
2424 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2426 build_got(s1);
2428 if (file_type == TCC_OUTPUT_EXE) {
2429 bind_exe_dynsyms(s1);
2430 if (s1->nb_errors)
2431 goto the_end;
2432 bind_libs_dynsyms(s1);
2433 } else {
2434 /* shared library case: simply export all global symbols */
2435 export_global_syms(s1);
2438 build_got_entries(s1);
2439 version_add (s1);
2441 #endif
2443 /* we add a section for symbols */
2444 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2445 put_elf_str(strsec, "");
2447 /* Allocate strings for section names */
2448 ret = alloc_sec_names(s1, file_type, strsec);
2450 #ifndef ELF_OBJ_ONLY
2451 if (dynamic) {
2452 int i;
2453 /* add a list of needed dlls */
2454 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2455 DLLReference *dllref = s1->loaded_dlls[i];
2456 if (dllref->level == 0)
2457 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2460 if (s1->rpath)
2461 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2462 put_elf_str(dynstr, s1->rpath));
2464 if (file_type == TCC_OUTPUT_DLL) {
2465 if (s1->soname)
2466 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2467 /* XXX: currently, since we do not handle PIC code, we
2468 must relocate the readonly segments */
2469 if (ret)
2470 put_dt(dynamic, DT_TEXTREL, 0);
2473 if (s1->symbolic)
2474 put_dt(dynamic, DT_SYMBOLIC, 0);
2476 dyninf.dynamic = dynamic;
2477 dyninf.dynstr = dynstr;
2478 /* remember offset and reserve space for 2nd call below */
2479 dyninf.data_offset = dynamic->data_offset;
2480 fill_dynamic(s1, &dyninf);
2481 dynamic->sh_size = dynamic->data_offset;
2482 dynstr->sh_size = dynstr->data_offset;
2484 #endif
2486 /* compute number of program headers */
2487 if (file_type == TCC_OUTPUT_OBJ)
2488 phnum = 0;
2489 else if (file_type == TCC_OUTPUT_DLL)
2490 phnum = 3;
2491 else if (s1->static_link)
2492 phnum = 2;
2493 else {
2494 int i;
2495 for (i = 1; i < s1->nb_sections &&
2496 !(s1->sections[i]->sh_flags & SHF_TLS); i++);
2497 phnum = i < s1->nb_sections ? 6 : 5;
2500 /* allocate program segment headers */
2501 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2503 /* compute number of sections */
2504 shnum = s1->nb_sections;
2506 /* this array is used to reorder sections in the output file */
2507 sec_order = tcc_malloc(sizeof(int) * shnum);
2508 sec_order[0] = 0;
2510 /* compute section to program header mapping */
2511 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2512 sec_order);
2514 #ifndef ELF_OBJ_ONLY
2515 /* Fill remaining program header and finalize relocation related to dynamic
2516 linking. */
2517 if (file_type != TCC_OUTPUT_OBJ) {
2518 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2519 if (dynamic) {
2520 ElfW(Sym) *sym;
2521 dynamic->data_offset = dyninf.data_offset;
2522 fill_dynamic(s1, &dyninf);
2524 /* put in GOT the dynamic section address and relocate PLT */
2525 write32le(s1->got->data, dynamic->sh_addr);
2526 if (file_type == TCC_OUTPUT_EXE
2527 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2528 relocate_plt(s1);
2530 /* relocate symbols in .dynsym now that final addresses are known */
2531 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2532 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2533 /* do symbol relocation */
2534 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2539 /* if building executable or DLL, then relocate each section
2540 except the GOT which is already relocated */
2541 ret = final_sections_reloc(s1);
2542 if (ret)
2543 goto the_end;
2544 tidy_section_headers(s1, sec_order);
2546 /* Perform relocation to GOT or PLT entries */
2547 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2548 fill_got(s1);
2549 else if (s1->got)
2550 fill_local_got_entries(s1);
2552 #endif
2554 /* Create the ELF file with name 'filename' */
2555 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2556 s1->nb_sections = shnum;
2557 goto the_end;
2558 the_end:
2559 tcc_free(sec_order);
2560 tcc_free(phdr);
2561 return ret;
2564 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2566 int ret;
2567 #ifdef TCC_TARGET_PE
2568 if (s->output_type != TCC_OUTPUT_OBJ) {
2569 ret = pe_output_file(s, filename);
2570 } else
2571 #elif TCC_TARGET_MACHO
2572 if (s->output_type != TCC_OUTPUT_OBJ) {
2573 ret = macho_output_file(s, filename);
2574 } else
2575 #endif
2576 ret = elf_output_file(s, filename);
2577 return ret;
2580 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
2581 char *cbuf = buf;
2582 size_t rnum = 0;
2583 while (1) {
2584 ssize_t num = read(fd, cbuf, count-rnum);
2585 if (num < 0) return num;
2586 if (num == 0) return rnum;
2587 rnum += num;
2588 cbuf += num;
2592 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
2594 void *data;
2596 data = tcc_malloc(size);
2597 lseek(fd, file_offset, SEEK_SET);
2598 full_read(fd, data, size);
2599 return data;
2602 typedef struct SectionMergeInfo {
2603 Section *s; /* corresponding existing section */
2604 unsigned long offset; /* offset of the new section in the existing section */
2605 uint8_t new_section; /* true if section 's' was added */
2606 uint8_t link_once; /* true if link once section */
2607 } SectionMergeInfo;
2609 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2611 int size = full_read(fd, h, sizeof *h);
2612 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2613 if (h->e_type == ET_REL)
2614 return AFF_BINTYPE_REL;
2615 if (h->e_type == ET_DYN)
2616 return AFF_BINTYPE_DYN;
2617 } else if (size >= 8) {
2618 if (0 == memcmp(h, ARMAG, 8))
2619 return AFF_BINTYPE_AR;
2620 #ifdef TCC_TARGET_COFF
2621 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2622 return AFF_BINTYPE_C67;
2623 #endif
2625 return 0;
2628 /* load an object file and merge it with current files */
2629 /* XXX: handle correctly stab (debug) info */
2630 ST_FUNC int tcc_load_object_file(TCCState *s1,
2631 int fd, unsigned long file_offset)
2633 ElfW(Ehdr) ehdr;
2634 ElfW(Shdr) *shdr, *sh;
2635 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2636 char *strsec, *strtab;
2637 int stab_index, stabstr_index;
2638 int *old_to_new_syms;
2639 char *sh_name, *name;
2640 SectionMergeInfo *sm_table, *sm;
2641 ElfW(Sym) *sym, *symtab;
2642 ElfW_Rel *rel;
2643 Section *s;
2645 lseek(fd, file_offset, SEEK_SET);
2646 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2647 goto fail1;
2648 /* test CPU specific stuff */
2649 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2650 ehdr.e_machine != EM_TCC_TARGET) {
2651 fail1:
2652 tcc_error_noabort("invalid object file");
2653 return -1;
2655 /* read sections */
2656 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2657 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2658 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2660 /* load section names */
2661 sh = &shdr[ehdr.e_shstrndx];
2662 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2664 /* load symtab and strtab */
2665 old_to_new_syms = NULL;
2666 symtab = NULL;
2667 strtab = NULL;
2668 nb_syms = 0;
2669 seencompressed = 0;
2670 stab_index = stabstr_index = 0;
2672 for(i = 1; i < ehdr.e_shnum; i++) {
2673 sh = &shdr[i];
2674 if (sh->sh_type == SHT_SYMTAB) {
2675 if (symtab) {
2676 tcc_error_noabort("object must contain only one symtab");
2677 fail:
2678 ret = -1;
2679 goto the_end;
2681 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2682 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2683 sm_table[i].s = symtab_section;
2685 /* now load strtab */
2686 sh = &shdr[sh->sh_link];
2687 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2689 if (sh->sh_flags & SHF_COMPRESSED)
2690 seencompressed = 1;
2693 /* now examine each section and try to merge its content with the
2694 ones in memory */
2695 for(i = 1; i < ehdr.e_shnum; i++) {
2696 /* no need to examine section name strtab */
2697 if (i == ehdr.e_shstrndx)
2698 continue;
2699 sh = &shdr[i];
2700 if (sh->sh_type == SHT_RELX)
2701 sh = &shdr[sh->sh_info];
2702 /* ignore sections types we do not handle (plus relocs to those) */
2703 if (sh->sh_type != SHT_PROGBITS &&
2704 #ifdef TCC_ARM_EABI
2705 sh->sh_type != SHT_ARM_EXIDX &&
2706 #endif
2707 sh->sh_type != SHT_NOBITS &&
2708 sh->sh_type != SHT_PREINIT_ARRAY &&
2709 sh->sh_type != SHT_INIT_ARRAY &&
2710 sh->sh_type != SHT_FINI_ARRAY &&
2711 strcmp(strsec + sh->sh_name, ".stabstr")
2713 continue;
2714 if (seencompressed
2715 && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
2716 continue;
2718 sh = &shdr[i];
2719 sh_name = strsec + sh->sh_name;
2720 if (sh->sh_addralign < 1)
2721 sh->sh_addralign = 1;
2722 /* find corresponding section, if any */
2723 for(j = 1; j < s1->nb_sections;j++) {
2724 s = s1->sections[j];
2725 if (!strcmp(s->name, sh_name)) {
2726 if (!strncmp(sh_name, ".gnu.linkonce",
2727 sizeof(".gnu.linkonce") - 1)) {
2728 /* if a 'linkonce' section is already present, we
2729 do not add it again. It is a little tricky as
2730 symbols can still be defined in
2731 it. */
2732 sm_table[i].link_once = 1;
2733 goto next;
2735 if (stab_section) {
2736 if (s == stab_section)
2737 stab_index = i;
2738 if (s == stab_section->link)
2739 stabstr_index = i;
2741 goto found;
2744 /* not found: create new section */
2745 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2746 /* take as much info as possible from the section. sh_link and
2747 sh_info will be updated later */
2748 s->sh_addralign = sh->sh_addralign;
2749 s->sh_entsize = sh->sh_entsize;
2750 sm_table[i].new_section = 1;
2751 found:
2752 if (sh->sh_type != s->sh_type) {
2753 tcc_error_noabort("invalid section type");
2754 goto fail;
2756 /* align start of section */
2757 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
2758 if (sh->sh_addralign > s->sh_addralign)
2759 s->sh_addralign = sh->sh_addralign;
2760 sm_table[i].offset = s->data_offset;
2761 sm_table[i].s = s;
2762 /* concatenate sections */
2763 size = sh->sh_size;
2764 if (sh->sh_type != SHT_NOBITS) {
2765 unsigned char *ptr;
2766 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2767 ptr = section_ptr_add(s, size);
2768 full_read(fd, ptr, size);
2769 } else {
2770 s->data_offset += size;
2772 next: ;
2775 /* gr relocate stab strings */
2776 if (stab_index && stabstr_index) {
2777 Stab_Sym *a, *b;
2778 unsigned o;
2779 s = sm_table[stab_index].s;
2780 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2781 b = (Stab_Sym *)(s->data + s->data_offset);
2782 o = sm_table[stabstr_index].offset;
2783 while (a < b) {
2784 if (a->n_strx)
2785 a->n_strx += o;
2786 a++;
2790 /* second short pass to update sh_link and sh_info fields of new
2791 sections */
2792 for(i = 1; i < ehdr.e_shnum; i++) {
2793 s = sm_table[i].s;
2794 if (!s || !sm_table[i].new_section)
2795 continue;
2796 sh = &shdr[i];
2797 if (sh->sh_link > 0)
2798 s->link = sm_table[sh->sh_link].s;
2799 if (sh->sh_type == SHT_RELX) {
2800 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2801 /* update backward link */
2802 s1->sections[s->sh_info]->reloc = s;
2806 /* resolve symbols */
2807 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2809 sym = symtab + 1;
2810 for(i = 1; i < nb_syms; i++, sym++) {
2811 if (sym->st_shndx != SHN_UNDEF &&
2812 sym->st_shndx < SHN_LORESERVE) {
2813 sm = &sm_table[sym->st_shndx];
2814 if (sm->link_once) {
2815 /* if a symbol is in a link once section, we use the
2816 already defined symbol. It is very important to get
2817 correct relocations */
2818 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2819 name = strtab + sym->st_name;
2820 sym_index = find_elf_sym(symtab_section, name);
2821 if (sym_index)
2822 old_to_new_syms[i] = sym_index;
2824 continue;
2826 /* if no corresponding section added, no need to add symbol */
2827 if (!sm->s)
2828 continue;
2829 /* convert section number */
2830 sym->st_shndx = sm->s->sh_num;
2831 /* offset value */
2832 sym->st_value += sm->offset;
2834 /* add symbol */
2835 name = strtab + sym->st_name;
2836 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2837 sym->st_info, sym->st_other,
2838 sym->st_shndx, name);
2839 old_to_new_syms[i] = sym_index;
2842 /* third pass to patch relocation entries */
2843 for(i = 1; i < ehdr.e_shnum; i++) {
2844 s = sm_table[i].s;
2845 if (!s)
2846 continue;
2847 sh = &shdr[i];
2848 offset = sm_table[i].offset;
2849 switch(s->sh_type) {
2850 case SHT_RELX:
2851 /* take relocation offset information */
2852 offseti = sm_table[sh->sh_info].offset;
2853 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2854 int type;
2855 unsigned sym_index;
2856 /* convert symbol index */
2857 type = ELFW(R_TYPE)(rel->r_info);
2858 sym_index = ELFW(R_SYM)(rel->r_info);
2859 /* NOTE: only one symtab assumed */
2860 if (sym_index >= nb_syms)
2861 goto invalid_reloc;
2862 sym_index = old_to_new_syms[sym_index];
2863 /* ignore link_once in rel section. */
2864 if (!sym_index && !sm_table[sh->sh_info].link_once
2865 #ifdef TCC_TARGET_ARM
2866 && type != R_ARM_V4BX
2867 #elif defined TCC_TARGET_RISCV64
2868 && type != R_RISCV_ALIGN
2869 && type != R_RISCV_RELAX
2870 #endif
2872 invalid_reloc:
2873 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2874 i, strsec + sh->sh_name, (int)rel->r_offset);
2875 goto fail;
2877 rel->r_info = ELFW(R_INFO)(sym_index, type);
2878 /* offset the relocation offset */
2879 rel->r_offset += offseti;
2880 #ifdef TCC_TARGET_ARM
2881 /* Jumps and branches from a Thumb code to a PLT entry need
2882 special handling since PLT entries are ARM code.
2883 Unconditional bl instructions referencing PLT entries are
2884 handled by converting these instructions into blx
2885 instructions. Other case of instructions referencing a PLT
2886 entry require to add a Thumb stub before the PLT entry to
2887 switch to ARM mode. We set bit plt_thumb_stub of the
2888 attribute of a symbol to indicate such a case. */
2889 if (type == R_ARM_THM_JUMP24)
2890 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2891 #endif
2893 break;
2894 default:
2895 break;
2899 ret = 0;
2900 the_end:
2901 tcc_free(symtab);
2902 tcc_free(strtab);
2903 tcc_free(old_to_new_syms);
2904 tcc_free(sm_table);
2905 tcc_free(strsec);
2906 tcc_free(shdr);
2907 return ret;
2910 typedef struct ArchiveHeader {
2911 char ar_name[16]; /* name of this member */
2912 char ar_date[12]; /* file mtime */
2913 char ar_uid[6]; /* owner uid; printed as decimal */
2914 char ar_gid[6]; /* owner gid; printed as decimal */
2915 char ar_mode[8]; /* file mode, printed as octal */
2916 char ar_size[10]; /* file size, printed as decimal */
2917 char ar_fmag[2]; /* should contain ARFMAG */
2918 } ArchiveHeader;
2920 #define ARFMAG "`\n"
2922 static unsigned long long get_be(const uint8_t *b, int n)
2924 unsigned long long ret = 0;
2925 while (n)
2926 ret = (ret << 8) | *b++, --n;
2927 return ret;
2930 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
2932 char *p, *e;
2933 int len;
2934 lseek(fd, offset, SEEK_SET);
2935 len = full_read(fd, hdr, sizeof(ArchiveHeader));
2936 if (len != sizeof(ArchiveHeader))
2937 return len ? -1 : 0;
2938 p = hdr->ar_name;
2939 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
2940 --e;
2941 *e = '\0';
2942 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
2943 return len;
2946 /* load only the objects which resolve undefined symbols */
2947 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2949 int i, bound, nsyms, sym_index, len, ret = -1;
2950 unsigned long long off;
2951 uint8_t *data;
2952 const char *ar_names, *p;
2953 const uint8_t *ar_index;
2954 ElfW(Sym) *sym;
2955 ArchiveHeader hdr;
2957 data = tcc_malloc(size);
2958 if (full_read(fd, data, size) != size)
2959 goto the_end;
2960 nsyms = get_be(data, entrysize);
2961 ar_index = data + entrysize;
2962 ar_names = (char *) ar_index + nsyms * entrysize;
2964 do {
2965 bound = 0;
2966 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2967 Section *s = symtab_section;
2968 sym_index = find_elf_sym(s, p);
2969 if (!sym_index)
2970 continue;
2971 sym = &((ElfW(Sym) *)s->data)[sym_index];
2972 if(sym->st_shndx != SHN_UNDEF)
2973 continue;
2974 off = get_be(ar_index + i * entrysize, entrysize);
2975 len = read_ar_header(fd, off, &hdr);
2976 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
2977 tcc_error_noabort("invalid archive");
2978 goto the_end;
2980 off += len;
2981 if (s1->verbose == 2)
2982 printf(" -> %s\n", hdr.ar_name);
2983 if (tcc_load_object_file(s1, fd, off) < 0)
2984 goto the_end;
2985 ++bound;
2987 } while(bound);
2988 ret = 0;
2989 the_end:
2990 tcc_free(data);
2991 return ret;
2994 /* load a '.a' file */
2995 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
2997 ArchiveHeader hdr;
2998 /* char magic[8]; */
2999 int size, len;
3000 unsigned long file_offset;
3001 ElfW(Ehdr) ehdr;
3003 /* skip magic which was already checked */
3004 /* full_read(fd, magic, sizeof(magic)); */
3005 file_offset = sizeof ARMAG - 1;
3007 for(;;) {
3008 len = read_ar_header(fd, file_offset, &hdr);
3009 if (len == 0)
3010 return 0;
3011 if (len < 0) {
3012 tcc_error_noabort("invalid archive");
3013 return -1;
3015 file_offset += len;
3016 size = strtol(hdr.ar_size, NULL, 0);
3017 /* align to even */
3018 size = (size + 1) & ~1;
3019 if (alacarte) {
3020 /* coff symbol table : we handle it */
3021 if (!strcmp(hdr.ar_name, "/"))
3022 return tcc_load_alacarte(s1, fd, size, 4);
3023 if (!strcmp(hdr.ar_name, "/SYM64/"))
3024 return tcc_load_alacarte(s1, fd, size, 8);
3025 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3026 if (s1->verbose == 2)
3027 printf(" -> %s\n", hdr.ar_name);
3028 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3029 return -1;
3031 file_offset += size;
3035 #ifndef ELF_OBJ_ONLY
3036 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3037 LV, maybe create a new entry for (LIB,VERSION). */
3038 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3040 while (i >= *n) {
3041 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3042 (*lv)[(*n)++] = -1;
3044 if ((*lv)[i] == -1) {
3045 int v, prev_same_lib = -1;
3046 for (v = 0; v < nb_sym_versions; v++) {
3047 if (strcmp(sym_versions[v].lib, lib))
3048 continue;
3049 prev_same_lib = v;
3050 if (!strcmp(sym_versions[v].version, version))
3051 break;
3053 if (v == nb_sym_versions) {
3054 sym_versions = tcc_realloc (sym_versions,
3055 (v + 1) * sizeof(*sym_versions));
3056 sym_versions[v].lib = tcc_strdup(lib);
3057 sym_versions[v].version = tcc_strdup(version);
3058 sym_versions[v].out_index = 0;
3059 sym_versions[v].prev_same_lib = prev_same_lib;
3060 nb_sym_versions++;
3062 (*lv)[i] = v;
3066 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3067 VERNDX. */
3068 static void
3069 set_sym_version(TCCState *s1, int sym_index, int verndx)
3071 if (sym_index >= nb_sym_to_version) {
3072 int newelems = sym_index ? sym_index * 2 : 1;
3073 sym_to_version = tcc_realloc(sym_to_version,
3074 newelems * sizeof(*sym_to_version));
3075 memset(sym_to_version + nb_sym_to_version, -1,
3076 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3077 nb_sym_to_version = newelems;
3079 if (sym_to_version[sym_index] < 0)
3080 sym_to_version[sym_index] = verndx;
3083 struct versym_info {
3084 int nb_versyms;
3085 ElfW(Verdef) *verdef;
3086 ElfW(Verneed) *verneed;
3087 ElfW(Half) *versym;
3088 int nb_local_ver, *local_ver;
3092 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3094 char *lib, *version;
3095 uint32_t next;
3096 int i;
3098 #define DEBUG_VERSION 0
3100 if (v->versym && v->verdef) {
3101 ElfW(Verdef) *vdef = v->verdef;
3102 lib = NULL;
3103 do {
3104 ElfW(Verdaux) *verdaux =
3105 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3107 #if DEBUG_VERSION
3108 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3109 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3110 vdef->vd_hash);
3111 #endif
3112 if (vdef->vd_cnt) {
3113 version = dynstr + verdaux->vda_name;
3115 if (lib == NULL)
3116 lib = version;
3117 else
3118 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3119 lib, version);
3120 #if DEBUG_VERSION
3121 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3122 #endif
3124 next = vdef->vd_next;
3125 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3126 } while (next);
3128 if (v->versym && v->verneed) {
3129 ElfW(Verneed) *vneed = v->verneed;
3130 do {
3131 ElfW(Vernaux) *vernaux =
3132 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3134 lib = dynstr + vneed->vn_file;
3135 #if DEBUG_VERSION
3136 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3137 #endif
3138 for (i = 0; i < vneed->vn_cnt; i++) {
3139 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3140 version = dynstr + vernaux->vna_name;
3141 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3142 lib, version);
3143 #if DEBUG_VERSION
3144 printf (" vernaux(%u): %u %u %s\n",
3145 vernaux->vna_other, vernaux->vna_hash,
3146 vernaux->vna_flags, version);
3147 #endif
3149 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3151 next = vneed->vn_next;
3152 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3153 } while (next);
3156 #if DEBUG_VERSION
3157 for (i = 0; i < v->nb_local_ver; i++) {
3158 if (v->local_ver[i] > 0) {
3159 printf ("%d: lib: %s, version %s\n",
3160 i, sym_versions[v->local_ver[i]].lib,
3161 sym_versions[v->local_ver[i]].version);
3164 #endif
3167 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3168 is referenced by the user (so it should be added as DT_NEEDED in
3169 the generated ELF file) */
3170 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3172 ElfW(Ehdr) ehdr;
3173 ElfW(Shdr) *shdr, *sh, *sh1;
3174 int i, j, nb_syms, nb_dts, sym_bind, ret;
3175 ElfW(Sym) *sym, *dynsym;
3176 ElfW(Dyn) *dt, *dynamic;
3178 char *dynstr;
3179 int sym_index;
3180 const char *name, *soname;
3181 DLLReference *dllref;
3182 struct versym_info v;
3184 full_read(fd, &ehdr, sizeof(ehdr));
3186 /* test CPU specific stuff */
3187 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3188 ehdr.e_machine != EM_TCC_TARGET) {
3189 tcc_error_noabort("bad architecture");
3190 return -1;
3193 /* read sections */
3194 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3196 /* load dynamic section and dynamic symbols */
3197 nb_syms = 0;
3198 nb_dts = 0;
3199 dynamic = NULL;
3200 dynsym = NULL; /* avoid warning */
3201 dynstr = NULL; /* avoid warning */
3202 memset(&v, 0, sizeof v);
3204 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3205 switch(sh->sh_type) {
3206 case SHT_DYNAMIC:
3207 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3208 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3209 break;
3210 case SHT_DYNSYM:
3211 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3212 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3213 sh1 = &shdr[sh->sh_link];
3214 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3215 break;
3216 case SHT_GNU_verdef:
3217 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3218 break;
3219 case SHT_GNU_verneed:
3220 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3221 break;
3222 case SHT_GNU_versym:
3223 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3224 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3225 break;
3226 default:
3227 break;
3231 /* compute the real library name */
3232 soname = tcc_basename(filename);
3234 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3235 if (dt->d_tag == DT_SONAME) {
3236 soname = dynstr + dt->d_un.d_val;
3240 /* if the dll is already loaded, do not load it */
3241 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3242 dllref = s1->loaded_dlls[i];
3243 if (!strcmp(soname, dllref->name)) {
3244 /* but update level if needed */
3245 if (level < dllref->level)
3246 dllref->level = level;
3247 ret = 0;
3248 goto the_end;
3252 if (v.nb_versyms != nb_syms)
3253 tcc_free (v.versym), v.versym = NULL;
3254 else
3255 store_version(s1, &v, dynstr);
3257 /* add the dll and its level */
3258 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
3259 dllref->level = level;
3260 strcpy(dllref->name, soname);
3261 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
3263 /* add dynamic symbols in dynsym_section */
3264 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3265 sym_bind = ELFW(ST_BIND)(sym->st_info);
3266 if (sym_bind == STB_LOCAL)
3267 continue;
3268 name = dynstr + sym->st_name;
3269 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3270 sym->st_info, sym->st_other, sym->st_shndx, name);
3271 if (v.versym) {
3272 ElfW(Half) vsym = v.versym[i];
3273 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3274 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3278 /* load all referenced DLLs */
3279 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3280 switch(dt->d_tag) {
3281 case DT_NEEDED:
3282 name = dynstr + dt->d_un.d_val;
3283 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3284 dllref = s1->loaded_dlls[j];
3285 if (!strcmp(name, dllref->name))
3286 goto already_loaded;
3288 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3289 tcc_error_noabort("referenced dll '%s' not found", name);
3290 ret = -1;
3291 goto the_end;
3293 already_loaded:
3294 break;
3297 ret = 0;
3298 the_end:
3299 tcc_free(dynstr);
3300 tcc_free(dynsym);
3301 tcc_free(dynamic);
3302 tcc_free(shdr);
3303 tcc_free(v.local_ver);
3304 tcc_free(v.verdef);
3305 tcc_free(v.verneed);
3306 tcc_free(v.versym);
3307 return ret;
3310 #define LD_TOK_NAME 256
3311 #define LD_TOK_EOF (-1)
3313 static int ld_inp(TCCState *s1)
3315 char b;
3316 if (s1->cc != -1) {
3317 int c = s1->cc;
3318 s1->cc = -1;
3319 return c;
3321 if (1 == read(s1->fd, &b, 1))
3322 return b;
3323 return CH_EOF;
3326 /* return next ld script token */
3327 static int ld_next(TCCState *s1, char *name, int name_size)
3329 int c, d, ch;
3330 char *q;
3332 redo:
3333 ch = ld_inp(s1);
3334 switch(ch) {
3335 case ' ':
3336 case '\t':
3337 case '\f':
3338 case '\v':
3339 case '\r':
3340 case '\n':
3341 goto redo;
3342 case '/':
3343 ch = ld_inp(s1);
3344 if (ch == '*') { /* comment */
3345 for (d = 0;; d = ch) {
3346 ch = ld_inp(s1);
3347 if (ch == CH_EOF || (ch == '/' && d == '*'))
3348 break;
3350 goto redo;
3351 } else {
3352 q = name;
3353 *q++ = '/';
3354 goto parse_name;
3356 break;
3357 case '\\':
3358 /* case 'a' ... 'z': */
3359 case 'a':
3360 case 'b':
3361 case 'c':
3362 case 'd':
3363 case 'e':
3364 case 'f':
3365 case 'g':
3366 case 'h':
3367 case 'i':
3368 case 'j':
3369 case 'k':
3370 case 'l':
3371 case 'm':
3372 case 'n':
3373 case 'o':
3374 case 'p':
3375 case 'q':
3376 case 'r':
3377 case 's':
3378 case 't':
3379 case 'u':
3380 case 'v':
3381 case 'w':
3382 case 'x':
3383 case 'y':
3384 case 'z':
3385 /* case 'A' ... 'z': */
3386 case 'A':
3387 case 'B':
3388 case 'C':
3389 case 'D':
3390 case 'E':
3391 case 'F':
3392 case 'G':
3393 case 'H':
3394 case 'I':
3395 case 'J':
3396 case 'K':
3397 case 'L':
3398 case 'M':
3399 case 'N':
3400 case 'O':
3401 case 'P':
3402 case 'Q':
3403 case 'R':
3404 case 'S':
3405 case 'T':
3406 case 'U':
3407 case 'V':
3408 case 'W':
3409 case 'X':
3410 case 'Y':
3411 case 'Z':
3412 case '_':
3413 case '.':
3414 case '$':
3415 case '~':
3416 q = name;
3417 parse_name:
3418 for(;;) {
3419 if (!((ch >= 'a' && ch <= 'z') ||
3420 (ch >= 'A' && ch <= 'Z') ||
3421 (ch >= '0' && ch <= '9') ||
3422 strchr("/.-_+=$:\\,~", ch)))
3423 break;
3424 if ((q - name) < name_size - 1) {
3425 *q++ = ch;
3427 ch = ld_inp(s1);
3429 s1->cc = ch;
3430 *q = '\0';
3431 c = LD_TOK_NAME;
3432 break;
3433 case CH_EOF:
3434 c = LD_TOK_EOF;
3435 break;
3436 default:
3437 c = ch;
3438 break;
3440 return c;
3443 static int ld_add_file(TCCState *s1, const char filename[])
3445 if (filename[0] == '/') {
3446 if (CONFIG_SYSROOT[0] == '\0'
3447 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3448 return 0;
3449 filename = tcc_basename(filename);
3451 return tcc_add_dll(s1, filename, 0);
3454 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3456 char filename[1024], libname[1024];
3457 int t, group, nblibs = 0, ret = 0;
3458 char **libs = NULL;
3460 group = !strcmp(cmd, "GROUP");
3461 if (!as_needed)
3462 s1->new_undef_sym = 0;
3463 t = ld_next(s1, filename, sizeof(filename));
3464 if (t != '(') {
3465 tcc_error_noabort("( expected");
3466 ret = -1;
3467 goto lib_parse_error;
3469 t = ld_next(s1, filename, sizeof(filename));
3470 for(;;) {
3471 libname[0] = '\0';
3472 if (t == LD_TOK_EOF) {
3473 tcc_error_noabort("unexpected end of file");
3474 ret = -1;
3475 goto lib_parse_error;
3476 } else if (t == ')') {
3477 break;
3478 } else if (t == '-') {
3479 t = ld_next(s1, filename, sizeof(filename));
3480 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3481 tcc_error_noabort("library name expected");
3482 ret = -1;
3483 goto lib_parse_error;
3485 pstrcpy(libname, sizeof libname, &filename[1]);
3486 if (s1->static_link) {
3487 snprintf(filename, sizeof filename, "lib%s.a", libname);
3488 } else {
3489 snprintf(filename, sizeof filename, "lib%s.so", libname);
3491 } else if (t != LD_TOK_NAME) {
3492 tcc_error_noabort("filename expected");
3493 ret = -1;
3494 goto lib_parse_error;
3496 if (!strcmp(filename, "AS_NEEDED")) {
3497 ret = ld_add_file_list(s1, cmd, 1);
3498 if (ret)
3499 goto lib_parse_error;
3500 } else {
3501 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3502 if (!as_needed) {
3503 ret = ld_add_file(s1, filename);
3504 if (ret)
3505 goto lib_parse_error;
3506 if (group) {
3507 /* Add the filename *and* the libname to avoid future conversions */
3508 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3509 if (libname[0] != '\0')
3510 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3514 t = ld_next(s1, filename, sizeof(filename));
3515 if (t == ',') {
3516 t = ld_next(s1, filename, sizeof(filename));
3519 if (group && !as_needed) {
3520 while (s1->new_undef_sym) {
3521 int i;
3522 s1->new_undef_sym = 0;
3523 for (i = 0; i < nblibs; i ++)
3524 ld_add_file(s1, libs[i]);
3527 lib_parse_error:
3528 dynarray_reset(&libs, &nblibs);
3529 return ret;
3532 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3533 files */
3534 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3536 char cmd[64];
3537 char filename[1024];
3538 int t, ret;
3540 s1->fd = fd;
3541 s1->cc = -1;
3542 for(;;) {
3543 t = ld_next(s1, cmd, sizeof(cmd));
3544 if (t == LD_TOK_EOF)
3545 return 0;
3546 else if (t != LD_TOK_NAME)
3547 return -1;
3548 if (!strcmp(cmd, "INPUT") ||
3549 !strcmp(cmd, "GROUP")) {
3550 ret = ld_add_file_list(s1, cmd, 0);
3551 if (ret)
3552 return ret;
3553 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3554 !strcmp(cmd, "TARGET")) {
3555 /* ignore some commands */
3556 t = ld_next(s1, cmd, sizeof(cmd));
3557 if (t != '(') {
3558 tcc_error_noabort("( expected");
3559 return -1;
3561 for(;;) {
3562 t = ld_next(s1, filename, sizeof(filename));
3563 if (t == LD_TOK_EOF) {
3564 tcc_error_noabort("unexpected end of file");
3565 return -1;
3566 } else if (t == ')') {
3567 break;
3570 } else {
3571 return -1;
3574 return 0;
3576 #endif /* !ELF_OBJ_ONLY */