NetBSD: longjmp(jmp_buf, 0) is not supported.
[tinycc.git] / tccelf.c
blobe31eb9f733510c2c587c899c1960e98212d5ac7f
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 | SHF_WRITE; // SHF_WRITE needed for musl/SELINUX
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;
738 int jmp_slot = type == R_JMP_SLOT;
740 sr = jmp_slot ? s->relocplt : s->reloc;
741 if (!sr) {
742 /* if no relocation section, create it */
743 if (jmp_slot)
744 snprintf(buf, sizeof(buf), RELPLT_SECTION_FMT);
745 else
746 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
747 /* if the symtab is allocated, then we consider the relocation
748 are also */
749 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
750 sr->sh_entsize = sizeof(ElfW_Rel);
751 sr->link = symtab;
752 sr->sh_info = s->sh_num;
753 if (jmp_slot)
754 s->relocplt = sr;
755 else
756 s->reloc = sr;
758 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
759 rel->r_offset = offset;
760 rel->r_info = ELFW(R_INFO)(symbol, type);
761 #if SHT_RELX == SHT_RELA
762 rel->r_addend = addend;
763 #endif
764 if (SHT_RELX != SHT_RELA && addend)
765 tcc_error("non-zero addend on REL architecture");
768 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
769 int type, int symbol)
771 put_elf_reloca(symtab, s, offset, type, symbol, 0);
774 /* put stab debug information */
775 ST_FUNC void put_stabs(TCCState *s1, const char *str, int type, int other, int desc,
776 unsigned long value)
778 Stab_Sym *sym;
780 unsigned offset;
781 if (type == N_SLINE
782 && (offset = stab_section->data_offset)
783 && (sym = (Stab_Sym*)(stab_section->data + offset) - 1)
784 && sym->n_type == type
785 && sym->n_value == value) {
786 /* just update line_number in previous entry */
787 sym->n_desc = desc;
788 return;
791 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
792 if (str) {
793 sym->n_strx = put_elf_str(stab_section->link, str);
794 } else {
795 sym->n_strx = 0;
797 sym->n_type = type;
798 sym->n_other = other;
799 sym->n_desc = desc;
800 sym->n_value = value;
803 ST_FUNC void put_stabs_r(TCCState *s1, const char *str, int type, int other, int desc,
804 unsigned long value, Section *sec, int sym_index)
806 put_elf_reloc(symtab_section, stab_section,
807 stab_section->data_offset + 8,
808 sizeof ((Stab_Sym*)0)->n_value == PTR_SIZE ? R_DATA_PTR : R_DATA_32,
809 sym_index);
810 put_stabs(s1, str, type, other, desc, value);
813 ST_FUNC void put_stabn(TCCState *s1, int type, int other, int desc, int value)
815 put_stabs(s1, NULL, type, other, desc, value);
818 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
820 int n;
821 struct sym_attr *tab;
823 if (index >= s1->nb_sym_attrs) {
824 if (!alloc)
825 return s1->sym_attrs;
826 /* find immediately bigger power of 2 and reallocate array */
827 n = 1;
828 while (index >= n)
829 n *= 2;
830 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
831 s1->sym_attrs = tab;
832 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
833 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
834 s1->nb_sym_attrs = n;
836 return &s1->sym_attrs[index];
839 /* In an ELF file symbol table, the local symbols must appear below
840 the global and weak ones. Since TCC cannot sort it while generating
841 the code, we must do it after. All the relocation tables are also
842 modified to take into account the symbol table sorting */
843 static void sort_syms(TCCState *s1, Section *s)
845 int *old_to_new_syms;
846 ElfW(Sym) *new_syms;
847 int nb_syms, i;
848 ElfW(Sym) *p, *q;
849 ElfW_Rel *rel;
850 Section *sr;
851 int type, sym_index;
853 nb_syms = s->data_offset / sizeof(ElfW(Sym));
854 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
855 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
857 /* first pass for local symbols */
858 p = (ElfW(Sym) *)s->data;
859 q = new_syms;
860 for(i = 0; i < nb_syms; i++) {
861 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
862 old_to_new_syms[i] = q - new_syms;
863 *q++ = *p;
865 p++;
867 /* save the number of local symbols in section header */
868 if( s->sh_size ) /* this 'if' makes IDA happy */
869 s->sh_info = q - new_syms;
871 /* then second pass for non local symbols */
872 p = (ElfW(Sym) *)s->data;
873 for(i = 0; i < nb_syms; i++) {
874 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
875 old_to_new_syms[i] = q - new_syms;
876 *q++ = *p;
878 p++;
881 /* we copy the new symbols to the old */
882 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
883 tcc_free(new_syms);
885 /* now we modify all the relocations */
886 for(i = 1; i < s1->nb_sections; i++) {
887 sr = s1->sections[i];
888 if (sr->sh_type == SHT_RELX && sr->link == s) {
889 for_each_elem(sr, 0, rel, ElfW_Rel) {
890 sym_index = ELFW(R_SYM)(rel->r_info);
891 type = ELFW(R_TYPE)(rel->r_info);
892 sym_index = old_to_new_syms[sym_index];
893 rel->r_info = ELFW(R_INFO)(sym_index, type);
898 tcc_free(old_to_new_syms);
901 /* relocate symbol table, resolve undefined symbols if do_resolve is
902 true and output error if undefined symbol. */
903 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
905 ElfW(Sym) *sym;
906 int sym_bind, sh_num;
907 const char *name;
909 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
910 sh_num = sym->st_shndx;
911 if (sh_num == SHN_UNDEF) {
912 name = (char *) s1->symtab->link->data + sym->st_name;
913 /* Use ld.so to resolve symbol for us (for tcc -run) */
914 if (do_resolve) {
915 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
916 /* dlsym() needs the undecorated name. */
917 void *addr = dlsym(RTLD_DEFAULT, &name[s1->leading_underscore]);
918 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
919 if (addr == NULL) {
920 int i;
921 for (i = 0; i < s1->nb_loaded_dlls; i++)
922 if ((addr = dlsym(s1->loaded_dlls[i]->handle, name)))
923 break;
925 #endif
926 if (addr) {
927 sym->st_value = (addr_t) addr;
928 #ifdef DEBUG_RELOC
929 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
930 #endif
931 goto found;
933 #endif
934 /* if dynamic symbol exist, it will be used in relocate_section */
935 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
936 goto found;
937 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
938 it */
939 if (!strcmp(name, "_fp_hw"))
940 goto found;
941 /* only weak symbols are accepted to be undefined. Their
942 value is zero */
943 sym_bind = ELFW(ST_BIND)(sym->st_info);
944 if (sym_bind == STB_WEAK)
945 sym->st_value = 0;
946 else
947 tcc_error_noabort("undefined symbol '%s'", name);
948 } else if (sh_num < SHN_LORESERVE) {
949 /* add section base */
950 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
952 found: ;
956 /* relocate a given section (CPU dependent) by applying the relocations
957 in the associated relocation section */
958 ST_FUNC void relocate_section(TCCState *s1, Section *s)
960 Section *sr = s->reloc;
961 ElfW_Rel *rel;
962 ElfW(Sym) *sym;
963 int type, sym_index;
964 unsigned char *ptr;
965 addr_t tgt, addr;
967 qrel = (ElfW_Rel *)sr->data;
969 for_each_elem(sr, 0, rel, ElfW_Rel) {
970 ptr = s->data + rel->r_offset;
971 sym_index = ELFW(R_SYM)(rel->r_info);
972 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
973 type = ELFW(R_TYPE)(rel->r_info);
974 tgt = sym->st_value;
975 #if SHT_RELX == SHT_RELA
976 tgt += rel->r_addend;
977 #endif
978 addr = s->sh_addr + rel->r_offset;
979 relocate(s1, rel, type, ptr, addr, tgt);
981 /* if the relocation is allocated, we change its symbol table */
982 if (sr->sh_flags & SHF_ALLOC) {
983 sr->link = s1->dynsym;
984 if (s1->output_type == TCC_OUTPUT_DLL) {
985 size_t r = (uint8_t*)qrel - sr->data;
986 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
987 && 0 == strcmp(s->name, ".stab"))
988 r = 0; /* cannot apply 64bit relocation to 32bit value */
989 sr->data_offset = sr->sh_size = r;
994 #ifndef ELF_OBJ_ONLY
995 /* relocate relocation table in 'sr' */
996 static void relocate_rel(TCCState *s1, Section *sr)
998 Section *s;
999 ElfW_Rel *rel;
1001 s = s1->sections[sr->sh_info];
1002 for_each_elem(sr, 0, rel, ElfW_Rel)
1003 rel->r_offset += s->sh_addr;
1006 /* count the number of dynamic relocations so that we can reserve
1007 their space */
1008 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
1010 int count = 0;
1011 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1012 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1013 defined(TCC_TARGET_RISCV64)
1014 ElfW_Rel *rel;
1015 for_each_elem(sr, 0, rel, ElfW_Rel) {
1016 int sym_index = ELFW(R_SYM)(rel->r_info);
1017 int type = ELFW(R_TYPE)(rel->r_info);
1018 switch(type) {
1019 #if defined(TCC_TARGET_I386)
1020 case R_386_32:
1021 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
1022 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
1023 /* don't fixup unresolved (weak) symbols */
1024 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
1025 break;
1027 #elif defined(TCC_TARGET_X86_64)
1028 case R_X86_64_32:
1029 case R_X86_64_32S:
1030 case R_X86_64_64:
1031 #elif defined(TCC_TARGET_ARM)
1032 case R_ARM_ABS32:
1033 #elif defined(TCC_TARGET_ARM64)
1034 case R_AARCH64_ABS32:
1035 case R_AARCH64_ABS64:
1036 #elif defined(TCC_TARGET_RISCV64)
1037 case R_RISCV_32:
1038 case R_RISCV_64:
1039 #endif
1040 count++;
1041 break;
1042 #if defined(TCC_TARGET_I386)
1043 case R_386_PC32:
1044 #elif defined(TCC_TARGET_X86_64)
1045 case R_X86_64_PC32:
1046 #elif defined(TCC_TARGET_ARM64)
1047 case R_AARCH64_PREL32:
1048 #endif
1049 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1050 count++;
1051 break;
1052 default:
1053 break;
1056 if (count) {
1057 /* allocate the section */
1058 sr->sh_flags |= SHF_ALLOC;
1059 sr->sh_size = count * sizeof(ElfW_Rel);
1061 #endif
1062 return count;
1064 #endif
1066 #if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE)
1067 static void build_got(TCCState *s1)
1069 /* if no got, then create it */
1070 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1071 s1->got->sh_entsize = 4;
1072 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1073 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1074 /* keep space for _DYNAMIC pointer and two dummy got entries */
1075 section_ptr_add(s1->got, 3 * PTR_SIZE);
1078 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1079 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1080 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1081 Returns the offset of the GOT or (if any) PLT entry. */
1082 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1083 int sym_index)
1085 int need_plt_entry;
1086 const char *name;
1087 ElfW(Sym) *sym;
1088 struct sym_attr *attr;
1089 unsigned got_offset;
1090 char plt_name[100];
1091 int len;
1093 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1094 attr = get_sym_attr(s1, sym_index, 1);
1096 /* In case a function is both called and its address taken 2 GOT entries
1097 are created, one for taking the address (GOT) and the other for the PLT
1098 entry (PLTGOT). */
1099 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1100 return attr;
1102 /* create the GOT entry */
1103 got_offset = s1->got->data_offset;
1104 section_ptr_add(s1->got, PTR_SIZE);
1106 /* Create the GOT relocation that will insert the address of the object or
1107 function of interest in the GOT entry. This is a static relocation for
1108 memory output (dlsym will give us the address of symbols) and dynamic
1109 relocation otherwise (executable and DLLs). The relocation should be
1110 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1111 associated to a PLT entry) but is currently done at load time for an
1112 unknown reason. */
1114 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1115 name = (char *) symtab_section->link->data + sym->st_name;
1117 if (s1->dynsym) {
1118 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1119 /* Hack alarm. We don't want to emit dynamic symbols
1120 and symbol based relocs for STB_LOCAL symbols, but rather
1121 want to resolve them directly. At this point the symbol
1122 values aren't final yet, so we must defer this. We will later
1123 have to create a RELATIVE reloc anyway, so we misuse the
1124 relocation slot to smuggle the symbol reference until
1125 fill_local_got_entries. Not that the sym_index is
1126 relative to symtab_section, not s1->dynsym! Nevertheless
1127 we use s1->dyn_sym so that if this is the first call
1128 that got->reloc is correctly created. Also note that
1129 RELATIVE relocs are not normally created for the .got,
1130 so the types serves as a marker for later (and is retained
1131 also for the final output, which is okay because then the
1132 got is just normal data). */
1133 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1134 sym_index);
1135 } else {
1136 if (0 == attr->dyn_index)
1137 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1138 sym->st_size, sym->st_info, 0,
1139 sym->st_shndx, name);
1140 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
1141 attr->dyn_index);
1143 } else {
1144 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1145 sym_index);
1148 if (need_plt_entry) {
1149 if (!s1->plt) {
1150 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1151 SHF_ALLOC | SHF_EXECINSTR);
1152 s1->plt->sh_entsize = 4;
1155 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1157 /* create a symbol 'sym@plt' for the PLT jump vector */
1158 len = strlen(name);
1159 if (len > sizeof plt_name - 5)
1160 len = sizeof plt_name - 5;
1161 memcpy(plt_name, name, len);
1162 strcpy(plt_name + len, "@plt");
1163 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
1164 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1166 } else {
1167 attr->got_offset = got_offset;
1170 return attr;
1173 /* build GOT and PLT entries */
1174 static void build_got_entries_pass(TCCState *s1, int pass)
1176 Section *s;
1177 ElfW_Rel *rel;
1178 ElfW(Sym) *sym;
1179 int i, type, gotplt_entry, reloc_type, sym_index;
1180 struct sym_attr *attr;
1182 for(i = 1; i < s1->nb_sections; i++) {
1183 s = s1->sections[i];
1184 if (s->sh_type != SHT_RELX)
1185 continue;
1186 /* no need to handle got relocations */
1187 if (s->link != symtab_section)
1188 continue;
1189 for_each_elem(s, 0, rel, ElfW_Rel) {
1190 type = ELFW(R_TYPE)(rel->r_info);
1191 gotplt_entry = gotplt_entry_type(type);
1192 if (gotplt_entry == -1)
1193 tcc_error ("Unknown relocation type for got: %d", type);
1194 sym_index = ELFW(R_SYM)(rel->r_info);
1195 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1197 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1198 continue;
1201 /* Automatically create PLT/GOT [entry] if it is an undefined
1202 reference (resolved at runtime), or the symbol is absolute,
1203 probably created by tcc_add_symbol, and thus on 64-bit
1204 targets might be too far from application code. */
1205 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1206 if (sym->st_shndx == SHN_UNDEF) {
1207 ElfW(Sym) *esym;
1208 int dynindex;
1209 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1210 continue;
1211 /* Relocations for UNDEF symbols would normally need
1212 to be transferred into the executable or shared object.
1213 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1214 But TCC doesn't do that (at least for exes), so we
1215 need to resolve all such relocs locally. And that
1216 means PLT slots for functions in DLLs and COPY relocs for
1217 data symbols. COPY relocs were generated in
1218 bind_exe_dynsyms (and the symbol adjusted to be defined),
1219 and for functions we were generated a dynamic symbol
1220 of function type. */
1221 if (s1->dynsym) {
1222 /* dynsym isn't set for -run :-/ */
1223 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1224 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1225 if (dynindex
1226 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1227 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1228 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1229 goto jmp_slot;
1231 } else if (!(sym->st_shndx == SHN_ABS
1232 #ifndef TCC_TARGET_ARM
1233 && PTR_SIZE == 8
1234 #endif
1236 continue;
1239 #ifdef TCC_TARGET_X86_64
1240 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1241 sym->st_shndx != SHN_UNDEF &&
1242 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1243 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1244 s1->output_type == TCC_OUTPUT_EXE)) {
1245 if (pass == 0)
1246 continue;
1247 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1248 continue;
1250 #endif
1251 reloc_type = code_reloc(type);
1252 if (reloc_type == -1)
1253 tcc_error ("Unknown relocation type: %d", type);
1254 else if (reloc_type != 0) {
1255 jmp_slot:
1256 reloc_type = R_JMP_SLOT;
1257 } else
1258 reloc_type = R_GLOB_DAT;
1261 if ((pass == 0 && reloc_type == R_GLOB_DAT) ||
1262 (pass == 1 && reloc_type == R_JMP_SLOT))
1263 continue;
1265 if (!s1->got)
1266 build_got(s1);
1268 if (gotplt_entry == BUILD_GOT_ONLY)
1269 continue;
1271 attr = put_got_entry(s1, reloc_type, sym_index);
1273 if (reloc_type == R_JMP_SLOT)
1274 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1279 ST_FUNC void build_got_entries(TCCState *s1)
1281 int i;
1283 /* Two passes because R_JMP_SLOT should become first.
1284 Some targets (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1285 for (i = 0; i < 2; i++)
1286 build_got_entries_pass(s1, i);
1288 #endif
1290 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
1292 int shn = sec ? sec->sh_num : offs ? SHN_ABS : SHN_UNDEF;
1293 if (sec && offs == -1)
1294 offs = sec->data_offset;
1295 return set_elf_sym(symtab_section, offs, 0,
1296 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1299 static void add_init_array_defines(TCCState *s1, const char *section_name)
1301 Section *s;
1302 addr_t end_offset;
1303 char buf[1024];
1304 s = find_section(s1, section_name);
1305 if (!s) {
1306 end_offset = 0;
1307 s = data_section;
1308 } else {
1309 end_offset = s->data_offset;
1311 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1312 set_global_sym(s1, buf, s, 0);
1313 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1314 set_global_sym(s1, buf, s, end_offset);
1317 #ifndef TCC_TARGET_PE
1318 static void tcc_add_support(TCCState *s1, const char *filename)
1320 char buf[1024];
1321 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1322 tcc_add_file(s1, buf);
1324 #endif
1326 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1328 Section *s;
1329 s = find_section(s1, sec);
1330 s->sh_flags |= SHF_WRITE;
1331 #ifndef TCC_TARGET_PE
1332 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1333 #endif
1334 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1335 section_ptr_add(s, PTR_SIZE);
1338 #ifdef CONFIG_TCC_BCHECK
1339 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1341 if (0 == s1->do_bounds_check)
1342 return;
1343 section_ptr_add(bounds_section, sizeof(addr_t));
1345 #endif
1347 #ifdef CONFIG_TCC_BACKTRACE
1348 static void put_ptr(TCCState *s1, Section *s, int offs)
1350 int c;
1351 c = set_global_sym(s1, NULL, s, offs);
1352 s = data_section;
1353 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1354 section_ptr_add(s, PTR_SIZE);
1357 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1358 a dynamic symbol to allow so's to have one each with a different value. */
1359 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1361 int c = find_elf_sym(s1->symtab, name);
1362 if (c) {
1363 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1364 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1365 esym->st_value = offset;
1366 esym->st_shndx = s->sh_num;
1370 ST_FUNC void tcc_add_btstub(TCCState *s1)
1372 Section *s;
1373 int n, o;
1374 CString cstr;
1376 s = data_section;
1377 o = s->data_offset;
1378 /* create (part of) a struct rt_context (see tccrun.c) */
1379 put_ptr(s1, stab_section, 0);
1380 put_ptr(s1, stab_section, -1);
1381 put_ptr(s1, stab_section->link, 0);
1382 section_ptr_add(s, 3 * PTR_SIZE);
1383 /* prog_base */
1384 #ifndef TCC_TARGET_MACHO
1385 /* XXX this relocation is wrong, it uses sym-index 0 (local,undef) */
1386 put_elf_reloc(s1->symtab, s, s->data_offset, R_DATA_PTR, 0);
1387 #endif
1388 section_ptr_add(s, PTR_SIZE);
1389 n = 2 * PTR_SIZE;
1390 #ifdef CONFIG_TCC_BCHECK
1391 if (s1->do_bounds_check) {
1392 put_ptr(s1, bounds_section, 0);
1393 n -= PTR_SIZE;
1395 #endif
1396 section_ptr_add(s, n);
1398 cstr_new(&cstr);
1399 cstr_printf(&cstr,
1400 " extern void __bt_init(),*__rt_info[],__bt_init_dll();"
1401 "__attribute__((constructor)) static void __bt_init_rt(){");
1402 #ifdef TCC_TARGET_PE
1403 if (s1->output_type == TCC_OUTPUT_DLL)
1404 #ifdef CONFIG_TCC_BCHECK
1405 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1406 #else
1407 cstr_printf(&cstr, "__bt_init_dll(0);");
1408 #endif
1409 #endif
1410 cstr_printf(&cstr, "__bt_init(__rt_info,%d, 0);}",
1411 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1412 tcc_compile_string(s1, cstr.data);
1413 cstr_free(&cstr);
1414 set_local_sym(s1, &"___rt_info"[!s1->leading_underscore], s, o);
1416 #endif
1418 #ifndef TCC_TARGET_PE
1419 /* add tcc runtime libraries */
1420 ST_FUNC void tcc_add_runtime(TCCState *s1)
1422 s1->filetype = 0;
1423 #ifdef CONFIG_TCC_BCHECK
1424 tcc_add_bcheck(s1);
1425 #endif
1426 tcc_add_pragma_libs(s1);
1427 /* add libc */
1428 if (!s1->nostdlib) {
1429 if (s1->option_pthread)
1430 tcc_add_library_err(s1, "pthread");
1431 tcc_add_library_err(s1, "c");
1432 #ifdef TCC_LIBGCC
1433 if (!s1->static_link) {
1434 if (TCC_LIBGCC[0] == '/')
1435 tcc_add_file(s1, TCC_LIBGCC);
1436 else
1437 tcc_add_dll(s1, TCC_LIBGCC, 0);
1439 #endif
1440 #ifdef CONFIG_TCC_BCHECK
1441 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1442 tcc_add_library_err(s1, "pthread");
1443 #if !TARGETOS_OpenBSD && !TARGETOS_NetBSD
1444 tcc_add_library_err(s1, "dl");
1445 #endif
1446 tcc_add_support(s1, "bcheck.o");
1448 #endif
1449 #ifdef CONFIG_TCC_BACKTRACE
1450 if (s1->do_backtrace) {
1451 if (s1->output_type == TCC_OUTPUT_EXE)
1452 tcc_add_support(s1, "bt-exe.o");
1453 if (s1->output_type != TCC_OUTPUT_DLL)
1454 tcc_add_support(s1, "bt-log.o");
1455 if (s1->output_type != TCC_OUTPUT_MEMORY)
1456 tcc_add_btstub(s1);
1458 #endif
1459 if (strlen(TCC_LIBTCC1) > 0)
1460 tcc_add_support(s1, TCC_LIBTCC1);
1461 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
1462 /* add crt end if not memory output */
1463 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1464 if (s1->output_type == TCC_OUTPUT_DLL)
1465 tcc_add_crt(s1, "crtendS.o");
1466 else
1467 tcc_add_crt(s1, "crtend.o");
1468 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
1469 tcc_add_crt(s1, "crtn.o");
1470 #endif
1472 #elif !defined(TCC_TARGET_MACHO)
1473 /* add crt end if not memory output */
1474 if (s1->output_type != TCC_OUTPUT_MEMORY)
1475 tcc_add_crt(s1, "crtn.o");
1476 #endif
1479 #endif
1481 /* add various standard linker symbols (must be done after the
1482 sections are filled (for example after allocating common
1483 symbols)) */
1484 static void tcc_add_linker_symbols(TCCState *s1)
1486 char buf[1024];
1487 int i;
1488 Section *s;
1490 set_global_sym(s1, "_etext", text_section, -1);
1491 set_global_sym(s1, "_edata", data_section, -1);
1492 set_global_sym(s1, "_end", bss_section, -1);
1493 #ifdef TCC_TARGET_RISCV64
1494 /* XXX should be .sdata+0x800, not .data+0x800 */
1495 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1496 #endif
1497 /* horrible new standard ldscript defines */
1498 add_init_array_defines(s1, ".preinit_array");
1499 add_init_array_defines(s1, ".init_array");
1500 add_init_array_defines(s1, ".fini_array");
1501 /* add start and stop symbols for sections whose name can be
1502 expressed in C */
1503 for(i = 1; i < s1->nb_sections; i++) {
1504 s = s1->sections[i];
1505 if ((s->sh_flags & SHF_ALLOC)
1506 && (s->sh_type == SHT_PROGBITS
1507 || s->sh_type == SHT_STRTAB)) {
1508 const char *p;
1509 /* check if section name can be expressed in C */
1510 p = s->name;
1511 for(;;) {
1512 int c = *p;
1513 if (!c)
1514 break;
1515 if (!isid(c) && !isnum(c))
1516 goto next_sec;
1517 p++;
1519 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1520 set_global_sym(s1, buf, s, 0);
1521 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1522 set_global_sym(s1, buf, s, -1);
1524 next_sec: ;
1528 ST_FUNC void resolve_common_syms(TCCState *s1)
1530 ElfW(Sym) *sym;
1532 /* Allocate common symbols in BSS. */
1533 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1534 if (sym->st_shndx == SHN_COMMON) {
1535 /* symbol alignment is in st_value for SHN_COMMONs */
1536 sym->st_value = section_add(bss_section, sym->st_size,
1537 sym->st_value);
1538 sym->st_shndx = bss_section->sh_num;
1542 /* Now assign linker provided symbols their value. */
1543 tcc_add_linker_symbols(s1);
1546 static void tcc_output_binary(TCCState *s1, FILE *f,
1547 const int *sec_order)
1549 Section *s;
1550 int i, offset, size;
1552 offset = 0;
1553 for(i=1;i<s1->nb_sections;i++) {
1554 s = s1->sections[sec_order[i]];
1555 if (s->sh_type != SHT_NOBITS &&
1556 (s->sh_flags & SHF_ALLOC)) {
1557 while (offset < s->sh_offset) {
1558 fputc(0, f);
1559 offset++;
1561 size = s->sh_size;
1562 fwrite(s->data, 1, size, f);
1563 offset += size;
1568 #ifndef ELF_OBJ_ONLY
1569 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1571 int sym_index = ELFW(R_SYM) (rel->r_info);
1572 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1573 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1574 unsigned offset = attr->got_offset;
1576 if (0 == offset)
1577 return;
1578 section_reserve(s1->got, offset + PTR_SIZE);
1579 #if PTR_SIZE == 8
1580 write64le(s1->got->data + offset, sym->st_value);
1581 #else
1582 write32le(s1->got->data + offset, sym->st_value);
1583 #endif
1586 /* Perform relocation to GOT or PLT entries */
1587 ST_FUNC void fill_got(TCCState *s1)
1589 Section *s;
1590 ElfW_Rel *rel;
1591 int i;
1593 for(i = 1; i < s1->nb_sections; i++) {
1594 s = s1->sections[i];
1595 if (s->sh_type != SHT_RELX)
1596 continue;
1597 /* no need to handle got relocations */
1598 if (s->link != symtab_section)
1599 continue;
1600 for_each_elem(s, 0, rel, ElfW_Rel) {
1601 switch (ELFW(R_TYPE) (rel->r_info)) {
1602 case R_X86_64_GOT32:
1603 case R_X86_64_GOTPCREL:
1604 case R_X86_64_GOTPCRELX:
1605 case R_X86_64_REX_GOTPCRELX:
1606 case R_X86_64_PLT32:
1607 fill_got_entry(s1, rel);
1608 break;
1614 /* See put_got_entry for a description. This is the second stage
1615 where GOT references to local defined symbols are rewritten. */
1616 static void fill_local_got_entries(TCCState *s1)
1618 ElfW_Rel *rel;
1619 if (!s1->got->reloc)
1620 return;
1621 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1622 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1623 int sym_index = ELFW(R_SYM) (rel->r_info);
1624 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1625 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1626 unsigned offset = attr->got_offset;
1627 if (offset != rel->r_offset - s1->got->sh_addr)
1628 tcc_error_noabort("huh");
1629 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1630 #if SHT_RELX == SHT_RELA
1631 rel->r_addend = sym->st_value;
1632 #else
1633 /* All our REL architectures also happen to be 32bit LE. */
1634 write32le(s1->got->data + offset, sym->st_value);
1635 #endif
1640 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1641 in shared libraries and export non local defined symbols to shared libraries
1642 if -rdynamic switch was given on command line */
1643 static void bind_exe_dynsyms(TCCState *s1)
1645 const char *name;
1646 int sym_index, index;
1647 ElfW(Sym) *sym, *esym;
1648 int type;
1650 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1651 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1652 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1653 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1654 if (sym->st_shndx == SHN_UNDEF) {
1655 name = (char *) symtab_section->link->data + sym->st_name;
1656 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1657 if (sym_index) {
1658 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1659 type = ELFW(ST_TYPE)(esym->st_info);
1660 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1661 /* Indirect functions shall have STT_FUNC type in executable
1662 * dynsym section. Indeed, a dlsym call following a lazy
1663 * resolution would pick the symbol value from the
1664 * executable dynsym entry which would contain the address
1665 * of the function wanted by the caller of dlsym instead of
1666 * the address of the function that would return that
1667 * address */
1668 int dynindex
1669 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1670 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1671 name);
1672 int index = sym - (ElfW(Sym) *) symtab_section->data;
1673 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1674 } else if (type == STT_OBJECT) {
1675 unsigned long offset;
1676 ElfW(Sym) *dynsym;
1677 offset = bss_section->data_offset;
1678 /* XXX: which alignment ? */
1679 offset = (offset + 16 - 1) & -16;
1680 set_elf_sym (s1->symtab, offset, esym->st_size,
1681 esym->st_info, 0, bss_section->sh_num, name);
1682 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1683 esym->st_info, 0, bss_section->sh_num,
1684 name);
1686 /* Ensure R_COPY works for weak symbol aliases */
1687 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1688 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1689 if ((dynsym->st_value == esym->st_value)
1690 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1691 char *dynname = (char *) s1->dynsymtab_section->link->data
1692 + dynsym->st_name;
1693 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1694 dynsym->st_info, 0,
1695 bss_section->sh_num, dynname);
1696 break;
1701 put_elf_reloc(s1->dynsym, bss_section,
1702 offset, R_COPY, index);
1703 offset += esym->st_size;
1704 bss_section->data_offset = offset;
1706 } else {
1707 /* STB_WEAK undefined symbols are accepted */
1708 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1709 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1710 !strcmp(name, "_fp_hw")) {
1711 } else {
1712 tcc_error_noabort("undefined symbol '%s'", name);
1715 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1716 /* if -rdynamic option, then export all non local symbols */
1717 name = (char *) symtab_section->link->data + sym->st_name;
1718 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1719 0, sym->st_shndx, name);
1724 /* Bind symbols of libraries: export all non local symbols of executable that
1725 are referenced by shared libraries. The reason is that the dynamic loader
1726 search symbol first in executable and then in libraries. Therefore a
1727 reference to a symbol already defined by a library can still be resolved by
1728 a symbol in the executable. */
1729 static void bind_libs_dynsyms(TCCState *s1)
1731 const char *name;
1732 int sym_index;
1733 ElfW(Sym) *sym, *esym;
1735 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1736 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1737 sym_index = find_elf_sym(symtab_section, name);
1738 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1739 if (sym_index && sym->st_shndx != SHN_UNDEF
1740 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1741 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1742 sym->st_info, 0, sym->st_shndx, name);
1743 } else if (esym->st_shndx == SHN_UNDEF) {
1744 /* weak symbols can stay undefined */
1745 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1746 tcc_warning("undefined dynamic symbol '%s'", name);
1751 /* Export all non local symbols. This is used by shared libraries so that the
1752 non local symbols they define can resolve a reference in another shared
1753 library or in the executable. Correspondingly, it allows undefined local
1754 symbols to be resolved by other shared libraries or by the executable. */
1755 static void export_global_syms(TCCState *s1)
1757 int dynindex, index;
1758 const char *name;
1759 ElfW(Sym) *sym;
1761 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1762 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1763 name = (char *) symtab_section->link->data + sym->st_name;
1764 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1765 sym->st_info, 0, sym->st_shndx, name);
1766 index = sym - (ElfW(Sym) *) symtab_section->data;
1767 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1771 #endif
1773 /* Allocate strings for section names and decide if an unallocated section
1774 should be output.
1775 NOTE: the strsec section comes last, so its size is also correct ! */
1776 static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1778 int i;
1779 Section *s;
1780 int textrel = 0;
1782 /* Allocate strings for section names */
1783 for(i = 1; i < s1->nb_sections; i++) {
1784 s = s1->sections[i];
1785 /* when generating a DLL, we include relocations but we may
1786 patch them */
1787 #ifndef ELF_OBJ_ONLY
1788 if (file_type == TCC_OUTPUT_DLL &&
1789 s->sh_type == SHT_RELX &&
1790 !(s->sh_flags & SHF_ALLOC) &&
1791 (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
1792 prepare_dynamic_rel(s1, s)) {
1793 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1794 textrel = 1;
1795 } else
1796 #endif
1797 if ((s1->do_debug && s->sh_type != SHT_RELX) ||
1798 file_type == TCC_OUTPUT_OBJ ||
1799 (s->sh_flags & SHF_ALLOC) ||
1800 i == (s1->nb_sections - 1)
1801 #ifdef TCC_TARGET_ARM
1802 || s->sh_type == SHT_ARM_ATTRIBUTES
1803 #endif
1805 /* we output all sections if debug or object file */
1806 s->sh_size = s->data_offset;
1808 #ifdef TCC_TARGET_ARM
1809 /* XXX: Suppress stack unwinding section. */
1810 if (s->sh_type == SHT_ARM_EXIDX) {
1811 s->sh_flags = 0;
1812 s->sh_size = 0;
1814 #endif
1815 if (s->sh_size || (s->sh_flags & SHF_ALLOC))
1816 s->sh_name = put_elf_str(strsec, s->name);
1818 strsec->sh_size = strsec->data_offset;
1819 return textrel;
1822 /* Info to be copied in dynamic section */
1823 struct dyn_inf {
1824 Section *dynamic;
1825 Section *dynstr;
1826 unsigned long data_offset;
1827 addr_t rel_addr;
1828 addr_t rel_size;
1831 /* Assign sections to segments and decide how are sections laid out when loaded
1832 in memory. This function also fills corresponding program headers. */
1833 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1834 Section *interp, Section* strsec,
1835 struct dyn_inf *dyninf, int *sec_order)
1837 int i, sh_order_index, file_offset;
1838 Section *s;
1840 sh_order_index = 1;
1841 file_offset = 0;
1842 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1843 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1845 #ifndef ELF_OBJ_ONLY
1846 if (phnum > 0) { /* phnum is 0 for TCC_OUTPUT_OBJ */
1847 unsigned long s_align;
1848 long long tmp;
1849 addr_t addr;
1850 ElfW(Phdr) *ph;
1851 int j, k, file_type = s1->output_type;
1853 s_align = ELF_PAGE_SIZE;
1854 if (s1->section_align)
1855 s_align = s1->section_align;
1857 if (s1->has_text_addr) {
1858 int a_offset, p_offset;
1859 addr = s1->text_addr;
1860 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1861 ELF_PAGE_SIZE */
1862 a_offset = (int) (addr & (s_align - 1));
1863 p_offset = file_offset & (s_align - 1);
1864 if (a_offset < p_offset)
1865 a_offset += s_align;
1866 file_offset += (a_offset - p_offset);
1867 } else {
1868 if (file_type == TCC_OUTPUT_DLL)
1869 addr = 0;
1870 else
1871 addr = ELF_START_ADDR;
1872 /* compute address after headers */
1873 addr += (file_offset & (s_align - 1));
1876 ph = &phdr[0];
1877 /* Leave one program headers for the program interpreter and one for
1878 the program header table itself if needed. These are done later as
1879 they require section layout to be done first. */
1880 if (interp)
1881 ph += 2;
1883 /* dynamic relocation table information, for .dynamic section */
1884 dyninf->rel_addr = dyninf->rel_size = 0;
1886 for(j = 0; j < (phnum == 6 ? 3 : 2); j++) {
1887 Section *relocplt = s1->got ? s1->got->relocplt : NULL;
1889 ph->p_type = j == 2 ? PT_TLS : PT_LOAD;
1890 if (j == 0)
1891 ph->p_flags = PF_R | PF_X;
1892 else
1893 ph->p_flags = PF_R | PF_W;
1894 ph->p_align = j == 2 ? 4 : s_align;
1896 /* Decide the layout of sections loaded in memory. This must
1897 be done before program headers are filled since they contain
1898 info about the layout. We do the following ordering: interp,
1899 symbol tables, relocations, progbits, nobits */
1900 /* XXX: do faster and simpler sorting */
1901 for(k = 0; k < 6; k++) {
1902 for(i = 1; i < s1->nb_sections; i++) {
1903 s = s1->sections[i];
1904 /* compute if section should be included */
1905 if (j == 0) {
1906 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1907 SHF_ALLOC)
1908 continue;
1909 } else if (j == 1) {
1910 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1911 (SHF_ALLOC | SHF_WRITE))
1912 continue;
1913 } else {
1914 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1915 (SHF_ALLOC | SHF_WRITE | SHF_TLS))
1916 continue;
1918 if (s == interp) {
1919 if (k != 0)
1920 continue;
1921 } else if ((s->sh_type == SHT_DYNSYM ||
1922 s->sh_type == SHT_STRTAB ||
1923 s->sh_type == SHT_HASH)
1924 && !strstr(s->name, ".stab")) {
1925 if (k != 1)
1926 continue;
1927 } else if (s->sh_type == SHT_RELX) {
1928 if (k != 2 && s != relocplt)
1929 continue;
1930 else if (k != 3 && s == relocplt)
1931 continue;
1932 } else if (s->sh_type == SHT_NOBITS) {
1933 if (k != 5)
1934 continue;
1935 } else {
1936 if (k != 4)
1937 continue;
1939 sec_order[sh_order_index++] = i;
1941 /* section matches: we align it and add its size */
1942 tmp = addr;
1943 addr = (addr + s->sh_addralign - 1) &
1944 ~(s->sh_addralign - 1);
1945 file_offset += (int) ( addr - tmp );
1946 s->sh_offset = file_offset;
1947 s->sh_addr = addr;
1949 /* update program header infos */
1950 if (ph->p_offset == 0) {
1951 ph->p_offset = file_offset;
1952 ph->p_vaddr = addr;
1953 ph->p_paddr = ph->p_vaddr;
1955 /* update dynamic relocation infos */
1956 if (s->sh_type == SHT_RELX && s != relocplt) {
1957 if (dyninf->rel_size == 0)
1958 dyninf->rel_addr = addr;
1959 dyninf->rel_size += s->sh_size;
1961 addr += s->sh_size;
1962 if (s->sh_type != SHT_NOBITS)
1963 file_offset += s->sh_size;
1966 if (j == 0) {
1967 /* Make the first PT_LOAD segment include the program
1968 headers itself (and the ELF header as well), it'll
1969 come out with same memory use but will make various
1970 tools like binutils strip work better. */
1971 ph->p_offset &= ~(ph->p_align - 1);
1972 ph->p_vaddr &= ~(ph->p_align - 1);
1973 ph->p_paddr &= ~(ph->p_align - 1);
1975 ph->p_filesz = file_offset - ph->p_offset;
1976 ph->p_memsz = addr - ph->p_vaddr;
1977 ph++;
1978 if (j == 0) {
1979 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1980 /* if in the middle of a page, we duplicate the page in
1981 memory so that one copy is RX and the other is RW */
1982 if ((addr & (s_align - 1)) != 0)
1983 addr += s_align;
1984 } else {
1985 addr = (addr + s_align - 1) & ~(s_align - 1);
1986 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1991 #endif /* ELF_OBJ_ONLY */
1993 /* all other sections come after */
1994 for(i = 1; i < s1->nb_sections; i++) {
1995 s = s1->sections[i];
1996 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1997 continue;
1998 sec_order[sh_order_index++] = i;
2000 file_offset = (file_offset + s->sh_addralign - 1) &
2001 ~(s->sh_addralign - 1);
2002 s->sh_offset = file_offset;
2003 if (s->sh_type != SHT_NOBITS)
2004 file_offset += s->sh_size;
2007 return file_offset;
2010 #ifndef ELF_OBJ_ONLY
2011 /* put dynamic tag */
2012 static void put_dt(Section *dynamic, int dt, addr_t val)
2014 ElfW(Dyn) *dyn;
2015 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
2016 dyn->d_tag = dt;
2017 dyn->d_un.d_val = val;
2020 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
2021 Section *dynamic, Section *note)
2023 ElfW(Phdr) *ph;
2025 /* if interpreter, then add corresponding program header */
2026 if (interp) {
2027 ph = &phdr[0];
2029 ph->p_type = PT_PHDR;
2030 ph->p_offset = sizeof(ElfW(Ehdr));
2031 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
2032 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
2033 ph->p_paddr = ph->p_vaddr;
2034 ph->p_flags = PF_R | PF_X;
2035 ph->p_align = 4; /* interp->sh_addralign; */
2036 ph++;
2038 ph->p_type = PT_INTERP;
2039 ph->p_offset = interp->sh_offset;
2040 ph->p_vaddr = interp->sh_addr;
2041 ph->p_paddr = ph->p_vaddr;
2042 ph->p_filesz = interp->sh_size;
2043 ph->p_memsz = interp->sh_size;
2044 ph->p_flags = PF_R;
2045 ph->p_align = interp->sh_addralign;
2048 if (note) {
2049 ph = &phdr[phnum - 2];
2051 ph->p_type = PT_NOTE;
2052 ph->p_offset = note->sh_offset;
2053 ph->p_vaddr = note->sh_addr;
2054 ph->p_paddr = ph->p_vaddr;
2055 ph->p_filesz = note->sh_size;
2056 ph->p_memsz = note->sh_size;
2057 ph->p_flags = PF_R;
2058 ph->p_align = note->sh_addralign;
2061 /* if dynamic section, then add corresponding program header */
2062 if (dynamic) {
2063 ph = &phdr[phnum - 1];
2065 ph->p_type = PT_DYNAMIC;
2066 ph->p_offset = dynamic->sh_offset;
2067 ph->p_vaddr = dynamic->sh_addr;
2068 ph->p_paddr = ph->p_vaddr;
2069 ph->p_filesz = dynamic->sh_size;
2070 ph->p_memsz = dynamic->sh_size;
2071 ph->p_flags = PF_R | PF_W;
2072 ph->p_align = dynamic->sh_addralign;
2076 /* Fill the dynamic section with tags describing the address and size of
2077 sections */
2078 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2080 Section *dynamic = dyninf->dynamic;
2081 Section *s;
2083 /* put dynamic section entries */
2084 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2085 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2086 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2087 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2088 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2089 #if PTR_SIZE == 8
2090 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2091 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2092 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2093 if (s1->got && s1->got->relocplt) {
2094 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2095 put_dt(dynamic, DT_PLTRELSZ, s1->got->relocplt->data_offset);
2096 put_dt(dynamic, DT_JMPREL, s1->got->relocplt->sh_addr);
2097 put_dt(dynamic, DT_PLTREL, DT_RELA);
2099 put_dt(dynamic, DT_RELACOUNT, 0);
2100 #else
2101 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2102 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2103 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2104 if (s1->got && s1->got->relocplt) {
2105 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2106 put_dt(dynamic, DT_PLTRELSZ, s1->got->relocplt->data_offset);
2107 put_dt(dynamic, DT_JMPREL, s1->got->relocplt->sh_addr);
2108 put_dt(dynamic, DT_PLTREL, DT_REL);
2110 put_dt(dynamic, DT_RELCOUNT, 0);
2111 #endif
2112 if (versym_section && verneed_section) {
2113 /* The dynamic linker can not handle VERSYM without VERNEED */
2114 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2115 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2116 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2118 s = find_section_create (s1, ".preinit_array", 0);
2119 if (s && s->data_offset) {
2120 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2121 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2123 s = find_section_create (s1, ".init_array", 0);
2124 if (s && s->data_offset) {
2125 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2126 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2128 s = find_section_create (s1, ".fini_array", 0);
2129 if (s && s->data_offset) {
2130 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2131 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2133 s = find_section_create (s1, ".init", 0);
2134 if (s && s->data_offset) {
2135 put_dt(dynamic, DT_INIT, s->sh_addr);
2137 s = find_section_create (s1, ".fini", 0);
2138 if (s && s->data_offset) {
2139 put_dt(dynamic, DT_FINI, s->sh_addr);
2141 if (s1->do_debug)
2142 put_dt(dynamic, DT_DEBUG, 0);
2143 put_dt(dynamic, DT_NULL, 0);
2146 /* Relocate remaining sections and symbols (that is those not related to
2147 dynamic linking) */
2148 static int final_sections_reloc(TCCState *s1)
2150 int i;
2151 Section *s;
2153 relocate_syms(s1, s1->symtab, 0);
2155 if (s1->nb_errors != 0)
2156 return -1;
2158 /* relocate sections */
2159 /* XXX: ignore sections with allocated relocations ? */
2160 for(i = 1; i < s1->nb_sections; i++) {
2161 s = s1->sections[i];
2162 if (s->reloc && (s != s1->got || s1->static_link))
2163 relocate_section(s1, s);
2166 /* relocate relocation entries if the relocation tables are
2167 allocated in the executable */
2168 for(i = 1; i < s1->nb_sections; i++) {
2169 s = s1->sections[i];
2170 if ((s->sh_flags & SHF_ALLOC) &&
2171 s->sh_type == SHT_RELX) {
2172 relocate_rel(s1, s);
2175 return 0;
2177 #endif
2179 /* Create an ELF file on disk.
2180 This function handle ELF specific layout requirements */
2181 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2182 int file_offset, int *sec_order)
2184 int i, shnum, offset, size, file_type;
2185 Section *s;
2186 ElfW(Ehdr) ehdr;
2187 ElfW(Shdr) shdr, *sh;
2189 file_type = s1->output_type;
2190 shnum = s1->nb_sections;
2192 memset(&ehdr, 0, sizeof(ehdr));
2194 if (phnum > 0) {
2195 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2196 ehdr.e_phnum = phnum;
2197 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2200 /* align to 4 */
2201 file_offset = (file_offset + 3) & -4;
2203 /* fill header */
2204 ehdr.e_ident[0] = ELFMAG0;
2205 ehdr.e_ident[1] = ELFMAG1;
2206 ehdr.e_ident[2] = ELFMAG2;
2207 ehdr.e_ident[3] = ELFMAG3;
2208 ehdr.e_ident[4] = ELFCLASSW;
2209 ehdr.e_ident[5] = ELFDATA2LSB;
2210 ehdr.e_ident[6] = EV_CURRENT;
2211 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2212 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2213 #endif
2214 #ifdef TCC_TARGET_ARM
2215 #ifdef TCC_ARM_EABI
2216 ehdr.e_ident[EI_OSABI] = 0;
2217 ehdr.e_flags = EF_ARM_EABI_VER4;
2218 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2219 ehdr.e_flags |= EF_ARM_HASENTRY;
2220 if (s1->float_abi == ARM_HARD_FLOAT)
2221 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2222 else
2223 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2224 #else
2225 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2226 #endif
2227 #elif defined TCC_TARGET_RISCV64
2228 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2229 #endif
2230 switch(file_type) {
2231 default:
2232 case TCC_OUTPUT_EXE:
2233 ehdr.e_type = ET_EXEC;
2234 ehdr.e_entry = get_sym_addr(s1, "_start", 1, 0);
2235 break;
2236 case TCC_OUTPUT_DLL:
2237 ehdr.e_type = ET_DYN;
2238 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2239 break;
2240 case TCC_OUTPUT_OBJ:
2241 ehdr.e_type = ET_REL;
2242 break;
2244 ehdr.e_machine = EM_TCC_TARGET;
2245 ehdr.e_version = EV_CURRENT;
2246 ehdr.e_shoff = file_offset;
2247 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2248 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2249 ehdr.e_shnum = shnum;
2250 ehdr.e_shstrndx = shnum - 1;
2252 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2253 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2254 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2256 sort_syms(s1, symtab_section);
2257 for(i = 1; i < s1->nb_sections; i++) {
2258 s = s1->sections[sec_order[i]];
2259 if (s->sh_type != SHT_NOBITS) {
2260 while (offset < s->sh_offset) {
2261 fputc(0, f);
2262 offset++;
2264 size = s->sh_size;
2265 if (size)
2266 fwrite(s->data, 1, size, f);
2267 offset += size;
2271 /* output section headers */
2272 while (offset < ehdr.e_shoff) {
2273 fputc(0, f);
2274 offset++;
2277 for(i = 0; i < s1->nb_sections; i++) {
2278 sh = &shdr;
2279 memset(sh, 0, sizeof(ElfW(Shdr)));
2280 s = s1->sections[i];
2281 if (s) {
2282 sh->sh_name = s->sh_name;
2283 sh->sh_type = s->sh_type;
2284 sh->sh_flags = s->sh_flags;
2285 sh->sh_entsize = s->sh_entsize;
2286 sh->sh_info = s->sh_info;
2287 if (s->link)
2288 sh->sh_link = s->link->sh_num;
2289 sh->sh_addralign = s->sh_addralign;
2290 sh->sh_addr = s->sh_addr;
2291 sh->sh_offset = s->sh_offset;
2292 sh->sh_size = s->sh_size;
2294 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2298 /* Write an elf, coff or "binary" file */
2299 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2300 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2302 int fd, mode, file_type;
2303 FILE *f;
2305 file_type = s1->output_type;
2306 if (file_type == TCC_OUTPUT_OBJ)
2307 mode = 0666;
2308 else
2309 mode = 0777;
2310 unlink(filename);
2311 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2312 if (fd < 0) {
2313 tcc_error_noabort("could not write '%s'", filename);
2314 return -1;
2316 f = fdopen(fd, "wb");
2317 if (s1->verbose)
2318 printf("<- %s\n", filename);
2320 #ifdef TCC_TARGET_COFF
2321 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2322 tcc_output_coff(s1, f);
2323 else
2324 #endif
2325 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2326 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2327 else
2328 tcc_output_binary(s1, f, sec_order);
2329 fclose(f);
2331 return 0;
2334 #ifndef ELF_OBJ_ONLY
2335 /* Sort section headers by assigned sh_addr, remove sections
2336 that we aren't going to output. */
2337 static void tidy_section_headers(TCCState *s1, int *sec_order)
2339 int i, nnew, l, *backmap;
2340 Section **snew, *s;
2341 ElfW(Sym) *sym;
2343 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2344 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2345 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2346 s = s1->sections[sec_order[i]];
2347 if (!i || s->sh_name) {
2348 backmap[sec_order[i]] = nnew;
2349 snew[nnew] = s;
2350 ++nnew;
2351 } else {
2352 backmap[sec_order[i]] = 0;
2353 snew[--l] = s;
2356 for (i = 0; i < nnew; i++) {
2357 s = snew[i];
2358 if (s) {
2359 s->sh_num = i;
2360 if (s->sh_type == SHT_RELX)
2361 s->sh_info = backmap[s->sh_info];
2365 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2366 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2367 sym->st_shndx = backmap[sym->st_shndx];
2368 if ( !s1->static_link ) {
2369 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2370 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2371 sym->st_shndx = backmap[sym->st_shndx];
2373 for (i = 0; i < s1->nb_sections; i++)
2374 sec_order[i] = i;
2375 tcc_free(s1->sections);
2376 s1->sections = snew;
2377 s1->nb_sections = nnew;
2378 tcc_free(backmap);
2380 #endif
2382 #ifdef TCC_TARGET_ARM
2383 static void create_arm_attribute_section(TCCState *s1)
2385 // Needed for DLL support.
2386 static const unsigned char arm_attr[] = {
2387 0x41, // 'A'
2388 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2389 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2390 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2391 0x05, 0x36, 0x00, // 'CPU_name', "6"
2392 0x06, 0x06, // 'CPU_arch', 'v6'
2393 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2394 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2395 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2396 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2397 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2398 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2399 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2400 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2401 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2402 0x1a, 0x02, // 'ABI_enum_size', 'int'
2403 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2404 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2406 Section *attr = new_section(s1, ".ARM.attributes", SHT_ARM_ATTRIBUTES, 0);
2407 unsigned char *ptr = section_ptr_add(attr, sizeof(arm_attr));
2408 attr->sh_addralign = 1;
2409 memcpy(ptr, arm_attr, sizeof(arm_attr));
2410 if (s1->float_abi != ARM_HARD_FLOAT) {
2411 ptr[26] = 0x00; // 'FP_arch', 'No'
2412 ptr[41] = 0x1e; // 'ABI_optimization_goals'
2413 ptr[42] = 0x06; // 'Aggressive Debug'
2416 #endif
2418 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2419 static Section *create_bsd_note_section(TCCState *s1,
2420 const char *name,
2421 const char *value)
2423 Section *s = find_section (s1, name);
2425 if (s->data_offset == 0) {
2426 unsigned char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
2427 ElfW(Nhdr) *note = (ElfW(Nhdr) *) ptr;
2429 s->sh_type = SHT_NOTE;
2430 note->n_namesz = 8;
2431 note->n_descsz = 4;
2432 note->n_type = ELF_NOTE_OS_GNU;
2433 strcpy (ptr + sizeof(ElfW(Nhdr)), value);
2435 return s;
2437 #endif
2439 /* Output an elf, coff or binary file */
2440 /* XXX: suppress unneeded sections */
2441 static int elf_output_file(TCCState *s1, const char *filename)
2443 int ret, phnum, shnum, file_type, file_offset, *sec_order;
2444 struct dyn_inf dyninf = {0};
2445 ElfW(Phdr) *phdr;
2446 Section *strsec, *interp, *dynamic, *dynstr, *note = NULL;
2448 file_type = s1->output_type;
2450 #ifdef TCC_TARGET_ARM
2451 create_arm_attribute_section (s1);
2452 #endif
2453 #if TARGETOS_OpenBSD
2454 if (file_type != TCC_OUTPUT_OBJ)
2455 note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
2456 #endif
2457 #if TARGETOS_NetBSD
2458 if (file_type != TCC_OUTPUT_OBJ)
2459 note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD");
2460 #endif
2462 s1->nb_errors = 0;
2463 ret = -1;
2464 phdr = NULL;
2465 sec_order = NULL;
2466 interp = dynamic = dynstr = NULL; /* avoid warning */
2468 #ifndef ELF_OBJ_ONLY
2469 if (file_type != TCC_OUTPUT_OBJ) {
2470 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2471 tcc_add_runtime(s1);
2472 resolve_common_syms(s1);
2474 if (!s1->static_link) {
2475 if (file_type == TCC_OUTPUT_EXE) {
2476 char *ptr;
2477 /* allow override the dynamic loader */
2478 const char *elfint = getenv("LD_SO");
2479 if (elfint == NULL)
2480 elfint = DEFAULT_ELFINTERP(s1);
2481 /* add interpreter section only if executable */
2482 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2483 interp->sh_addralign = 1;
2484 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2485 strcpy(ptr, elfint);
2488 /* add dynamic symbol table */
2489 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2490 ".dynstr",
2491 ".hash", SHF_ALLOC);
2492 dynstr = s1->dynsym->link;
2493 /* add dynamic section */
2494 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2495 SHF_ALLOC | SHF_WRITE);
2496 dynamic->link = dynstr;
2497 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2499 build_got(s1);
2501 if (file_type == TCC_OUTPUT_EXE) {
2502 bind_exe_dynsyms(s1);
2503 if (s1->nb_errors)
2504 goto the_end;
2505 bind_libs_dynsyms(s1);
2506 } else {
2507 /* shared library case: simply export all global symbols */
2508 export_global_syms(s1);
2511 build_got_entries(s1);
2512 version_add (s1);
2514 #endif
2516 /* we add a section for symbols */
2517 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2518 put_elf_str(strsec, "");
2520 /* Allocate strings for section names */
2521 ret = alloc_sec_names(s1, file_type, strsec);
2523 #ifndef ELF_OBJ_ONLY
2524 if (dynamic) {
2525 int i;
2526 /* add a list of needed dlls */
2527 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2528 DLLReference *dllref = s1->loaded_dlls[i];
2529 if (dllref->level == 0)
2530 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2533 if (s1->rpath)
2534 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2535 put_elf_str(dynstr, s1->rpath));
2537 if (file_type == TCC_OUTPUT_DLL) {
2538 if (s1->soname)
2539 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2540 /* XXX: currently, since we do not handle PIC code, we
2541 must relocate the readonly segments */
2542 if (ret)
2543 put_dt(dynamic, DT_TEXTREL, 0);
2546 if (s1->symbolic)
2547 put_dt(dynamic, DT_SYMBOLIC, 0);
2549 dyninf.dynamic = dynamic;
2550 dyninf.dynstr = dynstr;
2551 /* remember offset and reserve space for 2nd call below */
2552 dyninf.data_offset = dynamic->data_offset;
2553 fill_dynamic(s1, &dyninf);
2554 dynamic->sh_size = dynamic->data_offset;
2555 dynstr->sh_size = dynstr->data_offset;
2557 #endif
2559 /* compute number of program headers */
2560 if (file_type == TCC_OUTPUT_OBJ)
2561 phnum = 0;
2562 else if (file_type == TCC_OUTPUT_DLL)
2563 phnum = 3;
2564 else if (s1->static_link)
2565 phnum = 2;
2566 else {
2567 int i;
2568 for (i = 1; i < s1->nb_sections &&
2569 !(s1->sections[i]->sh_flags & SHF_TLS); i++);
2570 phnum = i < s1->nb_sections ? 6 : 5;
2573 phnum += note != NULL;
2575 /* allocate program segment headers */
2576 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2578 /* compute number of sections */
2579 shnum = s1->nb_sections;
2581 /* this array is used to reorder sections in the output file */
2582 sec_order = tcc_malloc(sizeof(int) * shnum);
2583 sec_order[0] = 0;
2585 /* compute section to program header mapping */
2586 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2587 sec_order);
2589 #ifndef ELF_OBJ_ONLY
2590 /* Fill remaining program header and finalize relocation related to dynamic
2591 linking. */
2592 if (file_type != TCC_OUTPUT_OBJ) {
2593 fill_unloadable_phdr(phdr, phnum, interp, dynamic, note);
2594 if (dynamic) {
2595 ElfW(Sym) *sym;
2596 dynamic->data_offset = dyninf.data_offset;
2597 fill_dynamic(s1, &dyninf);
2599 /* put in GOT the dynamic section address and relocate PLT */
2600 write32le(s1->got->data, dynamic->sh_addr);
2601 if (file_type == TCC_OUTPUT_EXE
2602 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2603 relocate_plt(s1);
2605 /* relocate symbols in .dynsym now that final addresses are known */
2606 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2607 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2608 /* do symbol relocation */
2609 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2614 /* if building executable or DLL, then relocate each section
2615 except the GOT which is already relocated */
2616 ret = final_sections_reloc(s1);
2617 if (ret)
2618 goto the_end;
2619 tidy_section_headers(s1, sec_order);
2621 /* Perform relocation to GOT or PLT entries */
2622 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2623 fill_got(s1);
2624 else if (s1->got)
2625 fill_local_got_entries(s1);
2627 #endif
2629 /* Create the ELF file with name 'filename' */
2630 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2631 s1->nb_sections = shnum;
2632 goto the_end;
2633 the_end:
2634 tcc_free(sec_order);
2635 tcc_free(phdr);
2636 return ret;
2639 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2641 int ret;
2642 #ifdef TCC_TARGET_PE
2643 if (s->output_type != TCC_OUTPUT_OBJ) {
2644 ret = pe_output_file(s, filename);
2645 } else
2646 #elif TCC_TARGET_MACHO
2647 if (s->output_type != TCC_OUTPUT_OBJ) {
2648 ret = macho_output_file(s, filename);
2649 } else
2650 #endif
2651 ret = elf_output_file(s, filename);
2652 return ret;
2655 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
2656 char *cbuf = buf;
2657 size_t rnum = 0;
2658 while (1) {
2659 ssize_t num = read(fd, cbuf, count-rnum);
2660 if (num < 0) return num;
2661 if (num == 0) return rnum;
2662 rnum += num;
2663 cbuf += num;
2667 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
2669 void *data;
2671 data = tcc_malloc(size);
2672 lseek(fd, file_offset, SEEK_SET);
2673 full_read(fd, data, size);
2674 return data;
2677 typedef struct SectionMergeInfo {
2678 Section *s; /* corresponding existing section */
2679 unsigned long offset; /* offset of the new section in the existing section */
2680 uint8_t new_section; /* true if section 's' was added */
2681 uint8_t link_once; /* true if link once section */
2682 } SectionMergeInfo;
2684 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2686 int size = full_read(fd, h, sizeof *h);
2687 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2688 if (h->e_type == ET_REL)
2689 return AFF_BINTYPE_REL;
2690 if (h->e_type == ET_DYN)
2691 return AFF_BINTYPE_DYN;
2692 } else if (size >= 8) {
2693 if (0 == memcmp(h, ARMAG, 8))
2694 return AFF_BINTYPE_AR;
2695 #ifdef TCC_TARGET_COFF
2696 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2697 return AFF_BINTYPE_C67;
2698 #endif
2700 return 0;
2703 /* load an object file and merge it with current files */
2704 /* XXX: handle correctly stab (debug) info */
2705 ST_FUNC int tcc_load_object_file(TCCState *s1,
2706 int fd, unsigned long file_offset)
2708 ElfW(Ehdr) ehdr;
2709 ElfW(Shdr) *shdr, *sh;
2710 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2711 char *strsec, *strtab;
2712 int stab_index, stabstr_index;
2713 int *old_to_new_syms;
2714 char *sh_name, *name;
2715 SectionMergeInfo *sm_table, *sm;
2716 ElfW(Sym) *sym, *symtab;
2717 ElfW_Rel *rel;
2718 Section *s;
2720 lseek(fd, file_offset, SEEK_SET);
2721 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2722 goto fail1;
2723 /* test CPU specific stuff */
2724 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2725 ehdr.e_machine != EM_TCC_TARGET) {
2726 fail1:
2727 tcc_error_noabort("invalid object file");
2728 return -1;
2730 /* read sections */
2731 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2732 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2733 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2735 /* load section names */
2736 sh = &shdr[ehdr.e_shstrndx];
2737 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2739 /* load symtab and strtab */
2740 old_to_new_syms = NULL;
2741 symtab = NULL;
2742 strtab = NULL;
2743 nb_syms = 0;
2744 seencompressed = 0;
2745 stab_index = stabstr_index = 0;
2747 for(i = 1; i < ehdr.e_shnum; i++) {
2748 sh = &shdr[i];
2749 if (sh->sh_type == SHT_SYMTAB) {
2750 if (symtab) {
2751 tcc_error_noabort("object must contain only one symtab");
2752 fail:
2753 ret = -1;
2754 goto the_end;
2756 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2757 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2758 sm_table[i].s = symtab_section;
2760 /* now load strtab */
2761 sh = &shdr[sh->sh_link];
2762 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2764 if (sh->sh_flags & SHF_COMPRESSED)
2765 seencompressed = 1;
2768 /* now examine each section and try to merge its content with the
2769 ones in memory */
2770 for(i = 1; i < ehdr.e_shnum; i++) {
2771 /* no need to examine section name strtab */
2772 if (i == ehdr.e_shstrndx)
2773 continue;
2774 sh = &shdr[i];
2775 if (sh->sh_type == SHT_RELX)
2776 sh = &shdr[sh->sh_info];
2777 /* ignore sections types we do not handle (plus relocs to those) */
2778 if (sh->sh_type != SHT_PROGBITS &&
2779 #ifdef TCC_ARM_EABI
2780 sh->sh_type != SHT_ARM_EXIDX &&
2781 #endif
2782 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2783 sh->sh_type != SHT_X86_64_UNWIND &&
2784 #endif
2785 sh->sh_type != SHT_NOTE &&
2786 sh->sh_type != SHT_NOBITS &&
2787 sh->sh_type != SHT_PREINIT_ARRAY &&
2788 sh->sh_type != SHT_INIT_ARRAY &&
2789 sh->sh_type != SHT_FINI_ARRAY &&
2790 strcmp(strsec + sh->sh_name, ".stabstr")
2792 continue;
2793 if (seencompressed
2794 && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
2795 continue;
2797 sh = &shdr[i];
2798 sh_name = strsec + sh->sh_name;
2799 if (sh->sh_addralign < 1)
2800 sh->sh_addralign = 1;
2801 /* find corresponding section, if any */
2802 for(j = 1; j < s1->nb_sections;j++) {
2803 s = s1->sections[j];
2804 if (!strcmp(s->name, sh_name)) {
2805 if (!strncmp(sh_name, ".gnu.linkonce",
2806 sizeof(".gnu.linkonce") - 1)) {
2807 /* if a 'linkonce' section is already present, we
2808 do not add it again. It is a little tricky as
2809 symbols can still be defined in
2810 it. */
2811 sm_table[i].link_once = 1;
2812 goto next;
2814 if (stab_section) {
2815 if (s == stab_section)
2816 stab_index = i;
2817 if (s == stab_section->link)
2818 stabstr_index = i;
2820 goto found;
2823 /* not found: create new section */
2824 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2825 /* take as much info as possible from the section. sh_link and
2826 sh_info will be updated later */
2827 s->sh_addralign = sh->sh_addralign;
2828 s->sh_entsize = sh->sh_entsize;
2829 sm_table[i].new_section = 1;
2830 found:
2831 if (sh->sh_type != s->sh_type) {
2832 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2833 if (strcmp (s->name, ".eh_frame"))
2834 #endif
2836 tcc_error_noabort("invalid section type");
2837 goto fail;
2840 /* align start of section */
2841 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
2842 if (sh->sh_addralign > s->sh_addralign)
2843 s->sh_addralign = sh->sh_addralign;
2844 sm_table[i].offset = s->data_offset;
2845 sm_table[i].s = s;
2846 /* concatenate sections */
2847 size = sh->sh_size;
2848 if (sh->sh_type != SHT_NOBITS) {
2849 unsigned char *ptr;
2850 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2851 ptr = section_ptr_add(s, size);
2852 full_read(fd, ptr, size);
2853 } else {
2854 s->data_offset += size;
2856 next: ;
2859 /* gr relocate stab strings */
2860 if (stab_index && stabstr_index) {
2861 Stab_Sym *a, *b;
2862 unsigned o;
2863 s = sm_table[stab_index].s;
2864 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2865 b = (Stab_Sym *)(s->data + s->data_offset);
2866 o = sm_table[stabstr_index].offset;
2867 while (a < b) {
2868 if (a->n_strx)
2869 a->n_strx += o;
2870 a++;
2874 /* second short pass to update sh_link and sh_info fields of new
2875 sections */
2876 for(i = 1; i < ehdr.e_shnum; i++) {
2877 s = sm_table[i].s;
2878 if (!s || !sm_table[i].new_section)
2879 continue;
2880 sh = &shdr[i];
2881 if (sh->sh_link > 0)
2882 s->link = sm_table[sh->sh_link].s;
2883 if (sh->sh_type == SHT_RELX) {
2884 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2885 /* update backward link */
2886 s1->sections[s->sh_info]->reloc = s;
2890 /* resolve symbols */
2891 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2893 sym = symtab + 1;
2894 for(i = 1; i < nb_syms; i++, sym++) {
2895 if (sym->st_shndx != SHN_UNDEF &&
2896 sym->st_shndx < SHN_LORESERVE) {
2897 sm = &sm_table[sym->st_shndx];
2898 if (sm->link_once) {
2899 /* if a symbol is in a link once section, we use the
2900 already defined symbol. It is very important to get
2901 correct relocations */
2902 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2903 name = strtab + sym->st_name;
2904 sym_index = find_elf_sym(symtab_section, name);
2905 if (sym_index)
2906 old_to_new_syms[i] = sym_index;
2908 continue;
2910 /* if no corresponding section added, no need to add symbol */
2911 if (!sm->s)
2912 continue;
2913 /* convert section number */
2914 sym->st_shndx = sm->s->sh_num;
2915 /* offset value */
2916 sym->st_value += sm->offset;
2918 /* add symbol */
2919 name = strtab + sym->st_name;
2920 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2921 sym->st_info, sym->st_other,
2922 sym->st_shndx, name);
2923 old_to_new_syms[i] = sym_index;
2926 /* third pass to patch relocation entries */
2927 for(i = 1; i < ehdr.e_shnum; i++) {
2928 s = sm_table[i].s;
2929 if (!s)
2930 continue;
2931 sh = &shdr[i];
2932 offset = sm_table[i].offset;
2933 switch(s->sh_type) {
2934 case SHT_RELX:
2935 /* take relocation offset information */
2936 offseti = sm_table[sh->sh_info].offset;
2937 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2938 int type;
2939 unsigned sym_index;
2940 /* convert symbol index */
2941 type = ELFW(R_TYPE)(rel->r_info);
2942 sym_index = ELFW(R_SYM)(rel->r_info);
2943 /* NOTE: only one symtab assumed */
2944 if (sym_index >= nb_syms)
2945 goto invalid_reloc;
2946 sym_index = old_to_new_syms[sym_index];
2947 /* ignore link_once in rel section. */
2948 if (!sym_index && !sm_table[sh->sh_info].link_once
2949 #ifdef TCC_TARGET_ARM
2950 && type != R_ARM_V4BX
2951 #elif defined TCC_TARGET_RISCV64
2952 && type != R_RISCV_ALIGN
2953 && type != R_RISCV_RELAX
2954 #endif
2956 invalid_reloc:
2957 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2958 i, strsec + sh->sh_name, (int)rel->r_offset);
2959 goto fail;
2961 rel->r_info = ELFW(R_INFO)(sym_index, type);
2962 /* offset the relocation offset */
2963 rel->r_offset += offseti;
2964 #ifdef TCC_TARGET_ARM
2965 /* Jumps and branches from a Thumb code to a PLT entry need
2966 special handling since PLT entries are ARM code.
2967 Unconditional bl instructions referencing PLT entries are
2968 handled by converting these instructions into blx
2969 instructions. Other case of instructions referencing a PLT
2970 entry require to add a Thumb stub before the PLT entry to
2971 switch to ARM mode. We set bit plt_thumb_stub of the
2972 attribute of a symbol to indicate such a case. */
2973 if (type == R_ARM_THM_JUMP24)
2974 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2975 #endif
2977 break;
2978 default:
2979 break;
2983 ret = 0;
2984 the_end:
2985 tcc_free(symtab);
2986 tcc_free(strtab);
2987 tcc_free(old_to_new_syms);
2988 tcc_free(sm_table);
2989 tcc_free(strsec);
2990 tcc_free(shdr);
2991 return ret;
2994 typedef struct ArchiveHeader {
2995 char ar_name[16]; /* name of this member */
2996 char ar_date[12]; /* file mtime */
2997 char ar_uid[6]; /* owner uid; printed as decimal */
2998 char ar_gid[6]; /* owner gid; printed as decimal */
2999 char ar_mode[8]; /* file mode, printed as octal */
3000 char ar_size[10]; /* file size, printed as decimal */
3001 char ar_fmag[2]; /* should contain ARFMAG */
3002 } ArchiveHeader;
3004 #define ARFMAG "`\n"
3006 static unsigned long long get_be(const uint8_t *b, int n)
3008 unsigned long long ret = 0;
3009 while (n)
3010 ret = (ret << 8) | *b++, --n;
3011 return ret;
3014 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
3016 char *p, *e;
3017 int len;
3018 lseek(fd, offset, SEEK_SET);
3019 len = full_read(fd, hdr, sizeof(ArchiveHeader));
3020 if (len != sizeof(ArchiveHeader))
3021 return len ? -1 : 0;
3022 p = hdr->ar_name;
3023 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
3024 --e;
3025 *e = '\0';
3026 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
3027 return len;
3030 /* load only the objects which resolve undefined symbols */
3031 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
3033 int i, bound, nsyms, sym_index, len, ret = -1;
3034 unsigned long long off;
3035 uint8_t *data;
3036 const char *ar_names, *p;
3037 const uint8_t *ar_index;
3038 ElfW(Sym) *sym;
3039 ArchiveHeader hdr;
3041 data = tcc_malloc(size);
3042 if (full_read(fd, data, size) != size)
3043 goto the_end;
3044 nsyms = get_be(data, entrysize);
3045 ar_index = data + entrysize;
3046 ar_names = (char *) ar_index + nsyms * entrysize;
3048 do {
3049 bound = 0;
3050 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
3051 Section *s = symtab_section;
3052 sym_index = find_elf_sym(s, p);
3053 if (!sym_index)
3054 continue;
3055 sym = &((ElfW(Sym) *)s->data)[sym_index];
3056 if(sym->st_shndx != SHN_UNDEF)
3057 continue;
3058 off = get_be(ar_index + i * entrysize, entrysize);
3059 len = read_ar_header(fd, off, &hdr);
3060 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
3061 tcc_error_noabort("invalid archive");
3062 goto the_end;
3064 off += len;
3065 if (s1->verbose == 2)
3066 printf(" -> %s\n", hdr.ar_name);
3067 if (tcc_load_object_file(s1, fd, off) < 0)
3068 goto the_end;
3069 ++bound;
3071 } while(bound);
3072 ret = 0;
3073 the_end:
3074 tcc_free(data);
3075 return ret;
3078 /* load a '.a' file */
3079 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
3081 ArchiveHeader hdr;
3082 /* char magic[8]; */
3083 int size, len;
3084 unsigned long file_offset;
3085 ElfW(Ehdr) ehdr;
3087 /* skip magic which was already checked */
3088 /* full_read(fd, magic, sizeof(magic)); */
3089 file_offset = sizeof ARMAG - 1;
3091 for(;;) {
3092 len = read_ar_header(fd, file_offset, &hdr);
3093 if (len == 0)
3094 return 0;
3095 if (len < 0) {
3096 tcc_error_noabort("invalid archive");
3097 return -1;
3099 file_offset += len;
3100 size = strtol(hdr.ar_size, NULL, 0);
3101 /* align to even */
3102 size = (size + 1) & ~1;
3103 if (alacarte) {
3104 /* coff symbol table : we handle it */
3105 if (!strcmp(hdr.ar_name, "/"))
3106 return tcc_load_alacarte(s1, fd, size, 4);
3107 if (!strcmp(hdr.ar_name, "/SYM64/"))
3108 return tcc_load_alacarte(s1, fd, size, 8);
3109 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3110 if (s1->verbose == 2)
3111 printf(" -> %s\n", hdr.ar_name);
3112 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3113 return -1;
3115 file_offset += size;
3119 #ifndef ELF_OBJ_ONLY
3120 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3121 LV, maybe create a new entry for (LIB,VERSION). */
3122 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3124 while (i >= *n) {
3125 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3126 (*lv)[(*n)++] = -1;
3128 if ((*lv)[i] == -1) {
3129 int v, prev_same_lib = -1;
3130 for (v = 0; v < nb_sym_versions; v++) {
3131 if (strcmp(sym_versions[v].lib, lib))
3132 continue;
3133 prev_same_lib = v;
3134 if (!strcmp(sym_versions[v].version, version))
3135 break;
3137 if (v == nb_sym_versions) {
3138 sym_versions = tcc_realloc (sym_versions,
3139 (v + 1) * sizeof(*sym_versions));
3140 sym_versions[v].lib = tcc_strdup(lib);
3141 sym_versions[v].version = tcc_strdup(version);
3142 sym_versions[v].out_index = 0;
3143 sym_versions[v].prev_same_lib = prev_same_lib;
3144 nb_sym_versions++;
3146 (*lv)[i] = v;
3150 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3151 VERNDX. */
3152 static void
3153 set_sym_version(TCCState *s1, int sym_index, int verndx)
3155 if (sym_index >= nb_sym_to_version) {
3156 int newelems = sym_index ? sym_index * 2 : 1;
3157 sym_to_version = tcc_realloc(sym_to_version,
3158 newelems * sizeof(*sym_to_version));
3159 memset(sym_to_version + nb_sym_to_version, -1,
3160 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3161 nb_sym_to_version = newelems;
3163 if (sym_to_version[sym_index] < 0)
3164 sym_to_version[sym_index] = verndx;
3167 struct versym_info {
3168 int nb_versyms;
3169 ElfW(Verdef) *verdef;
3170 ElfW(Verneed) *verneed;
3171 ElfW(Half) *versym;
3172 int nb_local_ver, *local_ver;
3176 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3178 char *lib, *version;
3179 uint32_t next;
3180 int i;
3182 #define DEBUG_VERSION 0
3184 if (v->versym && v->verdef) {
3185 ElfW(Verdef) *vdef = v->verdef;
3186 lib = NULL;
3187 do {
3188 ElfW(Verdaux) *verdaux =
3189 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3191 #if DEBUG_VERSION
3192 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3193 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3194 vdef->vd_hash);
3195 #endif
3196 if (vdef->vd_cnt) {
3197 version = dynstr + verdaux->vda_name;
3199 if (lib == NULL)
3200 lib = version;
3201 else
3202 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3203 lib, version);
3204 #if DEBUG_VERSION
3205 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3206 #endif
3208 next = vdef->vd_next;
3209 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3210 } while (next);
3212 if (v->versym && v->verneed) {
3213 ElfW(Verneed) *vneed = v->verneed;
3214 do {
3215 ElfW(Vernaux) *vernaux =
3216 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3218 lib = dynstr + vneed->vn_file;
3219 #if DEBUG_VERSION
3220 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3221 #endif
3222 for (i = 0; i < vneed->vn_cnt; i++) {
3223 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3224 version = dynstr + vernaux->vna_name;
3225 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3226 lib, version);
3227 #if DEBUG_VERSION
3228 printf (" vernaux(%u): %u %u %s\n",
3229 vernaux->vna_other, vernaux->vna_hash,
3230 vernaux->vna_flags, version);
3231 #endif
3233 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3235 next = vneed->vn_next;
3236 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3237 } while (next);
3240 #if DEBUG_VERSION
3241 for (i = 0; i < v->nb_local_ver; i++) {
3242 if (v->local_ver[i] > 0) {
3243 printf ("%d: lib: %s, version %s\n",
3244 i, sym_versions[v->local_ver[i]].lib,
3245 sym_versions[v->local_ver[i]].version);
3248 #endif
3251 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3252 is referenced by the user (so it should be added as DT_NEEDED in
3253 the generated ELF file) */
3254 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3256 ElfW(Ehdr) ehdr;
3257 ElfW(Shdr) *shdr, *sh, *sh1;
3258 int i, j, nb_syms, nb_dts, sym_bind, ret;
3259 ElfW(Sym) *sym, *dynsym;
3260 ElfW(Dyn) *dt, *dynamic;
3262 char *dynstr;
3263 int sym_index;
3264 const char *name, *soname;
3265 DLLReference *dllref;
3266 struct versym_info v;
3268 full_read(fd, &ehdr, sizeof(ehdr));
3270 /* test CPU specific stuff */
3271 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3272 ehdr.e_machine != EM_TCC_TARGET) {
3273 tcc_error_noabort("bad architecture");
3274 return -1;
3277 /* read sections */
3278 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3280 /* load dynamic section and dynamic symbols */
3281 nb_syms = 0;
3282 nb_dts = 0;
3283 dynamic = NULL;
3284 dynsym = NULL; /* avoid warning */
3285 dynstr = NULL; /* avoid warning */
3286 memset(&v, 0, sizeof v);
3288 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3289 switch(sh->sh_type) {
3290 case SHT_DYNAMIC:
3291 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3292 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3293 break;
3294 case SHT_DYNSYM:
3295 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3296 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3297 sh1 = &shdr[sh->sh_link];
3298 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3299 break;
3300 case SHT_GNU_verdef:
3301 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3302 break;
3303 case SHT_GNU_verneed:
3304 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3305 break;
3306 case SHT_GNU_versym:
3307 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3308 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3309 break;
3310 default:
3311 break;
3315 /* compute the real library name */
3316 soname = tcc_basename(filename);
3318 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3319 if (dt->d_tag == DT_SONAME) {
3320 soname = dynstr + dt->d_un.d_val;
3324 /* if the dll is already loaded, do not load it */
3325 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3326 dllref = s1->loaded_dlls[i];
3327 if (!strcmp(soname, dllref->name)) {
3328 /* but update level if needed */
3329 if (level < dllref->level)
3330 dllref->level = level;
3331 ret = 0;
3332 goto the_end;
3336 if (v.nb_versyms != nb_syms)
3337 tcc_free (v.versym), v.versym = NULL;
3338 else
3339 store_version(s1, &v, dynstr);
3341 /* add the dll and its level */
3342 tcc_add_dllref(s1, soname)->level = level;
3344 /* add dynamic symbols in dynsym_section */
3345 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3346 sym_bind = ELFW(ST_BIND)(sym->st_info);
3347 if (sym_bind == STB_LOCAL)
3348 continue;
3349 name = dynstr + sym->st_name;
3350 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3351 sym->st_info, sym->st_other, sym->st_shndx, name);
3352 if (v.versym) {
3353 ElfW(Half) vsym = v.versym[i];
3354 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3355 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3359 /* load all referenced DLLs */
3360 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3361 switch(dt->d_tag) {
3362 case DT_NEEDED:
3363 name = dynstr + dt->d_un.d_val;
3364 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3365 dllref = s1->loaded_dlls[j];
3366 if (!strcmp(name, dllref->name))
3367 goto already_loaded;
3369 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3370 tcc_error_noabort("referenced dll '%s' not found", name);
3371 ret = -1;
3372 goto the_end;
3374 already_loaded:
3375 break;
3378 ret = 0;
3379 the_end:
3380 tcc_free(dynstr);
3381 tcc_free(dynsym);
3382 tcc_free(dynamic);
3383 tcc_free(shdr);
3384 tcc_free(v.local_ver);
3385 tcc_free(v.verdef);
3386 tcc_free(v.verneed);
3387 tcc_free(v.versym);
3388 return ret;
3391 #define LD_TOK_NAME 256
3392 #define LD_TOK_EOF (-1)
3394 static int ld_inp(TCCState *s1)
3396 char b;
3397 if (s1->cc != -1) {
3398 int c = s1->cc;
3399 s1->cc = -1;
3400 return c;
3402 if (1 == read(s1->fd, &b, 1))
3403 return b;
3404 return CH_EOF;
3407 /* return next ld script token */
3408 static int ld_next(TCCState *s1, char *name, int name_size)
3410 int c, d, ch;
3411 char *q;
3413 redo:
3414 ch = ld_inp(s1);
3415 switch(ch) {
3416 case ' ':
3417 case '\t':
3418 case '\f':
3419 case '\v':
3420 case '\r':
3421 case '\n':
3422 goto redo;
3423 case '/':
3424 ch = ld_inp(s1);
3425 if (ch == '*') { /* comment */
3426 for (d = 0;; d = ch) {
3427 ch = ld_inp(s1);
3428 if (ch == CH_EOF || (ch == '/' && d == '*'))
3429 break;
3431 goto redo;
3432 } else {
3433 q = name;
3434 *q++ = '/';
3435 goto parse_name;
3437 break;
3438 case '\\':
3439 /* case 'a' ... 'z': */
3440 case 'a':
3441 case 'b':
3442 case 'c':
3443 case 'd':
3444 case 'e':
3445 case 'f':
3446 case 'g':
3447 case 'h':
3448 case 'i':
3449 case 'j':
3450 case 'k':
3451 case 'l':
3452 case 'm':
3453 case 'n':
3454 case 'o':
3455 case 'p':
3456 case 'q':
3457 case 'r':
3458 case 's':
3459 case 't':
3460 case 'u':
3461 case 'v':
3462 case 'w':
3463 case 'x':
3464 case 'y':
3465 case 'z':
3466 /* case 'A' ... 'z': */
3467 case 'A':
3468 case 'B':
3469 case 'C':
3470 case 'D':
3471 case 'E':
3472 case 'F':
3473 case 'G':
3474 case 'H':
3475 case 'I':
3476 case 'J':
3477 case 'K':
3478 case 'L':
3479 case 'M':
3480 case 'N':
3481 case 'O':
3482 case 'P':
3483 case 'Q':
3484 case 'R':
3485 case 'S':
3486 case 'T':
3487 case 'U':
3488 case 'V':
3489 case 'W':
3490 case 'X':
3491 case 'Y':
3492 case 'Z':
3493 case '_':
3494 case '.':
3495 case '$':
3496 case '~':
3497 q = name;
3498 parse_name:
3499 for(;;) {
3500 if (!((ch >= 'a' && ch <= 'z') ||
3501 (ch >= 'A' && ch <= 'Z') ||
3502 (ch >= '0' && ch <= '9') ||
3503 strchr("/.-_+=$:\\,~", ch)))
3504 break;
3505 if ((q - name) < name_size - 1) {
3506 *q++ = ch;
3508 ch = ld_inp(s1);
3510 s1->cc = ch;
3511 *q = '\0';
3512 c = LD_TOK_NAME;
3513 break;
3514 case CH_EOF:
3515 c = LD_TOK_EOF;
3516 break;
3517 default:
3518 c = ch;
3519 break;
3521 return c;
3524 static int ld_add_file(TCCState *s1, const char filename[])
3526 if (filename[0] == '/') {
3527 if (CONFIG_SYSROOT[0] == '\0'
3528 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3529 return 0;
3530 filename = tcc_basename(filename);
3532 return tcc_add_dll(s1, filename, 0);
3535 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3537 char filename[1024], libname[1024];
3538 int t, group, nblibs = 0, ret = 0;
3539 char **libs = NULL;
3541 group = !strcmp(cmd, "GROUP");
3542 if (!as_needed)
3543 s1->new_undef_sym = 0;
3544 t = ld_next(s1, filename, sizeof(filename));
3545 if (t != '(') {
3546 tcc_error_noabort("( expected");
3547 ret = -1;
3548 goto lib_parse_error;
3550 t = ld_next(s1, filename, sizeof(filename));
3551 for(;;) {
3552 libname[0] = '\0';
3553 if (t == LD_TOK_EOF) {
3554 tcc_error_noabort("unexpected end of file");
3555 ret = -1;
3556 goto lib_parse_error;
3557 } else if (t == ')') {
3558 break;
3559 } else if (t == '-') {
3560 t = ld_next(s1, filename, sizeof(filename));
3561 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3562 tcc_error_noabort("library name expected");
3563 ret = -1;
3564 goto lib_parse_error;
3566 pstrcpy(libname, sizeof libname, &filename[1]);
3567 if (s1->static_link) {
3568 snprintf(filename, sizeof filename, "lib%s.a", libname);
3569 } else {
3570 snprintf(filename, sizeof filename, "lib%s.so", libname);
3572 } else if (t != LD_TOK_NAME) {
3573 tcc_error_noabort("filename expected");
3574 ret = -1;
3575 goto lib_parse_error;
3577 if (!strcmp(filename, "AS_NEEDED")) {
3578 ret = ld_add_file_list(s1, cmd, 1);
3579 if (ret)
3580 goto lib_parse_error;
3581 } else {
3582 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3583 if (!as_needed) {
3584 ret = ld_add_file(s1, filename);
3585 if (ret)
3586 goto lib_parse_error;
3587 if (group) {
3588 /* Add the filename *and* the libname to avoid future conversions */
3589 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3590 if (libname[0] != '\0')
3591 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3595 t = ld_next(s1, filename, sizeof(filename));
3596 if (t == ',') {
3597 t = ld_next(s1, filename, sizeof(filename));
3600 if (group && !as_needed) {
3601 while (s1->new_undef_sym) {
3602 int i;
3603 s1->new_undef_sym = 0;
3604 for (i = 0; i < nblibs; i ++)
3605 ld_add_file(s1, libs[i]);
3608 lib_parse_error:
3609 dynarray_reset(&libs, &nblibs);
3610 return ret;
3613 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3614 files */
3615 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3617 char cmd[64];
3618 char filename[1024];
3619 int t, ret;
3621 s1->fd = fd;
3622 s1->cc = -1;
3623 for(;;) {
3624 t = ld_next(s1, cmd, sizeof(cmd));
3625 if (t == LD_TOK_EOF)
3626 return 0;
3627 else if (t != LD_TOK_NAME)
3628 return -1;
3629 if (!strcmp(cmd, "INPUT") ||
3630 !strcmp(cmd, "GROUP")) {
3631 ret = ld_add_file_list(s1, cmd, 0);
3632 if (ret)
3633 return ret;
3634 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3635 !strcmp(cmd, "TARGET")) {
3636 /* ignore some commands */
3637 t = ld_next(s1, cmd, sizeof(cmd));
3638 if (t != '(') {
3639 tcc_error_noabort("( expected");
3640 return -1;
3642 for(;;) {
3643 t = ld_next(s1, filename, sizeof(filename));
3644 if (t == LD_TOK_EOF) {
3645 tcc_error_noabort("unexpected end of file");
3646 return -1;
3647 } else if (t == ')') {
3648 break;
3651 } else {
3652 return -1;
3655 return 0;
3657 #endif /* !ELF_OBJ_ONLY */