Fix stupid typo.
[tinycc.git] / tccelf.c
blobceb54b61c6a540172bd5208e463c31ec456a46ea
1 /*
2 * ELF file handling for TCC
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "tcc.h"
23 /* Define this to get some debug output during relocation processing. */
24 #undef DEBUG_RELOC
26 /********************************************************/
27 /* global variables */
29 /* elf version information */
30 struct sym_version {
31 char *lib;
32 char *version;
33 int out_index;
34 int prev_same_lib;
37 #define nb_sym_versions s1->nb_sym_versions
38 #define sym_versions s1->sym_versions
39 #define nb_sym_to_version s1->nb_sym_to_version
40 #define sym_to_version s1->sym_to_version
41 #define dt_verneednum s1->dt_verneednum
42 #define versym_section s1->versym_section
43 #define verneed_section s1->verneed_section
45 /* special flag to indicate that the section should not be linked to the other ones */
46 #define SHF_PRIVATE 0x80000000
47 /* section is dynsymtab_section */
48 #define SHF_DYNSYM 0x40000000
50 /* ------------------------------------------------------------------------- */
52 ST_FUNC void tccelf_new(TCCState *s)
54 TCCState *s1 = s;
55 /* no section zero */
56 dynarray_add(&s->sections, &s->nb_sections, NULL);
58 /* create standard sections */
59 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
60 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
61 #ifdef TCC_TARGET_PE
62 rodata_section = new_section(s, ".rdata", SHT_PROGBITS, SHF_ALLOC);
63 #else
64 /* create ro data section (make ro after relocation done with GNU_RELRO) */
65 rodata_section = new_section(s, ".data.ro", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
66 #endif
67 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
68 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
69 common_section->sh_num = SHN_COMMON;
71 /* symbols are always generated for linking stage */
72 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
73 ".strtab",
74 ".hashtab", SHF_PRIVATE);
75 s->symtab = symtab_section;
77 /* private symbol table for dynamic symbols */
78 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
79 ".dynstrtab",
80 ".dynhashtab", SHF_PRIVATE);
81 get_sym_attr(s, 0, 1);
84 #ifdef CONFIG_TCC_BCHECK
85 ST_FUNC void tccelf_bounds_new(TCCState *s)
87 TCCState *s1 = s;
88 /* create bounds sections (make ro after relocation done with GNU_RELRO) */
89 bounds_section = new_section(s, ".bounds",
90 SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
91 lbounds_section = new_section(s, ".lbounds",
92 SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
94 #endif
96 static void free_section(Section *s)
98 tcc_free(s->data);
101 ST_FUNC void tccelf_delete(TCCState *s1)
103 int i;
105 #ifndef ELF_OBJ_ONLY
106 /* free symbol versions */
107 for (i = 0; i < nb_sym_versions; i++) {
108 tcc_free(sym_versions[i].version);
109 tcc_free(sym_versions[i].lib);
111 tcc_free(sym_versions);
112 tcc_free(sym_to_version);
113 #endif
115 /* free all sections */
116 for(i = 1; i < s1->nb_sections; i++)
117 free_section(s1->sections[i]);
118 dynarray_reset(&s1->sections, &s1->nb_sections);
120 for(i = 0; i < s1->nb_priv_sections; i++)
121 free_section(s1->priv_sections[i]);
122 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
124 /* free any loaded DLLs */
125 #ifdef TCC_IS_NATIVE
126 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
127 DLLReference *ref = s1->loaded_dlls[i];
128 if ( ref->handle )
129 # ifdef _WIN32
130 FreeLibrary((HMODULE)ref->handle);
131 # else
132 dlclose(ref->handle);
133 # endif
135 #endif
136 /* free loaded dlls array */
137 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
138 tcc_free(s1->sym_attrs);
140 symtab_section = NULL; /* for tccrun.c:rt_printline() */
143 /* save section data state */
144 ST_FUNC void tccelf_begin_file(TCCState *s1)
146 Section *s; int i;
147 for (i = 1; i < s1->nb_sections; i++) {
148 s = s1->sections[i];
149 s->sh_offset = s->data_offset;
151 /* disable symbol hashing during compilation */
152 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
153 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
154 s1->uw_sym = 0;
155 #endif
158 /* At the end of compilation, convert any UNDEF syms to global, and merge
159 with previously existing symbols */
160 ST_FUNC void tccelf_end_file(TCCState *s1)
162 Section *s = s1->symtab;
163 int first_sym, nb_syms, *tr, i;
165 first_sym = s->sh_offset / sizeof (ElfSym);
166 nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
167 s->data_offset = s->sh_offset;
168 s->link->data_offset = s->link->sh_offset;
169 s->hash = s->reloc, s->reloc = NULL;
170 tr = tcc_mallocz(nb_syms * sizeof *tr);
172 for (i = 0; i < nb_syms; ++i) {
173 ElfSym *sym = (ElfSym*)s->data + first_sym + i;
174 if (sym->st_shndx == SHN_UNDEF
175 && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
176 sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
177 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
178 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
180 /* now update relocations */
181 for (i = 1; i < s1->nb_sections; i++) {
182 Section *sr = s1->sections[i];
183 if (sr->sh_type == SHT_RELX && sr->link == s) {
184 ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
185 ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
186 for (; rel < rel_end; ++rel) {
187 int n = ELFW(R_SYM)(rel->r_info) - first_sym;
188 //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
189 rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
193 tcc_free(tr);
195 /* record text/data/bss output for -bench info */
196 for (i = 0; i < 4; ++i) {
197 s = s1->sections[i + 1];
198 s1->total_output[i] += s->data_offset - s->sh_offset;
202 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
204 Section *sec;
206 sec = tcc_mallocz(sizeof(Section) + strlen(name));
207 sec->s1 = s1;
208 strcpy(sec->name, name);
209 sec->sh_type = sh_type;
210 sec->sh_flags = sh_flags;
211 switch(sh_type) {
212 case SHT_GNU_versym:
213 sec->sh_addralign = 2;
214 break;
215 case SHT_HASH:
216 case SHT_REL:
217 case SHT_RELA:
218 case SHT_DYNSYM:
219 case SHT_SYMTAB:
220 case SHT_DYNAMIC:
221 case SHT_GNU_verneed:
222 case SHT_GNU_verdef:
223 sec->sh_addralign = PTR_SIZE;
224 break;
225 case SHT_STRTAB:
226 sec->sh_addralign = 1;
227 break;
228 default:
229 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */
230 break;
233 if (sh_flags & SHF_PRIVATE) {
234 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
235 } else {
236 sec->sh_num = s1->nb_sections;
237 dynarray_add(&s1->sections, &s1->nb_sections, sec);
240 return sec;
243 ST_FUNC Section *new_symtab(TCCState *s1,
244 const char *symtab_name, int sh_type, int sh_flags,
245 const char *strtab_name,
246 const char *hash_name, int hash_sh_flags)
248 Section *symtab, *strtab, *hash;
249 int *ptr, nb_buckets;
251 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
252 symtab->sh_entsize = sizeof(ElfW(Sym));
253 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
254 put_elf_str(strtab, "");
255 symtab->link = strtab;
256 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
258 nb_buckets = 1;
260 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
261 hash->sh_entsize = sizeof(int);
262 symtab->hash = hash;
263 hash->link = symtab;
265 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
266 ptr[0] = nb_buckets;
267 ptr[1] = 1;
268 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
269 return symtab;
272 /* realloc section and set its content to zero */
273 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
275 unsigned long size;
276 unsigned char *data;
278 size = sec->data_allocated;
279 if (size == 0)
280 size = 1;
281 while (size < new_size)
282 size = size * 2;
283 data = tcc_realloc(sec->data, size);
284 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
285 sec->data = data;
286 sec->data_allocated = size;
289 /* reserve at least 'size' bytes aligned per 'align' in section
290 'sec' from current offset, and return the aligned offset */
291 ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
293 size_t offset, offset1;
295 offset = (sec->data_offset + align - 1) & -align;
296 offset1 = offset + size;
297 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
298 section_realloc(sec, offset1);
299 sec->data_offset = offset1;
300 if (align > sec->sh_addralign)
301 sec->sh_addralign = align;
302 return offset;
305 /* reserve at least 'size' bytes in section 'sec' from
306 sec->data_offset. */
307 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
309 size_t offset = section_add(sec, size, 1);
310 return sec->data + offset;
313 #ifndef ELF_OBJ_ONLY
314 /* reserve at least 'size' bytes from section start */
315 static void section_reserve(Section *sec, unsigned long size)
317 if (size > sec->data_allocated)
318 section_realloc(sec, size);
319 if (size > sec->data_offset)
320 sec->data_offset = size;
322 #endif
324 static Section *find_section_create (TCCState *s1, const char *name, int create)
326 Section *sec;
327 int i;
328 for(i = 1; i < s1->nb_sections; i++) {
329 sec = s1->sections[i];
330 if (!strcmp(name, sec->name))
331 return sec;
333 /* sections are created as PROGBITS */
334 return create ? new_section(s1, name, SHT_PROGBITS, SHF_ALLOC) : NULL;
337 /* return a reference to a section, and create it if it does not
338 exists */
339 ST_FUNC Section *find_section(TCCState *s1, const char *name)
341 return find_section_create (s1, name, 1);
344 /* ------------------------------------------------------------------------- */
346 ST_FUNC int put_elf_str(Section *s, const char *sym)
348 int offset, len;
349 char *ptr;
351 len = strlen(sym) + 1;
352 offset = s->data_offset;
353 ptr = section_ptr_add(s, len);
354 memmove(ptr, sym, len);
355 return offset;
358 /* elf symbol hashing function */
359 static unsigned long elf_hash(const unsigned char *name)
361 unsigned long h = 0, g;
363 while (*name) {
364 h = (h << 4) + *name++;
365 g = h & 0xf0000000;
366 if (g)
367 h ^= g >> 24;
368 h &= ~g;
370 return h;
373 /* rebuild hash table of section s */
374 /* NOTE: we do factorize the hash table code to go faster */
375 static void rebuild_hash(Section *s, unsigned int nb_buckets)
377 ElfW(Sym) *sym;
378 int *ptr, *hash, nb_syms, sym_index, h;
379 unsigned char *strtab;
381 strtab = s->link->data;
382 nb_syms = s->data_offset / sizeof(ElfW(Sym));
384 if (!nb_buckets)
385 nb_buckets = ((int*)s->hash->data)[0];
387 s->hash->data_offset = 0;
388 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
389 ptr[0] = nb_buckets;
390 ptr[1] = nb_syms;
391 ptr += 2;
392 hash = ptr;
393 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
394 ptr += nb_buckets + 1;
396 sym = (ElfW(Sym) *)s->data + 1;
397 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
398 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
399 h = elf_hash(strtab + sym->st_name) % nb_buckets;
400 *ptr = hash[h];
401 hash[h] = sym_index;
402 } else {
403 *ptr = 0;
405 ptr++;
406 sym++;
410 /* return the symbol number */
411 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
412 int info, int other, int shndx, const char *name)
414 int name_offset, sym_index;
415 int nbuckets, h;
416 ElfW(Sym) *sym;
417 Section *hs;
419 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
420 if (name && name[0])
421 name_offset = put_elf_str(s->link, name);
422 else
423 name_offset = 0;
424 /* XXX: endianness */
425 sym->st_name = name_offset;
426 sym->st_value = value;
427 sym->st_size = size;
428 sym->st_info = info;
429 sym->st_other = other;
430 sym->st_shndx = shndx;
431 sym_index = sym - (ElfW(Sym) *)s->data;
432 hs = s->hash;
433 if (hs) {
434 int *ptr, *base;
435 ptr = section_ptr_add(hs, sizeof(int));
436 base = (int *)hs->data;
437 /* only add global or weak symbols. */
438 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
439 /* add another hashing entry */
440 nbuckets = base[0];
441 h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
442 *ptr = base[2 + h];
443 base[2 + h] = sym_index;
444 base[1]++;
445 /* we resize the hash table */
446 hs->nb_hashed_syms++;
447 if (hs->nb_hashed_syms > 2 * nbuckets) {
448 rebuild_hash(s, 2 * nbuckets);
450 } else {
451 *ptr = 0;
452 base[1]++;
455 return sym_index;
458 ST_FUNC int find_elf_sym(Section *s, const char *name)
460 ElfW(Sym) *sym;
461 Section *hs;
462 int nbuckets, sym_index, h;
463 const char *name1;
465 hs = s->hash;
466 if (!hs)
467 return 0;
468 nbuckets = ((int *)hs->data)[0];
469 h = elf_hash((unsigned char *) name) % nbuckets;
470 sym_index = ((int *)hs->data)[2 + h];
471 while (sym_index != 0) {
472 sym = &((ElfW(Sym) *)s->data)[sym_index];
473 name1 = (char *) s->link->data + sym->st_name;
474 if (!strcmp(name, name1))
475 return sym_index;
476 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
478 return 0;
481 /* return elf symbol value, signal error if 'err' is nonzero, decorate
482 name if FORC */
483 ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
485 int sym_index;
486 ElfW(Sym) *sym;
487 char buf[256];
488 if (forc && s1->leading_underscore
489 #ifdef TCC_TARGET_PE
490 /* win32-32bit stdcall symbols always have _ already */
491 && !strchr(name, '@')
492 #endif
494 buf[0] = '_';
495 pstrcpy(buf + 1, sizeof(buf) - 1, name);
496 name = buf;
498 sym_index = find_elf_sym(s1->symtab, name);
499 sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
500 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
501 if (err)
502 tcc_error("%s not defined", name);
503 return (addr_t)-1;
505 return sym->st_value;
508 /* return elf symbol value */
509 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
511 addr_t addr = get_sym_addr(s, name, 0, 1);
512 return addr == -1 ? NULL : (void*)(uintptr_t)addr;
515 /* list elf symbol names and values */
516 ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
517 void (*symbol_cb)(void *ctx, const char *name, const void *val))
519 ElfW(Sym) *sym;
520 Section *symtab;
521 int sym_index, end_sym;
522 const char *name;
523 unsigned char sym_vis, sym_bind;
525 symtab = s->symtab;
526 end_sym = symtab->data_offset / sizeof (ElfSym);
527 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
528 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
529 if (sym->st_value) {
530 name = (char *) symtab->link->data + sym->st_name;
531 sym_bind = ELFW(ST_BIND)(sym->st_info);
532 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
533 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
534 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
539 /* list elf symbol names and values */
540 LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
541 void (*symbol_cb)(void *ctx, const char *name, const void *val))
543 list_elf_symbols(s, ctx, symbol_cb);
546 #ifndef ELF_OBJ_ONLY
547 static void
548 version_add (TCCState *s1)
550 int i;
551 ElfW(Sym) *sym;
552 ElfW(Verneed) *vn = NULL;
553 Section *symtab;
554 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
555 ElfW(Half) *versym;
556 const char *name;
558 if (0 == nb_sym_versions)
559 return;
560 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
561 versym_section->sh_entsize = sizeof(ElfW(Half));
562 versym_section->link = s1->dynsym;
564 /* add needed symbols */
565 symtab = s1->dynsym;
566 end_sym = symtab->data_offset / sizeof (ElfSym);
567 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
568 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
569 int dllindex, verndx;
570 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
571 name = (char *) symtab->link->data + sym->st_name;
572 dllindex = find_elf_sym(s1->dynsymtab_section, name);
573 verndx = (dllindex && dllindex < nb_sym_to_version)
574 ? sym_to_version[dllindex] : -1;
575 if (verndx >= 0) {
576 if (!sym_versions[verndx].out_index)
577 sym_versions[verndx].out_index = nb_versions++;
578 versym[sym_index] = sym_versions[verndx].out_index;
579 } else
580 versym[sym_index] = 0;
582 /* generate verneed section, but not when it will be empty. Some
583 dynamic linkers look at their contents even when DTVERNEEDNUM and
584 section size is zero. */
585 if (nb_versions > 2) {
586 verneed_section = new_section(s1, ".gnu.version_r",
587 SHT_GNU_verneed, SHF_ALLOC);
588 verneed_section->link = s1->dynsym->link;
589 for (i = nb_sym_versions; i-- > 0;) {
590 struct sym_version *sv = &sym_versions[i];
591 int n_same_libs = 0, prev;
592 size_t vnofs;
593 ElfW(Vernaux) *vna = 0;
594 if (sv->out_index < 1)
595 continue;
596 vnofs = section_add(verneed_section, sizeof(*vn), 1);
597 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
598 vn->vn_version = 1;
599 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
600 vn->vn_aux = sizeof (*vn);
601 do {
602 prev = sv->prev_same_lib;
603 if (sv->out_index > 0) {
604 vna = section_ptr_add(verneed_section, sizeof(*vna));
605 vna->vna_hash = elf_hash ((const unsigned char *)sv->version);
606 vna->vna_flags = 0;
607 vna->vna_other = sv->out_index;
608 sv->out_index = -2;
609 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
610 vna->vna_next = sizeof (*vna);
611 n_same_libs++;
613 if (prev >= 0)
614 sv = &sym_versions[prev];
615 } while(prev >= 0);
616 vna->vna_next = 0;
617 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
618 vn->vn_cnt = n_same_libs;
619 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
620 nb_entries++;
622 if (vn)
623 vn->vn_next = 0;
624 verneed_section->sh_info = nb_entries;
626 dt_verneednum = nb_entries;
628 #endif /* ndef ELF_OBJ_ONLY */
630 /* add an elf symbol : check if it is already defined and patch
631 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
632 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
633 int info, int other, int shndx, const char *name)
635 TCCState *s1 = s->s1;
636 ElfW(Sym) *esym;
637 int sym_bind, sym_index, sym_type, esym_bind;
638 unsigned char sym_vis, esym_vis, new_vis;
640 sym_bind = ELFW(ST_BIND)(info);
641 sym_type = ELFW(ST_TYPE)(info);
642 sym_vis = ELFW(ST_VISIBILITY)(other);
644 if (sym_bind != STB_LOCAL) {
645 /* we search global or weak symbols */
646 sym_index = find_elf_sym(s, name);
647 if (!sym_index)
648 goto do_def;
649 esym = &((ElfW(Sym) *)s->data)[sym_index];
650 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
651 && esym->st_other == other && esym->st_shndx == shndx)
652 return sym_index;
653 if (esym->st_shndx != SHN_UNDEF) {
654 esym_bind = ELFW(ST_BIND)(esym->st_info);
655 /* propagate the most constraining visibility */
656 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
657 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
658 if (esym_vis == STV_DEFAULT) {
659 new_vis = sym_vis;
660 } else if (sym_vis == STV_DEFAULT) {
661 new_vis = esym_vis;
662 } else {
663 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
665 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
666 | new_vis;
667 if (shndx == SHN_UNDEF) {
668 /* ignore adding of undefined symbol if the
669 corresponding symbol is already defined */
670 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
671 /* global overrides weak, so patch */
672 goto do_patch;
673 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
674 /* weak is ignored if already global */
675 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
676 /* keep first-found weak definition, ignore subsequents */
677 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
678 /* ignore hidden symbols after */
679 } else if ((esym->st_shndx == SHN_COMMON
680 || esym->st_shndx == bss_section->sh_num)
681 && (shndx < SHN_LORESERVE
682 && shndx != bss_section->sh_num)) {
683 /* data symbol gets precedence over common/bss */
684 goto do_patch;
685 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
686 /* data symbol keeps precedence over common/bss */
687 } else if (s->sh_flags & SHF_DYNSYM) {
688 /* we accept that two DLL define the same symbol */
689 } else if (esym->st_other & ST_ASM_SET) {
690 /* If the existing symbol came from an asm .set
691 we can override. */
692 goto do_patch;
693 } else {
694 #if 0
695 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
696 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
697 #endif
698 tcc_error_noabort("'%s' defined twice", name);
700 } else {
701 esym->st_other = other;
702 do_patch:
703 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
704 esym->st_shndx = shndx;
705 s1->new_undef_sym = 1;
706 esym->st_value = value;
707 esym->st_size = size;
709 } else {
710 do_def:
711 sym_index = put_elf_sym(s, value, size,
712 ELFW(ST_INFO)(sym_bind, sym_type), other,
713 shndx, name);
715 return sym_index;
718 /* put relocation */
719 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
720 int type, int symbol, addr_t addend)
722 TCCState *s1 = s->s1;
723 char buf[256];
724 Section *sr;
725 ElfW_Rel *rel;
727 sr = s->reloc;
728 if (!sr) {
729 /* if no relocation section, create it */
730 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
731 /* if the symtab is allocated, then we consider the relocation
732 are also */
733 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
734 sr->sh_entsize = sizeof(ElfW_Rel);
735 sr->link = symtab;
736 sr->sh_info = s->sh_num;
737 s->reloc = sr;
739 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
740 rel->r_offset = offset;
741 rel->r_info = ELFW(R_INFO)(symbol, type);
742 #if SHT_RELX == SHT_RELA
743 rel->r_addend = addend;
744 #endif
745 if (SHT_RELX != SHT_RELA && addend)
746 tcc_error("non-zero addend on REL architecture");
749 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
750 int type, int symbol)
752 put_elf_reloca(symtab, s, offset, type, symbol, 0);
755 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
757 int n;
758 struct sym_attr *tab;
760 if (index >= s1->nb_sym_attrs) {
761 if (!alloc)
762 return s1->sym_attrs;
763 /* find immediately bigger power of 2 and reallocate array */
764 n = 1;
765 while (index >= n)
766 n *= 2;
767 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
768 s1->sym_attrs = tab;
769 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
770 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
771 s1->nb_sym_attrs = n;
773 return &s1->sym_attrs[index];
776 /* In an ELF file symbol table, the local symbols must appear below
777 the global and weak ones. Since TCC cannot sort it while generating
778 the code, we must do it after. All the relocation tables are also
779 modified to take into account the symbol table sorting */
780 static void sort_syms(TCCState *s1, Section *s)
782 int *old_to_new_syms;
783 ElfW(Sym) *new_syms;
784 int nb_syms, i;
785 ElfW(Sym) *p, *q;
786 ElfW_Rel *rel;
787 Section *sr;
788 int type, sym_index;
790 nb_syms = s->data_offset / sizeof(ElfW(Sym));
791 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
792 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
794 /* first pass for local symbols */
795 p = (ElfW(Sym) *)s->data;
796 q = new_syms;
797 for(i = 0; i < nb_syms; i++) {
798 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
799 old_to_new_syms[i] = q - new_syms;
800 *q++ = *p;
802 p++;
804 /* save the number of local symbols in section header */
805 if( s->sh_size ) /* this 'if' makes IDA happy */
806 s->sh_info = q - new_syms;
808 /* then second pass for non local symbols */
809 p = (ElfW(Sym) *)s->data;
810 for(i = 0; i < nb_syms; i++) {
811 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
812 old_to_new_syms[i] = q - new_syms;
813 *q++ = *p;
815 p++;
818 /* we copy the new symbols to the old */
819 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
820 tcc_free(new_syms);
822 /* now we modify all the relocations */
823 for(i = 1; i < s1->nb_sections; i++) {
824 sr = s1->sections[i];
825 if (sr->sh_type == SHT_RELX && sr->link == s) {
826 for_each_elem(sr, 0, rel, ElfW_Rel) {
827 sym_index = ELFW(R_SYM)(rel->r_info);
828 type = ELFW(R_TYPE)(rel->r_info);
829 sym_index = old_to_new_syms[sym_index];
830 rel->r_info = ELFW(R_INFO)(sym_index, type);
835 tcc_free(old_to_new_syms);
838 /* relocate symbol table, resolve undefined symbols if do_resolve is
839 true and output error if undefined symbol. */
840 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
842 ElfW(Sym) *sym;
843 int sym_bind, sh_num;
844 const char *name;
846 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
847 sh_num = sym->st_shndx;
848 if (sh_num == SHN_UNDEF) {
849 name = (char *) s1->symtab->link->data + sym->st_name;
850 /* Use ld.so to resolve symbol for us (for tcc -run) */
851 if (do_resolve) {
852 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
853 /* dlsym() needs the undecorated name. */
854 void *addr = dlsym(RTLD_DEFAULT, &name[s1->leading_underscore]);
855 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
856 if (addr == NULL) {
857 int i;
858 for (i = 0; i < s1->nb_loaded_dlls; i++)
859 if ((addr = dlsym(s1->loaded_dlls[i]->handle, name)))
860 break;
862 #endif
863 if (addr) {
864 sym->st_value = (addr_t) addr;
865 #ifdef DEBUG_RELOC
866 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
867 #endif
868 goto found;
870 #endif
871 /* if dynamic symbol exist, it will be used in relocate_section */
872 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
873 goto found;
874 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
875 it */
876 if (!strcmp(name, "_fp_hw"))
877 goto found;
878 /* only weak symbols are accepted to be undefined. Their
879 value is zero */
880 sym_bind = ELFW(ST_BIND)(sym->st_info);
881 if (sym_bind == STB_WEAK)
882 sym->st_value = 0;
883 else
884 tcc_error_noabort("undefined symbol '%s'", name);
886 } else if (sh_num < SHN_LORESERVE) {
887 /* add section base */
888 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
890 found: ;
894 /* relocate a given section (CPU dependent) by applying the relocations
895 in the associated relocation section */
896 static void relocate_section(TCCState *s1, Section *s, Section *sr)
898 ElfW_Rel *rel;
899 ElfW(Sym) *sym;
900 int type, sym_index;
901 unsigned char *ptr;
902 addr_t tgt, addr;
903 int is_dwarf = s->sh_num >= s1->dwlo && s->sh_num < s1->dwhi;
905 qrel = (ElfW_Rel *)sr->data;
906 for_each_elem(sr, 0, rel, ElfW_Rel) {
907 ptr = s->data + rel->r_offset;
908 sym_index = ELFW(R_SYM)(rel->r_info);
909 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
910 type = ELFW(R_TYPE)(rel->r_info);
911 tgt = sym->st_value;
912 #if SHT_RELX == SHT_RELA
913 tgt += rel->r_addend;
914 #endif
915 if (is_dwarf && type == R_DATA_32DW
916 && sym->st_shndx >= s1->dwlo && sym->st_shndx < s1->dwhi) {
917 /* dwarf section relocation to each other */
918 add32le(ptr, tgt - s1->sections[sym->st_shndx]->sh_addr);
919 continue;
921 addr = s->sh_addr + rel->r_offset;
922 relocate(s1, rel, type, ptr, addr, tgt);
924 #ifndef ELF_OBJ_ONLY
925 /* if the relocation is allocated, we change its symbol table */
926 if (sr->sh_flags & SHF_ALLOC) {
927 sr->link = s1->dynsym;
928 if (s1->output_type == TCC_OUTPUT_DLL) {
929 size_t r = (uint8_t*)qrel - sr->data;
930 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
931 && 0 == strcmp(s->name, ".stab"))
932 r = 0; /* cannot apply 64bit relocation to 32bit value */
933 sr->data_offset = sr->sh_size = r;
936 #endif
939 /* relocate all sections */
940 ST_FUNC void relocate_sections(TCCState *s1)
942 int i;
943 Section *s, *sr;
945 for (i = 1; i < s1->nb_sections; ++i) {
946 sr = s1->sections[i];
947 if (sr->sh_type != SHT_RELX)
948 continue;
949 s = s1->sections[sr->sh_info];
950 #ifndef TCC_TARGET_MACHO
951 if (s != s1->got
952 || s1->static_link
953 || s1->output_type == TCC_OUTPUT_MEMORY)
954 #endif
956 relocate_section(s1, s, sr);
958 #ifndef ELF_OBJ_ONLY
959 if (sr->sh_flags & SHF_ALLOC) {
960 ElfW_Rel *rel;
961 /* relocate relocation table in 'sr' */
962 for_each_elem(sr, 0, rel, ElfW_Rel)
963 rel->r_offset += s->sh_addr;
965 #endif
969 #ifndef ELF_OBJ_ONLY
970 /* count the number of dynamic relocations so that we can reserve
971 their space */
972 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
974 int count = 0;
975 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
976 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
977 defined(TCC_TARGET_RISCV64)
978 ElfW_Rel *rel;
979 for_each_elem(sr, 0, rel, ElfW_Rel) {
980 int sym_index = ELFW(R_SYM)(rel->r_info);
981 int type = ELFW(R_TYPE)(rel->r_info);
982 switch(type) {
983 #if defined(TCC_TARGET_I386)
984 case R_386_32:
985 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
986 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
987 /* don't fixup unresolved (weak) symbols */
988 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
989 break;
991 #elif defined(TCC_TARGET_X86_64)
992 case R_X86_64_32:
993 case R_X86_64_32S:
994 case R_X86_64_64:
995 #elif defined(TCC_TARGET_ARM)
996 case R_ARM_ABS32:
997 case R_ARM_TARGET1:
998 #elif defined(TCC_TARGET_ARM64)
999 case R_AARCH64_ABS32:
1000 case R_AARCH64_ABS64:
1001 #elif defined(TCC_TARGET_RISCV64)
1002 case R_RISCV_32:
1003 case R_RISCV_64:
1004 #endif
1005 count++;
1006 break;
1007 #if defined(TCC_TARGET_I386)
1008 case R_386_PC32:
1009 #elif defined(TCC_TARGET_X86_64)
1010 case R_X86_64_PC32:
1012 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1014 /* Hidden defined symbols can and must be resolved locally.
1015 We're misusing a PLT32 reloc for this, as that's always
1016 resolved to its address even in shared libs. */
1017 if (sym->st_shndx != SHN_UNDEF &&
1018 ELFW(ST_VISIBILITY)(sym->st_other) == STV_HIDDEN) {
1019 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PLT32);
1020 break;
1023 #elif defined(TCC_TARGET_ARM64)
1024 case R_AARCH64_PREL32:
1025 #endif
1026 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1027 count++;
1028 break;
1029 default:
1030 break;
1033 #endif
1034 return count;
1036 #endif
1038 #ifdef NEED_BUILD_GOT
1039 static void build_got(TCCState *s1)
1041 /* if no got, then create it */
1042 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1043 s1->got->sh_entsize = 4;
1044 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1045 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1046 /* keep space for _DYNAMIC pointer and two dummy got entries */
1047 section_ptr_add(s1->got, 3 * PTR_SIZE);
1050 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1051 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1052 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1053 Returns the offset of the GOT or (if any) PLT entry. */
1054 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1055 int sym_index)
1057 int need_plt_entry;
1058 const char *name;
1059 ElfW(Sym) *sym;
1060 struct sym_attr *attr;
1061 unsigned got_offset;
1062 char plt_name[100];
1063 int len;
1064 Section *s_rel;
1066 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1067 attr = get_sym_attr(s1, sym_index, 1);
1069 /* In case a function is both called and its address taken 2 GOT entries
1070 are created, one for taking the address (GOT) and the other for the PLT
1071 entry (PLTGOT). */
1072 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1073 return attr;
1075 s_rel = s1->got;
1076 if (need_plt_entry) {
1077 if (!s1->plt) {
1078 s1->plt = new_section(s1, ".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
1079 s1->plt->sh_entsize = 4;
1081 s_rel = s1->plt;
1084 /* create the GOT entry */
1085 got_offset = s1->got->data_offset;
1086 section_ptr_add(s1->got, PTR_SIZE);
1088 /* Create the GOT relocation that will insert the address of the object or
1089 function of interest in the GOT entry. This is a static relocation for
1090 memory output (dlsym will give us the address of symbols) and dynamic
1091 relocation otherwise (executable and DLLs). The relocation should be
1092 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1093 associated to a PLT entry) but is currently done at load time for an
1094 unknown reason. */
1096 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1097 name = (char *) symtab_section->link->data + sym->st_name;
1098 //printf("sym %d %s\n", need_plt_entry, name);
1100 if (s1->dynsym) {
1101 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1102 /* Hack alarm. We don't want to emit dynamic symbols
1103 and symbol based relocs for STB_LOCAL symbols, but rather
1104 want to resolve them directly. At this point the symbol
1105 values aren't final yet, so we must defer this. We will later
1106 have to create a RELATIVE reloc anyway, so we misuse the
1107 relocation slot to smuggle the symbol reference until
1108 fill_local_got_entries. Not that the sym_index is
1109 relative to symtab_section, not s1->dynsym! Nevertheless
1110 we use s1->dyn_sym so that if this is the first call
1111 that got->reloc is correctly created. Also note that
1112 RELATIVE relocs are not normally created for the .got,
1113 so the types serves as a marker for later (and is retained
1114 also for the final output, which is okay because then the
1115 got is just normal data). */
1116 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1117 sym_index);
1118 } else {
1119 if (0 == attr->dyn_index)
1120 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1121 sym->st_size, sym->st_info, 0,
1122 sym->st_shndx, name);
1123 put_elf_reloc(s1->dynsym, s_rel, got_offset, dyn_reloc_type,
1124 attr->dyn_index);
1126 } else {
1127 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1128 sym_index);
1131 if (need_plt_entry) {
1132 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1134 /* create a symbol 'sym@plt' for the PLT jump vector */
1135 len = strlen(name);
1136 if (len > sizeof plt_name - 5)
1137 len = sizeof plt_name - 5;
1138 memcpy(plt_name, name, len);
1139 strcpy(plt_name + len, "@plt");
1140 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
1141 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1142 } else {
1143 attr->got_offset = got_offset;
1146 return attr;
1149 /* build GOT and PLT entries */
1150 /* Two passes because R_JMP_SLOT should become first. Some targets
1151 (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1152 ST_FUNC void build_got_entries(TCCState *s1)
1154 Section *s;
1155 ElfW_Rel *rel;
1156 ElfW(Sym) *sym;
1157 int i, type, gotplt_entry, reloc_type, sym_index;
1158 struct sym_attr *attr;
1159 int pass = 0;
1161 redo:
1162 for(i = 1; i < s1->nb_sections; i++) {
1163 s = s1->sections[i];
1164 if (s->sh_type != SHT_RELX)
1165 continue;
1166 /* no need to handle got relocations */
1167 if (s->link != symtab_section)
1168 continue;
1169 for_each_elem(s, 0, rel, ElfW_Rel) {
1170 type = ELFW(R_TYPE)(rel->r_info);
1171 gotplt_entry = gotplt_entry_type(type);
1172 if (gotplt_entry == -1)
1173 tcc_error ("Unknown relocation type for got: %d", type);
1174 sym_index = ELFW(R_SYM)(rel->r_info);
1175 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1177 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1178 continue;
1181 /* Automatically create PLT/GOT [entry] if it is an undefined
1182 reference (resolved at runtime), or the symbol is absolute,
1183 probably created by tcc_add_symbol, and thus on 64-bit
1184 targets might be too far from application code. */
1185 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1186 if (sym->st_shndx == SHN_UNDEF) {
1187 ElfW(Sym) *esym;
1188 int dynindex;
1189 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1190 continue;
1191 /* Relocations for UNDEF symbols would normally need
1192 to be transferred into the executable or shared object.
1193 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1194 But TCC doesn't do that (at least for exes), so we
1195 need to resolve all such relocs locally. And that
1196 means PLT slots for functions in DLLs and COPY relocs for
1197 data symbols. COPY relocs were generated in
1198 bind_exe_dynsyms (and the symbol adjusted to be defined),
1199 and for functions we were generated a dynamic symbol
1200 of function type. */
1201 if (s1->dynsym) {
1202 /* dynsym isn't set for -run :-/ */
1203 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1204 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1205 if (dynindex
1206 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1207 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1208 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1209 goto jmp_slot;
1211 } else if (sym->st_shndx == SHN_ABS) {
1212 if (sym->st_value == 0) /* from tcc_add_btstub() */
1213 continue;
1214 #ifndef TCC_TARGET_ARM
1215 if (PTR_SIZE != 8)
1216 continue;
1217 #endif
1218 /* from tcc_add_symbol(): on 64 bit platforms these
1219 need to go through .got */
1220 } else
1221 continue;
1224 #ifdef TCC_TARGET_X86_64
1225 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1226 sym->st_shndx != SHN_UNDEF &&
1227 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1228 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1229 s1->output_type == TCC_OUTPUT_EXE)) {
1230 if (pass != 0)
1231 continue;
1232 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1233 continue;
1235 #endif
1236 reloc_type = code_reloc(type);
1237 if (reloc_type == -1)
1238 tcc_error ("Unknown relocation type: %d", type);
1240 if (reloc_type != 0) {
1241 jmp_slot:
1242 if (pass != 0)
1243 continue;
1244 reloc_type = R_JMP_SLOT;
1245 } else {
1246 if (pass != 1)
1247 continue;
1248 reloc_type = R_GLOB_DAT;
1251 if (!s1->got)
1252 build_got(s1);
1254 if (gotplt_entry == BUILD_GOT_ONLY)
1255 continue;
1257 attr = put_got_entry(s1, reloc_type, sym_index);
1259 if (reloc_type == R_JMP_SLOT)
1260 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1263 if (++pass < 2)
1264 goto redo;
1266 /* .rel.plt refers to .got actually */
1267 if (s1->plt && s1->plt->reloc)
1268 s1->plt->reloc->sh_info = s1->got->sh_num;
1271 #endif /* def NEED_BUILD_GOT */
1273 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
1275 int shn = sec ? sec->sh_num : offs || !name ? SHN_ABS : SHN_UNDEF;
1276 if (sec && offs == -1)
1277 offs = sec->data_offset;
1278 return set_elf_sym(symtab_section, offs, 0,
1279 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1282 static void add_init_array_defines(TCCState *s1, const char *section_name)
1284 Section *s;
1285 addr_t end_offset;
1286 char buf[1024];
1287 s = find_section_create(s1, section_name, 0);
1288 if (!s) {
1289 end_offset = 0;
1290 s = data_section;
1291 } else {
1292 end_offset = s->data_offset;
1294 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1295 set_global_sym(s1, buf, s, 0);
1296 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1297 set_global_sym(s1, buf, s, end_offset);
1300 #ifndef TCC_TARGET_PE
1301 static void tcc_add_support(TCCState *s1, const char *filename)
1303 char buf[1024];
1304 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1305 tcc_add_file(s1, buf);
1307 #endif
1309 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1311 Section *s;
1312 s = find_section(s1, sec);
1313 s->sh_flags |= SHF_WRITE;
1314 #ifndef TCC_TARGET_PE
1315 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1316 #endif
1317 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1318 section_ptr_add(s, PTR_SIZE);
1321 #ifdef CONFIG_TCC_BCHECK
1322 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1324 if (0 == s1->do_bounds_check)
1325 return;
1326 section_ptr_add(bounds_section, sizeof(addr_t));
1328 #endif
1330 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1331 a dynamic symbol to allow so's to have one each with a different value. */
1332 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1334 int c = find_elf_sym(s1->symtab, name);
1335 if (c) {
1336 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1337 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1338 esym->st_value = offset;
1339 esym->st_shndx = s->sh_num;
1343 /* avoid generating debug/test_coverage code for stub functions */
1344 static void tcc_compile_string_no_debug(TCCState *s, const char *str)
1346 int save_do_debug = s->do_debug;
1347 int save_test_coverage = s->test_coverage;
1349 s->do_debug = 0;
1350 s->test_coverage = 0;
1351 tcc_compile_string(s, str);
1352 s->do_debug = save_do_debug;
1353 s->test_coverage = save_test_coverage;
1356 #ifdef CONFIG_TCC_BACKTRACE
1357 static void put_ptr(TCCState *s1, Section *s, int offs)
1359 int c;
1360 c = set_global_sym(s1, NULL, s, offs);
1361 s = data_section;
1362 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1363 section_ptr_add(s, PTR_SIZE);
1366 ST_FUNC void tcc_add_btstub(TCCState *s1)
1368 Section *s;
1369 int n, o;
1370 CString cstr;
1372 s = data_section;
1373 /* Align to PTR_SIZE */
1374 section_ptr_add(s, -s->data_offset & (PTR_SIZE - 1));
1375 o = s->data_offset;
1376 /* create (part of) a struct rt_context (see tccrun.c) */
1377 if (s1->dwarf) {
1378 put_ptr(s1, dwarf_line_section, 0);
1379 put_ptr(s1, dwarf_line_section, -1);
1380 if (s1->dwarf >= 5)
1381 put_ptr(s1, dwarf_line_str_section, 0);
1382 else
1383 put_ptr(s1, dwarf_str_section, 0);
1384 put_ptr(s1, text_section, 0);
1386 else
1388 put_ptr(s1, stab_section, 0);
1389 put_ptr(s1, stab_section, -1);
1390 put_ptr(s1, stab_section->link, 0);
1391 section_ptr_add(s, PTR_SIZE);
1393 /* skip esym_start/esym_end/elf_str (not loaded) */
1394 section_ptr_add(s, 3 * PTR_SIZE);
1395 /* prog_base : local nameless symbol with offset 0 at SHN_ABS */
1396 put_ptr(s1, NULL, 0);
1397 n = 2 * PTR_SIZE;
1398 #ifdef CONFIG_TCC_BCHECK
1399 if (s1->do_bounds_check) {
1400 put_ptr(s1, bounds_section, 0);
1401 n -= PTR_SIZE;
1403 #endif
1404 section_ptr_add(s, n);
1405 cstr_new(&cstr);
1406 cstr_printf(&cstr,
1407 "extern void __bt_init(),__bt_init_dll();"
1408 "static void *__rt_info[];"
1409 "__attribute__((constructor)) static void __bt_init_rt(){");
1410 #ifdef TCC_TARGET_PE
1411 if (s1->output_type == TCC_OUTPUT_DLL)
1412 #ifdef CONFIG_TCC_BCHECK
1413 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1414 #else
1415 cstr_printf(&cstr, "__bt_init_dll(0);");
1416 #endif
1417 #endif
1418 cstr_printf(&cstr, "__bt_init(__rt_info,%d);}",
1419 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1420 tcc_compile_string_no_debug(s1, cstr.data);
1421 cstr_free(&cstr);
1422 set_local_sym(s1, &"___rt_info"[!s1->leading_underscore], s, o);
1424 #endif /* def CONFIG_TCC_BACKTRACE */
1426 static void tcc_tcov_add_file(TCCState *s1, const char *filename)
1428 CString cstr;
1429 void *ptr;
1430 char wd[1024];
1432 if (tcov_section == NULL)
1433 return;
1434 section_ptr_add(tcov_section, 1);
1435 write32le (tcov_section->data, tcov_section->data_offset);
1437 cstr_new (&cstr);
1438 if (filename[0] == '/')
1439 cstr_printf (&cstr, "%s.tcov", filename);
1440 else {
1441 getcwd (wd, sizeof(wd));
1442 cstr_printf (&cstr, "%s/%s.tcov", wd, filename);
1444 ptr = section_ptr_add(tcov_section, cstr.size + 1);
1445 strcpy((char *)ptr, cstr.data);
1446 unlink((char *)ptr);
1447 #ifdef _WIN32
1448 normalize_slashes((char *)ptr);
1449 #endif
1450 cstr_free (&cstr);
1452 cstr_new(&cstr);
1453 cstr_printf(&cstr,
1454 "extern char *__tcov_data[];"
1455 "extern void __store_test_coverage ();"
1456 "__attribute__((destructor)) static void __tcov_exit() {"
1457 "__store_test_coverage(__tcov_data);"
1458 "}");
1459 tcc_compile_string_no_debug(s1, cstr.data);
1460 cstr_free(&cstr);
1461 set_local_sym(s1, &"___tcov_data"[!s1->leading_underscore], tcov_section, 0);
1464 #ifndef TCC_TARGET_PE
1465 /* add tcc runtime libraries */
1466 ST_FUNC void tcc_add_runtime(TCCState *s1)
1468 s1->filetype = 0;
1469 #ifdef CONFIG_TCC_BCHECK
1470 tcc_add_bcheck(s1);
1471 #endif
1472 tcc_add_pragma_libs(s1);
1473 /* add libc */
1474 if (!s1->nostdlib) {
1475 if (s1->option_pthread)
1476 tcc_add_library_err(s1, "pthread");
1477 tcc_add_library_err(s1, "c");
1478 #ifdef TCC_LIBGCC
1479 if (!s1->static_link) {
1480 if (TCC_LIBGCC[0] == '/')
1481 tcc_add_file(s1, TCC_LIBGCC);
1482 else
1483 tcc_add_dll(s1, TCC_LIBGCC, 0);
1485 #endif
1486 #if TCC_TARGET_ARM && TARGETOS_FreeBSD
1487 tcc_add_library_err(s1, "gcc_s"); // unwind code
1488 #endif
1489 #ifdef CONFIG_TCC_BCHECK
1490 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1491 tcc_add_library_err(s1, "pthread");
1492 #if !TARGETOS_OpenBSD && !TARGETOS_NetBSD
1493 tcc_add_library_err(s1, "dl");
1494 #endif
1495 tcc_add_support(s1, "bcheck.o");
1496 if (s1->static_link)
1497 tcc_add_library_err(s1, "c");
1499 #endif
1500 #ifdef CONFIG_TCC_BACKTRACE
1501 if (s1->do_backtrace) {
1502 if (s1->output_type == TCC_OUTPUT_EXE)
1503 tcc_add_support(s1, "bt-exe.o");
1504 if (s1->output_type != TCC_OUTPUT_DLL)
1505 tcc_add_support(s1, "bt-log.o");
1506 if (s1->output_type != TCC_OUTPUT_MEMORY)
1507 tcc_add_btstub(s1);
1509 #endif
1510 if (TCC_LIBTCC1[0])
1511 tcc_add_support(s1, TCC_LIBTCC1);
1513 #if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO
1514 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
1515 /* add crt end if not memory output */
1516 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1517 if (s1->output_type == TCC_OUTPUT_DLL)
1518 tcc_add_crt(s1, "crtendS.o");
1519 else
1520 tcc_add_crt(s1, "crtend.o");
1521 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
1522 tcc_add_crt(s1, "crtn.o");
1523 #endif
1525 #elif !defined(TCC_TARGET_MACHO)
1526 /* add crt end if not memory output */
1527 if (s1->output_type != TCC_OUTPUT_MEMORY)
1528 tcc_add_crt(s1, "crtn.o");
1529 #endif
1530 #endif
1533 #endif /* ndef TCC_TARGET_PE */
1535 /* add various standard linker symbols (must be done after the
1536 sections are filled (for example after allocating common
1537 symbols)) */
1538 static void tcc_add_linker_symbols(TCCState *s1)
1540 char buf[1024];
1541 int i;
1542 Section *s;
1544 set_global_sym(s1, "_etext", text_section, -1);
1545 set_global_sym(s1, "_edata", data_section, -1);
1546 set_global_sym(s1, "_end", bss_section, -1);
1547 #if TARGETOS_OpenBSD
1548 set_global_sym(s1, "__executable_start", NULL, ELF_START_ADDR);
1549 #endif
1550 #ifdef TCC_TARGET_RISCV64
1551 /* XXX should be .sdata+0x800, not .data+0x800 */
1552 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1553 #endif
1554 /* horrible new standard ldscript defines */
1555 #ifndef TCC_TARGET_PE
1556 add_init_array_defines(s1, ".preinit_array");
1557 #endif
1558 add_init_array_defines(s1, ".init_array");
1559 add_init_array_defines(s1, ".fini_array");
1560 /* add start and stop symbols for sections whose name can be
1561 expressed in C */
1562 for(i = 1; i < s1->nb_sections; i++) {
1563 s = s1->sections[i];
1564 if ((s->sh_flags & SHF_ALLOC)
1565 && (s->sh_type == SHT_PROGBITS
1566 || s->sh_type == SHT_STRTAB)) {
1567 const char *p;
1568 /* check if section name can be expressed in C */
1569 p = s->name;
1570 for(;;) {
1571 int c = *p;
1572 if (!c)
1573 break;
1574 if (!isid(c) && !isnum(c))
1575 goto next_sec;
1576 p++;
1578 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1579 set_global_sym(s1, buf, s, 0);
1580 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1581 set_global_sym(s1, buf, s, -1);
1583 next_sec: ;
1587 ST_FUNC void resolve_common_syms(TCCState *s1)
1589 ElfW(Sym) *sym;
1591 /* Allocate common symbols in BSS. */
1592 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1593 if (sym->st_shndx == SHN_COMMON) {
1594 /* symbol alignment is in st_value for SHN_COMMONs */
1595 sym->st_value = section_add(bss_section, sym->st_size,
1596 sym->st_value);
1597 sym->st_shndx = bss_section->sh_num;
1601 /* Now assign linker provided symbols their value. */
1602 tcc_add_linker_symbols(s1);
1605 #ifndef ELF_OBJ_ONLY
1606 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1608 int sym_index = ELFW(R_SYM) (rel->r_info);
1609 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1610 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1611 unsigned offset = attr->got_offset;
1613 if (0 == offset)
1614 return;
1615 section_reserve(s1->got, offset + PTR_SIZE);
1616 #if PTR_SIZE == 8
1617 write64le(s1->got->data + offset, sym->st_value);
1618 #else
1619 write32le(s1->got->data + offset, sym->st_value);
1620 #endif
1623 /* Perform relocation to GOT or PLT entries */
1624 ST_FUNC void fill_got(TCCState *s1)
1626 Section *s;
1627 ElfW_Rel *rel;
1628 int i;
1630 for(i = 1; i < s1->nb_sections; i++) {
1631 s = s1->sections[i];
1632 if (s->sh_type != SHT_RELX)
1633 continue;
1634 /* no need to handle got relocations */
1635 if (s->link != symtab_section)
1636 continue;
1637 for_each_elem(s, 0, rel, ElfW_Rel) {
1638 switch (ELFW(R_TYPE) (rel->r_info)) {
1639 case R_X86_64_GOT32:
1640 case R_X86_64_GOTPCREL:
1641 case R_X86_64_GOTPCRELX:
1642 case R_X86_64_REX_GOTPCRELX:
1643 case R_X86_64_PLT32:
1644 fill_got_entry(s1, rel);
1645 break;
1651 /* See put_got_entry for a description. This is the second stage
1652 where GOT references to local defined symbols are rewritten. */
1653 static void fill_local_got_entries(TCCState *s1)
1655 ElfW_Rel *rel;
1656 if (!s1->got->reloc)
1657 return;
1658 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1659 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1660 int sym_index = ELFW(R_SYM) (rel->r_info);
1661 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1662 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1663 unsigned offset = attr->got_offset;
1664 if (offset != rel->r_offset - s1->got->sh_addr)
1665 tcc_error_noabort("huh");
1666 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1667 #if SHT_RELX == SHT_RELA
1668 rel->r_addend = sym->st_value;
1669 #else
1670 /* All our REL architectures also happen to be 32bit LE. */
1671 write32le(s1->got->data + offset, sym->st_value);
1672 #endif
1677 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1678 in shared libraries and export non local defined symbols to shared libraries
1679 if -rdynamic switch was given on command line */
1680 static void bind_exe_dynsyms(TCCState *s1)
1682 const char *name;
1683 int sym_index, index;
1684 ElfW(Sym) *sym, *esym;
1685 int type;
1687 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1688 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1689 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1690 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1691 if (sym->st_shndx == SHN_UNDEF) {
1692 name = (char *) symtab_section->link->data + sym->st_name;
1693 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1694 if (sym_index) {
1695 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1696 type = ELFW(ST_TYPE)(esym->st_info);
1697 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1698 /* Indirect functions shall have STT_FUNC type in executable
1699 * dynsym section. Indeed, a dlsym call following a lazy
1700 * resolution would pick the symbol value from the
1701 * executable dynsym entry which would contain the address
1702 * of the function wanted by the caller of dlsym instead of
1703 * the address of the function that would return that
1704 * address */
1705 int dynindex
1706 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1707 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1708 name);
1709 int index = sym - (ElfW(Sym) *) symtab_section->data;
1710 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1711 } else if (type == STT_OBJECT) {
1712 unsigned long offset;
1713 ElfW(Sym) *dynsym;
1714 offset = bss_section->data_offset;
1715 /* XXX: which alignment ? */
1716 offset = (offset + 16 - 1) & -16;
1717 set_elf_sym (s1->symtab, offset, esym->st_size,
1718 esym->st_info, 0, bss_section->sh_num, name);
1719 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1720 esym->st_info, 0, bss_section->sh_num,
1721 name);
1723 /* Ensure R_COPY works for weak symbol aliases */
1724 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1725 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1726 if ((dynsym->st_value == esym->st_value)
1727 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1728 char *dynname = (char *) s1->dynsymtab_section->link->data
1729 + dynsym->st_name;
1730 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1731 dynsym->st_info, 0,
1732 bss_section->sh_num, dynname);
1733 break;
1738 put_elf_reloc(s1->dynsym, bss_section,
1739 offset, R_COPY, index);
1740 offset += esym->st_size;
1741 bss_section->data_offset = offset;
1743 } else {
1744 /* STB_WEAK undefined symbols are accepted */
1745 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1746 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1747 !strcmp(name, "_fp_hw")) {
1748 } else {
1749 tcc_error_noabort("undefined symbol '%s'", name);
1752 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1753 /* if -rdynamic option, then export all non local symbols */
1754 name = (char *) symtab_section->link->data + sym->st_name;
1755 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1756 0, sym->st_shndx, name);
1761 /* Bind symbols of libraries: export all non local symbols of executable that
1762 are referenced by shared libraries. The reason is that the dynamic loader
1763 search symbol first in executable and then in libraries. Therefore a
1764 reference to a symbol already defined by a library can still be resolved by
1765 a symbol in the executable. */
1766 static void bind_libs_dynsyms(TCCState *s1)
1768 const char *name;
1769 int sym_index;
1770 ElfW(Sym) *sym, *esym;
1772 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1773 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1774 sym_index = find_elf_sym(symtab_section, name);
1775 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1776 if (sym_index && sym->st_shndx != SHN_UNDEF
1777 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1778 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1779 sym->st_info, 0, sym->st_shndx, name);
1780 } else if (esym->st_shndx == SHN_UNDEF) {
1781 /* weak symbols can stay undefined */
1782 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1783 tcc_warning("undefined dynamic symbol '%s'", name);
1788 /* Export all non local symbols. This is used by shared libraries so that the
1789 non local symbols they define can resolve a reference in another shared
1790 library or in the executable. Correspondingly, it allows undefined local
1791 symbols to be resolved by other shared libraries or by the executable. */
1792 static void export_global_syms(TCCState *s1)
1794 int dynindex, index;
1795 const char *name;
1796 ElfW(Sym) *sym;
1798 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1799 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1800 name = (char *) symtab_section->link->data + sym->st_name;
1801 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1802 sym->st_info, 0, sym->st_shndx, name);
1803 index = sym - (ElfW(Sym) *) symtab_section->data;
1804 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1809 /* decide if an unallocated section should be output. */
1810 static int set_sec_sizes(TCCState *s1)
1812 int i;
1813 Section *s;
1814 int textrel = 0;
1815 int file_type = s1->output_type;
1817 /* Allocate strings for section names */
1818 for(i = 1; i < s1->nb_sections; i++) {
1819 s = s1->sections[i];
1820 if (s->sh_type == SHT_RELX && !(s->sh_flags & SHF_ALLOC)) {
1821 /* when generating a DLL, we include relocations but
1822 we may patch them */
1823 if (file_type == TCC_OUTPUT_DLL
1824 && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) {
1825 int count = prepare_dynamic_rel(s1, s);
1826 if (count) {
1827 /* allocate the section */
1828 s->sh_flags |= SHF_ALLOC;
1829 s->sh_size = count * sizeof(ElfW_Rel);
1830 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1831 textrel = 1;
1834 } else if ((s->sh_flags & SHF_ALLOC)
1835 #ifdef TCC_TARGET_ARM
1836 || s->sh_type == SHT_ARM_ATTRIBUTES
1837 #endif
1838 || s1->do_debug) {
1839 s->sh_size = s->data_offset;
1842 #ifdef TCC_TARGET_ARM
1843 /* XXX: Suppress stack unwinding section. */
1844 if (s->sh_type == SHT_ARM_EXIDX) {
1845 s->sh_flags = 0;
1846 s->sh_size = 0;
1848 #endif
1851 return textrel;
1855 /* Info to be copied in dynamic section */
1856 struct dyn_inf {
1857 Section *dynamic;
1858 Section *dynstr;
1859 unsigned long data_offset;
1860 addr_t rel_addr;
1861 addr_t rel_size;
1864 /* Info for GNU_RELRO */
1865 struct ro_inf {
1866 addr_t sh_offset;
1867 addr_t sh_addr;
1868 addr_t sh_size;
1871 static void alloc_sec_names(
1872 TCCState *s1, int is_obj
1875 static int layout_any_sections(
1876 TCCState *s1, int file_offset, int *sec_order, int is_obj
1879 /* Assign sections to segments and decide how are sections laid out when loaded
1880 in memory. This function also fills corresponding program headers. */
1881 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr,
1882 int phnum, int phfill,
1883 Section *interp,
1884 struct ro_inf *roinf, int *sec_order)
1886 int i, file_offset;
1887 Section *s;
1889 file_offset = 0;
1890 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1891 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1894 unsigned long s_align;
1895 long long tmp;
1896 addr_t addr;
1897 ElfW(Phdr) *ph;
1898 int j, k, f, file_type = s1->output_type;
1900 s_align = ELF_PAGE_SIZE;
1901 if (s1->section_align)
1902 s_align = s1->section_align;
1904 if (s1->has_text_addr) {
1905 int a_offset, p_offset;
1906 addr = s1->text_addr;
1907 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1908 ELF_PAGE_SIZE */
1909 a_offset = (int) (addr & (s_align - 1));
1910 p_offset = file_offset & (s_align - 1);
1911 if (a_offset < p_offset)
1912 a_offset += s_align;
1913 file_offset += (a_offset - p_offset);
1914 } else {
1915 if (file_type == TCC_OUTPUT_DLL)
1916 addr = 0;
1917 else
1918 addr = ELF_START_ADDR;
1919 /* compute address after headers */
1920 addr += (file_offset & (s_align - 1));
1923 ph = &phdr[0];
1924 /* Leave one program headers for the program interpreter and one for
1925 the program header table itself if needed. These are done later as
1926 they require section layout to be done first. */
1927 if (interp)
1928 ph += 2;
1930 /* read only segment mapping for GNU_RELRO */
1931 roinf->sh_offset = roinf->sh_addr = roinf->sh_size = 0;
1933 for(j = 0; j < phfill; j++) {
1934 ph->p_type = j == 2 ? PT_TLS : PT_LOAD;
1935 if (j == 0)
1936 ph->p_flags = PF_R | PF_X;
1937 else
1938 ph->p_flags = PF_R | PF_W;
1939 ph->p_align = j == 2 ? 4 : s_align;
1941 /* Decide the layout of sections loaded in memory. This must
1942 be done before program headers are filled since they contain
1943 info about the layout. We do the following ordering: interp,
1944 symbol tables, relocations, progbits, nobits */
1945 /* XXX: do faster and simpler sorting */
1946 f = -1;
1947 for(k = 0; k < 7; k++) {
1948 for(i = 1; i < s1->nb_sections; i++) {
1949 s = s1->sections[i];
1950 /* compute if section should be included */
1951 if (j == 0) {
1952 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1953 SHF_ALLOC)
1954 continue;
1955 } else if (j == 1) {
1956 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1957 (SHF_ALLOC | SHF_WRITE))
1958 continue;
1959 } else {
1960 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1961 (SHF_ALLOC | SHF_WRITE | SHF_TLS))
1962 continue;
1964 if (s == interp) {
1965 if (k != 0)
1966 continue;
1967 } else if ((s->sh_type == SHT_DYNSYM ||
1968 s->sh_type == SHT_STRTAB ||
1969 s->sh_type == SHT_HASH)
1970 && !strstr(s->name, ".stab")) {
1971 if (k != 1)
1972 continue;
1973 } else if (s->sh_type == SHT_RELX) {
1974 if (s1->plt && s == s1->plt->reloc) {
1975 if (k != 3)
1976 continue;
1977 } else {
1978 if (k != 2)
1979 continue;
1981 } else if (s->sh_type == SHT_NOBITS) {
1982 if (k != 6)
1983 continue;
1984 } else if ((s == rodata_section
1985 #ifdef CONFIG_TCC_BCHECK
1986 || s == bounds_section
1987 || s == lbounds_section
1988 #endif
1989 ) && (s->sh_flags & SHF_WRITE)) {
1990 if (k != 4)
1991 continue;
1992 /* Align next section on page size.
1993 This is needed to remap roinf section ro. */
1994 f = 1;
1995 } else {
1996 if (k != 5)
1997 continue;
1999 *sec_order++ = i;
2001 /* section matches: we align it and add its size */
2002 tmp = addr;
2003 if (f-- == 0)
2004 s->sh_addralign = PAGESIZE;
2005 addr = (addr + s->sh_addralign - 1) &
2006 ~(s->sh_addralign - 1);
2007 file_offset += (int) ( addr - tmp );
2008 s->sh_offset = file_offset;
2009 s->sh_addr = addr;
2011 /* update program header infos */
2012 if (ph->p_offset == 0) {
2013 ph->p_offset = file_offset;
2014 ph->p_vaddr = addr;
2015 ph->p_paddr = ph->p_vaddr;
2018 if (k == 4) {
2019 if (roinf->sh_size == 0) {
2020 roinf->sh_offset = s->sh_offset;
2021 roinf->sh_addr = s->sh_addr;
2023 roinf->sh_size = (addr - roinf->sh_addr) + s->sh_size;
2026 addr += s->sh_size;
2027 if (s->sh_type != SHT_NOBITS)
2028 file_offset += s->sh_size;
2031 if (j == 0) {
2032 /* Make the first PT_LOAD segment include the program
2033 headers itself (and the ELF header as well), it'll
2034 come out with same memory use but will make various
2035 tools like binutils strip work better. */
2036 ph->p_offset &= ~(ph->p_align - 1);
2037 ph->p_vaddr &= ~(ph->p_align - 1);
2038 ph->p_paddr &= ~(ph->p_align - 1);
2040 ph->p_filesz = file_offset - ph->p_offset;
2041 ph->p_memsz = addr - ph->p_vaddr;
2042 ph++;
2043 if (j == 0) {
2044 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
2045 /* if in the middle of a page, we duplicate the page in
2046 memory so that one copy is RX and the other is RW */
2047 if ((addr & (s_align - 1)) != 0)
2048 addr += s_align;
2049 } else {
2050 addr = (addr + s_align - 1) & ~(s_align - 1);
2051 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
2057 /* all other sections come after */
2058 return layout_any_sections(s1, file_offset, sec_order, 0);
2061 /* put dynamic tag */
2062 static void put_dt(Section *dynamic, int dt, addr_t val)
2064 ElfW(Dyn) *dyn;
2065 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
2066 dyn->d_tag = dt;
2067 dyn->d_un.d_val = val;
2070 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
2071 Section *dynamic, Section *note, struct ro_inf *roinf)
2073 ElfW(Phdr) *ph;
2075 /* if interpreter, then add corresponding program header */
2076 if (interp) {
2077 ph = &phdr[0];
2079 ph->p_type = PT_PHDR;
2080 ph->p_offset = sizeof(ElfW(Ehdr));
2081 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
2082 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
2083 ph->p_paddr = ph->p_vaddr;
2084 ph->p_flags = PF_R | PF_X;
2085 ph->p_align = 4; /* interp->sh_addralign; */
2086 ph++;
2088 ph->p_type = PT_INTERP;
2089 ph->p_offset = interp->sh_offset;
2090 ph->p_vaddr = interp->sh_addr;
2091 ph->p_paddr = ph->p_vaddr;
2092 ph->p_filesz = interp->sh_size;
2093 ph->p_memsz = interp->sh_size;
2094 ph->p_flags = PF_R;
2095 ph->p_align = interp->sh_addralign;
2098 if (note) {
2099 ph = &phdr[phnum - 2 - (roinf != NULL)];
2101 ph->p_type = PT_NOTE;
2102 ph->p_offset = note->sh_offset;
2103 ph->p_vaddr = note->sh_addr;
2104 ph->p_paddr = ph->p_vaddr;
2105 ph->p_filesz = note->sh_size;
2106 ph->p_memsz = note->sh_size;
2107 ph->p_flags = PF_R;
2108 ph->p_align = note->sh_addralign;
2111 /* if dynamic section, then add corresponding program header */
2112 if (dynamic) {
2113 ph = &phdr[phnum - 1 - (roinf != NULL)];
2115 ph->p_type = PT_DYNAMIC;
2116 ph->p_offset = dynamic->sh_offset;
2117 ph->p_vaddr = dynamic->sh_addr;
2118 ph->p_paddr = ph->p_vaddr;
2119 ph->p_filesz = dynamic->sh_size;
2120 ph->p_memsz = dynamic->sh_size;
2121 ph->p_flags = PF_R | PF_W;
2122 ph->p_align = dynamic->sh_addralign;
2125 if (roinf) {
2126 ph = &phdr[phnum - 1];
2128 ph->p_type = PT_GNU_RELRO;
2129 ph->p_offset = roinf->sh_offset;
2130 ph->p_vaddr = roinf->sh_addr;
2131 ph->p_paddr = ph->p_vaddr;
2132 ph->p_filesz = roinf->sh_size;
2133 ph->p_memsz = roinf->sh_size;
2134 ph->p_flags = PF_R;
2135 ph->p_align = 1;
2139 /* Fill the dynamic section with tags describing the address and size of
2140 sections */
2141 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2143 Section *dynamic = dyninf->dynamic;
2144 Section *s;
2146 /* put dynamic section entries */
2147 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2148 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2149 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2150 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2151 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2152 #if PTR_SIZE == 8
2153 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2154 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2155 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2156 if (s1->plt && s1->plt->reloc) {
2157 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2158 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2159 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2160 put_dt(dynamic, DT_PLTREL, DT_RELA);
2162 put_dt(dynamic, DT_RELACOUNT, 0);
2163 #else
2164 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2165 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2166 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2167 if (s1->plt && s1->plt->reloc) {
2168 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2169 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2170 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2171 put_dt(dynamic, DT_PLTREL, DT_REL);
2173 put_dt(dynamic, DT_RELCOUNT, 0);
2174 #endif
2175 if (versym_section && verneed_section) {
2176 /* The dynamic linker can not handle VERSYM without VERNEED */
2177 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2178 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2179 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2181 s = find_section_create (s1, ".preinit_array", 0);
2182 if (s && s->data_offset) {
2183 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2184 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2186 s = find_section_create (s1, ".init_array", 0);
2187 if (s && s->data_offset) {
2188 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2189 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2191 s = find_section_create (s1, ".fini_array", 0);
2192 if (s && s->data_offset) {
2193 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2194 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2196 s = find_section_create (s1, ".init", 0);
2197 if (s && s->data_offset) {
2198 put_dt(dynamic, DT_INIT, s->sh_addr);
2200 s = find_section_create (s1, ".fini", 0);
2201 if (s && s->data_offset) {
2202 put_dt(dynamic, DT_FINI, s->sh_addr);
2204 if (s1->do_debug)
2205 put_dt(dynamic, DT_DEBUG, 0);
2206 put_dt(dynamic, DT_NULL, 0);
2209 /* Remove gaps between RELX sections.
2210 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2211 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2212 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2213 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2214 static void update_reloc_sections(TCCState *s1, struct dyn_inf *dyninf)
2216 int i;
2217 unsigned long file_offset = 0;
2218 Section *s;
2219 Section *relocplt = s1->plt ? s1->plt->reloc : NULL;
2221 /* dynamic relocation table information, for .dynamic section */
2222 dyninf->rel_addr = dyninf->rel_size = 0;
2224 for(i = 1; i < s1->nb_sections; i++) {
2225 s = s1->sections[i];
2226 if (s->sh_type == SHT_RELX && s != relocplt) {
2227 if (dyninf->rel_size == 0) {
2228 dyninf->rel_addr = s->sh_addr;
2229 file_offset = s->sh_offset;
2231 else {
2232 s->sh_addr = dyninf->rel_addr + dyninf->rel_size;
2233 s->sh_offset = file_offset + dyninf->rel_size;
2235 dyninf->rel_size += s->sh_size;
2240 #endif /* ndef ELF_OBJ_ONLY */
2242 /* Create an ELF file on disk.
2243 This function handle ELF specific layout requirements */
2244 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2245 int file_offset, int *sec_order)
2247 int i, shnum, offset, size, file_type;
2248 Section *s;
2249 ElfW(Ehdr) ehdr;
2250 ElfW(Shdr) shdr, *sh;
2252 file_type = s1->output_type;
2253 shnum = s1->nb_sections;
2255 memset(&ehdr, 0, sizeof(ehdr));
2257 if (phnum > 0) {
2258 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2259 ehdr.e_phnum = phnum;
2260 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2263 /* align to 4 */
2264 file_offset = (file_offset + 3) & -4;
2266 /* fill header */
2267 ehdr.e_ident[0] = ELFMAG0;
2268 ehdr.e_ident[1] = ELFMAG1;
2269 ehdr.e_ident[2] = ELFMAG2;
2270 ehdr.e_ident[3] = ELFMAG3;
2271 ehdr.e_ident[4] = ELFCLASSW;
2272 ehdr.e_ident[5] = ELFDATA2LSB;
2273 ehdr.e_ident[6] = EV_CURRENT;
2274 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2275 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2276 #endif
2277 #ifdef TCC_TARGET_ARM
2278 #ifdef TCC_ARM_EABI
2279 ehdr.e_ident[EI_OSABI] = 0;
2280 ehdr.e_flags = EF_ARM_EABI_VER4;
2281 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2282 ehdr.e_flags |= EF_ARM_HASENTRY;
2283 if (s1->float_abi == ARM_HARD_FLOAT)
2284 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2285 else
2286 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2287 #else
2288 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2289 #endif
2290 #elif defined TCC_TARGET_RISCV64
2291 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2292 #endif
2293 switch(file_type) {
2294 default:
2295 case TCC_OUTPUT_EXE:
2296 ehdr.e_type = ET_EXEC;
2297 ehdr.e_entry = get_sym_addr(s1,
2298 s1->elf_entryname ?
2299 s1->elf_entryname : "_start",
2300 1, 0);
2301 break;
2302 case TCC_OUTPUT_DLL:
2303 ehdr.e_type = ET_DYN;
2304 ehdr.e_entry = s1->elf_entryname ?
2305 get_sym_addr(s1,s1->elf_entryname,1,0) :
2306 text_section->sh_addr;
2307 /* XXX: is it correct ? */
2308 break;
2309 case TCC_OUTPUT_OBJ:
2310 ehdr.e_type = ET_REL;
2311 break;
2313 ehdr.e_machine = EM_TCC_TARGET;
2314 ehdr.e_version = EV_CURRENT;
2315 ehdr.e_shoff = file_offset;
2316 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2317 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2318 ehdr.e_shnum = shnum;
2319 ehdr.e_shstrndx = shnum - 1;
2321 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2322 if (phdr)
2323 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2324 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2326 sort_syms(s1, symtab_section);
2327 for(i = 1; i < s1->nb_sections; i++) {
2328 s = s1->sections[sec_order[i]];
2329 if (s->sh_type != SHT_NOBITS) {
2330 while (offset < s->sh_offset) {
2331 fputc(0, f);
2332 offset++;
2334 size = s->sh_size;
2335 if (size)
2336 fwrite(s->data, 1, size, f);
2337 offset += size;
2341 /* output section headers */
2342 while (offset < ehdr.e_shoff) {
2343 fputc(0, f);
2344 offset++;
2347 for(i = 0; i < s1->nb_sections; i++) {
2348 sh = &shdr;
2349 memset(sh, 0, sizeof(ElfW(Shdr)));
2350 s = s1->sections[i];
2351 if (s) {
2352 sh->sh_name = s->sh_name;
2353 sh->sh_type = s->sh_type;
2354 sh->sh_flags = s->sh_flags;
2355 sh->sh_entsize = s->sh_entsize;
2356 sh->sh_info = s->sh_info;
2357 if (s->link)
2358 sh->sh_link = s->link->sh_num;
2359 sh->sh_addralign = s->sh_addralign;
2360 sh->sh_addr = s->sh_addr;
2361 sh->sh_offset = s->sh_offset;
2362 sh->sh_size = s->sh_size;
2364 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2368 static void tcc_output_binary(TCCState *s1, FILE *f,
2369 const int *sec_order)
2371 Section *s;
2372 int i, offset, size;
2374 offset = 0;
2375 for(i=1;i<s1->nb_sections;i++) {
2376 s = s1->sections[sec_order[i]];
2377 if (s->sh_type != SHT_NOBITS &&
2378 (s->sh_flags & SHF_ALLOC)) {
2379 while (offset < s->sh_offset) {
2380 fputc(0, f);
2381 offset++;
2383 size = s->sh_size;
2384 fwrite(s->data, 1, size, f);
2385 offset += size;
2390 /* Write an elf, coff or "binary" file */
2391 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2392 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2394 int fd, mode, file_type;
2395 FILE *f;
2397 file_type = s1->output_type;
2398 if (file_type == TCC_OUTPUT_OBJ)
2399 mode = 0666;
2400 else
2401 mode = 0777;
2402 unlink(filename);
2403 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2404 if (fd < 0 || (f = fdopen(fd, "wb")) == NULL) {
2405 tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno));
2406 return -1;
2408 if (s1->verbose)
2409 printf("<- %s\n", filename);
2411 #ifdef TCC_TARGET_COFF
2412 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2413 tcc_output_coff(s1, f);
2414 else
2415 #endif
2416 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2417 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2418 else
2419 tcc_output_binary(s1, f, sec_order);
2420 fclose(f);
2422 return 0;
2425 #ifndef ELF_OBJ_ONLY
2426 /* Sort section headers by assigned sh_addr, remove sections
2427 that we aren't going to output. */
2428 static void tidy_section_headers(TCCState *s1, int *sec_order)
2430 int i, nnew, l, *backmap;
2431 Section **snew, *s;
2432 ElfW(Sym) *sym;
2434 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2435 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2436 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2437 s = s1->sections[sec_order[i]];
2438 if (!i || s->sh_name) {
2439 backmap[sec_order[i]] = nnew;
2440 snew[nnew] = s;
2441 ++nnew;
2442 } else {
2443 backmap[sec_order[i]] = 0;
2444 snew[--l] = s;
2447 for (i = 0; i < nnew; i++) {
2448 s = snew[i];
2449 if (s) {
2450 s->sh_num = i;
2451 if (s->sh_type == SHT_RELX)
2452 s->sh_info = backmap[s->sh_info];
2456 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2457 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2458 sym->st_shndx = backmap[sym->st_shndx];
2459 if ( !s1->static_link ) {
2460 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2461 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2462 sym->st_shndx = backmap[sym->st_shndx];
2464 for (i = 0; i < s1->nb_sections; i++)
2465 sec_order[i] = i;
2466 tcc_free(s1->sections);
2467 s1->sections = snew;
2468 s1->nb_sections = nnew;
2469 tcc_free(backmap);
2472 #ifdef TCC_TARGET_ARM
2473 static void create_arm_attribute_section(TCCState *s1)
2475 // Needed for DLL support.
2476 static const unsigned char arm_attr[] = {
2477 0x41, // 'A'
2478 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2479 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2480 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2481 0x05, 0x36, 0x00, // 'CPU_name', "6"
2482 0x06, 0x06, // 'CPU_arch', 'v6'
2483 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2484 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2485 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2486 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2487 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2488 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2489 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2490 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2491 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2492 0x1a, 0x02, // 'ABI_enum_size', 'int'
2493 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2494 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2496 Section *attr = new_section(s1, ".ARM.attributes", SHT_ARM_ATTRIBUTES, 0);
2497 unsigned char *ptr = section_ptr_add(attr, sizeof(arm_attr));
2498 attr->sh_addralign = 1;
2499 memcpy(ptr, arm_attr, sizeof(arm_attr));
2500 if (s1->float_abi != ARM_HARD_FLOAT) {
2501 ptr[26] = 0x00; // 'FP_arch', 'No'
2502 ptr[41] = 0x1e; // 'ABI_optimization_goals'
2503 ptr[42] = 0x06; // 'Aggressive Debug'
2506 #endif
2508 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2509 static Section *create_bsd_note_section(TCCState *s1,
2510 const char *name,
2511 const char *value)
2513 Section *s = find_section (s1, name);
2515 if (s->data_offset == 0) {
2516 char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
2517 ElfW(Nhdr) *note = (ElfW(Nhdr) *) ptr;
2519 s->sh_type = SHT_NOTE;
2520 note->n_namesz = 8;
2521 note->n_descsz = 4;
2522 note->n_type = ELF_NOTE_OS_GNU;
2523 strcpy (ptr + sizeof(ElfW(Nhdr)), value);
2525 return s;
2527 #endif
2529 /* Output an elf, coff or binary file */
2530 /* XXX: suppress unneeded sections */
2531 static int elf_output_file(TCCState *s1, const char *filename)
2533 int i, ret, phnum, phfill, shnum, file_type, file_offset, *sec_order;
2534 struct dyn_inf dyninf = {0};
2535 struct ro_inf roinf;
2536 ElfW(Phdr) *phdr;
2537 Section *interp, *dynamic, *dynstr, *note;
2538 struct ro_inf *roinf_use = NULL;
2539 int textrel;
2541 file_type = s1->output_type;
2542 s1->nb_errors = 0;
2543 ret = -1;
2544 phdr = NULL;
2545 sec_order = NULL;
2546 interp = dynamic = dynstr = note = NULL;
2548 #ifdef TCC_TARGET_ARM
2549 create_arm_attribute_section (s1);
2550 #endif
2552 #if TARGETOS_OpenBSD
2553 note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
2554 #endif
2556 #if TARGETOS_NetBSD
2557 note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD");
2558 #endif
2561 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2562 tcc_add_runtime(s1);
2563 resolve_common_syms(s1);
2565 if (!s1->static_link) {
2566 if (file_type == TCC_OUTPUT_EXE) {
2567 char *ptr;
2568 /* allow override the dynamic loader */
2569 const char *elfint = getenv("LD_SO");
2570 if (elfint == NULL)
2571 elfint = DEFAULT_ELFINTERP(s1);
2572 /* add interpreter section only if executable */
2573 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2574 interp->sh_addralign = 1;
2575 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2576 strcpy(ptr, elfint);
2579 /* add dynamic symbol table */
2580 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2581 ".dynstr",
2582 ".hash", SHF_ALLOC);
2583 /* Number of local symbols (readelf complains if not set) */
2584 s1->dynsym->sh_info = 1;
2585 dynstr = s1->dynsym->link;
2586 /* add dynamic section */
2587 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2588 SHF_ALLOC | SHF_WRITE);
2589 dynamic->link = dynstr;
2590 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2592 build_got(s1);
2594 if (file_type == TCC_OUTPUT_EXE) {
2595 bind_exe_dynsyms(s1);
2596 if (s1->nb_errors)
2597 goto the_end;
2598 bind_libs_dynsyms(s1);
2599 } else {
2600 /* shared library case: simply export all global symbols */
2601 export_global_syms(s1);
2604 build_got_entries(s1);
2605 version_add (s1);
2608 textrel = set_sec_sizes(s1);
2609 alloc_sec_names(s1, 0);
2611 if (!s1->static_link) {
2612 int i;
2613 /* add a list of needed dlls */
2614 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2615 DLLReference *dllref = s1->loaded_dlls[i];
2616 if (dllref->level == 0)
2617 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2620 if (s1->rpath)
2621 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2622 put_elf_str(dynstr, s1->rpath));
2624 if (file_type == TCC_OUTPUT_DLL) {
2625 if (s1->soname)
2626 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2627 /* XXX: currently, since we do not handle PIC code, we
2628 must relocate the readonly segments */
2629 if (textrel)
2630 put_dt(dynamic, DT_TEXTREL, 0);
2633 if (s1->symbolic)
2634 put_dt(dynamic, DT_SYMBOLIC, 0);
2636 dyninf.dynamic = dynamic;
2637 dyninf.dynstr = dynstr;
2638 /* remember offset and reserve space for 2nd call below */
2639 dyninf.data_offset = dynamic->data_offset;
2640 fill_dynamic(s1, &dyninf);
2641 dynamic->sh_size = dynamic->data_offset;
2642 dynstr->sh_size = dynstr->data_offset;
2645 for (i = 1; i < s1->nb_sections &&
2646 !(s1->sections[i]->sh_flags & SHF_TLS); i++);
2647 phfill = 2 + (i < s1->nb_sections);
2649 /* compute number of program headers */
2650 if (file_type == TCC_OUTPUT_DLL)
2651 phnum = 3;
2652 else if (s1->static_link)
2653 phnum = 3;
2654 else {
2655 phnum = 5 + (i < s1->nb_sections);
2658 phnum += note != NULL;
2659 #if !TARGETOS_FreeBSD && !TARGETOS_NetBSD
2660 /* GNU_RELRO */
2661 phnum++, roinf_use = &roinf;
2662 #endif
2664 /* allocate program segment headers */
2665 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2666 /* compute number of sections */
2667 shnum = s1->nb_sections;
2668 /* this array is used to reorder sections in the output file */
2669 sec_order = tcc_malloc(sizeof(int) * shnum);
2670 sec_order[0] = 0;
2672 /* compute section to program header mapping */
2673 file_offset = layout_sections(s1, phdr, phnum, phfill, interp, &roinf, sec_order + 1);
2675 /* Fill remaining program header and finalize relocation related to dynamic
2676 linking. */
2678 fill_unloadable_phdr(phdr, phnum, interp, dynamic, note, roinf_use);
2679 if (dynamic) {
2680 ElfW(Sym) *sym;
2682 /* put in GOT the dynamic section address and relocate PLT */
2683 write32le(s1->got->data, dynamic->sh_addr);
2684 if (file_type == TCC_OUTPUT_EXE
2685 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2686 relocate_plt(s1);
2688 /* relocate symbols in .dynsym now that final addresses are known */
2689 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2690 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2691 /* do symbol relocation */
2692 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2697 /* if building executable or DLL, then relocate each section
2698 except the GOT which is already relocated */
2699 relocate_syms(s1, s1->symtab, 0);
2700 ret = -1;
2701 if (s1->nb_errors != 0)
2702 goto the_end;
2703 relocate_sections(s1);
2704 if (dynamic) {
2705 update_reloc_sections (s1, &dyninf);
2706 dynamic->data_offset = dyninf.data_offset;
2707 fill_dynamic(s1, &dyninf);
2709 tidy_section_headers(s1, sec_order);
2711 /* Perform relocation to GOT or PLT entries */
2712 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2713 fill_got(s1);
2714 else if (s1->got)
2715 fill_local_got_entries(s1);
2717 /* Create the ELF file with name 'filename' */
2718 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2719 s1->nb_sections = shnum;
2721 the_end:
2722 tcc_free(sec_order);
2723 tcc_free(phdr);
2724 return ret;
2726 #endif /* ndef ELF_OBJ_ONLY */
2728 /* Allocate strings for section names */
2729 static void alloc_sec_names(TCCState *s1, int is_obj)
2731 int i;
2732 Section *s, *strsec;
2734 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2735 put_elf_str(strsec, "");
2736 for(i = 1; i < s1->nb_sections; i++) {
2737 s = s1->sections[i];
2738 if (is_obj)
2739 s->sh_size = s->data_offset;
2740 if (s == strsec || s->sh_size || (s->sh_flags & SHF_ALLOC))
2741 s->sh_name = put_elf_str(strsec, s->name);
2743 strsec->sh_size = strsec->data_offset;
2746 static int layout_any_sections(TCCState *s1, int file_offset, int *sec_order, int is_obj)
2748 int i;
2749 Section *s;
2750 for(i = 1; i < s1->nb_sections; i++) {
2751 s = s1->sections[i];
2752 if (!is_obj && (s->sh_flags & SHF_ALLOC))
2753 continue;
2754 *sec_order++ = i;
2755 file_offset = (file_offset + s->sh_addralign - 1) &
2756 ~(s->sh_addralign - 1);
2757 s->sh_offset = file_offset;
2758 if (s->sh_type != SHT_NOBITS)
2759 file_offset += s->sh_size;
2761 return file_offset;
2764 /* Output an elf .o file */
2765 static int elf_output_obj(TCCState *s1, const char *filename)
2767 int ret, file_offset;
2768 int *sec_order;
2769 s1->nb_errors = 0;
2771 /* Allocate strings for section names */
2772 alloc_sec_names(s1, 1);
2774 /* this array is used to reorder sections in the output file */
2775 sec_order = tcc_malloc(sizeof(int) * s1->nb_sections);
2776 sec_order[0] = 0;
2777 file_offset = layout_any_sections(s1, sizeof (ElfW(Ehdr)), sec_order + 1, 1);
2779 /* Create the ELF file with name 'filename' */
2780 ret = tcc_write_elf_file(s1, filename, 0, NULL, file_offset, sec_order);
2781 tcc_free(sec_order);
2782 return ret;
2785 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2787 if (s->test_coverage)
2788 tcc_tcov_add_file(s, filename);
2789 if (s->output_type == TCC_OUTPUT_OBJ)
2790 return elf_output_obj(s, filename);
2791 #ifdef TCC_TARGET_PE
2792 return pe_output_file(s, filename);
2793 #elif TCC_TARGET_MACHO
2794 return macho_output_file(s, filename);
2795 #else
2796 return elf_output_file(s, filename);
2797 #endif
2800 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
2801 char *cbuf = buf;
2802 size_t rnum = 0;
2803 while (1) {
2804 ssize_t num = read(fd, cbuf, count-rnum);
2805 if (num < 0) return num;
2806 if (num == 0) return rnum;
2807 rnum += num;
2808 cbuf += num;
2812 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
2814 void *data;
2816 data = tcc_malloc(size);
2817 lseek(fd, file_offset, SEEK_SET);
2818 full_read(fd, data, size);
2819 return data;
2822 typedef struct SectionMergeInfo {
2823 Section *s; /* corresponding existing section */
2824 unsigned long offset; /* offset of the new section in the existing section */
2825 uint8_t new_section; /* true if section 's' was added */
2826 uint8_t link_once; /* true if link once section */
2827 } SectionMergeInfo;
2829 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2831 int size = full_read(fd, h, sizeof *h);
2832 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2833 if (h->e_type == ET_REL)
2834 return AFF_BINTYPE_REL;
2835 if (h->e_type == ET_DYN)
2836 return AFF_BINTYPE_DYN;
2837 } else if (size >= 8) {
2838 if (0 == memcmp(h, ARMAG, 8))
2839 return AFF_BINTYPE_AR;
2840 #ifdef TCC_TARGET_COFF
2841 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2842 return AFF_BINTYPE_C67;
2843 #endif
2845 return 0;
2848 /* load an object file and merge it with current files */
2849 /* XXX: handle correctly stab (debug) info */
2850 ST_FUNC int tcc_load_object_file(TCCState *s1,
2851 int fd, unsigned long file_offset)
2853 ElfW(Ehdr) ehdr;
2854 ElfW(Shdr) *shdr, *sh;
2855 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2856 char *strsec, *strtab;
2857 int stab_index, stabstr_index;
2858 int *old_to_new_syms;
2859 char *sh_name, *name;
2860 SectionMergeInfo *sm_table, *sm;
2861 ElfW(Sym) *sym, *symtab;
2862 ElfW_Rel *rel;
2863 Section *s;
2865 lseek(fd, file_offset, SEEK_SET);
2866 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2867 goto fail1;
2868 /* test CPU specific stuff */
2869 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2870 ehdr.e_machine != EM_TCC_TARGET) {
2871 fail1:
2872 tcc_error_noabort("invalid object file");
2873 return -1;
2875 /* read sections */
2876 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2877 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2878 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2880 /* load section names */
2881 sh = &shdr[ehdr.e_shstrndx];
2882 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2884 /* load symtab and strtab */
2885 old_to_new_syms = NULL;
2886 symtab = NULL;
2887 strtab = NULL;
2888 nb_syms = 0;
2889 seencompressed = 0;
2890 stab_index = stabstr_index = 0;
2892 for(i = 1; i < ehdr.e_shnum; i++) {
2893 sh = &shdr[i];
2894 if (sh->sh_type == SHT_SYMTAB) {
2895 if (symtab) {
2896 tcc_error_noabort("object must contain only one symtab");
2897 fail:
2898 ret = -1;
2899 goto the_end;
2901 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2902 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2903 sm_table[i].s = symtab_section;
2905 /* now load strtab */
2906 sh = &shdr[sh->sh_link];
2907 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2909 if (sh->sh_flags & SHF_COMPRESSED)
2910 seencompressed = 1;
2913 /* now examine each section and try to merge its content with the
2914 ones in memory */
2915 for(i = 1; i < ehdr.e_shnum; i++) {
2916 /* no need to examine section name strtab */
2917 if (i == ehdr.e_shstrndx)
2918 continue;
2919 sh = &shdr[i];
2920 if (sh->sh_type == SHT_RELX)
2921 sh = &shdr[sh->sh_info];
2922 /* ignore sections types we do not handle (plus relocs to those) */
2923 if (sh->sh_type != SHT_PROGBITS &&
2924 #ifdef TCC_ARM_EABI
2925 sh->sh_type != SHT_ARM_EXIDX &&
2926 #endif
2927 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2928 sh->sh_type != SHT_X86_64_UNWIND &&
2929 #endif
2930 sh->sh_type != SHT_NOTE &&
2931 sh->sh_type != SHT_NOBITS &&
2932 sh->sh_type != SHT_PREINIT_ARRAY &&
2933 sh->sh_type != SHT_INIT_ARRAY &&
2934 sh->sh_type != SHT_FINI_ARRAY &&
2935 strcmp(strsec + sh->sh_name, ".stabstr")
2937 continue;
2938 if (seencompressed && 0 == strncmp(strsec + sh->sh_name, ".debug_", 7))
2939 continue;
2941 sh = &shdr[i];
2942 sh_name = strsec + sh->sh_name;
2943 if (sh->sh_addralign < 1)
2944 sh->sh_addralign = 1;
2945 /* find corresponding section, if any */
2946 for(j = 1; j < s1->nb_sections;j++) {
2947 s = s1->sections[j];
2948 if (!strcmp(s->name, sh_name)) {
2949 if (!strncmp(sh_name, ".gnu.linkonce",
2950 sizeof(".gnu.linkonce") - 1)) {
2951 /* if a 'linkonce' section is already present, we
2952 do not add it again. It is a little tricky as
2953 symbols can still be defined in
2954 it. */
2955 sm_table[i].link_once = 1;
2956 goto next;
2958 if (stab_section) {
2959 if (s == stab_section)
2960 stab_index = i;
2961 if (s == stab_section->link)
2962 stabstr_index = i;
2964 goto found;
2967 /* not found: create new section */
2968 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2969 /* take as much info as possible from the section. sh_link and
2970 sh_info will be updated later */
2971 s->sh_addralign = sh->sh_addralign;
2972 s->sh_entsize = sh->sh_entsize;
2973 sm_table[i].new_section = 1;
2974 found:
2975 if (sh->sh_type != s->sh_type) {
2976 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2977 if (strcmp (s->name, ".eh_frame"))
2978 #endif
2980 tcc_error_noabort("invalid section type");
2981 goto fail;
2984 /* align start of section */
2985 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
2986 if (sh->sh_addralign > s->sh_addralign)
2987 s->sh_addralign = sh->sh_addralign;
2988 sm_table[i].offset = s->data_offset;
2989 sm_table[i].s = s;
2990 /* concatenate sections */
2991 size = sh->sh_size;
2992 if (sh->sh_type != SHT_NOBITS) {
2993 unsigned char *ptr;
2994 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2995 ptr = section_ptr_add(s, size);
2996 full_read(fd, ptr, size);
2997 } else {
2998 s->data_offset += size;
3000 next: ;
3003 /* gr relocate stab strings */
3004 if (stab_index && stabstr_index) {
3005 Stab_Sym *a, *b;
3006 unsigned o;
3007 s = sm_table[stab_index].s;
3008 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
3009 b = (Stab_Sym *)(s->data + s->data_offset);
3010 o = sm_table[stabstr_index].offset;
3011 while (a < b) {
3012 if (a->n_strx)
3013 a->n_strx += o;
3014 a++;
3018 /* second short pass to update sh_link and sh_info fields of new
3019 sections */
3020 for(i = 1; i < ehdr.e_shnum; i++) {
3021 s = sm_table[i].s;
3022 if (!s || !sm_table[i].new_section)
3023 continue;
3024 sh = &shdr[i];
3025 if (sh->sh_link > 0)
3026 s->link = sm_table[sh->sh_link].s;
3027 if (sh->sh_type == SHT_RELX) {
3028 s->sh_info = sm_table[sh->sh_info].s->sh_num;
3029 /* update backward link */
3030 s1->sections[s->sh_info]->reloc = s;
3034 /* resolve symbols */
3035 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
3037 sym = symtab + 1;
3038 for(i = 1; i < nb_syms; i++, sym++) {
3039 if (sym->st_shndx != SHN_UNDEF &&
3040 sym->st_shndx < SHN_LORESERVE) {
3041 sm = &sm_table[sym->st_shndx];
3042 if (sm->link_once) {
3043 /* if a symbol is in a link once section, we use the
3044 already defined symbol. It is very important to get
3045 correct relocations */
3046 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
3047 name = strtab + sym->st_name;
3048 sym_index = find_elf_sym(symtab_section, name);
3049 if (sym_index)
3050 old_to_new_syms[i] = sym_index;
3052 continue;
3054 /* if no corresponding section added, no need to add symbol */
3055 if (!sm->s)
3056 continue;
3057 /* convert section number */
3058 sym->st_shndx = sm->s->sh_num;
3059 /* offset value */
3060 sym->st_value += sm->offset;
3062 /* add symbol */
3063 name = strtab + sym->st_name;
3064 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
3065 sym->st_info, sym->st_other,
3066 sym->st_shndx, name);
3067 old_to_new_syms[i] = sym_index;
3070 /* third pass to patch relocation entries */
3071 for(i = 1; i < ehdr.e_shnum; i++) {
3072 s = sm_table[i].s;
3073 if (!s)
3074 continue;
3075 sh = &shdr[i];
3076 offset = sm_table[i].offset;
3077 size = sh->sh_size;
3078 switch(s->sh_type) {
3079 case SHT_RELX:
3080 /* take relocation offset information */
3081 offseti = sm_table[sh->sh_info].offset;
3082 for (rel = (ElfW_Rel *) s->data + (offset / sizeof(*rel));
3083 rel < (ElfW_Rel *) s->data + ((offset + size) / sizeof(*rel));
3084 rel++) {
3085 int type;
3086 unsigned sym_index;
3087 /* convert symbol index */
3088 type = ELFW(R_TYPE)(rel->r_info);
3089 sym_index = ELFW(R_SYM)(rel->r_info);
3090 /* NOTE: only one symtab assumed */
3091 if (sym_index >= nb_syms)
3092 goto invalid_reloc;
3093 sym_index = old_to_new_syms[sym_index];
3094 /* ignore link_once in rel section. */
3095 if (!sym_index && !sm_table[sh->sh_info].link_once
3096 #ifdef TCC_TARGET_ARM
3097 && type != R_ARM_V4BX
3098 #elif defined TCC_TARGET_RISCV64
3099 && type != R_RISCV_ALIGN
3100 && type != R_RISCV_RELAX
3101 #endif
3103 invalid_reloc:
3104 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3105 i, strsec + sh->sh_name, (int)rel->r_offset);
3106 goto fail;
3108 rel->r_info = ELFW(R_INFO)(sym_index, type);
3109 /* offset the relocation offset */
3110 rel->r_offset += offseti;
3111 #ifdef TCC_TARGET_ARM
3112 /* Jumps and branches from a Thumb code to a PLT entry need
3113 special handling since PLT entries are ARM code.
3114 Unconditional bl instructions referencing PLT entries are
3115 handled by converting these instructions into blx
3116 instructions. Other case of instructions referencing a PLT
3117 entry require to add a Thumb stub before the PLT entry to
3118 switch to ARM mode. We set bit plt_thumb_stub of the
3119 attribute of a symbol to indicate such a case. */
3120 if (type == R_ARM_THM_JUMP24)
3121 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
3122 #endif
3124 break;
3125 default:
3126 break;
3130 ret = 0;
3131 the_end:
3132 tcc_free(symtab);
3133 tcc_free(strtab);
3134 tcc_free(old_to_new_syms);
3135 tcc_free(sm_table);
3136 tcc_free(strsec);
3137 tcc_free(shdr);
3138 return ret;
3141 typedef struct ArchiveHeader {
3142 char ar_name[16]; /* name of this member */
3143 char ar_date[12]; /* file mtime */
3144 char ar_uid[6]; /* owner uid; printed as decimal */
3145 char ar_gid[6]; /* owner gid; printed as decimal */
3146 char ar_mode[8]; /* file mode, printed as octal */
3147 char ar_size[10]; /* file size, printed as decimal */
3148 char ar_fmag[2]; /* should contain ARFMAG */
3149 } ArchiveHeader;
3151 #define ARFMAG "`\n"
3153 static unsigned long long get_be(const uint8_t *b, int n)
3155 unsigned long long ret = 0;
3156 while (n)
3157 ret = (ret << 8) | *b++, --n;
3158 return ret;
3161 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
3163 char *p, *e;
3164 int len;
3165 lseek(fd, offset, SEEK_SET);
3166 len = full_read(fd, hdr, sizeof(ArchiveHeader));
3167 if (len != sizeof(ArchiveHeader))
3168 return len ? -1 : 0;
3169 p = hdr->ar_name;
3170 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
3171 --e;
3172 *e = '\0';
3173 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
3174 return len;
3177 /* load only the objects which resolve undefined symbols */
3178 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
3180 int i, bound, nsyms, sym_index, len, ret = -1;
3181 unsigned long long off;
3182 uint8_t *data;
3183 const char *ar_names, *p;
3184 const uint8_t *ar_index;
3185 ElfW(Sym) *sym;
3186 ArchiveHeader hdr;
3188 data = tcc_malloc(size);
3189 if (full_read(fd, data, size) != size)
3190 goto the_end;
3191 nsyms = get_be(data, entrysize);
3192 ar_index = data + entrysize;
3193 ar_names = (char *) ar_index + nsyms * entrysize;
3195 do {
3196 bound = 0;
3197 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
3198 Section *s = symtab_section;
3199 sym_index = find_elf_sym(s, p);
3200 if (!sym_index)
3201 continue;
3202 sym = &((ElfW(Sym) *)s->data)[sym_index];
3203 if(sym->st_shndx != SHN_UNDEF)
3204 continue;
3205 off = get_be(ar_index + i * entrysize, entrysize);
3206 len = read_ar_header(fd, off, &hdr);
3207 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
3208 tcc_error_noabort("invalid archive");
3209 goto the_end;
3211 off += len;
3212 if (s1->verbose == 2)
3213 printf(" -> %s\n", hdr.ar_name);
3214 if (tcc_load_object_file(s1, fd, off) < 0)
3215 goto the_end;
3216 ++bound;
3218 } while(bound);
3219 ret = 0;
3220 the_end:
3221 tcc_free(data);
3222 return ret;
3225 /* load a '.a' file */
3226 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
3228 ArchiveHeader hdr;
3229 /* char magic[8]; */
3230 int size, len;
3231 unsigned long file_offset;
3232 ElfW(Ehdr) ehdr;
3234 /* skip magic which was already checked */
3235 /* full_read(fd, magic, sizeof(magic)); */
3236 file_offset = sizeof ARMAG - 1;
3238 for(;;) {
3239 len = read_ar_header(fd, file_offset, &hdr);
3240 if (len == 0)
3241 return 0;
3242 if (len < 0) {
3243 tcc_error_noabort("invalid archive");
3244 return -1;
3246 file_offset += len;
3247 size = strtol(hdr.ar_size, NULL, 0);
3248 /* align to even */
3249 size = (size + 1) & ~1;
3250 if (alacarte) {
3251 /* coff symbol table : we handle it */
3252 if (!strcmp(hdr.ar_name, "/"))
3253 return tcc_load_alacarte(s1, fd, size, 4);
3254 if (!strcmp(hdr.ar_name, "/SYM64/"))
3255 return tcc_load_alacarte(s1, fd, size, 8);
3256 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3257 if (s1->verbose == 2)
3258 printf(" -> %s\n", hdr.ar_name);
3259 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3260 return -1;
3262 file_offset += size;
3266 #ifndef ELF_OBJ_ONLY
3267 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3268 LV, maybe create a new entry for (LIB,VERSION). */
3269 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3271 while (i >= *n) {
3272 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3273 (*lv)[(*n)++] = -1;
3275 if ((*lv)[i] == -1) {
3276 int v, prev_same_lib = -1;
3277 for (v = 0; v < nb_sym_versions; v++) {
3278 if (strcmp(sym_versions[v].lib, lib))
3279 continue;
3280 prev_same_lib = v;
3281 if (!strcmp(sym_versions[v].version, version))
3282 break;
3284 if (v == nb_sym_versions) {
3285 sym_versions = tcc_realloc (sym_versions,
3286 (v + 1) * sizeof(*sym_versions));
3287 sym_versions[v].lib = tcc_strdup(lib);
3288 sym_versions[v].version = tcc_strdup(version);
3289 sym_versions[v].out_index = 0;
3290 sym_versions[v].prev_same_lib = prev_same_lib;
3291 nb_sym_versions++;
3293 (*lv)[i] = v;
3297 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3298 VERNDX. */
3299 static void
3300 set_sym_version(TCCState *s1, int sym_index, int verndx)
3302 if (sym_index >= nb_sym_to_version) {
3303 int newelems = sym_index ? sym_index * 2 : 1;
3304 sym_to_version = tcc_realloc(sym_to_version,
3305 newelems * sizeof(*sym_to_version));
3306 memset(sym_to_version + nb_sym_to_version, -1,
3307 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3308 nb_sym_to_version = newelems;
3310 if (sym_to_version[sym_index] < 0)
3311 sym_to_version[sym_index] = verndx;
3314 struct versym_info {
3315 int nb_versyms;
3316 ElfW(Verdef) *verdef;
3317 ElfW(Verneed) *verneed;
3318 ElfW(Half) *versym;
3319 int nb_local_ver, *local_ver;
3323 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3325 char *lib, *version;
3326 uint32_t next;
3327 int i;
3329 #define DEBUG_VERSION 0
3331 if (v->versym && v->verdef) {
3332 ElfW(Verdef) *vdef = v->verdef;
3333 lib = NULL;
3334 do {
3335 ElfW(Verdaux) *verdaux =
3336 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3338 #if DEBUG_VERSION
3339 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3340 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3341 vdef->vd_hash);
3342 #endif
3343 if (vdef->vd_cnt) {
3344 version = dynstr + verdaux->vda_name;
3346 if (lib == NULL)
3347 lib = version;
3348 else
3349 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3350 lib, version);
3351 #if DEBUG_VERSION
3352 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3353 #endif
3355 next = vdef->vd_next;
3356 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3357 } while (next);
3359 if (v->versym && v->verneed) {
3360 ElfW(Verneed) *vneed = v->verneed;
3361 do {
3362 ElfW(Vernaux) *vernaux =
3363 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3365 lib = dynstr + vneed->vn_file;
3366 #if DEBUG_VERSION
3367 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3368 #endif
3369 for (i = 0; i < vneed->vn_cnt; i++) {
3370 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3371 version = dynstr + vernaux->vna_name;
3372 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3373 lib, version);
3374 #if DEBUG_VERSION
3375 printf (" vernaux(%u): %u %u %s\n",
3376 vernaux->vna_other, vernaux->vna_hash,
3377 vernaux->vna_flags, version);
3378 #endif
3380 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3382 next = vneed->vn_next;
3383 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3384 } while (next);
3387 #if DEBUG_VERSION
3388 for (i = 0; i < v->nb_local_ver; i++) {
3389 if (v->local_ver[i] > 0) {
3390 printf ("%d: lib: %s, version %s\n",
3391 i, sym_versions[v->local_ver[i]].lib,
3392 sym_versions[v->local_ver[i]].version);
3395 #endif
3398 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3399 is referenced by the user (so it should be added as DT_NEEDED in
3400 the generated ELF file) */
3401 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3403 ElfW(Ehdr) ehdr;
3404 ElfW(Shdr) *shdr, *sh, *sh1;
3405 int i, j, nb_syms, nb_dts, sym_bind, ret;
3406 ElfW(Sym) *sym, *dynsym;
3407 ElfW(Dyn) *dt, *dynamic;
3409 char *dynstr;
3410 int sym_index;
3411 const char *name, *soname;
3412 DLLReference *dllref;
3413 struct versym_info v;
3415 full_read(fd, &ehdr, sizeof(ehdr));
3417 /* test CPU specific stuff */
3418 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3419 ehdr.e_machine != EM_TCC_TARGET) {
3420 tcc_error_noabort("bad architecture");
3421 return -1;
3424 /* read sections */
3425 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3427 /* load dynamic section and dynamic symbols */
3428 nb_syms = 0;
3429 nb_dts = 0;
3430 dynamic = NULL;
3431 dynsym = NULL; /* avoid warning */
3432 dynstr = NULL; /* avoid warning */
3433 memset(&v, 0, sizeof v);
3435 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3436 switch(sh->sh_type) {
3437 case SHT_DYNAMIC:
3438 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3439 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3440 break;
3441 case SHT_DYNSYM:
3442 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3443 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3444 sh1 = &shdr[sh->sh_link];
3445 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3446 break;
3447 case SHT_GNU_verdef:
3448 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3449 break;
3450 case SHT_GNU_verneed:
3451 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3452 break;
3453 case SHT_GNU_versym:
3454 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3455 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3456 break;
3457 default:
3458 break;
3462 /* compute the real library name */
3463 soname = tcc_basename(filename);
3465 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3466 if (dt->d_tag == DT_SONAME) {
3467 soname = dynstr + dt->d_un.d_val;
3468 } else if (dt->d_tag == DT_RPATH) {
3469 tcc_add_library_path(s1, dynstr + dt->d_un.d_val);
3473 /* if the dll is already loaded, do not load it */
3474 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3475 dllref = s1->loaded_dlls[i];
3476 if (!strcmp(soname, dllref->name)) {
3477 /* but update level if needed */
3478 if (level < dllref->level)
3479 dllref->level = level;
3480 ret = 0;
3481 goto the_end;
3485 if (v.nb_versyms != nb_syms)
3486 tcc_free (v.versym), v.versym = NULL;
3487 else
3488 store_version(s1, &v, dynstr);
3490 /* add the dll and its level */
3491 tcc_add_dllref(s1, soname)->level = level;
3493 /* add dynamic symbols in dynsym_section */
3494 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3495 sym_bind = ELFW(ST_BIND)(sym->st_info);
3496 if (sym_bind == STB_LOCAL)
3497 continue;
3498 name = dynstr + sym->st_name;
3499 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3500 sym->st_info, sym->st_other, sym->st_shndx, name);
3501 if (v.versym) {
3502 ElfW(Half) vsym = v.versym[i];
3503 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3504 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3508 /* load all referenced DLLs */
3509 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3510 switch(dt->d_tag) {
3511 case DT_NEEDED:
3512 name = dynstr + dt->d_un.d_val;
3513 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3514 dllref = s1->loaded_dlls[j];
3515 if (!strcmp(name, dllref->name))
3516 goto already_loaded;
3518 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3519 tcc_error_noabort("referenced dll '%s' not found", name);
3520 ret = -1;
3521 goto the_end;
3523 already_loaded:
3524 break;
3527 ret = 0;
3528 the_end:
3529 tcc_free(dynstr);
3530 tcc_free(dynsym);
3531 tcc_free(dynamic);
3532 tcc_free(shdr);
3533 tcc_free(v.local_ver);
3534 tcc_free(v.verdef);
3535 tcc_free(v.verneed);
3536 tcc_free(v.versym);
3537 return ret;
3540 #define LD_TOK_NAME 256
3541 #define LD_TOK_EOF (-1)
3543 static int ld_inp(TCCState *s1)
3545 char b;
3546 if (s1->cc != -1) {
3547 int c = s1->cc;
3548 s1->cc = -1;
3549 return c;
3551 if (1 == read(s1->fd, &b, 1))
3552 return b;
3553 return CH_EOF;
3556 /* return next ld script token */
3557 static int ld_next(TCCState *s1, char *name, int name_size)
3559 int c, d, ch;
3560 char *q;
3562 redo:
3563 ch = ld_inp(s1);
3564 switch(ch) {
3565 case ' ':
3566 case '\t':
3567 case '\f':
3568 case '\v':
3569 case '\r':
3570 case '\n':
3571 goto redo;
3572 case '/':
3573 ch = ld_inp(s1);
3574 if (ch == '*') { /* comment */
3575 for (d = 0;; d = ch) {
3576 ch = ld_inp(s1);
3577 if (ch == CH_EOF || (ch == '/' && d == '*'))
3578 break;
3580 goto redo;
3581 } else {
3582 q = name;
3583 *q++ = '/';
3584 goto parse_name;
3586 break;
3587 case '\\':
3588 /* case 'a' ... 'z': */
3589 case 'a':
3590 case 'b':
3591 case 'c':
3592 case 'd':
3593 case 'e':
3594 case 'f':
3595 case 'g':
3596 case 'h':
3597 case 'i':
3598 case 'j':
3599 case 'k':
3600 case 'l':
3601 case 'm':
3602 case 'n':
3603 case 'o':
3604 case 'p':
3605 case 'q':
3606 case 'r':
3607 case 's':
3608 case 't':
3609 case 'u':
3610 case 'v':
3611 case 'w':
3612 case 'x':
3613 case 'y':
3614 case 'z':
3615 /* case 'A' ... 'z': */
3616 case 'A':
3617 case 'B':
3618 case 'C':
3619 case 'D':
3620 case 'E':
3621 case 'F':
3622 case 'G':
3623 case 'H':
3624 case 'I':
3625 case 'J':
3626 case 'K':
3627 case 'L':
3628 case 'M':
3629 case 'N':
3630 case 'O':
3631 case 'P':
3632 case 'Q':
3633 case 'R':
3634 case 'S':
3635 case 'T':
3636 case 'U':
3637 case 'V':
3638 case 'W':
3639 case 'X':
3640 case 'Y':
3641 case 'Z':
3642 case '_':
3643 case '.':
3644 case '$':
3645 case '~':
3646 q = name;
3647 parse_name:
3648 for(;;) {
3649 if (!((ch >= 'a' && ch <= 'z') ||
3650 (ch >= 'A' && ch <= 'Z') ||
3651 (ch >= '0' && ch <= '9') ||
3652 strchr("/.-_+=$:\\,~", ch)))
3653 break;
3654 if ((q - name) < name_size - 1) {
3655 *q++ = ch;
3657 ch = ld_inp(s1);
3659 s1->cc = ch;
3660 *q = '\0';
3661 c = LD_TOK_NAME;
3662 break;
3663 case CH_EOF:
3664 c = LD_TOK_EOF;
3665 break;
3666 default:
3667 c = ch;
3668 break;
3670 return c;
3673 static int ld_add_file(TCCState *s1, const char filename[])
3675 if (filename[0] == '/') {
3676 if (CONFIG_SYSROOT[0] == '\0'
3677 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3678 return 0;
3679 filename = tcc_basename(filename);
3681 return tcc_add_dll(s1, filename, 0);
3684 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3686 char filename[1024], libname[1024];
3687 int t, group, nblibs = 0, ret = 0;
3688 char **libs = NULL;
3690 group = !strcmp(cmd, "GROUP");
3691 if (!as_needed)
3692 s1->new_undef_sym = 0;
3693 t = ld_next(s1, filename, sizeof(filename));
3694 if (t != '(') {
3695 tcc_error_noabort("( expected");
3696 ret = -1;
3697 goto lib_parse_error;
3699 t = ld_next(s1, filename, sizeof(filename));
3700 for(;;) {
3701 libname[0] = '\0';
3702 if (t == LD_TOK_EOF) {
3703 tcc_error_noabort("unexpected end of file");
3704 ret = -1;
3705 goto lib_parse_error;
3706 } else if (t == ')') {
3707 break;
3708 } else if (t == '-') {
3709 t = ld_next(s1, filename, sizeof(filename));
3710 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3711 tcc_error_noabort("library name expected");
3712 ret = -1;
3713 goto lib_parse_error;
3715 pstrcpy(libname, sizeof libname, &filename[1]);
3716 if (s1->static_link) {
3717 snprintf(filename, sizeof filename, "lib%s.a", libname);
3718 } else {
3719 snprintf(filename, sizeof filename, "lib%s.so", libname);
3721 } else if (t != LD_TOK_NAME) {
3722 tcc_error_noabort("filename expected");
3723 ret = -1;
3724 goto lib_parse_error;
3726 if (!strcmp(filename, "AS_NEEDED")) {
3727 ret = ld_add_file_list(s1, cmd, 1);
3728 if (ret)
3729 goto lib_parse_error;
3730 } else {
3731 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3732 if (!as_needed) {
3733 ret = ld_add_file(s1, filename);
3734 if (ret)
3735 goto lib_parse_error;
3736 if (group) {
3737 /* Add the filename *and* the libname to avoid future conversions */
3738 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3739 if (libname[0] != '\0')
3740 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3744 t = ld_next(s1, filename, sizeof(filename));
3745 if (t == ',') {
3746 t = ld_next(s1, filename, sizeof(filename));
3749 if (group && !as_needed) {
3750 while (s1->new_undef_sym) {
3751 int i;
3752 s1->new_undef_sym = 0;
3753 for (i = 0; i < nblibs; i ++)
3754 ld_add_file(s1, libs[i]);
3757 lib_parse_error:
3758 dynarray_reset(&libs, &nblibs);
3759 return ret;
3762 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3763 files */
3764 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3766 char cmd[64];
3767 char filename[1024];
3768 int t, ret;
3770 s1->fd = fd;
3771 s1->cc = -1;
3772 for(;;) {
3773 t = ld_next(s1, cmd, sizeof(cmd));
3774 if (t == LD_TOK_EOF)
3775 return 0;
3776 else if (t != LD_TOK_NAME)
3777 return -1;
3778 if (!strcmp(cmd, "INPUT") ||
3779 !strcmp(cmd, "GROUP")) {
3780 ret = ld_add_file_list(s1, cmd, 0);
3781 if (ret)
3782 return ret;
3783 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3784 !strcmp(cmd, "TARGET")) {
3785 /* ignore some commands */
3786 t = ld_next(s1, cmd, sizeof(cmd));
3787 if (t != '(') {
3788 tcc_error_noabort("( expected");
3789 return -1;
3791 for(;;) {
3792 t = ld_next(s1, filename, sizeof(filename));
3793 if (t == LD_TOK_EOF) {
3794 tcc_error_noabort("unexpected end of file");
3795 return -1;
3796 } else if (t == ')') {
3797 break;
3800 } else {
3801 return -1;
3804 return 0;
3806 #endif /* !ELF_OBJ_ONLY */