FreeBSD (aarch64): fix relocation error.
[tinycc.git] / tccelf.c
blob03c670d78e4c085a0fcdf09051069b1c4fb21145
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;
1829 #if PTR_SIZE == 4 && (TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel)
1830 addr_t bss_addr;
1831 addr_t bss_size;
1832 #endif
1835 /* Assign sections to segments and decide how are sections laid out when loaded
1836 in memory. This function also fills corresponding program headers. */
1837 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1838 Section *interp, Section* strsec,
1839 struct dyn_inf *dyninf, int *sec_order)
1841 int i, sh_order_index, file_offset;
1842 Section *s;
1844 sh_order_index = 1;
1845 file_offset = 0;
1846 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1847 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1849 #ifndef ELF_OBJ_ONLY
1850 if (phnum > 0) { /* phnum is 0 for TCC_OUTPUT_OBJ */
1851 unsigned long s_align;
1852 long long tmp;
1853 addr_t addr;
1854 ElfW(Phdr) *ph;
1855 int j, k, file_type = s1->output_type;
1857 s_align = ELF_PAGE_SIZE;
1858 if (s1->section_align)
1859 s_align = s1->section_align;
1861 if (s1->has_text_addr) {
1862 int a_offset, p_offset;
1863 addr = s1->text_addr;
1864 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1865 ELF_PAGE_SIZE */
1866 a_offset = (int) (addr & (s_align - 1));
1867 p_offset = file_offset & (s_align - 1);
1868 if (a_offset < p_offset)
1869 a_offset += s_align;
1870 file_offset += (a_offset - p_offset);
1871 } else {
1872 if (file_type == TCC_OUTPUT_DLL)
1873 addr = 0;
1874 else
1875 addr = ELF_START_ADDR;
1876 /* compute address after headers */
1877 addr += (file_offset & (s_align - 1));
1880 ph = &phdr[0];
1881 /* Leave one program headers for the program interpreter and one for
1882 the program header table itself if needed. These are done later as
1883 they require section layout to be done first. */
1884 if (interp)
1885 ph += 2;
1887 /* dynamic relocation table information, for .dynamic section */
1888 dyninf->rel_addr = dyninf->rel_size = 0;
1889 #if PTR_SIZE == 4 && (TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel)
1890 dyninf->bss_addr = dyninf->bss_size = 0;
1891 #endif
1893 for(j = 0; j < (phnum == 6 ? 3 : 2); j++) {
1894 Section *relocplt = s1->got ? s1->got->relocplt : NULL;
1896 ph->p_type = j == 2 ? PT_TLS : PT_LOAD;
1897 if (j == 0)
1898 ph->p_flags = PF_R | PF_X;
1899 else
1900 ph->p_flags = PF_R | PF_W;
1901 ph->p_align = j == 2 ? 4 : s_align;
1903 /* Decide the layout of sections loaded in memory. This must
1904 be done before program headers are filled since they contain
1905 info about the layout. We do the following ordering: interp,
1906 symbol tables, relocations, progbits, nobits */
1907 /* XXX: do faster and simpler sorting */
1908 for(k = 0; k < 6; k++) {
1909 for(i = 1; i < s1->nb_sections; i++) {
1910 s = s1->sections[i];
1911 /* compute if section should be included */
1912 if (j == 0) {
1913 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1914 SHF_ALLOC)
1915 continue;
1916 } else if (j == 1) {
1917 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1918 (SHF_ALLOC | SHF_WRITE))
1919 continue;
1920 } else {
1921 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1922 (SHF_ALLOC | SHF_WRITE | SHF_TLS))
1923 continue;
1925 if (s == interp) {
1926 if (k != 0)
1927 continue;
1928 } else if ((s->sh_type == SHT_DYNSYM ||
1929 s->sh_type == SHT_STRTAB ||
1930 s->sh_type == SHT_HASH)
1931 && !strstr(s->name, ".stab")) {
1932 if (k != 1)
1933 continue;
1934 } else if (s->sh_type == SHT_RELX) {
1935 if (k != 2 && s != relocplt)
1936 continue;
1937 else if (k != 3 && s == relocplt)
1938 continue;
1939 } else if (s->sh_type == SHT_NOBITS) {
1940 if (k != 5)
1941 continue;
1942 } else {
1943 if (k != 4)
1944 continue;
1946 sec_order[sh_order_index++] = i;
1948 /* section matches: we align it and add its size */
1949 tmp = addr;
1950 addr = (addr + s->sh_addralign - 1) &
1951 ~(s->sh_addralign - 1);
1952 file_offset += (int) ( addr - tmp );
1953 s->sh_offset = file_offset;
1954 s->sh_addr = addr;
1956 /* update program header infos */
1957 if (ph->p_offset == 0) {
1958 ph->p_offset = file_offset;
1959 ph->p_vaddr = addr;
1960 ph->p_paddr = ph->p_vaddr;
1962 /* update dynamic relocation infos */
1963 if (s->sh_type == SHT_RELX && s != relocplt) {
1964 #if PTR_SIZE == 4 && (TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel)
1965 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1966 dyninf->rel_addr = addr;
1967 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1969 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1970 dyninf->bss_addr = addr;
1971 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1973 #else
1974 if (dyninf->rel_size == 0)
1975 dyninf->rel_addr = addr;
1976 dyninf->rel_size += s->sh_size;
1977 #endif
1979 addr += s->sh_size;
1980 if (s->sh_type != SHT_NOBITS)
1981 file_offset += s->sh_size;
1984 if (j == 0) {
1985 /* Make the first PT_LOAD segment include the program
1986 headers itself (and the ELF header as well), it'll
1987 come out with same memory use but will make various
1988 tools like binutils strip work better. */
1989 ph->p_offset &= ~(ph->p_align - 1);
1990 ph->p_vaddr &= ~(ph->p_align - 1);
1991 ph->p_paddr &= ~(ph->p_align - 1);
1993 ph->p_filesz = file_offset - ph->p_offset;
1994 ph->p_memsz = addr - ph->p_vaddr;
1995 ph++;
1996 if (j == 0) {
1997 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1998 /* if in the middle of a page, we duplicate the page in
1999 memory so that one copy is RX and the other is RW */
2000 if ((addr & (s_align - 1)) != 0)
2001 addr += s_align;
2002 } else {
2003 addr = (addr + s_align - 1) & ~(s_align - 1);
2004 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
2009 #endif /* ELF_OBJ_ONLY */
2011 /* all other sections come after */
2012 for(i = 1; i < s1->nb_sections; i++) {
2013 s = s1->sections[i];
2014 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
2015 continue;
2016 sec_order[sh_order_index++] = i;
2018 file_offset = (file_offset + s->sh_addralign - 1) &
2019 ~(s->sh_addralign - 1);
2020 s->sh_offset = file_offset;
2021 if (s->sh_type != SHT_NOBITS)
2022 file_offset += s->sh_size;
2025 return file_offset;
2028 #ifndef ELF_OBJ_ONLY
2029 /* put dynamic tag */
2030 static void put_dt(Section *dynamic, int dt, addr_t val)
2032 ElfW(Dyn) *dyn;
2033 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
2034 dyn->d_tag = dt;
2035 dyn->d_un.d_val = val;
2038 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
2039 Section *dynamic, Section *note)
2041 ElfW(Phdr) *ph;
2043 /* if interpreter, then add corresponding program header */
2044 if (interp) {
2045 ph = &phdr[0];
2047 ph->p_type = PT_PHDR;
2048 ph->p_offset = sizeof(ElfW(Ehdr));
2049 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
2050 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
2051 ph->p_paddr = ph->p_vaddr;
2052 ph->p_flags = PF_R | PF_X;
2053 ph->p_align = 4; /* interp->sh_addralign; */
2054 ph++;
2056 ph->p_type = PT_INTERP;
2057 ph->p_offset = interp->sh_offset;
2058 ph->p_vaddr = interp->sh_addr;
2059 ph->p_paddr = ph->p_vaddr;
2060 ph->p_filesz = interp->sh_size;
2061 ph->p_memsz = interp->sh_size;
2062 ph->p_flags = PF_R;
2063 ph->p_align = interp->sh_addralign;
2066 if (note) {
2067 ph = &phdr[phnum - 2];
2069 ph->p_type = PT_NOTE;
2070 ph->p_offset = note->sh_offset;
2071 ph->p_vaddr = note->sh_addr;
2072 ph->p_paddr = ph->p_vaddr;
2073 ph->p_filesz = note->sh_size;
2074 ph->p_memsz = note->sh_size;
2075 ph->p_flags = PF_R;
2076 ph->p_align = note->sh_addralign;
2079 /* if dynamic section, then add corresponding program header */
2080 if (dynamic) {
2081 ph = &phdr[phnum - 1];
2083 ph->p_type = PT_DYNAMIC;
2084 ph->p_offset = dynamic->sh_offset;
2085 ph->p_vaddr = dynamic->sh_addr;
2086 ph->p_paddr = ph->p_vaddr;
2087 ph->p_filesz = dynamic->sh_size;
2088 ph->p_memsz = dynamic->sh_size;
2089 ph->p_flags = PF_R | PF_W;
2090 ph->p_align = dynamic->sh_addralign;
2094 /* Fill the dynamic section with tags describing the address and size of
2095 sections */
2096 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2098 Section *dynamic = dyninf->dynamic;
2099 Section *s;
2101 /* put dynamic section entries */
2102 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2103 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2104 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2105 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2106 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2107 #if PTR_SIZE == 8
2108 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2109 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2110 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2111 if (s1->got && s1->got->relocplt) {
2112 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2113 put_dt(dynamic, DT_PLTRELSZ, s1->got->relocplt->data_offset);
2114 put_dt(dynamic, DT_JMPREL, s1->got->relocplt->sh_addr);
2115 put_dt(dynamic, DT_PLTREL, DT_RELA);
2117 put_dt(dynamic, DT_RELACOUNT, 0);
2118 #else
2119 #if PTR_SIZE == 4 && (TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel)
2120 if (s1->got)
2121 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2122 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
2123 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2124 put_dt(dynamic, DT_PLTREL, DT_REL);
2125 put_dt(dynamic, DT_REL, dyninf->bss_addr);
2126 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
2127 #else
2128 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2129 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2130 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2131 if (s1->got && s1->got->relocplt) {
2132 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2133 put_dt(dynamic, DT_PLTRELSZ, s1->got->relocplt->data_offset);
2134 put_dt(dynamic, DT_JMPREL, s1->got->relocplt->sh_addr);
2135 put_dt(dynamic, DT_PLTREL, DT_REL);
2137 put_dt(dynamic, DT_RELCOUNT, 0);
2138 #endif
2139 #endif
2140 if (versym_section && verneed_section) {
2141 /* The dynamic linker can not handle VERSYM without VERNEED */
2142 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2143 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2144 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2146 s = find_section_create (s1, ".preinit_array", 0);
2147 if (s && s->data_offset) {
2148 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2149 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2151 s = find_section_create (s1, ".init_array", 0);
2152 if (s && s->data_offset) {
2153 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2154 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2156 s = find_section_create (s1, ".fini_array", 0);
2157 if (s && s->data_offset) {
2158 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2159 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2161 s = find_section_create (s1, ".init", 0);
2162 if (s && s->data_offset) {
2163 put_dt(dynamic, DT_INIT, s->sh_addr);
2165 s = find_section_create (s1, ".fini", 0);
2166 if (s && s->data_offset) {
2167 put_dt(dynamic, DT_FINI, s->sh_addr);
2169 if (s1->do_debug)
2170 put_dt(dynamic, DT_DEBUG, 0);
2171 put_dt(dynamic, DT_NULL, 0);
2174 /* Relocate remaining sections and symbols (that is those not related to
2175 dynamic linking) */
2176 static int final_sections_reloc(TCCState *s1)
2178 int i;
2179 Section *s;
2181 relocate_syms(s1, s1->symtab, 0);
2183 if (s1->nb_errors != 0)
2184 return -1;
2186 /* relocate sections */
2187 /* XXX: ignore sections with allocated relocations ? */
2188 for(i = 1; i < s1->nb_sections; i++) {
2189 s = s1->sections[i];
2190 if (s->reloc && (s != s1->got || s1->static_link))
2191 relocate_section(s1, s);
2194 /* relocate relocation entries if the relocation tables are
2195 allocated in the executable */
2196 for(i = 1; i < s1->nb_sections; i++) {
2197 s = s1->sections[i];
2198 if ((s->sh_flags & SHF_ALLOC) &&
2199 s->sh_type == SHT_RELX) {
2200 relocate_rel(s1, s);
2203 return 0;
2205 #endif
2207 /* Create an ELF file on disk.
2208 This function handle ELF specific layout requirements */
2209 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2210 int file_offset, int *sec_order)
2212 int i, shnum, offset, size, file_type;
2213 Section *s;
2214 ElfW(Ehdr) ehdr;
2215 ElfW(Shdr) shdr, *sh;
2217 file_type = s1->output_type;
2218 shnum = s1->nb_sections;
2220 memset(&ehdr, 0, sizeof(ehdr));
2222 if (phnum > 0) {
2223 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2224 ehdr.e_phnum = phnum;
2225 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2228 /* align to 4 */
2229 file_offset = (file_offset + 3) & -4;
2231 /* fill header */
2232 ehdr.e_ident[0] = ELFMAG0;
2233 ehdr.e_ident[1] = ELFMAG1;
2234 ehdr.e_ident[2] = ELFMAG2;
2235 ehdr.e_ident[3] = ELFMAG3;
2236 ehdr.e_ident[4] = ELFCLASSW;
2237 ehdr.e_ident[5] = ELFDATA2LSB;
2238 ehdr.e_ident[6] = EV_CURRENT;
2239 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2240 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2241 #endif
2242 #ifdef TCC_TARGET_ARM
2243 #ifdef TCC_ARM_EABI
2244 ehdr.e_ident[EI_OSABI] = 0;
2245 ehdr.e_flags = EF_ARM_EABI_VER4;
2246 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2247 ehdr.e_flags |= EF_ARM_HASENTRY;
2248 if (s1->float_abi == ARM_HARD_FLOAT)
2249 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2250 else
2251 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2252 #else
2253 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2254 #endif
2255 #elif defined TCC_TARGET_RISCV64
2256 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2257 #endif
2258 switch(file_type) {
2259 default:
2260 case TCC_OUTPUT_EXE:
2261 ehdr.e_type = ET_EXEC;
2262 ehdr.e_entry = get_sym_addr(s1, "_start", 1, 0);
2263 break;
2264 case TCC_OUTPUT_DLL:
2265 ehdr.e_type = ET_DYN;
2266 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2267 break;
2268 case TCC_OUTPUT_OBJ:
2269 ehdr.e_type = ET_REL;
2270 break;
2272 ehdr.e_machine = EM_TCC_TARGET;
2273 ehdr.e_version = EV_CURRENT;
2274 ehdr.e_shoff = file_offset;
2275 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2276 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2277 ehdr.e_shnum = shnum;
2278 ehdr.e_shstrndx = shnum - 1;
2280 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2281 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2282 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2284 sort_syms(s1, symtab_section);
2285 for(i = 1; i < s1->nb_sections; i++) {
2286 s = s1->sections[sec_order[i]];
2287 if (s->sh_type != SHT_NOBITS) {
2288 while (offset < s->sh_offset) {
2289 fputc(0, f);
2290 offset++;
2292 size = s->sh_size;
2293 if (size)
2294 fwrite(s->data, 1, size, f);
2295 offset += size;
2299 /* output section headers */
2300 while (offset < ehdr.e_shoff) {
2301 fputc(0, f);
2302 offset++;
2305 for(i = 0; i < s1->nb_sections; i++) {
2306 sh = &shdr;
2307 memset(sh, 0, sizeof(ElfW(Shdr)));
2308 s = s1->sections[i];
2309 if (s) {
2310 sh->sh_name = s->sh_name;
2311 sh->sh_type = s->sh_type;
2312 sh->sh_flags = s->sh_flags;
2313 sh->sh_entsize = s->sh_entsize;
2314 sh->sh_info = s->sh_info;
2315 if (s->link)
2316 sh->sh_link = s->link->sh_num;
2317 sh->sh_addralign = s->sh_addralign;
2318 sh->sh_addr = s->sh_addr;
2319 sh->sh_offset = s->sh_offset;
2320 sh->sh_size = s->sh_size;
2322 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2326 /* Write an elf, coff or "binary" file */
2327 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2328 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2330 int fd, mode, file_type;
2331 FILE *f;
2333 file_type = s1->output_type;
2334 if (file_type == TCC_OUTPUT_OBJ)
2335 mode = 0666;
2336 else
2337 mode = 0777;
2338 unlink(filename);
2339 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2340 if (fd < 0) {
2341 tcc_error_noabort("could not write '%s'", filename);
2342 return -1;
2344 f = fdopen(fd, "wb");
2345 if (s1->verbose)
2346 printf("<- %s\n", filename);
2348 #ifdef TCC_TARGET_COFF
2349 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2350 tcc_output_coff(s1, f);
2351 else
2352 #endif
2353 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2354 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2355 else
2356 tcc_output_binary(s1, f, sec_order);
2357 fclose(f);
2359 return 0;
2362 #ifndef ELF_OBJ_ONLY
2363 /* Sort section headers by assigned sh_addr, remove sections
2364 that we aren't going to output. */
2365 static void tidy_section_headers(TCCState *s1, int *sec_order)
2367 int i, nnew, l, *backmap;
2368 Section **snew, *s;
2369 ElfW(Sym) *sym;
2371 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2372 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2373 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2374 s = s1->sections[sec_order[i]];
2375 if (!i || s->sh_name) {
2376 backmap[sec_order[i]] = nnew;
2377 snew[nnew] = s;
2378 ++nnew;
2379 } else {
2380 backmap[sec_order[i]] = 0;
2381 snew[--l] = s;
2384 for (i = 0; i < nnew; i++) {
2385 s = snew[i];
2386 if (s) {
2387 s->sh_num = i;
2388 if (s->sh_type == SHT_RELX)
2389 s->sh_info = backmap[s->sh_info];
2393 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2394 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2395 sym->st_shndx = backmap[sym->st_shndx];
2396 if ( !s1->static_link ) {
2397 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2398 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2399 sym->st_shndx = backmap[sym->st_shndx];
2401 for (i = 0; i < s1->nb_sections; i++)
2402 sec_order[i] = i;
2403 tcc_free(s1->sections);
2404 s1->sections = snew;
2405 s1->nb_sections = nnew;
2406 tcc_free(backmap);
2408 #endif
2410 #ifdef TCC_TARGET_ARM
2411 static void create_arm_attribute_section(TCCState *s1)
2413 // Needed for DLL support.
2414 static const unsigned char arm_attr[] = {
2415 0x41, // 'A'
2416 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2417 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2418 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2419 0x05, 0x36, 0x00, // 'CPU_name', "6"
2420 0x06, 0x06, // 'CPU_arch', 'v6'
2421 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2422 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2423 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2424 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2425 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2426 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2427 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2428 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2429 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2430 0x1a, 0x02, // 'ABI_enum_size', 'int'
2431 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2432 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2434 Section *attr = new_section(s1, ".ARM.attributes", SHT_ARM_ATTRIBUTES, 0);
2435 unsigned char *ptr = section_ptr_add(attr, sizeof(arm_attr));
2436 attr->sh_addralign = 1;
2437 memcpy(ptr, arm_attr, sizeof(arm_attr));
2438 if (s1->float_abi != ARM_HARD_FLOAT) {
2439 ptr[26] = 0x00; // 'FP_arch', 'No'
2440 ptr[41] = 0x1e; // 'ABI_optimization_goals'
2441 ptr[42] = 0x06; // 'Aggressive Debug'
2444 #endif
2446 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2447 static Section *create_bsd_note_section(TCCState *s1,
2448 const char *name,
2449 const char *value)
2451 Section *s = find_section (s1, name);
2453 if (s->data_offset == 0) {
2454 unsigned char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
2455 ElfW(Nhdr) *note = (ElfW(Nhdr) *) ptr;
2457 s->sh_type = SHT_NOTE;
2458 note->n_namesz = 8;
2459 note->n_descsz = 4;
2460 note->n_type = ELF_NOTE_OS_GNU;
2461 strcpy (ptr + sizeof(ElfW(Nhdr)), value);
2463 return s;
2465 #endif
2467 /* Output an elf, coff or binary file */
2468 /* XXX: suppress unneeded sections */
2469 static int elf_output_file(TCCState *s1, const char *filename)
2471 int ret, phnum, shnum, file_type, file_offset, *sec_order;
2472 struct dyn_inf dyninf = {0};
2473 ElfW(Phdr) *phdr;
2474 Section *strsec, *interp, *dynamic, *dynstr, *note = NULL;
2476 file_type = s1->output_type;
2478 #ifdef TCC_TARGET_ARM
2479 create_arm_attribute_section (s1);
2480 #endif
2481 #if TARGETOS_OpenBSD
2482 if (file_type != TCC_OUTPUT_OBJ)
2483 note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
2484 #endif
2485 #if TARGETOS_NetBSD
2486 if (file_type != TCC_OUTPUT_OBJ)
2487 note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD");
2488 #endif
2490 s1->nb_errors = 0;
2491 ret = -1;
2492 phdr = NULL;
2493 sec_order = NULL;
2494 interp = dynamic = dynstr = NULL; /* avoid warning */
2496 #ifndef ELF_OBJ_ONLY
2497 if (file_type != TCC_OUTPUT_OBJ) {
2498 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2499 tcc_add_runtime(s1);
2500 resolve_common_syms(s1);
2502 if (!s1->static_link) {
2503 if (file_type == TCC_OUTPUT_EXE) {
2504 char *ptr;
2505 /* allow override the dynamic loader */
2506 const char *elfint = getenv("LD_SO");
2507 if (elfint == NULL)
2508 elfint = DEFAULT_ELFINTERP(s1);
2509 /* add interpreter section only if executable */
2510 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2511 interp->sh_addralign = 1;
2512 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2513 strcpy(ptr, elfint);
2516 /* add dynamic symbol table */
2517 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2518 ".dynstr",
2519 ".hash", SHF_ALLOC);
2520 dynstr = s1->dynsym->link;
2521 /* add dynamic section */
2522 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2523 SHF_ALLOC | SHF_WRITE);
2524 dynamic->link = dynstr;
2525 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2527 build_got(s1);
2529 if (file_type == TCC_OUTPUT_EXE) {
2530 bind_exe_dynsyms(s1);
2531 if (s1->nb_errors)
2532 goto the_end;
2533 bind_libs_dynsyms(s1);
2534 } else {
2535 /* shared library case: simply export all global symbols */
2536 export_global_syms(s1);
2539 build_got_entries(s1);
2540 version_add (s1);
2542 #endif
2544 /* we add a section for symbols */
2545 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2546 put_elf_str(strsec, "");
2548 /* Allocate strings for section names */
2549 ret = alloc_sec_names(s1, file_type, strsec);
2551 #ifndef ELF_OBJ_ONLY
2552 if (dynamic) {
2553 int i;
2554 /* add a list of needed dlls */
2555 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2556 DLLReference *dllref = s1->loaded_dlls[i];
2557 if (dllref->level == 0)
2558 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2561 if (s1->rpath)
2562 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2563 put_elf_str(dynstr, s1->rpath));
2565 if (file_type == TCC_OUTPUT_DLL) {
2566 if (s1->soname)
2567 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2568 /* XXX: currently, since we do not handle PIC code, we
2569 must relocate the readonly segments */
2570 if (ret)
2571 put_dt(dynamic, DT_TEXTREL, 0);
2574 if (s1->symbolic)
2575 put_dt(dynamic, DT_SYMBOLIC, 0);
2577 dyninf.dynamic = dynamic;
2578 dyninf.dynstr = dynstr;
2579 /* remember offset and reserve space for 2nd call below */
2580 dyninf.data_offset = dynamic->data_offset;
2581 fill_dynamic(s1, &dyninf);
2582 dynamic->sh_size = dynamic->data_offset;
2583 dynstr->sh_size = dynstr->data_offset;
2585 #endif
2587 /* compute number of program headers */
2588 if (file_type == TCC_OUTPUT_OBJ)
2589 phnum = 0;
2590 else if (file_type == TCC_OUTPUT_DLL)
2591 phnum = 3;
2592 else if (s1->static_link)
2593 phnum = 2;
2594 else {
2595 int i;
2596 for (i = 1; i < s1->nb_sections &&
2597 !(s1->sections[i]->sh_flags & SHF_TLS); i++);
2598 phnum = i < s1->nb_sections ? 6 : 5;
2601 phnum += note != NULL;
2603 /* allocate program segment headers */
2604 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2606 /* compute number of sections */
2607 shnum = s1->nb_sections;
2609 /* this array is used to reorder sections in the output file */
2610 sec_order = tcc_malloc(sizeof(int) * shnum);
2611 sec_order[0] = 0;
2613 /* compute section to program header mapping */
2614 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2615 sec_order);
2617 #ifndef ELF_OBJ_ONLY
2618 /* Fill remaining program header and finalize relocation related to dynamic
2619 linking. */
2620 if (file_type != TCC_OUTPUT_OBJ) {
2621 fill_unloadable_phdr(phdr, phnum, interp, dynamic, note);
2622 if (dynamic) {
2623 ElfW(Sym) *sym;
2624 dynamic->data_offset = dyninf.data_offset;
2625 fill_dynamic(s1, &dyninf);
2627 /* put in GOT the dynamic section address and relocate PLT */
2628 write32le(s1->got->data, dynamic->sh_addr);
2629 if (file_type == TCC_OUTPUT_EXE
2630 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2631 relocate_plt(s1);
2633 /* relocate symbols in .dynsym now that final addresses are known */
2634 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2635 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2636 /* do symbol relocation */
2637 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2642 /* if building executable or DLL, then relocate each section
2643 except the GOT which is already relocated */
2644 ret = final_sections_reloc(s1);
2645 if (ret)
2646 goto the_end;
2647 tidy_section_headers(s1, sec_order);
2649 /* Perform relocation to GOT or PLT entries */
2650 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2651 fill_got(s1);
2652 else if (s1->got)
2653 fill_local_got_entries(s1);
2655 #endif
2657 /* Create the ELF file with name 'filename' */
2658 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2659 s1->nb_sections = shnum;
2660 goto the_end;
2661 the_end:
2662 tcc_free(sec_order);
2663 tcc_free(phdr);
2664 return ret;
2667 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2669 int ret;
2670 #ifdef TCC_TARGET_PE
2671 if (s->output_type != TCC_OUTPUT_OBJ) {
2672 ret = pe_output_file(s, filename);
2673 } else
2674 #elif TCC_TARGET_MACHO
2675 if (s->output_type != TCC_OUTPUT_OBJ) {
2676 ret = macho_output_file(s, filename);
2677 } else
2678 #endif
2679 ret = elf_output_file(s, filename);
2680 return ret;
2683 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
2684 char *cbuf = buf;
2685 size_t rnum = 0;
2686 while (1) {
2687 ssize_t num = read(fd, cbuf, count-rnum);
2688 if (num < 0) return num;
2689 if (num == 0) return rnum;
2690 rnum += num;
2691 cbuf += num;
2695 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
2697 void *data;
2699 data = tcc_malloc(size);
2700 lseek(fd, file_offset, SEEK_SET);
2701 full_read(fd, data, size);
2702 return data;
2705 typedef struct SectionMergeInfo {
2706 Section *s; /* corresponding existing section */
2707 unsigned long offset; /* offset of the new section in the existing section */
2708 uint8_t new_section; /* true if section 's' was added */
2709 uint8_t link_once; /* true if link once section */
2710 } SectionMergeInfo;
2712 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2714 int size = full_read(fd, h, sizeof *h);
2715 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2716 if (h->e_type == ET_REL)
2717 return AFF_BINTYPE_REL;
2718 if (h->e_type == ET_DYN)
2719 return AFF_BINTYPE_DYN;
2720 } else if (size >= 8) {
2721 if (0 == memcmp(h, ARMAG, 8))
2722 return AFF_BINTYPE_AR;
2723 #ifdef TCC_TARGET_COFF
2724 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2725 return AFF_BINTYPE_C67;
2726 #endif
2728 return 0;
2731 /* load an object file and merge it with current files */
2732 /* XXX: handle correctly stab (debug) info */
2733 ST_FUNC int tcc_load_object_file(TCCState *s1,
2734 int fd, unsigned long file_offset)
2736 ElfW(Ehdr) ehdr;
2737 ElfW(Shdr) *shdr, *sh;
2738 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2739 char *strsec, *strtab;
2740 int stab_index, stabstr_index;
2741 int *old_to_new_syms;
2742 char *sh_name, *name;
2743 SectionMergeInfo *sm_table, *sm;
2744 ElfW(Sym) *sym, *symtab;
2745 ElfW_Rel *rel;
2746 Section *s;
2748 lseek(fd, file_offset, SEEK_SET);
2749 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2750 goto fail1;
2751 /* test CPU specific stuff */
2752 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2753 ehdr.e_machine != EM_TCC_TARGET) {
2754 fail1:
2755 tcc_error_noabort("invalid object file");
2756 return -1;
2758 /* read sections */
2759 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2760 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2761 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2763 /* load section names */
2764 sh = &shdr[ehdr.e_shstrndx];
2765 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2767 /* load symtab and strtab */
2768 old_to_new_syms = NULL;
2769 symtab = NULL;
2770 strtab = NULL;
2771 nb_syms = 0;
2772 seencompressed = 0;
2773 stab_index = stabstr_index = 0;
2775 for(i = 1; i < ehdr.e_shnum; i++) {
2776 sh = &shdr[i];
2777 if (sh->sh_type == SHT_SYMTAB) {
2778 if (symtab) {
2779 tcc_error_noabort("object must contain only one symtab");
2780 fail:
2781 ret = -1;
2782 goto the_end;
2784 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2785 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2786 sm_table[i].s = symtab_section;
2788 /* now load strtab */
2789 sh = &shdr[sh->sh_link];
2790 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2792 if (sh->sh_flags & SHF_COMPRESSED)
2793 seencompressed = 1;
2796 /* now examine each section and try to merge its content with the
2797 ones in memory */
2798 for(i = 1; i < ehdr.e_shnum; i++) {
2799 /* no need to examine section name strtab */
2800 if (i == ehdr.e_shstrndx)
2801 continue;
2802 sh = &shdr[i];
2803 if (sh->sh_type == SHT_RELX)
2804 sh = &shdr[sh->sh_info];
2805 /* ignore sections types we do not handle (plus relocs to those) */
2806 if (sh->sh_type != SHT_PROGBITS &&
2807 #ifdef TCC_ARM_EABI
2808 sh->sh_type != SHT_ARM_EXIDX &&
2809 #endif
2810 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2811 sh->sh_type != SHT_X86_64_UNWIND &&
2812 sh->sh_type != SHT_NOTE &&
2813 #endif
2814 sh->sh_type != SHT_NOBITS &&
2815 sh->sh_type != SHT_PREINIT_ARRAY &&
2816 sh->sh_type != SHT_INIT_ARRAY &&
2817 sh->sh_type != SHT_FINI_ARRAY &&
2818 strcmp(strsec + sh->sh_name, ".stabstr")
2820 continue;
2821 if (seencompressed
2822 && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
2823 continue;
2825 sh = &shdr[i];
2826 sh_name = strsec + sh->sh_name;
2827 if (sh->sh_addralign < 1)
2828 sh->sh_addralign = 1;
2829 /* find corresponding section, if any */
2830 for(j = 1; j < s1->nb_sections;j++) {
2831 s = s1->sections[j];
2832 if (!strcmp(s->name, sh_name)) {
2833 if (!strncmp(sh_name, ".gnu.linkonce",
2834 sizeof(".gnu.linkonce") - 1)) {
2835 /* if a 'linkonce' section is already present, we
2836 do not add it again. It is a little tricky as
2837 symbols can still be defined in
2838 it. */
2839 sm_table[i].link_once = 1;
2840 goto next;
2842 if (stab_section) {
2843 if (s == stab_section)
2844 stab_index = i;
2845 if (s == stab_section->link)
2846 stabstr_index = i;
2848 goto found;
2851 /* not found: create new section */
2852 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2853 /* take as much info as possible from the section. sh_link and
2854 sh_info will be updated later */
2855 s->sh_addralign = sh->sh_addralign;
2856 s->sh_entsize = sh->sh_entsize;
2857 sm_table[i].new_section = 1;
2858 found:
2859 if (sh->sh_type != s->sh_type) {
2860 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2861 if (strcmp (s->name, ".eh_frame"))
2862 #endif
2864 tcc_error_noabort("invalid section type");
2865 goto fail;
2868 /* align start of section */
2869 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
2870 if (sh->sh_addralign > s->sh_addralign)
2871 s->sh_addralign = sh->sh_addralign;
2872 sm_table[i].offset = s->data_offset;
2873 sm_table[i].s = s;
2874 /* concatenate sections */
2875 size = sh->sh_size;
2876 if (sh->sh_type != SHT_NOBITS) {
2877 unsigned char *ptr;
2878 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2879 ptr = section_ptr_add(s, size);
2880 full_read(fd, ptr, size);
2881 } else {
2882 s->data_offset += size;
2884 next: ;
2887 /* gr relocate stab strings */
2888 if (stab_index && stabstr_index) {
2889 Stab_Sym *a, *b;
2890 unsigned o;
2891 s = sm_table[stab_index].s;
2892 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2893 b = (Stab_Sym *)(s->data + s->data_offset);
2894 o = sm_table[stabstr_index].offset;
2895 while (a < b) {
2896 if (a->n_strx)
2897 a->n_strx += o;
2898 a++;
2902 /* second short pass to update sh_link and sh_info fields of new
2903 sections */
2904 for(i = 1; i < ehdr.e_shnum; i++) {
2905 s = sm_table[i].s;
2906 if (!s || !sm_table[i].new_section)
2907 continue;
2908 sh = &shdr[i];
2909 if (sh->sh_link > 0)
2910 s->link = sm_table[sh->sh_link].s;
2911 if (sh->sh_type == SHT_RELX) {
2912 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2913 /* update backward link */
2914 s1->sections[s->sh_info]->reloc = s;
2918 /* resolve symbols */
2919 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2921 sym = symtab + 1;
2922 for(i = 1; i < nb_syms; i++, sym++) {
2923 if (sym->st_shndx != SHN_UNDEF &&
2924 sym->st_shndx < SHN_LORESERVE) {
2925 sm = &sm_table[sym->st_shndx];
2926 if (sm->link_once) {
2927 /* if a symbol is in a link once section, we use the
2928 already defined symbol. It is very important to get
2929 correct relocations */
2930 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2931 name = strtab + sym->st_name;
2932 sym_index = find_elf_sym(symtab_section, name);
2933 if (sym_index)
2934 old_to_new_syms[i] = sym_index;
2936 continue;
2938 /* if no corresponding section added, no need to add symbol */
2939 if (!sm->s)
2940 continue;
2941 /* convert section number */
2942 sym->st_shndx = sm->s->sh_num;
2943 /* offset value */
2944 sym->st_value += sm->offset;
2946 /* add symbol */
2947 name = strtab + sym->st_name;
2948 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2949 sym->st_info, sym->st_other,
2950 sym->st_shndx, name);
2951 old_to_new_syms[i] = sym_index;
2954 /* third pass to patch relocation entries */
2955 for(i = 1; i < ehdr.e_shnum; i++) {
2956 s = sm_table[i].s;
2957 if (!s)
2958 continue;
2959 sh = &shdr[i];
2960 offset = sm_table[i].offset;
2961 switch(s->sh_type) {
2962 case SHT_RELX:
2963 /* take relocation offset information */
2964 offseti = sm_table[sh->sh_info].offset;
2965 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2966 int type;
2967 unsigned sym_index;
2968 /* convert symbol index */
2969 type = ELFW(R_TYPE)(rel->r_info);
2970 sym_index = ELFW(R_SYM)(rel->r_info);
2971 /* NOTE: only one symtab assumed */
2972 if (sym_index >= nb_syms)
2973 goto invalid_reloc;
2974 sym_index = old_to_new_syms[sym_index];
2975 /* ignore link_once in rel section. */
2976 if (!sym_index && !sm_table[sh->sh_info].link_once
2977 #ifdef TCC_TARGET_ARM
2978 && type != R_ARM_V4BX
2979 #elif defined TCC_TARGET_RISCV64
2980 && type != R_RISCV_ALIGN
2981 && type != R_RISCV_RELAX
2982 #endif
2984 invalid_reloc:
2985 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2986 i, strsec + sh->sh_name, (int)rel->r_offset);
2987 goto fail;
2989 rel->r_info = ELFW(R_INFO)(sym_index, type);
2990 /* offset the relocation offset */
2991 rel->r_offset += offseti;
2992 #ifdef TCC_TARGET_ARM
2993 /* Jumps and branches from a Thumb code to a PLT entry need
2994 special handling since PLT entries are ARM code.
2995 Unconditional bl instructions referencing PLT entries are
2996 handled by converting these instructions into blx
2997 instructions. Other case of instructions referencing a PLT
2998 entry require to add a Thumb stub before the PLT entry to
2999 switch to ARM mode. We set bit plt_thumb_stub of the
3000 attribute of a symbol to indicate such a case. */
3001 if (type == R_ARM_THM_JUMP24)
3002 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
3003 #endif
3005 break;
3006 default:
3007 break;
3011 ret = 0;
3012 the_end:
3013 tcc_free(symtab);
3014 tcc_free(strtab);
3015 tcc_free(old_to_new_syms);
3016 tcc_free(sm_table);
3017 tcc_free(strsec);
3018 tcc_free(shdr);
3019 return ret;
3022 typedef struct ArchiveHeader {
3023 char ar_name[16]; /* name of this member */
3024 char ar_date[12]; /* file mtime */
3025 char ar_uid[6]; /* owner uid; printed as decimal */
3026 char ar_gid[6]; /* owner gid; printed as decimal */
3027 char ar_mode[8]; /* file mode, printed as octal */
3028 char ar_size[10]; /* file size, printed as decimal */
3029 char ar_fmag[2]; /* should contain ARFMAG */
3030 } ArchiveHeader;
3032 #define ARFMAG "`\n"
3034 static unsigned long long get_be(const uint8_t *b, int n)
3036 unsigned long long ret = 0;
3037 while (n)
3038 ret = (ret << 8) | *b++, --n;
3039 return ret;
3042 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
3044 char *p, *e;
3045 int len;
3046 lseek(fd, offset, SEEK_SET);
3047 len = full_read(fd, hdr, sizeof(ArchiveHeader));
3048 if (len != sizeof(ArchiveHeader))
3049 return len ? -1 : 0;
3050 p = hdr->ar_name;
3051 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
3052 --e;
3053 *e = '\0';
3054 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
3055 return len;
3058 /* load only the objects which resolve undefined symbols */
3059 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
3061 int i, bound, nsyms, sym_index, len, ret = -1;
3062 unsigned long long off;
3063 uint8_t *data;
3064 const char *ar_names, *p;
3065 const uint8_t *ar_index;
3066 ElfW(Sym) *sym;
3067 ArchiveHeader hdr;
3069 data = tcc_malloc(size);
3070 if (full_read(fd, data, size) != size)
3071 goto the_end;
3072 nsyms = get_be(data, entrysize);
3073 ar_index = data + entrysize;
3074 ar_names = (char *) ar_index + nsyms * entrysize;
3076 do {
3077 bound = 0;
3078 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
3079 Section *s = symtab_section;
3080 sym_index = find_elf_sym(s, p);
3081 if (!sym_index)
3082 continue;
3083 sym = &((ElfW(Sym) *)s->data)[sym_index];
3084 if(sym->st_shndx != SHN_UNDEF)
3085 continue;
3086 off = get_be(ar_index + i * entrysize, entrysize);
3087 len = read_ar_header(fd, off, &hdr);
3088 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
3089 tcc_error_noabort("invalid archive");
3090 goto the_end;
3092 off += len;
3093 if (s1->verbose == 2)
3094 printf(" -> %s\n", hdr.ar_name);
3095 if (tcc_load_object_file(s1, fd, off) < 0)
3096 goto the_end;
3097 ++bound;
3099 } while(bound);
3100 ret = 0;
3101 the_end:
3102 tcc_free(data);
3103 return ret;
3106 /* load a '.a' file */
3107 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
3109 ArchiveHeader hdr;
3110 /* char magic[8]; */
3111 int size, len;
3112 unsigned long file_offset;
3113 ElfW(Ehdr) ehdr;
3115 /* skip magic which was already checked */
3116 /* full_read(fd, magic, sizeof(magic)); */
3117 file_offset = sizeof ARMAG - 1;
3119 for(;;) {
3120 len = read_ar_header(fd, file_offset, &hdr);
3121 if (len == 0)
3122 return 0;
3123 if (len < 0) {
3124 tcc_error_noabort("invalid archive");
3125 return -1;
3127 file_offset += len;
3128 size = strtol(hdr.ar_size, NULL, 0);
3129 /* align to even */
3130 size = (size + 1) & ~1;
3131 if (alacarte) {
3132 /* coff symbol table : we handle it */
3133 if (!strcmp(hdr.ar_name, "/"))
3134 return tcc_load_alacarte(s1, fd, size, 4);
3135 if (!strcmp(hdr.ar_name, "/SYM64/"))
3136 return tcc_load_alacarte(s1, fd, size, 8);
3137 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3138 if (s1->verbose == 2)
3139 printf(" -> %s\n", hdr.ar_name);
3140 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3141 return -1;
3143 file_offset += size;
3147 #ifndef ELF_OBJ_ONLY
3148 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3149 LV, maybe create a new entry for (LIB,VERSION). */
3150 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3152 while (i >= *n) {
3153 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3154 (*lv)[(*n)++] = -1;
3156 if ((*lv)[i] == -1) {
3157 int v, prev_same_lib = -1;
3158 for (v = 0; v < nb_sym_versions; v++) {
3159 if (strcmp(sym_versions[v].lib, lib))
3160 continue;
3161 prev_same_lib = v;
3162 if (!strcmp(sym_versions[v].version, version))
3163 break;
3165 if (v == nb_sym_versions) {
3166 sym_versions = tcc_realloc (sym_versions,
3167 (v + 1) * sizeof(*sym_versions));
3168 sym_versions[v].lib = tcc_strdup(lib);
3169 sym_versions[v].version = tcc_strdup(version);
3170 sym_versions[v].out_index = 0;
3171 sym_versions[v].prev_same_lib = prev_same_lib;
3172 nb_sym_versions++;
3174 (*lv)[i] = v;
3178 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3179 VERNDX. */
3180 static void
3181 set_sym_version(TCCState *s1, int sym_index, int verndx)
3183 if (sym_index >= nb_sym_to_version) {
3184 int newelems = sym_index ? sym_index * 2 : 1;
3185 sym_to_version = tcc_realloc(sym_to_version,
3186 newelems * sizeof(*sym_to_version));
3187 memset(sym_to_version + nb_sym_to_version, -1,
3188 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3189 nb_sym_to_version = newelems;
3191 if (sym_to_version[sym_index] < 0)
3192 sym_to_version[sym_index] = verndx;
3195 struct versym_info {
3196 int nb_versyms;
3197 ElfW(Verdef) *verdef;
3198 ElfW(Verneed) *verneed;
3199 ElfW(Half) *versym;
3200 int nb_local_ver, *local_ver;
3204 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3206 char *lib, *version;
3207 uint32_t next;
3208 int i;
3210 #define DEBUG_VERSION 0
3212 if (v->versym && v->verdef) {
3213 ElfW(Verdef) *vdef = v->verdef;
3214 lib = NULL;
3215 do {
3216 ElfW(Verdaux) *verdaux =
3217 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3219 #if DEBUG_VERSION
3220 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3221 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3222 vdef->vd_hash);
3223 #endif
3224 if (vdef->vd_cnt) {
3225 version = dynstr + verdaux->vda_name;
3227 if (lib == NULL)
3228 lib = version;
3229 else
3230 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3231 lib, version);
3232 #if DEBUG_VERSION
3233 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3234 #endif
3236 next = vdef->vd_next;
3237 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3238 } while (next);
3240 if (v->versym && v->verneed) {
3241 ElfW(Verneed) *vneed = v->verneed;
3242 do {
3243 ElfW(Vernaux) *vernaux =
3244 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3246 lib = dynstr + vneed->vn_file;
3247 #if DEBUG_VERSION
3248 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3249 #endif
3250 for (i = 0; i < vneed->vn_cnt; i++) {
3251 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3252 version = dynstr + vernaux->vna_name;
3253 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3254 lib, version);
3255 #if DEBUG_VERSION
3256 printf (" vernaux(%u): %u %u %s\n",
3257 vernaux->vna_other, vernaux->vna_hash,
3258 vernaux->vna_flags, version);
3259 #endif
3261 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3263 next = vneed->vn_next;
3264 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3265 } while (next);
3268 #if DEBUG_VERSION
3269 for (i = 0; i < v->nb_local_ver; i++) {
3270 if (v->local_ver[i] > 0) {
3271 printf ("%d: lib: %s, version %s\n",
3272 i, sym_versions[v->local_ver[i]].lib,
3273 sym_versions[v->local_ver[i]].version);
3276 #endif
3279 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3280 is referenced by the user (so it should be added as DT_NEEDED in
3281 the generated ELF file) */
3282 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3284 ElfW(Ehdr) ehdr;
3285 ElfW(Shdr) *shdr, *sh, *sh1;
3286 int i, j, nb_syms, nb_dts, sym_bind, ret;
3287 ElfW(Sym) *sym, *dynsym;
3288 ElfW(Dyn) *dt, *dynamic;
3290 char *dynstr;
3291 int sym_index;
3292 const char *name, *soname;
3293 DLLReference *dllref;
3294 struct versym_info v;
3296 full_read(fd, &ehdr, sizeof(ehdr));
3298 /* test CPU specific stuff */
3299 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3300 ehdr.e_machine != EM_TCC_TARGET) {
3301 tcc_error_noabort("bad architecture");
3302 return -1;
3305 /* read sections */
3306 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3308 /* load dynamic section and dynamic symbols */
3309 nb_syms = 0;
3310 nb_dts = 0;
3311 dynamic = NULL;
3312 dynsym = NULL; /* avoid warning */
3313 dynstr = NULL; /* avoid warning */
3314 memset(&v, 0, sizeof v);
3316 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3317 switch(sh->sh_type) {
3318 case SHT_DYNAMIC:
3319 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3320 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3321 break;
3322 case SHT_DYNSYM:
3323 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3324 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3325 sh1 = &shdr[sh->sh_link];
3326 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3327 break;
3328 case SHT_GNU_verdef:
3329 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3330 break;
3331 case SHT_GNU_verneed:
3332 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3333 break;
3334 case SHT_GNU_versym:
3335 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3336 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3337 break;
3338 default:
3339 break;
3343 /* compute the real library name */
3344 soname = tcc_basename(filename);
3346 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3347 if (dt->d_tag == DT_SONAME) {
3348 soname = dynstr + dt->d_un.d_val;
3352 /* if the dll is already loaded, do not load it */
3353 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3354 dllref = s1->loaded_dlls[i];
3355 if (!strcmp(soname, dllref->name)) {
3356 /* but update level if needed */
3357 if (level < dllref->level)
3358 dllref->level = level;
3359 ret = 0;
3360 goto the_end;
3364 if (v.nb_versyms != nb_syms)
3365 tcc_free (v.versym), v.versym = NULL;
3366 else
3367 store_version(s1, &v, dynstr);
3369 /* add the dll and its level */
3370 tcc_add_dllref(s1, soname)->level = level;
3372 /* add dynamic symbols in dynsym_section */
3373 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3374 sym_bind = ELFW(ST_BIND)(sym->st_info);
3375 if (sym_bind == STB_LOCAL)
3376 continue;
3377 name = dynstr + sym->st_name;
3378 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3379 sym->st_info, sym->st_other, sym->st_shndx, name);
3380 if (v.versym) {
3381 ElfW(Half) vsym = v.versym[i];
3382 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3383 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3387 /* load all referenced DLLs */
3388 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3389 switch(dt->d_tag) {
3390 case DT_NEEDED:
3391 name = dynstr + dt->d_un.d_val;
3392 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3393 dllref = s1->loaded_dlls[j];
3394 if (!strcmp(name, dllref->name))
3395 goto already_loaded;
3397 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3398 tcc_error_noabort("referenced dll '%s' not found", name);
3399 ret = -1;
3400 goto the_end;
3402 already_loaded:
3403 break;
3406 ret = 0;
3407 the_end:
3408 tcc_free(dynstr);
3409 tcc_free(dynsym);
3410 tcc_free(dynamic);
3411 tcc_free(shdr);
3412 tcc_free(v.local_ver);
3413 tcc_free(v.verdef);
3414 tcc_free(v.verneed);
3415 tcc_free(v.versym);
3416 return ret;
3419 #define LD_TOK_NAME 256
3420 #define LD_TOK_EOF (-1)
3422 static int ld_inp(TCCState *s1)
3424 char b;
3425 if (s1->cc != -1) {
3426 int c = s1->cc;
3427 s1->cc = -1;
3428 return c;
3430 if (1 == read(s1->fd, &b, 1))
3431 return b;
3432 return CH_EOF;
3435 /* return next ld script token */
3436 static int ld_next(TCCState *s1, char *name, int name_size)
3438 int c, d, ch;
3439 char *q;
3441 redo:
3442 ch = ld_inp(s1);
3443 switch(ch) {
3444 case ' ':
3445 case '\t':
3446 case '\f':
3447 case '\v':
3448 case '\r':
3449 case '\n':
3450 goto redo;
3451 case '/':
3452 ch = ld_inp(s1);
3453 if (ch == '*') { /* comment */
3454 for (d = 0;; d = ch) {
3455 ch = ld_inp(s1);
3456 if (ch == CH_EOF || (ch == '/' && d == '*'))
3457 break;
3459 goto redo;
3460 } else {
3461 q = name;
3462 *q++ = '/';
3463 goto parse_name;
3465 break;
3466 case '\\':
3467 /* case 'a' ... 'z': */
3468 case 'a':
3469 case 'b':
3470 case 'c':
3471 case 'd':
3472 case 'e':
3473 case 'f':
3474 case 'g':
3475 case 'h':
3476 case 'i':
3477 case 'j':
3478 case 'k':
3479 case 'l':
3480 case 'm':
3481 case 'n':
3482 case 'o':
3483 case 'p':
3484 case 'q':
3485 case 'r':
3486 case 's':
3487 case 't':
3488 case 'u':
3489 case 'v':
3490 case 'w':
3491 case 'x':
3492 case 'y':
3493 case 'z':
3494 /* case 'A' ... 'z': */
3495 case 'A':
3496 case 'B':
3497 case 'C':
3498 case 'D':
3499 case 'E':
3500 case 'F':
3501 case 'G':
3502 case 'H':
3503 case 'I':
3504 case 'J':
3505 case 'K':
3506 case 'L':
3507 case 'M':
3508 case 'N':
3509 case 'O':
3510 case 'P':
3511 case 'Q':
3512 case 'R':
3513 case 'S':
3514 case 'T':
3515 case 'U':
3516 case 'V':
3517 case 'W':
3518 case 'X':
3519 case 'Y':
3520 case 'Z':
3521 case '_':
3522 case '.':
3523 case '$':
3524 case '~':
3525 q = name;
3526 parse_name:
3527 for(;;) {
3528 if (!((ch >= 'a' && ch <= 'z') ||
3529 (ch >= 'A' && ch <= 'Z') ||
3530 (ch >= '0' && ch <= '9') ||
3531 strchr("/.-_+=$:\\,~", ch)))
3532 break;
3533 if ((q - name) < name_size - 1) {
3534 *q++ = ch;
3536 ch = ld_inp(s1);
3538 s1->cc = ch;
3539 *q = '\0';
3540 c = LD_TOK_NAME;
3541 break;
3542 case CH_EOF:
3543 c = LD_TOK_EOF;
3544 break;
3545 default:
3546 c = ch;
3547 break;
3549 return c;
3552 static int ld_add_file(TCCState *s1, const char filename[])
3554 if (filename[0] == '/') {
3555 if (CONFIG_SYSROOT[0] == '\0'
3556 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3557 return 0;
3558 filename = tcc_basename(filename);
3560 return tcc_add_dll(s1, filename, 0);
3563 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3565 char filename[1024], libname[1024];
3566 int t, group, nblibs = 0, ret = 0;
3567 char **libs = NULL;
3569 group = !strcmp(cmd, "GROUP");
3570 if (!as_needed)
3571 s1->new_undef_sym = 0;
3572 t = ld_next(s1, filename, sizeof(filename));
3573 if (t != '(') {
3574 tcc_error_noabort("( expected");
3575 ret = -1;
3576 goto lib_parse_error;
3578 t = ld_next(s1, filename, sizeof(filename));
3579 for(;;) {
3580 libname[0] = '\0';
3581 if (t == LD_TOK_EOF) {
3582 tcc_error_noabort("unexpected end of file");
3583 ret = -1;
3584 goto lib_parse_error;
3585 } else if (t == ')') {
3586 break;
3587 } else if (t == '-') {
3588 t = ld_next(s1, filename, sizeof(filename));
3589 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3590 tcc_error_noabort("library name expected");
3591 ret = -1;
3592 goto lib_parse_error;
3594 pstrcpy(libname, sizeof libname, &filename[1]);
3595 if (s1->static_link) {
3596 snprintf(filename, sizeof filename, "lib%s.a", libname);
3597 } else {
3598 snprintf(filename, sizeof filename, "lib%s.so", libname);
3600 } else if (t != LD_TOK_NAME) {
3601 tcc_error_noabort("filename expected");
3602 ret = -1;
3603 goto lib_parse_error;
3605 if (!strcmp(filename, "AS_NEEDED")) {
3606 ret = ld_add_file_list(s1, cmd, 1);
3607 if (ret)
3608 goto lib_parse_error;
3609 } else {
3610 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3611 if (!as_needed) {
3612 ret = ld_add_file(s1, filename);
3613 if (ret)
3614 goto lib_parse_error;
3615 if (group) {
3616 /* Add the filename *and* the libname to avoid future conversions */
3617 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3618 if (libname[0] != '\0')
3619 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3623 t = ld_next(s1, filename, sizeof(filename));
3624 if (t == ',') {
3625 t = ld_next(s1, filename, sizeof(filename));
3628 if (group && !as_needed) {
3629 while (s1->new_undef_sym) {
3630 int i;
3631 s1->new_undef_sym = 0;
3632 for (i = 0; i < nblibs; i ++)
3633 ld_add_file(s1, libs[i]);
3636 lib_parse_error:
3637 dynarray_reset(&libs, &nblibs);
3638 return ret;
3641 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3642 files */
3643 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3645 char cmd[64];
3646 char filename[1024];
3647 int t, ret;
3649 s1->fd = fd;
3650 s1->cc = -1;
3651 for(;;) {
3652 t = ld_next(s1, cmd, sizeof(cmd));
3653 if (t == LD_TOK_EOF)
3654 return 0;
3655 else if (t != LD_TOK_NAME)
3656 return -1;
3657 if (!strcmp(cmd, "INPUT") ||
3658 !strcmp(cmd, "GROUP")) {
3659 ret = ld_add_file_list(s1, cmd, 0);
3660 if (ret)
3661 return ret;
3662 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3663 !strcmp(cmd, "TARGET")) {
3664 /* ignore some commands */
3665 t = ld_next(s1, cmd, sizeof(cmd));
3666 if (t != '(') {
3667 tcc_error_noabort("( expected");
3668 return -1;
3670 for(;;) {
3671 t = ld_next(s1, filename, sizeof(filename));
3672 if (t == LD_TOK_EOF) {
3673 tcc_error_noabort("unexpected end of file");
3674 return -1;
3675 } else if (t == ')') {
3676 break;
3679 } else {
3680 return -1;
3683 return 0;
3685 #endif /* !ELF_OBJ_ONLY */