tccgen: don't generate elf-symbols under nocode/NODATA
[tinycc.git] / tccelf.c
bloba72d0466ea97c142f2e61e7af54cb02a0e0f7a0b
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 void 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 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1048 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1049 /* keep space for _DYNAMIC pointer and two dummy got entries */
1050 section_ptr_add(s1->got, 3 * PTR_SIZE);
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)
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;
1164 redo:
1165 for(i = 1; i < s1->nb_sections; i++) {
1166 s = s1->sections[i];
1167 if (s->sh_type != SHT_RELX)
1168 continue;
1169 /* no need to handle got relocations */
1170 if (s->link != symtab_section)
1171 continue;
1172 for_each_elem(s, 0, rel, ElfW_Rel) {
1173 type = ELFW(R_TYPE)(rel->r_info);
1174 gotplt_entry = gotplt_entry_type(type);
1175 if (gotplt_entry == -1)
1176 tcc_error ("Unknown relocation type for got: %d", type);
1177 sym_index = ELFW(R_SYM)(rel->r_info);
1178 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1180 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1181 continue;
1184 /* Automatically create PLT/GOT [entry] if it is an undefined
1185 reference (resolved at runtime), or the symbol is absolute,
1186 probably created by tcc_add_symbol, and thus on 64-bit
1187 targets might be too far from application code. */
1188 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1189 if (sym->st_shndx == SHN_UNDEF) {
1190 ElfW(Sym) *esym;
1191 int dynindex;
1192 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1193 continue;
1194 /* Relocations for UNDEF symbols would normally need
1195 to be transferred into the executable or shared object.
1196 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1197 But TCC doesn't do that (at least for exes), so we
1198 need to resolve all such relocs locally. And that
1199 means PLT slots for functions in DLLs and COPY relocs for
1200 data symbols. COPY relocs were generated in
1201 bind_exe_dynsyms (and the symbol adjusted to be defined),
1202 and for functions we were generated a dynamic symbol
1203 of function type. */
1204 if (s1->dynsym) {
1205 /* dynsym isn't set for -run :-/ */
1206 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1207 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1208 if (dynindex
1209 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1210 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1211 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1212 goto jmp_slot;
1214 } else if (sym->st_shndx == SHN_ABS) {
1215 if (sym->st_value == 0) /* from tcc_add_btstub() */
1216 continue;
1217 #ifndef TCC_TARGET_ARM
1218 if (PTR_SIZE != 8)
1219 continue;
1220 #endif
1221 /* from tcc_add_symbol(): on 64 bit platforms these
1222 need to go through .got */
1223 } else
1224 continue;
1227 #ifdef TCC_TARGET_X86_64
1228 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1229 sym->st_shndx != SHN_UNDEF &&
1230 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1231 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1232 s1->output_type == TCC_OUTPUT_EXE)) {
1233 if (pass != 0)
1234 continue;
1235 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1236 continue;
1238 #endif
1239 reloc_type = code_reloc(type);
1240 if (reloc_type == -1)
1241 tcc_error ("Unknown relocation type: %d", type);
1243 if (reloc_type != 0) {
1244 jmp_slot:
1245 if (pass != 0)
1246 continue;
1247 reloc_type = R_JMP_SLOT;
1248 } else {
1249 if (pass != 1)
1250 continue;
1251 reloc_type = R_GLOB_DAT;
1254 if (!s1->got)
1255 build_got(s1);
1257 if (gotplt_entry == BUILD_GOT_ONLY)
1258 continue;
1260 attr = put_got_entry(s1, reloc_type, sym_index);
1262 if (reloc_type == R_JMP_SLOT)
1263 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1266 if (++pass < 2)
1267 goto redo;
1269 /* .rel.plt refers to .got actually */
1270 if (s1->plt && s1->plt->reloc)
1271 s1->plt->reloc->sh_info = s1->got->sh_num;
1274 #endif /* def NEED_BUILD_GOT */
1276 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
1278 int shn = sec ? sec->sh_num : offs || !name ? SHN_ABS : SHN_UNDEF;
1279 if (sec && offs == -1)
1280 offs = sec->data_offset;
1281 return set_elf_sym(symtab_section, offs, 0,
1282 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1285 static void add_init_array_defines(TCCState *s1, const char *section_name)
1287 Section *s;
1288 addr_t end_offset;
1289 char buf[1024];
1290 s = find_section_create(s1, section_name, 0);
1291 if (!s) {
1292 end_offset = 0;
1293 s = data_section;
1294 } else {
1295 end_offset = s->data_offset;
1297 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1298 set_global_sym(s1, buf, s, 0);
1299 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1300 set_global_sym(s1, buf, s, end_offset);
1303 #ifndef TCC_TARGET_PE
1304 static void tcc_add_support(TCCState *s1, const char *filename)
1306 char buf[1024];
1307 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1308 tcc_add_file(s1, buf);
1310 #endif
1312 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1314 Section *s;
1315 s = find_section(s1, sec);
1316 s->sh_flags |= SHF_WRITE;
1317 #ifndef TCC_TARGET_PE
1318 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1319 #endif
1320 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1321 section_ptr_add(s, PTR_SIZE);
1324 #ifdef CONFIG_TCC_BCHECK
1325 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1327 if (0 == s1->do_bounds_check)
1328 return;
1329 section_ptr_add(bounds_section, sizeof(addr_t));
1331 #endif
1333 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1334 a dynamic symbol to allow so's to have one each with a different value. */
1335 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1337 int c = find_elf_sym(s1->symtab, name);
1338 if (c) {
1339 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1340 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1341 esym->st_value = offset;
1342 esym->st_shndx = s->sh_num;
1346 /* avoid generating debug/test_coverage code for stub functions */
1347 static void tcc_compile_string_no_debug(TCCState *s, const char *str)
1349 int save_do_debug = s->do_debug;
1350 int save_test_coverage = s->test_coverage;
1352 s->do_debug = 0;
1353 s->test_coverage = 0;
1354 tcc_compile_string(s, str);
1355 s->do_debug = save_do_debug;
1356 s->test_coverage = save_test_coverage;
1359 #ifdef CONFIG_TCC_BACKTRACE
1360 static void put_ptr(TCCState *s1, Section *s, int offs)
1362 int c;
1363 c = set_global_sym(s1, NULL, s, offs);
1364 s = data_section;
1365 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1366 section_ptr_add(s, PTR_SIZE);
1369 ST_FUNC void tcc_add_btstub(TCCState *s1)
1371 Section *s;
1372 int n, o;
1373 CString cstr;
1375 s = data_section;
1376 /* Align to PTR_SIZE */
1377 section_ptr_add(s, -s->data_offset & (PTR_SIZE - 1));
1378 o = s->data_offset;
1379 /* create (part of) a struct rt_context (see tccrun.c) */
1380 if (s1->dwarf) {
1381 put_ptr(s1, dwarf_line_section, 0);
1382 put_ptr(s1, dwarf_line_section, -1);
1383 if (s1->dwarf >= 5)
1384 put_ptr(s1, dwarf_line_str_section, 0);
1385 else
1386 put_ptr(s1, dwarf_str_section, 0);
1388 else
1390 put_ptr(s1, stab_section, 0);
1391 put_ptr(s1, stab_section, -1);
1392 put_ptr(s1, stab_section->link, 0);
1394 *(addr_t *)section_ptr_add(s, PTR_SIZE) = s1->dwarf;
1395 /* skip esym_start/esym_end/elf_str (not loaded) */
1396 section_ptr_add(s, 3 * PTR_SIZE);
1397 /* prog_base : local nameless symbol with offset 0 at SHN_ABS */
1398 put_ptr(s1, NULL, 0);
1399 n = 2 * PTR_SIZE;
1400 #ifdef CONFIG_TCC_BCHECK
1401 if (s1->do_bounds_check) {
1402 put_ptr(s1, bounds_section, 0);
1403 n -= PTR_SIZE;
1405 #endif
1406 section_ptr_add(s, n);
1407 cstr_new(&cstr);
1408 cstr_printf(&cstr,
1409 "extern void __bt_init(),__bt_exit(),__bt_init_dll();"
1410 "static void *__rt_info[];"
1411 "__attribute__((constructor)) static void __bt_init_rt(){");
1412 #ifdef TCC_TARGET_PE
1413 if (s1->output_type == TCC_OUTPUT_DLL)
1414 #ifdef CONFIG_TCC_BCHECK
1415 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1416 #else
1417 cstr_printf(&cstr, "__bt_init_dll(0);");
1418 #endif
1419 #endif
1420 cstr_printf(&cstr, "__bt_init(__rt_info,%d);}",
1421 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1422 /* In case dlcose is called by application */
1423 cstr_printf(&cstr,
1424 "__attribute__((destructor)) static void __bt_exit_rt(){"
1425 "__bt_exit(__rt_info);}");
1426 tcc_compile_string_no_debug(s1, cstr.data);
1427 cstr_free(&cstr);
1428 set_local_sym(s1, &"___rt_info"[!s1->leading_underscore], s, o);
1430 #endif /* def CONFIG_TCC_BACKTRACE */
1432 static void tcc_tcov_add_file(TCCState *s1, const char *filename)
1434 CString cstr;
1435 void *ptr;
1436 char wd[1024];
1438 if (tcov_section == NULL)
1439 return;
1440 section_ptr_add(tcov_section, 1);
1441 write32le (tcov_section->data, tcov_section->data_offset);
1443 cstr_new (&cstr);
1444 if (filename[0] == '/')
1445 cstr_printf (&cstr, "%s.tcov", filename);
1446 else {
1447 getcwd (wd, sizeof(wd));
1448 cstr_printf (&cstr, "%s/%s.tcov", wd, filename);
1450 ptr = section_ptr_add(tcov_section, cstr.size + 1);
1451 strcpy((char *)ptr, cstr.data);
1452 unlink((char *)ptr);
1453 #ifdef _WIN32
1454 normalize_slashes((char *)ptr);
1455 #endif
1456 cstr_free (&cstr);
1458 cstr_new(&cstr);
1459 cstr_printf(&cstr,
1460 "extern char *__tcov_data[];"
1461 "extern void __store_test_coverage ();"
1462 "__attribute__((destructor)) static void __tcov_exit() {"
1463 "__store_test_coverage(__tcov_data);"
1464 "}");
1465 tcc_compile_string_no_debug(s1, cstr.data);
1466 cstr_free(&cstr);
1467 set_local_sym(s1, &"___tcov_data"[!s1->leading_underscore], tcov_section, 0);
1470 #ifndef TCC_TARGET_PE
1471 /* add tcc runtime libraries */
1472 ST_FUNC void tcc_add_runtime(TCCState *s1)
1474 s1->filetype = 0;
1475 #ifdef CONFIG_TCC_BCHECK
1476 tcc_add_bcheck(s1);
1477 #endif
1478 tcc_add_pragma_libs(s1);
1479 /* add libc */
1480 if (!s1->nostdlib) {
1481 if (s1->option_pthread)
1482 tcc_add_library_err(s1, "pthread");
1483 tcc_add_library_err(s1, "c");
1484 #ifdef TCC_LIBGCC
1485 if (!s1->static_link) {
1486 if (TCC_LIBGCC[0] == '/')
1487 tcc_add_file(s1, TCC_LIBGCC);
1488 else
1489 tcc_add_dll(s1, TCC_LIBGCC, 0);
1491 #endif
1492 #if TCC_TARGET_ARM && TARGETOS_FreeBSD
1493 tcc_add_library_err(s1, "gcc_s"); // unwind code
1494 #endif
1495 #ifdef CONFIG_TCC_BCHECK
1496 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1497 tcc_add_library_err(s1, "pthread");
1498 #if !TARGETOS_OpenBSD && !TARGETOS_NetBSD
1499 tcc_add_library_err(s1, "dl");
1500 #endif
1501 tcc_add_support(s1, "bcheck.o");
1502 if (s1->static_link)
1503 tcc_add_library_err(s1, "c");
1505 #endif
1506 #ifdef CONFIG_TCC_BACKTRACE
1507 if (s1->do_backtrace) {
1508 if (s1->output_type == TCC_OUTPUT_EXE)
1509 tcc_add_support(s1, "bt-exe.o");
1510 if (s1->output_type != TCC_OUTPUT_DLL)
1511 tcc_add_support(s1, "bt-log.o");
1512 if (s1->output_type != TCC_OUTPUT_MEMORY)
1513 tcc_add_btstub(s1);
1515 #endif
1516 if (TCC_LIBTCC1[0])
1517 tcc_add_support(s1, TCC_LIBTCC1);
1519 #if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO
1520 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
1521 /* add crt end if not memory output */
1522 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1523 if (s1->output_type == TCC_OUTPUT_DLL)
1524 tcc_add_crt(s1, "crtendS.o");
1525 else
1526 tcc_add_crt(s1, "crtend.o");
1527 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
1528 tcc_add_crt(s1, "crtn.o");
1529 #endif
1531 #elif !defined(TCC_TARGET_MACHO)
1532 /* add crt end if not memory output */
1533 if (s1->output_type != TCC_OUTPUT_MEMORY)
1534 tcc_add_crt(s1, "crtn.o");
1535 #endif
1536 #endif
1539 #endif /* ndef TCC_TARGET_PE */
1541 /* add various standard linker symbols (must be done after the
1542 sections are filled (for example after allocating common
1543 symbols)) */
1544 static void tcc_add_linker_symbols(TCCState *s1)
1546 char buf[1024];
1547 int i;
1548 Section *s;
1550 set_global_sym(s1, "_etext", text_section, -1);
1551 set_global_sym(s1, "_edata", data_section, -1);
1552 set_global_sym(s1, "_end", bss_section, -1);
1553 #if TARGETOS_OpenBSD
1554 set_global_sym(s1, "__executable_start", NULL, ELF_START_ADDR);
1555 #endif
1556 #ifdef TCC_TARGET_RISCV64
1557 /* XXX should be .sdata+0x800, not .data+0x800 */
1558 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1559 #endif
1560 /* horrible new standard ldscript defines */
1561 #ifndef TCC_TARGET_PE
1562 add_init_array_defines(s1, ".preinit_array");
1563 #endif
1564 add_init_array_defines(s1, ".init_array");
1565 add_init_array_defines(s1, ".fini_array");
1566 /* add start and stop symbols for sections whose name can be
1567 expressed in C */
1568 for(i = 1; i < s1->nb_sections; i++) {
1569 s = s1->sections[i];
1570 if ((s->sh_flags & SHF_ALLOC)
1571 && (s->sh_type == SHT_PROGBITS
1572 || s->sh_type == SHT_STRTAB)) {
1573 const char *p;
1574 /* check if section name can be expressed in C */
1575 p = s->name;
1576 for(;;) {
1577 int c = *p;
1578 if (!c)
1579 break;
1580 if (!isid(c) && !isnum(c))
1581 goto next_sec;
1582 p++;
1584 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1585 set_global_sym(s1, buf, s, 0);
1586 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1587 set_global_sym(s1, buf, s, -1);
1589 next_sec: ;
1593 ST_FUNC void resolve_common_syms(TCCState *s1)
1595 ElfW(Sym) *sym;
1597 /* Allocate common symbols in BSS. */
1598 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1599 if (sym->st_shndx == SHN_COMMON) {
1600 /* symbol alignment is in st_value for SHN_COMMONs */
1601 sym->st_value = section_add(bss_section, sym->st_size,
1602 sym->st_value);
1603 sym->st_shndx = bss_section->sh_num;
1607 /* Now assign linker provided symbols their value. */
1608 tcc_add_linker_symbols(s1);
1611 #ifndef ELF_OBJ_ONLY
1612 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1614 int sym_index = ELFW(R_SYM) (rel->r_info);
1615 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1616 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1617 unsigned offset = attr->got_offset;
1619 if (0 == offset)
1620 return;
1621 section_reserve(s1->got, offset + PTR_SIZE);
1622 #if PTR_SIZE == 8
1623 write64le(s1->got->data + offset, sym->st_value);
1624 #else
1625 write32le(s1->got->data + offset, sym->st_value);
1626 #endif
1629 /* Perform relocation to GOT or PLT entries */
1630 ST_FUNC void fill_got(TCCState *s1)
1632 Section *s;
1633 ElfW_Rel *rel;
1634 int i;
1636 for(i = 1; i < s1->nb_sections; i++) {
1637 s = s1->sections[i];
1638 if (s->sh_type != SHT_RELX)
1639 continue;
1640 /* no need to handle got relocations */
1641 if (s->link != symtab_section)
1642 continue;
1643 for_each_elem(s, 0, rel, ElfW_Rel) {
1644 switch (ELFW(R_TYPE) (rel->r_info)) {
1645 case R_X86_64_GOT32:
1646 case R_X86_64_GOTPCREL:
1647 case R_X86_64_GOTPCRELX:
1648 case R_X86_64_REX_GOTPCRELX:
1649 case R_X86_64_PLT32:
1650 fill_got_entry(s1, rel);
1651 break;
1657 /* See put_got_entry for a description. This is the second stage
1658 where GOT references to local defined symbols are rewritten. */
1659 static void fill_local_got_entries(TCCState *s1)
1661 ElfW_Rel *rel;
1662 if (!s1->got->reloc)
1663 return;
1664 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1665 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1666 int sym_index = ELFW(R_SYM) (rel->r_info);
1667 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1668 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1669 unsigned offset = attr->got_offset;
1670 if (offset != rel->r_offset - s1->got->sh_addr)
1671 tcc_error_noabort("huh");
1672 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1673 #if SHT_RELX == SHT_RELA
1674 rel->r_addend = sym->st_value;
1675 #else
1676 /* All our REL architectures also happen to be 32bit LE. */
1677 write32le(s1->got->data + offset, sym->st_value);
1678 #endif
1683 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1684 in shared libraries and export non local defined symbols to shared libraries
1685 if -rdynamic switch was given on command line */
1686 static void bind_exe_dynsyms(TCCState *s1)
1688 const char *name;
1689 int sym_index, index;
1690 ElfW(Sym) *sym, *esym;
1691 int type;
1693 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1694 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1695 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1696 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1697 if (sym->st_shndx == SHN_UNDEF) {
1698 name = (char *) symtab_section->link->data + sym->st_name;
1699 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1700 if (sym_index) {
1701 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1702 type = ELFW(ST_TYPE)(esym->st_info);
1703 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1704 /* Indirect functions shall have STT_FUNC type in executable
1705 * dynsym section. Indeed, a dlsym call following a lazy
1706 * resolution would pick the symbol value from the
1707 * executable dynsym entry which would contain the address
1708 * of the function wanted by the caller of dlsym instead of
1709 * the address of the function that would return that
1710 * address */
1711 int dynindex
1712 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1713 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1714 name);
1715 int index = sym - (ElfW(Sym) *) symtab_section->data;
1716 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1717 } else if (type == STT_OBJECT) {
1718 unsigned long offset;
1719 ElfW(Sym) *dynsym;
1720 offset = bss_section->data_offset;
1721 /* XXX: which alignment ? */
1722 offset = (offset + 16 - 1) & -16;
1723 set_elf_sym (s1->symtab, offset, esym->st_size,
1724 esym->st_info, 0, bss_section->sh_num, name);
1725 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1726 esym->st_info, 0, bss_section->sh_num,
1727 name);
1729 /* Ensure R_COPY works for weak symbol aliases */
1730 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1731 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1732 if ((dynsym->st_value == esym->st_value)
1733 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1734 char *dynname = (char *) s1->dynsymtab_section->link->data
1735 + dynsym->st_name;
1736 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1737 dynsym->st_info, 0,
1738 bss_section->sh_num, dynname);
1739 break;
1744 put_elf_reloc(s1->dynsym, bss_section,
1745 offset, R_COPY, index);
1746 offset += esym->st_size;
1747 bss_section->data_offset = offset;
1749 } else {
1750 /* STB_WEAK undefined symbols are accepted */
1751 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1752 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1753 !strcmp(name, "_fp_hw")) {
1754 } else {
1755 tcc_error_noabort("undefined symbol '%s'", name);
1758 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1759 /* if -rdynamic option, then export all non local symbols */
1760 name = (char *) symtab_section->link->data + sym->st_name;
1761 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1762 0, sym->st_shndx, name);
1767 /* Bind symbols of libraries: export all non local symbols of executable that
1768 are referenced by shared libraries. The reason is that the dynamic loader
1769 search symbol first in executable and then in libraries. Therefore a
1770 reference to a symbol already defined by a library can still be resolved by
1771 a symbol in the executable. */
1772 static void bind_libs_dynsyms(TCCState *s1)
1774 const char *name;
1775 int sym_index;
1776 ElfW(Sym) *sym, *esym;
1778 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1779 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1780 sym_index = find_elf_sym(symtab_section, name);
1781 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1782 if (sym_index && sym->st_shndx != SHN_UNDEF
1783 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1784 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1785 sym->st_info, 0, sym->st_shndx, name);
1786 } else if (esym->st_shndx == SHN_UNDEF) {
1787 /* weak symbols can stay undefined */
1788 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1789 tcc_warning("undefined dynamic symbol '%s'", name);
1794 /* Export all non local symbols. This is used by shared libraries so that the
1795 non local symbols they define can resolve a reference in another shared
1796 library or in the executable. Correspondingly, it allows undefined local
1797 symbols to be resolved by other shared libraries or by the executable. */
1798 static void export_global_syms(TCCState *s1)
1800 int dynindex, index;
1801 const char *name;
1802 ElfW(Sym) *sym;
1804 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1805 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1806 name = (char *) symtab_section->link->data + sym->st_name;
1807 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1808 sym->st_info, 0, sym->st_shndx, name);
1809 index = sym - (ElfW(Sym) *) symtab_section->data;
1810 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1815 /* decide if an unallocated section should be output. */
1816 static int set_sec_sizes(TCCState *s1)
1818 int i;
1819 Section *s;
1820 int textrel = 0;
1821 int file_type = s1->output_type;
1823 /* Allocate strings for section names */
1824 for(i = 1; i < s1->nb_sections; i++) {
1825 s = s1->sections[i];
1826 if (s->sh_type == SHT_RELX && !(s->sh_flags & SHF_ALLOC)) {
1827 /* when generating a DLL, we include relocations but
1828 we may patch them */
1829 if (file_type == TCC_OUTPUT_DLL
1830 && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) {
1831 int count = prepare_dynamic_rel(s1, s);
1832 if (count) {
1833 /* allocate the section */
1834 s->sh_flags |= SHF_ALLOC;
1835 s->sh_size = count * sizeof(ElfW_Rel);
1836 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1837 textrel = 1;
1840 } else if ((s->sh_flags & SHF_ALLOC)
1841 #ifdef TCC_TARGET_ARM
1842 || s->sh_type == SHT_ARM_ATTRIBUTES
1843 #endif
1844 || s1->do_debug) {
1845 s->sh_size = s->data_offset;
1848 #ifdef TCC_TARGET_ARM
1849 /* XXX: Suppress stack unwinding section. */
1850 if (s->sh_type == SHT_ARM_EXIDX) {
1851 s->sh_flags = 0;
1852 s->sh_size = 0;
1854 #endif
1857 return textrel;
1861 /* Info to be copied in dynamic section */
1862 struct dyn_inf {
1863 Section *dynamic;
1864 Section *dynstr;
1865 unsigned long data_offset;
1866 addr_t rel_addr;
1867 addr_t rel_size;
1870 /* Info for GNU_RELRO */
1871 struct ro_inf {
1872 addr_t sh_offset;
1873 addr_t sh_addr;
1874 addr_t sh_size;
1877 static void alloc_sec_names(
1878 TCCState *s1, int is_obj
1881 static int layout_any_sections(
1882 TCCState *s1, int file_offset, int *sec_order, int is_obj
1885 /* Assign sections to segments and decide how are sections laid out when loaded
1886 in memory. This function also fills corresponding program headers. */
1887 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr,
1888 int phnum, int phfill,
1889 Section *interp,
1890 struct ro_inf *roinf, int *sec_order)
1892 int i, file_offset;
1893 Section *s;
1895 file_offset = 0;
1896 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1897 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1900 unsigned long s_align;
1901 long long tmp;
1902 addr_t addr;
1903 ElfW(Phdr) *ph;
1904 int j, k, f, file_type = s1->output_type;
1906 s_align = ELF_PAGE_SIZE;
1907 if (s1->section_align)
1908 s_align = s1->section_align;
1910 if (s1->has_text_addr) {
1911 int a_offset, p_offset;
1912 addr = s1->text_addr;
1913 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1914 ELF_PAGE_SIZE */
1915 a_offset = (int) (addr & (s_align - 1));
1916 p_offset = file_offset & (s_align - 1);
1917 if (a_offset < p_offset)
1918 a_offset += s_align;
1919 file_offset += (a_offset - p_offset);
1920 } else {
1921 if (file_type == TCC_OUTPUT_DLL)
1922 addr = 0;
1923 else
1924 addr = ELF_START_ADDR;
1925 /* compute address after headers */
1926 addr += (file_offset & (s_align - 1));
1929 ph = &phdr[0];
1930 /* Leave one program headers for the program interpreter and one for
1931 the program header table itself if needed. These are done later as
1932 they require section layout to be done first. */
1933 if (interp)
1934 ph += 2;
1936 /* read only segment mapping for GNU_RELRO */
1937 roinf->sh_offset = roinf->sh_addr = roinf->sh_size = 0;
1939 for(j = 0; j < phfill; j++) {
1940 ph->p_type = j == 2 ? PT_TLS : PT_LOAD;
1941 if (j == 0)
1942 ph->p_flags = PF_R | PF_X;
1943 else
1944 ph->p_flags = PF_R | PF_W;
1945 ph->p_align = j == 2 ? 4 : s_align;
1947 /* Decide the layout of sections loaded in memory. This must
1948 be done before program headers are filled since they contain
1949 info about the layout. We do the following ordering: interp,
1950 symbol tables, relocations, progbits, nobits */
1951 /* XXX: do faster and simpler sorting */
1952 f = -1;
1953 for(k = 0; k < 7; k++) {
1954 for(i = 1; i < s1->nb_sections; i++) {
1955 s = s1->sections[i];
1956 /* compute if section should be included */
1957 if (j == 0) {
1958 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1959 SHF_ALLOC)
1960 continue;
1961 } else if (j == 1) {
1962 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1963 (SHF_ALLOC | SHF_WRITE))
1964 continue;
1965 } else {
1966 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1967 (SHF_ALLOC | SHF_WRITE | SHF_TLS))
1968 continue;
1970 if (s == interp) {
1971 if (k != 0)
1972 continue;
1973 } else if ((s->sh_type == SHT_DYNSYM ||
1974 s->sh_type == SHT_STRTAB ||
1975 s->sh_type == SHT_HASH)
1976 && !strstr(s->name, ".stab")) {
1977 if (k != 1)
1978 continue;
1979 } else if (s->sh_type == SHT_RELX) {
1980 if (s1->plt && s == s1->plt->reloc) {
1981 if (k != 3)
1982 continue;
1983 } else {
1984 if (k != 2)
1985 continue;
1987 } else if (s->sh_type == SHT_NOBITS) {
1988 if (k != 6)
1989 continue;
1990 } else if ((s == rodata_section
1991 #ifdef CONFIG_TCC_BCHECK
1992 || s == bounds_section
1993 || s == lbounds_section
1994 #endif
1995 ) && (s->sh_flags & SHF_WRITE)) {
1996 if (k != 4)
1997 continue;
1998 /* Align next section on page size.
1999 This is needed to remap roinf section ro. */
2000 f = 1;
2001 } else {
2002 if (k != 5)
2003 continue;
2005 *sec_order++ = i;
2007 /* section matches: we align it and add its size */
2008 tmp = addr;
2009 if (f-- == 0)
2010 s->sh_addralign = PAGESIZE;
2011 addr = (addr + s->sh_addralign - 1) &
2012 ~(s->sh_addralign - 1);
2013 file_offset += (int) ( addr - tmp );
2014 s->sh_offset = file_offset;
2015 s->sh_addr = addr;
2017 /* update program header infos */
2018 if (ph->p_offset == 0) {
2019 ph->p_offset = file_offset;
2020 ph->p_vaddr = addr;
2021 ph->p_paddr = ph->p_vaddr;
2024 if (k == 4) {
2025 if (roinf->sh_size == 0) {
2026 roinf->sh_offset = s->sh_offset;
2027 roinf->sh_addr = s->sh_addr;
2029 roinf->sh_size = (addr - roinf->sh_addr) + s->sh_size;
2032 addr += s->sh_size;
2033 if (s->sh_type != SHT_NOBITS)
2034 file_offset += s->sh_size;
2037 if (j == 0) {
2038 /* Make the first PT_LOAD segment include the program
2039 headers itself (and the ELF header as well), it'll
2040 come out with same memory use but will make various
2041 tools like binutils strip work better. */
2042 ph->p_offset &= ~(ph->p_align - 1);
2043 ph->p_vaddr &= ~(ph->p_align - 1);
2044 ph->p_paddr &= ~(ph->p_align - 1);
2046 ph->p_filesz = file_offset - ph->p_offset;
2047 ph->p_memsz = addr - ph->p_vaddr;
2048 ph++;
2049 if (j == 0) {
2050 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
2051 /* if in the middle of a page, we duplicate the page in
2052 memory so that one copy is RX and the other is RW */
2053 if ((addr & (s_align - 1)) != 0)
2054 addr += s_align;
2055 } else {
2056 addr = (addr + s_align - 1) & ~(s_align - 1);
2057 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
2063 /* all other sections come after */
2064 return layout_any_sections(s1, file_offset, sec_order, 0);
2067 /* put dynamic tag */
2068 static void put_dt(Section *dynamic, int dt, addr_t val)
2070 ElfW(Dyn) *dyn;
2071 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
2072 dyn->d_tag = dt;
2073 dyn->d_un.d_val = val;
2076 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
2077 Section *dynamic, Section *note, struct ro_inf *roinf)
2079 ElfW(Phdr) *ph;
2081 /* if interpreter, then add corresponding program header */
2082 if (interp) {
2083 ph = &phdr[0];
2085 ph->p_type = PT_PHDR;
2086 ph->p_offset = sizeof(ElfW(Ehdr));
2087 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
2088 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
2089 ph->p_paddr = ph->p_vaddr;
2090 ph->p_flags = PF_R | PF_X;
2091 ph->p_align = 4; /* interp->sh_addralign; */
2092 ph++;
2094 ph->p_type = PT_INTERP;
2095 ph->p_offset = interp->sh_offset;
2096 ph->p_vaddr = interp->sh_addr;
2097 ph->p_paddr = ph->p_vaddr;
2098 ph->p_filesz = interp->sh_size;
2099 ph->p_memsz = interp->sh_size;
2100 ph->p_flags = PF_R;
2101 ph->p_align = interp->sh_addralign;
2104 if (note) {
2105 ph = &phdr[phnum - 2 - (roinf != NULL)];
2107 ph->p_type = PT_NOTE;
2108 ph->p_offset = note->sh_offset;
2109 ph->p_vaddr = note->sh_addr;
2110 ph->p_paddr = ph->p_vaddr;
2111 ph->p_filesz = note->sh_size;
2112 ph->p_memsz = note->sh_size;
2113 ph->p_flags = PF_R;
2114 ph->p_align = note->sh_addralign;
2117 /* if dynamic section, then add corresponding program header */
2118 if (dynamic) {
2119 ph = &phdr[phnum - 1 - (roinf != NULL)];
2121 ph->p_type = PT_DYNAMIC;
2122 ph->p_offset = dynamic->sh_offset;
2123 ph->p_vaddr = dynamic->sh_addr;
2124 ph->p_paddr = ph->p_vaddr;
2125 ph->p_filesz = dynamic->sh_size;
2126 ph->p_memsz = dynamic->sh_size;
2127 ph->p_flags = PF_R | PF_W;
2128 ph->p_align = dynamic->sh_addralign;
2131 if (roinf) {
2132 ph = &phdr[phnum - 1];
2134 ph->p_type = PT_GNU_RELRO;
2135 ph->p_offset = roinf->sh_offset;
2136 ph->p_vaddr = roinf->sh_addr;
2137 ph->p_paddr = ph->p_vaddr;
2138 ph->p_filesz = roinf->sh_size;
2139 ph->p_memsz = roinf->sh_size;
2140 ph->p_flags = PF_R;
2141 ph->p_align = 1;
2145 /* Fill the dynamic section with tags describing the address and size of
2146 sections */
2147 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2149 Section *dynamic = dyninf->dynamic;
2150 Section *s;
2152 /* put dynamic section entries */
2153 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2154 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2155 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2156 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2157 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2158 #if PTR_SIZE == 8
2159 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2160 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2161 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2162 if (s1->plt && s1->plt->reloc) {
2163 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2164 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2165 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2166 put_dt(dynamic, DT_PLTREL, DT_RELA);
2168 put_dt(dynamic, DT_RELACOUNT, 0);
2169 #else
2170 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2171 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2172 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2173 if (s1->plt && s1->plt->reloc) {
2174 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2175 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2176 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2177 put_dt(dynamic, DT_PLTREL, DT_REL);
2179 put_dt(dynamic, DT_RELCOUNT, 0);
2180 #endif
2181 if (versym_section && verneed_section) {
2182 /* The dynamic linker can not handle VERSYM without VERNEED */
2183 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2184 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2185 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2187 s = find_section_create (s1, ".preinit_array", 0);
2188 if (s && s->data_offset) {
2189 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2190 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2192 s = find_section_create (s1, ".init_array", 0);
2193 if (s && s->data_offset) {
2194 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2195 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2197 s = find_section_create (s1, ".fini_array", 0);
2198 if (s && s->data_offset) {
2199 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2200 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2202 s = find_section_create (s1, ".init", 0);
2203 if (s && s->data_offset) {
2204 put_dt(dynamic, DT_INIT, s->sh_addr);
2206 s = find_section_create (s1, ".fini", 0);
2207 if (s && s->data_offset) {
2208 put_dt(dynamic, DT_FINI, s->sh_addr);
2210 if (s1->do_debug)
2211 put_dt(dynamic, DT_DEBUG, 0);
2212 put_dt(dynamic, DT_NULL, 0);
2215 /* Remove gaps between RELX sections.
2216 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2217 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2218 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2219 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2220 static void update_reloc_sections(TCCState *s1, struct dyn_inf *dyninf)
2222 int i;
2223 unsigned long file_offset = 0;
2224 Section *s;
2225 Section *relocplt = s1->plt ? s1->plt->reloc : NULL;
2227 /* dynamic relocation table information, for .dynamic section */
2228 dyninf->rel_addr = dyninf->rel_size = 0;
2230 for(i = 1; i < s1->nb_sections; i++) {
2231 s = s1->sections[i];
2232 if (s->sh_type == SHT_RELX && s != relocplt) {
2233 if (dyninf->rel_size == 0) {
2234 dyninf->rel_addr = s->sh_addr;
2235 file_offset = s->sh_offset;
2237 else {
2238 s->sh_addr = dyninf->rel_addr + dyninf->rel_size;
2239 s->sh_offset = file_offset + dyninf->rel_size;
2241 dyninf->rel_size += s->sh_size;
2246 #endif /* ndef ELF_OBJ_ONLY */
2248 /* Create an ELF file on disk.
2249 This function handle ELF specific layout requirements */
2250 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2251 int file_offset, int *sec_order)
2253 int i, shnum, offset, size, file_type;
2254 Section *s;
2255 ElfW(Ehdr) ehdr;
2256 ElfW(Shdr) shdr, *sh;
2258 file_type = s1->output_type;
2259 shnum = s1->nb_sections;
2261 memset(&ehdr, 0, sizeof(ehdr));
2263 if (phnum > 0) {
2264 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2265 ehdr.e_phnum = phnum;
2266 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2269 /* align to 4 */
2270 file_offset = (file_offset + 3) & -4;
2272 /* fill header */
2273 ehdr.e_ident[0] = ELFMAG0;
2274 ehdr.e_ident[1] = ELFMAG1;
2275 ehdr.e_ident[2] = ELFMAG2;
2276 ehdr.e_ident[3] = ELFMAG3;
2277 ehdr.e_ident[4] = ELFCLASSW;
2278 ehdr.e_ident[5] = ELFDATA2LSB;
2279 ehdr.e_ident[6] = EV_CURRENT;
2280 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2281 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2282 #endif
2283 #ifdef TCC_TARGET_ARM
2284 #ifdef TCC_ARM_EABI
2285 ehdr.e_ident[EI_OSABI] = 0;
2286 ehdr.e_flags = EF_ARM_EABI_VER4;
2287 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2288 ehdr.e_flags |= EF_ARM_HASENTRY;
2289 if (s1->float_abi == ARM_HARD_FLOAT)
2290 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2291 else
2292 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2293 #else
2294 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2295 #endif
2296 #elif defined TCC_TARGET_RISCV64
2297 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2298 #endif
2299 switch(file_type) {
2300 default:
2301 case TCC_OUTPUT_EXE:
2302 ehdr.e_type = ET_EXEC;
2303 ehdr.e_entry = get_sym_addr(s1,
2304 s1->elf_entryname ?
2305 s1->elf_entryname : "_start",
2306 1, 0);
2307 break;
2308 case TCC_OUTPUT_DLL:
2309 ehdr.e_type = ET_DYN;
2310 ehdr.e_entry = s1->elf_entryname ?
2311 get_sym_addr(s1,s1->elf_entryname,1,0) :
2312 text_section->sh_addr;
2313 /* XXX: is it correct ? */
2314 break;
2315 case TCC_OUTPUT_OBJ:
2316 ehdr.e_type = ET_REL;
2317 break;
2319 ehdr.e_machine = EM_TCC_TARGET;
2320 ehdr.e_version = EV_CURRENT;
2321 ehdr.e_shoff = file_offset;
2322 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2323 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2324 ehdr.e_shnum = shnum;
2325 ehdr.e_shstrndx = shnum - 1;
2327 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2328 if (phdr)
2329 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2330 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2332 sort_syms(s1, symtab_section);
2333 for(i = 1; i < s1->nb_sections; i++) {
2334 s = s1->sections[sec_order[i]];
2335 if (s->sh_type != SHT_NOBITS) {
2336 while (offset < s->sh_offset) {
2337 fputc(0, f);
2338 offset++;
2340 size = s->sh_size;
2341 if (size)
2342 fwrite(s->data, 1, size, f);
2343 offset += size;
2347 /* output section headers */
2348 while (offset < ehdr.e_shoff) {
2349 fputc(0, f);
2350 offset++;
2353 for(i = 0; i < s1->nb_sections; i++) {
2354 sh = &shdr;
2355 memset(sh, 0, sizeof(ElfW(Shdr)));
2356 s = s1->sections[i];
2357 if (s) {
2358 sh->sh_name = s->sh_name;
2359 sh->sh_type = s->sh_type;
2360 sh->sh_flags = s->sh_flags;
2361 sh->sh_entsize = s->sh_entsize;
2362 sh->sh_info = s->sh_info;
2363 if (s->link)
2364 sh->sh_link = s->link->sh_num;
2365 sh->sh_addralign = s->sh_addralign;
2366 sh->sh_addr = s->sh_addr;
2367 sh->sh_offset = s->sh_offset;
2368 sh->sh_size = s->sh_size;
2370 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2374 static void tcc_output_binary(TCCState *s1, FILE *f,
2375 const int *sec_order)
2377 Section *s;
2378 int i, offset, size;
2380 offset = 0;
2381 for(i=1;i<s1->nb_sections;i++) {
2382 s = s1->sections[sec_order[i]];
2383 if (s->sh_type != SHT_NOBITS &&
2384 (s->sh_flags & SHF_ALLOC)) {
2385 while (offset < s->sh_offset) {
2386 fputc(0, f);
2387 offset++;
2389 size = s->sh_size;
2390 fwrite(s->data, 1, size, f);
2391 offset += size;
2396 /* Write an elf, coff or "binary" file */
2397 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2398 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2400 int fd, mode, file_type;
2401 FILE *f;
2403 file_type = s1->output_type;
2404 if (file_type == TCC_OUTPUT_OBJ)
2405 mode = 0666;
2406 else
2407 mode = 0777;
2408 unlink(filename);
2409 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2410 if (fd < 0 || (f = fdopen(fd, "wb")) == NULL) {
2411 tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno));
2412 return -1;
2414 if (s1->verbose)
2415 printf("<- %s\n", filename);
2417 #ifdef TCC_TARGET_COFF
2418 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2419 tcc_output_coff(s1, f);
2420 else
2421 #endif
2422 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2423 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2424 else
2425 tcc_output_binary(s1, f, sec_order);
2426 fclose(f);
2428 return 0;
2431 #ifndef ELF_OBJ_ONLY
2432 /* Sort section headers by assigned sh_addr, remove sections
2433 that we aren't going to output. */
2434 static void tidy_section_headers(TCCState *s1, int *sec_order)
2436 int i, nnew, l, *backmap;
2437 Section **snew, *s;
2438 ElfW(Sym) *sym;
2440 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2441 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2442 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2443 s = s1->sections[sec_order[i]];
2444 if (!i || s->sh_name) {
2445 backmap[sec_order[i]] = nnew;
2446 snew[nnew] = s;
2447 ++nnew;
2448 } else {
2449 backmap[sec_order[i]] = 0;
2450 snew[--l] = s;
2453 for (i = 0; i < nnew; i++) {
2454 s = snew[i];
2455 if (s) {
2456 s->sh_num = i;
2457 if (s->sh_type == SHT_RELX)
2458 s->sh_info = backmap[s->sh_info];
2462 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2463 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2464 sym->st_shndx = backmap[sym->st_shndx];
2465 if ( !s1->static_link ) {
2466 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2467 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2468 sym->st_shndx = backmap[sym->st_shndx];
2470 for (i = 0; i < s1->nb_sections; i++)
2471 sec_order[i] = i;
2472 tcc_free(s1->sections);
2473 s1->sections = snew;
2474 s1->nb_sections = nnew;
2475 tcc_free(backmap);
2478 #ifdef TCC_TARGET_ARM
2479 static void create_arm_attribute_section(TCCState *s1)
2481 // Needed for DLL support.
2482 static const unsigned char arm_attr[] = {
2483 0x41, // 'A'
2484 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2485 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2486 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2487 0x05, 0x36, 0x00, // 'CPU_name', "6"
2488 0x06, 0x06, // 'CPU_arch', 'v6'
2489 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2490 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2491 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2492 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2493 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2494 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2495 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2496 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2497 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2498 0x1a, 0x02, // 'ABI_enum_size', 'int'
2499 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2500 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2502 Section *attr = new_section(s1, ".ARM.attributes", SHT_ARM_ATTRIBUTES, 0);
2503 unsigned char *ptr = section_ptr_add(attr, sizeof(arm_attr));
2504 attr->sh_addralign = 1;
2505 memcpy(ptr, arm_attr, sizeof(arm_attr));
2506 if (s1->float_abi != ARM_HARD_FLOAT) {
2507 ptr[26] = 0x00; // 'FP_arch', 'No'
2508 ptr[41] = 0x1e; // 'ABI_optimization_goals'
2509 ptr[42] = 0x06; // 'Aggressive Debug'
2512 #endif
2514 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2515 static Section *create_bsd_note_section(TCCState *s1,
2516 const char *name,
2517 const char *value)
2519 Section *s = find_section (s1, name);
2521 if (s->data_offset == 0) {
2522 char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
2523 ElfW(Nhdr) *note = (ElfW(Nhdr) *) ptr;
2525 s->sh_type = SHT_NOTE;
2526 note->n_namesz = 8;
2527 note->n_descsz = 4;
2528 note->n_type = ELF_NOTE_OS_GNU;
2529 strcpy (ptr + sizeof(ElfW(Nhdr)), value);
2531 return s;
2533 #endif
2535 static void elf_patch_global_offset_size(TCCState *s1, Section *s)
2537 int sym_index;
2539 if (s && (sym_index = find_elf_sym(s, "_GLOBAL_OFFSET_TABLE_")))
2540 ((ElfW(Sym) *)s->data)[sym_index].st_size = s1->got->data_offset;
2543 /* Output an elf, coff or binary file */
2544 /* XXX: suppress unneeded sections */
2545 static int elf_output_file(TCCState *s1, const char *filename)
2547 int i, ret, phnum, phfill, shnum, file_type, file_offset, *sec_order;
2548 struct dyn_inf dyninf = {0};
2549 struct ro_inf roinf;
2550 ElfW(Phdr) *phdr;
2551 Section *interp, *dynamic, *dynstr, *note;
2552 struct ro_inf *roinf_use = NULL;
2553 int textrel;
2555 file_type = s1->output_type;
2556 s1->nb_errors = 0;
2557 ret = -1;
2558 phdr = NULL;
2559 sec_order = NULL;
2560 interp = dynamic = dynstr = note = NULL;
2562 #ifdef TCC_TARGET_ARM
2563 create_arm_attribute_section (s1);
2564 #endif
2566 #if TARGETOS_OpenBSD
2567 note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
2568 #endif
2570 #if TARGETOS_NetBSD
2571 note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD");
2572 #endif
2575 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2576 tcc_add_runtime(s1);
2577 resolve_common_syms(s1);
2579 if (!s1->static_link) {
2580 if (file_type == TCC_OUTPUT_EXE) {
2581 char *ptr;
2582 /* allow override the dynamic loader */
2583 const char *elfint = getenv("LD_SO");
2584 if (elfint == NULL)
2585 elfint = DEFAULT_ELFINTERP(s1);
2586 /* add interpreter section only if executable */
2587 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2588 interp->sh_addralign = 1;
2589 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2590 strcpy(ptr, elfint);
2593 /* add dynamic symbol table */
2594 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2595 ".dynstr",
2596 ".hash", SHF_ALLOC);
2597 /* Number of local symbols (readelf complains if not set) */
2598 s1->dynsym->sh_info = 1;
2599 dynstr = s1->dynsym->link;
2600 /* add dynamic section */
2601 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2602 SHF_ALLOC | SHF_WRITE);
2603 dynamic->link = dynstr;
2604 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2606 if (!s1->got)
2607 build_got(s1);
2609 if (file_type == TCC_OUTPUT_EXE) {
2610 bind_exe_dynsyms(s1);
2611 if (s1->nb_errors)
2612 goto the_end;
2613 bind_libs_dynsyms(s1);
2614 } else {
2615 /* shared library case: simply export all global symbols */
2616 export_global_syms(s1);
2619 build_got_entries(s1);
2620 elf_patch_global_offset_size(s1, symtab_section);
2621 elf_patch_global_offset_size(s1, s1->dynsym);
2622 version_add (s1);
2625 textrel = set_sec_sizes(s1);
2626 alloc_sec_names(s1, 0);
2628 if (!s1->static_link) {
2629 int i;
2630 /* add a list of needed dlls */
2631 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2632 DLLReference *dllref = s1->loaded_dlls[i];
2633 if (dllref->level == 0)
2634 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2637 if (s1->rpath)
2638 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2639 put_elf_str(dynstr, s1->rpath));
2641 if (file_type == TCC_OUTPUT_DLL) {
2642 if (s1->soname)
2643 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2644 /* XXX: currently, since we do not handle PIC code, we
2645 must relocate the readonly segments */
2646 if (textrel)
2647 put_dt(dynamic, DT_TEXTREL, 0);
2650 if (s1->symbolic)
2651 put_dt(dynamic, DT_SYMBOLIC, 0);
2653 dyninf.dynamic = dynamic;
2654 dyninf.dynstr = dynstr;
2655 /* remember offset and reserve space for 2nd call below */
2656 dyninf.data_offset = dynamic->data_offset;
2657 fill_dynamic(s1, &dyninf);
2658 dynamic->sh_size = dynamic->data_offset;
2659 dynstr->sh_size = dynstr->data_offset;
2662 for (i = 1; i < s1->nb_sections &&
2663 !(s1->sections[i]->sh_flags & SHF_TLS); i++);
2664 phfill = 2 + (i < s1->nb_sections);
2666 /* compute number of program headers */
2667 if (file_type == TCC_OUTPUT_DLL)
2668 phnum = 3;
2669 else if (s1->static_link)
2670 phnum = 3;
2671 else {
2672 phnum = 5 + (i < s1->nb_sections);
2675 phnum += note != NULL;
2676 #if !TARGETOS_FreeBSD && !TARGETOS_NetBSD
2677 /* GNU_RELRO */
2678 phnum++, roinf_use = &roinf;
2679 #endif
2681 /* allocate program segment headers */
2682 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2683 /* compute number of sections */
2684 shnum = s1->nb_sections;
2685 /* this array is used to reorder sections in the output file */
2686 sec_order = tcc_malloc(sizeof(int) * shnum);
2687 sec_order[0] = 0;
2689 /* compute section to program header mapping */
2690 file_offset = layout_sections(s1, phdr, phnum, phfill, interp, &roinf, sec_order + 1);
2692 /* Fill remaining program header and finalize relocation related to dynamic
2693 linking. */
2695 fill_unloadable_phdr(phdr, phnum, interp, dynamic, note, roinf_use);
2696 if (dynamic) {
2697 ElfW(Sym) *sym;
2699 /* put in GOT the dynamic section address and relocate PLT */
2700 write32le(s1->got->data, dynamic->sh_addr);
2701 if (file_type == TCC_OUTPUT_EXE
2702 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2703 relocate_plt(s1);
2705 /* relocate symbols in .dynsym now that final addresses are known */
2706 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2707 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2708 /* do symbol relocation */
2709 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2714 /* if building executable or DLL, then relocate each section
2715 except the GOT which is already relocated */
2716 relocate_syms(s1, s1->symtab, 0);
2717 ret = -1;
2718 if (s1->nb_errors != 0)
2719 goto the_end;
2720 relocate_sections(s1);
2721 if (dynamic) {
2722 update_reloc_sections (s1, &dyninf);
2723 dynamic->data_offset = dyninf.data_offset;
2724 fill_dynamic(s1, &dyninf);
2726 tidy_section_headers(s1, sec_order);
2728 /* Perform relocation to GOT or PLT entries */
2729 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2730 fill_got(s1);
2731 else if (s1->got)
2732 fill_local_got_entries(s1);
2734 /* Create the ELF file with name 'filename' */
2735 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2736 s1->nb_sections = shnum;
2738 the_end:
2739 tcc_free(sec_order);
2740 tcc_free(phdr);
2741 return ret;
2743 #endif /* ndef ELF_OBJ_ONLY */
2745 /* Allocate strings for section names */
2746 static void alloc_sec_names(TCCState *s1, int is_obj)
2748 int i;
2749 Section *s, *strsec;
2751 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2752 put_elf_str(strsec, "");
2753 for(i = 1; i < s1->nb_sections; i++) {
2754 s = s1->sections[i];
2755 if (is_obj)
2756 s->sh_size = s->data_offset;
2757 if (s == strsec || s->sh_size || (s->sh_flags & SHF_ALLOC))
2758 s->sh_name = put_elf_str(strsec, s->name);
2760 strsec->sh_size = strsec->data_offset;
2763 static int layout_any_sections(TCCState *s1, int file_offset, int *sec_order, int is_obj)
2765 int i;
2766 Section *s;
2767 for(i = 1; i < s1->nb_sections; i++) {
2768 s = s1->sections[i];
2769 if (!is_obj && (s->sh_flags & SHF_ALLOC))
2770 continue;
2771 *sec_order++ = i;
2772 file_offset = (file_offset + s->sh_addralign - 1) &
2773 ~(s->sh_addralign - 1);
2774 s->sh_offset = file_offset;
2775 if (s->sh_type != SHT_NOBITS)
2776 file_offset += s->sh_size;
2778 return file_offset;
2781 /* Output an elf .o file */
2782 static int elf_output_obj(TCCState *s1, const char *filename)
2784 int ret, file_offset;
2785 int *sec_order;
2786 s1->nb_errors = 0;
2788 /* Allocate strings for section names */
2789 alloc_sec_names(s1, 1);
2791 /* this array is used to reorder sections in the output file */
2792 sec_order = tcc_malloc(sizeof(int) * s1->nb_sections);
2793 sec_order[0] = 0;
2794 file_offset = layout_any_sections(s1, sizeof (ElfW(Ehdr)), sec_order + 1, 1);
2796 /* Create the ELF file with name 'filename' */
2797 ret = tcc_write_elf_file(s1, filename, 0, NULL, file_offset, sec_order);
2798 tcc_free(sec_order);
2799 return ret;
2802 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2804 if (s->test_coverage)
2805 tcc_tcov_add_file(s, filename);
2806 if (s->output_type == TCC_OUTPUT_OBJ)
2807 return elf_output_obj(s, filename);
2808 #ifdef TCC_TARGET_PE
2809 return pe_output_file(s, filename);
2810 #elif TCC_TARGET_MACHO
2811 return macho_output_file(s, filename);
2812 #else
2813 return elf_output_file(s, filename);
2814 #endif
2817 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
2818 char *cbuf = buf;
2819 size_t rnum = 0;
2820 while (1) {
2821 ssize_t num = read(fd, cbuf, count-rnum);
2822 if (num < 0) return num;
2823 if (num == 0) return rnum;
2824 rnum += num;
2825 cbuf += num;
2829 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
2831 void *data;
2833 data = tcc_malloc(size);
2834 lseek(fd, file_offset, SEEK_SET);
2835 full_read(fd, data, size);
2836 return data;
2839 typedef struct SectionMergeInfo {
2840 Section *s; /* corresponding existing section */
2841 unsigned long offset; /* offset of the new section in the existing section */
2842 uint8_t new_section; /* true if section 's' was added */
2843 uint8_t link_once; /* true if link once section */
2844 } SectionMergeInfo;
2846 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2848 int size = full_read(fd, h, sizeof *h);
2849 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2850 if (h->e_type == ET_REL)
2851 return AFF_BINTYPE_REL;
2852 if (h->e_type == ET_DYN)
2853 return AFF_BINTYPE_DYN;
2854 } else if (size >= 8) {
2855 if (0 == memcmp(h, ARMAG, 8))
2856 return AFF_BINTYPE_AR;
2857 #ifdef TCC_TARGET_COFF
2858 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2859 return AFF_BINTYPE_C67;
2860 #endif
2862 return 0;
2865 /* load an object file and merge it with current files */
2866 /* XXX: handle correctly stab (debug) info */
2867 ST_FUNC int tcc_load_object_file(TCCState *s1,
2868 int fd, unsigned long file_offset)
2870 ElfW(Ehdr) ehdr;
2871 ElfW(Shdr) *shdr, *sh;
2872 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2873 char *strsec, *strtab;
2874 int stab_index, stabstr_index;
2875 int *old_to_new_syms;
2876 char *sh_name, *name;
2877 SectionMergeInfo *sm_table, *sm;
2878 ElfW(Sym) *sym, *symtab;
2879 ElfW_Rel *rel;
2880 Section *s;
2882 lseek(fd, file_offset, SEEK_SET);
2883 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2884 goto fail1;
2885 /* test CPU specific stuff */
2886 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2887 ehdr.e_machine != EM_TCC_TARGET) {
2888 fail1:
2889 tcc_error_noabort("invalid object file");
2890 return -1;
2892 /* read sections */
2893 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2894 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2895 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2897 /* load section names */
2898 sh = &shdr[ehdr.e_shstrndx];
2899 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2901 /* load symtab and strtab */
2902 old_to_new_syms = NULL;
2903 symtab = NULL;
2904 strtab = NULL;
2905 nb_syms = 0;
2906 seencompressed = 0;
2907 stab_index = stabstr_index = 0;
2909 for(i = 1; i < ehdr.e_shnum; i++) {
2910 sh = &shdr[i];
2911 if (sh->sh_type == SHT_SYMTAB) {
2912 if (symtab) {
2913 tcc_error_noabort("object must contain only one symtab");
2914 fail:
2915 ret = -1;
2916 goto the_end;
2918 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2919 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2920 sm_table[i].s = symtab_section;
2922 /* now load strtab */
2923 sh = &shdr[sh->sh_link];
2924 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2926 if (sh->sh_flags & SHF_COMPRESSED)
2927 seencompressed = 1;
2930 /* now examine each section and try to merge its content with the
2931 ones in memory */
2932 for(i = 1; i < ehdr.e_shnum; i++) {
2933 /* no need to examine section name strtab */
2934 if (i == ehdr.e_shstrndx)
2935 continue;
2936 sh = &shdr[i];
2937 if (sh->sh_type == SHT_RELX)
2938 sh = &shdr[sh->sh_info];
2939 /* ignore sections types we do not handle (plus relocs to those) */
2940 if (sh->sh_type != SHT_PROGBITS &&
2941 #ifdef TCC_ARM_EABI
2942 sh->sh_type != SHT_ARM_EXIDX &&
2943 #endif
2944 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2945 sh->sh_type != SHT_X86_64_UNWIND &&
2946 #endif
2947 sh->sh_type != SHT_NOTE &&
2948 sh->sh_type != SHT_NOBITS &&
2949 sh->sh_type != SHT_PREINIT_ARRAY &&
2950 sh->sh_type != SHT_INIT_ARRAY &&
2951 sh->sh_type != SHT_FINI_ARRAY &&
2952 strcmp(strsec + sh->sh_name, ".stabstr")
2954 continue;
2955 if (seencompressed && 0 == strncmp(strsec + sh->sh_name, ".debug_", 7))
2956 continue;
2958 sh = &shdr[i];
2959 sh_name = strsec + sh->sh_name;
2960 if (sh->sh_addralign < 1)
2961 sh->sh_addralign = 1;
2962 /* find corresponding section, if any */
2963 for(j = 1; j < s1->nb_sections;j++) {
2964 s = s1->sections[j];
2965 if (!strcmp(s->name, sh_name)) {
2966 if (!strncmp(sh_name, ".gnu.linkonce",
2967 sizeof(".gnu.linkonce") - 1)) {
2968 /* if a 'linkonce' section is already present, we
2969 do not add it again. It is a little tricky as
2970 symbols can still be defined in
2971 it. */
2972 sm_table[i].link_once = 1;
2973 goto next;
2975 if (stab_section) {
2976 if (s == stab_section)
2977 stab_index = i;
2978 if (s == stab_section->link)
2979 stabstr_index = i;
2981 goto found;
2984 /* not found: create new section */
2985 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2986 /* take as much info as possible from the section. sh_link and
2987 sh_info will be updated later */
2988 s->sh_addralign = sh->sh_addralign;
2989 s->sh_entsize = sh->sh_entsize;
2990 sm_table[i].new_section = 1;
2991 found:
2992 if (sh->sh_type != s->sh_type) {
2993 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2994 if (strcmp (s->name, ".eh_frame"))
2995 #endif
2997 tcc_error_noabort("invalid section type");
2998 goto fail;
3001 /* align start of section */
3002 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
3003 if (sh->sh_addralign > s->sh_addralign)
3004 s->sh_addralign = sh->sh_addralign;
3005 sm_table[i].offset = s->data_offset;
3006 sm_table[i].s = s;
3007 /* concatenate sections */
3008 size = sh->sh_size;
3009 if (sh->sh_type != SHT_NOBITS) {
3010 unsigned char *ptr;
3011 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
3012 ptr = section_ptr_add(s, size);
3013 full_read(fd, ptr, size);
3014 } else {
3015 s->data_offset += size;
3017 next: ;
3020 /* gr relocate stab strings */
3021 if (stab_index && stabstr_index) {
3022 Stab_Sym *a, *b;
3023 unsigned o;
3024 s = sm_table[stab_index].s;
3025 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
3026 b = (Stab_Sym *)(s->data + s->data_offset);
3027 o = sm_table[stabstr_index].offset;
3028 while (a < b) {
3029 if (a->n_strx)
3030 a->n_strx += o;
3031 a++;
3035 /* second short pass to update sh_link and sh_info fields of new
3036 sections */
3037 for(i = 1; i < ehdr.e_shnum; i++) {
3038 s = sm_table[i].s;
3039 if (!s || !sm_table[i].new_section)
3040 continue;
3041 sh = &shdr[i];
3042 if (sh->sh_link > 0)
3043 s->link = sm_table[sh->sh_link].s;
3044 if (sh->sh_type == SHT_RELX) {
3045 s->sh_info = sm_table[sh->sh_info].s->sh_num;
3046 /* update backward link */
3047 s1->sections[s->sh_info]->reloc = s;
3051 /* resolve symbols */
3052 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
3054 sym = symtab + 1;
3055 for(i = 1; i < nb_syms; i++, sym++) {
3056 if (sym->st_shndx != SHN_UNDEF &&
3057 sym->st_shndx < SHN_LORESERVE) {
3058 sm = &sm_table[sym->st_shndx];
3059 if (sm->link_once) {
3060 /* if a symbol is in a link once section, we use the
3061 already defined symbol. It is very important to get
3062 correct relocations */
3063 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
3064 name = strtab + sym->st_name;
3065 sym_index = find_elf_sym(symtab_section, name);
3066 if (sym_index)
3067 old_to_new_syms[i] = sym_index;
3069 continue;
3071 /* if no corresponding section added, no need to add symbol */
3072 if (!sm->s)
3073 continue;
3074 /* convert section number */
3075 sym->st_shndx = sm->s->sh_num;
3076 /* offset value */
3077 sym->st_value += sm->offset;
3079 /* add symbol */
3080 name = strtab + sym->st_name;
3081 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
3082 sym->st_info, sym->st_other,
3083 sym->st_shndx, name);
3084 old_to_new_syms[i] = sym_index;
3087 /* third pass to patch relocation entries */
3088 for(i = 1; i < ehdr.e_shnum; i++) {
3089 s = sm_table[i].s;
3090 if (!s)
3091 continue;
3092 sh = &shdr[i];
3093 offset = sm_table[i].offset;
3094 size = sh->sh_size;
3095 switch(s->sh_type) {
3096 case SHT_RELX:
3097 /* take relocation offset information */
3098 offseti = sm_table[sh->sh_info].offset;
3099 for (rel = (ElfW_Rel *) s->data + (offset / sizeof(*rel));
3100 rel < (ElfW_Rel *) s->data + ((offset + size) / sizeof(*rel));
3101 rel++) {
3102 int type;
3103 unsigned sym_index;
3104 /* convert symbol index */
3105 type = ELFW(R_TYPE)(rel->r_info);
3106 sym_index = ELFW(R_SYM)(rel->r_info);
3107 /* NOTE: only one symtab assumed */
3108 if (sym_index >= nb_syms)
3109 goto invalid_reloc;
3110 sym_index = old_to_new_syms[sym_index];
3111 /* ignore link_once in rel section. */
3112 if (!sym_index && !sm_table[sh->sh_info].link_once
3113 #ifdef TCC_TARGET_ARM
3114 && type != R_ARM_V4BX
3115 #elif defined TCC_TARGET_RISCV64
3116 && type != R_RISCV_ALIGN
3117 && type != R_RISCV_RELAX
3118 #endif
3120 invalid_reloc:
3121 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3122 i, strsec + sh->sh_name, (int)rel->r_offset);
3123 goto fail;
3125 rel->r_info = ELFW(R_INFO)(sym_index, type);
3126 /* offset the relocation offset */
3127 rel->r_offset += offseti;
3128 #ifdef TCC_TARGET_ARM
3129 /* Jumps and branches from a Thumb code to a PLT entry need
3130 special handling since PLT entries are ARM code.
3131 Unconditional bl instructions referencing PLT entries are
3132 handled by converting these instructions into blx
3133 instructions. Other case of instructions referencing a PLT
3134 entry require to add a Thumb stub before the PLT entry to
3135 switch to ARM mode. We set bit plt_thumb_stub of the
3136 attribute of a symbol to indicate such a case. */
3137 if (type == R_ARM_THM_JUMP24)
3138 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
3139 #endif
3141 break;
3142 default:
3143 break;
3147 ret = 0;
3148 the_end:
3149 tcc_free(symtab);
3150 tcc_free(strtab);
3151 tcc_free(old_to_new_syms);
3152 tcc_free(sm_table);
3153 tcc_free(strsec);
3154 tcc_free(shdr);
3155 return ret;
3158 typedef struct ArchiveHeader {
3159 char ar_name[16]; /* name of this member */
3160 char ar_date[12]; /* file mtime */
3161 char ar_uid[6]; /* owner uid; printed as decimal */
3162 char ar_gid[6]; /* owner gid; printed as decimal */
3163 char ar_mode[8]; /* file mode, printed as octal */
3164 char ar_size[10]; /* file size, printed as decimal */
3165 char ar_fmag[2]; /* should contain ARFMAG */
3166 } ArchiveHeader;
3168 #define ARFMAG "`\n"
3170 static unsigned long long get_be(const uint8_t *b, int n)
3172 unsigned long long ret = 0;
3173 while (n)
3174 ret = (ret << 8) | *b++, --n;
3175 return ret;
3178 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
3180 char *p, *e;
3181 int len;
3182 lseek(fd, offset, SEEK_SET);
3183 len = full_read(fd, hdr, sizeof(ArchiveHeader));
3184 if (len != sizeof(ArchiveHeader))
3185 return len ? -1 : 0;
3186 p = hdr->ar_name;
3187 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
3188 --e;
3189 *e = '\0';
3190 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
3191 return len;
3194 /* load only the objects which resolve undefined symbols */
3195 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
3197 int i, bound, nsyms, sym_index, len, ret = -1;
3198 unsigned long long off;
3199 uint8_t *data;
3200 const char *ar_names, *p;
3201 const uint8_t *ar_index;
3202 ElfW(Sym) *sym;
3203 ArchiveHeader hdr;
3205 data = tcc_malloc(size);
3206 if (full_read(fd, data, size) != size)
3207 goto the_end;
3208 nsyms = get_be(data, entrysize);
3209 ar_index = data + entrysize;
3210 ar_names = (char *) ar_index + nsyms * entrysize;
3212 do {
3213 bound = 0;
3214 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
3215 Section *s = symtab_section;
3216 sym_index = find_elf_sym(s, p);
3217 if (!sym_index)
3218 continue;
3219 sym = &((ElfW(Sym) *)s->data)[sym_index];
3220 if(sym->st_shndx != SHN_UNDEF)
3221 continue;
3222 off = get_be(ar_index + i * entrysize, entrysize);
3223 len = read_ar_header(fd, off, &hdr);
3224 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
3225 tcc_error_noabort("invalid archive");
3226 goto the_end;
3228 off += len;
3229 if (s1->verbose == 2)
3230 printf(" -> %s\n", hdr.ar_name);
3231 if (tcc_load_object_file(s1, fd, off) < 0)
3232 goto the_end;
3233 ++bound;
3235 } while(bound);
3236 ret = 0;
3237 the_end:
3238 tcc_free(data);
3239 return ret;
3242 /* load a '.a' file */
3243 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
3245 ArchiveHeader hdr;
3246 /* char magic[8]; */
3247 int size, len;
3248 unsigned long file_offset;
3249 ElfW(Ehdr) ehdr;
3251 /* skip magic which was already checked */
3252 /* full_read(fd, magic, sizeof(magic)); */
3253 file_offset = sizeof ARMAG - 1;
3255 for(;;) {
3256 len = read_ar_header(fd, file_offset, &hdr);
3257 if (len == 0)
3258 return 0;
3259 if (len < 0) {
3260 tcc_error_noabort("invalid archive");
3261 return -1;
3263 file_offset += len;
3264 size = strtol(hdr.ar_size, NULL, 0);
3265 /* align to even */
3266 size = (size + 1) & ~1;
3267 if (alacarte) {
3268 /* coff symbol table : we handle it */
3269 if (!strcmp(hdr.ar_name, "/"))
3270 return tcc_load_alacarte(s1, fd, size, 4);
3271 if (!strcmp(hdr.ar_name, "/SYM64/"))
3272 return tcc_load_alacarte(s1, fd, size, 8);
3273 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3274 if (s1->verbose == 2)
3275 printf(" -> %s\n", hdr.ar_name);
3276 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3277 return -1;
3279 file_offset += size;
3283 #ifndef ELF_OBJ_ONLY
3284 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3285 LV, maybe create a new entry for (LIB,VERSION). */
3286 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3288 while (i >= *n) {
3289 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3290 (*lv)[(*n)++] = -1;
3292 if ((*lv)[i] == -1) {
3293 int v, prev_same_lib = -1;
3294 for (v = 0; v < nb_sym_versions; v++) {
3295 if (strcmp(sym_versions[v].lib, lib))
3296 continue;
3297 prev_same_lib = v;
3298 if (!strcmp(sym_versions[v].version, version))
3299 break;
3301 if (v == nb_sym_versions) {
3302 sym_versions = tcc_realloc (sym_versions,
3303 (v + 1) * sizeof(*sym_versions));
3304 sym_versions[v].lib = tcc_strdup(lib);
3305 sym_versions[v].version = tcc_strdup(version);
3306 sym_versions[v].out_index = 0;
3307 sym_versions[v].prev_same_lib = prev_same_lib;
3308 nb_sym_versions++;
3310 (*lv)[i] = v;
3314 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3315 VERNDX. */
3316 static void
3317 set_sym_version(TCCState *s1, int sym_index, int verndx)
3319 if (sym_index >= nb_sym_to_version) {
3320 int newelems = sym_index ? sym_index * 2 : 1;
3321 sym_to_version = tcc_realloc(sym_to_version,
3322 newelems * sizeof(*sym_to_version));
3323 memset(sym_to_version + nb_sym_to_version, -1,
3324 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3325 nb_sym_to_version = newelems;
3327 if (sym_to_version[sym_index] < 0)
3328 sym_to_version[sym_index] = verndx;
3331 struct versym_info {
3332 int nb_versyms;
3333 ElfW(Verdef) *verdef;
3334 ElfW(Verneed) *verneed;
3335 ElfW(Half) *versym;
3336 int nb_local_ver, *local_ver;
3340 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3342 char *lib, *version;
3343 uint32_t next;
3344 int i;
3346 #define DEBUG_VERSION 0
3348 if (v->versym && v->verdef) {
3349 ElfW(Verdef) *vdef = v->verdef;
3350 lib = NULL;
3351 do {
3352 ElfW(Verdaux) *verdaux =
3353 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3355 #if DEBUG_VERSION
3356 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3357 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3358 vdef->vd_hash);
3359 #endif
3360 if (vdef->vd_cnt) {
3361 version = dynstr + verdaux->vda_name;
3363 if (lib == NULL)
3364 lib = version;
3365 else
3366 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3367 lib, version);
3368 #if DEBUG_VERSION
3369 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3370 #endif
3372 next = vdef->vd_next;
3373 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3374 } while (next);
3376 if (v->versym && v->verneed) {
3377 ElfW(Verneed) *vneed = v->verneed;
3378 do {
3379 ElfW(Vernaux) *vernaux =
3380 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3382 lib = dynstr + vneed->vn_file;
3383 #if DEBUG_VERSION
3384 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3385 #endif
3386 for (i = 0; i < vneed->vn_cnt; i++) {
3387 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3388 version = dynstr + vernaux->vna_name;
3389 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3390 lib, version);
3391 #if DEBUG_VERSION
3392 printf (" vernaux(%u): %u %u %s\n",
3393 vernaux->vna_other, vernaux->vna_hash,
3394 vernaux->vna_flags, version);
3395 #endif
3397 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3399 next = vneed->vn_next;
3400 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3401 } while (next);
3404 #if DEBUG_VERSION
3405 for (i = 0; i < v->nb_local_ver; i++) {
3406 if (v->local_ver[i] > 0) {
3407 printf ("%d: lib: %s, version %s\n",
3408 i, sym_versions[v->local_ver[i]].lib,
3409 sym_versions[v->local_ver[i]].version);
3412 #endif
3415 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3416 is referenced by the user (so it should be added as DT_NEEDED in
3417 the generated ELF file) */
3418 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3420 ElfW(Ehdr) ehdr;
3421 ElfW(Shdr) *shdr, *sh, *sh1;
3422 int i, nb_syms, nb_dts, sym_bind, ret = -1;
3423 ElfW(Sym) *sym, *dynsym;
3424 ElfW(Dyn) *dt, *dynamic;
3426 char *dynstr;
3427 int sym_index;
3428 const char *name, *soname;
3429 struct versym_info v;
3431 full_read(fd, &ehdr, sizeof(ehdr));
3433 /* test CPU specific stuff */
3434 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3435 ehdr.e_machine != EM_TCC_TARGET) {
3436 tcc_error_noabort("bad architecture");
3437 return -1;
3440 /* read sections */
3441 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3443 /* load dynamic section and dynamic symbols */
3444 nb_syms = 0;
3445 nb_dts = 0;
3446 dynamic = NULL;
3447 dynsym = NULL; /* avoid warning */
3448 dynstr = NULL; /* avoid warning */
3449 memset(&v, 0, sizeof v);
3451 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3452 switch(sh->sh_type) {
3453 case SHT_DYNAMIC:
3454 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3455 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3456 break;
3457 case SHT_DYNSYM:
3458 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3459 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3460 sh1 = &shdr[sh->sh_link];
3461 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3462 break;
3463 case SHT_GNU_verdef:
3464 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3465 break;
3466 case SHT_GNU_verneed:
3467 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3468 break;
3469 case SHT_GNU_versym:
3470 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3471 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3472 break;
3473 default:
3474 break;
3478 if (!dynamic)
3479 goto the_end;
3481 /* compute the real library name */
3482 soname = tcc_basename(filename);
3483 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
3484 if (dt->d_tag == DT_SONAME)
3485 soname = dynstr + dt->d_un.d_val;
3487 /* if the dll is already loaded, do not load it */
3488 if (tcc_add_dllref(s1, soname, level)->found)
3489 goto ret_success;
3491 if (v.nb_versyms != nb_syms)
3492 tcc_free (v.versym), v.versym = NULL;
3493 else
3494 store_version(s1, &v, dynstr);
3496 /* add dynamic symbols in dynsym_section */
3497 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3498 sym_bind = ELFW(ST_BIND)(sym->st_info);
3499 if (sym_bind == STB_LOCAL)
3500 continue;
3501 name = dynstr + sym->st_name;
3502 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3503 sym->st_info, sym->st_other, sym->st_shndx, name);
3504 if (v.versym) {
3505 ElfW(Half) vsym = v.versym[i];
3506 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3507 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3511 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
3512 if (dt->d_tag == DT_RPATH)
3513 tcc_add_library_path(s1, dynstr + dt->d_un.d_val);
3515 /* load all referenced DLLs */
3516 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3517 switch(dt->d_tag) {
3518 case DT_NEEDED:
3519 name = dynstr + dt->d_un.d_val;
3520 if (tcc_add_dllref(s1, name, -1))
3521 continue;
3522 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3523 tcc_error_noabort("referenced dll '%s' not found", name);
3524 goto the_end;
3529 ret_success:
3530 ret = 0;
3531 the_end:
3532 tcc_free(dynstr);
3533 tcc_free(dynsym);
3534 tcc_free(dynamic);
3535 tcc_free(shdr);
3536 tcc_free(v.local_ver);
3537 tcc_free(v.verdef);
3538 tcc_free(v.verneed);
3539 tcc_free(v.versym);
3540 return ret;
3543 #define LD_TOK_NAME 256
3544 #define LD_TOK_EOF (-1)
3546 static int ld_inp(TCCState *s1)
3548 char b;
3549 if (s1->cc != -1) {
3550 int c = s1->cc;
3551 s1->cc = -1;
3552 return c;
3554 if (1 == read(s1->fd, &b, 1))
3555 return b;
3556 return CH_EOF;
3559 /* return next ld script token */
3560 static int ld_next(TCCState *s1, char *name, int name_size)
3562 int c, d, ch;
3563 char *q;
3565 redo:
3566 ch = ld_inp(s1);
3567 switch(ch) {
3568 case ' ':
3569 case '\t':
3570 case '\f':
3571 case '\v':
3572 case '\r':
3573 case '\n':
3574 goto redo;
3575 case '/':
3576 ch = ld_inp(s1);
3577 if (ch == '*') { /* comment */
3578 for (d = 0;; d = ch) {
3579 ch = ld_inp(s1);
3580 if (ch == CH_EOF || (ch == '/' && d == '*'))
3581 break;
3583 goto redo;
3584 } else {
3585 q = name;
3586 *q++ = '/';
3587 goto parse_name;
3589 break;
3590 case '\\':
3591 /* case 'a' ... 'z': */
3592 case 'a':
3593 case 'b':
3594 case 'c':
3595 case 'd':
3596 case 'e':
3597 case 'f':
3598 case 'g':
3599 case 'h':
3600 case 'i':
3601 case 'j':
3602 case 'k':
3603 case 'l':
3604 case 'm':
3605 case 'n':
3606 case 'o':
3607 case 'p':
3608 case 'q':
3609 case 'r':
3610 case 's':
3611 case 't':
3612 case 'u':
3613 case 'v':
3614 case 'w':
3615 case 'x':
3616 case 'y':
3617 case 'z':
3618 /* case 'A' ... 'z': */
3619 case 'A':
3620 case 'B':
3621 case 'C':
3622 case 'D':
3623 case 'E':
3624 case 'F':
3625 case 'G':
3626 case 'H':
3627 case 'I':
3628 case 'J':
3629 case 'K':
3630 case 'L':
3631 case 'M':
3632 case 'N':
3633 case 'O':
3634 case 'P':
3635 case 'Q':
3636 case 'R':
3637 case 'S':
3638 case 'T':
3639 case 'U':
3640 case 'V':
3641 case 'W':
3642 case 'X':
3643 case 'Y':
3644 case 'Z':
3645 case '_':
3646 case '.':
3647 case '$':
3648 case '~':
3649 q = name;
3650 parse_name:
3651 for(;;) {
3652 if (!((ch >= 'a' && ch <= 'z') ||
3653 (ch >= 'A' && ch <= 'Z') ||
3654 (ch >= '0' && ch <= '9') ||
3655 strchr("/.-_+=$:\\,~", ch)))
3656 break;
3657 if ((q - name) < name_size - 1) {
3658 *q++ = ch;
3660 ch = ld_inp(s1);
3662 s1->cc = ch;
3663 *q = '\0';
3664 c = LD_TOK_NAME;
3665 break;
3666 case CH_EOF:
3667 c = LD_TOK_EOF;
3668 break;
3669 default:
3670 c = ch;
3671 break;
3673 return c;
3676 static int ld_add_file(TCCState *s1, const char filename[])
3678 if (filename[0] == '/') {
3679 if (CONFIG_SYSROOT[0] == '\0'
3680 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3681 return 0;
3682 filename = tcc_basename(filename);
3684 return tcc_add_dll(s1, filename, 0);
3687 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3689 char filename[1024], libname[1024];
3690 int t, group, nblibs = 0, ret = 0;
3691 char **libs = NULL;
3693 group = !strcmp(cmd, "GROUP");
3694 if (!as_needed)
3695 s1->new_undef_sym = 0;
3696 t = ld_next(s1, filename, sizeof(filename));
3697 if (t != '(') {
3698 tcc_error_noabort("( expected");
3699 ret = -1;
3700 goto lib_parse_error;
3702 t = ld_next(s1, filename, sizeof(filename));
3703 for(;;) {
3704 libname[0] = '\0';
3705 if (t == LD_TOK_EOF) {
3706 tcc_error_noabort("unexpected end of file");
3707 ret = -1;
3708 goto lib_parse_error;
3709 } else if (t == ')') {
3710 break;
3711 } else if (t == '-') {
3712 t = ld_next(s1, filename, sizeof(filename));
3713 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3714 tcc_error_noabort("library name expected");
3715 ret = -1;
3716 goto lib_parse_error;
3718 pstrcpy(libname, sizeof libname, &filename[1]);
3719 if (s1->static_link) {
3720 snprintf(filename, sizeof filename, "lib%s.a", libname);
3721 } else {
3722 snprintf(filename, sizeof filename, "lib%s.so", libname);
3724 } else if (t != LD_TOK_NAME) {
3725 tcc_error_noabort("filename expected");
3726 ret = -1;
3727 goto lib_parse_error;
3729 if (!strcmp(filename, "AS_NEEDED")) {
3730 ret = ld_add_file_list(s1, cmd, 1);
3731 if (ret)
3732 goto lib_parse_error;
3733 } else {
3734 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3735 if (!as_needed) {
3736 ret = ld_add_file(s1, filename);
3737 if (ret)
3738 goto lib_parse_error;
3739 if (group) {
3740 /* Add the filename *and* the libname to avoid future conversions */
3741 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3742 if (libname[0] != '\0')
3743 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3747 t = ld_next(s1, filename, sizeof(filename));
3748 if (t == ',') {
3749 t = ld_next(s1, filename, sizeof(filename));
3752 if (group && !as_needed) {
3753 while (s1->new_undef_sym) {
3754 int i;
3755 s1->new_undef_sym = 0;
3756 for (i = 0; i < nblibs; i ++)
3757 ld_add_file(s1, libs[i]);
3760 lib_parse_error:
3761 dynarray_reset(&libs, &nblibs);
3762 return ret;
3765 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3766 files */
3767 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3769 char cmd[64];
3770 char filename[1024];
3771 int t, ret;
3773 s1->fd = fd;
3774 s1->cc = -1;
3775 for(;;) {
3776 t = ld_next(s1, cmd, sizeof(cmd));
3777 if (t == LD_TOK_EOF)
3778 return 0;
3779 else if (t != LD_TOK_NAME)
3780 return -1;
3781 if (!strcmp(cmd, "INPUT") ||
3782 !strcmp(cmd, "GROUP")) {
3783 ret = ld_add_file_list(s1, cmd, 0);
3784 if (ret)
3785 return ret;
3786 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3787 !strcmp(cmd, "TARGET")) {
3788 /* ignore some commands */
3789 t = ld_next(s1, cmd, sizeof(cmd));
3790 if (t != '(') {
3791 tcc_error_noabort("( expected");
3792 return -1;
3794 for(;;) {
3795 t = ld_next(s1, filename, sizeof(filename));
3796 if (t == LD_TOK_EOF) {
3797 tcc_error_noabort("unexpected end of file");
3798 return -1;
3799 } else if (t == ')') {
3800 break;
3803 } else {
3804 return -1;
3807 return 0;
3809 #endif /* !ELF_OBJ_ONLY */