Better handling of UCNs in strings
[tinycc.git] / tccelf.c
blob0371ae59c8e5680d305c190f5b2970985d13f71a
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 /* create ro data section (make ro after relocation done with GNU_RELRO) */
62 data_ro_section = new_section(s, ".data.ro", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
63 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
64 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
65 common_section->sh_num = SHN_COMMON;
67 /* symbols are always generated for linking stage */
68 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
69 ".strtab",
70 ".hashtab", SHF_PRIVATE);
71 s->symtab = symtab_section;
73 /* private symbol table for dynamic symbols */
74 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
75 ".dynstrtab",
76 ".dynhashtab", SHF_PRIVATE);
77 get_sym_attr(s, 0, 1);
80 #ifdef CONFIG_TCC_BCHECK
81 ST_FUNC void tccelf_bounds_new(TCCState *s)
83 TCCState *s1 = s;
84 /* create bounds sections (make ro after relocation done with GNU_RELRO) */
85 bounds_section = new_section(s, ".bounds",
86 SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
87 lbounds_section = new_section(s, ".lbounds",
88 SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
90 #endif
92 ST_FUNC void tccelf_stab_new(TCCState *s)
94 TCCState *s1 = s;
95 int shf = 0;
96 #ifdef CONFIG_TCC_BACKTRACE
97 /* include stab info with standalone backtrace support */
98 if (s->do_backtrace && s->output_type != TCC_OUTPUT_MEMORY)
99 shf = SHF_ALLOC | SHF_WRITE; // SHF_WRITE needed for musl/SELINUX
100 #endif
101 stab_section = new_section(s, ".stab", SHT_PROGBITS, shf);
102 stab_section->sh_entsize = sizeof(Stab_Sym);
103 stab_section->sh_addralign = sizeof ((Stab_Sym*)0)->n_value;
104 stab_section->link = new_section(s, ".stabstr", SHT_STRTAB, shf);
105 /* put first entry */
106 put_stabs(s, "", 0, 0, 0, 0);
109 static void free_section(Section *s)
111 tcc_free(s->data);
114 ST_FUNC void tccelf_delete(TCCState *s1)
116 int i;
118 #ifndef ELF_OBJ_ONLY
119 /* free symbol versions */
120 for (i = 0; i < nb_sym_versions; i++) {
121 tcc_free(sym_versions[i].version);
122 tcc_free(sym_versions[i].lib);
124 tcc_free(sym_versions);
125 tcc_free(sym_to_version);
126 #endif
128 /* free all sections */
129 for(i = 1; i < s1->nb_sections; i++)
130 free_section(s1->sections[i]);
131 dynarray_reset(&s1->sections, &s1->nb_sections);
133 for(i = 0; i < s1->nb_priv_sections; i++)
134 free_section(s1->priv_sections[i]);
135 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
137 /* free any loaded DLLs */
138 #ifdef TCC_IS_NATIVE
139 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
140 DLLReference *ref = s1->loaded_dlls[i];
141 if ( ref->handle )
142 # ifdef _WIN32
143 FreeLibrary((HMODULE)ref->handle);
144 # else
145 dlclose(ref->handle);
146 # endif
148 #endif
149 /* free loaded dlls array */
150 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
151 tcc_free(s1->sym_attrs);
153 symtab_section = NULL; /* for tccrun.c:rt_printline() */
156 /* save section data state */
157 ST_FUNC void tccelf_begin_file(TCCState *s1)
159 Section *s; int i;
160 for (i = 1; i < s1->nb_sections; i++) {
161 s = s1->sections[i];
162 s->sh_offset = s->data_offset;
164 /* disable symbol hashing during compilation */
165 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
166 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
167 s1->uw_sym = 0;
168 #endif
171 /* At the end of compilation, convert any UNDEF syms to global, and merge
172 with previously existing symbols */
173 ST_FUNC void tccelf_end_file(TCCState *s1)
175 Section *s = s1->symtab;
176 int first_sym, nb_syms, *tr, i;
178 first_sym = s->sh_offset / sizeof (ElfSym);
179 nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
180 s->data_offset = s->sh_offset;
181 s->link->data_offset = s->link->sh_offset;
182 s->hash = s->reloc, s->reloc = NULL;
183 tr = tcc_mallocz(nb_syms * sizeof *tr);
185 for (i = 0; i < nb_syms; ++i) {
186 ElfSym *sym = (ElfSym*)s->data + first_sym + i;
187 if (sym->st_shndx == SHN_UNDEF
188 && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
189 sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
190 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
191 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
193 /* now update relocations */
194 for (i = 1; i < s1->nb_sections; i++) {
195 Section *sr = s1->sections[i];
196 if (sr->sh_type == SHT_RELX && sr->link == s) {
197 ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
198 ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
199 for (; rel < rel_end; ++rel) {
200 int n = ELFW(R_SYM)(rel->r_info) - first_sym;
201 //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
202 rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
206 tcc_free(tr);
208 /* record text/data/bss output for -bench info */
209 for (i = 0; i < 3; ++i) {
210 s = s1->sections[i + 1];
211 s1->total_output[i] += s->data_offset - s->sh_offset;
215 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
217 Section *sec;
219 sec = tcc_mallocz(sizeof(Section) + strlen(name));
220 sec->s1 = s1;
221 strcpy(sec->name, name);
222 sec->sh_type = sh_type;
223 sec->sh_flags = sh_flags;
224 switch(sh_type) {
225 case SHT_GNU_versym:
226 sec->sh_addralign = 2;
227 break;
228 case SHT_HASH:
229 case SHT_REL:
230 case SHT_RELA:
231 case SHT_DYNSYM:
232 case SHT_SYMTAB:
233 case SHT_DYNAMIC:
234 case SHT_GNU_verneed:
235 case SHT_GNU_verdef:
236 sec->sh_addralign = PTR_SIZE;
237 break;
238 case SHT_STRTAB:
239 sec->sh_addralign = 1;
240 break;
241 default:
242 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */
243 break;
246 if (sh_flags & SHF_PRIVATE) {
247 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
248 } else {
249 sec->sh_num = s1->nb_sections;
250 dynarray_add(&s1->sections, &s1->nb_sections, sec);
253 return sec;
256 ST_FUNC Section *new_symtab(TCCState *s1,
257 const char *symtab_name, int sh_type, int sh_flags,
258 const char *strtab_name,
259 const char *hash_name, int hash_sh_flags)
261 Section *symtab, *strtab, *hash;
262 int *ptr, nb_buckets;
264 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
265 symtab->sh_entsize = sizeof(ElfW(Sym));
266 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
267 put_elf_str(strtab, "");
268 symtab->link = strtab;
269 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
271 nb_buckets = 1;
273 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
274 hash->sh_entsize = sizeof(int);
275 symtab->hash = hash;
276 hash->link = symtab;
278 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
279 ptr[0] = nb_buckets;
280 ptr[1] = 1;
281 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
282 return symtab;
285 /* realloc section and set its content to zero */
286 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
288 unsigned long size;
289 unsigned char *data;
291 size = sec->data_allocated;
292 if (size == 0)
293 size = 1;
294 while (size < new_size)
295 size = size * 2;
296 data = tcc_realloc(sec->data, size);
297 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
298 sec->data = data;
299 sec->data_allocated = size;
302 /* reserve at least 'size' bytes aligned per 'align' in section
303 'sec' from current offset, and return the aligned offset */
304 ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
306 size_t offset, offset1;
308 offset = (sec->data_offset + align - 1) & -align;
309 offset1 = offset + size;
310 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
311 section_realloc(sec, offset1);
312 sec->data_offset = offset1;
313 if (align > sec->sh_addralign)
314 sec->sh_addralign = align;
315 return offset;
318 /* reserve at least 'size' bytes in section 'sec' from
319 sec->data_offset. */
320 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
322 size_t offset = section_add(sec, size, 1);
323 return sec->data + offset;
326 #ifndef ELF_OBJ_ONLY
327 /* reserve at least 'size' bytes from section start */
328 static void section_reserve(Section *sec, unsigned long size)
330 if (size > sec->data_allocated)
331 section_realloc(sec, size);
332 if (size > sec->data_offset)
333 sec->data_offset = size;
335 #endif
337 static Section *find_section_create (TCCState *s1, const char *name, int create)
339 Section *sec;
340 int i;
341 for(i = 1; i < s1->nb_sections; i++) {
342 sec = s1->sections[i];
343 if (!strcmp(name, sec->name))
344 return sec;
346 /* sections are created as PROGBITS */
347 return create ? new_section(s1, name, SHT_PROGBITS, SHF_ALLOC) : NULL;
350 /* return a reference to a section, and create it if it does not
351 exists */
352 ST_FUNC Section *find_section(TCCState *s1, const char *name)
354 return find_section_create (s1, name, 1);
357 /* ------------------------------------------------------------------------- */
359 ST_FUNC int put_elf_str(Section *s, const char *sym)
361 int offset, len;
362 char *ptr;
364 len = strlen(sym) + 1;
365 offset = s->data_offset;
366 ptr = section_ptr_add(s, len);
367 memmove(ptr, sym, len);
368 return offset;
371 /* elf symbol hashing function */
372 static unsigned long elf_hash(const unsigned char *name)
374 unsigned long h = 0, g;
376 while (*name) {
377 h = (h << 4) + *name++;
378 g = h & 0xf0000000;
379 if (g)
380 h ^= g >> 24;
381 h &= ~g;
383 return h;
386 /* rebuild hash table of section s */
387 /* NOTE: we do factorize the hash table code to go faster */
388 static void rebuild_hash(Section *s, unsigned int nb_buckets)
390 ElfW(Sym) *sym;
391 int *ptr, *hash, nb_syms, sym_index, h;
392 unsigned char *strtab;
394 strtab = s->link->data;
395 nb_syms = s->data_offset / sizeof(ElfW(Sym));
397 if (!nb_buckets)
398 nb_buckets = ((int*)s->hash->data)[0];
400 s->hash->data_offset = 0;
401 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
402 ptr[0] = nb_buckets;
403 ptr[1] = nb_syms;
404 ptr += 2;
405 hash = ptr;
406 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
407 ptr += nb_buckets + 1;
409 sym = (ElfW(Sym) *)s->data + 1;
410 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
411 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
412 h = elf_hash(strtab + sym->st_name) % nb_buckets;
413 *ptr = hash[h];
414 hash[h] = sym_index;
415 } else {
416 *ptr = 0;
418 ptr++;
419 sym++;
423 /* return the symbol number */
424 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
425 int info, int other, int shndx, const char *name)
427 int name_offset, sym_index;
428 int nbuckets, h;
429 ElfW(Sym) *sym;
430 Section *hs;
432 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
433 if (name && name[0])
434 name_offset = put_elf_str(s->link, name);
435 else
436 name_offset = 0;
437 /* XXX: endianness */
438 sym->st_name = name_offset;
439 sym->st_value = value;
440 sym->st_size = size;
441 sym->st_info = info;
442 sym->st_other = other;
443 sym->st_shndx = shndx;
444 sym_index = sym - (ElfW(Sym) *)s->data;
445 hs = s->hash;
446 if (hs) {
447 int *ptr, *base;
448 ptr = section_ptr_add(hs, sizeof(int));
449 base = (int *)hs->data;
450 /* only add global or weak symbols. */
451 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
452 /* add another hashing entry */
453 nbuckets = base[0];
454 h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
455 *ptr = base[2 + h];
456 base[2 + h] = sym_index;
457 base[1]++;
458 /* we resize the hash table */
459 hs->nb_hashed_syms++;
460 if (hs->nb_hashed_syms > 2 * nbuckets) {
461 rebuild_hash(s, 2 * nbuckets);
463 } else {
464 *ptr = 0;
465 base[1]++;
468 return sym_index;
471 ST_FUNC int find_elf_sym(Section *s, const char *name)
473 ElfW(Sym) *sym;
474 Section *hs;
475 int nbuckets, sym_index, h;
476 const char *name1;
478 hs = s->hash;
479 if (!hs)
480 return 0;
481 nbuckets = ((int *)hs->data)[0];
482 h = elf_hash((unsigned char *) name) % nbuckets;
483 sym_index = ((int *)hs->data)[2 + h];
484 while (sym_index != 0) {
485 sym = &((ElfW(Sym) *)s->data)[sym_index];
486 name1 = (char *) s->link->data + sym->st_name;
487 if (!strcmp(name, name1))
488 return sym_index;
489 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
491 return 0;
494 /* return elf symbol value, signal error if 'err' is nonzero, decorate
495 name if FORC */
496 ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
498 int sym_index;
499 ElfW(Sym) *sym;
500 char buf[256];
501 if (forc && s1->leading_underscore
502 #ifdef TCC_TARGET_PE
503 /* win32-32bit stdcall symbols always have _ already */
504 && !strchr(name, '@')
505 #endif
507 buf[0] = '_';
508 pstrcpy(buf + 1, sizeof(buf) - 1, name);
509 name = buf;
511 sym_index = find_elf_sym(s1->symtab, name);
512 sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
513 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
514 if (err)
515 tcc_error("%s not defined", name);
516 return (addr_t)-1;
518 return sym->st_value;
521 /* return elf symbol value */
522 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
524 addr_t addr = get_sym_addr(s, name, 0, 1);
525 return addr == -1 ? NULL : (void*)(uintptr_t)addr;
528 /* list elf symbol names and values */
529 ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
530 void (*symbol_cb)(void *ctx, const char *name, const void *val))
532 ElfW(Sym) *sym;
533 Section *symtab;
534 int sym_index, end_sym;
535 const char *name;
536 unsigned char sym_vis, sym_bind;
538 symtab = s->symtab;
539 end_sym = symtab->data_offset / sizeof (ElfSym);
540 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
541 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
542 if (sym->st_value) {
543 name = (char *) symtab->link->data + sym->st_name;
544 sym_bind = ELFW(ST_BIND)(sym->st_info);
545 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
546 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
547 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
552 /* list elf symbol names and values */
553 LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
554 void (*symbol_cb)(void *ctx, const char *name, const void *val))
556 list_elf_symbols(s, ctx, symbol_cb);
559 #ifndef ELF_OBJ_ONLY
560 static void
561 version_add (TCCState *s1)
563 int i;
564 ElfW(Sym) *sym;
565 ElfW(Verneed) *vn = NULL;
566 Section *symtab;
567 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
568 ElfW(Half) *versym;
569 const char *name;
571 if (0 == nb_sym_versions)
572 return;
573 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
574 versym_section->sh_entsize = sizeof(ElfW(Half));
575 versym_section->link = s1->dynsym;
577 /* add needed symbols */
578 symtab = s1->dynsym;
579 end_sym = symtab->data_offset / sizeof (ElfSym);
580 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
581 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
582 int dllindex, verndx;
583 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
584 name = (char *) symtab->link->data + sym->st_name;
585 dllindex = find_elf_sym(s1->dynsymtab_section, name);
586 verndx = (dllindex && dllindex < nb_sym_to_version)
587 ? sym_to_version[dllindex] : -1;
588 if (verndx >= 0) {
589 if (!sym_versions[verndx].out_index)
590 sym_versions[verndx].out_index = nb_versions++;
591 versym[sym_index] = sym_versions[verndx].out_index;
592 } else
593 versym[sym_index] = 0;
595 /* generate verneed section, but not when it will be empty. Some
596 dynamic linkers look at their contents even when DTVERNEEDNUM and
597 section size is zero. */
598 if (nb_versions > 2) {
599 verneed_section = new_section(s1, ".gnu.version_r",
600 SHT_GNU_verneed, SHF_ALLOC);
601 verneed_section->link = s1->dynsym->link;
602 for (i = nb_sym_versions; i-- > 0;) {
603 struct sym_version *sv = &sym_versions[i];
604 int n_same_libs = 0, prev;
605 size_t vnofs;
606 ElfW(Vernaux) *vna = 0;
607 if (sv->out_index < 1)
608 continue;
609 vnofs = section_add(verneed_section, sizeof(*vn), 1);
610 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
611 vn->vn_version = 1;
612 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
613 vn->vn_aux = sizeof (*vn);
614 do {
615 prev = sv->prev_same_lib;
616 if (sv->out_index > 0) {
617 vna = section_ptr_add(verneed_section, sizeof(*vna));
618 vna->vna_hash = elf_hash ((const unsigned char *)sv->version);
619 vna->vna_flags = 0;
620 vna->vna_other = sv->out_index;
621 sv->out_index = -2;
622 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
623 vna->vna_next = sizeof (*vna);
624 n_same_libs++;
626 if (prev >= 0)
627 sv = &sym_versions[prev];
628 } while(prev >= 0);
629 vna->vna_next = 0;
630 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
631 vn->vn_cnt = n_same_libs;
632 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
633 nb_entries++;
635 if (vn)
636 vn->vn_next = 0;
637 verneed_section->sh_info = nb_entries;
639 dt_verneednum = nb_entries;
641 #endif
643 /* add an elf symbol : check if it is already defined and patch
644 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
645 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
646 int info, int other, int shndx, const char *name)
648 TCCState *s1 = s->s1;
649 ElfW(Sym) *esym;
650 int sym_bind, sym_index, sym_type, esym_bind;
651 unsigned char sym_vis, esym_vis, new_vis;
653 sym_bind = ELFW(ST_BIND)(info);
654 sym_type = ELFW(ST_TYPE)(info);
655 sym_vis = ELFW(ST_VISIBILITY)(other);
657 if (sym_bind != STB_LOCAL) {
658 /* we search global or weak symbols */
659 sym_index = find_elf_sym(s, name);
660 if (!sym_index)
661 goto do_def;
662 esym = &((ElfW(Sym) *)s->data)[sym_index];
663 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
664 && esym->st_other == other && esym->st_shndx == shndx)
665 return sym_index;
666 if (esym->st_shndx != SHN_UNDEF) {
667 esym_bind = ELFW(ST_BIND)(esym->st_info);
668 /* propagate the most constraining visibility */
669 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
670 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
671 if (esym_vis == STV_DEFAULT) {
672 new_vis = sym_vis;
673 } else if (sym_vis == STV_DEFAULT) {
674 new_vis = esym_vis;
675 } else {
676 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
678 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
679 | new_vis;
680 other = esym->st_other; /* in case we have to patch esym */
681 if (shndx == SHN_UNDEF) {
682 /* ignore adding of undefined symbol if the
683 corresponding symbol is already defined */
684 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
685 /* global overrides weak, so patch */
686 goto do_patch;
687 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
688 /* weak is ignored if already global */
689 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
690 /* keep first-found weak definition, ignore subsequents */
691 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
692 /* ignore hidden symbols after */
693 } else if ((esym->st_shndx == SHN_COMMON
694 || esym->st_shndx == bss_section->sh_num)
695 && (shndx < SHN_LORESERVE
696 && shndx != bss_section->sh_num)) {
697 /* data symbol gets precedence over common/bss */
698 goto do_patch;
699 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
700 /* data symbol keeps precedence over common/bss */
701 } else if (s->sh_flags & SHF_DYNSYM) {
702 /* we accept that two DLL define the same symbol */
703 } else if (esym->st_other & ST_ASM_SET) {
704 /* If the existing symbol came from an asm .set
705 we can override. */
706 goto do_patch;
707 } else {
708 #if 0
709 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
710 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
711 #endif
712 tcc_error_noabort("'%s' defined twice", name);
714 } else {
715 do_patch:
716 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
717 esym->st_shndx = shndx;
718 s1->new_undef_sym = 1;
719 esym->st_value = value;
720 esym->st_size = size;
721 esym->st_other = other;
723 } else {
724 do_def:
725 sym_index = put_elf_sym(s, value, size,
726 ELFW(ST_INFO)(sym_bind, sym_type), other,
727 shndx, name);
729 return sym_index;
732 /* put relocation */
733 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
734 int type, int symbol, addr_t addend)
736 TCCState *s1 = s->s1;
737 char buf[256];
738 Section *sr;
739 ElfW_Rel *rel;
740 int jmp_slot = type == R_JMP_SLOT;
742 sr = jmp_slot ? s->relocplt : s->reloc;
743 if (!sr) {
744 /* if no relocation section, create it */
745 if (jmp_slot)
746 snprintf(buf, sizeof(buf), RELPLT_SECTION_FMT);
747 else
748 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
749 /* if the symtab is allocated, then we consider the relocation
750 are also */
751 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
752 sr->sh_entsize = sizeof(ElfW_Rel);
753 sr->link = symtab;
754 sr->sh_info = s->sh_num;
755 if (jmp_slot)
756 s->relocplt = sr;
757 else
758 s->reloc = sr;
760 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
761 rel->r_offset = offset;
762 rel->r_info = ELFW(R_INFO)(symbol, type);
763 #if SHT_RELX == SHT_RELA
764 rel->r_addend = addend;
765 #endif
766 if (SHT_RELX != SHT_RELA && addend)
767 tcc_error("non-zero addend on REL architecture");
770 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
771 int type, int symbol)
773 put_elf_reloca(symtab, s, offset, type, symbol, 0);
776 /* put stab debug information */
777 ST_FUNC void put_stabs(TCCState *s1, const char *str, int type, int other, int desc,
778 unsigned long value)
780 Stab_Sym *sym;
782 unsigned offset;
783 if (type == N_SLINE
784 && (offset = stab_section->data_offset)
785 && (sym = (Stab_Sym*)(stab_section->data + offset) - 1)
786 && sym->n_type == type
787 && sym->n_value == value) {
788 /* just update line_number in previous entry */
789 sym->n_desc = desc;
790 return;
793 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
794 if (str) {
795 sym->n_strx = put_elf_str(stab_section->link, str);
796 } else {
797 sym->n_strx = 0;
799 sym->n_type = type;
800 sym->n_other = other;
801 sym->n_desc = desc;
802 sym->n_value = value;
805 ST_FUNC void put_stabs_r(TCCState *s1, const char *str, int type, int other, int desc,
806 unsigned long value, Section *sec, int sym_index)
808 put_elf_reloc(symtab_section, stab_section,
809 stab_section->data_offset + 8,
810 sizeof ((Stab_Sym*)0)->n_value == PTR_SIZE ? R_DATA_PTR : R_DATA_32,
811 sym_index);
812 put_stabs(s1, str, type, other, desc, value);
815 ST_FUNC void put_stabn(TCCState *s1, int type, int other, int desc, int value)
817 put_stabs(s1, NULL, type, other, desc, value);
820 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
822 int n;
823 struct sym_attr *tab;
825 if (index >= s1->nb_sym_attrs) {
826 if (!alloc)
827 return s1->sym_attrs;
828 /* find immediately bigger power of 2 and reallocate array */
829 n = 1;
830 while (index >= n)
831 n *= 2;
832 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
833 s1->sym_attrs = tab;
834 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
835 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
836 s1->nb_sym_attrs = n;
838 return &s1->sym_attrs[index];
841 /* In an ELF file symbol table, the local symbols must appear below
842 the global and weak ones. Since TCC cannot sort it while generating
843 the code, we must do it after. All the relocation tables are also
844 modified to take into account the symbol table sorting */
845 static void sort_syms(TCCState *s1, Section *s)
847 int *old_to_new_syms;
848 ElfW(Sym) *new_syms;
849 int nb_syms, i;
850 ElfW(Sym) *p, *q;
851 ElfW_Rel *rel;
852 Section *sr;
853 int type, sym_index;
855 nb_syms = s->data_offset / sizeof(ElfW(Sym));
856 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
857 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
859 /* first pass for local symbols */
860 p = (ElfW(Sym) *)s->data;
861 q = new_syms;
862 for(i = 0; i < nb_syms; i++) {
863 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
864 old_to_new_syms[i] = q - new_syms;
865 *q++ = *p;
867 p++;
869 /* save the number of local symbols in section header */
870 if( s->sh_size ) /* this 'if' makes IDA happy */
871 s->sh_info = q - new_syms;
873 /* then second pass for non local symbols */
874 p = (ElfW(Sym) *)s->data;
875 for(i = 0; i < nb_syms; i++) {
876 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
877 old_to_new_syms[i] = q - new_syms;
878 *q++ = *p;
880 p++;
883 /* we copy the new symbols to the old */
884 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
885 tcc_free(new_syms);
887 /* now we modify all the relocations */
888 for(i = 1; i < s1->nb_sections; i++) {
889 sr = s1->sections[i];
890 if (sr->sh_type == SHT_RELX && sr->link == s) {
891 for_each_elem(sr, 0, rel, ElfW_Rel) {
892 sym_index = ELFW(R_SYM)(rel->r_info);
893 type = ELFW(R_TYPE)(rel->r_info);
894 sym_index = old_to_new_syms[sym_index];
895 rel->r_info = ELFW(R_INFO)(sym_index, type);
900 tcc_free(old_to_new_syms);
903 /* relocate symbol table, resolve undefined symbols if do_resolve is
904 true and output error if undefined symbol. */
905 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
907 ElfW(Sym) *sym;
908 int sym_bind, sh_num;
909 const char *name;
911 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
912 sh_num = sym->st_shndx;
913 if (sh_num == SHN_UNDEF) {
914 name = (char *) s1->symtab->link->data + sym->st_name;
915 /* Use ld.so to resolve symbol for us (for tcc -run) */
916 if (do_resolve) {
917 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
918 /* dlsym() needs the undecorated name. */
919 void *addr = dlsym(RTLD_DEFAULT, &name[s1->leading_underscore]);
920 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
921 if (addr == NULL) {
922 int i;
923 for (i = 0; i < s1->nb_loaded_dlls; i++)
924 if ((addr = dlsym(s1->loaded_dlls[i]->handle, name)))
925 break;
927 #endif
928 if (addr) {
929 sym->st_value = (addr_t) addr;
930 #ifdef DEBUG_RELOC
931 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
932 #endif
933 goto found;
935 #endif
936 /* if dynamic symbol exist, it will be used in relocate_section */
937 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
938 goto found;
939 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
940 it */
941 if (!strcmp(name, "_fp_hw"))
942 goto found;
943 /* only weak symbols are accepted to be undefined. Their
944 value is zero */
945 sym_bind = ELFW(ST_BIND)(sym->st_info);
946 if (sym_bind == STB_WEAK)
947 sym->st_value = 0;
948 else
949 tcc_error_noabort("undefined symbol '%s'", name);
950 } else if (sh_num < SHN_LORESERVE) {
951 /* add section base */
952 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
954 found: ;
958 /* relocate a given section (CPU dependent) by applying the relocations
959 in the associated relocation section */
960 ST_FUNC void relocate_section(TCCState *s1, Section *s)
962 Section *sr = s->reloc;
963 ElfW_Rel *rel;
964 ElfW(Sym) *sym;
965 int type, sym_index;
966 unsigned char *ptr;
967 addr_t tgt, addr;
969 qrel = (ElfW_Rel *)sr->data;
971 for_each_elem(sr, 0, rel, ElfW_Rel) {
972 ptr = s->data + rel->r_offset;
973 sym_index = ELFW(R_SYM)(rel->r_info);
974 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
975 type = ELFW(R_TYPE)(rel->r_info);
976 tgt = sym->st_value;
977 #if SHT_RELX == SHT_RELA
978 tgt += rel->r_addend;
979 #endif
980 addr = s->sh_addr + rel->r_offset;
981 relocate(s1, rel, type, ptr, addr, tgt);
983 /* if the relocation is allocated, we change its symbol table */
984 if (sr->sh_flags & SHF_ALLOC) {
985 sr->link = s1->dynsym;
986 if (s1->output_type == TCC_OUTPUT_DLL) {
987 size_t r = (uint8_t*)qrel - sr->data;
988 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
989 && 0 == strcmp(s->name, ".stab"))
990 r = 0; /* cannot apply 64bit relocation to 32bit value */
991 sr->data_offset = sr->sh_size = r;
996 #ifndef ELF_OBJ_ONLY
997 /* relocate relocation table in 'sr' */
998 static void relocate_rel(TCCState *s1, Section *sr)
1000 Section *s;
1001 ElfW_Rel *rel;
1003 s = s1->sections[sr->sh_info];
1004 for_each_elem(sr, 0, rel, ElfW_Rel)
1005 rel->r_offset += s->sh_addr;
1008 /* count the number of dynamic relocations so that we can reserve
1009 their space */
1010 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
1012 int count = 0;
1013 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1014 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1015 defined(TCC_TARGET_RISCV64)
1016 ElfW_Rel *rel;
1017 for_each_elem(sr, 0, rel, ElfW_Rel) {
1018 int sym_index = ELFW(R_SYM)(rel->r_info);
1019 int type = ELFW(R_TYPE)(rel->r_info);
1020 switch(type) {
1021 #if defined(TCC_TARGET_I386)
1022 case R_386_32:
1023 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
1024 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
1025 /* don't fixup unresolved (weak) symbols */
1026 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
1027 break;
1029 #elif defined(TCC_TARGET_X86_64)
1030 case R_X86_64_32:
1031 case R_X86_64_32S:
1032 case R_X86_64_64:
1033 #elif defined(TCC_TARGET_ARM)
1034 case R_ARM_ABS32:
1035 case R_ARM_TARGET1:
1036 #elif defined(TCC_TARGET_ARM64)
1037 case R_AARCH64_ABS32:
1038 case R_AARCH64_ABS64:
1039 #elif defined(TCC_TARGET_RISCV64)
1040 case R_RISCV_32:
1041 case R_RISCV_64:
1042 #endif
1043 count++;
1044 break;
1045 #if defined(TCC_TARGET_I386)
1046 case R_386_PC32:
1047 #elif defined(TCC_TARGET_X86_64)
1048 case R_X86_64_PC32:
1050 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1052 /* Hidden defined symbols can and must be resolved locally.
1053 We're misusing a PLT32 reloc for this, as that's always
1054 resolved to its address even in shared libs. */
1055 if (sym->st_shndx != SHN_UNDEF &&
1056 ELFW(ST_VISIBILITY)(sym->st_other) == STV_HIDDEN) {
1057 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PLT32);
1058 break;
1061 #elif defined(TCC_TARGET_ARM64)
1062 case R_AARCH64_PREL32:
1063 #endif
1064 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1065 count++;
1066 break;
1067 default:
1068 break;
1071 #endif
1072 return count;
1074 #endif
1076 #if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE)
1077 static void build_got(TCCState *s1)
1079 /* if no got, then create it */
1080 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1081 s1->got->sh_entsize = 4;
1082 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1083 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1084 /* keep space for _DYNAMIC pointer and two dummy got entries */
1085 section_ptr_add(s1->got, 3 * PTR_SIZE);
1088 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1089 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1090 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1091 Returns the offset of the GOT or (if any) PLT entry. */
1092 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1093 int sym_index)
1095 int need_plt_entry;
1096 const char *name;
1097 ElfW(Sym) *sym;
1098 struct sym_attr *attr;
1099 unsigned got_offset;
1100 char plt_name[100];
1101 int len;
1103 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1104 attr = get_sym_attr(s1, sym_index, 1);
1106 /* In case a function is both called and its address taken 2 GOT entries
1107 are created, one for taking the address (GOT) and the other for the PLT
1108 entry (PLTGOT). */
1109 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1110 return attr;
1112 /* create the GOT entry */
1113 got_offset = s1->got->data_offset;
1114 section_ptr_add(s1->got, PTR_SIZE);
1116 /* Create the GOT relocation that will insert the address of the object or
1117 function of interest in the GOT entry. This is a static relocation for
1118 memory output (dlsym will give us the address of symbols) and dynamic
1119 relocation otherwise (executable and DLLs). The relocation should be
1120 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1121 associated to a PLT entry) but is currently done at load time for an
1122 unknown reason. */
1124 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1125 name = (char *) symtab_section->link->data + sym->st_name;
1127 if (s1->dynsym) {
1128 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1129 /* Hack alarm. We don't want to emit dynamic symbols
1130 and symbol based relocs for STB_LOCAL symbols, but rather
1131 want to resolve them directly. At this point the symbol
1132 values aren't final yet, so we must defer this. We will later
1133 have to create a RELATIVE reloc anyway, so we misuse the
1134 relocation slot to smuggle the symbol reference until
1135 fill_local_got_entries. Not that the sym_index is
1136 relative to symtab_section, not s1->dynsym! Nevertheless
1137 we use s1->dyn_sym so that if this is the first call
1138 that got->reloc is correctly created. Also note that
1139 RELATIVE relocs are not normally created for the .got,
1140 so the types serves as a marker for later (and is retained
1141 also for the final output, which is okay because then the
1142 got is just normal data). */
1143 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1144 sym_index);
1145 } else {
1146 if (0 == attr->dyn_index)
1147 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1148 sym->st_size, sym->st_info, 0,
1149 sym->st_shndx, name);
1150 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
1151 attr->dyn_index);
1153 } else {
1154 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1155 sym_index);
1158 if (need_plt_entry) {
1159 if (!s1->plt) {
1160 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1161 SHF_ALLOC | SHF_EXECINSTR);
1162 s1->plt->sh_entsize = 4;
1165 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1167 /* create a symbol 'sym@plt' for the PLT jump vector */
1168 len = strlen(name);
1169 if (len > sizeof plt_name - 5)
1170 len = sizeof plt_name - 5;
1171 memcpy(plt_name, name, len);
1172 strcpy(plt_name + len, "@plt");
1173 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
1174 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1176 } else {
1177 attr->got_offset = got_offset;
1180 return attr;
1183 /* build GOT and PLT entries */
1184 static void build_got_entries_pass(TCCState *s1, int pass)
1186 Section *s;
1187 ElfW_Rel *rel;
1188 ElfW(Sym) *sym;
1189 int i, type, gotplt_entry, reloc_type, sym_index;
1190 struct sym_attr *attr;
1192 for(i = 1; i < s1->nb_sections; i++) {
1193 s = s1->sections[i];
1194 if (s->sh_type != SHT_RELX)
1195 continue;
1196 /* no need to handle got relocations */
1197 if (s->link != symtab_section)
1198 continue;
1199 for_each_elem(s, 0, rel, ElfW_Rel) {
1200 type = ELFW(R_TYPE)(rel->r_info);
1201 gotplt_entry = gotplt_entry_type(type);
1202 if (gotplt_entry == -1)
1203 tcc_error ("Unknown relocation type for got: %d", type);
1204 sym_index = ELFW(R_SYM)(rel->r_info);
1205 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1207 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1208 continue;
1211 /* Automatically create PLT/GOT [entry] if it is an undefined
1212 reference (resolved at runtime), or the symbol is absolute,
1213 probably created by tcc_add_symbol, and thus on 64-bit
1214 targets might be too far from application code. */
1215 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1216 if (sym->st_shndx == SHN_UNDEF) {
1217 ElfW(Sym) *esym;
1218 int dynindex;
1219 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1220 continue;
1221 /* Relocations for UNDEF symbols would normally need
1222 to be transferred into the executable or shared object.
1223 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1224 But TCC doesn't do that (at least for exes), so we
1225 need to resolve all such relocs locally. And that
1226 means PLT slots for functions in DLLs and COPY relocs for
1227 data symbols. COPY relocs were generated in
1228 bind_exe_dynsyms (and the symbol adjusted to be defined),
1229 and for functions we were generated a dynamic symbol
1230 of function type. */
1231 if (s1->dynsym) {
1232 /* dynsym isn't set for -run :-/ */
1233 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1234 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1235 if (dynindex
1236 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1237 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1238 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1239 goto jmp_slot;
1241 } else if (!(sym->st_shndx == SHN_ABS
1242 #ifndef TCC_TARGET_ARM
1243 && PTR_SIZE == 8
1244 #endif
1246 continue;
1249 #ifdef TCC_TARGET_X86_64
1250 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1251 sym->st_shndx != SHN_UNDEF &&
1252 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1253 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1254 s1->output_type == TCC_OUTPUT_EXE)) {
1255 if (pass == 0)
1256 continue;
1257 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1258 continue;
1260 #endif
1261 reloc_type = code_reloc(type);
1262 if (reloc_type == -1)
1263 tcc_error ("Unknown relocation type: %d", type);
1264 else if (reloc_type != 0) {
1265 jmp_slot:
1266 reloc_type = R_JMP_SLOT;
1267 } else
1268 reloc_type = R_GLOB_DAT;
1271 if ((pass == 0 && reloc_type == R_GLOB_DAT) ||
1272 (pass == 1 && reloc_type == R_JMP_SLOT))
1273 continue;
1275 if (!s1->got)
1276 build_got(s1);
1278 if (gotplt_entry == BUILD_GOT_ONLY)
1279 continue;
1281 attr = put_got_entry(s1, reloc_type, sym_index);
1283 if (reloc_type == R_JMP_SLOT)
1284 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1289 ST_FUNC void build_got_entries(TCCState *s1)
1291 int i;
1293 /* Two passes because R_JMP_SLOT should become first.
1294 Some targets (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1295 for (i = 0; i < 2; i++)
1296 build_got_entries_pass(s1, i);
1298 #endif
1300 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
1302 int shn = sec ? sec->sh_num : offs ? SHN_ABS : SHN_UNDEF;
1303 if (sec && offs == -1)
1304 offs = sec->data_offset;
1305 return set_elf_sym(symtab_section, offs, 0,
1306 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1309 static void add_init_array_defines(TCCState *s1, const char *section_name)
1311 Section *s;
1312 addr_t end_offset;
1313 char buf[1024];
1314 s = find_section(s1, section_name);
1315 if (!s) {
1316 end_offset = 0;
1317 s = data_section;
1318 } else {
1319 end_offset = s->data_offset;
1321 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1322 set_global_sym(s1, buf, s, 0);
1323 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1324 set_global_sym(s1, buf, s, end_offset);
1327 #ifndef TCC_TARGET_PE
1328 static void tcc_add_support(TCCState *s1, const char *filename)
1330 char buf[1024];
1331 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1332 tcc_add_file(s1, buf);
1334 #endif
1336 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1338 Section *s;
1339 s = find_section(s1, sec);
1340 s->sh_flags |= SHF_WRITE;
1341 #ifndef TCC_TARGET_PE
1342 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1343 #endif
1344 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1345 section_ptr_add(s, PTR_SIZE);
1348 #ifdef CONFIG_TCC_BCHECK
1349 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1351 if (0 == s1->do_bounds_check)
1352 return;
1353 section_ptr_add(bounds_section, sizeof(addr_t));
1355 #endif
1357 #ifdef CONFIG_TCC_BACKTRACE
1358 static void put_ptr(TCCState *s1, Section *s, int offs)
1360 int c;
1361 c = set_global_sym(s1, NULL, s, offs);
1362 s = data_section;
1363 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1364 section_ptr_add(s, PTR_SIZE);
1367 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1368 a dynamic symbol to allow so's to have one each with a different value. */
1369 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1371 int c = find_elf_sym(s1->symtab, name);
1372 if (c) {
1373 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1374 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1375 esym->st_value = offset;
1376 esym->st_shndx = s->sh_num;
1380 ST_FUNC void tcc_add_btstub(TCCState *s1)
1382 Section *s;
1383 int n, o;
1384 CString cstr;
1386 s = data_section;
1387 /* Align to PTR_SIZE */
1388 section_ptr_add(s, -s->data_offset & (PTR_SIZE - 1));
1389 o = s->data_offset;
1390 /* create (part of) a struct rt_context (see tccrun.c) */
1391 put_ptr(s1, stab_section, 0);
1392 put_ptr(s1, stab_section, -1);
1393 put_ptr(s1, stab_section->link, 0);
1394 section_ptr_add(s, 3 * PTR_SIZE);
1395 /* prog_base */
1396 #ifndef TCC_TARGET_MACHO
1397 /* XXX this relocation is wrong, it uses sym-index 0 (local,undef) */
1398 put_elf_reloc(s1->symtab, s, s->data_offset, R_DATA_PTR, 0);
1399 #endif
1400 section_ptr_add(s, PTR_SIZE);
1401 n = 2 * PTR_SIZE;
1402 #ifdef CONFIG_TCC_BCHECK
1403 if (s1->do_bounds_check) {
1404 put_ptr(s1, bounds_section, 0);
1405 n -= PTR_SIZE;
1407 #endif
1408 section_ptr_add(s, n);
1410 cstr_new(&cstr);
1411 cstr_printf(&cstr,
1412 " extern void __bt_init(),*__rt_info[],__bt_init_dll();"
1413 "__attribute__((constructor)) static void __bt_init_rt(){");
1414 #ifdef TCC_TARGET_PE
1415 if (s1->output_type == TCC_OUTPUT_DLL)
1416 #ifdef CONFIG_TCC_BCHECK
1417 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1418 #else
1419 cstr_printf(&cstr, "__bt_init_dll(0);");
1420 #endif
1421 #endif
1422 cstr_printf(&cstr, "__bt_init(__rt_info,%d, 0);}",
1423 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1424 tcc_compile_string(s1, cstr.data);
1425 cstr_free(&cstr);
1426 set_local_sym(s1, &"___rt_info"[!s1->leading_underscore], s, o);
1428 #endif
1430 #ifndef TCC_TARGET_PE
1431 /* add tcc runtime libraries */
1432 ST_FUNC void tcc_add_runtime(TCCState *s1)
1434 s1->filetype = 0;
1435 #ifdef CONFIG_TCC_BCHECK
1436 tcc_add_bcheck(s1);
1437 #endif
1438 tcc_add_pragma_libs(s1);
1439 /* add libc */
1440 if (!s1->nostdlib) {
1441 if (s1->option_pthread)
1442 tcc_add_library_err(s1, "pthread");
1443 tcc_add_library_err(s1, "c");
1444 #ifdef TCC_LIBGCC
1445 if (!s1->static_link) {
1446 if (TCC_LIBGCC[0] == '/')
1447 tcc_add_file(s1, TCC_LIBGCC);
1448 else
1449 tcc_add_dll(s1, TCC_LIBGCC, 0);
1451 #endif
1452 #if TCC_TARGET_ARM && TARGETOS_FreeBSD
1453 tcc_add_library_err(s1, "gcc_s"); // unwind code
1454 #endif
1455 #ifdef CONFIG_TCC_BCHECK
1456 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1457 tcc_add_library_err(s1, "pthread");
1458 #if !TARGETOS_OpenBSD && !TARGETOS_NetBSD
1459 tcc_add_library_err(s1, "dl");
1460 #endif
1461 tcc_add_support(s1, "bcheck.o");
1462 if (s1->static_link)
1463 tcc_add_library_err(s1, "c");
1465 #endif
1466 #ifdef CONFIG_TCC_BACKTRACE
1467 if (s1->do_backtrace) {
1468 if (s1->output_type == TCC_OUTPUT_EXE)
1469 tcc_add_support(s1, "bt-exe.o");
1470 if (s1->output_type != TCC_OUTPUT_DLL)
1471 tcc_add_support(s1, "bt-log.o");
1472 if (s1->output_type != TCC_OUTPUT_MEMORY)
1473 tcc_add_btstub(s1);
1475 #endif
1476 if (strlen(TCC_LIBTCC1) > 0)
1477 tcc_add_support(s1, TCC_LIBTCC1);
1478 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
1479 /* add crt end if not memory output */
1480 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1481 if (s1->output_type == TCC_OUTPUT_DLL)
1482 tcc_add_crt(s1, "crtendS.o");
1483 else
1484 tcc_add_crt(s1, "crtend.o");
1485 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
1486 tcc_add_crt(s1, "crtn.o");
1487 #endif
1489 #elif !defined(TCC_TARGET_MACHO)
1490 /* add crt end if not memory output */
1491 if (s1->output_type != TCC_OUTPUT_MEMORY)
1492 tcc_add_crt(s1, "crtn.o");
1493 #endif
1496 #endif
1498 /* add various standard linker symbols (must be done after the
1499 sections are filled (for example after allocating common
1500 symbols)) */
1501 static void tcc_add_linker_symbols(TCCState *s1)
1503 char buf[1024];
1504 int i;
1505 Section *s;
1507 set_global_sym(s1, "_etext", text_section, -1);
1508 set_global_sym(s1, "_edata", data_section, -1);
1509 set_global_sym(s1, "_end", bss_section, -1);
1510 #if TARGETOS_OpenBSD
1511 set_global_sym(s1, "__executable_start", NULL, ELF_START_ADDR);
1512 #endif
1513 #ifdef TCC_TARGET_RISCV64
1514 /* XXX should be .sdata+0x800, not .data+0x800 */
1515 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1516 #endif
1517 /* horrible new standard ldscript defines */
1518 add_init_array_defines(s1, ".preinit_array");
1519 add_init_array_defines(s1, ".init_array");
1520 add_init_array_defines(s1, ".fini_array");
1521 /* add start and stop symbols for sections whose name can be
1522 expressed in C */
1523 for(i = 1; i < s1->nb_sections; i++) {
1524 s = s1->sections[i];
1525 if ((s->sh_flags & SHF_ALLOC)
1526 && (s->sh_type == SHT_PROGBITS
1527 || s->sh_type == SHT_STRTAB)) {
1528 const char *p;
1529 /* check if section name can be expressed in C */
1530 p = s->name;
1531 for(;;) {
1532 int c = *p;
1533 if (!c)
1534 break;
1535 if (!isid(c) && !isnum(c))
1536 goto next_sec;
1537 p++;
1539 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1540 set_global_sym(s1, buf, s, 0);
1541 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1542 set_global_sym(s1, buf, s, -1);
1544 next_sec: ;
1548 ST_FUNC void resolve_common_syms(TCCState *s1)
1550 ElfW(Sym) *sym;
1552 /* Allocate common symbols in BSS. */
1553 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1554 if (sym->st_shndx == SHN_COMMON) {
1555 /* symbol alignment is in st_value for SHN_COMMONs */
1556 sym->st_value = section_add(bss_section, sym->st_size,
1557 sym->st_value);
1558 sym->st_shndx = bss_section->sh_num;
1562 /* Now assign linker provided symbols their value. */
1563 tcc_add_linker_symbols(s1);
1566 #ifndef ELF_OBJ_ONLY
1568 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1570 int sym_index = ELFW(R_SYM) (rel->r_info);
1571 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1572 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1573 unsigned offset = attr->got_offset;
1575 if (0 == offset)
1576 return;
1577 section_reserve(s1->got, offset + PTR_SIZE);
1578 #if PTR_SIZE == 8
1579 write64le(s1->got->data + offset, sym->st_value);
1580 #else
1581 write32le(s1->got->data + offset, sym->st_value);
1582 #endif
1585 /* Perform relocation to GOT or PLT entries */
1586 ST_FUNC void fill_got(TCCState *s1)
1588 Section *s;
1589 ElfW_Rel *rel;
1590 int i;
1592 for(i = 1; i < s1->nb_sections; i++) {
1593 s = s1->sections[i];
1594 if (s->sh_type != SHT_RELX)
1595 continue;
1596 /* no need to handle got relocations */
1597 if (s->link != symtab_section)
1598 continue;
1599 for_each_elem(s, 0, rel, ElfW_Rel) {
1600 switch (ELFW(R_TYPE) (rel->r_info)) {
1601 case R_X86_64_GOT32:
1602 case R_X86_64_GOTPCREL:
1603 case R_X86_64_GOTPCRELX:
1604 case R_X86_64_REX_GOTPCRELX:
1605 case R_X86_64_PLT32:
1606 fill_got_entry(s1, rel);
1607 break;
1613 /* See put_got_entry for a description. This is the second stage
1614 where GOT references to local defined symbols are rewritten. */
1615 static void fill_local_got_entries(TCCState *s1)
1617 ElfW_Rel *rel;
1618 if (!s1->got->reloc)
1619 return;
1620 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1621 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1622 int sym_index = ELFW(R_SYM) (rel->r_info);
1623 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1624 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1625 unsigned offset = attr->got_offset;
1626 if (offset != rel->r_offset - s1->got->sh_addr)
1627 tcc_error_noabort("huh");
1628 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1629 #if SHT_RELX == SHT_RELA
1630 rel->r_addend = sym->st_value;
1631 #else
1632 /* All our REL architectures also happen to be 32bit LE. */
1633 write32le(s1->got->data + offset, sym->st_value);
1634 #endif
1639 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1640 in shared libraries and export non local defined symbols to shared libraries
1641 if -rdynamic switch was given on command line */
1642 static void bind_exe_dynsyms(TCCState *s1)
1644 const char *name;
1645 int sym_index, index;
1646 ElfW(Sym) *sym, *esym;
1647 int type;
1649 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1650 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1651 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1652 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1653 if (sym->st_shndx == SHN_UNDEF) {
1654 name = (char *) symtab_section->link->data + sym->st_name;
1655 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1656 if (sym_index) {
1657 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1658 type = ELFW(ST_TYPE)(esym->st_info);
1659 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1660 /* Indirect functions shall have STT_FUNC type in executable
1661 * dynsym section. Indeed, a dlsym call following a lazy
1662 * resolution would pick the symbol value from the
1663 * executable dynsym entry which would contain the address
1664 * of the function wanted by the caller of dlsym instead of
1665 * the address of the function that would return that
1666 * address */
1667 int dynindex
1668 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1669 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1670 name);
1671 int index = sym - (ElfW(Sym) *) symtab_section->data;
1672 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1673 } else if (type == STT_OBJECT) {
1674 unsigned long offset;
1675 ElfW(Sym) *dynsym;
1676 offset = bss_section->data_offset;
1677 /* XXX: which alignment ? */
1678 offset = (offset + 16 - 1) & -16;
1679 set_elf_sym (s1->symtab, offset, esym->st_size,
1680 esym->st_info, 0, bss_section->sh_num, name);
1681 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1682 esym->st_info, 0, bss_section->sh_num,
1683 name);
1685 /* Ensure R_COPY works for weak symbol aliases */
1686 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1687 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1688 if ((dynsym->st_value == esym->st_value)
1689 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1690 char *dynname = (char *) s1->dynsymtab_section->link->data
1691 + dynsym->st_name;
1692 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1693 dynsym->st_info, 0,
1694 bss_section->sh_num, dynname);
1695 break;
1700 put_elf_reloc(s1->dynsym, bss_section,
1701 offset, R_COPY, index);
1702 offset += esym->st_size;
1703 bss_section->data_offset = offset;
1705 } else {
1706 /* STB_WEAK undefined symbols are accepted */
1707 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1708 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1709 !strcmp(name, "_fp_hw")) {
1710 } else {
1711 tcc_error_noabort("undefined symbol '%s'", name);
1714 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1715 /* if -rdynamic option, then export all non local symbols */
1716 name = (char *) symtab_section->link->data + sym->st_name;
1717 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1718 0, sym->st_shndx, name);
1723 /* Bind symbols of libraries: export all non local symbols of executable that
1724 are referenced by shared libraries. The reason is that the dynamic loader
1725 search symbol first in executable and then in libraries. Therefore a
1726 reference to a symbol already defined by a library can still be resolved by
1727 a symbol in the executable. */
1728 static void bind_libs_dynsyms(TCCState *s1)
1730 const char *name;
1731 int sym_index;
1732 ElfW(Sym) *sym, *esym;
1734 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1735 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1736 sym_index = find_elf_sym(symtab_section, name);
1737 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1738 if (sym_index && sym->st_shndx != SHN_UNDEF
1739 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1740 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1741 sym->st_info, 0, sym->st_shndx, name);
1742 } else if (esym->st_shndx == SHN_UNDEF) {
1743 /* weak symbols can stay undefined */
1744 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1745 tcc_warning("undefined dynamic symbol '%s'", name);
1750 /* Export all non local symbols. This is used by shared libraries so that the
1751 non local symbols they define can resolve a reference in another shared
1752 library or in the executable. Correspondingly, it allows undefined local
1753 symbols to be resolved by other shared libraries or by the executable. */
1754 static void export_global_syms(TCCState *s1)
1756 int dynindex, index;
1757 const char *name;
1758 ElfW(Sym) *sym;
1760 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1761 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1762 name = (char *) symtab_section->link->data + sym->st_name;
1763 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1764 sym->st_info, 0, sym->st_shndx, name);
1765 index = sym - (ElfW(Sym) *) symtab_section->data;
1766 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1771 /* decide if an unallocated section should be output. */
1772 static int set_sec_sizes(TCCState *s1)
1774 int i;
1775 Section *s;
1776 int textrel = 0;
1777 int file_type = s1->output_type;
1779 /* Allocate strings for section names */
1780 for(i = 1; i < s1->nb_sections; i++) {
1781 s = s1->sections[i];
1782 if (s->sh_type == SHT_RELX && !(s->sh_flags & SHF_ALLOC)) {
1783 /* when generating a DLL, we include relocations but
1784 we may patch them */
1785 if (file_type == TCC_OUTPUT_DLL
1786 && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) {
1787 int count = prepare_dynamic_rel(s1, s);
1788 if (count) {
1789 /* allocate the section */
1790 s->sh_flags |= SHF_ALLOC;
1791 s->sh_size = count * sizeof(ElfW_Rel);
1792 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1793 textrel = 1;
1796 } else if ((s->sh_flags & SHF_ALLOC)
1797 #ifdef TCC_TARGET_ARM
1798 || s->sh_type == SHT_ARM_ATTRIBUTES
1799 #endif
1800 || s1->do_debug) {
1801 s->sh_size = s->data_offset;
1804 #ifdef TCC_TARGET_ARM
1805 /* XXX: Suppress stack unwinding section. */
1806 if (s->sh_type == SHT_ARM_EXIDX) {
1807 s->sh_flags = 0;
1808 s->sh_size = 0;
1810 #endif
1813 return textrel;
1817 /* Info to be copied in dynamic section */
1818 struct dyn_inf {
1819 Section *dynamic;
1820 Section *dynstr;
1821 unsigned long data_offset;
1822 addr_t rel_addr;
1823 addr_t rel_size;
1826 /* Info for GNU_RELRO */
1827 struct ro_inf {
1828 addr_t sh_offset;
1829 addr_t sh_addr;
1830 addr_t sh_size;
1833 static void alloc_sec_names(
1834 TCCState *s1, int is_obj
1837 static int layout_any_sections(
1838 TCCState *s1, int file_offset, int *sec_order, int is_obj
1841 /* Assign sections to segments and decide how are sections laid out when loaded
1842 in memory. This function also fills corresponding program headers. */
1843 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr,
1844 int phnum, int phfill,
1845 Section *interp,
1846 struct ro_inf *roinf, int *sec_order)
1848 int i, file_offset;
1849 Section *s;
1851 file_offset = 0;
1852 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1853 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1856 unsigned long s_align;
1857 long long tmp;
1858 addr_t addr;
1859 ElfW(Phdr) *ph;
1860 int j, k, f, file_type = s1->output_type;
1862 s_align = ELF_PAGE_SIZE;
1863 if (s1->section_align)
1864 s_align = s1->section_align;
1866 if (s1->has_text_addr) {
1867 int a_offset, p_offset;
1868 addr = s1->text_addr;
1869 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1870 ELF_PAGE_SIZE */
1871 a_offset = (int) (addr & (s_align - 1));
1872 p_offset = file_offset & (s_align - 1);
1873 if (a_offset < p_offset)
1874 a_offset += s_align;
1875 file_offset += (a_offset - p_offset);
1876 } else {
1877 if (file_type == TCC_OUTPUT_DLL)
1878 addr = 0;
1879 else
1880 addr = ELF_START_ADDR;
1881 /* compute address after headers */
1882 addr += (file_offset & (s_align - 1));
1885 ph = &phdr[0];
1886 /* Leave one program headers for the program interpreter and one for
1887 the program header table itself if needed. These are done later as
1888 they require section layout to be done first. */
1889 if (interp)
1890 ph += 2;
1892 /* read only segment mapping for GNU_RELRO */
1893 roinf->sh_offset = roinf->sh_addr = roinf->sh_size = 0;
1895 for(j = 0; j < phfill; j++) {
1896 Section *relocplt = s1->got ? s1->got->relocplt : NULL;
1898 ph->p_type = j == 2 ? PT_TLS : PT_LOAD;
1899 if (j == 0)
1900 ph->p_flags = PF_R | PF_X;
1901 else
1902 ph->p_flags = PF_R | PF_W;
1903 ph->p_align = j == 2 ? 4 : s_align;
1905 /* Decide the layout of sections loaded in memory. This must
1906 be done before program headers are filled since they contain
1907 info about the layout. We do the following ordering: interp,
1908 symbol tables, relocations, progbits, nobits */
1909 /* XXX: do faster and simpler sorting */
1910 f = -1;
1911 for(k = 0; k < 7; k++) {
1912 for(i = 1; i < s1->nb_sections; i++) {
1913 s = s1->sections[i];
1914 /* compute if section should be included */
1915 if (j == 0) {
1916 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1917 SHF_ALLOC)
1918 continue;
1919 } else if (j == 1) {
1920 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1921 (SHF_ALLOC | SHF_WRITE))
1922 continue;
1923 } else {
1924 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1925 (SHF_ALLOC | SHF_WRITE | SHF_TLS))
1926 continue;
1928 if (s == interp) {
1929 if (k != 0)
1930 continue;
1931 } else if ((s->sh_type == SHT_DYNSYM ||
1932 s->sh_type == SHT_STRTAB ||
1933 s->sh_type == SHT_HASH)
1934 && !strstr(s->name, ".stab")) {
1935 if (k != 1)
1936 continue;
1937 } else if (s->sh_type == SHT_RELX) {
1938 if (k != 2 && s != relocplt)
1939 continue;
1940 else if (k != 3 && s == relocplt)
1941 continue;
1942 } else if (s->sh_type == SHT_NOBITS) {
1943 if (k != 6)
1944 continue;
1945 } else if (s == data_ro_section ||
1946 #ifdef CONFIG_TCC_BCHECK
1947 s == bounds_section ||
1948 s == lbounds_section ||
1949 #endif
1950 0) {
1951 if (k != 4)
1952 continue;
1953 /* Align next section on page size.
1954 This is needed to remap roinf section ro. */
1955 f = 1;
1956 } else {
1957 if (k != 5)
1958 continue;
1960 *sec_order++ = i;
1962 /* section matches: we align it and add its size */
1963 tmp = addr;
1964 if (f-- == 0)
1965 s->sh_addralign = PAGESIZE;
1966 addr = (addr + s->sh_addralign - 1) &
1967 ~(s->sh_addralign - 1);
1968 file_offset += (int) ( addr - tmp );
1969 s->sh_offset = file_offset;
1970 s->sh_addr = addr;
1972 /* update program header infos */
1973 if (ph->p_offset == 0) {
1974 ph->p_offset = file_offset;
1975 ph->p_vaddr = addr;
1976 ph->p_paddr = ph->p_vaddr;
1978 if (s == data_ro_section ||
1979 #ifdef CONFIG_TCC_BCHECK
1980 s == bounds_section ||
1981 s == lbounds_section ||
1982 #endif
1983 0) {
1984 if (roinf->sh_size == 0) {
1985 roinf->sh_offset = s->sh_offset;
1986 roinf->sh_addr = s->sh_addr;
1988 roinf->sh_size = (addr - roinf->sh_addr) + s->sh_size;
1990 addr += s->sh_size;
1991 if (s->sh_type != SHT_NOBITS)
1992 file_offset += s->sh_size;
1995 if (j == 0) {
1996 /* Make the first PT_LOAD segment include the program
1997 headers itself (and the ELF header as well), it'll
1998 come out with same memory use but will make various
1999 tools like binutils strip work better. */
2000 ph->p_offset &= ~(ph->p_align - 1);
2001 ph->p_vaddr &= ~(ph->p_align - 1);
2002 ph->p_paddr &= ~(ph->p_align - 1);
2004 ph->p_filesz = file_offset - ph->p_offset;
2005 ph->p_memsz = addr - ph->p_vaddr;
2006 ph++;
2007 if (j == 0) {
2008 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
2009 /* if in the middle of a page, we duplicate the page in
2010 memory so that one copy is RX and the other is RW */
2011 if ((addr & (s_align - 1)) != 0)
2012 addr += s_align;
2013 } else {
2014 addr = (addr + s_align - 1) & ~(s_align - 1);
2015 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
2021 /* all other sections come after */
2022 return layout_any_sections(s1, file_offset, sec_order, 0);
2025 /* put dynamic tag */
2026 static void put_dt(Section *dynamic, int dt, addr_t val)
2028 ElfW(Dyn) *dyn;
2029 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
2030 dyn->d_tag = dt;
2031 dyn->d_un.d_val = val;
2034 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
2035 Section *dynamic, Section *note, struct ro_inf *roinf)
2037 ElfW(Phdr) *ph;
2039 /* if interpreter, then add corresponding program header */
2040 if (interp) {
2041 ph = &phdr[0];
2043 ph->p_type = PT_PHDR;
2044 ph->p_offset = sizeof(ElfW(Ehdr));
2045 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
2046 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
2047 ph->p_paddr = ph->p_vaddr;
2048 ph->p_flags = PF_R | PF_X;
2049 ph->p_align = 4; /* interp->sh_addralign; */
2050 ph++;
2052 ph->p_type = PT_INTERP;
2053 ph->p_offset = interp->sh_offset;
2054 ph->p_vaddr = interp->sh_addr;
2055 ph->p_paddr = ph->p_vaddr;
2056 ph->p_filesz = interp->sh_size;
2057 ph->p_memsz = interp->sh_size;
2058 ph->p_flags = PF_R;
2059 ph->p_align = interp->sh_addralign;
2062 if (note) {
2063 ph = &phdr[phnum - 2 - (roinf != NULL)];
2065 ph->p_type = PT_NOTE;
2066 ph->p_offset = note->sh_offset;
2067 ph->p_vaddr = note->sh_addr;
2068 ph->p_paddr = ph->p_vaddr;
2069 ph->p_filesz = note->sh_size;
2070 ph->p_memsz = note->sh_size;
2071 ph->p_flags = PF_R;
2072 ph->p_align = note->sh_addralign;
2075 /* if dynamic section, then add corresponding program header */
2076 if (dynamic) {
2077 ph = &phdr[phnum - 1 - (roinf != NULL)];
2079 ph->p_type = PT_DYNAMIC;
2080 ph->p_offset = dynamic->sh_offset;
2081 ph->p_vaddr = dynamic->sh_addr;
2082 ph->p_paddr = ph->p_vaddr;
2083 ph->p_filesz = dynamic->sh_size;
2084 ph->p_memsz = dynamic->sh_size;
2085 ph->p_flags = PF_R | PF_W;
2086 ph->p_align = dynamic->sh_addralign;
2089 if (roinf) {
2090 ph = &phdr[phnum - 1];
2092 ph->p_type = PT_GNU_RELRO;
2093 ph->p_offset = roinf->sh_offset;
2094 ph->p_vaddr = roinf->sh_addr;
2095 ph->p_paddr = ph->p_vaddr;
2096 ph->p_filesz = roinf->sh_size;
2097 ph->p_memsz = roinf->sh_size;
2098 ph->p_flags = PF_R;
2099 ph->p_align = 1;
2103 /* Fill the dynamic section with tags describing the address and size of
2104 sections */
2105 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2107 Section *dynamic = dyninf->dynamic;
2108 Section *s;
2110 /* put dynamic section entries */
2111 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2112 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2113 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2114 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2115 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2116 #if PTR_SIZE == 8
2117 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2118 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2119 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2120 if (s1->got && s1->got->relocplt) {
2121 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2122 put_dt(dynamic, DT_PLTRELSZ, s1->got->relocplt->data_offset);
2123 put_dt(dynamic, DT_JMPREL, s1->got->relocplt->sh_addr);
2124 put_dt(dynamic, DT_PLTREL, DT_RELA);
2126 put_dt(dynamic, DT_RELACOUNT, 0);
2127 #else
2128 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2129 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2130 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2131 if (s1->got && s1->got->relocplt) {
2132 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2133 put_dt(dynamic, DT_PLTRELSZ, s1->got->relocplt->data_offset);
2134 put_dt(dynamic, DT_JMPREL, s1->got->relocplt->sh_addr);
2135 put_dt(dynamic, DT_PLTREL, DT_REL);
2137 put_dt(dynamic, DT_RELCOUNT, 0);
2138 #endif
2139 if (versym_section && verneed_section) {
2140 /* The dynamic linker can not handle VERSYM without VERNEED */
2141 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2142 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2143 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2145 s = find_section_create (s1, ".preinit_array", 0);
2146 if (s && s->data_offset) {
2147 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2148 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2150 s = find_section_create (s1, ".init_array", 0);
2151 if (s && s->data_offset) {
2152 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2153 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2155 s = find_section_create (s1, ".fini_array", 0);
2156 if (s && s->data_offset) {
2157 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2158 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2160 s = find_section_create (s1, ".init", 0);
2161 if (s && s->data_offset) {
2162 put_dt(dynamic, DT_INIT, s->sh_addr);
2164 s = find_section_create (s1, ".fini", 0);
2165 if (s && s->data_offset) {
2166 put_dt(dynamic, DT_FINI, s->sh_addr);
2168 if (s1->do_debug)
2169 put_dt(dynamic, DT_DEBUG, 0);
2170 put_dt(dynamic, DT_NULL, 0);
2173 /* Relocate remaining sections and symbols (that is those not related to
2174 dynamic linking) */
2175 static int final_sections_reloc(TCCState *s1)
2177 int i;
2178 Section *s;
2180 relocate_syms(s1, s1->symtab, 0);
2182 if (s1->nb_errors != 0)
2183 return -1;
2185 /* relocate sections */
2186 /* XXX: ignore sections with allocated relocations ? */
2187 for(i = 1; i < s1->nb_sections; i++) {
2188 s = s1->sections[i];
2189 if (s->reloc && (s != s1->got || s1->static_link))
2190 relocate_section(s1, s);
2193 /* relocate relocation entries if the relocation tables are
2194 allocated in the executable */
2195 for(i = 1; i < s1->nb_sections; i++) {
2196 s = s1->sections[i];
2197 if ((s->sh_flags & SHF_ALLOC) &&
2198 s->sh_type == SHT_RELX) {
2199 relocate_rel(s1, s);
2202 return 0;
2205 /* Remove gaps between RELX sections.
2206 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2207 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2208 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2209 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2210 static void update_reloc_sections(TCCState *s1, struct dyn_inf *dyninf)
2212 int i;
2213 unsigned long file_offset = 0;
2214 Section *s;
2215 Section *relocplt = s1->got ? s1->got->relocplt : NULL;
2217 /* dynamic relocation table information, for .dynamic section */
2218 dyninf->rel_addr = dyninf->rel_size = 0;
2220 for(i = 1; i < s1->nb_sections; i++) {
2221 s = s1->sections[i];
2222 if (s->sh_type == SHT_RELX && s != relocplt) {
2223 if (dyninf->rel_size == 0) {
2224 dyninf->rel_addr = s->sh_addr;
2225 file_offset = s->sh_offset;
2227 else {
2228 s->sh_addr = dyninf->rel_addr + dyninf->rel_size;
2229 s->sh_offset = file_offset + dyninf->rel_size;
2231 dyninf->rel_size += s->sh_size;
2236 #endif /* ndef ELF_OBJ_ONLY */
2238 /* Create an ELF file on disk.
2239 This function handle ELF specific layout requirements */
2240 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2241 int file_offset, int *sec_order)
2243 int i, shnum, offset, size, file_type;
2244 Section *s;
2245 ElfW(Ehdr) ehdr;
2246 ElfW(Shdr) shdr, *sh;
2248 file_type = s1->output_type;
2249 shnum = s1->nb_sections;
2251 memset(&ehdr, 0, sizeof(ehdr));
2253 if (phnum > 0) {
2254 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2255 ehdr.e_phnum = phnum;
2256 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2259 /* align to 4 */
2260 file_offset = (file_offset + 3) & -4;
2262 /* fill header */
2263 ehdr.e_ident[0] = ELFMAG0;
2264 ehdr.e_ident[1] = ELFMAG1;
2265 ehdr.e_ident[2] = ELFMAG2;
2266 ehdr.e_ident[3] = ELFMAG3;
2267 ehdr.e_ident[4] = ELFCLASSW;
2268 ehdr.e_ident[5] = ELFDATA2LSB;
2269 ehdr.e_ident[6] = EV_CURRENT;
2270 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2271 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2272 #endif
2273 #ifdef TCC_TARGET_ARM
2274 #ifdef TCC_ARM_EABI
2275 ehdr.e_ident[EI_OSABI] = 0;
2276 ehdr.e_flags = EF_ARM_EABI_VER4;
2277 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2278 ehdr.e_flags |= EF_ARM_HASENTRY;
2279 if (s1->float_abi == ARM_HARD_FLOAT)
2280 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2281 else
2282 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2283 #else
2284 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2285 #endif
2286 #elif defined TCC_TARGET_RISCV64
2287 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2288 #endif
2289 switch(file_type) {
2290 default:
2291 case TCC_OUTPUT_EXE:
2292 ehdr.e_type = ET_EXEC;
2293 ehdr.e_entry = get_sym_addr(s1, "_start", 1, 0);
2294 break;
2295 case TCC_OUTPUT_DLL:
2296 ehdr.e_type = ET_DYN;
2297 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2298 break;
2299 case TCC_OUTPUT_OBJ:
2300 ehdr.e_type = ET_REL;
2301 break;
2303 ehdr.e_machine = EM_TCC_TARGET;
2304 ehdr.e_version = EV_CURRENT;
2305 ehdr.e_shoff = file_offset;
2306 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2307 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2308 ehdr.e_shnum = shnum;
2309 ehdr.e_shstrndx = shnum - 1;
2311 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2312 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2313 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2315 sort_syms(s1, symtab_section);
2316 for(i = 1; i < s1->nb_sections; i++) {
2317 s = s1->sections[sec_order[i]];
2318 if (s->sh_type != SHT_NOBITS) {
2319 while (offset < s->sh_offset) {
2320 fputc(0, f);
2321 offset++;
2323 size = s->sh_size;
2324 if (size)
2325 fwrite(s->data, 1, size, f);
2326 offset += size;
2330 /* output section headers */
2331 while (offset < ehdr.e_shoff) {
2332 fputc(0, f);
2333 offset++;
2336 for(i = 0; i < s1->nb_sections; i++) {
2337 sh = &shdr;
2338 memset(sh, 0, sizeof(ElfW(Shdr)));
2339 s = s1->sections[i];
2340 if (s) {
2341 sh->sh_name = s->sh_name;
2342 sh->sh_type = s->sh_type;
2343 sh->sh_flags = s->sh_flags;
2344 sh->sh_entsize = s->sh_entsize;
2345 sh->sh_info = s->sh_info;
2346 if (s->link)
2347 sh->sh_link = s->link->sh_num;
2348 sh->sh_addralign = s->sh_addralign;
2349 sh->sh_addr = s->sh_addr;
2350 sh->sh_offset = s->sh_offset;
2351 sh->sh_size = s->sh_size;
2353 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2357 static void tcc_output_binary(TCCState *s1, FILE *f,
2358 const int *sec_order)
2360 Section *s;
2361 int i, offset, size;
2363 offset = 0;
2364 for(i=1;i<s1->nb_sections;i++) {
2365 s = s1->sections[sec_order[i]];
2366 if (s->sh_type != SHT_NOBITS &&
2367 (s->sh_flags & SHF_ALLOC)) {
2368 while (offset < s->sh_offset) {
2369 fputc(0, f);
2370 offset++;
2372 size = s->sh_size;
2373 fwrite(s->data, 1, size, f);
2374 offset += size;
2379 /* Write an elf, coff or "binary" file */
2380 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2381 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2383 int fd, mode, file_type;
2384 FILE *f;
2386 file_type = s1->output_type;
2387 if (file_type == TCC_OUTPUT_OBJ)
2388 mode = 0666;
2389 else
2390 mode = 0777;
2391 unlink(filename);
2392 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2393 if (fd < 0) {
2394 tcc_error_noabort("could not write '%s'", filename);
2395 return -1;
2397 f = fdopen(fd, "wb");
2398 if (s1->verbose)
2399 printf("<- %s\n", filename);
2401 #ifdef TCC_TARGET_COFF
2402 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2403 tcc_output_coff(s1, f);
2404 else
2405 #endif
2406 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2407 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2408 else
2409 tcc_output_binary(s1, f, sec_order);
2410 fclose(f);
2412 return 0;
2415 #ifndef ELF_OBJ_ONLY
2416 /* Sort section headers by assigned sh_addr, remove sections
2417 that we aren't going to output. */
2418 static void tidy_section_headers(TCCState *s1, int *sec_order)
2420 int i, nnew, l, *backmap;
2421 Section **snew, *s;
2422 ElfW(Sym) *sym;
2424 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2425 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2426 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2427 s = s1->sections[sec_order[i]];
2428 if (!i || s->sh_name) {
2429 backmap[sec_order[i]] = nnew;
2430 snew[nnew] = s;
2431 ++nnew;
2432 } else {
2433 backmap[sec_order[i]] = 0;
2434 snew[--l] = s;
2437 for (i = 0; i < nnew; i++) {
2438 s = snew[i];
2439 if (s) {
2440 s->sh_num = i;
2441 if (s->sh_type == SHT_RELX)
2442 s->sh_info = backmap[s->sh_info];
2446 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2447 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2448 sym->st_shndx = backmap[sym->st_shndx];
2449 if ( !s1->static_link ) {
2450 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2451 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2452 sym->st_shndx = backmap[sym->st_shndx];
2454 for (i = 0; i < s1->nb_sections; i++)
2455 sec_order[i] = i;
2456 tcc_free(s1->sections);
2457 s1->sections = snew;
2458 s1->nb_sections = nnew;
2459 tcc_free(backmap);
2462 #ifdef TCC_TARGET_ARM
2463 static void create_arm_attribute_section(TCCState *s1)
2465 // Needed for DLL support.
2466 static const unsigned char arm_attr[] = {
2467 0x41, // 'A'
2468 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2469 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2470 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2471 0x05, 0x36, 0x00, // 'CPU_name', "6"
2472 0x06, 0x06, // 'CPU_arch', 'v6'
2473 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2474 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2475 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2476 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2477 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2478 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2479 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2480 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2481 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2482 0x1a, 0x02, // 'ABI_enum_size', 'int'
2483 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2484 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2486 Section *attr = new_section(s1, ".ARM.attributes", SHT_ARM_ATTRIBUTES, 0);
2487 unsigned char *ptr = section_ptr_add(attr, sizeof(arm_attr));
2488 attr->sh_addralign = 1;
2489 memcpy(ptr, arm_attr, sizeof(arm_attr));
2490 if (s1->float_abi != ARM_HARD_FLOAT) {
2491 ptr[26] = 0x00; // 'FP_arch', 'No'
2492 ptr[41] = 0x1e; // 'ABI_optimization_goals'
2493 ptr[42] = 0x06; // 'Aggressive Debug'
2496 #endif
2498 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2499 static Section *create_bsd_note_section(TCCState *s1,
2500 const char *name,
2501 const char *value)
2503 Section *s = find_section (s1, name);
2505 if (s->data_offset == 0) {
2506 char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
2507 ElfW(Nhdr) *note = (ElfW(Nhdr) *) ptr;
2509 s->sh_type = SHT_NOTE;
2510 note->n_namesz = 8;
2511 note->n_descsz = 4;
2512 note->n_type = ELF_NOTE_OS_GNU;
2513 strcpy (ptr + sizeof(ElfW(Nhdr)), value);
2515 return s;
2517 #endif
2519 /* Output an elf, coff or binary file */
2520 /* XXX: suppress unneeded sections */
2521 static int elf_output_file(TCCState *s1, const char *filename)
2523 int i, ret, phnum, phfill, shnum, file_type, file_offset, *sec_order;
2524 struct dyn_inf dyninf = {0};
2525 struct ro_inf roinf;
2526 ElfW(Phdr) *phdr;
2527 Section *interp, *dynamic, *dynstr, *note;
2528 struct ro_inf *roinf_use = NULL;
2529 int textrel;
2531 file_type = s1->output_type;
2532 s1->nb_errors = 0;
2533 ret = -1;
2534 phdr = NULL;
2535 sec_order = NULL;
2536 interp = dynamic = dynstr = note = NULL;
2538 #ifdef TCC_TARGET_ARM
2539 create_arm_attribute_section (s1);
2540 #endif
2542 #if TARGETOS_OpenBSD
2543 note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
2544 #endif
2546 #if TARGETOS_NetBSD
2547 note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD");
2548 #endif
2551 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2552 tcc_add_runtime(s1);
2553 resolve_common_syms(s1);
2555 if (!s1->static_link) {
2556 if (file_type == TCC_OUTPUT_EXE) {
2557 char *ptr;
2558 /* allow override the dynamic loader */
2559 const char *elfint = getenv("LD_SO");
2560 if (elfint == NULL)
2561 elfint = DEFAULT_ELFINTERP(s1);
2562 /* add interpreter section only if executable */
2563 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2564 interp->sh_addralign = 1;
2565 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2566 strcpy(ptr, elfint);
2569 /* add dynamic symbol table */
2570 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2571 ".dynstr",
2572 ".hash", SHF_ALLOC);
2573 /* Number of local symbols (readelf complains if not set) */
2574 s1->dynsym->sh_info = 1;
2575 dynstr = s1->dynsym->link;
2576 /* add dynamic section */
2577 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2578 SHF_ALLOC | SHF_WRITE);
2579 dynamic->link = dynstr;
2580 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2582 build_got(s1);
2584 if (file_type == TCC_OUTPUT_EXE) {
2585 bind_exe_dynsyms(s1);
2586 if (s1->nb_errors)
2587 goto the_end;
2588 bind_libs_dynsyms(s1);
2589 } else {
2590 /* shared library case: simply export all global symbols */
2591 export_global_syms(s1);
2594 build_got_entries(s1);
2595 version_add (s1);
2598 textrel = set_sec_sizes(s1);
2599 alloc_sec_names(s1, 0);
2601 if (!s1->static_link) {
2602 int i;
2603 /* add a list of needed dlls */
2604 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2605 DLLReference *dllref = s1->loaded_dlls[i];
2606 if (dllref->level == 0)
2607 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2610 if (s1->rpath)
2611 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2612 put_elf_str(dynstr, s1->rpath));
2614 if (file_type == TCC_OUTPUT_DLL) {
2615 if (s1->soname)
2616 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2617 /* XXX: currently, since we do not handle PIC code, we
2618 must relocate the readonly segments */
2619 if (textrel)
2620 put_dt(dynamic, DT_TEXTREL, 0);
2623 if (s1->symbolic)
2624 put_dt(dynamic, DT_SYMBOLIC, 0);
2626 dyninf.dynamic = dynamic;
2627 dyninf.dynstr = dynstr;
2628 /* remember offset and reserve space for 2nd call below */
2629 dyninf.data_offset = dynamic->data_offset;
2630 fill_dynamic(s1, &dyninf);
2631 dynamic->sh_size = dynamic->data_offset;
2632 dynstr->sh_size = dynstr->data_offset;
2635 for (i = 1; i < s1->nb_sections &&
2636 !(s1->sections[i]->sh_flags & SHF_TLS); i++);
2637 phfill = 2 + (i < s1->nb_sections);
2639 /* compute number of program headers */
2640 if (file_type == TCC_OUTPUT_DLL)
2641 phnum = 3;
2642 else if (s1->static_link)
2643 phnum = 3;
2644 else {
2645 phnum = 5 + (i < s1->nb_sections);
2648 phnum += note != NULL;
2649 #if !TARGETOS_FreeBSD && !TARGETOS_NetBSD
2650 /* GNU_RELRO */
2651 phnum++, roinf_use = &roinf;
2652 #endif
2654 /* allocate program segment headers */
2655 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2656 /* compute number of sections */
2657 shnum = s1->nb_sections;
2658 /* this array is used to reorder sections in the output file */
2659 sec_order = tcc_malloc(sizeof(int) * shnum);
2660 sec_order[0] = 0;
2662 /* compute section to program header mapping */
2663 file_offset = layout_sections(s1, phdr, phnum, phfill, interp, &roinf, sec_order + 1);
2665 /* Fill remaining program header and finalize relocation related to dynamic
2666 linking. */
2668 fill_unloadable_phdr(phdr, phnum, interp, dynamic, note, roinf_use);
2669 if (dynamic) {
2670 ElfW(Sym) *sym;
2672 /* put in GOT the dynamic section address and relocate PLT */
2673 write32le(s1->got->data, dynamic->sh_addr);
2674 if (file_type == TCC_OUTPUT_EXE
2675 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2676 relocate_plt(s1);
2678 /* relocate symbols in .dynsym now that final addresses are known */
2679 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2680 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2681 /* do symbol relocation */
2682 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2687 /* if building executable or DLL, then relocate each section
2688 except the GOT which is already relocated */
2689 ret = final_sections_reloc(s1);
2690 if (ret)
2691 goto the_end;
2692 if (dynamic) {
2693 update_reloc_sections (s1, &dyninf);
2694 dynamic->data_offset = dyninf.data_offset;
2695 fill_dynamic(s1, &dyninf);
2697 tidy_section_headers(s1, sec_order);
2699 /* Perform relocation to GOT or PLT entries */
2700 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2701 fill_got(s1);
2702 else if (s1->got)
2703 fill_local_got_entries(s1);
2705 /* Create the ELF file with name 'filename' */
2706 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2707 s1->nb_sections = shnum;
2709 the_end:
2710 tcc_free(sec_order);
2711 tcc_free(phdr);
2712 return ret;
2714 #endif /* ndef ELF_OBJ_ONLY */
2716 /* Allocate strings for section names */
2717 static void alloc_sec_names(TCCState *s1, int is_obj)
2719 int i;
2720 Section *s, *strsec;
2722 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2723 put_elf_str(strsec, "");
2724 for(i = 1; i < s1->nb_sections; i++) {
2725 s = s1->sections[i];
2726 if (is_obj)
2727 s->sh_size = s->data_offset;
2728 if (s == strsec || s->sh_size || (s->sh_flags & SHF_ALLOC))
2729 s->sh_name = put_elf_str(strsec, s->name);
2731 strsec->sh_size = strsec->data_offset;
2734 static int layout_any_sections(TCCState *s1, int file_offset, int *sec_order, int is_obj)
2736 int i;
2737 Section *s;
2738 for(i = 1; i < s1->nb_sections; i++) {
2739 s = s1->sections[i];
2740 if (!is_obj && (s->sh_flags & SHF_ALLOC))
2741 continue;
2742 *sec_order++ = i;
2743 file_offset = (file_offset + s->sh_addralign - 1) &
2744 ~(s->sh_addralign - 1);
2745 s->sh_offset = file_offset;
2746 if (s->sh_type != SHT_NOBITS)
2747 file_offset += s->sh_size;
2749 return file_offset;
2752 /* Output an elf .o file */
2753 static int elf_output_obj(TCCState *s1, const char *filename)
2755 int ret, file_offset;
2756 int *sec_order;
2757 s1->nb_errors = 0;
2759 /* Allocate strings for section names */
2760 alloc_sec_names(s1, 1);
2762 /* this array is used to reorder sections in the output file */
2763 sec_order = tcc_malloc(sizeof(int) * s1->nb_sections);
2764 sec_order[0] = 0;
2765 file_offset = layout_any_sections(s1, sizeof (ElfW(Ehdr)), sec_order + 1, 1);
2767 /* Create the ELF file with name 'filename' */
2768 ret = tcc_write_elf_file(s1, filename, 0, NULL, file_offset, sec_order);
2769 tcc_free(sec_order);
2770 return ret;
2773 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2775 if (s->output_type == TCC_OUTPUT_OBJ)
2776 return elf_output_obj(s, filename);
2777 #ifdef TCC_TARGET_PE
2778 return pe_output_file(s, filename);
2779 #elif TCC_TARGET_MACHO
2780 return macho_output_file(s, filename);
2781 #else
2782 return elf_output_file(s, filename);
2783 #endif
2786 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
2787 char *cbuf = buf;
2788 size_t rnum = 0;
2789 while (1) {
2790 ssize_t num = read(fd, cbuf, count-rnum);
2791 if (num < 0) return num;
2792 if (num == 0) return rnum;
2793 rnum += num;
2794 cbuf += num;
2798 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
2800 void *data;
2802 data = tcc_malloc(size);
2803 lseek(fd, file_offset, SEEK_SET);
2804 full_read(fd, data, size);
2805 return data;
2808 typedef struct SectionMergeInfo {
2809 Section *s; /* corresponding existing section */
2810 unsigned long offset; /* offset of the new section in the existing section */
2811 uint8_t new_section; /* true if section 's' was added */
2812 uint8_t link_once; /* true if link once section */
2813 } SectionMergeInfo;
2815 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2817 int size = full_read(fd, h, sizeof *h);
2818 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2819 if (h->e_type == ET_REL)
2820 return AFF_BINTYPE_REL;
2821 if (h->e_type == ET_DYN)
2822 return AFF_BINTYPE_DYN;
2823 } else if (size >= 8) {
2824 if (0 == memcmp(h, ARMAG, 8))
2825 return AFF_BINTYPE_AR;
2826 #ifdef TCC_TARGET_COFF
2827 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2828 return AFF_BINTYPE_C67;
2829 #endif
2831 return 0;
2834 /* load an object file and merge it with current files */
2835 /* XXX: handle correctly stab (debug) info */
2836 ST_FUNC int tcc_load_object_file(TCCState *s1,
2837 int fd, unsigned long file_offset)
2839 ElfW(Ehdr) ehdr;
2840 ElfW(Shdr) *shdr, *sh;
2841 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2842 char *strsec, *strtab;
2843 int stab_index, stabstr_index;
2844 int *old_to_new_syms;
2845 char *sh_name, *name;
2846 SectionMergeInfo *sm_table, *sm;
2847 ElfW(Sym) *sym, *symtab;
2848 ElfW_Rel *rel;
2849 Section *s;
2851 lseek(fd, file_offset, SEEK_SET);
2852 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2853 goto fail1;
2854 /* test CPU specific stuff */
2855 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2856 ehdr.e_machine != EM_TCC_TARGET) {
2857 fail1:
2858 tcc_error_noabort("invalid object file");
2859 return -1;
2861 /* read sections */
2862 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2863 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2864 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2866 /* load section names */
2867 sh = &shdr[ehdr.e_shstrndx];
2868 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2870 /* load symtab and strtab */
2871 old_to_new_syms = NULL;
2872 symtab = NULL;
2873 strtab = NULL;
2874 nb_syms = 0;
2875 seencompressed = 0;
2876 stab_index = stabstr_index = 0;
2878 for(i = 1; i < ehdr.e_shnum; i++) {
2879 sh = &shdr[i];
2880 if (sh->sh_type == SHT_SYMTAB) {
2881 if (symtab) {
2882 tcc_error_noabort("object must contain only one symtab");
2883 fail:
2884 ret = -1;
2885 goto the_end;
2887 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2888 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2889 sm_table[i].s = symtab_section;
2891 /* now load strtab */
2892 sh = &shdr[sh->sh_link];
2893 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2895 if (sh->sh_flags & SHF_COMPRESSED)
2896 seencompressed = 1;
2899 /* now examine each section and try to merge its content with the
2900 ones in memory */
2901 for(i = 1; i < ehdr.e_shnum; i++) {
2902 /* no need to examine section name strtab */
2903 if (i == ehdr.e_shstrndx)
2904 continue;
2905 sh = &shdr[i];
2906 if (sh->sh_type == SHT_RELX)
2907 sh = &shdr[sh->sh_info];
2908 /* ignore sections types we do not handle (plus relocs to those) */
2909 if (sh->sh_type != SHT_PROGBITS &&
2910 #ifdef TCC_ARM_EABI
2911 sh->sh_type != SHT_ARM_EXIDX &&
2912 #endif
2913 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2914 sh->sh_type != SHT_X86_64_UNWIND &&
2915 #endif
2916 sh->sh_type != SHT_NOTE &&
2917 sh->sh_type != SHT_NOBITS &&
2918 sh->sh_type != SHT_PREINIT_ARRAY &&
2919 sh->sh_type != SHT_INIT_ARRAY &&
2920 sh->sh_type != SHT_FINI_ARRAY &&
2921 strcmp(strsec + sh->sh_name, ".stabstr")
2923 continue;
2924 if (seencompressed
2925 && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
2926 continue;
2928 sh = &shdr[i];
2929 sh_name = strsec + sh->sh_name;
2930 if (sh->sh_addralign < 1)
2931 sh->sh_addralign = 1;
2932 /* find corresponding section, if any */
2933 for(j = 1; j < s1->nb_sections;j++) {
2934 s = s1->sections[j];
2935 if (!strcmp(s->name, sh_name)) {
2936 if (!strncmp(sh_name, ".gnu.linkonce",
2937 sizeof(".gnu.linkonce") - 1)) {
2938 /* if a 'linkonce' section is already present, we
2939 do not add it again. It is a little tricky as
2940 symbols can still be defined in
2941 it. */
2942 sm_table[i].link_once = 1;
2943 goto next;
2945 if (stab_section) {
2946 if (s == stab_section)
2947 stab_index = i;
2948 if (s == stab_section->link)
2949 stabstr_index = i;
2951 goto found;
2954 /* not found: create new section */
2955 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2956 /* take as much info as possible from the section. sh_link and
2957 sh_info will be updated later */
2958 s->sh_addralign = sh->sh_addralign;
2959 s->sh_entsize = sh->sh_entsize;
2960 sm_table[i].new_section = 1;
2961 found:
2962 if (sh->sh_type != s->sh_type) {
2963 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2964 if (strcmp (s->name, ".eh_frame"))
2965 #endif
2967 tcc_error_noabort("invalid section type");
2968 goto fail;
2971 /* align start of section */
2972 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
2973 if (sh->sh_addralign > s->sh_addralign)
2974 s->sh_addralign = sh->sh_addralign;
2975 sm_table[i].offset = s->data_offset;
2976 sm_table[i].s = s;
2977 /* concatenate sections */
2978 size = sh->sh_size;
2979 if (sh->sh_type != SHT_NOBITS) {
2980 unsigned char *ptr;
2981 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2982 ptr = section_ptr_add(s, size);
2983 full_read(fd, ptr, size);
2984 } else {
2985 s->data_offset += size;
2987 next: ;
2990 /* gr relocate stab strings */
2991 if (stab_index && stabstr_index) {
2992 Stab_Sym *a, *b;
2993 unsigned o;
2994 s = sm_table[stab_index].s;
2995 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2996 b = (Stab_Sym *)(s->data + s->data_offset);
2997 o = sm_table[stabstr_index].offset;
2998 while (a < b) {
2999 if (a->n_strx)
3000 a->n_strx += o;
3001 a++;
3005 /* second short pass to update sh_link and sh_info fields of new
3006 sections */
3007 for(i = 1; i < ehdr.e_shnum; i++) {
3008 s = sm_table[i].s;
3009 if (!s || !sm_table[i].new_section)
3010 continue;
3011 sh = &shdr[i];
3012 if (sh->sh_link > 0)
3013 s->link = sm_table[sh->sh_link].s;
3014 if (sh->sh_type == SHT_RELX) {
3015 s->sh_info = sm_table[sh->sh_info].s->sh_num;
3016 /* update backward link */
3017 s1->sections[s->sh_info]->reloc = s;
3021 /* resolve symbols */
3022 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
3024 sym = symtab + 1;
3025 for(i = 1; i < nb_syms; i++, sym++) {
3026 if (sym->st_shndx != SHN_UNDEF &&
3027 sym->st_shndx < SHN_LORESERVE) {
3028 sm = &sm_table[sym->st_shndx];
3029 if (sm->link_once) {
3030 /* if a symbol is in a link once section, we use the
3031 already defined symbol. It is very important to get
3032 correct relocations */
3033 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
3034 name = strtab + sym->st_name;
3035 sym_index = find_elf_sym(symtab_section, name);
3036 if (sym_index)
3037 old_to_new_syms[i] = sym_index;
3039 continue;
3041 /* if no corresponding section added, no need to add symbol */
3042 if (!sm->s)
3043 continue;
3044 /* convert section number */
3045 sym->st_shndx = sm->s->sh_num;
3046 /* offset value */
3047 sym->st_value += sm->offset;
3049 /* add symbol */
3050 name = strtab + sym->st_name;
3051 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
3052 sym->st_info, sym->st_other,
3053 sym->st_shndx, name);
3054 old_to_new_syms[i] = sym_index;
3057 /* third pass to patch relocation entries */
3058 for(i = 1; i < ehdr.e_shnum; i++) {
3059 s = sm_table[i].s;
3060 if (!s)
3061 continue;
3062 sh = &shdr[i];
3063 offset = sm_table[i].offset;
3064 size = sh->sh_size;
3065 switch(s->sh_type) {
3066 case SHT_RELX:
3067 /* take relocation offset information */
3068 offseti = sm_table[sh->sh_info].offset;
3069 for (rel = (ElfW_Rel *) s->data + (offset / sizeof(*rel));
3070 rel < (ElfW_Rel *) s->data + ((offset + size) / sizeof(*rel));
3071 rel++) {
3072 int type;
3073 unsigned sym_index;
3074 /* convert symbol index */
3075 type = ELFW(R_TYPE)(rel->r_info);
3076 sym_index = ELFW(R_SYM)(rel->r_info);
3077 /* NOTE: only one symtab assumed */
3078 if (sym_index >= nb_syms)
3079 goto invalid_reloc;
3080 sym_index = old_to_new_syms[sym_index];
3081 /* ignore link_once in rel section. */
3082 if (!sym_index && !sm_table[sh->sh_info].link_once
3083 #ifdef TCC_TARGET_ARM
3084 && type != R_ARM_V4BX
3085 #elif defined TCC_TARGET_RISCV64
3086 && type != R_RISCV_ALIGN
3087 && type != R_RISCV_RELAX
3088 #endif
3090 invalid_reloc:
3091 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3092 i, strsec + sh->sh_name, (int)rel->r_offset);
3093 goto fail;
3095 rel->r_info = ELFW(R_INFO)(sym_index, type);
3096 /* offset the relocation offset */
3097 rel->r_offset += offseti;
3098 #ifdef TCC_TARGET_ARM
3099 /* Jumps and branches from a Thumb code to a PLT entry need
3100 special handling since PLT entries are ARM code.
3101 Unconditional bl instructions referencing PLT entries are
3102 handled by converting these instructions into blx
3103 instructions. Other case of instructions referencing a PLT
3104 entry require to add a Thumb stub before the PLT entry to
3105 switch to ARM mode. We set bit plt_thumb_stub of the
3106 attribute of a symbol to indicate such a case. */
3107 if (type == R_ARM_THM_JUMP24)
3108 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
3109 #endif
3111 break;
3112 default:
3113 break;
3117 ret = 0;
3118 the_end:
3119 tcc_free(symtab);
3120 tcc_free(strtab);
3121 tcc_free(old_to_new_syms);
3122 tcc_free(sm_table);
3123 tcc_free(strsec);
3124 tcc_free(shdr);
3125 return ret;
3128 typedef struct ArchiveHeader {
3129 char ar_name[16]; /* name of this member */
3130 char ar_date[12]; /* file mtime */
3131 char ar_uid[6]; /* owner uid; printed as decimal */
3132 char ar_gid[6]; /* owner gid; printed as decimal */
3133 char ar_mode[8]; /* file mode, printed as octal */
3134 char ar_size[10]; /* file size, printed as decimal */
3135 char ar_fmag[2]; /* should contain ARFMAG */
3136 } ArchiveHeader;
3138 #define ARFMAG "`\n"
3140 static unsigned long long get_be(const uint8_t *b, int n)
3142 unsigned long long ret = 0;
3143 while (n)
3144 ret = (ret << 8) | *b++, --n;
3145 return ret;
3148 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
3150 char *p, *e;
3151 int len;
3152 lseek(fd, offset, SEEK_SET);
3153 len = full_read(fd, hdr, sizeof(ArchiveHeader));
3154 if (len != sizeof(ArchiveHeader))
3155 return len ? -1 : 0;
3156 p = hdr->ar_name;
3157 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
3158 --e;
3159 *e = '\0';
3160 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
3161 return len;
3164 /* load only the objects which resolve undefined symbols */
3165 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
3167 int i, bound, nsyms, sym_index, len, ret = -1;
3168 unsigned long long off;
3169 uint8_t *data;
3170 const char *ar_names, *p;
3171 const uint8_t *ar_index;
3172 ElfW(Sym) *sym;
3173 ArchiveHeader hdr;
3175 data = tcc_malloc(size);
3176 if (full_read(fd, data, size) != size)
3177 goto the_end;
3178 nsyms = get_be(data, entrysize);
3179 ar_index = data + entrysize;
3180 ar_names = (char *) ar_index + nsyms * entrysize;
3182 do {
3183 bound = 0;
3184 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
3185 Section *s = symtab_section;
3186 sym_index = find_elf_sym(s, p);
3187 if (!sym_index)
3188 continue;
3189 sym = &((ElfW(Sym) *)s->data)[sym_index];
3190 if(sym->st_shndx != SHN_UNDEF)
3191 continue;
3192 off = get_be(ar_index + i * entrysize, entrysize);
3193 len = read_ar_header(fd, off, &hdr);
3194 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
3195 tcc_error_noabort("invalid archive");
3196 goto the_end;
3198 off += len;
3199 if (s1->verbose == 2)
3200 printf(" -> %s\n", hdr.ar_name);
3201 if (tcc_load_object_file(s1, fd, off) < 0)
3202 goto the_end;
3203 ++bound;
3205 } while(bound);
3206 ret = 0;
3207 the_end:
3208 tcc_free(data);
3209 return ret;
3212 /* load a '.a' file */
3213 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
3215 ArchiveHeader hdr;
3216 /* char magic[8]; */
3217 int size, len;
3218 unsigned long file_offset;
3219 ElfW(Ehdr) ehdr;
3221 /* skip magic which was already checked */
3222 /* full_read(fd, magic, sizeof(magic)); */
3223 file_offset = sizeof ARMAG - 1;
3225 for(;;) {
3226 len = read_ar_header(fd, file_offset, &hdr);
3227 if (len == 0)
3228 return 0;
3229 if (len < 0) {
3230 tcc_error_noabort("invalid archive");
3231 return -1;
3233 file_offset += len;
3234 size = strtol(hdr.ar_size, NULL, 0);
3235 /* align to even */
3236 size = (size + 1) & ~1;
3237 if (alacarte) {
3238 /* coff symbol table : we handle it */
3239 if (!strcmp(hdr.ar_name, "/"))
3240 return tcc_load_alacarte(s1, fd, size, 4);
3241 if (!strcmp(hdr.ar_name, "/SYM64/"))
3242 return tcc_load_alacarte(s1, fd, size, 8);
3243 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3244 if (s1->verbose == 2)
3245 printf(" -> %s\n", hdr.ar_name);
3246 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3247 return -1;
3249 file_offset += size;
3253 #ifndef ELF_OBJ_ONLY
3254 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3255 LV, maybe create a new entry for (LIB,VERSION). */
3256 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3258 while (i >= *n) {
3259 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3260 (*lv)[(*n)++] = -1;
3262 if ((*lv)[i] == -1) {
3263 int v, prev_same_lib = -1;
3264 for (v = 0; v < nb_sym_versions; v++) {
3265 if (strcmp(sym_versions[v].lib, lib))
3266 continue;
3267 prev_same_lib = v;
3268 if (!strcmp(sym_versions[v].version, version))
3269 break;
3271 if (v == nb_sym_versions) {
3272 sym_versions = tcc_realloc (sym_versions,
3273 (v + 1) * sizeof(*sym_versions));
3274 sym_versions[v].lib = tcc_strdup(lib);
3275 sym_versions[v].version = tcc_strdup(version);
3276 sym_versions[v].out_index = 0;
3277 sym_versions[v].prev_same_lib = prev_same_lib;
3278 nb_sym_versions++;
3280 (*lv)[i] = v;
3284 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3285 VERNDX. */
3286 static void
3287 set_sym_version(TCCState *s1, int sym_index, int verndx)
3289 if (sym_index >= nb_sym_to_version) {
3290 int newelems = sym_index ? sym_index * 2 : 1;
3291 sym_to_version = tcc_realloc(sym_to_version,
3292 newelems * sizeof(*sym_to_version));
3293 memset(sym_to_version + nb_sym_to_version, -1,
3294 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3295 nb_sym_to_version = newelems;
3297 if (sym_to_version[sym_index] < 0)
3298 sym_to_version[sym_index] = verndx;
3301 struct versym_info {
3302 int nb_versyms;
3303 ElfW(Verdef) *verdef;
3304 ElfW(Verneed) *verneed;
3305 ElfW(Half) *versym;
3306 int nb_local_ver, *local_ver;
3310 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3312 char *lib, *version;
3313 uint32_t next;
3314 int i;
3316 #define DEBUG_VERSION 0
3318 if (v->versym && v->verdef) {
3319 ElfW(Verdef) *vdef = v->verdef;
3320 lib = NULL;
3321 do {
3322 ElfW(Verdaux) *verdaux =
3323 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3325 #if DEBUG_VERSION
3326 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3327 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3328 vdef->vd_hash);
3329 #endif
3330 if (vdef->vd_cnt) {
3331 version = dynstr + verdaux->vda_name;
3333 if (lib == NULL)
3334 lib = version;
3335 else
3336 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3337 lib, version);
3338 #if DEBUG_VERSION
3339 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3340 #endif
3342 next = vdef->vd_next;
3343 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3344 } while (next);
3346 if (v->versym && v->verneed) {
3347 ElfW(Verneed) *vneed = v->verneed;
3348 do {
3349 ElfW(Vernaux) *vernaux =
3350 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3352 lib = dynstr + vneed->vn_file;
3353 #if DEBUG_VERSION
3354 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3355 #endif
3356 for (i = 0; i < vneed->vn_cnt; i++) {
3357 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3358 version = dynstr + vernaux->vna_name;
3359 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3360 lib, version);
3361 #if DEBUG_VERSION
3362 printf (" vernaux(%u): %u %u %s\n",
3363 vernaux->vna_other, vernaux->vna_hash,
3364 vernaux->vna_flags, version);
3365 #endif
3367 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3369 next = vneed->vn_next;
3370 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3371 } while (next);
3374 #if DEBUG_VERSION
3375 for (i = 0; i < v->nb_local_ver; i++) {
3376 if (v->local_ver[i] > 0) {
3377 printf ("%d: lib: %s, version %s\n",
3378 i, sym_versions[v->local_ver[i]].lib,
3379 sym_versions[v->local_ver[i]].version);
3382 #endif
3385 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3386 is referenced by the user (so it should be added as DT_NEEDED in
3387 the generated ELF file) */
3388 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3390 ElfW(Ehdr) ehdr;
3391 ElfW(Shdr) *shdr, *sh, *sh1;
3392 int i, j, nb_syms, nb_dts, sym_bind, ret;
3393 ElfW(Sym) *sym, *dynsym;
3394 ElfW(Dyn) *dt, *dynamic;
3396 char *dynstr;
3397 int sym_index;
3398 const char *name, *soname;
3399 DLLReference *dllref;
3400 struct versym_info v;
3402 full_read(fd, &ehdr, sizeof(ehdr));
3404 /* test CPU specific stuff */
3405 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3406 ehdr.e_machine != EM_TCC_TARGET) {
3407 tcc_error_noabort("bad architecture");
3408 return -1;
3411 /* read sections */
3412 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3414 /* load dynamic section and dynamic symbols */
3415 nb_syms = 0;
3416 nb_dts = 0;
3417 dynamic = NULL;
3418 dynsym = NULL; /* avoid warning */
3419 dynstr = NULL; /* avoid warning */
3420 memset(&v, 0, sizeof v);
3422 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3423 switch(sh->sh_type) {
3424 case SHT_DYNAMIC:
3425 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3426 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3427 break;
3428 case SHT_DYNSYM:
3429 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3430 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3431 sh1 = &shdr[sh->sh_link];
3432 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3433 break;
3434 case SHT_GNU_verdef:
3435 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3436 break;
3437 case SHT_GNU_verneed:
3438 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3439 break;
3440 case SHT_GNU_versym:
3441 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3442 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3443 break;
3444 default:
3445 break;
3449 /* compute the real library name */
3450 soname = tcc_basename(filename);
3452 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3453 if (dt->d_tag == DT_SONAME) {
3454 soname = dynstr + dt->d_un.d_val;
3458 /* if the dll is already loaded, do not load it */
3459 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3460 dllref = s1->loaded_dlls[i];
3461 if (!strcmp(soname, dllref->name)) {
3462 /* but update level if needed */
3463 if (level < dllref->level)
3464 dllref->level = level;
3465 ret = 0;
3466 goto the_end;
3470 if (v.nb_versyms != nb_syms)
3471 tcc_free (v.versym), v.versym = NULL;
3472 else
3473 store_version(s1, &v, dynstr);
3475 /* add the dll and its level */
3476 tcc_add_dllref(s1, soname)->level = level;
3478 /* add dynamic symbols in dynsym_section */
3479 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3480 sym_bind = ELFW(ST_BIND)(sym->st_info);
3481 if (sym_bind == STB_LOCAL)
3482 continue;
3483 name = dynstr + sym->st_name;
3484 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3485 sym->st_info, sym->st_other, sym->st_shndx, name);
3486 if (v.versym) {
3487 ElfW(Half) vsym = v.versym[i];
3488 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3489 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3493 /* load all referenced DLLs */
3494 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3495 switch(dt->d_tag) {
3496 case DT_NEEDED:
3497 name = dynstr + dt->d_un.d_val;
3498 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3499 dllref = s1->loaded_dlls[j];
3500 if (!strcmp(name, dllref->name))
3501 goto already_loaded;
3503 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3504 tcc_error_noabort("referenced dll '%s' not found", name);
3505 ret = -1;
3506 goto the_end;
3508 already_loaded:
3509 break;
3512 ret = 0;
3513 the_end:
3514 tcc_free(dynstr);
3515 tcc_free(dynsym);
3516 tcc_free(dynamic);
3517 tcc_free(shdr);
3518 tcc_free(v.local_ver);
3519 tcc_free(v.verdef);
3520 tcc_free(v.verneed);
3521 tcc_free(v.versym);
3522 return ret;
3525 #define LD_TOK_NAME 256
3526 #define LD_TOK_EOF (-1)
3528 static int ld_inp(TCCState *s1)
3530 char b;
3531 if (s1->cc != -1) {
3532 int c = s1->cc;
3533 s1->cc = -1;
3534 return c;
3536 if (1 == read(s1->fd, &b, 1))
3537 return b;
3538 return CH_EOF;
3541 /* return next ld script token */
3542 static int ld_next(TCCState *s1, char *name, int name_size)
3544 int c, d, ch;
3545 char *q;
3547 redo:
3548 ch = ld_inp(s1);
3549 switch(ch) {
3550 case ' ':
3551 case '\t':
3552 case '\f':
3553 case '\v':
3554 case '\r':
3555 case '\n':
3556 goto redo;
3557 case '/':
3558 ch = ld_inp(s1);
3559 if (ch == '*') { /* comment */
3560 for (d = 0;; d = ch) {
3561 ch = ld_inp(s1);
3562 if (ch == CH_EOF || (ch == '/' && d == '*'))
3563 break;
3565 goto redo;
3566 } else {
3567 q = name;
3568 *q++ = '/';
3569 goto parse_name;
3571 break;
3572 case '\\':
3573 /* case 'a' ... 'z': */
3574 case 'a':
3575 case 'b':
3576 case 'c':
3577 case 'd':
3578 case 'e':
3579 case 'f':
3580 case 'g':
3581 case 'h':
3582 case 'i':
3583 case 'j':
3584 case 'k':
3585 case 'l':
3586 case 'm':
3587 case 'n':
3588 case 'o':
3589 case 'p':
3590 case 'q':
3591 case 'r':
3592 case 's':
3593 case 't':
3594 case 'u':
3595 case 'v':
3596 case 'w':
3597 case 'x':
3598 case 'y':
3599 case 'z':
3600 /* case 'A' ... 'z': */
3601 case 'A':
3602 case 'B':
3603 case 'C':
3604 case 'D':
3605 case 'E':
3606 case 'F':
3607 case 'G':
3608 case 'H':
3609 case 'I':
3610 case 'J':
3611 case 'K':
3612 case 'L':
3613 case 'M':
3614 case 'N':
3615 case 'O':
3616 case 'P':
3617 case 'Q':
3618 case 'R':
3619 case 'S':
3620 case 'T':
3621 case 'U':
3622 case 'V':
3623 case 'W':
3624 case 'X':
3625 case 'Y':
3626 case 'Z':
3627 case '_':
3628 case '.':
3629 case '$':
3630 case '~':
3631 q = name;
3632 parse_name:
3633 for(;;) {
3634 if (!((ch >= 'a' && ch <= 'z') ||
3635 (ch >= 'A' && ch <= 'Z') ||
3636 (ch >= '0' && ch <= '9') ||
3637 strchr("/.-_+=$:\\,~", ch)))
3638 break;
3639 if ((q - name) < name_size - 1) {
3640 *q++ = ch;
3642 ch = ld_inp(s1);
3644 s1->cc = ch;
3645 *q = '\0';
3646 c = LD_TOK_NAME;
3647 break;
3648 case CH_EOF:
3649 c = LD_TOK_EOF;
3650 break;
3651 default:
3652 c = ch;
3653 break;
3655 return c;
3658 static int ld_add_file(TCCState *s1, const char filename[])
3660 if (filename[0] == '/') {
3661 if (CONFIG_SYSROOT[0] == '\0'
3662 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3663 return 0;
3664 filename = tcc_basename(filename);
3666 return tcc_add_dll(s1, filename, 0);
3669 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3671 char filename[1024], libname[1024];
3672 int t, group, nblibs = 0, ret = 0;
3673 char **libs = NULL;
3675 group = !strcmp(cmd, "GROUP");
3676 if (!as_needed)
3677 s1->new_undef_sym = 0;
3678 t = ld_next(s1, filename, sizeof(filename));
3679 if (t != '(') {
3680 tcc_error_noabort("( expected");
3681 ret = -1;
3682 goto lib_parse_error;
3684 t = ld_next(s1, filename, sizeof(filename));
3685 for(;;) {
3686 libname[0] = '\0';
3687 if (t == LD_TOK_EOF) {
3688 tcc_error_noabort("unexpected end of file");
3689 ret = -1;
3690 goto lib_parse_error;
3691 } else if (t == ')') {
3692 break;
3693 } else if (t == '-') {
3694 t = ld_next(s1, filename, sizeof(filename));
3695 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3696 tcc_error_noabort("library name expected");
3697 ret = -1;
3698 goto lib_parse_error;
3700 pstrcpy(libname, sizeof libname, &filename[1]);
3701 if (s1->static_link) {
3702 snprintf(filename, sizeof filename, "lib%s.a", libname);
3703 } else {
3704 snprintf(filename, sizeof filename, "lib%s.so", libname);
3706 } else if (t != LD_TOK_NAME) {
3707 tcc_error_noabort("filename expected");
3708 ret = -1;
3709 goto lib_parse_error;
3711 if (!strcmp(filename, "AS_NEEDED")) {
3712 ret = ld_add_file_list(s1, cmd, 1);
3713 if (ret)
3714 goto lib_parse_error;
3715 } else {
3716 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3717 if (!as_needed) {
3718 ret = ld_add_file(s1, filename);
3719 if (ret)
3720 goto lib_parse_error;
3721 if (group) {
3722 /* Add the filename *and* the libname to avoid future conversions */
3723 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3724 if (libname[0] != '\0')
3725 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3729 t = ld_next(s1, filename, sizeof(filename));
3730 if (t == ',') {
3731 t = ld_next(s1, filename, sizeof(filename));
3734 if (group && !as_needed) {
3735 while (s1->new_undef_sym) {
3736 int i;
3737 s1->new_undef_sym = 0;
3738 for (i = 0; i < nblibs; i ++)
3739 ld_add_file(s1, libs[i]);
3742 lib_parse_error:
3743 dynarray_reset(&libs, &nblibs);
3744 return ret;
3747 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3748 files */
3749 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3751 char cmd[64];
3752 char filename[1024];
3753 int t, ret;
3755 s1->fd = fd;
3756 s1->cc = -1;
3757 for(;;) {
3758 t = ld_next(s1, cmd, sizeof(cmd));
3759 if (t == LD_TOK_EOF)
3760 return 0;
3761 else if (t != LD_TOK_NAME)
3762 return -1;
3763 if (!strcmp(cmd, "INPUT") ||
3764 !strcmp(cmd, "GROUP")) {
3765 ret = ld_add_file_list(s1, cmd, 0);
3766 if (ret)
3767 return ret;
3768 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3769 !strcmp(cmd, "TARGET")) {
3770 /* ignore some commands */
3771 t = ld_next(s1, cmd, sizeof(cmd));
3772 if (t != '(') {
3773 tcc_error_noabort("( expected");
3774 return -1;
3776 for(;;) {
3777 t = ld_next(s1, filename, sizeof(filename));
3778 if (t == LD_TOK_EOF) {
3779 tcc_error_noabort("unexpected end of file");
3780 return -1;
3781 } else if (t == ')') {
3782 break;
3785 } else {
3786 return -1;
3789 return 0;
3791 #endif /* !ELF_OBJ_ONLY */