tccelf: load objects first
[tinycc.git] / tccelf.c
blob37f943f2f8ca92d4921f5e4c3e8945da07e46692
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 = 1; sym_index < end_sym; ++sym_index) {
569 int dllindex, verndx;
570 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
571 if (sym->st_shndx != SHN_UNDEF)
572 continue; /* defined symbol doesn't need library version */
573 name = (char *) symtab->link->data + sym->st_name;
574 dllindex = find_elf_sym(s1->dynsymtab_section, name);
575 verndx = (dllindex && dllindex < nb_sym_to_version)
576 ? sym_to_version[dllindex] : -1;
577 if (verndx >= 0) {
578 if (!sym_versions[verndx].out_index)
579 sym_versions[verndx].out_index = nb_versions++;
580 versym[sym_index] = sym_versions[verndx].out_index;
583 /* generate verneed section, but not when it will be empty. Some
584 dynamic linkers look at their contents even when DTVERNEEDNUM and
585 section size is zero. */
586 if (nb_versions > 2) {
587 verneed_section = new_section(s1, ".gnu.version_r",
588 SHT_GNU_verneed, SHF_ALLOC);
589 verneed_section->link = s1->dynsym->link;
590 for (i = nb_sym_versions; i-- > 0;) {
591 struct sym_version *sv = &sym_versions[i];
592 int n_same_libs = 0, prev;
593 size_t vnofs;
594 ElfW(Vernaux) *vna = 0;
595 if (sv->out_index < 1)
596 continue;
597 /* make sure that a DT_NEEDED tag is put */
598 tcc_add_dllref(s1, sv->lib, 0);
599 vnofs = section_add(verneed_section, sizeof(*vn), 1);
600 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
601 vn->vn_version = 1;
602 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
603 vn->vn_aux = sizeof (*vn);
604 do {
605 prev = sv->prev_same_lib;
606 if (sv->out_index > 0) {
607 vna = section_ptr_add(verneed_section, sizeof(*vna));
608 vna->vna_hash = elf_hash ((const unsigned char *)sv->version);
609 vna->vna_flags = 0;
610 vna->vna_other = sv->out_index;
611 sv->out_index = -2;
612 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
613 vna->vna_next = sizeof (*vna);
614 n_same_libs++;
616 if (prev >= 0)
617 sv = &sym_versions[prev];
618 } while(prev >= 0);
619 vna->vna_next = 0;
620 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
621 vn->vn_cnt = n_same_libs;
622 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
623 nb_entries++;
625 if (vn)
626 vn->vn_next = 0;
627 verneed_section->sh_info = nb_entries;
629 dt_verneednum = nb_entries;
631 #endif /* ndef ELF_OBJ_ONLY */
633 /* add an elf symbol : check if it is already defined and patch
634 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
635 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
636 int info, int other, int shndx, const char *name)
638 TCCState *s1 = s->s1;
639 ElfW(Sym) *esym;
640 int sym_bind, sym_index, sym_type, esym_bind;
641 unsigned char sym_vis, esym_vis, new_vis;
643 sym_bind = ELFW(ST_BIND)(info);
644 sym_type = ELFW(ST_TYPE)(info);
645 sym_vis = ELFW(ST_VISIBILITY)(other);
647 if (sym_bind != STB_LOCAL) {
648 /* we search global or weak symbols */
649 sym_index = find_elf_sym(s, name);
650 if (!sym_index)
651 goto do_def;
652 esym = &((ElfW(Sym) *)s->data)[sym_index];
653 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
654 && esym->st_other == other && esym->st_shndx == shndx)
655 return sym_index;
656 if (esym->st_shndx != SHN_UNDEF) {
657 esym_bind = ELFW(ST_BIND)(esym->st_info);
658 /* propagate the most constraining visibility */
659 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
660 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
661 if (esym_vis == STV_DEFAULT) {
662 new_vis = sym_vis;
663 } else if (sym_vis == STV_DEFAULT) {
664 new_vis = esym_vis;
665 } else {
666 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
668 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
669 | new_vis;
670 if (shndx == SHN_UNDEF) {
671 /* ignore adding of undefined symbol if the
672 corresponding symbol is already defined */
673 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
674 /* global overrides weak, so patch */
675 goto do_patch;
676 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
677 /* weak is ignored if already global */
678 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
679 /* keep first-found weak definition, ignore subsequents */
680 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
681 /* ignore hidden symbols after */
682 } else if ((esym->st_shndx == SHN_COMMON
683 || esym->st_shndx == bss_section->sh_num)
684 && (shndx < SHN_LORESERVE
685 && shndx != bss_section->sh_num)) {
686 /* data symbol gets precedence over common/bss */
687 goto do_patch;
688 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
689 /* data symbol keeps precedence over common/bss */
690 } else if (s->sh_flags & SHF_DYNSYM) {
691 /* we accept that two DLL define the same symbol */
692 } else if (esym->st_other & ST_ASM_SET) {
693 /* If the existing symbol came from an asm .set
694 we can override. */
695 goto do_patch;
696 } else {
697 #if 0
698 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
699 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
700 #endif
701 tcc_error_noabort("'%s' defined twice", name);
703 } else {
704 esym->st_other = other;
705 do_patch:
706 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
707 esym->st_shndx = shndx;
708 s1->new_undef_sym = 1;
709 esym->st_value = value;
710 esym->st_size = size;
712 } else {
713 do_def:
714 sym_index = put_elf_sym(s, value, size,
715 ELFW(ST_INFO)(sym_bind, sym_type), other,
716 shndx, name);
718 return sym_index;
721 /* put relocation */
722 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
723 int type, int symbol, addr_t addend)
725 TCCState *s1 = s->s1;
726 char buf[256];
727 Section *sr;
728 ElfW_Rel *rel;
730 sr = s->reloc;
731 if (!sr) {
732 /* if no relocation section, create it */
733 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
734 /* if the symtab is allocated, then we consider the relocation
735 are also */
736 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
737 sr->sh_entsize = sizeof(ElfW_Rel);
738 sr->link = symtab;
739 sr->sh_info = s->sh_num;
740 s->reloc = sr;
742 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
743 rel->r_offset = offset;
744 rel->r_info = ELFW(R_INFO)(symbol, type);
745 #if SHT_RELX == SHT_RELA
746 rel->r_addend = addend;
747 #endif
748 if (SHT_RELX != SHT_RELA && addend)
749 tcc_error("non-zero addend on REL architecture");
752 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
753 int type, int symbol)
755 put_elf_reloca(symtab, s, offset, type, symbol, 0);
758 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
760 int n;
761 struct sym_attr *tab;
763 if (index >= s1->nb_sym_attrs) {
764 if (!alloc)
765 return s1->sym_attrs;
766 /* find immediately bigger power of 2 and reallocate array */
767 n = 1;
768 while (index >= n)
769 n *= 2;
770 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
771 s1->sym_attrs = tab;
772 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
773 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
774 s1->nb_sym_attrs = n;
776 return &s1->sym_attrs[index];
779 /* In an ELF file symbol table, the local symbols must appear below
780 the global and weak ones. Since TCC cannot sort it while generating
781 the code, we must do it after. All the relocation tables are also
782 modified to take into account the symbol table sorting */
783 static void sort_syms(TCCState *s1, Section *s)
785 int *old_to_new_syms;
786 ElfW(Sym) *new_syms;
787 int nb_syms, i;
788 ElfW(Sym) *p, *q;
789 ElfW_Rel *rel;
790 Section *sr;
791 int type, sym_index;
793 nb_syms = s->data_offset / sizeof(ElfW(Sym));
794 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
795 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
797 /* first pass for local symbols */
798 p = (ElfW(Sym) *)s->data;
799 q = new_syms;
800 for(i = 0; i < nb_syms; i++) {
801 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
802 old_to_new_syms[i] = q - new_syms;
803 *q++ = *p;
805 p++;
807 /* save the number of local symbols in section header */
808 if( s->sh_size ) /* this 'if' makes IDA happy */
809 s->sh_info = q - new_syms;
811 /* then second pass for non local symbols */
812 p = (ElfW(Sym) *)s->data;
813 for(i = 0; i < nb_syms; i++) {
814 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
815 old_to_new_syms[i] = q - new_syms;
816 *q++ = *p;
818 p++;
821 /* we copy the new symbols to the old */
822 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
823 tcc_free(new_syms);
825 /* now we modify all the relocations */
826 for(i = 1; i < s1->nb_sections; i++) {
827 sr = s1->sections[i];
828 if (sr->sh_type == SHT_RELX && sr->link == s) {
829 for_each_elem(sr, 0, rel, ElfW_Rel) {
830 sym_index = ELFW(R_SYM)(rel->r_info);
831 type = ELFW(R_TYPE)(rel->r_info);
832 sym_index = old_to_new_syms[sym_index];
833 rel->r_info = ELFW(R_INFO)(sym_index, type);
838 tcc_free(old_to_new_syms);
841 /* relocate symbol table, resolve undefined symbols if do_resolve is
842 true and output error if undefined symbol. */
843 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
845 ElfW(Sym) *sym;
846 int sym_bind, sh_num;
847 const char *name;
849 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
850 sh_num = sym->st_shndx;
851 if (sh_num == SHN_UNDEF) {
852 name = (char *) s1->symtab->link->data + sym->st_name;
853 /* Use ld.so to resolve symbol for us (for tcc -run) */
854 if (do_resolve) {
855 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
856 /* dlsym() needs the undecorated name. */
857 void *addr = dlsym(RTLD_DEFAULT, &name[s1->leading_underscore]);
858 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
859 if (addr == NULL) {
860 int i;
861 for (i = 0; i < s1->nb_loaded_dlls; i++)
862 if ((addr = dlsym(s1->loaded_dlls[i]->handle, name)))
863 break;
865 #endif
866 if (addr) {
867 sym->st_value = (addr_t) addr;
868 #ifdef DEBUG_RELOC
869 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
870 #endif
871 goto found;
873 #endif
874 /* if dynamic symbol exist, it will be used in relocate_section */
875 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
876 goto found;
877 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
878 it */
879 if (!strcmp(name, "_fp_hw"))
880 goto found;
881 /* only weak symbols are accepted to be undefined. Their
882 value is zero */
883 sym_bind = ELFW(ST_BIND)(sym->st_info);
884 if (sym_bind == STB_WEAK)
885 sym->st_value = 0;
886 else
887 tcc_error_noabort("undefined symbol '%s'", name);
889 } else if (sh_num < SHN_LORESERVE) {
890 /* add section base */
891 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
893 found: ;
897 /* relocate a given section (CPU dependent) by applying the relocations
898 in the associated relocation section */
899 static void relocate_section(TCCState *s1, Section *s, Section *sr)
901 ElfW_Rel *rel;
902 ElfW(Sym) *sym;
903 int type, sym_index;
904 unsigned char *ptr;
905 addr_t tgt, addr;
906 int is_dwarf = s->sh_num >= s1->dwlo && s->sh_num < s1->dwhi;
908 qrel = (ElfW_Rel *)sr->data;
909 for_each_elem(sr, 0, rel, ElfW_Rel) {
910 ptr = s->data + rel->r_offset;
911 sym_index = ELFW(R_SYM)(rel->r_info);
912 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
913 type = ELFW(R_TYPE)(rel->r_info);
914 tgt = sym->st_value;
915 #if SHT_RELX == SHT_RELA
916 tgt += rel->r_addend;
917 #endif
918 if (is_dwarf && type == R_DATA_32DW
919 && sym->st_shndx >= s1->dwlo && sym->st_shndx < s1->dwhi) {
920 /* dwarf section relocation to each other */
921 add32le(ptr, tgt - s1->sections[sym->st_shndx]->sh_addr);
922 continue;
924 addr = s->sh_addr + rel->r_offset;
925 relocate(s1, rel, type, ptr, addr, tgt);
927 #ifndef ELF_OBJ_ONLY
928 /* if the relocation is allocated, we change its symbol table */
929 if (sr->sh_flags & SHF_ALLOC) {
930 sr->link = s1->dynsym;
931 if (s1->output_type == TCC_OUTPUT_DLL) {
932 size_t r = (uint8_t*)qrel - sr->data;
933 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
934 && 0 == strcmp(s->name, ".stab"))
935 r = 0; /* cannot apply 64bit relocation to 32bit value */
936 sr->data_offset = sr->sh_size = r;
939 #endif
942 /* relocate all sections */
943 ST_FUNC void relocate_sections(TCCState *s1)
945 int i;
946 Section *s, *sr;
948 for (i = 1; i < s1->nb_sections; ++i) {
949 sr = s1->sections[i];
950 if (sr->sh_type != SHT_RELX)
951 continue;
952 s = s1->sections[sr->sh_info];
953 #ifndef TCC_TARGET_MACHO
954 if (s != s1->got
955 || s1->static_link
956 || s1->output_type == TCC_OUTPUT_MEMORY)
957 #endif
959 relocate_section(s1, s, sr);
961 #ifndef ELF_OBJ_ONLY
962 if (sr->sh_flags & SHF_ALLOC) {
963 ElfW_Rel *rel;
964 /* relocate relocation table in 'sr' */
965 for_each_elem(sr, 0, rel, ElfW_Rel)
966 rel->r_offset += s->sh_addr;
968 #endif
972 #ifndef ELF_OBJ_ONLY
973 /* count the number of dynamic relocations so that we can reserve
974 their space */
975 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
977 int count = 0;
978 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
979 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
980 defined(TCC_TARGET_RISCV64)
981 ElfW_Rel *rel;
982 for_each_elem(sr, 0, rel, ElfW_Rel) {
983 int sym_index = ELFW(R_SYM)(rel->r_info);
984 int type = ELFW(R_TYPE)(rel->r_info);
985 switch(type) {
986 #if defined(TCC_TARGET_I386)
987 case R_386_32:
988 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
989 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
990 /* don't fixup unresolved (weak) symbols */
991 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
992 break;
994 #elif defined(TCC_TARGET_X86_64)
995 case R_X86_64_32:
996 case R_X86_64_32S:
997 case R_X86_64_64:
998 #elif defined(TCC_TARGET_ARM)
999 case R_ARM_ABS32:
1000 case R_ARM_TARGET1:
1001 #elif defined(TCC_TARGET_ARM64)
1002 case R_AARCH64_ABS32:
1003 case R_AARCH64_ABS64:
1004 #elif defined(TCC_TARGET_RISCV64)
1005 case R_RISCV_32:
1006 case R_RISCV_64:
1007 #endif
1008 count++;
1009 break;
1010 #if defined(TCC_TARGET_I386)
1011 case R_386_PC32:
1012 #elif defined(TCC_TARGET_X86_64)
1013 case R_X86_64_PC32:
1015 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1017 /* Hidden defined symbols can and must be resolved locally.
1018 We're misusing a PLT32 reloc for this, as that's always
1019 resolved to its address even in shared libs. */
1020 if (sym->st_shndx != SHN_UNDEF &&
1021 ELFW(ST_VISIBILITY)(sym->st_other) == STV_HIDDEN) {
1022 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PLT32);
1023 break;
1026 #elif defined(TCC_TARGET_ARM64)
1027 case R_AARCH64_PREL32:
1028 #endif
1029 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1030 count++;
1031 break;
1032 default:
1033 break;
1036 #endif
1037 return count;
1039 #endif
1041 #ifdef NEED_BUILD_GOT
1042 static int build_got(TCCState *s1)
1044 /* if no got, then create it */
1045 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1046 s1->got->sh_entsize = 4;
1047 /* keep space for _DYNAMIC pointer and two dummy got entries */
1048 section_ptr_add(s1->got, 3 * PTR_SIZE);
1049 return set_elf_sym(symtab_section, 0, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1050 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1053 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1054 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1055 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1056 Returns the offset of the GOT or (if any) PLT entry. */
1057 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1058 int sym_index)
1060 int need_plt_entry;
1061 const char *name;
1062 ElfW(Sym) *sym;
1063 struct sym_attr *attr;
1064 unsigned got_offset;
1065 char plt_name[100];
1066 int len;
1067 Section *s_rel;
1069 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1070 attr = get_sym_attr(s1, sym_index, 1);
1072 /* In case a function is both called and its address taken 2 GOT entries
1073 are created, one for taking the address (GOT) and the other for the PLT
1074 entry (PLTGOT). */
1075 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1076 return attr;
1078 s_rel = s1->got;
1079 if (need_plt_entry) {
1080 if (!s1->plt) {
1081 s1->plt = new_section(s1, ".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
1082 s1->plt->sh_entsize = 4;
1084 s_rel = s1->plt;
1087 /* create the GOT entry */
1088 got_offset = s1->got->data_offset;
1089 section_ptr_add(s1->got, PTR_SIZE);
1091 /* Create the GOT relocation that will insert the address of the object or
1092 function of interest in the GOT entry. This is a static relocation for
1093 memory output (dlsym will give us the address of symbols) and dynamic
1094 relocation otherwise (executable and DLLs). The relocation should be
1095 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1096 associated to a PLT entry) but is currently done at load time for an
1097 unknown reason. */
1099 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1100 name = (char *) symtab_section->link->data + sym->st_name;
1101 //printf("sym %d %s\n", need_plt_entry, name);
1103 if (s1->dynsym) {
1104 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1105 /* Hack alarm. We don't want to emit dynamic symbols
1106 and symbol based relocs for STB_LOCAL symbols, but rather
1107 want to resolve them directly. At this point the symbol
1108 values aren't final yet, so we must defer this. We will later
1109 have to create a RELATIVE reloc anyway, so we misuse the
1110 relocation slot to smuggle the symbol reference until
1111 fill_local_got_entries. Not that the sym_index is
1112 relative to symtab_section, not s1->dynsym! Nevertheless
1113 we use s1->dyn_sym so that if this is the first call
1114 that got->reloc is correctly created. Also note that
1115 RELATIVE relocs are not normally created for the .got,
1116 so the types serves as a marker for later (and is retained
1117 also for the final output, which is okay because then the
1118 got is just normal data). */
1119 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1120 sym_index);
1121 } else {
1122 if (0 == attr->dyn_index)
1123 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1124 sym->st_size, sym->st_info, 0,
1125 sym->st_shndx, name);
1126 put_elf_reloc(s1->dynsym, s_rel, got_offset, dyn_reloc_type,
1127 attr->dyn_index);
1129 } else {
1130 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1131 sym_index);
1134 if (need_plt_entry) {
1135 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1137 /* create a symbol 'sym@plt' for the PLT jump vector */
1138 len = strlen(name);
1139 if (len > sizeof plt_name - 5)
1140 len = sizeof plt_name - 5;
1141 memcpy(plt_name, name, len);
1142 strcpy(plt_name + len, "@plt");
1143 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, 0,
1144 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1145 } else {
1146 attr->got_offset = got_offset;
1149 return attr;
1152 /* build GOT and PLT entries */
1153 /* Two passes because R_JMP_SLOT should become first. Some targets
1154 (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1155 ST_FUNC void build_got_entries(TCCState *s1, int got_sym)
1157 Section *s;
1158 ElfW_Rel *rel;
1159 ElfW(Sym) *sym;
1160 int i, type, gotplt_entry, reloc_type, sym_index;
1161 struct sym_attr *attr;
1162 int pass = 0;
1163 redo:
1164 for(i = 1; i < s1->nb_sections; i++) {
1165 s = s1->sections[i];
1166 if (s->sh_type != SHT_RELX)
1167 continue;
1168 /* no need to handle got relocations */
1169 if (s->link != symtab_section)
1170 continue;
1171 for_each_elem(s, 0, rel, ElfW_Rel) {
1172 type = ELFW(R_TYPE)(rel->r_info);
1173 gotplt_entry = gotplt_entry_type(type);
1174 if (gotplt_entry == -1)
1175 tcc_error ("Unknown relocation type for got: %d", type);
1176 sym_index = ELFW(R_SYM)(rel->r_info);
1177 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1179 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1180 continue;
1183 /* Automatically create PLT/GOT [entry] if it is an undefined
1184 reference (resolved at runtime), or the symbol is absolute,
1185 probably created by tcc_add_symbol, and thus on 64-bit
1186 targets might be too far from application code. */
1187 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1188 if (sym->st_shndx == SHN_UNDEF) {
1189 ElfW(Sym) *esym;
1190 int dynindex;
1191 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1192 continue;
1193 /* Relocations for UNDEF symbols would normally need
1194 to be transferred into the executable or shared object.
1195 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1196 But TCC doesn't do that (at least for exes), so we
1197 need to resolve all such relocs locally. And that
1198 means PLT slots for functions in DLLs and COPY relocs for
1199 data symbols. COPY relocs were generated in
1200 bind_exe_dynsyms (and the symbol adjusted to be defined),
1201 and for functions we were generated a dynamic symbol
1202 of function type. */
1203 if (s1->dynsym) {
1204 /* dynsym isn't set for -run :-/ */
1205 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1206 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1207 if (dynindex
1208 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1209 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1210 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1211 goto jmp_slot;
1213 } else if (sym->st_shndx == SHN_ABS) {
1214 if (sym->st_value == 0) /* from tcc_add_btstub() */
1215 continue;
1216 #ifndef TCC_TARGET_ARM
1217 if (PTR_SIZE != 8)
1218 continue;
1219 #endif
1220 /* from tcc_add_symbol(): on 64 bit platforms these
1221 need to go through .got */
1222 } else
1223 continue;
1226 #ifdef TCC_TARGET_X86_64
1227 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1228 sym->st_shndx != SHN_UNDEF &&
1229 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1230 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1231 s1->output_type == TCC_OUTPUT_EXE)) {
1232 if (pass != 0)
1233 continue;
1234 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1235 continue;
1237 #endif
1238 reloc_type = code_reloc(type);
1239 if (reloc_type == -1)
1240 tcc_error ("Unknown relocation type: %d", type);
1242 if (reloc_type != 0) {
1243 jmp_slot:
1244 if (pass != 0)
1245 continue;
1246 reloc_type = R_JMP_SLOT;
1247 } else {
1248 if (pass != 1)
1249 continue;
1250 reloc_type = R_GLOB_DAT;
1253 if (!s1->got)
1254 got_sym = build_got(s1);
1256 if (gotplt_entry == BUILD_GOT_ONLY)
1257 continue;
1259 attr = put_got_entry(s1, reloc_type, sym_index);
1261 if (reloc_type == R_JMP_SLOT)
1262 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1265 if (++pass < 2)
1266 goto redo;
1267 /* .rel.plt refers to .got actually */
1268 if (s1->plt && s1->plt->reloc)
1269 s1->plt->reloc->sh_info = s1->got->sh_num;
1270 if (got_sym) /* set size */
1271 ((ElfW(Sym)*)symtab_section->data)[got_sym].st_size = s1->got->data_offset;
1273 #endif /* def NEED_BUILD_GOT */
1275 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
1277 int shn = sec ? sec->sh_num : offs || !name ? SHN_ABS : SHN_UNDEF;
1278 if (sec && offs == -1)
1279 offs = sec->data_offset;
1280 return set_elf_sym(symtab_section, offs, 0,
1281 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1284 static void add_init_array_defines(TCCState *s1, const char *section_name)
1286 Section *s;
1287 addr_t end_offset;
1288 char buf[1024];
1289 s = find_section_create(s1, section_name, 0);
1290 if (!s) {
1291 end_offset = 0;
1292 s = data_section;
1293 } else {
1294 end_offset = s->data_offset;
1296 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1297 set_global_sym(s1, buf, s, 0);
1298 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1299 set_global_sym(s1, buf, s, end_offset);
1302 #ifndef TCC_TARGET_PE
1303 static void tcc_add_support(TCCState *s1, const char *filename)
1305 char buf[1024];
1306 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1307 tcc_add_file(s1, buf);
1309 #endif
1311 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1313 Section *s;
1314 s = find_section(s1, sec);
1315 s->sh_flags |= SHF_WRITE;
1316 #ifndef TCC_TARGET_PE
1317 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1318 #endif
1319 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1320 section_ptr_add(s, PTR_SIZE);
1323 #ifdef CONFIG_TCC_BCHECK
1324 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1326 if (0 == s1->do_bounds_check)
1327 return;
1328 section_ptr_add(bounds_section, sizeof(addr_t));
1330 #endif
1332 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1333 a dynamic symbol to allow so's to have one each with a different value. */
1334 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1336 int c = find_elf_sym(s1->symtab, name);
1337 if (c) {
1338 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1339 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1340 esym->st_value = offset;
1341 esym->st_shndx = s->sh_num;
1345 /* avoid generating debug/test_coverage code for stub functions */
1346 static void tcc_compile_string_no_debug(TCCState *s, const char *str)
1348 int save_do_debug = s->do_debug;
1349 int save_test_coverage = s->test_coverage;
1351 s->do_debug = 0;
1352 s->test_coverage = 0;
1353 tcc_compile_string(s, str);
1354 s->do_debug = save_do_debug;
1355 s->test_coverage = save_test_coverage;
1358 #ifdef CONFIG_TCC_BACKTRACE
1359 static void put_ptr(TCCState *s1, Section *s, int offs)
1361 int c;
1362 c = set_global_sym(s1, NULL, s, offs);
1363 s = data_section;
1364 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1365 section_ptr_add(s, PTR_SIZE);
1368 ST_FUNC void tcc_add_btstub(TCCState *s1)
1370 Section *s;
1371 int n, o;
1372 CString cstr;
1374 s = data_section;
1375 /* Align to PTR_SIZE */
1376 section_ptr_add(s, -s->data_offset & (PTR_SIZE - 1));
1377 o = s->data_offset;
1378 /* create (part of) a struct rt_context (see tccrun.c) */
1379 if (s1->dwarf) {
1380 put_ptr(s1, dwarf_line_section, 0);
1381 put_ptr(s1, dwarf_line_section, -1);
1382 if (s1->dwarf >= 5)
1383 put_ptr(s1, dwarf_line_str_section, 0);
1384 else
1385 put_ptr(s1, dwarf_str_section, 0);
1387 else
1389 put_ptr(s1, stab_section, 0);
1390 put_ptr(s1, stab_section, -1);
1391 put_ptr(s1, stab_section->link, 0);
1393 *(addr_t *)section_ptr_add(s, PTR_SIZE) = s1->dwarf;
1394 /* skip esym_start/esym_end/elf_str (not loaded) */
1395 section_ptr_add(s, 3 * PTR_SIZE);
1396 /* prog_base : local nameless symbol with offset 0 at SHN_ABS */
1397 put_ptr(s1, NULL, 0);
1398 n = 2 * PTR_SIZE;
1399 #ifdef CONFIG_TCC_BCHECK
1400 if (s1->do_bounds_check) {
1401 put_ptr(s1, bounds_section, 0);
1402 n -= PTR_SIZE;
1404 #endif
1405 section_ptr_add(s, n);
1406 cstr_new(&cstr);
1407 cstr_printf(&cstr,
1408 "extern void __bt_init(),__bt_exit(),__bt_init_dll();"
1409 "static void *__rt_info[];"
1410 "__attribute__((constructor)) static void __bt_init_rt(){");
1411 #ifdef TCC_TARGET_PE
1412 if (s1->output_type == TCC_OUTPUT_DLL)
1413 #ifdef CONFIG_TCC_BCHECK
1414 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1415 #else
1416 cstr_printf(&cstr, "__bt_init_dll(0);");
1417 #endif
1418 #endif
1419 cstr_printf(&cstr, "__bt_init(__rt_info,%d);}",
1420 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1421 /* In case dlcose is called by application */
1422 cstr_printf(&cstr,
1423 "__attribute__((destructor)) static void __bt_exit_rt(){"
1424 "__bt_exit(__rt_info);}");
1425 tcc_compile_string_no_debug(s1, cstr.data);
1426 cstr_free(&cstr);
1427 set_local_sym(s1, &"___rt_info"[!s1->leading_underscore], s, o);
1429 #endif /* def CONFIG_TCC_BACKTRACE */
1431 static void tcc_tcov_add_file(TCCState *s1, const char *filename)
1433 CString cstr;
1434 void *ptr;
1435 char wd[1024];
1437 if (tcov_section == NULL)
1438 return;
1439 section_ptr_add(tcov_section, 1);
1440 write32le (tcov_section->data, tcov_section->data_offset);
1442 cstr_new (&cstr);
1443 if (filename[0] == '/')
1444 cstr_printf (&cstr, "%s.tcov", filename);
1445 else {
1446 getcwd (wd, sizeof(wd));
1447 cstr_printf (&cstr, "%s/%s.tcov", wd, filename);
1449 ptr = section_ptr_add(tcov_section, cstr.size + 1);
1450 strcpy((char *)ptr, cstr.data);
1451 unlink((char *)ptr);
1452 #ifdef _WIN32
1453 normalize_slashes((char *)ptr);
1454 #endif
1455 cstr_free (&cstr);
1457 cstr_new(&cstr);
1458 cstr_printf(&cstr,
1459 "extern char *__tcov_data[];"
1460 "extern void __store_test_coverage ();"
1461 "__attribute__((destructor)) static void __tcov_exit() {"
1462 "__store_test_coverage(__tcov_data);"
1463 "}");
1464 tcc_compile_string_no_debug(s1, cstr.data);
1465 cstr_free(&cstr);
1466 set_local_sym(s1, &"___tcov_data"[!s1->leading_underscore], tcov_section, 0);
1469 #ifndef TCC_TARGET_PE
1470 /* add tcc runtime libraries */
1471 ST_FUNC void tcc_add_runtime(TCCState *s1)
1473 s1->filetype = 0;
1475 #ifdef CONFIG_TCC_BCHECK
1476 tcc_add_bcheck(s1);
1477 #endif
1478 tcc_add_pragma_libs(s1);
1480 /* add libc */
1481 if (!s1->nostdlib) {
1482 int lpthread = s1->option_pthread;
1484 #ifdef CONFIG_TCC_BCHECK
1485 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1486 tcc_add_support(s1, "bcheck.o");
1487 # if !(TARGETOS_OpenBSD || TARGETOS_NetBSD)
1488 tcc_add_library_err(s1, "dl");
1489 # endif
1490 lpthread = 1;
1492 #endif
1493 #ifdef CONFIG_TCC_BACKTRACE
1494 if (s1->do_backtrace) {
1495 if (s1->output_type == TCC_OUTPUT_EXE)
1496 tcc_add_support(s1, "bt-exe.o");
1497 if (s1->output_type != TCC_OUTPUT_DLL)
1498 tcc_add_support(s1, "bt-log.o");
1499 if (s1->output_type != TCC_OUTPUT_MEMORY)
1500 tcc_add_btstub(s1);
1502 #endif
1503 if (lpthread)
1504 tcc_add_library_err(s1, "pthread");
1505 tcc_add_library_err(s1, "c");
1506 #ifdef TCC_LIBGCC
1507 if (!s1->static_link) {
1508 if (TCC_LIBGCC[0] == '/')
1509 tcc_add_file(s1, TCC_LIBGCC);
1510 else
1511 tcc_add_dll(s1, TCC_LIBGCC, 0);
1513 #endif
1514 #if defined TCC_TARGET_ARM && TARGETOS_FreeBSD
1515 tcc_add_library_err(s1, "gcc_s"); // unwind code
1516 #endif
1517 if (TCC_LIBTCC1[0])
1518 tcc_add_support(s1, TCC_LIBTCC1);
1520 /* add crt end if not memory output */
1521 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1522 #if defined TCC_TARGET_MACHO
1523 /* nothing to do */
1524 #elif TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
1525 if (s1->output_type == TCC_OUTPUT_DLL)
1526 tcc_add_crt(s1, "crtendS.o");
1527 else
1528 tcc_add_crt(s1, "crtend.o");
1529 # if !TARGETOS_OpenBSD
1530 tcc_add_crt(s1, "crtn.o");
1531 # endif
1532 #else
1533 tcc_add_crt(s1, "crtn.o");
1534 #endif
1538 #endif /* ndef TCC_TARGET_PE */
1540 /* add various standard linker symbols (must be done after the
1541 sections are filled (for example after allocating common
1542 symbols)) */
1543 static void tcc_add_linker_symbols(TCCState *s1)
1545 char buf[1024];
1546 int i;
1547 Section *s;
1549 set_global_sym(s1, "_etext", text_section, -1);
1550 set_global_sym(s1, "_edata", data_section, -1);
1551 set_global_sym(s1, "_end", bss_section, -1);
1552 #if TARGETOS_OpenBSD
1553 set_global_sym(s1, "__executable_start", NULL, ELF_START_ADDR);
1554 #endif
1555 #ifdef TCC_TARGET_RISCV64
1556 /* XXX should be .sdata+0x800, not .data+0x800 */
1557 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1558 #endif
1559 /* horrible new standard ldscript defines */
1560 #ifndef TCC_TARGET_PE
1561 add_init_array_defines(s1, ".preinit_array");
1562 #endif
1563 add_init_array_defines(s1, ".init_array");
1564 add_init_array_defines(s1, ".fini_array");
1565 /* add start and stop symbols for sections whose name can be
1566 expressed in C */
1567 for(i = 1; i < s1->nb_sections; i++) {
1568 s = s1->sections[i];
1569 if ((s->sh_flags & SHF_ALLOC)
1570 && (s->sh_type == SHT_PROGBITS
1571 || s->sh_type == SHT_STRTAB)) {
1572 const char *p;
1573 /* check if section name can be expressed in C */
1574 p = s->name;
1575 for(;;) {
1576 int c = *p;
1577 if (!c)
1578 break;
1579 if (!isid(c) && !isnum(c))
1580 goto next_sec;
1581 p++;
1583 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1584 set_global_sym(s1, buf, s, 0);
1585 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1586 set_global_sym(s1, buf, s, -1);
1588 next_sec: ;
1592 ST_FUNC void resolve_common_syms(TCCState *s1)
1594 ElfW(Sym) *sym;
1596 /* Allocate common symbols in BSS. */
1597 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1598 if (sym->st_shndx == SHN_COMMON) {
1599 /* symbol alignment is in st_value for SHN_COMMONs */
1600 sym->st_value = section_add(bss_section, sym->st_size,
1601 sym->st_value);
1602 sym->st_shndx = bss_section->sh_num;
1606 /* Now assign linker provided symbols their value. */
1607 tcc_add_linker_symbols(s1);
1610 #ifndef ELF_OBJ_ONLY
1611 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1613 int sym_index = ELFW(R_SYM) (rel->r_info);
1614 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1615 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1616 unsigned offset = attr->got_offset;
1618 if (0 == offset)
1619 return;
1620 section_reserve(s1->got, offset + PTR_SIZE);
1621 #if PTR_SIZE == 8
1622 write64le(s1->got->data + offset, sym->st_value);
1623 #else
1624 write32le(s1->got->data + offset, sym->st_value);
1625 #endif
1628 /* Perform relocation to GOT or PLT entries */
1629 ST_FUNC void fill_got(TCCState *s1)
1631 Section *s;
1632 ElfW_Rel *rel;
1633 int i;
1635 for(i = 1; i < s1->nb_sections; i++) {
1636 s = s1->sections[i];
1637 if (s->sh_type != SHT_RELX)
1638 continue;
1639 /* no need to handle got relocations */
1640 if (s->link != symtab_section)
1641 continue;
1642 for_each_elem(s, 0, rel, ElfW_Rel) {
1643 switch (ELFW(R_TYPE) (rel->r_info)) {
1644 case R_X86_64_GOT32:
1645 case R_X86_64_GOTPCREL:
1646 case R_X86_64_GOTPCRELX:
1647 case R_X86_64_REX_GOTPCRELX:
1648 case R_X86_64_PLT32:
1649 fill_got_entry(s1, rel);
1650 break;
1656 /* See put_got_entry for a description. This is the second stage
1657 where GOT references to local defined symbols are rewritten. */
1658 static void fill_local_got_entries(TCCState *s1)
1660 ElfW_Rel *rel;
1661 if (!s1->got->reloc)
1662 return;
1663 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1664 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1665 int sym_index = ELFW(R_SYM) (rel->r_info);
1666 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1667 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1668 unsigned offset = attr->got_offset;
1669 if (offset != rel->r_offset - s1->got->sh_addr)
1670 tcc_error_noabort("huh");
1671 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1672 #if SHT_RELX == SHT_RELA
1673 rel->r_addend = sym->st_value;
1674 #else
1675 /* All our REL architectures also happen to be 32bit LE. */
1676 write32le(s1->got->data + offset, sym->st_value);
1677 #endif
1682 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1683 in shared libraries */
1684 static void bind_exe_dynsyms(TCCState *s1)
1686 const char *name;
1687 int sym_index, index;
1688 ElfW(Sym) *sym, *esym;
1689 int type;
1691 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1692 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1693 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1694 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1695 if (sym->st_shndx == SHN_UNDEF) {
1696 name = (char *) symtab_section->link->data + sym->st_name;
1697 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1698 if (sym_index) {
1699 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1700 type = ELFW(ST_TYPE)(esym->st_info);
1701 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1702 /* Indirect functions shall have STT_FUNC type in executable
1703 * dynsym section. Indeed, a dlsym call following a lazy
1704 * resolution would pick the symbol value from the
1705 * executable dynsym entry which would contain the address
1706 * of the function wanted by the caller of dlsym instead of
1707 * the address of the function that would return that
1708 * address */
1709 int dynindex
1710 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1711 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1712 name);
1713 int index = sym - (ElfW(Sym) *) symtab_section->data;
1714 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1715 } else if (type == STT_OBJECT) {
1716 unsigned long offset;
1717 ElfW(Sym) *dynsym;
1718 offset = bss_section->data_offset;
1719 /* XXX: which alignment ? */
1720 offset = (offset + 16 - 1) & -16;
1721 set_elf_sym (s1->symtab, offset, esym->st_size,
1722 esym->st_info, 0, bss_section->sh_num, name);
1723 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1724 esym->st_info, 0, bss_section->sh_num,
1725 name);
1727 /* Ensure R_COPY works for weak symbol aliases */
1728 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1729 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1730 if ((dynsym->st_value == esym->st_value)
1731 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1732 char *dynname = (char *) s1->dynsymtab_section->link->data
1733 + dynsym->st_name;
1734 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1735 dynsym->st_info, 0,
1736 bss_section->sh_num, dynname);
1737 break;
1742 put_elf_reloc(s1->dynsym, bss_section,
1743 offset, R_COPY, index);
1744 offset += esym->st_size;
1745 bss_section->data_offset = offset;
1747 } else {
1748 /* STB_WEAK undefined symbols are accepted */
1749 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1750 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1751 !strcmp(name, "_fp_hw")) {
1752 } else {
1753 tcc_error_noabort("undefined symbol '%s'", name);
1760 /* Bind symbols of libraries: export all non local symbols of executable that
1761 are referenced by shared libraries. The reason is that the dynamic loader
1762 search symbol first in executable and then in libraries. Therefore a
1763 reference to a symbol already defined by a library can still be resolved by
1764 a symbol in the executable. With -rdynamic, export all defined symbols */
1765 static void bind_libs_dynsyms(TCCState *s1)
1767 const char *name;
1768 int dynsym_index;
1769 ElfW(Sym) *sym, *esym;
1771 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1772 name = (char *)symtab_section->link->data + sym->st_name;
1773 dynsym_index = find_elf_sym(s1->dynsymtab_section, name);
1774 if (sym->st_shndx != SHN_UNDEF
1775 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1776 if (dynsym_index || s1->rdynamic)
1777 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1778 sym->st_info, 0, sym->st_shndx, name);
1779 } else if (dynsym_index) {
1780 esym = (ElfW(Sym) *)s1->dynsymtab_section->data + dynsym_index;
1781 if (esym->st_shndx == SHN_UNDEF) {
1782 /* weak symbols can stay undefined */
1783 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1784 tcc_warning("undefined dynamic symbol '%s'", name);
1790 /* Export all non local symbols. This is used by shared libraries so that the
1791 non local symbols they define can resolve a reference in another shared
1792 library or in the executable. Correspondingly, it allows undefined local
1793 symbols to be resolved by other shared libraries or by the executable. */
1794 static void export_global_syms(TCCState *s1)
1796 int dynindex, index;
1797 const char *name;
1798 ElfW(Sym) *sym;
1799 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1800 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1801 name = (char *) symtab_section->link->data + sym->st_name;
1802 dynindex = set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1803 sym->st_info, 0, sym->st_shndx, name);
1804 index = sym - (ElfW(Sym) *) symtab_section->data;
1805 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1810 /* decide if an unallocated section should be output. */
1811 static int set_sec_sizes(TCCState *s1)
1813 int i;
1814 Section *s;
1815 int textrel = 0;
1816 int file_type = s1->output_type;
1818 /* Allocate strings for section names */
1819 for(i = 1; i < s1->nb_sections; i++) {
1820 s = s1->sections[i];
1821 if (s->sh_type == SHT_RELX && !(s->sh_flags & SHF_ALLOC)) {
1822 /* when generating a DLL, we include relocations but
1823 we may patch them */
1824 if (file_type == TCC_OUTPUT_DLL
1825 && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) {
1826 int count = prepare_dynamic_rel(s1, s);
1827 if (count) {
1828 /* allocate the section */
1829 s->sh_flags |= SHF_ALLOC;
1830 s->sh_size = count * sizeof(ElfW_Rel);
1831 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1832 textrel = 1;
1835 } else if ((s->sh_flags & SHF_ALLOC)
1836 #ifdef TCC_TARGET_ARM
1837 || s->sh_type == SHT_ARM_ATTRIBUTES
1838 #endif
1839 || s1->do_debug) {
1840 s->sh_size = s->data_offset;
1843 #ifdef TCC_TARGET_ARM
1844 /* XXX: Suppress stack unwinding section. */
1845 if (s->sh_type == SHT_ARM_EXIDX) {
1846 s->sh_flags = 0;
1847 s->sh_size = 0;
1849 #endif
1852 return textrel;
1856 /* Info to be copied in dynamic section */
1857 struct dyn_inf {
1858 Section *dynamic;
1859 Section *dynstr;
1860 unsigned long data_offset;
1861 addr_t rel_addr;
1862 addr_t rel_size;
1865 /* Info for GNU_RELRO */
1866 struct ro_inf {
1867 addr_t sh_offset;
1868 addr_t sh_addr;
1869 addr_t sh_size;
1872 static void alloc_sec_names(
1873 TCCState *s1, int is_obj
1876 static int layout_any_sections(
1877 TCCState *s1, int file_offset, int *sec_order, int is_obj
1880 /* Assign sections to segments and decide how are sections laid out when loaded
1881 in memory. This function also fills corresponding program headers. */
1882 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr,
1883 int phnum, int phfill,
1884 Section *interp,
1885 struct ro_inf *roinf, int *sec_order)
1887 int i, file_offset;
1888 Section *s;
1890 file_offset = 0;
1891 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1892 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1895 unsigned long s_align;
1896 long long tmp;
1897 addr_t addr;
1898 ElfW(Phdr) *ph;
1899 int j, k, f, file_type = s1->output_type;
1901 s_align = ELF_PAGE_SIZE;
1902 if (s1->section_align)
1903 s_align = s1->section_align;
1905 if (s1->has_text_addr) {
1906 int a_offset, p_offset;
1907 addr = s1->text_addr;
1908 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1909 ELF_PAGE_SIZE */
1910 a_offset = (int) (addr & (s_align - 1));
1911 p_offset = file_offset & (s_align - 1);
1912 if (a_offset < p_offset)
1913 a_offset += s_align;
1914 file_offset += (a_offset - p_offset);
1915 } else {
1916 if (file_type == TCC_OUTPUT_DLL)
1917 addr = 0;
1918 else
1919 addr = ELF_START_ADDR;
1920 /* compute address after headers */
1921 addr += (file_offset & (s_align - 1));
1924 ph = &phdr[0];
1925 /* Leave one program headers for the program interpreter and one for
1926 the program header table itself if needed. These are done later as
1927 they require section layout to be done first. */
1928 if (interp)
1929 ph += 2;
1931 /* read only segment mapping for GNU_RELRO */
1932 roinf->sh_offset = roinf->sh_addr = roinf->sh_size = 0;
1934 for(j = 0; j < phfill; j++) {
1935 ph->p_type = j == 2 ? PT_TLS : PT_LOAD;
1936 if (j == 0)
1937 ph->p_flags = PF_R | PF_X;
1938 else
1939 ph->p_flags = PF_R | PF_W;
1940 ph->p_align = j == 2 ? 4 : s_align;
1942 /* Decide the layout of sections loaded in memory. This must
1943 be done before program headers are filled since they contain
1944 info about the layout. We do the following ordering: interp,
1945 symbol tables, relocations, progbits, nobits */
1946 /* XXX: do faster and simpler sorting */
1947 f = -1;
1948 for(k = 0; k < 7; k++) {
1949 for(i = 1; i < s1->nb_sections; i++) {
1950 s = s1->sections[i];
1951 /* compute if section should be included */
1952 if (j == 0) {
1953 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1954 SHF_ALLOC)
1955 continue;
1956 } else if (j == 1) {
1957 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1958 (SHF_ALLOC | SHF_WRITE))
1959 continue;
1960 } else {
1961 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1962 (SHF_ALLOC | SHF_WRITE | SHF_TLS))
1963 continue;
1965 if (s == interp) {
1966 if (k != 0)
1967 continue;
1968 } else if ((s->sh_type == SHT_DYNSYM ||
1969 s->sh_type == SHT_STRTAB ||
1970 s->sh_type == SHT_HASH)
1971 && !strstr(s->name, ".stab")) {
1972 if (k != 1)
1973 continue;
1974 } else if (s->sh_type == SHT_RELX) {
1975 if (s1->plt && s == s1->plt->reloc) {
1976 if (k != 3)
1977 continue;
1978 } else {
1979 if (k != 2)
1980 continue;
1982 } else if (s->sh_type == SHT_NOBITS) {
1983 if (k != 6)
1984 continue;
1985 } else if ((s == rodata_section
1986 #ifdef CONFIG_TCC_BCHECK
1987 || s == bounds_section
1988 || s == lbounds_section
1989 #endif
1990 ) && (s->sh_flags & SHF_WRITE)) {
1991 if (k != 4)
1992 continue;
1993 /* Align next section on page size.
1994 This is needed to remap roinf section ro. */
1995 f = 1;
1996 } else {
1997 if (k != 5)
1998 continue;
2000 *sec_order++ = i;
2002 /* section matches: we align it and add its size */
2003 tmp = addr;
2004 if (f-- == 0)
2005 s->sh_addralign = PAGESIZE;
2006 addr = (addr + s->sh_addralign - 1) &
2007 ~(s->sh_addralign - 1);
2008 file_offset += (int) ( addr - tmp );
2009 s->sh_offset = file_offset;
2010 s->sh_addr = addr;
2012 /* update program header infos */
2013 if (ph->p_offset == 0) {
2014 ph->p_offset = file_offset;
2015 ph->p_vaddr = addr;
2016 ph->p_paddr = ph->p_vaddr;
2019 if (k == 4) {
2020 if (roinf->sh_size == 0) {
2021 roinf->sh_offset = s->sh_offset;
2022 roinf->sh_addr = s->sh_addr;
2024 roinf->sh_size = (addr - roinf->sh_addr) + s->sh_size;
2027 addr += s->sh_size;
2028 if (s->sh_type != SHT_NOBITS)
2029 file_offset += s->sh_size;
2032 if (j == 0) {
2033 /* Make the first PT_LOAD segment include the program
2034 headers itself (and the ELF header as well), it'll
2035 come out with same memory use but will make various
2036 tools like binutils strip work better. */
2037 ph->p_offset &= ~(ph->p_align - 1);
2038 ph->p_vaddr &= ~(ph->p_align - 1);
2039 ph->p_paddr &= ~(ph->p_align - 1);
2041 ph->p_filesz = file_offset - ph->p_offset;
2042 ph->p_memsz = addr - ph->p_vaddr;
2043 ph++;
2044 if (j == 0) {
2045 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
2046 /* if in the middle of a page, we duplicate the page in
2047 memory so that one copy is RX and the other is RW */
2048 if ((addr & (s_align - 1)) != 0)
2049 addr += s_align;
2050 } else {
2051 addr = (addr + s_align - 1) & ~(s_align - 1);
2052 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
2058 /* all other sections come after */
2059 return layout_any_sections(s1, file_offset, sec_order, 0);
2062 /* put dynamic tag */
2063 static void put_dt(Section *dynamic, int dt, addr_t val)
2065 ElfW(Dyn) *dyn;
2066 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
2067 dyn->d_tag = dt;
2068 dyn->d_un.d_val = val;
2071 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
2072 Section *dynamic, Section *note, struct ro_inf *roinf)
2074 ElfW(Phdr) *ph;
2076 /* if interpreter, then add corresponding program header */
2077 if (interp) {
2078 ph = &phdr[0];
2080 ph->p_type = PT_PHDR;
2081 ph->p_offset = sizeof(ElfW(Ehdr));
2082 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
2083 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
2084 ph->p_paddr = ph->p_vaddr;
2085 ph->p_flags = PF_R | PF_X;
2086 ph->p_align = 4; /* interp->sh_addralign; */
2087 ph++;
2089 ph->p_type = PT_INTERP;
2090 ph->p_offset = interp->sh_offset;
2091 ph->p_vaddr = interp->sh_addr;
2092 ph->p_paddr = ph->p_vaddr;
2093 ph->p_filesz = interp->sh_size;
2094 ph->p_memsz = interp->sh_size;
2095 ph->p_flags = PF_R;
2096 ph->p_align = interp->sh_addralign;
2099 if (note) {
2100 ph = &phdr[phnum - 2 - (roinf != NULL)];
2102 ph->p_type = PT_NOTE;
2103 ph->p_offset = note->sh_offset;
2104 ph->p_vaddr = note->sh_addr;
2105 ph->p_paddr = ph->p_vaddr;
2106 ph->p_filesz = note->sh_size;
2107 ph->p_memsz = note->sh_size;
2108 ph->p_flags = PF_R;
2109 ph->p_align = note->sh_addralign;
2112 /* if dynamic section, then add corresponding program header */
2113 if (dynamic) {
2114 ph = &phdr[phnum - 1 - (roinf != NULL)];
2116 ph->p_type = PT_DYNAMIC;
2117 ph->p_offset = dynamic->sh_offset;
2118 ph->p_vaddr = dynamic->sh_addr;
2119 ph->p_paddr = ph->p_vaddr;
2120 ph->p_filesz = dynamic->sh_size;
2121 ph->p_memsz = dynamic->sh_size;
2122 ph->p_flags = PF_R | PF_W;
2123 ph->p_align = dynamic->sh_addralign;
2126 if (roinf) {
2127 ph = &phdr[phnum - 1];
2129 ph->p_type = PT_GNU_RELRO;
2130 ph->p_offset = roinf->sh_offset;
2131 ph->p_vaddr = roinf->sh_addr;
2132 ph->p_paddr = ph->p_vaddr;
2133 ph->p_filesz = roinf->sh_size;
2134 ph->p_memsz = roinf->sh_size;
2135 ph->p_flags = PF_R;
2136 ph->p_align = 1;
2140 /* Fill the dynamic section with tags describing the address and size of
2141 sections */
2142 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2144 Section *dynamic = dyninf->dynamic;
2145 Section *s;
2147 /* put dynamic section entries */
2148 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2149 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2150 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2151 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2152 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2153 #if PTR_SIZE == 8
2154 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2155 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2156 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2157 if (s1->plt && s1->plt->reloc) {
2158 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2159 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2160 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2161 put_dt(dynamic, DT_PLTREL, DT_RELA);
2163 put_dt(dynamic, DT_RELACOUNT, 0);
2164 #else
2165 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2166 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2167 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2168 if (s1->plt && s1->plt->reloc) {
2169 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2170 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2171 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2172 put_dt(dynamic, DT_PLTREL, DT_REL);
2174 put_dt(dynamic, DT_RELCOUNT, 0);
2175 #endif
2176 if (versym_section && verneed_section) {
2177 /* The dynamic linker can not handle VERSYM without VERNEED */
2178 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2179 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2180 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2182 s = find_section_create (s1, ".preinit_array", 0);
2183 if (s && s->data_offset) {
2184 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2185 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2187 s = find_section_create (s1, ".init_array", 0);
2188 if (s && s->data_offset) {
2189 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2190 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2192 s = find_section_create (s1, ".fini_array", 0);
2193 if (s && s->data_offset) {
2194 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2195 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2197 s = find_section_create (s1, ".init", 0);
2198 if (s && s->data_offset) {
2199 put_dt(dynamic, DT_INIT, s->sh_addr);
2201 s = find_section_create (s1, ".fini", 0);
2202 if (s && s->data_offset) {
2203 put_dt(dynamic, DT_FINI, s->sh_addr);
2205 if (s1->do_debug)
2206 put_dt(dynamic, DT_DEBUG, 0);
2207 put_dt(dynamic, DT_NULL, 0);
2210 /* Remove gaps between RELX sections.
2211 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2212 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2213 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2214 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2215 static void update_reloc_sections(TCCState *s1, struct dyn_inf *dyninf)
2217 int i;
2218 unsigned long file_offset = 0;
2219 Section *s;
2220 Section *relocplt = s1->plt ? s1->plt->reloc : NULL;
2222 /* dynamic relocation table information, for .dynamic section */
2223 dyninf->rel_addr = dyninf->rel_size = 0;
2225 for(i = 1; i < s1->nb_sections; i++) {
2226 s = s1->sections[i];
2227 if (s->sh_type == SHT_RELX && s != relocplt) {
2228 if (dyninf->rel_size == 0) {
2229 dyninf->rel_addr = s->sh_addr;
2230 file_offset = s->sh_offset;
2232 else {
2233 s->sh_addr = dyninf->rel_addr + dyninf->rel_size;
2234 s->sh_offset = file_offset + dyninf->rel_size;
2236 dyninf->rel_size += s->sh_size;
2241 #endif /* ndef ELF_OBJ_ONLY */
2243 /* Create an ELF file on disk.
2244 This function handle ELF specific layout requirements */
2245 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2246 int file_offset, int *sec_order)
2248 int i, shnum, offset, size, file_type;
2249 Section *s;
2250 ElfW(Ehdr) ehdr;
2251 ElfW(Shdr) shdr, *sh;
2253 file_type = s1->output_type;
2254 shnum = s1->nb_sections;
2256 memset(&ehdr, 0, sizeof(ehdr));
2258 if (phnum > 0) {
2259 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2260 ehdr.e_phnum = phnum;
2261 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2264 /* align to 4 */
2265 file_offset = (file_offset + 3) & -4;
2267 /* fill header */
2268 ehdr.e_ident[0] = ELFMAG0;
2269 ehdr.e_ident[1] = ELFMAG1;
2270 ehdr.e_ident[2] = ELFMAG2;
2271 ehdr.e_ident[3] = ELFMAG3;
2272 ehdr.e_ident[4] = ELFCLASSW;
2273 ehdr.e_ident[5] = ELFDATA2LSB;
2274 ehdr.e_ident[6] = EV_CURRENT;
2275 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2276 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2277 #endif
2278 #ifdef TCC_TARGET_ARM
2279 #ifdef TCC_ARM_EABI
2280 ehdr.e_ident[EI_OSABI] = 0;
2281 ehdr.e_flags = EF_ARM_EABI_VER4;
2282 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2283 ehdr.e_flags |= EF_ARM_HASENTRY;
2284 if (s1->float_abi == ARM_HARD_FLOAT)
2285 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2286 else
2287 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2288 #else
2289 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2290 #endif
2291 #elif defined TCC_TARGET_RISCV64
2292 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2293 #endif
2294 switch(file_type) {
2295 default:
2296 case TCC_OUTPUT_EXE:
2297 ehdr.e_type = ET_EXEC;
2298 ehdr.e_entry = get_sym_addr(s1,
2299 s1->elf_entryname ?
2300 s1->elf_entryname : "_start",
2301 1, 0);
2302 break;
2303 case TCC_OUTPUT_DLL:
2304 ehdr.e_type = ET_DYN;
2305 ehdr.e_entry = s1->elf_entryname ?
2306 get_sym_addr(s1,s1->elf_entryname,1,0) :
2307 text_section->sh_addr;
2308 /* XXX: is it correct ? */
2309 break;
2310 case TCC_OUTPUT_OBJ:
2311 ehdr.e_type = ET_REL;
2312 break;
2314 ehdr.e_machine = EM_TCC_TARGET;
2315 ehdr.e_version = EV_CURRENT;
2316 ehdr.e_shoff = file_offset;
2317 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2318 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2319 ehdr.e_shnum = shnum;
2320 ehdr.e_shstrndx = shnum - 1;
2322 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2323 if (phdr)
2324 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2325 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2327 sort_syms(s1, symtab_section);
2328 for(i = 1; i < s1->nb_sections; i++) {
2329 s = s1->sections[sec_order[i]];
2330 if (s->sh_type != SHT_NOBITS) {
2331 while (offset < s->sh_offset) {
2332 fputc(0, f);
2333 offset++;
2335 size = s->sh_size;
2336 if (size)
2337 fwrite(s->data, 1, size, f);
2338 offset += size;
2342 /* output section headers */
2343 while (offset < ehdr.e_shoff) {
2344 fputc(0, f);
2345 offset++;
2348 for(i = 0; i < s1->nb_sections; i++) {
2349 sh = &shdr;
2350 memset(sh, 0, sizeof(ElfW(Shdr)));
2351 s = s1->sections[i];
2352 if (s) {
2353 sh->sh_name = s->sh_name;
2354 sh->sh_type = s->sh_type;
2355 sh->sh_flags = s->sh_flags;
2356 sh->sh_entsize = s->sh_entsize;
2357 sh->sh_info = s->sh_info;
2358 if (s->link)
2359 sh->sh_link = s->link->sh_num;
2360 sh->sh_addralign = s->sh_addralign;
2361 sh->sh_addr = s->sh_addr;
2362 sh->sh_offset = s->sh_offset;
2363 sh->sh_size = s->sh_size;
2365 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2369 static void tcc_output_binary(TCCState *s1, FILE *f,
2370 const int *sec_order)
2372 Section *s;
2373 int i, offset, size;
2375 offset = 0;
2376 for(i=1;i<s1->nb_sections;i++) {
2377 s = s1->sections[sec_order[i]];
2378 if (s->sh_type != SHT_NOBITS &&
2379 (s->sh_flags & SHF_ALLOC)) {
2380 while (offset < s->sh_offset) {
2381 fputc(0, f);
2382 offset++;
2384 size = s->sh_size;
2385 fwrite(s->data, 1, size, f);
2386 offset += size;
2391 /* Write an elf, coff or "binary" file */
2392 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2393 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2395 int fd, mode, file_type;
2396 FILE *f;
2398 file_type = s1->output_type;
2399 if (file_type == TCC_OUTPUT_OBJ)
2400 mode = 0666;
2401 else
2402 mode = 0777;
2403 unlink(filename);
2404 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2405 if (fd < 0 || (f = fdopen(fd, "wb")) == NULL) {
2406 tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno));
2407 return -1;
2409 if (s1->verbose)
2410 printf("<- %s\n", filename);
2412 #ifdef TCC_TARGET_COFF
2413 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2414 tcc_output_coff(s1, f);
2415 else
2416 #endif
2417 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2418 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2419 else
2420 tcc_output_binary(s1, f, sec_order);
2421 fclose(f);
2423 return 0;
2426 #ifndef ELF_OBJ_ONLY
2427 /* Sort section headers by assigned sh_addr, remove sections
2428 that we aren't going to output. */
2429 static void tidy_section_headers(TCCState *s1, int *sec_order)
2431 int i, nnew, l, *backmap;
2432 Section **snew, *s;
2433 ElfW(Sym) *sym;
2435 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2436 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2437 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2438 s = s1->sections[sec_order[i]];
2439 if (!i || s->sh_name) {
2440 backmap[sec_order[i]] = nnew;
2441 snew[nnew] = s;
2442 ++nnew;
2443 } else {
2444 backmap[sec_order[i]] = 0;
2445 snew[--l] = s;
2448 for (i = 0; i < nnew; i++) {
2449 s = snew[i];
2450 if (s) {
2451 s->sh_num = i;
2452 if (s->sh_type == SHT_RELX)
2453 s->sh_info = backmap[s->sh_info];
2457 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2458 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2459 sym->st_shndx = backmap[sym->st_shndx];
2460 if ( !s1->static_link ) {
2461 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2462 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2463 sym->st_shndx = backmap[sym->st_shndx];
2465 for (i = 0; i < s1->nb_sections; i++)
2466 sec_order[i] = i;
2467 tcc_free(s1->sections);
2468 s1->sections = snew;
2469 s1->nb_sections = nnew;
2470 tcc_free(backmap);
2473 #ifdef TCC_TARGET_ARM
2474 static void create_arm_attribute_section(TCCState *s1)
2476 // Needed for DLL support.
2477 static const unsigned char arm_attr[] = {
2478 0x41, // 'A'
2479 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2480 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2481 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2482 0x05, 0x36, 0x00, // 'CPU_name', "6"
2483 0x06, 0x06, // 'CPU_arch', 'v6'
2484 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2485 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2486 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2487 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2488 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2489 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2490 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2491 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2492 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2493 0x1a, 0x02, // 'ABI_enum_size', 'int'
2494 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2495 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2497 Section *attr = new_section(s1, ".ARM.attributes", SHT_ARM_ATTRIBUTES, 0);
2498 unsigned char *ptr = section_ptr_add(attr, sizeof(arm_attr));
2499 attr->sh_addralign = 1;
2500 memcpy(ptr, arm_attr, sizeof(arm_attr));
2501 if (s1->float_abi != ARM_HARD_FLOAT) {
2502 ptr[26] = 0x00; // 'FP_arch', 'No'
2503 ptr[41] = 0x1e; // 'ABI_optimization_goals'
2504 ptr[42] = 0x06; // 'Aggressive Debug'
2507 #endif
2509 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2510 static Section *create_bsd_note_section(TCCState *s1,
2511 const char *name,
2512 const char *value)
2514 Section *s = find_section (s1, name);
2516 if (s->data_offset == 0) {
2517 char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
2518 ElfW(Nhdr) *note = (ElfW(Nhdr) *) ptr;
2520 s->sh_type = SHT_NOTE;
2521 note->n_namesz = 8;
2522 note->n_descsz = 4;
2523 note->n_type = ELF_NOTE_OS_GNU;
2524 strcpy (ptr + sizeof(ElfW(Nhdr)), value);
2526 return s;
2528 #endif
2530 static void alloc_sec_names(TCCState *s1, int is_obj);
2532 /* Output an elf, coff or binary file */
2533 /* XXX: suppress unneeded sections */
2534 static int elf_output_file(TCCState *s1, const char *filename)
2536 int i, ret, phnum, phfill, shnum, file_type, file_offset, *sec_order;
2537 struct dyn_inf dyninf = {0};
2538 struct ro_inf roinf;
2539 ElfW(Phdr) *phdr;
2540 Section *interp, *dynamic, *dynstr, *note;
2541 struct ro_inf *roinf_use = NULL;
2542 int textrel, got_sym;
2544 file_type = s1->output_type;
2545 s1->nb_errors = 0;
2546 ret = -1;
2547 phdr = NULL;
2548 sec_order = NULL;
2549 interp = dynamic = dynstr = note = NULL;
2551 #ifdef TCC_TARGET_ARM
2552 create_arm_attribute_section (s1);
2553 #endif
2555 #if TARGETOS_OpenBSD
2556 note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
2557 #endif
2559 #if TARGETOS_NetBSD
2560 note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD");
2561 #endif
2564 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2565 tcc_add_runtime(s1);
2566 resolve_common_syms(s1);
2568 if (!s1->static_link) {
2569 if (file_type == TCC_OUTPUT_EXE) {
2570 char *ptr;
2571 /* allow override the dynamic loader */
2572 const char *elfint = getenv("LD_SO");
2573 if (elfint == NULL)
2574 elfint = DEFAULT_ELFINTERP(s1);
2575 /* add interpreter section only if executable */
2576 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2577 interp->sh_addralign = 1;
2578 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2579 strcpy(ptr, elfint);
2582 /* add dynamic symbol table */
2583 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2584 ".dynstr",
2585 ".hash", SHF_ALLOC);
2586 /* Number of local symbols (readelf complains if not set) */
2587 s1->dynsym->sh_info = 1;
2588 dynstr = s1->dynsym->link;
2589 /* add dynamic section */
2590 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2591 SHF_ALLOC | SHF_WRITE);
2592 dynamic->link = dynstr;
2593 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2595 got_sym = build_got(s1);
2596 if (file_type == TCC_OUTPUT_EXE) {
2597 bind_exe_dynsyms(s1);
2598 if (s1->nb_errors)
2599 goto the_end;
2601 build_got_entries(s1, got_sym);
2602 if (file_type == TCC_OUTPUT_EXE) {
2603 bind_libs_dynsyms(s1);
2604 } else {
2605 /* shared library case: simply export all global symbols */
2606 export_global_syms(s1);
2608 } else {
2609 build_got_entries(s1, 0);
2611 version_add (s1);
2614 textrel = set_sec_sizes(s1);
2615 alloc_sec_names(s1, 0);
2617 if (!s1->static_link) {
2618 int i;
2619 /* add a list of needed dlls */
2620 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2621 DLLReference *dllref = s1->loaded_dlls[i];
2622 if (dllref->level == 0)
2623 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2626 if (s1->rpath)
2627 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2628 put_elf_str(dynstr, s1->rpath));
2630 if (file_type == TCC_OUTPUT_DLL) {
2631 if (s1->soname)
2632 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2633 /* XXX: currently, since we do not handle PIC code, we
2634 must relocate the readonly segments */
2635 if (textrel)
2636 put_dt(dynamic, DT_TEXTREL, 0);
2639 if (s1->symbolic)
2640 put_dt(dynamic, DT_SYMBOLIC, 0);
2642 dyninf.dynamic = dynamic;
2643 dyninf.dynstr = dynstr;
2644 /* remember offset and reserve space for 2nd call below */
2645 dyninf.data_offset = dynamic->data_offset;
2646 fill_dynamic(s1, &dyninf);
2647 dynamic->sh_size = dynamic->data_offset;
2648 dynstr->sh_size = dynstr->data_offset;
2651 for (i = 1; i < s1->nb_sections &&
2652 !(s1->sections[i]->sh_flags & SHF_TLS); i++);
2653 phfill = 2 + (i < s1->nb_sections);
2655 /* compute number of program headers */
2656 if (file_type == TCC_OUTPUT_DLL)
2657 phnum = 3;
2658 else if (s1->static_link)
2659 phnum = 3;
2660 else {
2661 phnum = 5 + (i < s1->nb_sections);
2664 phnum += note != NULL;
2665 #if !TARGETOS_FreeBSD && !TARGETOS_NetBSD
2666 /* GNU_RELRO */
2667 phnum++, roinf_use = &roinf;
2668 #endif
2670 /* allocate program segment headers */
2671 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2672 /* compute number of sections */
2673 shnum = s1->nb_sections;
2674 /* this array is used to reorder sections in the output file */
2675 sec_order = tcc_malloc(sizeof(int) * shnum);
2676 sec_order[0] = 0;
2678 /* compute section to program header mapping */
2679 file_offset = layout_sections(s1, phdr, phnum, phfill, interp, &roinf, sec_order + 1);
2681 /* Fill remaining program header and finalize relocation related to dynamic
2682 linking. */
2684 fill_unloadable_phdr(phdr, phnum, interp, dynamic, note, roinf_use);
2685 if (dynamic) {
2686 ElfW(Sym) *sym;
2688 /* put in GOT the dynamic section address and relocate PLT */
2689 write32le(s1->got->data, dynamic->sh_addr);
2690 if (file_type == TCC_OUTPUT_EXE
2691 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2692 relocate_plt(s1);
2694 /* relocate symbols in .dynsym now that final addresses are known */
2695 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2696 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2697 /* do symbol relocation */
2698 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2703 /* if building executable or DLL, then relocate each section
2704 except the GOT which is already relocated */
2705 relocate_syms(s1, s1->symtab, 0);
2706 ret = -1;
2707 if (s1->nb_errors != 0)
2708 goto the_end;
2709 relocate_sections(s1);
2710 if (dynamic) {
2711 update_reloc_sections (s1, &dyninf);
2712 dynamic->data_offset = dyninf.data_offset;
2713 fill_dynamic(s1, &dyninf);
2715 tidy_section_headers(s1, sec_order);
2717 /* Perform relocation to GOT or PLT entries */
2718 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2719 fill_got(s1);
2720 else if (s1->got)
2721 fill_local_got_entries(s1);
2723 /* Create the ELF file with name 'filename' */
2724 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2725 s1->nb_sections = shnum;
2727 the_end:
2728 tcc_free(sec_order);
2729 tcc_free(phdr);
2730 return ret;
2732 #endif /* ndef ELF_OBJ_ONLY */
2734 /* Allocate strings for section names */
2735 static void alloc_sec_names(TCCState *s1, int is_obj)
2737 int i;
2738 Section *s, *strsec;
2740 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2741 put_elf_str(strsec, "");
2742 for(i = 1; i < s1->nb_sections; i++) {
2743 s = s1->sections[i];
2744 if (is_obj)
2745 s->sh_size = s->data_offset;
2746 if (s == strsec || s->sh_size || (s->sh_flags & SHF_ALLOC))
2747 s->sh_name = put_elf_str(strsec, s->name);
2749 strsec->sh_size = strsec->data_offset;
2752 static int layout_any_sections(TCCState *s1, int file_offset, int *sec_order, int is_obj)
2754 int i;
2755 Section *s;
2756 for(i = 1; i < s1->nb_sections; i++) {
2757 s = s1->sections[i];
2758 if (!is_obj && (s->sh_flags & SHF_ALLOC))
2759 continue;
2760 *sec_order++ = i;
2761 file_offset = (file_offset + s->sh_addralign - 1) &
2762 ~(s->sh_addralign - 1);
2763 s->sh_offset = file_offset;
2764 if (s->sh_type != SHT_NOBITS)
2765 file_offset += s->sh_size;
2767 return file_offset;
2770 /* Output an elf .o file */
2771 static int elf_output_obj(TCCState *s1, const char *filename)
2773 int ret, file_offset;
2774 int *sec_order;
2775 s1->nb_errors = 0;
2777 /* Allocate strings for section names */
2778 alloc_sec_names(s1, 1);
2780 /* this array is used to reorder sections in the output file */
2781 sec_order = tcc_malloc(sizeof(int) * s1->nb_sections);
2782 sec_order[0] = 0;
2783 file_offset = layout_any_sections(s1, sizeof (ElfW(Ehdr)), sec_order + 1, 1);
2785 /* Create the ELF file with name 'filename' */
2786 ret = tcc_write_elf_file(s1, filename, 0, NULL, file_offset, sec_order);
2787 tcc_free(sec_order);
2788 return ret;
2791 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2793 if (s->test_coverage)
2794 tcc_tcov_add_file(s, filename);
2795 if (s->output_type == TCC_OUTPUT_OBJ)
2796 return elf_output_obj(s, filename);
2797 #ifdef TCC_TARGET_PE
2798 return pe_output_file(s, filename);
2799 #elif TCC_TARGET_MACHO
2800 return macho_output_file(s, filename);
2801 #else
2802 return elf_output_file(s, filename);
2803 #endif
2806 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
2807 char *cbuf = buf;
2808 size_t rnum = 0;
2809 while (1) {
2810 ssize_t num = read(fd, cbuf, count-rnum);
2811 if (num < 0) return num;
2812 if (num == 0) return rnum;
2813 rnum += num;
2814 cbuf += num;
2818 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
2820 void *data;
2822 data = tcc_malloc(size);
2823 lseek(fd, file_offset, SEEK_SET);
2824 full_read(fd, data, size);
2825 return data;
2828 typedef struct SectionMergeInfo {
2829 Section *s; /* corresponding existing section */
2830 unsigned long offset; /* offset of the new section in the existing section */
2831 uint8_t new_section; /* true if section 's' was added */
2832 uint8_t link_once; /* true if link once section */
2833 } SectionMergeInfo;
2835 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2837 int size = full_read(fd, h, sizeof *h);
2838 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2839 if (h->e_type == ET_REL)
2840 return AFF_BINTYPE_REL;
2841 if (h->e_type == ET_DYN)
2842 return AFF_BINTYPE_DYN;
2843 } else if (size >= 8) {
2844 if (0 == memcmp(h, ARMAG, 8))
2845 return AFF_BINTYPE_AR;
2846 #ifdef TCC_TARGET_COFF
2847 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2848 return AFF_BINTYPE_C67;
2849 #endif
2851 return 0;
2854 /* load an object file and merge it with current files */
2855 /* XXX: handle correctly stab (debug) info */
2856 ST_FUNC int tcc_load_object_file(TCCState *s1,
2857 int fd, unsigned long file_offset)
2859 ElfW(Ehdr) ehdr;
2860 ElfW(Shdr) *shdr, *sh;
2861 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2862 char *strsec, *strtab;
2863 int stab_index, stabstr_index;
2864 int *old_to_new_syms;
2865 char *sh_name, *name;
2866 SectionMergeInfo *sm_table, *sm;
2867 ElfW(Sym) *sym, *symtab;
2868 ElfW_Rel *rel;
2869 Section *s;
2871 lseek(fd, file_offset, SEEK_SET);
2872 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2873 goto fail1;
2874 /* test CPU specific stuff */
2875 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2876 ehdr.e_machine != EM_TCC_TARGET) {
2877 fail1:
2878 tcc_error_noabort("invalid object file");
2879 return -1;
2881 /* read sections */
2882 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2883 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2884 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2886 /* load section names */
2887 sh = &shdr[ehdr.e_shstrndx];
2888 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2890 /* load symtab and strtab */
2891 old_to_new_syms = NULL;
2892 symtab = NULL;
2893 strtab = NULL;
2894 nb_syms = 0;
2895 seencompressed = 0;
2896 stab_index = stabstr_index = 0;
2898 for(i = 1; i < ehdr.e_shnum; i++) {
2899 sh = &shdr[i];
2900 if (sh->sh_type == SHT_SYMTAB) {
2901 if (symtab) {
2902 tcc_error_noabort("object must contain only one symtab");
2903 fail:
2904 ret = -1;
2905 goto the_end;
2907 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2908 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2909 sm_table[i].s = symtab_section;
2911 /* now load strtab */
2912 sh = &shdr[sh->sh_link];
2913 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2915 if (sh->sh_flags & SHF_COMPRESSED)
2916 seencompressed = 1;
2919 /* now examine each section and try to merge its content with the
2920 ones in memory */
2921 for(i = 1; i < ehdr.e_shnum; i++) {
2922 /* no need to examine section name strtab */
2923 if (i == ehdr.e_shstrndx)
2924 continue;
2925 sh = &shdr[i];
2926 if (sh->sh_type == SHT_RELX)
2927 sh = &shdr[sh->sh_info];
2928 /* ignore sections types we do not handle (plus relocs to those) */
2929 if (sh->sh_type != SHT_PROGBITS &&
2930 #ifdef TCC_ARM_EABI
2931 sh->sh_type != SHT_ARM_EXIDX &&
2932 #endif
2933 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2934 sh->sh_type != SHT_X86_64_UNWIND &&
2935 #endif
2936 sh->sh_type != SHT_NOTE &&
2937 sh->sh_type != SHT_NOBITS &&
2938 sh->sh_type != SHT_PREINIT_ARRAY &&
2939 sh->sh_type != SHT_INIT_ARRAY &&
2940 sh->sh_type != SHT_FINI_ARRAY &&
2941 strcmp(strsec + sh->sh_name, ".stabstr")
2943 continue;
2944 if (seencompressed && 0 == strncmp(strsec + sh->sh_name, ".debug_", 7))
2945 continue;
2947 sh = &shdr[i];
2948 sh_name = strsec + sh->sh_name;
2949 if (sh->sh_addralign < 1)
2950 sh->sh_addralign = 1;
2951 /* find corresponding section, if any */
2952 for(j = 1; j < s1->nb_sections;j++) {
2953 s = s1->sections[j];
2954 if (!strcmp(s->name, sh_name)) {
2955 if (!strncmp(sh_name, ".gnu.linkonce",
2956 sizeof(".gnu.linkonce") - 1)) {
2957 /* if a 'linkonce' section is already present, we
2958 do not add it again. It is a little tricky as
2959 symbols can still be defined in
2960 it. */
2961 sm_table[i].link_once = 1;
2962 goto next;
2964 if (stab_section) {
2965 if (s == stab_section)
2966 stab_index = i;
2967 if (s == stab_section->link)
2968 stabstr_index = i;
2970 goto found;
2973 /* not found: create new section */
2974 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2975 /* take as much info as possible from the section. sh_link and
2976 sh_info will be updated later */
2977 s->sh_addralign = sh->sh_addralign;
2978 s->sh_entsize = sh->sh_entsize;
2979 sm_table[i].new_section = 1;
2980 found:
2981 if (sh->sh_type != s->sh_type) {
2982 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2983 if (strcmp (s->name, ".eh_frame"))
2984 #endif
2986 tcc_error_noabort("invalid section type");
2987 goto fail;
2990 /* align start of section */
2991 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
2992 if (sh->sh_addralign > s->sh_addralign)
2993 s->sh_addralign = sh->sh_addralign;
2994 sm_table[i].offset = s->data_offset;
2995 sm_table[i].s = s;
2996 /* concatenate sections */
2997 size = sh->sh_size;
2998 if (sh->sh_type != SHT_NOBITS) {
2999 unsigned char *ptr;
3000 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
3001 ptr = section_ptr_add(s, size);
3002 full_read(fd, ptr, size);
3003 } else {
3004 s->data_offset += size;
3006 next: ;
3009 /* gr relocate stab strings */
3010 if (stab_index && stabstr_index) {
3011 Stab_Sym *a, *b;
3012 unsigned o;
3013 s = sm_table[stab_index].s;
3014 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
3015 b = (Stab_Sym *)(s->data + s->data_offset);
3016 o = sm_table[stabstr_index].offset;
3017 while (a < b) {
3018 if (a->n_strx)
3019 a->n_strx += o;
3020 a++;
3024 /* second short pass to update sh_link and sh_info fields of new
3025 sections */
3026 for(i = 1; i < ehdr.e_shnum; i++) {
3027 s = sm_table[i].s;
3028 if (!s || !sm_table[i].new_section)
3029 continue;
3030 sh = &shdr[i];
3031 if (sh->sh_link > 0)
3032 s->link = sm_table[sh->sh_link].s;
3033 if (sh->sh_type == SHT_RELX) {
3034 s->sh_info = sm_table[sh->sh_info].s->sh_num;
3035 /* update backward link */
3036 s1->sections[s->sh_info]->reloc = s;
3040 /* resolve symbols */
3041 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
3043 sym = symtab + 1;
3044 for(i = 1; i < nb_syms; i++, sym++) {
3045 if (sym->st_shndx != SHN_UNDEF &&
3046 sym->st_shndx < SHN_LORESERVE) {
3047 sm = &sm_table[sym->st_shndx];
3048 if (sm->link_once) {
3049 /* if a symbol is in a link once section, we use the
3050 already defined symbol. It is very important to get
3051 correct relocations */
3052 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
3053 name = strtab + sym->st_name;
3054 sym_index = find_elf_sym(symtab_section, name);
3055 if (sym_index)
3056 old_to_new_syms[i] = sym_index;
3058 continue;
3060 /* if no corresponding section added, no need to add symbol */
3061 if (!sm->s)
3062 continue;
3063 /* convert section number */
3064 sym->st_shndx = sm->s->sh_num;
3065 /* offset value */
3066 sym->st_value += sm->offset;
3068 /* add symbol */
3069 name = strtab + sym->st_name;
3070 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
3071 sym->st_info, sym->st_other,
3072 sym->st_shndx, name);
3073 old_to_new_syms[i] = sym_index;
3076 /* third pass to patch relocation entries */
3077 for(i = 1; i < ehdr.e_shnum; i++) {
3078 s = sm_table[i].s;
3079 if (!s)
3080 continue;
3081 sh = &shdr[i];
3082 offset = sm_table[i].offset;
3083 size = sh->sh_size;
3084 switch(s->sh_type) {
3085 case SHT_RELX:
3086 /* take relocation offset information */
3087 offseti = sm_table[sh->sh_info].offset;
3088 for (rel = (ElfW_Rel *) s->data + (offset / sizeof(*rel));
3089 rel < (ElfW_Rel *) s->data + ((offset + size) / sizeof(*rel));
3090 rel++) {
3091 int type;
3092 unsigned sym_index;
3093 /* convert symbol index */
3094 type = ELFW(R_TYPE)(rel->r_info);
3095 sym_index = ELFW(R_SYM)(rel->r_info);
3096 /* NOTE: only one symtab assumed */
3097 if (sym_index >= nb_syms)
3098 goto invalid_reloc;
3099 sym_index = old_to_new_syms[sym_index];
3100 /* ignore link_once in rel section. */
3101 if (!sym_index && !sm_table[sh->sh_info].link_once
3102 #ifdef TCC_TARGET_ARM
3103 && type != R_ARM_V4BX
3104 #elif defined TCC_TARGET_RISCV64
3105 && type != R_RISCV_ALIGN
3106 && type != R_RISCV_RELAX
3107 #endif
3109 invalid_reloc:
3110 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3111 i, strsec + sh->sh_name, (int)rel->r_offset);
3112 goto fail;
3114 rel->r_info = ELFW(R_INFO)(sym_index, type);
3115 /* offset the relocation offset */
3116 rel->r_offset += offseti;
3117 #ifdef TCC_TARGET_ARM
3118 /* Jumps and branches from a Thumb code to a PLT entry need
3119 special handling since PLT entries are ARM code.
3120 Unconditional bl instructions referencing PLT entries are
3121 handled by converting these instructions into blx
3122 instructions. Other case of instructions referencing a PLT
3123 entry require to add a Thumb stub before the PLT entry to
3124 switch to ARM mode. We set bit plt_thumb_stub of the
3125 attribute of a symbol to indicate such a case. */
3126 if (type == R_ARM_THM_JUMP24)
3127 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
3128 #endif
3130 break;
3131 default:
3132 break;
3136 ret = 0;
3137 the_end:
3138 tcc_free(symtab);
3139 tcc_free(strtab);
3140 tcc_free(old_to_new_syms);
3141 tcc_free(sm_table);
3142 tcc_free(strsec);
3143 tcc_free(shdr);
3144 return ret;
3147 typedef struct ArchiveHeader {
3148 char ar_name[16]; /* name of this member */
3149 char ar_date[12]; /* file mtime */
3150 char ar_uid[6]; /* owner uid; printed as decimal */
3151 char ar_gid[6]; /* owner gid; printed as decimal */
3152 char ar_mode[8]; /* file mode, printed as octal */
3153 char ar_size[10]; /* file size, printed as decimal */
3154 char ar_fmag[2]; /* should contain ARFMAG */
3155 } ArchiveHeader;
3157 #define ARFMAG "`\n"
3159 static unsigned long long get_be(const uint8_t *b, int n)
3161 unsigned long long ret = 0;
3162 while (n)
3163 ret = (ret << 8) | *b++, --n;
3164 return ret;
3167 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
3169 char *p, *e;
3170 int len;
3171 lseek(fd, offset, SEEK_SET);
3172 len = full_read(fd, hdr, sizeof(ArchiveHeader));
3173 if (len != sizeof(ArchiveHeader))
3174 return len ? -1 : 0;
3175 p = hdr->ar_name;
3176 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
3177 --e;
3178 *e = '\0';
3179 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
3180 return len;
3183 /* load only the objects which resolve undefined symbols */
3184 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
3186 int i, bound, nsyms, sym_index, len, ret = -1;
3187 unsigned long long off;
3188 uint8_t *data;
3189 const char *ar_names, *p;
3190 const uint8_t *ar_index;
3191 ElfW(Sym) *sym;
3192 ArchiveHeader hdr;
3194 data = tcc_malloc(size);
3195 if (full_read(fd, data, size) != size)
3196 goto the_end;
3197 nsyms = get_be(data, entrysize);
3198 ar_index = data + entrysize;
3199 ar_names = (char *) ar_index + nsyms * entrysize;
3201 do {
3202 bound = 0;
3203 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
3204 Section *s = symtab_section;
3205 sym_index = find_elf_sym(s, p);
3206 if (!sym_index)
3207 continue;
3208 sym = &((ElfW(Sym) *)s->data)[sym_index];
3209 if(sym->st_shndx != SHN_UNDEF)
3210 continue;
3211 off = get_be(ar_index + i * entrysize, entrysize);
3212 len = read_ar_header(fd, off, &hdr);
3213 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
3214 tcc_error_noabort("invalid archive");
3215 goto the_end;
3217 off += len;
3218 if (s1->verbose == 2)
3219 printf(" -> %s\n", hdr.ar_name);
3220 if (tcc_load_object_file(s1, fd, off) < 0)
3221 goto the_end;
3222 ++bound;
3224 } while(bound);
3225 ret = 0;
3226 the_end:
3227 tcc_free(data);
3228 return ret;
3231 /* load a '.a' file */
3232 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
3234 ArchiveHeader hdr;
3235 /* char magic[8]; */
3236 int size, len;
3237 unsigned long file_offset;
3238 ElfW(Ehdr) ehdr;
3240 /* skip magic which was already checked */
3241 /* full_read(fd, magic, sizeof(magic)); */
3242 file_offset = sizeof ARMAG - 1;
3244 for(;;) {
3245 len = read_ar_header(fd, file_offset, &hdr);
3246 if (len == 0)
3247 return 0;
3248 if (len < 0) {
3249 tcc_error_noabort("invalid archive");
3250 return -1;
3252 file_offset += len;
3253 size = strtol(hdr.ar_size, NULL, 0);
3254 /* align to even */
3255 size = (size + 1) & ~1;
3256 if (alacarte) {
3257 /* coff symbol table : we handle it */
3258 if (!strcmp(hdr.ar_name, "/"))
3259 return tcc_load_alacarte(s1, fd, size, 4);
3260 if (!strcmp(hdr.ar_name, "/SYM64/"))
3261 return tcc_load_alacarte(s1, fd, size, 8);
3262 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3263 if (s1->verbose == 2)
3264 printf(" -> %s\n", hdr.ar_name);
3265 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3266 return -1;
3268 file_offset += size;
3272 #ifndef ELF_OBJ_ONLY
3273 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3274 LV, maybe create a new entry for (LIB,VERSION). */
3275 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3277 while (i >= *n) {
3278 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3279 (*lv)[(*n)++] = -1;
3281 if ((*lv)[i] == -1) {
3282 int v, prev_same_lib = -1;
3283 for (v = 0; v < nb_sym_versions; v++) {
3284 if (strcmp(sym_versions[v].lib, lib))
3285 continue;
3286 prev_same_lib = v;
3287 if (!strcmp(sym_versions[v].version, version))
3288 break;
3290 if (v == nb_sym_versions) {
3291 sym_versions = tcc_realloc (sym_versions,
3292 (v + 1) * sizeof(*sym_versions));
3293 sym_versions[v].lib = tcc_strdup(lib);
3294 sym_versions[v].version = tcc_strdup(version);
3295 sym_versions[v].out_index = 0;
3296 sym_versions[v].prev_same_lib = prev_same_lib;
3297 nb_sym_versions++;
3299 (*lv)[i] = v;
3303 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3304 VERNDX. */
3305 static void
3306 set_sym_version(TCCState *s1, int sym_index, int verndx)
3308 if (sym_index >= nb_sym_to_version) {
3309 int newelems = sym_index ? sym_index * 2 : 1;
3310 sym_to_version = tcc_realloc(sym_to_version,
3311 newelems * sizeof(*sym_to_version));
3312 memset(sym_to_version + nb_sym_to_version, -1,
3313 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3314 nb_sym_to_version = newelems;
3316 if (sym_to_version[sym_index] < 0)
3317 sym_to_version[sym_index] = verndx;
3320 struct versym_info {
3321 int nb_versyms;
3322 ElfW(Verdef) *verdef;
3323 ElfW(Verneed) *verneed;
3324 ElfW(Half) *versym;
3325 int nb_local_ver, *local_ver;
3329 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3331 char *lib, *version;
3332 uint32_t next;
3333 int i;
3335 #define DEBUG_VERSION 0
3337 if (v->versym && v->verdef) {
3338 ElfW(Verdef) *vdef = v->verdef;
3339 lib = NULL;
3340 do {
3341 ElfW(Verdaux) *verdaux =
3342 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3344 #if DEBUG_VERSION
3345 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3346 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3347 vdef->vd_hash);
3348 #endif
3349 if (vdef->vd_cnt) {
3350 version = dynstr + verdaux->vda_name;
3352 if (lib == NULL)
3353 lib = version;
3354 else
3355 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3356 lib, version);
3357 #if DEBUG_VERSION
3358 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3359 #endif
3361 next = vdef->vd_next;
3362 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3363 } while (next);
3365 if (v->versym && v->verneed) {
3366 ElfW(Verneed) *vneed = v->verneed;
3367 do {
3368 ElfW(Vernaux) *vernaux =
3369 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3371 lib = dynstr + vneed->vn_file;
3372 #if DEBUG_VERSION
3373 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3374 #endif
3375 for (i = 0; i < vneed->vn_cnt; i++) {
3376 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3377 version = dynstr + vernaux->vna_name;
3378 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3379 lib, version);
3380 #if DEBUG_VERSION
3381 printf (" vernaux(%u): %u %u %s\n",
3382 vernaux->vna_other, vernaux->vna_hash,
3383 vernaux->vna_flags, version);
3384 #endif
3386 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3388 next = vneed->vn_next;
3389 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3390 } while (next);
3393 #if DEBUG_VERSION
3394 for (i = 0; i < v->nb_local_ver; i++) {
3395 if (v->local_ver[i] > 0) {
3396 printf ("%d: lib: %s, version %s\n",
3397 i, sym_versions[v->local_ver[i]].lib,
3398 sym_versions[v->local_ver[i]].version);
3401 #endif
3404 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3405 is referenced by the user (so it should be added as DT_NEEDED in
3406 the generated ELF file) */
3407 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3409 ElfW(Ehdr) ehdr;
3410 ElfW(Shdr) *shdr, *sh, *sh1;
3411 int i, nb_syms, nb_dts, sym_bind, ret = -1;
3412 ElfW(Sym) *sym, *dynsym;
3413 ElfW(Dyn) *dt, *dynamic;
3415 char *dynstr;
3416 int sym_index;
3417 const char *name, *soname;
3418 struct versym_info v;
3420 full_read(fd, &ehdr, sizeof(ehdr));
3422 /* test CPU specific stuff */
3423 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3424 ehdr.e_machine != EM_TCC_TARGET) {
3425 tcc_error_noabort("bad architecture");
3426 return -1;
3429 /* read sections */
3430 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3432 /* load dynamic section and dynamic symbols */
3433 nb_syms = 0;
3434 nb_dts = 0;
3435 dynamic = NULL;
3436 dynsym = NULL; /* avoid warning */
3437 dynstr = NULL; /* avoid warning */
3438 memset(&v, 0, sizeof v);
3440 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3441 switch(sh->sh_type) {
3442 case SHT_DYNAMIC:
3443 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3444 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3445 break;
3446 case SHT_DYNSYM:
3447 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3448 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3449 sh1 = &shdr[sh->sh_link];
3450 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3451 break;
3452 case SHT_GNU_verdef:
3453 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3454 break;
3455 case SHT_GNU_verneed:
3456 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3457 break;
3458 case SHT_GNU_versym:
3459 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3460 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3461 break;
3462 default:
3463 break;
3467 if (!dynamic)
3468 goto the_end;
3470 /* compute the real library name */
3471 soname = tcc_basename(filename);
3472 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
3473 if (dt->d_tag == DT_SONAME)
3474 soname = dynstr + dt->d_un.d_val;
3476 /* if the dll is already loaded, do not load it */
3477 if (tcc_add_dllref(s1, soname, level)->found)
3478 goto ret_success;
3480 if (v.nb_versyms != nb_syms)
3481 tcc_free (v.versym), v.versym = NULL;
3482 else
3483 store_version(s1, &v, dynstr);
3485 /* add dynamic symbols in dynsym_section */
3486 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3487 sym_bind = ELFW(ST_BIND)(sym->st_info);
3488 if (sym_bind == STB_LOCAL)
3489 continue;
3490 name = dynstr + sym->st_name;
3491 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3492 sym->st_info, sym->st_other, sym->st_shndx, name);
3493 if (v.versym) {
3494 ElfW(Half) vsym = v.versym[i];
3495 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3496 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3500 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
3501 if (dt->d_tag == DT_RPATH)
3502 tcc_add_library_path(s1, dynstr + dt->d_un.d_val);
3504 /* load all referenced DLLs */
3505 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3506 switch(dt->d_tag) {
3507 case DT_NEEDED:
3508 name = dynstr + dt->d_un.d_val;
3509 if (tcc_add_dllref(s1, name, -1))
3510 continue;
3511 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3512 tcc_error_noabort("referenced dll '%s' not found", name);
3513 goto the_end;
3518 ret_success:
3519 ret = 0;
3520 the_end:
3521 tcc_free(dynstr);
3522 tcc_free(dynsym);
3523 tcc_free(dynamic);
3524 tcc_free(shdr);
3525 tcc_free(v.local_ver);
3526 tcc_free(v.verdef);
3527 tcc_free(v.verneed);
3528 tcc_free(v.versym);
3529 return ret;
3532 #define LD_TOK_NAME 256
3533 #define LD_TOK_EOF (-1)
3535 static int ld_inp(TCCState *s1)
3537 char b;
3538 if (s1->cc != -1) {
3539 int c = s1->cc;
3540 s1->cc = -1;
3541 return c;
3543 if (1 == read(s1->fd, &b, 1))
3544 return b;
3545 return CH_EOF;
3548 /* return next ld script token */
3549 static int ld_next(TCCState *s1, char *name, int name_size)
3551 int c, d, ch;
3552 char *q;
3554 redo:
3555 ch = ld_inp(s1);
3556 switch(ch) {
3557 case ' ':
3558 case '\t':
3559 case '\f':
3560 case '\v':
3561 case '\r':
3562 case '\n':
3563 goto redo;
3564 case '/':
3565 ch = ld_inp(s1);
3566 if (ch == '*') { /* comment */
3567 for (d = 0;; d = ch) {
3568 ch = ld_inp(s1);
3569 if (ch == CH_EOF || (ch == '/' && d == '*'))
3570 break;
3572 goto redo;
3573 } else {
3574 q = name;
3575 *q++ = '/';
3576 goto parse_name;
3578 break;
3579 case '\\':
3580 /* case 'a' ... 'z': */
3581 case 'a':
3582 case 'b':
3583 case 'c':
3584 case 'd':
3585 case 'e':
3586 case 'f':
3587 case 'g':
3588 case 'h':
3589 case 'i':
3590 case 'j':
3591 case 'k':
3592 case 'l':
3593 case 'm':
3594 case 'n':
3595 case 'o':
3596 case 'p':
3597 case 'q':
3598 case 'r':
3599 case 's':
3600 case 't':
3601 case 'u':
3602 case 'v':
3603 case 'w':
3604 case 'x':
3605 case 'y':
3606 case 'z':
3607 /* case 'A' ... 'z': */
3608 case 'A':
3609 case 'B':
3610 case 'C':
3611 case 'D':
3612 case 'E':
3613 case 'F':
3614 case 'G':
3615 case 'H':
3616 case 'I':
3617 case 'J':
3618 case 'K':
3619 case 'L':
3620 case 'M':
3621 case 'N':
3622 case 'O':
3623 case 'P':
3624 case 'Q':
3625 case 'R':
3626 case 'S':
3627 case 'T':
3628 case 'U':
3629 case 'V':
3630 case 'W':
3631 case 'X':
3632 case 'Y':
3633 case 'Z':
3634 case '_':
3635 case '.':
3636 case '$':
3637 case '~':
3638 q = name;
3639 parse_name:
3640 for(;;) {
3641 if (!((ch >= 'a' && ch <= 'z') ||
3642 (ch >= 'A' && ch <= 'Z') ||
3643 (ch >= '0' && ch <= '9') ||
3644 strchr("/.-_+=$:\\,~", ch)))
3645 break;
3646 if ((q - name) < name_size - 1) {
3647 *q++ = ch;
3649 ch = ld_inp(s1);
3651 s1->cc = ch;
3652 *q = '\0';
3653 c = LD_TOK_NAME;
3654 break;
3655 case CH_EOF:
3656 c = LD_TOK_EOF;
3657 break;
3658 default:
3659 c = ch;
3660 break;
3662 return c;
3665 static int ld_add_file(TCCState *s1, const char filename[])
3667 if (filename[0] == '/') {
3668 if (CONFIG_SYSROOT[0] == '\0'
3669 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3670 return 0;
3671 filename = tcc_basename(filename);
3673 return tcc_add_dll(s1, filename, 0);
3676 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3678 char filename[1024], libname[1024];
3679 int t, group, nblibs = 0, ret = 0;
3680 char **libs = NULL;
3682 group = !strcmp(cmd, "GROUP");
3683 if (!as_needed)
3684 s1->new_undef_sym = 0;
3685 t = ld_next(s1, filename, sizeof(filename));
3686 if (t != '(') {
3687 tcc_error_noabort("( expected");
3688 ret = -1;
3689 goto lib_parse_error;
3691 t = ld_next(s1, filename, sizeof(filename));
3692 for(;;) {
3693 libname[0] = '\0';
3694 if (t == LD_TOK_EOF) {
3695 tcc_error_noabort("unexpected end of file");
3696 ret = -1;
3697 goto lib_parse_error;
3698 } else if (t == ')') {
3699 break;
3700 } else if (t == '-') {
3701 t = ld_next(s1, filename, sizeof(filename));
3702 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3703 tcc_error_noabort("library name expected");
3704 ret = -1;
3705 goto lib_parse_error;
3707 pstrcpy(libname, sizeof libname, &filename[1]);
3708 if (s1->static_link) {
3709 snprintf(filename, sizeof filename, "lib%s.a", libname);
3710 } else {
3711 snprintf(filename, sizeof filename, "lib%s.so", libname);
3713 } else if (t != LD_TOK_NAME) {
3714 tcc_error_noabort("filename expected");
3715 ret = -1;
3716 goto lib_parse_error;
3718 if (!strcmp(filename, "AS_NEEDED")) {
3719 ret = ld_add_file_list(s1, cmd, 1);
3720 if (ret)
3721 goto lib_parse_error;
3722 } else {
3723 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3724 if (!as_needed) {
3725 ret = ld_add_file(s1, filename);
3726 if (ret)
3727 goto lib_parse_error;
3728 if (group) {
3729 /* Add the filename *and* the libname to avoid future conversions */
3730 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3731 if (libname[0] != '\0')
3732 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3736 t = ld_next(s1, filename, sizeof(filename));
3737 if (t == ',') {
3738 t = ld_next(s1, filename, sizeof(filename));
3741 if (group && !as_needed) {
3742 while (s1->new_undef_sym) {
3743 int i;
3744 s1->new_undef_sym = 0;
3745 for (i = 0; i < nblibs; i ++)
3746 ld_add_file(s1, libs[i]);
3749 lib_parse_error:
3750 dynarray_reset(&libs, &nblibs);
3751 return ret;
3754 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3755 files */
3756 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3758 char cmd[64];
3759 char filename[1024];
3760 int t, ret;
3762 s1->fd = fd;
3763 s1->cc = -1;
3764 for(;;) {
3765 t = ld_next(s1, cmd, sizeof(cmd));
3766 if (t == LD_TOK_EOF)
3767 return 0;
3768 else if (t != LD_TOK_NAME)
3769 return -1;
3770 if (!strcmp(cmd, "INPUT") ||
3771 !strcmp(cmd, "GROUP")) {
3772 ret = ld_add_file_list(s1, cmd, 0);
3773 if (ret)
3774 return ret;
3775 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3776 !strcmp(cmd, "TARGET")) {
3777 /* ignore some commands */
3778 t = ld_next(s1, cmd, sizeof(cmd));
3779 if (t != '(') {
3780 tcc_error_noabort("( expected");
3781 return -1;
3783 for(;;) {
3784 t = ld_next(s1, filename, sizeof(filename));
3785 if (t == LD_TOK_EOF) {
3786 tcc_error_noabort("unexpected end of file");
3787 return -1;
3788 } else if (t == ')') {
3789 break;
3792 } else {
3793 return -1;
3796 return 0;
3798 #endif /* !ELF_OBJ_ONLY */