dce: Don't force unreachable case label to be live
[tinycc.git] / tccelf.c
blob1103f3d1c4eca584c8b00650a6f21d2e41774279
1 /*
2 * ELF file handling for TCC
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "tcc.h"
23 /* Define this to get some debug output during relocation processing. */
24 #undef DEBUG_RELOC
26 /********************************************************/
27 /* global variables */
29 /* elf version information */
30 struct sym_version {
31 char *lib;
32 char *version;
33 int out_index;
34 int prev_same_lib;
37 #define nb_sym_versions s1->nb_sym_versions
38 #define sym_versions s1->sym_versions
39 #define nb_sym_to_version s1->nb_sym_to_version
40 #define sym_to_version s1->sym_to_version
41 #define dt_verneednum s1->dt_verneednum
42 #define versym_section s1->versym_section
43 #define verneed_section s1->verneed_section
45 /* special flag to indicate that the section should not be linked to the other ones */
46 #define SHF_PRIVATE 0x80000000
47 /* section is dynsymtab_section */
48 #define SHF_DYNSYM 0x40000000
50 #ifdef TCC_TARGET_PE
51 static const int shf_RELRO = SHF_ALLOC;
52 static const char rdata[] = ".rdata";
53 #else
54 static const int shf_RELRO = SHF_ALLOC | SHF_WRITE;
55 static const char rdata[] = ".data.ro";
56 #endif
58 /* ------------------------------------------------------------------------- */
60 ST_FUNC void tccelf_new(TCCState *s)
62 TCCState *s1 = s;
63 /* no section zero */
64 dynarray_add(&s->sections, &s->nb_sections, NULL);
66 /* create standard sections */
67 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
68 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
69 /* create ro data section (make ro after relocation done with GNU_RELRO) */
70 rodata_section = new_section(s, rdata, SHT_PROGBITS, shf_RELRO);
71 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
72 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
73 common_section->sh_num = SHN_COMMON;
75 /* symbols are always generated for linking stage */
76 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
77 ".strtab",
78 ".hashtab", SHF_PRIVATE);
79 s->symtab = symtab_section;
81 /* private symbol table for dynamic symbols */
82 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
83 ".dynstrtab",
84 ".dynhashtab", SHF_PRIVATE);
85 get_sym_attr(s, 0, 1);
88 #ifdef CONFIG_TCC_BCHECK
89 ST_FUNC void tccelf_bounds_new(TCCState *s)
91 TCCState *s1 = s;
92 /* create bounds sections (make ro after relocation done with GNU_RELRO) */
93 bounds_section = new_section(s, ".bounds", SHT_PROGBITS, shf_RELRO);
94 lbounds_section = new_section(s, ".lbounds", SHT_PROGBITS, shf_RELRO);
96 #endif
98 static void free_section(Section *s)
100 tcc_free(s->data);
103 ST_FUNC void tccelf_delete(TCCState *s1)
105 int i;
107 #ifndef ELF_OBJ_ONLY
108 /* free symbol versions */
109 for (i = 0; i < nb_sym_versions; i++) {
110 tcc_free(sym_versions[i].version);
111 tcc_free(sym_versions[i].lib);
113 tcc_free(sym_versions);
114 tcc_free(sym_to_version);
115 #endif
117 /* free all sections */
118 for(i = 1; i < s1->nb_sections; i++)
119 free_section(s1->sections[i]);
120 dynarray_reset(&s1->sections, &s1->nb_sections);
122 for(i = 0; i < s1->nb_priv_sections; i++)
123 free_section(s1->priv_sections[i]);
124 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
126 /* free any loaded DLLs */
127 #ifdef TCC_IS_NATIVE
128 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
129 DLLReference *ref = s1->loaded_dlls[i];
130 if ( ref->handle )
131 # ifdef _WIN32
132 FreeLibrary((HMODULE)ref->handle);
133 # else
134 dlclose(ref->handle);
135 # endif
137 #endif
138 /* free loaded dlls array */
139 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
140 tcc_free(s1->sym_attrs);
142 symtab_section = NULL; /* for tccrun.c:rt_printline() */
145 /* save section data state */
146 ST_FUNC void tccelf_begin_file(TCCState *s1)
148 Section *s; int i;
149 for (i = 1; i < s1->nb_sections; i++) {
150 s = s1->sections[i];
151 s->sh_offset = s->data_offset;
153 /* disable symbol hashing during compilation */
154 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
155 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
156 s1->uw_sym = 0;
157 #endif
160 /* At the end of compilation, convert any UNDEF syms to global, and merge
161 with previously existing symbols */
162 ST_FUNC void tccelf_end_file(TCCState *s1)
164 Section *s = s1->symtab;
165 int first_sym, nb_syms, *tr, i;
167 first_sym = s->sh_offset / sizeof (ElfSym);
168 nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
169 s->data_offset = s->sh_offset;
170 s->link->data_offset = s->link->sh_offset;
171 s->hash = s->reloc, s->reloc = NULL;
172 tr = tcc_mallocz(nb_syms * sizeof *tr);
174 for (i = 0; i < nb_syms; ++i) {
175 ElfSym *sym = (ElfSym*)s->data + first_sym + i;
176 if (sym->st_shndx == SHN_UNDEF
177 && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
178 sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
179 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
180 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
182 /* now update relocations */
183 for (i = 1; i < s1->nb_sections; i++) {
184 Section *sr = s1->sections[i];
185 if (sr->sh_type == SHT_RELX && sr->link == s) {
186 ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
187 ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
188 for (; rel < rel_end; ++rel) {
189 int n = ELFW(R_SYM)(rel->r_info) - first_sym;
190 //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
191 rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
195 tcc_free(tr);
197 /* record text/data/bss output for -bench info */
198 for (i = 0; i < 4; ++i) {
199 s = s1->sections[i + 1];
200 s1->total_output[i] += s->data_offset - s->sh_offset;
204 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
206 Section *sec;
208 sec = tcc_mallocz(sizeof(Section) + strlen(name));
209 sec->s1 = s1;
210 strcpy(sec->name, name);
211 sec->sh_type = sh_type;
212 sec->sh_flags = sh_flags;
213 switch(sh_type) {
214 case SHT_GNU_versym:
215 sec->sh_addralign = 2;
216 break;
217 case SHT_HASH:
218 case SHT_REL:
219 case SHT_RELA:
220 case SHT_DYNSYM:
221 case SHT_SYMTAB:
222 case SHT_DYNAMIC:
223 case SHT_GNU_verneed:
224 case SHT_GNU_verdef:
225 sec->sh_addralign = PTR_SIZE;
226 break;
227 case SHT_STRTAB:
228 sec->sh_addralign = 1;
229 break;
230 default:
231 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */
232 break;
235 if (sh_flags & SHF_PRIVATE) {
236 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
237 } else {
238 sec->sh_num = s1->nb_sections;
239 dynarray_add(&s1->sections, &s1->nb_sections, sec);
242 return sec;
245 ST_FUNC Section *new_symtab(TCCState *s1,
246 const char *symtab_name, int sh_type, int sh_flags,
247 const char *strtab_name,
248 const char *hash_name, int hash_sh_flags)
250 Section *symtab, *strtab, *hash;
251 int *ptr, nb_buckets;
253 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
254 symtab->sh_entsize = sizeof(ElfW(Sym));
255 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
256 put_elf_str(strtab, "");
257 symtab->link = strtab;
258 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
260 nb_buckets = 1;
262 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
263 hash->sh_entsize = sizeof(int);
264 symtab->hash = hash;
265 hash->link = symtab;
267 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
268 ptr[0] = nb_buckets;
269 ptr[1] = 1;
270 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
271 return symtab;
274 /* realloc section and set its content to zero */
275 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
277 unsigned long size;
278 unsigned char *data;
280 size = sec->data_allocated;
281 if (size == 0)
282 size = 1;
283 while (size < new_size)
284 size = size * 2;
285 data = tcc_realloc(sec->data, size);
286 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
287 sec->data = data;
288 sec->data_allocated = size;
291 /* reserve at least 'size' bytes aligned per 'align' in section
292 'sec' from current offset, and return the aligned offset */
293 ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
295 size_t offset, offset1;
297 offset = (sec->data_offset + align - 1) & -align;
298 offset1 = offset + size;
299 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
300 section_realloc(sec, offset1);
301 sec->data_offset = offset1;
302 if (align > sec->sh_addralign)
303 sec->sh_addralign = align;
304 return offset;
307 /* reserve at least 'size' bytes in section 'sec' from
308 sec->data_offset. */
309 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
311 size_t offset = section_add(sec, size, 1);
312 return sec->data + offset;
315 #ifndef ELF_OBJ_ONLY
316 /* reserve at least 'size' bytes from section start */
317 static void section_reserve(Section *sec, unsigned long size)
319 if (size > sec->data_allocated)
320 section_realloc(sec, size);
321 if (size > sec->data_offset)
322 sec->data_offset = size;
324 #endif
326 static Section *find_section_create (TCCState *s1, const char *name, int create)
328 Section *sec;
329 int i;
330 for(i = 1; i < s1->nb_sections; i++) {
331 sec = s1->sections[i];
332 if (!strcmp(name, sec->name))
333 return sec;
335 /* sections are created as PROGBITS */
336 return create ? new_section(s1, name, SHT_PROGBITS, SHF_ALLOC) : NULL;
339 /* return a reference to a section, and create it if it does not
340 exists */
341 ST_FUNC Section *find_section(TCCState *s1, const char *name)
343 return find_section_create (s1, name, 1);
346 /* ------------------------------------------------------------------------- */
348 ST_FUNC int put_elf_str(Section *s, const char *sym)
350 int offset, len;
351 char *ptr;
353 len = strlen(sym) + 1;
354 offset = s->data_offset;
355 ptr = section_ptr_add(s, len);
356 memmove(ptr, sym, len);
357 return offset;
360 /* elf symbol hashing function */
361 static unsigned long elf_hash(const unsigned char *name)
363 unsigned long h = 0, g;
365 while (*name) {
366 h = (h << 4) + *name++;
367 g = h & 0xf0000000;
368 if (g)
369 h ^= g >> 24;
370 h &= ~g;
372 return h;
375 /* rebuild hash table of section s */
376 /* NOTE: we do factorize the hash table code to go faster */
377 static void rebuild_hash(Section *s, unsigned int nb_buckets)
379 ElfW(Sym) *sym;
380 int *ptr, *hash, nb_syms, sym_index, h;
381 unsigned char *strtab;
383 strtab = s->link->data;
384 nb_syms = s->data_offset / sizeof(ElfW(Sym));
386 if (!nb_buckets)
387 nb_buckets = ((int*)s->hash->data)[0];
389 s->hash->data_offset = 0;
390 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
391 ptr[0] = nb_buckets;
392 ptr[1] = nb_syms;
393 ptr += 2;
394 hash = ptr;
395 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
396 ptr += nb_buckets + 1;
398 sym = (ElfW(Sym) *)s->data + 1;
399 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
400 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
401 h = elf_hash(strtab + sym->st_name) % nb_buckets;
402 *ptr = hash[h];
403 hash[h] = sym_index;
404 } else {
405 *ptr = 0;
407 ptr++;
408 sym++;
412 /* return the symbol number */
413 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
414 int info, int other, int shndx, const char *name)
416 int name_offset, sym_index;
417 int nbuckets, h;
418 ElfW(Sym) *sym;
419 Section *hs;
421 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
422 if (name && name[0])
423 name_offset = put_elf_str(s->link, name);
424 else
425 name_offset = 0;
426 /* XXX: endianness */
427 sym->st_name = name_offset;
428 sym->st_value = value;
429 sym->st_size = size;
430 sym->st_info = info;
431 sym->st_other = other;
432 sym->st_shndx = shndx;
433 sym_index = sym - (ElfW(Sym) *)s->data;
434 hs = s->hash;
435 if (hs) {
436 int *ptr, *base;
437 ptr = section_ptr_add(hs, sizeof(int));
438 base = (int *)hs->data;
439 /* only add global or weak symbols. */
440 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
441 /* add another hashing entry */
442 nbuckets = base[0];
443 h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
444 *ptr = base[2 + h];
445 base[2 + h] = sym_index;
446 base[1]++;
447 /* we resize the hash table */
448 hs->nb_hashed_syms++;
449 if (hs->nb_hashed_syms > 2 * nbuckets) {
450 rebuild_hash(s, 2 * nbuckets);
452 } else {
453 *ptr = 0;
454 base[1]++;
457 return sym_index;
460 ST_FUNC int find_elf_sym(Section *s, const char *name)
462 ElfW(Sym) *sym;
463 Section *hs;
464 int nbuckets, sym_index, h;
465 const char *name1;
467 hs = s->hash;
468 if (!hs)
469 return 0;
470 nbuckets = ((int *)hs->data)[0];
471 h = elf_hash((unsigned char *) name) % nbuckets;
472 sym_index = ((int *)hs->data)[2 + h];
473 while (sym_index != 0) {
474 sym = &((ElfW(Sym) *)s->data)[sym_index];
475 name1 = (char *) s->link->data + sym->st_name;
476 if (!strcmp(name, name1))
477 return sym_index;
478 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
480 return 0;
483 /* return elf symbol value, signal error if 'err' is nonzero, decorate
484 name if FORC */
485 ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
487 int sym_index;
488 ElfW(Sym) *sym;
489 char buf[256];
490 if (forc && s1->leading_underscore
491 #ifdef TCC_TARGET_PE
492 /* win32-32bit stdcall symbols always have _ already */
493 && !strchr(name, '@')
494 #endif
496 buf[0] = '_';
497 pstrcpy(buf + 1, sizeof(buf) - 1, name);
498 name = buf;
500 sym_index = find_elf_sym(s1->symtab, name);
501 sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
502 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
503 if (err)
504 tcc_error("%s not defined", name);
505 return (addr_t)-1;
507 return sym->st_value;
510 /* return elf symbol value */
511 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
513 addr_t addr = get_sym_addr(s, name, 0, 1);
514 return addr == -1 ? NULL : (void*)(uintptr_t)addr;
517 /* list elf symbol names and values */
518 ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
519 void (*symbol_cb)(void *ctx, const char *name, const void *val))
521 ElfW(Sym) *sym;
522 Section *symtab;
523 int sym_index, end_sym;
524 const char *name;
525 unsigned char sym_vis, sym_bind;
527 symtab = s->symtab;
528 end_sym = symtab->data_offset / sizeof (ElfSym);
529 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
530 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
531 if (sym->st_value) {
532 name = (char *) symtab->link->data + sym->st_name;
533 sym_bind = ELFW(ST_BIND)(sym->st_info);
534 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
535 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
536 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
541 /* list elf symbol names and values */
542 LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
543 void (*symbol_cb)(void *ctx, const char *name, const void *val))
545 list_elf_symbols(s, ctx, symbol_cb);
548 #ifndef ELF_OBJ_ONLY
549 static void
550 version_add (TCCState *s1)
552 int i;
553 ElfW(Sym) *sym;
554 ElfW(Verneed) *vn = NULL;
555 Section *symtab;
556 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
557 ElfW(Half) *versym;
558 const char *name;
560 if (0 == nb_sym_versions)
561 return;
562 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
563 versym_section->sh_entsize = sizeof(ElfW(Half));
564 versym_section->link = s1->dynsym;
566 /* add needed symbols */
567 symtab = s1->dynsym;
568 end_sym = symtab->data_offset / sizeof (ElfSym);
569 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
570 for (sym_index = 1; sym_index < end_sym; ++sym_index) {
571 int dllindex, verndx;
572 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
573 if (sym->st_shndx != SHN_UNDEF)
574 continue; /* defined symbol doesn't need library version */
575 name = (char *) symtab->link->data + sym->st_name;
576 dllindex = find_elf_sym(s1->dynsymtab_section, name);
577 verndx = (dllindex && dllindex < nb_sym_to_version)
578 ? sym_to_version[dllindex] : -1;
579 if (verndx >= 0) {
580 if (!sym_versions[verndx].out_index)
581 sym_versions[verndx].out_index = nb_versions++;
582 versym[sym_index] = sym_versions[verndx].out_index;
585 /* generate verneed section, but not when it will be empty. Some
586 dynamic linkers look at their contents even when DTVERNEEDNUM and
587 section size is zero. */
588 if (nb_versions > 2) {
589 verneed_section = new_section(s1, ".gnu.version_r",
590 SHT_GNU_verneed, SHF_ALLOC);
591 verneed_section->link = s1->dynsym->link;
592 for (i = nb_sym_versions; i-- > 0;) {
593 struct sym_version *sv = &sym_versions[i];
594 int n_same_libs = 0, prev;
595 size_t vnofs;
596 ElfW(Vernaux) *vna = 0;
597 if (sv->out_index < 1)
598 continue;
599 /* make sure that a DT_NEEDED tag is put */
600 tcc_add_dllref(s1, sv->lib, 0);
601 vnofs = section_add(verneed_section, sizeof(*vn), 1);
602 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
603 vn->vn_version = 1;
604 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
605 vn->vn_aux = sizeof (*vn);
606 do {
607 prev = sv->prev_same_lib;
608 if (sv->out_index > 0) {
609 vna = section_ptr_add(verneed_section, sizeof(*vna));
610 vna->vna_hash = elf_hash ((const unsigned char *)sv->version);
611 vna->vna_flags = 0;
612 vna->vna_other = sv->out_index;
613 sv->out_index = -2;
614 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
615 vna->vna_next = sizeof (*vna);
616 n_same_libs++;
618 if (prev >= 0)
619 sv = &sym_versions[prev];
620 } while(prev >= 0);
621 vna->vna_next = 0;
622 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
623 vn->vn_cnt = n_same_libs;
624 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
625 nb_entries++;
627 if (vn)
628 vn->vn_next = 0;
629 verneed_section->sh_info = nb_entries;
631 dt_verneednum = nb_entries;
633 #endif /* ndef ELF_OBJ_ONLY */
635 /* add an elf symbol : check if it is already defined and patch
636 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
637 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
638 int info, int other, int shndx, const char *name)
640 TCCState *s1 = s->s1;
641 ElfW(Sym) *esym;
642 int sym_bind, sym_index, sym_type, esym_bind;
643 unsigned char sym_vis, esym_vis, new_vis;
645 sym_bind = ELFW(ST_BIND)(info);
646 sym_type = ELFW(ST_TYPE)(info);
647 sym_vis = ELFW(ST_VISIBILITY)(other);
649 if (sym_bind != STB_LOCAL) {
650 /* we search global or weak symbols */
651 sym_index = find_elf_sym(s, name);
652 if (!sym_index)
653 goto do_def;
654 esym = &((ElfW(Sym) *)s->data)[sym_index];
655 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
656 && esym->st_other == other && esym->st_shndx == shndx)
657 return sym_index;
658 if (esym->st_shndx != SHN_UNDEF) {
659 esym_bind = ELFW(ST_BIND)(esym->st_info);
660 /* propagate the most constraining visibility */
661 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
662 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
663 if (esym_vis == STV_DEFAULT) {
664 new_vis = sym_vis;
665 } else if (sym_vis == STV_DEFAULT) {
666 new_vis = esym_vis;
667 } else {
668 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
670 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
671 | new_vis;
672 if (shndx == SHN_UNDEF) {
673 /* ignore adding of undefined symbol if the
674 corresponding symbol is already defined */
675 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
676 /* global overrides weak, so patch */
677 goto do_patch;
678 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
679 /* weak is ignored if already global */
680 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
681 /* keep first-found weak definition, ignore subsequents */
682 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
683 /* ignore hidden symbols after */
684 } else if ((esym->st_shndx == SHN_COMMON
685 || esym->st_shndx == bss_section->sh_num)
686 && (shndx < SHN_LORESERVE
687 && shndx != bss_section->sh_num)) {
688 /* data symbol gets precedence over common/bss */
689 goto do_patch;
690 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
691 /* data symbol keeps precedence over common/bss */
692 } else if (s->sh_flags & SHF_DYNSYM) {
693 /* we accept that two DLL define the same symbol */
694 } else if (esym->st_other & ST_ASM_SET) {
695 /* If the existing symbol came from an asm .set
696 we can override. */
697 goto do_patch;
698 } else {
699 #if 0
700 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
701 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
702 #endif
703 tcc_error_noabort("'%s' defined twice", name);
705 } else {
706 esym->st_other = other;
707 do_patch:
708 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
709 esym->st_shndx = shndx;
710 s1->new_undef_sym = 1;
711 esym->st_value = value;
712 esym->st_size = size;
714 } else {
715 do_def:
716 sym_index = put_elf_sym(s, value, size,
717 ELFW(ST_INFO)(sym_bind, sym_type), other,
718 shndx, name);
720 return sym_index;
723 /* put relocation */
724 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
725 int type, int symbol, addr_t addend)
727 TCCState *s1 = s->s1;
728 char buf[256];
729 Section *sr;
730 ElfW_Rel *rel;
732 sr = s->reloc;
733 if (!sr) {
734 /* if no relocation section, create it */
735 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
736 /* if the symtab is allocated, then we consider the relocation
737 are also */
738 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
739 sr->sh_entsize = sizeof(ElfW_Rel);
740 sr->link = symtab;
741 sr->sh_info = s->sh_num;
742 s->reloc = sr;
744 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
745 rel->r_offset = offset;
746 rel->r_info = ELFW(R_INFO)(symbol, type);
747 #if SHT_RELX == SHT_RELA
748 rel->r_addend = addend;
749 #endif
750 if (SHT_RELX != SHT_RELA && addend)
751 tcc_error("non-zero addend on REL architecture");
754 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
755 int type, int symbol)
757 put_elf_reloca(symtab, s, offset, type, symbol, 0);
760 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
762 int n;
763 struct sym_attr *tab;
765 if (index >= s1->nb_sym_attrs) {
766 if (!alloc)
767 return s1->sym_attrs;
768 /* find immediately bigger power of 2 and reallocate array */
769 n = 1;
770 while (index >= n)
771 n *= 2;
772 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
773 s1->sym_attrs = tab;
774 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
775 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
776 s1->nb_sym_attrs = n;
778 return &s1->sym_attrs[index];
781 /* In an ELF file symbol table, the local symbols must appear below
782 the global and weak ones. Since TCC cannot sort it while generating
783 the code, we must do it after. All the relocation tables are also
784 modified to take into account the symbol table sorting */
785 static void sort_syms(TCCState *s1, Section *s)
787 int *old_to_new_syms;
788 ElfW(Sym) *new_syms;
789 int nb_syms, i;
790 ElfW(Sym) *p, *q;
791 ElfW_Rel *rel;
792 Section *sr;
793 int type, sym_index;
795 nb_syms = s->data_offset / sizeof(ElfW(Sym));
796 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
797 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
799 /* first pass for local symbols */
800 p = (ElfW(Sym) *)s->data;
801 q = new_syms;
802 for(i = 0; i < nb_syms; i++) {
803 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
804 old_to_new_syms[i] = q - new_syms;
805 *q++ = *p;
807 p++;
809 /* save the number of local symbols in section header */
810 if( s->sh_size ) /* this 'if' makes IDA happy */
811 s->sh_info = q - new_syms;
813 /* then second pass for non local symbols */
814 p = (ElfW(Sym) *)s->data;
815 for(i = 0; i < nb_syms; i++) {
816 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
817 old_to_new_syms[i] = q - new_syms;
818 *q++ = *p;
820 p++;
823 /* we copy the new symbols to the old */
824 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
825 tcc_free(new_syms);
827 /* now we modify all the relocations */
828 for(i = 1; i < s1->nb_sections; i++) {
829 sr = s1->sections[i];
830 if (sr->sh_type == SHT_RELX && sr->link == s) {
831 for_each_elem(sr, 0, rel, ElfW_Rel) {
832 sym_index = ELFW(R_SYM)(rel->r_info);
833 type = ELFW(R_TYPE)(rel->r_info);
834 sym_index = old_to_new_syms[sym_index];
835 rel->r_info = ELFW(R_INFO)(sym_index, type);
840 tcc_free(old_to_new_syms);
843 /* relocate symbol table, resolve undefined symbols if do_resolve is
844 true and output error if undefined symbol. */
845 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
847 ElfW(Sym) *sym;
848 int sym_bind, sh_num;
849 const char *name;
851 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
852 sh_num = sym->st_shndx;
853 if (sh_num == SHN_UNDEF) {
854 name = (char *) s1->symtab->link->data + sym->st_name;
855 /* Use ld.so to resolve symbol for us (for tcc -run) */
856 if (do_resolve) {
857 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
858 /* dlsym() needs the undecorated name. */
859 void *addr = dlsym(RTLD_DEFAULT, &name[s1->leading_underscore]);
860 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD || TARGETOS_ANDROID
861 if (addr == NULL) {
862 int i;
863 for (i = 0; i < s1->nb_loaded_dlls; i++)
864 if ((addr = dlsym(s1->loaded_dlls[i]->handle, name)))
865 break;
867 #endif
868 if (addr) {
869 sym->st_value = (addr_t) addr;
870 #ifdef DEBUG_RELOC
871 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
872 #endif
873 goto found;
875 #endif
876 /* if dynamic symbol exist, it will be used in relocate_section */
877 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
878 goto found;
879 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
880 it */
881 if (!strcmp(name, "_fp_hw"))
882 goto found;
883 /* only weak symbols are accepted to be undefined. Their
884 value is zero */
885 sym_bind = ELFW(ST_BIND)(sym->st_info);
886 if (sym_bind == STB_WEAK)
887 sym->st_value = 0;
888 else
889 tcc_error_noabort("undefined symbol '%s'", name);
891 } else if (sh_num < SHN_LORESERVE) {
892 /* add section base */
893 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
895 found: ;
899 /* relocate a given section (CPU dependent) by applying the relocations
900 in the associated relocation section */
901 static void relocate_section(TCCState *s1, Section *s, Section *sr)
903 ElfW_Rel *rel;
904 ElfW(Sym) *sym;
905 int type, sym_index;
906 unsigned char *ptr;
907 addr_t tgt, addr;
908 int is_dwarf = s->sh_num >= s1->dwlo && s->sh_num < s1->dwhi;
910 qrel = (ElfW_Rel *)sr->data;
911 for_each_elem(sr, 0, rel, ElfW_Rel) {
912 ptr = s->data + rel->r_offset;
913 sym_index = ELFW(R_SYM)(rel->r_info);
914 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
915 type = ELFW(R_TYPE)(rel->r_info);
916 tgt = sym->st_value;
917 #if SHT_RELX == SHT_RELA
918 tgt += rel->r_addend;
919 #endif
920 if (is_dwarf && type == R_DATA_32DW
921 && sym->st_shndx >= s1->dwlo && sym->st_shndx < s1->dwhi) {
922 /* dwarf section relocation to each other */
923 add32le(ptr, tgt - s1->sections[sym->st_shndx]->sh_addr);
924 continue;
926 addr = s->sh_addr + rel->r_offset;
927 relocate(s1, rel, type, ptr, addr, tgt);
929 #ifndef ELF_OBJ_ONLY
930 /* if the relocation is allocated, we change its symbol table */
931 if (sr->sh_flags & SHF_ALLOC) {
932 sr->link = s1->dynsym;
933 if (s1->output_type & TCC_OUTPUT_DYN) {
934 size_t r = (uint8_t*)qrel - sr->data;
935 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
936 && 0 == strcmp(s->name, ".stab"))
937 r = 0; /* cannot apply 64bit relocation to 32bit value */
938 sr->data_offset = sr->sh_size = r;
939 #ifdef CONFIG_TCC_PIE
940 if (r && 0 == (s->sh_flags & SHF_WRITE))
941 tcc_warning("%d relocations to ro-section %s", (unsigned)(r / sizeof *qrel), s->name);
942 #endif
945 #endif
948 /* relocate all sections */
949 ST_FUNC void relocate_sections(TCCState *s1)
951 int i;
952 Section *s, *sr;
954 for (i = 1; i < s1->nb_sections; ++i) {
955 sr = s1->sections[i];
956 if (sr->sh_type != SHT_RELX)
957 continue;
958 s = s1->sections[sr->sh_info];
959 #ifndef TCC_TARGET_MACHO
960 if (s != s1->got
961 || s1->static_link
962 || s1->output_type == TCC_OUTPUT_MEMORY)
963 #endif
965 relocate_section(s1, s, sr);
967 #ifndef ELF_OBJ_ONLY
968 if (sr->sh_flags & SHF_ALLOC) {
969 ElfW_Rel *rel;
970 /* relocate relocation table in 'sr' */
971 for_each_elem(sr, 0, rel, ElfW_Rel)
972 rel->r_offset += s->sh_addr;
974 #endif
978 #ifndef ELF_OBJ_ONLY
979 /* count the number of dynamic relocations so that we can reserve
980 their space */
981 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
983 int count = 0;
984 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
985 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
986 defined(TCC_TARGET_RISCV64)
987 ElfW_Rel *rel;
988 for_each_elem(sr, 0, rel, ElfW_Rel) {
989 int sym_index = ELFW(R_SYM)(rel->r_info);
990 int type = ELFW(R_TYPE)(rel->r_info);
991 switch(type) {
992 #if defined(TCC_TARGET_I386)
993 case R_386_32:
994 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
995 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
996 /* don't fixup unresolved (weak) symbols */
997 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
998 break;
1000 #elif defined(TCC_TARGET_X86_64)
1001 case R_X86_64_32:
1002 case R_X86_64_32S:
1003 case R_X86_64_64:
1004 #elif defined(TCC_TARGET_ARM)
1005 case R_ARM_ABS32:
1006 case R_ARM_TARGET1:
1007 #elif defined(TCC_TARGET_ARM64)
1008 case R_AARCH64_ABS32:
1009 case R_AARCH64_ABS64:
1010 #elif defined(TCC_TARGET_RISCV64)
1011 case R_RISCV_32:
1012 case R_RISCV_64:
1013 #endif
1014 count++;
1015 break;
1016 #if defined(TCC_TARGET_I386)
1017 case R_386_PC32:
1018 #elif defined(TCC_TARGET_X86_64)
1019 case R_X86_64_PC32:
1021 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1022 /* Hidden defined symbols can and must be resolved locally.
1023 We're misusing a PLT32 reloc for this, as that's always
1024 resolved to its address even in shared libs. */
1025 if (sym->st_shndx != SHN_UNDEF &&
1026 ELFW(ST_VISIBILITY)(sym->st_other) == STV_HIDDEN) {
1027 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PLT32);
1028 break;
1031 #elif defined(TCC_TARGET_ARM64)
1032 case R_AARCH64_PREL32:
1033 #endif
1034 if (s1->output_type != TCC_OUTPUT_DLL)
1035 break;
1036 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1037 count++;
1038 break;
1039 default:
1040 break;
1043 #endif
1044 return count;
1046 #endif
1048 #ifdef NEED_BUILD_GOT
1049 static int build_got(TCCState *s1)
1051 /* if no got, then create it */
1052 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1053 s1->got->sh_entsize = 4;
1054 /* keep space for _DYNAMIC pointer and two dummy got entries */
1055 section_ptr_add(s1->got, 3 * PTR_SIZE);
1056 return set_elf_sym(symtab_section, 0, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1057 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1060 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1061 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1062 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1063 Returns the offset of the GOT or (if any) PLT entry. */
1064 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1065 int sym_index)
1067 int need_plt_entry;
1068 const char *name;
1069 ElfW(Sym) *sym;
1070 struct sym_attr *attr;
1071 unsigned got_offset;
1072 char plt_name[200];
1073 int len;
1074 Section *s_rel;
1076 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1077 attr = get_sym_attr(s1, sym_index, 1);
1079 /* In case a function is both called and its address taken 2 GOT entries
1080 are created, one for taking the address (GOT) and the other for the PLT
1081 entry (PLTGOT). */
1082 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1083 return attr;
1085 s_rel = s1->got;
1086 if (need_plt_entry) {
1087 if (!s1->plt) {
1088 s1->plt = new_section(s1, ".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
1089 s1->plt->sh_entsize = 4;
1091 s_rel = s1->plt;
1094 /* create the GOT entry */
1095 got_offset = s1->got->data_offset;
1096 section_ptr_add(s1->got, PTR_SIZE);
1098 /* Create the GOT relocation that will insert the address of the object or
1099 function of interest in the GOT entry. This is a static relocation for
1100 memory output (dlsym will give us the address of symbols) and dynamic
1101 relocation otherwise (executable and DLLs). The relocation should be
1102 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1103 associated to a PLT entry) but is currently done at load time for an
1104 unknown reason. */
1106 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1107 name = (char *) symtab_section->link->data + sym->st_name;
1108 //printf("sym %d %s\n", need_plt_entry, name);
1110 if (s1->dynsym) {
1111 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1112 /* Hack alarm. We don't want to emit dynamic symbols
1113 and symbol based relocs for STB_LOCAL symbols, but rather
1114 want to resolve them directly. At this point the symbol
1115 values aren't final yet, so we must defer this. We will later
1116 have to create a RELATIVE reloc anyway, so we misuse the
1117 relocation slot to smuggle the symbol reference until
1118 fill_local_got_entries. Not that the sym_index is
1119 relative to symtab_section, not s1->dynsym! Nevertheless
1120 we use s1->dyn_sym so that if this is the first call
1121 that got->reloc is correctly created. Also note that
1122 RELATIVE relocs are not normally created for the .got,
1123 so the types serves as a marker for later (and is retained
1124 also for the final output, which is okay because then the
1125 got is just normal data). */
1126 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1127 sym_index);
1128 } else {
1129 if (0 == attr->dyn_index)
1130 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1131 sym->st_size, sym->st_info, 0,
1132 sym->st_shndx, name);
1133 put_elf_reloc(s1->dynsym, s_rel, got_offset, dyn_reloc_type,
1134 attr->dyn_index);
1136 } else {
1137 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1138 sym_index);
1141 if (need_plt_entry) {
1142 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1144 /* create a symbol 'sym@plt' for the PLT jump vector */
1145 len = strlen(name);
1146 if (len > sizeof plt_name - 5)
1147 len = sizeof plt_name - 5;
1148 memcpy(plt_name, name, len);
1149 strcpy(plt_name + len, "@plt");
1150 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, 0,
1151 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1152 } else {
1153 attr->got_offset = got_offset;
1156 return attr;
1159 /* build GOT and PLT entries */
1160 /* Two passes because R_JMP_SLOT should become first. Some targets
1161 (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1162 ST_FUNC void build_got_entries(TCCState *s1, int got_sym)
1164 Section *s;
1165 ElfW_Rel *rel;
1166 ElfW(Sym) *sym;
1167 int i, type, gotplt_entry, reloc_type, sym_index;
1168 struct sym_attr *attr;
1169 int pass = 0;
1170 redo:
1171 for(i = 1; i < s1->nb_sections; i++) {
1172 s = s1->sections[i];
1173 if (s->sh_type != SHT_RELX)
1174 continue;
1175 /* no need to handle got relocations */
1176 if (s->link != symtab_section)
1177 continue;
1178 for_each_elem(s, 0, rel, ElfW_Rel) {
1179 type = ELFW(R_TYPE)(rel->r_info);
1180 gotplt_entry = gotplt_entry_type(type);
1181 if (gotplt_entry == -1)
1182 tcc_error ("Unknown relocation type for got: %d", type);
1183 sym_index = ELFW(R_SYM)(rel->r_info);
1184 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1186 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1187 continue;
1190 /* Automatically create PLT/GOT [entry] if it is an undefined
1191 reference (resolved at runtime), or the symbol is absolute,
1192 probably created by tcc_add_symbol, and thus on 64-bit
1193 targets might be too far from application code. */
1194 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1195 if (sym->st_shndx == SHN_UNDEF) {
1196 ElfW(Sym) *esym;
1197 int dynindex;
1198 if (!PCRELATIVE_DLLPLT
1199 && (s1->output_type & TCC_OUTPUT_DYN))
1200 continue;
1201 /* Relocations for UNDEF symbols would normally need
1202 to be transferred into the executable or shared object.
1203 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1204 But TCC doesn't do that (at least for exes), so we
1205 need to resolve all such relocs locally. And that
1206 means PLT slots for functions in DLLs and COPY relocs for
1207 data symbols. COPY relocs were generated in
1208 bind_exe_dynsyms (and the symbol adjusted to be defined),
1209 and for functions we were generated a dynamic symbol
1210 of function type. */
1211 if (s1->dynsym) {
1212 /* dynsym isn't set for -run :-/ */
1213 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1214 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1215 if (dynindex
1216 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1217 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1218 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1219 goto jmp_slot;
1221 } else if (sym->st_shndx == SHN_ABS) {
1222 if (sym->st_value == 0) /* from tcc_add_btstub() */
1223 continue;
1224 #ifndef TCC_TARGET_ARM
1225 if (PTR_SIZE != 8)
1226 continue;
1227 #endif
1228 /* from tcc_add_symbol(): on 64 bit platforms these
1229 need to go through .got */
1230 } else
1231 continue;
1234 #ifdef TCC_TARGET_X86_64
1235 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1236 sym->st_shndx != SHN_UNDEF &&
1237 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1238 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1239 s1->output_type & TCC_OUTPUT_EXE)) {
1240 if (pass != 0)
1241 continue;
1242 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1243 continue;
1245 #endif
1246 reloc_type = code_reloc(type);
1247 if (reloc_type == -1)
1248 tcc_error ("Unknown relocation type: %d", type);
1250 if (reloc_type != 0) {
1251 jmp_slot:
1252 if (pass != 0)
1253 continue;
1254 reloc_type = R_JMP_SLOT;
1255 } else {
1256 if (pass != 1)
1257 continue;
1258 reloc_type = R_GLOB_DAT;
1261 if (!s1->got)
1262 got_sym = build_got(s1);
1264 if (gotplt_entry == BUILD_GOT_ONLY)
1265 continue;
1267 attr = put_got_entry(s1, reloc_type, sym_index);
1269 if (reloc_type == R_JMP_SLOT)
1270 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1273 if (++pass < 2)
1274 goto redo;
1275 /* .rel.plt refers to .got actually */
1276 if (s1->plt && s1->plt->reloc)
1277 s1->plt->reloc->sh_info = s1->got->sh_num;
1278 if (got_sym) /* set size */
1279 ((ElfW(Sym)*)symtab_section->data)[got_sym].st_size = s1->got->data_offset;
1281 #endif /* def NEED_BUILD_GOT */
1283 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
1285 int shn = sec ? sec->sh_num : offs || !name ? SHN_ABS : SHN_UNDEF;
1286 if (sec && offs == -1)
1287 offs = sec->data_offset;
1288 return set_elf_sym(symtab_section, offs, 0,
1289 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1292 static void add_init_array_defines(TCCState *s1, const char *section_name)
1294 Section *s;
1295 addr_t end_offset;
1296 char buf[1024];
1297 s = find_section_create(s1, section_name, 0);
1298 if (!s) {
1299 end_offset = 0;
1300 s = data_section;
1301 } else {
1302 end_offset = s->data_offset;
1304 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1305 set_global_sym(s1, buf, s, 0);
1306 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1307 set_global_sym(s1, buf, s, end_offset);
1310 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1312 Section *s;
1313 s = find_section(s1, sec);
1314 s->sh_flags = shf_RELRO;
1315 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1316 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1317 section_ptr_add(s, PTR_SIZE);
1320 #ifdef CONFIG_TCC_BCHECK
1321 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1323 if (0 == s1->do_bounds_check)
1324 return;
1325 section_ptr_add(bounds_section, sizeof(addr_t));
1327 #endif
1329 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1330 a dynamic symbol to allow so's to have one each with a different value. */
1331 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1333 int c = find_elf_sym(s1->symtab, name);
1334 if (c) {
1335 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1336 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1337 esym->st_value = offset;
1338 esym->st_shndx = s->sh_num;
1342 /* avoid generating debug/test_coverage code for stub functions */
1343 static void tcc_compile_string_no_debug(TCCState *s, const char *str)
1345 int save_do_debug = s->do_debug;
1346 int save_test_coverage = s->test_coverage;
1348 s->do_debug = 0;
1349 s->test_coverage = 0;
1350 tcc_compile_string(s, str);
1351 s->do_debug = save_do_debug;
1352 s->test_coverage = save_test_coverage;
1355 #ifdef CONFIG_TCC_BACKTRACE
1356 static void put_ptr(TCCState *s1, Section *s, int offs)
1358 int c;
1359 c = set_global_sym(s1, NULL, s, offs);
1360 s = data_section;
1361 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1362 section_ptr_add(s, PTR_SIZE);
1365 ST_FUNC void tcc_add_btstub(TCCState *s1)
1367 Section *s;
1368 int n, o;
1369 CString cstr;
1371 s = data_section;
1372 /* Align to PTR_SIZE */
1373 section_ptr_add(s, -s->data_offset & (PTR_SIZE - 1));
1374 o = s->data_offset;
1375 /* create (part of) a struct rt_context (see tccrun.c) */
1376 if (s1->dwarf) {
1377 put_ptr(s1, dwarf_line_section, 0);
1378 put_ptr(s1, dwarf_line_section, -1);
1379 if (s1->dwarf >= 5)
1380 put_ptr(s1, dwarf_line_str_section, 0);
1381 else
1382 put_ptr(s1, dwarf_str_section, 0);
1384 else
1386 put_ptr(s1, stab_section, 0);
1387 put_ptr(s1, stab_section, -1);
1388 put_ptr(s1, stab_section->link, 0);
1390 *(addr_t *)section_ptr_add(s, PTR_SIZE) = s1->dwarf;
1391 /* skip esym_start/esym_end/elf_str (not loaded) */
1392 section_ptr_add(s, 3 * PTR_SIZE);
1393 /* prog_base : local nameless symbol with offset 0 at SHN_ABS */
1394 put_ptr(s1, NULL, 0);
1395 n = 2 * PTR_SIZE;
1396 #ifdef CONFIG_TCC_BCHECK
1397 if (s1->do_bounds_check) {
1398 put_ptr(s1, bounds_section, 0);
1399 n -= PTR_SIZE;
1401 #endif
1402 section_ptr_add(s, n);
1403 cstr_new(&cstr);
1404 cstr_printf(&cstr,
1405 "extern void __bt_init(),__bt_exit(),__bt_init_dll();"
1406 "static void *__rt_info[];"
1407 "__attribute__((constructor)) static void __bt_init_rt(){");
1408 #ifdef TCC_TARGET_PE
1409 if (s1->output_type == TCC_OUTPUT_DLL)
1410 #ifdef CONFIG_TCC_BCHECK
1411 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1412 #else
1413 cstr_printf(&cstr, "__bt_init_dll(0);");
1414 #endif
1415 #endif
1416 cstr_printf(&cstr, "__bt_init(__rt_info,%d);}",
1417 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1418 /* In case dlcose is called by application */
1419 cstr_printf(&cstr,
1420 "__attribute__((destructor)) static void __bt_exit_rt(){"
1421 "__bt_exit(__rt_info);}");
1422 tcc_compile_string_no_debug(s1, cstr.data);
1423 cstr_free(&cstr);
1424 set_local_sym(s1, &"___rt_info"[!s1->leading_underscore], s, o);
1426 #endif /* def CONFIG_TCC_BACKTRACE */
1428 static void tcc_tcov_add_file(TCCState *s1, const char *filename)
1430 CString cstr;
1431 void *ptr;
1432 char wd[1024];
1434 if (tcov_section == NULL)
1435 return;
1436 section_ptr_add(tcov_section, 1);
1437 write32le (tcov_section->data, tcov_section->data_offset);
1439 cstr_new (&cstr);
1440 if (filename[0] == '/')
1441 cstr_printf (&cstr, "%s.tcov", filename);
1442 else {
1443 getcwd (wd, sizeof(wd));
1444 cstr_printf (&cstr, "%s/%s.tcov", wd, filename);
1446 ptr = section_ptr_add(tcov_section, cstr.size + 1);
1447 strcpy((char *)ptr, cstr.data);
1448 unlink((char *)ptr);
1449 #ifdef _WIN32
1450 normalize_slashes((char *)ptr);
1451 #endif
1452 cstr_free (&cstr);
1454 cstr_new(&cstr);
1455 cstr_printf(&cstr,
1456 "extern char *__tcov_data[];"
1457 "extern void __store_test_coverage ();"
1458 "__attribute__((destructor)) static void __tcov_exit() {"
1459 "__store_test_coverage(__tcov_data);"
1460 "}");
1461 tcc_compile_string_no_debug(s1, cstr.data);
1462 cstr_free(&cstr);
1463 set_local_sym(s1, &"___tcov_data"[!s1->leading_underscore], tcov_section, 0);
1466 #ifndef TCC_TARGET_PE
1467 /* add tcc runtime libraries */
1468 ST_FUNC void tcc_add_runtime(TCCState *s1)
1470 s1->filetype = 0;
1472 #ifdef CONFIG_TCC_BCHECK
1473 tcc_add_bcheck(s1);
1474 #endif
1475 tcc_add_pragma_libs(s1);
1477 /* add libc */
1478 if (!s1->nostdlib) {
1479 int lpthread = s1->option_pthread;
1481 #ifdef CONFIG_TCC_BCHECK
1482 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1483 tcc_add_support(s1, "bcheck.o");
1484 # if !(TARGETOS_OpenBSD || TARGETOS_NetBSD)
1485 tcc_add_library_err(s1, "dl");
1486 # endif
1487 lpthread = 1;
1489 #endif
1490 #ifdef CONFIG_TCC_BACKTRACE
1491 if (s1->do_backtrace) {
1492 if (s1->output_type & TCC_OUTPUT_EXE)
1493 tcc_add_support(s1, "bt-exe.o");
1494 if (s1->output_type != TCC_OUTPUT_DLL)
1495 tcc_add_support(s1, "bt-log.o");
1496 if (s1->output_type != TCC_OUTPUT_MEMORY)
1497 tcc_add_btstub(s1);
1499 #endif
1500 if (lpthread)
1501 tcc_add_library_err(s1, "pthread");
1502 tcc_add_library_err(s1, "c");
1503 #ifdef TCC_LIBGCC
1504 if (!s1->static_link) {
1505 if (TCC_LIBGCC[0] == '/')
1506 tcc_add_file(s1, TCC_LIBGCC);
1507 else
1508 tcc_add_dll(s1, TCC_LIBGCC, 0);
1510 #endif
1511 #if defined TCC_TARGET_ARM && TARGETOS_FreeBSD
1512 tcc_add_library_err(s1, "gcc_s"); // unwind code
1513 #endif
1514 if (TCC_LIBTCC1[0])
1515 tcc_add_support(s1, TCC_LIBTCC1);
1517 /* add crt end if not memory output */
1518 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1519 #if defined TCC_TARGET_MACHO
1520 /* nothing to do */
1521 #elif TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
1522 if (s1->output_type & TCC_OUTPUT_DYN)
1523 tcc_add_crt(s1, "crtendS.o");
1524 else
1525 tcc_add_crt(s1, "crtend.o");
1526 # if !TARGETOS_OpenBSD
1527 tcc_add_crt(s1, "crtn.o");
1528 # endif
1529 #elif TARGETOS_ANDROID
1530 if (s1->output_type == TCC_OUTPUT_DLL)
1531 tcc_add_crt(s1, "crtend_so.o");
1532 else
1533 tcc_add_crt(s1, "crtend_android.o");
1534 #else
1535 tcc_add_crt(s1, "crtn.o");
1536 #endif
1540 #endif /* ndef TCC_TARGET_PE */
1542 /* add various standard linker symbols (must be done after the
1543 sections are filled (for example after allocating common
1544 symbols)) */
1545 static void tcc_add_linker_symbols(TCCState *s1)
1547 char buf[1024];
1548 int i;
1549 Section *s;
1551 set_global_sym(s1, "_etext", text_section, -1);
1552 set_global_sym(s1, "_edata", data_section, -1);
1553 set_global_sym(s1, "_end", bss_section, -1);
1554 #if TARGETOS_OpenBSD
1555 set_global_sym(s1, "__executable_start", NULL, ELF_START_ADDR);
1556 #endif
1557 #ifdef TCC_TARGET_RISCV64
1558 /* XXX should be .sdata+0x800, not .data+0x800 */
1559 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1560 #endif
1561 /* horrible new standard ldscript defines */
1562 add_init_array_defines(s1, ".preinit_array");
1563 add_init_array_defines(s1, ".init_array");
1564 add_init_array_defines(s1, ".fini_array");
1565 /* add start and stop symbols for sections whose name can be
1566 expressed in C */
1567 for(i = 1; i < s1->nb_sections; i++) {
1568 s = s1->sections[i];
1569 if ((s->sh_flags & SHF_ALLOC)
1570 && (s->sh_type == SHT_PROGBITS
1571 || s->sh_type == SHT_STRTAB)) {
1572 const char *p;
1573 /* check if section name can be expressed in C */
1574 p = s->name;
1575 for(;;) {
1576 int c = *p;
1577 if (!c)
1578 break;
1579 if (!isid(c) && !isnum(c))
1580 goto next_sec;
1581 p++;
1583 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1584 set_global_sym(s1, buf, s, 0);
1585 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1586 set_global_sym(s1, buf, s, -1);
1588 next_sec: ;
1592 ST_FUNC void resolve_common_syms(TCCState *s1)
1594 ElfW(Sym) *sym;
1596 /* Allocate common symbols in BSS. */
1597 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1598 if (sym->st_shndx == SHN_COMMON) {
1599 /* symbol alignment is in st_value for SHN_COMMONs */
1600 sym->st_value = section_add(bss_section, sym->st_size,
1601 sym->st_value);
1602 sym->st_shndx = bss_section->sh_num;
1606 /* Now assign linker provided symbols their value. */
1607 tcc_add_linker_symbols(s1);
1610 #ifndef ELF_OBJ_ONLY
1611 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1613 int sym_index = ELFW(R_SYM) (rel->r_info);
1614 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1615 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1616 unsigned offset = attr->got_offset;
1618 if (0 == offset)
1619 return;
1620 section_reserve(s1->got, offset + PTR_SIZE);
1621 #if PTR_SIZE == 8
1622 write64le(s1->got->data + offset, sym->st_value);
1623 #else
1624 write32le(s1->got->data + offset, sym->st_value);
1625 #endif
1628 /* Perform relocation to GOT or PLT entries */
1629 ST_FUNC void fill_got(TCCState *s1)
1631 Section *s;
1632 ElfW_Rel *rel;
1633 int i;
1635 for(i = 1; i < s1->nb_sections; i++) {
1636 s = s1->sections[i];
1637 if (s->sh_type != SHT_RELX)
1638 continue;
1639 /* no need to handle got relocations */
1640 if (s->link != symtab_section)
1641 continue;
1642 for_each_elem(s, 0, rel, ElfW_Rel) {
1643 switch (ELFW(R_TYPE) (rel->r_info)) {
1644 case R_X86_64_GOT32:
1645 case R_X86_64_GOTPCREL:
1646 case R_X86_64_GOTPCRELX:
1647 case R_X86_64_REX_GOTPCRELX:
1648 case R_X86_64_PLT32:
1649 fill_got_entry(s1, rel);
1650 break;
1656 /* See put_got_entry for a description. This is the second stage
1657 where GOT references to local defined symbols are rewritten. */
1658 static void fill_local_got_entries(TCCState *s1)
1660 ElfW_Rel *rel;
1661 if (!s1->got->reloc)
1662 return;
1663 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1664 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1665 int sym_index = ELFW(R_SYM) (rel->r_info);
1666 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1667 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1668 unsigned offset = attr->got_offset;
1669 if (offset != rel->r_offset - s1->got->sh_addr)
1670 tcc_error_noabort("huh");
1671 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1672 #if SHT_RELX == SHT_RELA
1673 rel->r_addend = sym->st_value;
1674 #else
1675 /* All our REL architectures also happen to be 32bit LE. */
1676 write32le(s1->got->data + offset, sym->st_value);
1677 #endif
1682 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1683 in shared libraries */
1684 static void bind_exe_dynsyms(TCCState *s1)
1686 const char *name;
1687 int sym_index, index;
1688 ElfW(Sym) *sym, *esym;
1689 int type;
1691 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1692 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1693 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1694 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1695 if (sym->st_shndx == SHN_UNDEF) {
1696 name = (char *) symtab_section->link->data + sym->st_name;
1697 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1698 if (sym_index) {
1699 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1700 type = ELFW(ST_TYPE)(esym->st_info);
1701 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1702 /* Indirect functions shall have STT_FUNC type in executable
1703 * dynsym section. Indeed, a dlsym call following a lazy
1704 * resolution would pick the symbol value from the
1705 * executable dynsym entry which would contain the address
1706 * of the function wanted by the caller of dlsym instead of
1707 * the address of the function that would return that
1708 * address */
1709 int dynindex
1710 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1711 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1712 name);
1713 int index = sym - (ElfW(Sym) *) symtab_section->data;
1714 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1715 } else if (type == STT_OBJECT) {
1716 unsigned long offset;
1717 ElfW(Sym) *dynsym;
1718 offset = bss_section->data_offset;
1719 /* XXX: which alignment ? */
1720 offset = (offset + 16 - 1) & -16;
1721 set_elf_sym (s1->symtab, offset, esym->st_size,
1722 esym->st_info, 0, bss_section->sh_num, name);
1723 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1724 esym->st_info, 0, bss_section->sh_num,
1725 name);
1727 /* Ensure R_COPY works for weak symbol aliases */
1728 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1729 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1730 if ((dynsym->st_value == esym->st_value)
1731 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1732 char *dynname = (char *) s1->dynsymtab_section->link->data
1733 + dynsym->st_name;
1734 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1735 dynsym->st_info, 0,
1736 bss_section->sh_num, dynname);
1737 break;
1742 put_elf_reloc(s1->dynsym, bss_section,
1743 offset, R_COPY, index);
1744 offset += esym->st_size;
1745 bss_section->data_offset = offset;
1747 } else {
1748 /* STB_WEAK undefined symbols are accepted */
1749 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1750 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1751 !strcmp(name, "_fp_hw")) {
1752 } else {
1753 tcc_error_noabort("undefined symbol '%s'", name);
1760 /* Bind symbols of libraries: export all non local symbols of executable that
1761 are referenced by shared libraries. The reason is that the dynamic loader
1762 search symbol first in executable and then in libraries. Therefore a
1763 reference to a symbol already defined by a library can still be resolved by
1764 a symbol in the executable. With -rdynamic, export all defined symbols */
1765 static void bind_libs_dynsyms(TCCState *s1)
1767 const char *name;
1768 int dynsym_index;
1769 ElfW(Sym) *sym, *esym;
1771 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1772 name = (char *)symtab_section->link->data + sym->st_name;
1773 dynsym_index = find_elf_sym(s1->dynsymtab_section, name);
1774 if (sym->st_shndx != SHN_UNDEF
1775 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1776 if (dynsym_index || s1->rdynamic)
1777 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1778 sym->st_info, 0, sym->st_shndx, name);
1779 } else if (dynsym_index) {
1780 esym = (ElfW(Sym) *)s1->dynsymtab_section->data + dynsym_index;
1781 if (esym->st_shndx == SHN_UNDEF) {
1782 /* weak symbols can stay undefined */
1783 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1784 tcc_warning("undefined dynamic symbol '%s'", name);
1790 /* Export all non local symbols. This is used by shared libraries so that the
1791 non local symbols they define can resolve a reference in another shared
1792 library or in the executable. Correspondingly, it allows undefined local
1793 symbols to be resolved by other shared libraries or by the executable. */
1794 static void export_global_syms(TCCState *s1)
1796 int dynindex, index;
1797 const char *name;
1798 ElfW(Sym) *sym;
1799 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1800 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1801 name = (char *) symtab_section->link->data + sym->st_name;
1802 dynindex = set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1803 sym->st_info, 0, sym->st_shndx, name);
1804 index = sym - (ElfW(Sym) *) symtab_section->data;
1805 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1810 /* decide if an unallocated section should be output. */
1811 static int set_sec_sizes(TCCState *s1)
1813 int i;
1814 Section *s;
1815 int textrel = 0;
1816 int file_type = s1->output_type;
1818 /* Allocate strings for section names */
1819 for(i = 1; i < s1->nb_sections; i++) {
1820 s = s1->sections[i];
1821 if (s->sh_type == SHT_RELX && !(s->sh_flags & SHF_ALLOC)) {
1822 /* when generating a DLL, we include relocations but
1823 we may patch them */
1824 if ((file_type & TCC_OUTPUT_DYN)
1825 && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) {
1826 int count = prepare_dynamic_rel(s1, s);
1827 if (count) {
1828 /* allocate the section */
1829 s->sh_flags |= SHF_ALLOC;
1830 s->sh_size = count * sizeof(ElfW_Rel);
1831 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1832 textrel += count;
1835 } else if ((s->sh_flags & SHF_ALLOC)
1836 #ifdef TCC_TARGET_ARM
1837 || s->sh_type == SHT_ARM_ATTRIBUTES
1838 #endif
1839 || s1->do_debug) {
1840 s->sh_size = s->data_offset;
1843 #ifdef TCC_TARGET_ARM
1844 /* XXX: Suppress stack unwinding section. */
1845 if (s->sh_type == SHT_ARM_EXIDX) {
1846 s->sh_flags = 0;
1847 s->sh_size = 0;
1849 #endif
1852 return textrel;
1855 /* various data used under elf_output_file() */
1856 struct dyn_inf {
1857 Section *dynamic;
1858 Section *dynstr;
1859 struct {
1860 /* Info to be copied in dynamic section */
1861 unsigned long data_offset;
1862 addr_t rel_addr;
1863 addr_t rel_size;
1866 ElfW(Phdr) *phdr;
1867 int phnum;
1868 Section *interp;
1869 Section *note;
1871 /* read only segment mapping for GNU_RELRO */
1872 Section _roinf, *roinf;
1875 /* Decide the layout of sections loaded in memory. This must be done before
1876 program headers are filled since they contain info about the layout.
1877 We do the following ordering: interp, symbol tables, relocations, progbits,
1878 nobits */
1879 static int sort_sections(TCCState *s1, int *sec_order, Section *interp)
1881 Section *s;
1882 int i, j, k, f, f0, n;
1883 int nb_sections = s1->nb_sections;
1884 int *sec_cls = sec_order + nb_sections;
1886 for (i = 1; i < nb_sections; i++) {
1887 s = s1->sections[i];
1888 if (s->sh_flags & SHF_ALLOC) {
1889 j = 0x100;
1890 if (s->sh_flags & SHF_WRITE)
1891 j = 0x200;
1892 if (s->sh_flags & SHF_TLS)
1893 j += 0x200;
1894 } else if (s->sh_name) {
1895 j = 0x700;
1896 } else {
1897 j = 0x900; /* no sh_name: won't go to file */
1899 if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_DYNSYM) {
1900 k = 0x10;
1901 } else if (s->sh_type == SHT_STRTAB && strcmp(s->name, ".stabstr")) {
1902 k = 0x11;
1903 if (i == nb_sections - 1) /* ".shstrtab" assumed to remain last */
1904 k = 0xff;
1905 } else if (s->sh_type == SHT_HASH) {
1906 k = 0x12;
1907 } else if (s->sh_type == SHT_RELX) {
1908 k = 0x20;
1909 if (s1->plt && s == s1->plt->reloc)
1910 k = 0x21;
1911 } else if (s->sh_type == SHT_PREINIT_ARRAY) {
1912 k = 0x41;
1913 } else if (s->sh_type == SHT_INIT_ARRAY) {
1914 k = 0x42;
1915 } else if (s->sh_type == SHT_FINI_ARRAY) {
1916 k = 0x43;
1917 #ifdef CONFIG_TCC_BCHECK
1918 } else if (s == bounds_section || s == lbounds_section) {
1919 k = 0x44;
1920 #endif
1921 } else if (s == rodata_section || 0 == strcmp(s->name, ".data.rel.ro")) {
1922 k = 0x45;
1923 } else if (s->sh_type == SHT_DYNAMIC) {
1924 k = 0x46;
1925 } else if (s == s1->got) {
1926 k = 0x47; /* .got as RELRO needs BIND_NOW in DT_FLAGS */
1927 } else {
1928 k = 0x50;
1929 if (s->sh_type == SHT_NOTE)
1930 k = 0x60;
1931 if (s->sh_flags & SHF_EXECINSTR)
1932 k = 0x70;
1933 if (s->sh_type == SHT_NOBITS)
1934 k = 0x80;
1935 if (s == interp)
1936 k = 0x00;
1938 k += j;
1940 for (n = i; n > 1 && k < (f = sec_cls[n - 1]); --n)
1941 sec_cls[n] = f, sec_order[n] = sec_order[n - 1];
1942 sec_cls[n] = k, sec_order[n] = i;
1944 sec_order[0] = 0;
1946 /* count PT_LOAD headers needed */
1947 n = f0 = 0;
1948 for (i = 1; i < nb_sections; i++) {
1949 s = s1->sections[sec_order[i]];
1950 k = sec_cls[i];
1951 f = 0;
1952 if (k < 0x700) {
1953 f = s->sh_flags & (SHF_ALLOC|SHF_WRITE|SHF_EXECINSTR|SHF_TLS);
1954 #if TARGETOS_NetBSD
1955 /* NetBSD only supports 2 PT_LOAD sections.
1956 See: https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */
1957 if ((f & SHF_WRITE) == 0) f |= SHF_EXECINSTR;
1958 #else
1959 if ((k & 0xfff0) == 0x240) /* RELRO sections */
1960 f |= 1<<4;
1961 #endif
1962 if (f != f0) /* start new header when flags changed or relro */
1963 f0 = f, ++n, f |= 1<<8;
1965 sec_cls[i] = f;
1966 //printf("ph %d sec %02d : %3X %3X %8.2X %04X %s\n", !!f * n, i, f, k, s->sh_type, s->sh_size, s->name);
1968 return n;
1971 static ElfW(Phdr) *fill_phdr(ElfW(Phdr) *ph, int type, Section *s)
1973 if (s) {
1974 ph->p_offset = s->sh_offset;
1975 ph->p_vaddr = s->sh_addr;
1976 ph->p_filesz = s->sh_size;
1977 ph->p_align = s->sh_addralign;
1979 ph->p_type = type;
1980 ph->p_flags = PF_R;
1981 ph->p_paddr = ph->p_vaddr;
1982 ph->p_memsz = ph->p_filesz;
1983 return ph;
1986 /* Assign sections to segments and decide how are sections laid out when loaded
1987 in memory. This function also fills corresponding program headers. */
1988 static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
1990 Section *s;
1991 addr_t addr, tmp, align, s_align, base;
1992 ElfW(Phdr) *ph = NULL;
1993 int i, f, n, phnum, phfill;
1994 int file_offset;
1996 /* compute number of program headers */
1997 phnum = sort_sections(s1, sec_order, d->interp);
1998 phfill = 0; /* set to 1 to have dll's with a PT_PHDR */
1999 if (d->interp)
2000 phfill = 2;
2001 phnum += phfill;
2002 if (d->note)
2003 ++phnum;
2004 if (d->dynamic)
2005 ++phnum;
2006 if (d->roinf)
2007 ++phnum;
2008 d->phnum = phnum;
2009 d->phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2011 file_offset = 0;
2012 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2013 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2015 s_align = ELF_PAGE_SIZE;
2016 if (s1->section_align)
2017 s_align = s1->section_align;
2019 addr = ELF_START_ADDR;
2020 if (s1->output_type & TCC_OUTPUT_DYN)
2021 addr = 0;
2023 if (s1->has_text_addr) {
2024 addr = s1->text_addr;
2025 if (0) {
2026 int a_offset, p_offset;
2027 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
2028 ELF_PAGE_SIZE */
2029 a_offset = (int) (addr & (s_align - 1));
2030 p_offset = file_offset & (s_align - 1);
2031 if (a_offset < p_offset)
2032 a_offset += s_align;
2033 file_offset += (a_offset - p_offset);
2036 base = addr;
2037 /* compute address after headers */
2038 addr = addr + (file_offset & (s_align - 1));
2040 n = 0;
2041 for(i = 1; i < s1->nb_sections; i++) {
2042 s = s1->sections[sec_order[i]];
2043 f = sec_order[i + s1->nb_sections];
2044 align = s->sh_addralign - 1;
2046 if (f == 0) { /* no alloc */
2047 file_offset = (file_offset + align) & ~align;
2048 s->sh_offset = file_offset;
2049 if (s->sh_type != SHT_NOBITS)
2050 file_offset += s->sh_size;
2051 continue;
2054 if ((f & 1<<8) && n) {
2055 /* different rwx section flags */
2056 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
2057 /* if in the middle of a page, w e duplicate the page in
2058 memory so that one copy is RX and the other is RW */
2059 if ((addr & (s_align - 1)) != 0)
2060 addr += s_align;
2061 } else {
2062 align = s_align - 1;
2066 tmp = addr;
2067 addr = (addr + align) & ~align;
2068 file_offset += (int)(addr - tmp);
2069 s->sh_offset = file_offset;
2070 s->sh_addr = addr;
2072 if (f & 1<<8) {
2073 /* set new program header */
2074 ph = &d->phdr[phfill + n];
2075 ph->p_type = PT_LOAD;
2076 ph->p_align = s_align;
2077 ph->p_flags = PF_R;
2078 if (f & SHF_WRITE)
2079 ph->p_flags |= PF_W;
2080 if (f & SHF_EXECINSTR)
2081 ph->p_flags |= PF_X;
2082 if (f & SHF_TLS) {
2083 ph->p_type = PT_TLS;
2084 ph->p_align = 4;
2086 ph->p_offset = file_offset;
2087 ph->p_vaddr = addr;
2088 if (n == 0) {
2089 /* Make the first PT_LOAD segment include the program
2090 headers itself (and the ELF header as well), it'll
2091 come out with same memory use but will make various
2092 tools like binutils strip work better. */
2093 ph->p_offset = 0;
2094 ph->p_vaddr = base;
2096 ph->p_paddr = ph->p_vaddr;
2097 ++n;
2100 if (f & 1<<4) {
2101 Section *roinf = &d->_roinf;
2102 if (roinf->sh_size == 0) {
2103 roinf->sh_offset = s->sh_offset;
2104 roinf->sh_addr = s->sh_addr;
2105 roinf->sh_addralign = 1;
2107 roinf->sh_size = (addr - roinf->sh_addr) + s->sh_size;
2110 addr += s->sh_size;
2111 if (s->sh_type != SHT_NOBITS)
2112 file_offset += s->sh_size;
2114 ph->p_filesz = file_offset - ph->p_offset;
2115 ph->p_memsz = addr - ph->p_vaddr;
2118 /* Fill other headers */
2119 if (d->note)
2120 fill_phdr(++ph, PT_NOTE, d->note);
2121 if (d->dynamic)
2122 fill_phdr(++ph, PT_DYNAMIC, d->dynamic)->p_flags |= PF_W;
2123 if (d->roinf)
2124 fill_phdr(++ph, PT_GNU_RELRO, d->roinf)->p_flags |= PF_W;
2125 if (d->interp)
2126 fill_phdr(&d->phdr[1], PT_INTERP, d->interp);
2127 if (phfill) {
2128 ph = &d->phdr[0];
2129 ph->p_offset = sizeof(ElfW(Ehdr));
2130 ph->p_vaddr = base + ph->p_offset;
2131 ph->p_filesz = phnum * sizeof(ElfW(Phdr));
2132 ph->p_align = 4;
2133 fill_phdr(ph, PT_PHDR, NULL);
2135 return file_offset;
2138 /* put dynamic tag */
2139 static void put_dt(Section *dynamic, int dt, addr_t val)
2141 ElfW(Dyn) *dyn;
2142 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
2143 dyn->d_tag = dt;
2144 dyn->d_un.d_val = val;
2147 /* Fill the dynamic section with tags describing the address and size of
2148 sections */
2149 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2151 Section *dynamic = dyninf->dynamic;
2152 Section *s;
2154 /* put dynamic section entries */
2155 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2156 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2157 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2158 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2159 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2160 #if PTR_SIZE == 8
2161 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2162 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2163 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2164 if (s1->plt && s1->plt->reloc) {
2165 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2166 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2167 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2168 put_dt(dynamic, DT_PLTREL, DT_RELA);
2170 put_dt(dynamic, DT_RELACOUNT, 0);
2171 #else
2172 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2173 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2174 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2175 if (s1->plt && s1->plt->reloc) {
2176 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2177 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2178 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2179 put_dt(dynamic, DT_PLTREL, DT_REL);
2181 put_dt(dynamic, DT_RELCOUNT, 0);
2182 #endif
2183 if (versym_section && verneed_section) {
2184 /* The dynamic linker can not handle VERSYM without VERNEED */
2185 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2186 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2187 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2189 s = find_section_create (s1, ".preinit_array", 0);
2190 if (s && s->data_offset) {
2191 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2192 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2194 s = find_section_create (s1, ".init_array", 0);
2195 if (s && s->data_offset) {
2196 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2197 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2199 s = find_section_create (s1, ".fini_array", 0);
2200 if (s && s->data_offset) {
2201 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2202 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2204 s = find_section_create (s1, ".init", 0);
2205 if (s && s->data_offset) {
2206 put_dt(dynamic, DT_INIT, s->sh_addr);
2208 s = find_section_create (s1, ".fini", 0);
2209 if (s && s->data_offset) {
2210 put_dt(dynamic, DT_FINI, s->sh_addr);
2212 if (s1->do_debug)
2213 put_dt(dynamic, DT_DEBUG, 0);
2214 put_dt(dynamic, DT_NULL, 0);
2217 /* Remove gaps between RELX sections.
2218 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2219 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2220 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2221 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2222 static void update_reloc_sections(TCCState *s1, struct dyn_inf *dyninf)
2224 int i;
2225 unsigned long file_offset = 0;
2226 Section *s;
2227 Section *relocplt = s1->plt ? s1->plt->reloc : NULL;
2229 /* dynamic relocation table information, for .dynamic section */
2230 dyninf->rel_addr = dyninf->rel_size = 0;
2232 for(i = 1; i < s1->nb_sections; i++) {
2233 s = s1->sections[i];
2234 if (s->sh_type == SHT_RELX && s != relocplt) {
2235 if (dyninf->rel_size == 0) {
2236 dyninf->rel_addr = s->sh_addr;
2237 file_offset = s->sh_offset;
2239 else {
2240 s->sh_addr = dyninf->rel_addr + dyninf->rel_size;
2241 s->sh_offset = file_offset + dyninf->rel_size;
2243 dyninf->rel_size += s->sh_size;
2248 static int tidy_section_headers(TCCState *s1, int *sec_order);
2249 #endif /* ndef ELF_OBJ_ONLY */
2251 /* Create an ELF file on disk.
2252 This function handle ELF specific layout requirements */
2253 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2254 int file_offset, int *sec_order)
2256 int i, shnum, offset, size, file_type;
2257 Section *s;
2258 ElfW(Ehdr) ehdr;
2259 ElfW(Shdr) shdr, *sh;
2261 file_type = s1->output_type;
2262 shnum = s1->nb_sections;
2264 memset(&ehdr, 0, sizeof(ehdr));
2266 if (phnum > 0) {
2267 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2268 ehdr.e_phnum = phnum;
2269 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2270 #ifndef ELF_OBJ_ONLY
2271 shnum = tidy_section_headers(s1, sec_order);
2272 #endif
2275 /* align to 4 */
2276 file_offset = (file_offset + 3) & -4;
2278 /* fill header */
2279 ehdr.e_ident[0] = ELFMAG0;
2280 ehdr.e_ident[1] = ELFMAG1;
2281 ehdr.e_ident[2] = ELFMAG2;
2282 ehdr.e_ident[3] = ELFMAG3;
2283 ehdr.e_ident[4] = ELFCLASSW;
2284 ehdr.e_ident[5] = ELFDATA2LSB;
2285 ehdr.e_ident[6] = EV_CURRENT;
2287 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2288 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2289 #elif defined TCC_TARGET_ARM && defined TCC_ARM_EABI
2290 ehdr.e_flags = EF_ARM_EABI_VER5;
2291 ehdr.e_flags |= s1->float_abi == ARM_HARD_FLOAT
2292 ? EF_ARM_VFP_FLOAT : EF_ARM_SOFT_FLOAT;
2293 #elif defined TCC_TARGET_ARM
2294 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2295 #elif defined TCC_TARGET_RISCV64
2296 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2297 #endif
2299 if (file_type == TCC_OUTPUT_OBJ) {
2300 ehdr.e_type = ET_REL;
2301 } else {
2302 if (file_type & TCC_OUTPUT_DYN)
2303 ehdr.e_type = ET_DYN;
2304 else
2305 ehdr.e_type = ET_EXEC;
2306 if (s1->elf_entryname)
2307 ehdr.e_entry = get_sym_addr(s1, s1->elf_entryname, 1, 0);
2308 else
2309 ehdr.e_entry = get_sym_addr(s1, "_start", !!(file_type & TCC_OUTPUT_EXE), 0);
2310 if (ehdr.e_entry == (addr_t)-1)
2311 ehdr.e_entry = text_section->sh_addr;
2314 ehdr.e_machine = EM_TCC_TARGET;
2315 ehdr.e_version = EV_CURRENT;
2316 ehdr.e_shoff = file_offset;
2317 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2318 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2319 ehdr.e_shnum = shnum;
2320 ehdr.e_shstrndx = shnum - 1;
2322 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2323 if (phdr)
2324 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2325 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2327 sort_syms(s1, symtab_section);
2328 for(i = 1; i < shnum; i++) {
2329 s = s1->sections[sec_order ? sec_order[i] : i];
2330 if (s->sh_type != SHT_NOBITS) {
2331 while (offset < s->sh_offset) {
2332 fputc(0, f);
2333 offset++;
2335 size = s->sh_size;
2336 if (size)
2337 fwrite(s->data, 1, size, f);
2338 offset += size;
2342 /* output section headers */
2343 while (offset < ehdr.e_shoff) {
2344 fputc(0, f);
2345 offset++;
2348 for(i = 0; i < shnum; i++) {
2349 sh = &shdr;
2350 memset(sh, 0, sizeof(ElfW(Shdr)));
2351 s = s1->sections[i];
2352 if (s) {
2353 sh->sh_name = s->sh_name;
2354 sh->sh_type = s->sh_type;
2355 sh->sh_flags = s->sh_flags;
2356 sh->sh_entsize = s->sh_entsize;
2357 sh->sh_info = s->sh_info;
2358 if (s->link)
2359 sh->sh_link = s->link->sh_num;
2360 sh->sh_addralign = s->sh_addralign;
2361 sh->sh_addr = s->sh_addr;
2362 sh->sh_offset = s->sh_offset;
2363 sh->sh_size = s->sh_size;
2365 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2369 static void tcc_output_binary(TCCState *s1, FILE *f,
2370 const int *sec_order)
2372 Section *s;
2373 int i, offset, size;
2375 offset = 0;
2376 for(i=1;i<s1->nb_sections;i++) {
2377 s = s1->sections[sec_order[i]];
2378 if (s->sh_type != SHT_NOBITS &&
2379 (s->sh_flags & SHF_ALLOC)) {
2380 while (offset < s->sh_offset) {
2381 fputc(0, f);
2382 offset++;
2384 size = s->sh_size;
2385 fwrite(s->data, 1, size, f);
2386 offset += size;
2391 /* Write an elf, coff or "binary" file */
2392 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2393 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2395 int fd, mode, file_type;
2396 FILE *f;
2398 file_type = s1->output_type;
2399 if (file_type == TCC_OUTPUT_OBJ)
2400 mode = 0666;
2401 else
2402 mode = 0777;
2403 unlink(filename);
2404 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2405 if (fd < 0 || (f = fdopen(fd, "wb")) == NULL) {
2406 tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno));
2407 return -1;
2409 if (s1->verbose)
2410 printf("<- %s\n", filename);
2412 #ifdef TCC_TARGET_COFF
2413 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2414 tcc_output_coff(s1, f);
2415 else
2416 #endif
2417 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2418 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2419 else
2420 tcc_output_binary(s1, f, sec_order);
2421 fclose(f);
2423 return 0;
2426 #ifndef ELF_OBJ_ONLY
2427 /* Sort section headers by assigned sh_addr, remove sections
2428 that we aren't going to output. */
2429 static int tidy_section_headers(TCCState *s1, int *sec_order)
2431 int i, nnew, l, *backmap;
2432 Section **snew, *s;
2433 ElfW(Sym) *sym;
2435 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2436 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2437 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2438 s = s1->sections[sec_order[i]];
2439 if (!i || s->sh_name) {
2440 backmap[sec_order[i]] = nnew;
2441 snew[nnew] = s;
2442 ++nnew;
2443 } else {
2444 backmap[sec_order[i]] = 0;
2445 snew[--l] = s;
2448 for (i = 0; i < nnew; i++) {
2449 s = snew[i];
2450 if (s) {
2451 s->sh_num = i;
2452 if (s->sh_type == SHT_RELX)
2453 s->sh_info = backmap[s->sh_info];
2457 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2458 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2459 sym->st_shndx = backmap[sym->st_shndx];
2460 if ( !s1->static_link ) {
2461 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2462 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2463 sym->st_shndx = backmap[sym->st_shndx];
2465 for (i = 0; i < s1->nb_sections; i++)
2466 sec_order[i] = i;
2467 tcc_free(s1->sections);
2468 s1->sections = snew;
2469 tcc_free(backmap);
2470 return nnew;
2473 #ifdef TCC_TARGET_ARM
2474 static void create_arm_attribute_section(TCCState *s1)
2476 // Needed for DLL support.
2477 static const unsigned char arm_attr[] = {
2478 0x41, // 'A'
2479 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2480 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2481 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2482 0x05, 0x36, 0x00, // 'CPU_name', "6"
2483 0x06, 0x06, // 'CPU_arch', 'v6'
2484 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2485 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2486 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2487 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2488 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2489 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2490 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2491 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2492 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2493 0x1a, 0x02, // 'ABI_enum_size', 'int'
2494 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2495 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2497 Section *attr = new_section(s1, ".ARM.attributes", SHT_ARM_ATTRIBUTES, 0);
2498 unsigned char *ptr = section_ptr_add(attr, sizeof(arm_attr));
2499 attr->sh_addralign = 1;
2500 memcpy(ptr, arm_attr, sizeof(arm_attr));
2501 if (s1->float_abi != ARM_HARD_FLOAT) {
2502 ptr[26] = 0x00; // 'FP_arch', 'No'
2503 ptr[41] = 0x1e; // 'ABI_optimization_goals'
2504 ptr[42] = 0x06; // 'Aggressive Debug'
2507 #endif
2509 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2510 static Section *create_bsd_note_section(TCCState *s1,
2511 const char *name,
2512 const char *value)
2514 Section *s = find_section (s1, name);
2516 if (s->data_offset == 0) {
2517 char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
2518 ElfW(Nhdr) *note = (ElfW(Nhdr) *) ptr;
2520 s->sh_type = SHT_NOTE;
2521 note->n_namesz = 8;
2522 note->n_descsz = 4;
2523 note->n_type = ELF_NOTE_OS_GNU;
2524 strcpy (ptr + sizeof(ElfW(Nhdr)), value);
2526 return s;
2528 #endif
2530 static void alloc_sec_names(TCCState *s1, int is_obj);
2532 /* Output an elf, coff or binary file */
2533 /* XXX: suppress unneeded sections */
2534 static int elf_output_file(TCCState *s1, const char *filename)
2536 int i, ret, file_type, file_offset, *sec_order;
2537 struct dyn_inf dyninf = {0};
2538 Section *interp, *dynstr, *dynamic;
2539 int textrel, got_sym, dt_flags_1;
2541 file_type = s1->output_type;
2542 s1->nb_errors = 0;
2543 ret = -1;
2544 interp = dynstr = dynamic = NULL;
2545 sec_order = NULL;
2546 dyninf.roinf = &dyninf._roinf;
2548 #ifdef TCC_TARGET_ARM
2549 create_arm_attribute_section (s1);
2550 #endif
2552 #if TARGETOS_OpenBSD
2553 dyninf.note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
2554 #endif
2556 #if TARGETOS_NetBSD
2557 dyninf.note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD");
2558 #endif
2560 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
2561 dyninf.roinf = NULL;
2562 #endif
2563 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2564 tcc_add_runtime(s1);
2565 resolve_common_syms(s1);
2567 if (!s1->static_link) {
2568 if (file_type & TCC_OUTPUT_EXE) {
2569 char *ptr;
2570 /* allow override the dynamic loader */
2571 const char *elfint = getenv("LD_SO");
2572 if (elfint == NULL)
2573 elfint = DEFAULT_ELFINTERP(s1);
2574 /* add interpreter section only if executable */
2575 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2576 interp->sh_addralign = 1;
2577 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2578 strcpy(ptr, elfint);
2579 dyninf.interp = interp;
2582 /* add dynamic symbol table */
2583 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2584 ".dynstr",
2585 ".hash", SHF_ALLOC);
2586 /* Number of local symbols (readelf complains if not set) */
2587 s1->dynsym->sh_info = 1;
2588 dynstr = s1->dynsym->link;
2589 /* add dynamic section */
2590 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2591 SHF_ALLOC | SHF_WRITE);
2592 dynamic->link = dynstr;
2593 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2595 got_sym = build_got(s1);
2596 if (file_type == TCC_OUTPUT_EXE) {
2597 bind_exe_dynsyms(s1);
2598 if (s1->nb_errors)
2599 goto the_end;
2601 build_got_entries(s1, got_sym);
2602 if (file_type & TCC_OUTPUT_EXE) {
2603 bind_libs_dynsyms(s1);
2604 } else {
2605 /* shared library case: simply export all global symbols */
2606 export_global_syms(s1);
2608 } else {
2609 build_got_entries(s1, 0);
2611 version_add (s1);
2613 textrel = set_sec_sizes(s1);
2614 alloc_sec_names(s1, 0);
2616 if (!s1->static_link) {
2617 /* add a list of needed dlls */
2618 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2619 DLLReference *dllref = s1->loaded_dlls[i];
2620 if (dllref->level == 0)
2621 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2624 if (s1->rpath)
2625 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2626 put_elf_str(dynstr, s1->rpath));
2628 dt_flags_1 = DF_1_NOW;
2629 if (file_type & TCC_OUTPUT_DYN) {
2630 if (s1->soname)
2631 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2632 /* XXX: currently, since we do not handle PIC code, we
2633 must relocate the readonly segments */
2634 if (textrel)
2635 put_dt(dynamic, DT_TEXTREL, 0);
2636 if (file_type & TCC_OUTPUT_EXE)
2637 dt_flags_1 = DF_1_NOW | DF_1_PIE;
2639 put_dt(dynamic, DT_FLAGS, DF_BIND_NOW);
2640 put_dt(dynamic, DT_FLAGS_1, dt_flags_1);
2641 if (s1->symbolic)
2642 put_dt(dynamic, DT_SYMBOLIC, 0);
2644 dyninf.dynamic = dynamic;
2645 dyninf.dynstr = dynstr;
2646 /* remember offset and reserve space for 2nd call below */
2647 dyninf.data_offset = dynamic->data_offset;
2648 fill_dynamic(s1, &dyninf);
2649 dynamic->sh_size = dynamic->data_offset;
2650 dynstr->sh_size = dynstr->data_offset;
2653 /* this array is used to reorder sections in the output file */
2654 sec_order = tcc_malloc(sizeof(int) * 2 * s1->nb_sections);
2655 /* compute section to program header mapping */
2656 file_offset = layout_sections(s1, sec_order, &dyninf);
2658 if (dynamic) {
2659 ElfW(Sym) *sym;
2661 /* put in GOT the dynamic section address and relocate PLT */
2662 write32le(s1->got->data, dynamic->sh_addr);
2663 if (file_type == TCC_OUTPUT_EXE
2664 || (RELOCATE_DLLPLT && (file_type & TCC_OUTPUT_DYN)))
2665 relocate_plt(s1);
2667 /* relocate symbols in .dynsym now that final addresses are known */
2668 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2669 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2670 /* do symbol relocation */
2671 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2676 /* if building executable or DLL, then relocate each section
2677 except the GOT which is already relocated */
2678 relocate_syms(s1, s1->symtab, 0);
2679 if (s1->nb_errors != 0)
2680 goto the_end;
2681 relocate_sections(s1);
2682 if (dynamic) {
2683 update_reloc_sections (s1, &dyninf);
2684 dynamic->data_offset = dyninf.data_offset;
2685 fill_dynamic(s1, &dyninf);
2687 /* Perform relocation to GOT or PLT entries */
2688 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2689 fill_got(s1);
2690 else if (s1->got)
2691 fill_local_got_entries(s1);
2693 /* Create the ELF file with name 'filename' */
2694 ret = tcc_write_elf_file(s1, filename, dyninf.phnum, dyninf.phdr, file_offset, sec_order);
2695 the_end:
2696 tcc_free(sec_order);
2697 tcc_free(dyninf.phdr);
2698 return ret;
2700 #endif /* ndef ELF_OBJ_ONLY */
2702 /* Allocate strings for section names */
2703 static void alloc_sec_names(TCCState *s1, int is_obj)
2705 int i;
2706 Section *s, *strsec;
2708 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2709 put_elf_str(strsec, "");
2710 for(i = 1; i < s1->nb_sections; i++) {
2711 s = s1->sections[i];
2712 if (is_obj)
2713 s->sh_size = s->data_offset;
2714 if (s == strsec || s->sh_size || (s->sh_flags & SHF_ALLOC))
2715 s->sh_name = put_elf_str(strsec, s->name);
2717 strsec->sh_size = strsec->data_offset;
2720 /* Output an elf .o file */
2721 static int elf_output_obj(TCCState *s1, const char *filename)
2723 Section *s;
2724 int i, ret, file_offset;
2725 s1->nb_errors = 0;
2726 /* Allocate strings for section names */
2727 alloc_sec_names(s1, 1);
2728 file_offset = sizeof (ElfW(Ehdr));
2729 for(i = 1; i < s1->nb_sections; i++) {
2730 s = s1->sections[i];
2731 file_offset = (file_offset + 15) & -16;
2732 s->sh_offset = file_offset;
2733 if (s->sh_type != SHT_NOBITS)
2734 file_offset += s->sh_size;
2736 /* Create the ELF file with name 'filename' */
2737 ret = tcc_write_elf_file(s1, filename, 0, NULL, file_offset, NULL);
2738 return ret;
2741 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2743 if (s->test_coverage)
2744 tcc_tcov_add_file(s, filename);
2745 if (s->output_type == TCC_OUTPUT_OBJ)
2746 return elf_output_obj(s, filename);
2747 #ifdef TCC_TARGET_PE
2748 return pe_output_file(s, filename);
2749 #elif TCC_TARGET_MACHO
2750 return macho_output_file(s, filename);
2751 #else
2752 return elf_output_file(s, filename);
2753 #endif
2756 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
2757 char *cbuf = buf;
2758 size_t rnum = 0;
2759 while (1) {
2760 ssize_t num = read(fd, cbuf, count-rnum);
2761 if (num < 0) return num;
2762 if (num == 0) return rnum;
2763 rnum += num;
2764 cbuf += num;
2768 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
2770 void *data;
2772 data = tcc_malloc(size);
2773 lseek(fd, file_offset, SEEK_SET);
2774 full_read(fd, data, size);
2775 return data;
2778 typedef struct SectionMergeInfo {
2779 Section *s; /* corresponding existing section */
2780 unsigned long offset; /* offset of the new section in the existing section */
2781 uint8_t new_section; /* true if section 's' was added */
2782 uint8_t link_once; /* true if link once section */
2783 } SectionMergeInfo;
2785 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2787 int size = full_read(fd, h, sizeof *h);
2788 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2789 if (h->e_type == ET_REL)
2790 return AFF_BINTYPE_REL;
2791 if (h->e_type == ET_DYN)
2792 return AFF_BINTYPE_DYN;
2793 } else if (size >= 8) {
2794 if (0 == memcmp(h, ARMAG, 8))
2795 return AFF_BINTYPE_AR;
2796 #ifdef TCC_TARGET_COFF
2797 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2798 return AFF_BINTYPE_C67;
2799 #endif
2801 return 0;
2804 /* load an object file and merge it with current files */
2805 /* XXX: handle correctly stab (debug) info */
2806 ST_FUNC int tcc_load_object_file(TCCState *s1,
2807 int fd, unsigned long file_offset)
2809 ElfW(Ehdr) ehdr;
2810 ElfW(Shdr) *shdr, *sh;
2811 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2812 char *strsec, *strtab;
2813 int stab_index, stabstr_index;
2814 int *old_to_new_syms;
2815 char *sh_name, *name;
2816 SectionMergeInfo *sm_table, *sm;
2817 ElfW(Sym) *sym, *symtab;
2818 ElfW_Rel *rel;
2819 Section *s;
2821 lseek(fd, file_offset, SEEK_SET);
2822 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2823 goto fail1;
2824 /* test CPU specific stuff */
2825 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2826 ehdr.e_machine != EM_TCC_TARGET) {
2827 fail1:
2828 tcc_error_noabort("invalid object file");
2829 return -1;
2831 /* read sections */
2832 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2833 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2834 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2836 /* load section names */
2837 sh = &shdr[ehdr.e_shstrndx];
2838 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2840 /* load symtab and strtab */
2841 old_to_new_syms = NULL;
2842 symtab = NULL;
2843 strtab = NULL;
2844 nb_syms = 0;
2845 seencompressed = 0;
2846 stab_index = stabstr_index = 0;
2848 for(i = 1; i < ehdr.e_shnum; i++) {
2849 sh = &shdr[i];
2850 if (sh->sh_type == SHT_SYMTAB) {
2851 if (symtab) {
2852 tcc_error_noabort("object must contain only one symtab");
2853 fail:
2854 ret = -1;
2855 goto the_end;
2857 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2858 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2859 sm_table[i].s = symtab_section;
2861 /* now load strtab */
2862 sh = &shdr[sh->sh_link];
2863 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2865 if (sh->sh_flags & SHF_COMPRESSED)
2866 seencompressed = 1;
2869 /* now examine each section and try to merge its content with the
2870 ones in memory */
2871 for(i = 1; i < ehdr.e_shnum; i++) {
2872 /* no need to examine section name strtab */
2873 if (i == ehdr.e_shstrndx)
2874 continue;
2875 sh = &shdr[i];
2876 if (sh->sh_type == SHT_RELX)
2877 sh = &shdr[sh->sh_info];
2878 /* ignore sections types we do not handle (plus relocs to those) */
2879 if (sh->sh_type != SHT_PROGBITS &&
2880 #ifdef TCC_ARM_EABI
2881 sh->sh_type != SHT_ARM_EXIDX &&
2882 #endif
2883 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2884 sh->sh_type != SHT_X86_64_UNWIND &&
2885 #endif
2886 sh->sh_type != SHT_NOTE &&
2887 sh->sh_type != SHT_NOBITS &&
2888 sh->sh_type != SHT_PREINIT_ARRAY &&
2889 sh->sh_type != SHT_INIT_ARRAY &&
2890 sh->sh_type != SHT_FINI_ARRAY &&
2891 strcmp(strsec + sh->sh_name, ".stabstr")
2893 continue;
2894 if (seencompressed && 0 == strncmp(strsec + sh->sh_name, ".debug_", 7))
2895 continue;
2897 sh = &shdr[i];
2898 sh_name = strsec + sh->sh_name;
2899 if (sh->sh_addralign < 1)
2900 sh->sh_addralign = 1;
2901 /* find corresponding section, if any */
2902 for(j = 1; j < s1->nb_sections;j++) {
2903 s = s1->sections[j];
2904 if (!strcmp(s->name, sh_name)) {
2905 if (!strncmp(sh_name, ".gnu.linkonce",
2906 sizeof(".gnu.linkonce") - 1)) {
2907 /* if a 'linkonce' section is already present, we
2908 do not add it again. It is a little tricky as
2909 symbols can still be defined in
2910 it. */
2911 sm_table[i].link_once = 1;
2912 goto next;
2914 if (stab_section) {
2915 if (s == stab_section)
2916 stab_index = i;
2917 if (s == stab_section->link)
2918 stabstr_index = i;
2920 goto found;
2923 /* not found: create new section */
2924 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2925 /* take as much info as possible from the section. sh_link and
2926 sh_info will be updated later */
2927 s->sh_addralign = sh->sh_addralign;
2928 s->sh_entsize = sh->sh_entsize;
2929 sm_table[i].new_section = 1;
2930 found:
2931 if (sh->sh_type != s->sh_type) {
2932 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2933 if (strcmp (s->name, ".eh_frame"))
2934 #endif
2936 tcc_error_noabort("invalid section type");
2937 goto fail;
2940 /* align start of section */
2941 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
2942 if (sh->sh_addralign > s->sh_addralign)
2943 s->sh_addralign = sh->sh_addralign;
2944 sm_table[i].offset = s->data_offset;
2945 sm_table[i].s = s;
2946 /* concatenate sections */
2947 size = sh->sh_size;
2948 if (sh->sh_type != SHT_NOBITS) {
2949 unsigned char *ptr;
2950 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2951 ptr = section_ptr_add(s, size);
2952 full_read(fd, ptr, size);
2953 } else {
2954 s->data_offset += size;
2956 next: ;
2959 /* gr relocate stab strings */
2960 if (stab_index && stabstr_index) {
2961 Stab_Sym *a, *b;
2962 unsigned o;
2963 s = sm_table[stab_index].s;
2964 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2965 b = (Stab_Sym *)(s->data + s->data_offset);
2966 o = sm_table[stabstr_index].offset;
2967 while (a < b) {
2968 if (a->n_strx)
2969 a->n_strx += o;
2970 a++;
2974 /* second short pass to update sh_link and sh_info fields of new
2975 sections */
2976 for(i = 1; i < ehdr.e_shnum; i++) {
2977 s = sm_table[i].s;
2978 if (!s || !sm_table[i].new_section)
2979 continue;
2980 sh = &shdr[i];
2981 if (sh->sh_link > 0)
2982 s->link = sm_table[sh->sh_link].s;
2983 if (sh->sh_type == SHT_RELX) {
2984 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2985 /* update backward link */
2986 s1->sections[s->sh_info]->reloc = s;
2990 /* resolve symbols */
2991 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2993 sym = symtab + 1;
2994 for(i = 1; i < nb_syms; i++, sym++) {
2995 if (sym->st_shndx != SHN_UNDEF &&
2996 sym->st_shndx < SHN_LORESERVE) {
2997 sm = &sm_table[sym->st_shndx];
2998 if (sm->link_once) {
2999 /* if a symbol is in a link once section, we use the
3000 already defined symbol. It is very important to get
3001 correct relocations */
3002 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
3003 name = strtab + sym->st_name;
3004 sym_index = find_elf_sym(symtab_section, name);
3005 if (sym_index)
3006 old_to_new_syms[i] = sym_index;
3008 continue;
3010 /* if no corresponding section added, no need to add symbol */
3011 if (!sm->s)
3012 continue;
3013 /* convert section number */
3014 sym->st_shndx = sm->s->sh_num;
3015 /* offset value */
3016 sym->st_value += sm->offset;
3018 /* add symbol */
3019 name = strtab + sym->st_name;
3020 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
3021 sym->st_info, sym->st_other,
3022 sym->st_shndx, name);
3023 old_to_new_syms[i] = sym_index;
3026 /* third pass to patch relocation entries */
3027 for(i = 1; i < ehdr.e_shnum; i++) {
3028 s = sm_table[i].s;
3029 if (!s)
3030 continue;
3031 sh = &shdr[i];
3032 offset = sm_table[i].offset;
3033 size = sh->sh_size;
3034 switch(s->sh_type) {
3035 case SHT_RELX:
3036 /* take relocation offset information */
3037 offseti = sm_table[sh->sh_info].offset;
3038 for (rel = (ElfW_Rel *) s->data + (offset / sizeof(*rel));
3039 rel < (ElfW_Rel *) s->data + ((offset + size) / sizeof(*rel));
3040 rel++) {
3041 int type;
3042 unsigned sym_index;
3043 /* convert symbol index */
3044 type = ELFW(R_TYPE)(rel->r_info);
3045 sym_index = ELFW(R_SYM)(rel->r_info);
3046 /* NOTE: only one symtab assumed */
3047 if (sym_index >= nb_syms)
3048 goto invalid_reloc;
3049 sym_index = old_to_new_syms[sym_index];
3050 /* ignore link_once in rel section. */
3051 if (!sym_index && !sm_table[sh->sh_info].link_once
3052 #ifdef TCC_TARGET_ARM
3053 && type != R_ARM_V4BX
3054 #elif defined TCC_TARGET_RISCV64
3055 && type != R_RISCV_ALIGN
3056 && type != R_RISCV_RELAX
3057 #endif
3059 invalid_reloc:
3060 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3061 i, strsec + sh->sh_name, (int)rel->r_offset);
3062 goto fail;
3064 rel->r_info = ELFW(R_INFO)(sym_index, type);
3065 /* offset the relocation offset */
3066 rel->r_offset += offseti;
3067 #ifdef TCC_TARGET_ARM
3068 /* Jumps and branches from a Thumb code to a PLT entry need
3069 special handling since PLT entries are ARM code.
3070 Unconditional bl instructions referencing PLT entries are
3071 handled by converting these instructions into blx
3072 instructions. Other case of instructions referencing a PLT
3073 entry require to add a Thumb stub before the PLT entry to
3074 switch to ARM mode. We set bit plt_thumb_stub of the
3075 attribute of a symbol to indicate such a case. */
3076 if (type == R_ARM_THM_JUMP24)
3077 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
3078 #endif
3080 break;
3081 default:
3082 break;
3086 ret = 0;
3087 the_end:
3088 tcc_free(symtab);
3089 tcc_free(strtab);
3090 tcc_free(old_to_new_syms);
3091 tcc_free(sm_table);
3092 tcc_free(strsec);
3093 tcc_free(shdr);
3094 return ret;
3097 typedef struct ArchiveHeader {
3098 char ar_name[16]; /* name of this member */
3099 char ar_date[12]; /* file mtime */
3100 char ar_uid[6]; /* owner uid; printed as decimal */
3101 char ar_gid[6]; /* owner gid; printed as decimal */
3102 char ar_mode[8]; /* file mode, printed as octal */
3103 char ar_size[10]; /* file size, printed as decimal */
3104 char ar_fmag[2]; /* should contain ARFMAG */
3105 } ArchiveHeader;
3107 #define ARFMAG "`\n"
3109 static unsigned long long get_be(const uint8_t *b, int n)
3111 unsigned long long ret = 0;
3112 while (n)
3113 ret = (ret << 8) | *b++, --n;
3114 return ret;
3117 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
3119 char *p, *e;
3120 int len;
3121 lseek(fd, offset, SEEK_SET);
3122 len = full_read(fd, hdr, sizeof(ArchiveHeader));
3123 if (len != sizeof(ArchiveHeader))
3124 return len ? -1 : 0;
3125 p = hdr->ar_name;
3126 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
3127 --e;
3128 *e = '\0';
3129 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
3130 return len;
3133 /* load only the objects which resolve undefined symbols */
3134 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
3136 int i, bound, nsyms, sym_index, len, ret = -1;
3137 unsigned long long off;
3138 uint8_t *data;
3139 const char *ar_names, *p;
3140 const uint8_t *ar_index;
3141 ElfW(Sym) *sym;
3142 ArchiveHeader hdr;
3144 data = tcc_malloc(size);
3145 if (full_read(fd, data, size) != size)
3146 goto the_end;
3147 nsyms = get_be(data, entrysize);
3148 ar_index = data + entrysize;
3149 ar_names = (char *) ar_index + nsyms * entrysize;
3151 do {
3152 bound = 0;
3153 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
3154 Section *s = symtab_section;
3155 sym_index = find_elf_sym(s, p);
3156 if (!sym_index)
3157 continue;
3158 sym = &((ElfW(Sym) *)s->data)[sym_index];
3159 if(sym->st_shndx != SHN_UNDEF)
3160 continue;
3161 off = get_be(ar_index + i * entrysize, entrysize);
3162 len = read_ar_header(fd, off, &hdr);
3163 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
3164 tcc_error_noabort("invalid archive");
3165 goto the_end;
3167 off += len;
3168 if (s1->verbose == 2)
3169 printf(" -> %s\n", hdr.ar_name);
3170 if (tcc_load_object_file(s1, fd, off) < 0)
3171 goto the_end;
3172 ++bound;
3174 } while(bound);
3175 ret = 0;
3176 the_end:
3177 tcc_free(data);
3178 return ret;
3181 /* load a '.a' file */
3182 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
3184 ArchiveHeader hdr;
3185 /* char magic[8]; */
3186 int size, len;
3187 unsigned long file_offset;
3188 ElfW(Ehdr) ehdr;
3190 /* skip magic which was already checked */
3191 /* full_read(fd, magic, sizeof(magic)); */
3192 file_offset = sizeof ARMAG - 1;
3194 for(;;) {
3195 len = read_ar_header(fd, file_offset, &hdr);
3196 if (len == 0)
3197 return 0;
3198 if (len < 0) {
3199 tcc_error_noabort("invalid archive");
3200 return -1;
3202 file_offset += len;
3203 size = strtol(hdr.ar_size, NULL, 0);
3204 /* align to even */
3205 size = (size + 1) & ~1;
3206 if (alacarte) {
3207 /* coff symbol table : we handle it */
3208 if (!strcmp(hdr.ar_name, "/"))
3209 return tcc_load_alacarte(s1, fd, size, 4);
3210 if (!strcmp(hdr.ar_name, "/SYM64/"))
3211 return tcc_load_alacarte(s1, fd, size, 8);
3212 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3213 if (s1->verbose == 2)
3214 printf(" -> %s\n", hdr.ar_name);
3215 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3216 return -1;
3218 file_offset += size;
3222 #ifndef ELF_OBJ_ONLY
3223 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3224 LV, maybe create a new entry for (LIB,VERSION). */
3225 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3227 while (i >= *n) {
3228 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3229 (*lv)[(*n)++] = -1;
3231 if ((*lv)[i] == -1) {
3232 int v, prev_same_lib = -1;
3233 for (v = 0; v < nb_sym_versions; v++) {
3234 if (strcmp(sym_versions[v].lib, lib))
3235 continue;
3236 prev_same_lib = v;
3237 if (!strcmp(sym_versions[v].version, version))
3238 break;
3240 if (v == nb_sym_versions) {
3241 sym_versions = tcc_realloc (sym_versions,
3242 (v + 1) * sizeof(*sym_versions));
3243 sym_versions[v].lib = tcc_strdup(lib);
3244 sym_versions[v].version = tcc_strdup(version);
3245 sym_versions[v].out_index = 0;
3246 sym_versions[v].prev_same_lib = prev_same_lib;
3247 nb_sym_versions++;
3249 (*lv)[i] = v;
3253 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3254 VERNDX. */
3255 static void
3256 set_sym_version(TCCState *s1, int sym_index, int verndx)
3258 if (sym_index >= nb_sym_to_version) {
3259 int newelems = sym_index ? sym_index * 2 : 1;
3260 sym_to_version = tcc_realloc(sym_to_version,
3261 newelems * sizeof(*sym_to_version));
3262 memset(sym_to_version + nb_sym_to_version, -1,
3263 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3264 nb_sym_to_version = newelems;
3266 if (sym_to_version[sym_index] < 0)
3267 sym_to_version[sym_index] = verndx;
3270 struct versym_info {
3271 int nb_versyms;
3272 ElfW(Verdef) *verdef;
3273 ElfW(Verneed) *verneed;
3274 ElfW(Half) *versym;
3275 int nb_local_ver, *local_ver;
3279 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3281 char *lib, *version;
3282 uint32_t next;
3283 int i;
3285 #define DEBUG_VERSION 0
3287 if (v->versym && v->verdef) {
3288 ElfW(Verdef) *vdef = v->verdef;
3289 lib = NULL;
3290 do {
3291 ElfW(Verdaux) *verdaux =
3292 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3294 #if DEBUG_VERSION
3295 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3296 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3297 vdef->vd_hash);
3298 #endif
3299 if (vdef->vd_cnt) {
3300 version = dynstr + verdaux->vda_name;
3302 if (lib == NULL)
3303 lib = version;
3304 else
3305 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3306 lib, version);
3307 #if DEBUG_VERSION
3308 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3309 #endif
3311 next = vdef->vd_next;
3312 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3313 } while (next);
3315 if (v->versym && v->verneed) {
3316 ElfW(Verneed) *vneed = v->verneed;
3317 do {
3318 ElfW(Vernaux) *vernaux =
3319 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3321 lib = dynstr + vneed->vn_file;
3322 #if DEBUG_VERSION
3323 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3324 #endif
3325 for (i = 0; i < vneed->vn_cnt; i++) {
3326 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3327 version = dynstr + vernaux->vna_name;
3328 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3329 lib, version);
3330 #if DEBUG_VERSION
3331 printf (" vernaux(%u): %u %u %s\n",
3332 vernaux->vna_other, vernaux->vna_hash,
3333 vernaux->vna_flags, version);
3334 #endif
3336 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3338 next = vneed->vn_next;
3339 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3340 } while (next);
3343 #if DEBUG_VERSION
3344 for (i = 0; i < v->nb_local_ver; i++) {
3345 if (v->local_ver[i] > 0) {
3346 printf ("%d: lib: %s, version %s\n",
3347 i, sym_versions[v->local_ver[i]].lib,
3348 sym_versions[v->local_ver[i]].version);
3351 #endif
3354 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3355 is referenced by the user (so it should be added as DT_NEEDED in
3356 the generated ELF file) */
3357 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3359 ElfW(Ehdr) ehdr;
3360 ElfW(Shdr) *shdr, *sh, *sh1;
3361 int i, nb_syms, nb_dts, sym_bind, ret = -1;
3362 ElfW(Sym) *sym, *dynsym;
3363 ElfW(Dyn) *dt, *dynamic;
3365 char *dynstr;
3366 int sym_index;
3367 const char *name, *soname;
3368 struct versym_info v;
3370 full_read(fd, &ehdr, sizeof(ehdr));
3372 /* test CPU specific stuff */
3373 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3374 ehdr.e_machine != EM_TCC_TARGET) {
3375 tcc_error_noabort("bad architecture");
3376 return -1;
3379 /* read sections */
3380 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3382 /* load dynamic section and dynamic symbols */
3383 nb_syms = 0;
3384 nb_dts = 0;
3385 dynamic = NULL;
3386 dynsym = NULL; /* avoid warning */
3387 dynstr = NULL; /* avoid warning */
3388 memset(&v, 0, sizeof v);
3390 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3391 switch(sh->sh_type) {
3392 case SHT_DYNAMIC:
3393 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3394 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3395 break;
3396 case SHT_DYNSYM:
3397 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3398 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3399 sh1 = &shdr[sh->sh_link];
3400 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3401 break;
3402 case SHT_GNU_verdef:
3403 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3404 break;
3405 case SHT_GNU_verneed:
3406 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3407 break;
3408 case SHT_GNU_versym:
3409 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3410 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3411 break;
3412 default:
3413 break;
3417 if (!dynamic)
3418 goto the_end;
3420 /* compute the real library name */
3421 soname = tcc_basename(filename);
3422 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
3423 if (dt->d_tag == DT_SONAME)
3424 soname = dynstr + dt->d_un.d_val;
3426 /* if the dll is already loaded, do not load it */
3427 if (tcc_add_dllref(s1, soname, level)->found)
3428 goto ret_success;
3430 if (v.nb_versyms != nb_syms)
3431 tcc_free (v.versym), v.versym = NULL;
3432 else
3433 store_version(s1, &v, dynstr);
3435 /* add dynamic symbols in dynsym_section */
3436 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3437 sym_bind = ELFW(ST_BIND)(sym->st_info);
3438 if (sym_bind == STB_LOCAL)
3439 continue;
3440 name = dynstr + sym->st_name;
3441 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3442 sym->st_info, sym->st_other, sym->st_shndx, name);
3443 if (v.versym) {
3444 ElfW(Half) vsym = v.versym[i];
3445 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3446 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3450 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
3451 if (dt->d_tag == DT_RPATH)
3452 tcc_add_library_path(s1, dynstr + dt->d_un.d_val);
3454 /* load all referenced DLLs */
3455 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3456 switch(dt->d_tag) {
3457 case DT_NEEDED:
3458 name = dynstr + dt->d_un.d_val;
3459 if (tcc_add_dllref(s1, name, -1))
3460 continue;
3461 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3462 tcc_error_noabort("referenced dll '%s' not found", name);
3463 goto the_end;
3468 ret_success:
3469 ret = 0;
3470 the_end:
3471 tcc_free(dynstr);
3472 tcc_free(dynsym);
3473 tcc_free(dynamic);
3474 tcc_free(shdr);
3475 tcc_free(v.local_ver);
3476 tcc_free(v.verdef);
3477 tcc_free(v.verneed);
3478 tcc_free(v.versym);
3479 return ret;
3482 #define LD_TOK_NAME 256
3483 #define LD_TOK_EOF (-1)
3485 static int ld_inp(TCCState *s1)
3487 char b;
3488 if (s1->cc != -1) {
3489 int c = s1->cc;
3490 s1->cc = -1;
3491 return c;
3493 if (1 == read(s1->fd, &b, 1))
3494 return b;
3495 return CH_EOF;
3498 /* return next ld script token */
3499 static int ld_next(TCCState *s1, char *name, int name_size)
3501 int c, d, ch;
3502 char *q;
3504 redo:
3505 ch = ld_inp(s1);
3506 switch(ch) {
3507 case ' ':
3508 case '\t':
3509 case '\f':
3510 case '\v':
3511 case '\r':
3512 case '\n':
3513 goto redo;
3514 case '/':
3515 ch = ld_inp(s1);
3516 if (ch == '*') { /* comment */
3517 for (d = 0;; d = ch) {
3518 ch = ld_inp(s1);
3519 if (ch == CH_EOF || (ch == '/' && d == '*'))
3520 break;
3522 goto redo;
3523 } else {
3524 q = name;
3525 *q++ = '/';
3526 goto parse_name;
3528 break;
3529 case '\\':
3530 /* case 'a' ... 'z': */
3531 case 'a':
3532 case 'b':
3533 case 'c':
3534 case 'd':
3535 case 'e':
3536 case 'f':
3537 case 'g':
3538 case 'h':
3539 case 'i':
3540 case 'j':
3541 case 'k':
3542 case 'l':
3543 case 'm':
3544 case 'n':
3545 case 'o':
3546 case 'p':
3547 case 'q':
3548 case 'r':
3549 case 's':
3550 case 't':
3551 case 'u':
3552 case 'v':
3553 case 'w':
3554 case 'x':
3555 case 'y':
3556 case 'z':
3557 /* case 'A' ... 'z': */
3558 case 'A':
3559 case 'B':
3560 case 'C':
3561 case 'D':
3562 case 'E':
3563 case 'F':
3564 case 'G':
3565 case 'H':
3566 case 'I':
3567 case 'J':
3568 case 'K':
3569 case 'L':
3570 case 'M':
3571 case 'N':
3572 case 'O':
3573 case 'P':
3574 case 'Q':
3575 case 'R':
3576 case 'S':
3577 case 'T':
3578 case 'U':
3579 case 'V':
3580 case 'W':
3581 case 'X':
3582 case 'Y':
3583 case 'Z':
3584 case '_':
3585 case '.':
3586 case '$':
3587 case '~':
3588 q = name;
3589 parse_name:
3590 for(;;) {
3591 if (!((ch >= 'a' && ch <= 'z') ||
3592 (ch >= 'A' && ch <= 'Z') ||
3593 (ch >= '0' && ch <= '9') ||
3594 strchr("/.-_+=$:\\,~", ch)))
3595 break;
3596 if ((q - name) < name_size - 1) {
3597 *q++ = ch;
3599 ch = ld_inp(s1);
3601 s1->cc = ch;
3602 *q = '\0';
3603 c = LD_TOK_NAME;
3604 break;
3605 case CH_EOF:
3606 c = LD_TOK_EOF;
3607 break;
3608 default:
3609 c = ch;
3610 break;
3612 return c;
3615 static int ld_add_file(TCCState *s1, const char filename[])
3617 if (filename[0] == '/') {
3618 if (CONFIG_SYSROOT[0] == '\0'
3619 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3620 return 0;
3621 filename = tcc_basename(filename);
3623 return tcc_add_dll(s1, filename, 0);
3626 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3628 char filename[1024], libname[1024];
3629 int t, group, nblibs = 0, ret = 0;
3630 char **libs = NULL;
3632 group = !strcmp(cmd, "GROUP");
3633 if (!as_needed)
3634 s1->new_undef_sym = 0;
3635 t = ld_next(s1, filename, sizeof(filename));
3636 if (t != '(') {
3637 tcc_error_noabort("( expected");
3638 ret = -1;
3639 goto lib_parse_error;
3641 t = ld_next(s1, filename, sizeof(filename));
3642 for(;;) {
3643 libname[0] = '\0';
3644 if (t == LD_TOK_EOF) {
3645 tcc_error_noabort("unexpected end of file");
3646 ret = -1;
3647 goto lib_parse_error;
3648 } else if (t == ')') {
3649 break;
3650 } else if (t == '-') {
3651 t = ld_next(s1, filename, sizeof(filename));
3652 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3653 tcc_error_noabort("library name expected");
3654 ret = -1;
3655 goto lib_parse_error;
3657 pstrcpy(libname, sizeof libname, &filename[1]);
3658 if (s1->static_link) {
3659 snprintf(filename, sizeof filename, "lib%s.a", libname);
3660 } else {
3661 snprintf(filename, sizeof filename, "lib%s.so", libname);
3663 } else if (t != LD_TOK_NAME) {
3664 tcc_error_noabort("filename expected");
3665 ret = -1;
3666 goto lib_parse_error;
3668 if (!strcmp(filename, "AS_NEEDED")) {
3669 ret = ld_add_file_list(s1, cmd, 1);
3670 if (ret)
3671 goto lib_parse_error;
3672 } else {
3673 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3674 if (!as_needed) {
3675 ret = ld_add_file(s1, filename);
3676 if (ret)
3677 goto lib_parse_error;
3678 if (group) {
3679 /* Add the filename *and* the libname to avoid future conversions */
3680 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3681 if (libname[0] != '\0')
3682 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3686 t = ld_next(s1, filename, sizeof(filename));
3687 if (t == ',') {
3688 t = ld_next(s1, filename, sizeof(filename));
3691 if (group && !as_needed) {
3692 while (s1->new_undef_sym) {
3693 int i;
3694 s1->new_undef_sym = 0;
3695 for (i = 0; i < nblibs; i ++)
3696 ld_add_file(s1, libs[i]);
3699 lib_parse_error:
3700 dynarray_reset(&libs, &nblibs);
3701 return ret;
3704 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3705 files */
3706 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3708 char cmd[64];
3709 char filename[1024];
3710 int t, ret;
3712 s1->fd = fd;
3713 s1->cc = -1;
3714 for(;;) {
3715 t = ld_next(s1, cmd, sizeof(cmd));
3716 if (t == LD_TOK_EOF)
3717 return 0;
3718 else if (t != LD_TOK_NAME)
3719 return -1;
3720 if (!strcmp(cmd, "INPUT") ||
3721 !strcmp(cmd, "GROUP")) {
3722 ret = ld_add_file_list(s1, cmd, 0);
3723 if (ret)
3724 return ret;
3725 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3726 !strcmp(cmd, "TARGET")) {
3727 /* ignore some commands */
3728 t = ld_next(s1, cmd, sizeof(cmd));
3729 if (t != '(') {
3730 tcc_error_noabort("( expected");
3731 return -1;
3733 for(;;) {
3734 t = ld_next(s1, filename, sizeof(filename));
3735 if (t == LD_TOK_EOF) {
3736 tcc_error_noabort("unexpected end of file");
3737 return -1;
3738 } else if (t == ')') {
3739 break;
3742 } else {
3743 return -1;
3746 return 0;
3748 #endif /* !ELF_OBJ_ONLY */