fix cross compiler compilation
[tinycc.git] / tccelf.c
blob698a333d50ed04f6d368310fd529cba3ef60c1f1
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 #elif defined(TCC_TARGET_ARM64)
1036 case R_AARCH64_ABS32:
1037 case R_AARCH64_ABS64:
1038 #elif defined(TCC_TARGET_RISCV64)
1039 case R_RISCV_32:
1040 case R_RISCV_64:
1041 #endif
1042 count++;
1043 break;
1044 #if defined(TCC_TARGET_I386)
1045 case R_386_PC32:
1046 #elif defined(TCC_TARGET_X86_64)
1047 case R_X86_64_PC32:
1049 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1051 /* support __dso_handle in atexit() */
1052 if (sym->st_shndx != SHN_UNDEF &&
1053 ELFW(ST_VISIBILITY)(sym->st_other) == STV_HIDDEN) {
1054 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PLT32);
1055 break;
1058 #elif defined(TCC_TARGET_ARM64)
1059 case R_AARCH64_PREL32:
1060 #endif
1061 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1062 count++;
1063 break;
1064 default:
1065 break;
1068 if (count) {
1069 /* allocate the section */
1070 sr->sh_flags |= SHF_ALLOC;
1071 sr->sh_size = count * sizeof(ElfW_Rel);
1073 #endif
1074 return count;
1076 #endif
1078 #if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE)
1079 static void build_got(TCCState *s1)
1081 /* if no got, then create it */
1082 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1083 s1->got->sh_entsize = 4;
1084 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1085 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1086 /* keep space for _DYNAMIC pointer and two dummy got entries */
1087 section_ptr_add(s1->got, 3 * PTR_SIZE);
1090 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1091 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1092 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1093 Returns the offset of the GOT or (if any) PLT entry. */
1094 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1095 int sym_index)
1097 int need_plt_entry;
1098 const char *name;
1099 ElfW(Sym) *sym;
1100 struct sym_attr *attr;
1101 unsigned got_offset;
1102 char plt_name[100];
1103 int len;
1105 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1106 attr = get_sym_attr(s1, sym_index, 1);
1108 /* In case a function is both called and its address taken 2 GOT entries
1109 are created, one for taking the address (GOT) and the other for the PLT
1110 entry (PLTGOT). */
1111 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1112 return attr;
1114 /* create the GOT entry */
1115 got_offset = s1->got->data_offset;
1116 section_ptr_add(s1->got, PTR_SIZE);
1118 /* Create the GOT relocation that will insert the address of the object or
1119 function of interest in the GOT entry. This is a static relocation for
1120 memory output (dlsym will give us the address of symbols) and dynamic
1121 relocation otherwise (executable and DLLs). The relocation should be
1122 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1123 associated to a PLT entry) but is currently done at load time for an
1124 unknown reason. */
1126 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1127 name = (char *) symtab_section->link->data + sym->st_name;
1129 if (s1->dynsym) {
1130 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1131 /* Hack alarm. We don't want to emit dynamic symbols
1132 and symbol based relocs for STB_LOCAL symbols, but rather
1133 want to resolve them directly. At this point the symbol
1134 values aren't final yet, so we must defer this. We will later
1135 have to create a RELATIVE reloc anyway, so we misuse the
1136 relocation slot to smuggle the symbol reference until
1137 fill_local_got_entries. Not that the sym_index is
1138 relative to symtab_section, not s1->dynsym! Nevertheless
1139 we use s1->dyn_sym so that if this is the first call
1140 that got->reloc is correctly created. Also note that
1141 RELATIVE relocs are not normally created for the .got,
1142 so the types serves as a marker for later (and is retained
1143 also for the final output, which is okay because then the
1144 got is just normal data). */
1145 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1146 sym_index);
1147 } else {
1148 if (0 == attr->dyn_index)
1149 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1150 sym->st_size, sym->st_info, 0,
1151 sym->st_shndx, name);
1152 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
1153 attr->dyn_index);
1155 } else {
1156 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1157 sym_index);
1160 if (need_plt_entry) {
1161 if (!s1->plt) {
1162 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1163 SHF_ALLOC | SHF_EXECINSTR);
1164 s1->plt->sh_entsize = 4;
1167 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1169 /* create a symbol 'sym@plt' for the PLT jump vector */
1170 len = strlen(name);
1171 if (len > sizeof plt_name - 5)
1172 len = sizeof plt_name - 5;
1173 memcpy(plt_name, name, len);
1174 strcpy(plt_name + len, "@plt");
1175 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
1176 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1178 } else {
1179 attr->got_offset = got_offset;
1182 return attr;
1185 /* build GOT and PLT entries */
1186 static void build_got_entries_pass(TCCState *s1, int pass)
1188 Section *s;
1189 ElfW_Rel *rel;
1190 ElfW(Sym) *sym;
1191 int i, type, gotplt_entry, reloc_type, sym_index;
1192 struct sym_attr *attr;
1194 for(i = 1; i < s1->nb_sections; i++) {
1195 s = s1->sections[i];
1196 if (s->sh_type != SHT_RELX)
1197 continue;
1198 /* no need to handle got relocations */
1199 if (s->link != symtab_section)
1200 continue;
1201 for_each_elem(s, 0, rel, ElfW_Rel) {
1202 type = ELFW(R_TYPE)(rel->r_info);
1203 gotplt_entry = gotplt_entry_type(type);
1204 if (gotplt_entry == -1)
1205 tcc_error ("Unknown relocation type for got: %d", type);
1206 sym_index = ELFW(R_SYM)(rel->r_info);
1207 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1209 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1210 continue;
1213 /* Automatically create PLT/GOT [entry] if it is an undefined
1214 reference (resolved at runtime), or the symbol is absolute,
1215 probably created by tcc_add_symbol, and thus on 64-bit
1216 targets might be too far from application code. */
1217 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1218 if (sym->st_shndx == SHN_UNDEF) {
1219 ElfW(Sym) *esym;
1220 int dynindex;
1221 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1222 continue;
1223 /* Relocations for UNDEF symbols would normally need
1224 to be transferred into the executable or shared object.
1225 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1226 But TCC doesn't do that (at least for exes), so we
1227 need to resolve all such relocs locally. And that
1228 means PLT slots for functions in DLLs and COPY relocs for
1229 data symbols. COPY relocs were generated in
1230 bind_exe_dynsyms (and the symbol adjusted to be defined),
1231 and for functions we were generated a dynamic symbol
1232 of function type. */
1233 if (s1->dynsym) {
1234 /* dynsym isn't set for -run :-/ */
1235 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1236 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1237 if (dynindex
1238 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1239 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1240 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1241 goto jmp_slot;
1243 } else if (!(sym->st_shndx == SHN_ABS
1244 #ifndef TCC_TARGET_ARM
1245 && PTR_SIZE == 8
1246 #endif
1248 continue;
1251 #ifdef TCC_TARGET_X86_64
1252 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1253 sym->st_shndx != SHN_UNDEF &&
1254 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1255 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1256 s1->output_type == TCC_OUTPUT_EXE)) {
1257 if (pass == 0)
1258 continue;
1259 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1260 continue;
1262 #endif
1263 reloc_type = code_reloc(type);
1264 if (reloc_type == -1)
1265 tcc_error ("Unknown relocation type: %d", type);
1266 else if (reloc_type != 0) {
1267 jmp_slot:
1268 reloc_type = R_JMP_SLOT;
1269 } else
1270 reloc_type = R_GLOB_DAT;
1273 if ((pass == 0 && reloc_type == R_GLOB_DAT) ||
1274 (pass == 1 && reloc_type == R_JMP_SLOT))
1275 continue;
1277 if (!s1->got)
1278 build_got(s1);
1280 if (gotplt_entry == BUILD_GOT_ONLY)
1281 continue;
1283 attr = put_got_entry(s1, reloc_type, sym_index);
1285 if (reloc_type == R_JMP_SLOT)
1286 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1291 ST_FUNC void build_got_entries(TCCState *s1)
1293 int i;
1295 /* Two passes because R_JMP_SLOT should become first.
1296 Some targets (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1297 for (i = 0; i < 2; i++)
1298 build_got_entries_pass(s1, i);
1300 #endif
1302 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
1304 int shn = sec ? sec->sh_num : offs ? SHN_ABS : SHN_UNDEF;
1305 if (sec && offs == -1)
1306 offs = sec->data_offset;
1307 return set_elf_sym(symtab_section, offs, 0,
1308 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1311 static void add_init_array_defines(TCCState *s1, const char *section_name)
1313 Section *s;
1314 addr_t end_offset;
1315 char buf[1024];
1316 s = find_section(s1, section_name);
1317 if (!s) {
1318 end_offset = 0;
1319 s = data_section;
1320 } else {
1321 end_offset = s->data_offset;
1323 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1324 set_global_sym(s1, buf, s, 0);
1325 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1326 set_global_sym(s1, buf, s, end_offset);
1329 #ifndef TCC_TARGET_PE
1330 static void tcc_add_support(TCCState *s1, const char *filename)
1332 char buf[1024];
1333 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1334 tcc_add_file(s1, buf);
1336 #endif
1338 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1340 Section *s;
1341 s = find_section(s1, sec);
1342 s->sh_flags |= SHF_WRITE;
1343 #ifndef TCC_TARGET_PE
1344 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1345 #endif
1346 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1347 section_ptr_add(s, PTR_SIZE);
1350 #ifdef CONFIG_TCC_BCHECK
1351 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1353 if (0 == s1->do_bounds_check)
1354 return;
1355 section_ptr_add(bounds_section, sizeof(addr_t));
1357 #endif
1359 #ifdef CONFIG_TCC_BACKTRACE
1360 static void put_ptr(TCCState *s1, Section *s, int offs)
1362 int c;
1363 c = set_global_sym(s1, NULL, s, offs);
1364 s = data_section;
1365 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1366 section_ptr_add(s, PTR_SIZE);
1369 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1370 a dynamic symbol to allow so's to have one each with a different value. */
1371 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1373 int c = find_elf_sym(s1->symtab, name);
1374 if (c) {
1375 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1376 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1377 esym->st_value = offset;
1378 esym->st_shndx = s->sh_num;
1382 ST_FUNC void tcc_add_btstub(TCCState *s1)
1384 Section *s;
1385 int n, o;
1386 CString cstr;
1388 s = data_section;
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 #ifdef CONFIG_TCC_BCHECK
1453 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1454 tcc_add_library_err(s1, "pthread");
1455 #if !TARGETOS_OpenBSD && !TARGETOS_NetBSD
1456 tcc_add_library_err(s1, "dl");
1457 #endif
1458 tcc_add_support(s1, "bcheck.o");
1460 #endif
1461 #ifdef CONFIG_TCC_BACKTRACE
1462 if (s1->do_backtrace) {
1463 if (s1->output_type == TCC_OUTPUT_EXE)
1464 tcc_add_support(s1, "bt-exe.o");
1465 if (s1->output_type != TCC_OUTPUT_DLL)
1466 tcc_add_support(s1, "bt-log.o");
1467 if (s1->output_type != TCC_OUTPUT_MEMORY)
1468 tcc_add_btstub(s1);
1470 #endif
1471 if (strlen(TCC_LIBTCC1) > 0)
1472 tcc_add_support(s1, TCC_LIBTCC1);
1473 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
1474 /* add crt end if not memory output */
1475 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1476 if (s1->output_type == TCC_OUTPUT_DLL)
1477 tcc_add_crt(s1, "crtendS.o");
1478 else
1479 tcc_add_crt(s1, "crtend.o");
1480 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
1481 tcc_add_crt(s1, "crtn.o");
1482 #endif
1484 #elif !defined(TCC_TARGET_MACHO)
1485 /* add crt end if not memory output */
1486 if (s1->output_type != TCC_OUTPUT_MEMORY)
1487 tcc_add_crt(s1, "crtn.o");
1488 #endif
1491 #endif
1493 /* add various standard linker symbols (must be done after the
1494 sections are filled (for example after allocating common
1495 symbols)) */
1496 static void tcc_add_linker_symbols(TCCState *s1)
1498 char buf[1024];
1499 int i;
1500 Section *s;
1502 set_global_sym(s1, "_etext", text_section, -1);
1503 set_global_sym(s1, "_edata", data_section, -1);
1504 set_global_sym(s1, "_end", bss_section, -1);
1505 #ifdef TCC_TARGET_RISCV64
1506 /* XXX should be .sdata+0x800, not .data+0x800 */
1507 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1508 #endif
1509 /* horrible new standard ldscript defines */
1510 add_init_array_defines(s1, ".preinit_array");
1511 add_init_array_defines(s1, ".init_array");
1512 add_init_array_defines(s1, ".fini_array");
1513 /* add start and stop symbols for sections whose name can be
1514 expressed in C */
1515 for(i = 1; i < s1->nb_sections; i++) {
1516 s = s1->sections[i];
1517 if ((s->sh_flags & SHF_ALLOC)
1518 && (s->sh_type == SHT_PROGBITS
1519 || s->sh_type == SHT_STRTAB)) {
1520 const char *p;
1521 /* check if section name can be expressed in C */
1522 p = s->name;
1523 for(;;) {
1524 int c = *p;
1525 if (!c)
1526 break;
1527 if (!isid(c) && !isnum(c))
1528 goto next_sec;
1529 p++;
1531 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1532 set_global_sym(s1, buf, s, 0);
1533 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1534 set_global_sym(s1, buf, s, -1);
1536 next_sec: ;
1540 ST_FUNC void resolve_common_syms(TCCState *s1)
1542 ElfW(Sym) *sym;
1544 /* Allocate common symbols in BSS. */
1545 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1546 if (sym->st_shndx == SHN_COMMON) {
1547 /* symbol alignment is in st_value for SHN_COMMONs */
1548 sym->st_value = section_add(bss_section, sym->st_size,
1549 sym->st_value);
1550 sym->st_shndx = bss_section->sh_num;
1554 /* Now assign linker provided symbols their value. */
1555 tcc_add_linker_symbols(s1);
1558 static void tcc_output_binary(TCCState *s1, FILE *f,
1559 const int *sec_order)
1561 Section *s;
1562 int i, offset, size;
1564 offset = 0;
1565 for(i=1;i<s1->nb_sections;i++) {
1566 s = s1->sections[sec_order[i]];
1567 if (s->sh_type != SHT_NOBITS &&
1568 (s->sh_flags & SHF_ALLOC)) {
1569 while (offset < s->sh_offset) {
1570 fputc(0, f);
1571 offset++;
1573 size = s->sh_size;
1574 fwrite(s->data, 1, size, f);
1575 offset += size;
1580 #ifndef ELF_OBJ_ONLY
1581 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1583 int sym_index = ELFW(R_SYM) (rel->r_info);
1584 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1585 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1586 unsigned offset = attr->got_offset;
1588 if (0 == offset)
1589 return;
1590 section_reserve(s1->got, offset + PTR_SIZE);
1591 #if PTR_SIZE == 8
1592 write64le(s1->got->data + offset, sym->st_value);
1593 #else
1594 write32le(s1->got->data + offset, sym->st_value);
1595 #endif
1598 /* Perform relocation to GOT or PLT entries */
1599 ST_FUNC void fill_got(TCCState *s1)
1601 Section *s;
1602 ElfW_Rel *rel;
1603 int i;
1605 for(i = 1; i < s1->nb_sections; i++) {
1606 s = s1->sections[i];
1607 if (s->sh_type != SHT_RELX)
1608 continue;
1609 /* no need to handle got relocations */
1610 if (s->link != symtab_section)
1611 continue;
1612 for_each_elem(s, 0, rel, ElfW_Rel) {
1613 switch (ELFW(R_TYPE) (rel->r_info)) {
1614 case R_X86_64_GOT32:
1615 case R_X86_64_GOTPCREL:
1616 case R_X86_64_GOTPCRELX:
1617 case R_X86_64_REX_GOTPCRELX:
1618 case R_X86_64_PLT32:
1619 fill_got_entry(s1, rel);
1620 break;
1626 /* See put_got_entry for a description. This is the second stage
1627 where GOT references to local defined symbols are rewritten. */
1628 static void fill_local_got_entries(TCCState *s1)
1630 ElfW_Rel *rel;
1631 if (!s1->got->reloc)
1632 return;
1633 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1634 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1635 int sym_index = ELFW(R_SYM) (rel->r_info);
1636 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1637 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1638 unsigned offset = attr->got_offset;
1639 if (offset != rel->r_offset - s1->got->sh_addr)
1640 tcc_error_noabort("huh");
1641 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1642 #if SHT_RELX == SHT_RELA
1643 rel->r_addend = sym->st_value;
1644 #else
1645 /* All our REL architectures also happen to be 32bit LE. */
1646 write32le(s1->got->data + offset, sym->st_value);
1647 #endif
1652 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1653 in shared libraries and export non local defined symbols to shared libraries
1654 if -rdynamic switch was given on command line */
1655 static void bind_exe_dynsyms(TCCState *s1)
1657 const char *name;
1658 int sym_index, index;
1659 ElfW(Sym) *sym, *esym;
1660 int type;
1662 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1663 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1664 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1665 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1666 if (sym->st_shndx == SHN_UNDEF) {
1667 name = (char *) symtab_section->link->data + sym->st_name;
1668 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1669 if (sym_index) {
1670 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1671 type = ELFW(ST_TYPE)(esym->st_info);
1672 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1673 /* Indirect functions shall have STT_FUNC type in executable
1674 * dynsym section. Indeed, a dlsym call following a lazy
1675 * resolution would pick the symbol value from the
1676 * executable dynsym entry which would contain the address
1677 * of the function wanted by the caller of dlsym instead of
1678 * the address of the function that would return that
1679 * address */
1680 int dynindex
1681 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1682 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1683 name);
1684 int index = sym - (ElfW(Sym) *) symtab_section->data;
1685 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1686 } else if (type == STT_OBJECT) {
1687 unsigned long offset;
1688 ElfW(Sym) *dynsym;
1689 offset = bss_section->data_offset;
1690 /* XXX: which alignment ? */
1691 offset = (offset + 16 - 1) & -16;
1692 set_elf_sym (s1->symtab, offset, esym->st_size,
1693 esym->st_info, 0, bss_section->sh_num, name);
1694 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1695 esym->st_info, 0, bss_section->sh_num,
1696 name);
1698 /* Ensure R_COPY works for weak symbol aliases */
1699 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1700 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1701 if ((dynsym->st_value == esym->st_value)
1702 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1703 char *dynname = (char *) s1->dynsymtab_section->link->data
1704 + dynsym->st_name;
1705 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1706 dynsym->st_info, 0,
1707 bss_section->sh_num, dynname);
1708 break;
1713 put_elf_reloc(s1->dynsym, bss_section,
1714 offset, R_COPY, index);
1715 offset += esym->st_size;
1716 bss_section->data_offset = offset;
1718 } else {
1719 /* STB_WEAK undefined symbols are accepted */
1720 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1721 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1722 !strcmp(name, "_fp_hw")) {
1723 } else {
1724 tcc_error_noabort("undefined symbol '%s'", name);
1727 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1728 /* if -rdynamic option, then export all non local symbols */
1729 name = (char *) symtab_section->link->data + sym->st_name;
1730 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1731 0, sym->st_shndx, name);
1736 /* Bind symbols of libraries: export all non local symbols of executable that
1737 are referenced by shared libraries. The reason is that the dynamic loader
1738 search symbol first in executable and then in libraries. Therefore a
1739 reference to a symbol already defined by a library can still be resolved by
1740 a symbol in the executable. */
1741 static void bind_libs_dynsyms(TCCState *s1)
1743 const char *name;
1744 int sym_index;
1745 ElfW(Sym) *sym, *esym;
1747 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1748 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1749 sym_index = find_elf_sym(symtab_section, name);
1750 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1751 if (sym_index && sym->st_shndx != SHN_UNDEF
1752 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1753 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1754 sym->st_info, 0, sym->st_shndx, name);
1755 } else if (esym->st_shndx == SHN_UNDEF) {
1756 /* weak symbols can stay undefined */
1757 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1758 tcc_warning("undefined dynamic symbol '%s'", name);
1763 /* Export all non local symbols. This is used by shared libraries so that the
1764 non local symbols they define can resolve a reference in another shared
1765 library or in the executable. Correspondingly, it allows undefined local
1766 symbols to be resolved by other shared libraries or by the executable. */
1767 static void export_global_syms(TCCState *s1)
1769 int dynindex, index;
1770 const char *name;
1771 ElfW(Sym) *sym;
1773 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1774 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1775 name = (char *) symtab_section->link->data + sym->st_name;
1776 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1777 sym->st_info, 0, sym->st_shndx, name);
1778 index = sym - (ElfW(Sym) *) symtab_section->data;
1779 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1783 #endif
1785 /* Allocate strings for section names and decide if an unallocated section
1786 should be output.
1787 NOTE: the strsec section comes last, so its size is also correct ! */
1788 static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1790 int i;
1791 Section *s;
1792 int textrel = 0;
1794 /* Allocate strings for section names */
1795 for(i = 1; i < s1->nb_sections; i++) {
1796 s = s1->sections[i];
1797 /* when generating a DLL, we include relocations but we may
1798 patch them */
1799 #ifndef ELF_OBJ_ONLY
1800 if (file_type == TCC_OUTPUT_DLL &&
1801 s->sh_type == SHT_RELX &&
1802 !(s->sh_flags & SHF_ALLOC) &&
1803 (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
1804 prepare_dynamic_rel(s1, s)) {
1805 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1806 textrel = 1;
1807 } else
1808 #endif
1809 if ((s1->do_debug && s->sh_type != SHT_RELX) ||
1810 file_type == TCC_OUTPUT_OBJ ||
1811 (s->sh_flags & SHF_ALLOC) ||
1812 i == (s1->nb_sections - 1)
1813 #ifdef TCC_TARGET_ARM
1814 || s->sh_type == SHT_ARM_ATTRIBUTES
1815 #endif
1817 /* we output all sections if debug or object file */
1818 s->sh_size = s->data_offset;
1820 #ifdef TCC_TARGET_ARM
1821 /* XXX: Suppress stack unwinding section. */
1822 if (s->sh_type == SHT_ARM_EXIDX) {
1823 s->sh_flags = 0;
1824 s->sh_size = 0;
1826 #endif
1827 if (s->sh_size || (s->sh_flags & SHF_ALLOC))
1828 s->sh_name = put_elf_str(strsec, s->name);
1830 strsec->sh_size = strsec->data_offset;
1831 return textrel;
1834 /* Info to be copied in dynamic section */
1835 struct dyn_inf {
1836 Section *dynamic;
1837 Section *dynstr;
1838 unsigned long data_offset;
1839 addr_t rel_addr;
1840 addr_t rel_size;
1843 /* Info for GNU_RELRO */
1844 struct ro_inf {
1845 addr_t sh_offset;
1846 addr_t sh_addr;
1847 addr_t sh_size;
1850 /* Assign sections to segments and decide how are sections laid out when loaded
1851 in memory. This function also fills corresponding program headers. */
1852 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr,
1853 int phnum, int phfill,
1854 Section *interp, Section* strsec,
1855 struct dyn_inf *dyninf, struct ro_inf *roinf,
1856 int *sec_order)
1858 int i, sh_order_index, file_offset;
1859 Section *s;
1861 sh_order_index = 1;
1862 file_offset = 0;
1863 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1864 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1866 #ifndef ELF_OBJ_ONLY
1867 if (phnum > 0) { /* phnum is 0 for TCC_OUTPUT_OBJ */
1868 unsigned long s_align;
1869 long long tmp;
1870 addr_t addr;
1871 ElfW(Phdr) *ph;
1872 int j, k, file_type = s1->output_type;
1874 s_align = ELF_PAGE_SIZE;
1875 if (s1->section_align)
1876 s_align = s1->section_align;
1878 if (s1->has_text_addr) {
1879 int a_offset, p_offset;
1880 addr = s1->text_addr;
1881 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1882 ELF_PAGE_SIZE */
1883 a_offset = (int) (addr & (s_align - 1));
1884 p_offset = file_offset & (s_align - 1);
1885 if (a_offset < p_offset)
1886 a_offset += s_align;
1887 file_offset += (a_offset - p_offset);
1888 } else {
1889 if (file_type == TCC_OUTPUT_DLL)
1890 addr = 0;
1891 else
1892 addr = ELF_START_ADDR;
1893 /* compute address after headers */
1894 addr += (file_offset & (s_align - 1));
1897 ph = &phdr[0];
1898 /* Leave one program headers for the program interpreter and one for
1899 the program header table itself if needed. These are done later as
1900 they require section layout to be done first. */
1901 if (interp)
1902 ph += 2;
1904 /* dynamic relocation table information, for .dynamic section */
1905 dyninf->rel_addr = dyninf->rel_size = 0;
1907 /* read only segment mapping for GNU_RELRO */
1908 roinf->sh_offset = roinf->sh_addr = roinf->sh_size = 0;
1910 for(j = 0; j < phfill; j++) {
1911 Section *relocplt = s1->got ? s1->got->relocplt : NULL;
1913 ph->p_type = j == 2 ? PT_TLS : PT_LOAD;
1914 if (j == 0)
1915 ph->p_flags = PF_R | PF_X;
1916 else
1917 ph->p_flags = PF_R | PF_W;
1918 ph->p_align = j == 2 ? 4 : s_align;
1920 /* Decide the layout of sections loaded in memory. This must
1921 be done before program headers are filled since they contain
1922 info about the layout. We do the following ordering: interp,
1923 symbol tables, relocations, progbits, nobits */
1924 /* XXX: do faster and simpler sorting */
1925 for(k = 0; k < 7; k++) {
1926 for(i = 1; i < s1->nb_sections; i++) {
1927 s = s1->sections[i];
1928 /* compute if section should be included */
1929 if (j == 0) {
1930 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1931 SHF_ALLOC)
1932 continue;
1933 } else if (j == 1) {
1934 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1935 (SHF_ALLOC | SHF_WRITE))
1936 continue;
1937 } else {
1938 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1939 (SHF_ALLOC | SHF_WRITE | SHF_TLS))
1940 continue;
1942 if (s == interp) {
1943 if (k != 0)
1944 continue;
1945 } else if ((s->sh_type == SHT_DYNSYM ||
1946 s->sh_type == SHT_STRTAB ||
1947 s->sh_type == SHT_HASH)
1948 && !strstr(s->name, ".stab")) {
1949 if (k != 1)
1950 continue;
1951 } else if (s->sh_type == SHT_RELX) {
1952 if (k != 2 && s != relocplt)
1953 continue;
1954 else if (k != 3 && s == relocplt)
1955 continue;
1956 } else if (s->sh_type == SHT_NOBITS) {
1957 if (k != 6)
1958 continue;
1959 } else if (s == data_ro_section ||
1960 #ifdef CONFIG_TCC_BCHECK
1961 s == bounds_section ||
1962 s == lbounds_section ||
1963 #endif
1964 0) {
1965 if (k != 4)
1966 continue;
1967 } else {
1968 if (k != 5)
1969 continue;
1971 sec_order[sh_order_index++] = i;
1973 /* section matches: we align it and add its size */
1974 tmp = addr;
1975 addr = (addr + s->sh_addralign - 1) &
1976 ~(s->sh_addralign - 1);
1977 file_offset += (int) ( addr - tmp );
1978 s->sh_offset = file_offset;
1979 s->sh_addr = addr;
1981 /* update program header infos */
1982 if (ph->p_offset == 0) {
1983 ph->p_offset = file_offset;
1984 ph->p_vaddr = addr;
1985 ph->p_paddr = ph->p_vaddr;
1987 /* update dynamic relocation infos */
1988 if (s->sh_type == SHT_RELX && s != relocplt) {
1989 if (dyninf->rel_size == 0)
1990 dyninf->rel_addr = addr;
1991 dyninf->rel_size = (addr - dyninf->rel_addr) + s->sh_size;
1993 if (s == data_ro_section ||
1994 #ifdef CONFIG_TCC_BCHECK
1995 s == bounds_section ||
1996 s == lbounds_section ||
1997 #endif
1998 0) {
1999 if (roinf->sh_size == 0) {
2000 roinf->sh_offset = s->sh_offset;
2001 roinf->sh_addr = s->sh_addr;
2003 roinf->sh_size = (addr - roinf->sh_addr) + s->sh_size;
2005 addr += s->sh_size;
2006 if (s->sh_type != SHT_NOBITS)
2007 file_offset += s->sh_size;
2010 if (j == 0) {
2011 /* Make the first PT_LOAD segment include the program
2012 headers itself (and the ELF header as well), it'll
2013 come out with same memory use but will make various
2014 tools like binutils strip work better. */
2015 ph->p_offset &= ~(ph->p_align - 1);
2016 ph->p_vaddr &= ~(ph->p_align - 1);
2017 ph->p_paddr &= ~(ph->p_align - 1);
2019 ph->p_filesz = file_offset - ph->p_offset;
2020 ph->p_memsz = addr - ph->p_vaddr;
2021 ph++;
2022 if (j == 0) {
2023 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
2024 /* if in the middle of a page, we duplicate the page in
2025 memory so that one copy is RX and the other is RW */
2026 if ((addr & (s_align - 1)) != 0)
2027 addr += s_align;
2028 } else {
2029 addr = (addr + s_align - 1) & ~(s_align - 1);
2030 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
2035 #endif /* ELF_OBJ_ONLY */
2037 /* all other sections come after */
2038 for(i = 1; i < s1->nb_sections; i++) {
2039 s = s1->sections[i];
2040 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
2041 continue;
2042 sec_order[sh_order_index++] = i;
2044 file_offset = (file_offset + s->sh_addralign - 1) &
2045 ~(s->sh_addralign - 1);
2046 s->sh_offset = file_offset;
2047 if (s->sh_type != SHT_NOBITS)
2048 file_offset += s->sh_size;
2051 return file_offset;
2054 #ifndef ELF_OBJ_ONLY
2055 /* put dynamic tag */
2056 static void put_dt(Section *dynamic, int dt, addr_t val)
2058 ElfW(Dyn) *dyn;
2059 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
2060 dyn->d_tag = dt;
2061 dyn->d_un.d_val = val;
2064 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
2065 Section *dynamic, Section *note, struct ro_inf *roinf)
2067 ElfW(Phdr) *ph;
2069 /* if interpreter, then add corresponding program header */
2070 if (interp) {
2071 ph = &phdr[0];
2073 ph->p_type = PT_PHDR;
2074 ph->p_offset = sizeof(ElfW(Ehdr));
2075 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
2076 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
2077 ph->p_paddr = ph->p_vaddr;
2078 ph->p_flags = PF_R | PF_X;
2079 ph->p_align = 4; /* interp->sh_addralign; */
2080 ph++;
2082 ph->p_type = PT_INTERP;
2083 ph->p_offset = interp->sh_offset;
2084 ph->p_vaddr = interp->sh_addr;
2085 ph->p_paddr = ph->p_vaddr;
2086 ph->p_filesz = interp->sh_size;
2087 ph->p_memsz = interp->sh_size;
2088 ph->p_flags = PF_R;
2089 ph->p_align = interp->sh_addralign;
2092 if (note) {
2093 ph = &phdr[phnum - 2 - (roinf != NULL)];
2095 ph->p_type = PT_NOTE;
2096 ph->p_offset = note->sh_offset;
2097 ph->p_vaddr = note->sh_addr;
2098 ph->p_paddr = ph->p_vaddr;
2099 ph->p_filesz = note->sh_size;
2100 ph->p_memsz = note->sh_size;
2101 ph->p_flags = PF_R;
2102 ph->p_align = note->sh_addralign;
2105 /* if dynamic section, then add corresponding program header */
2106 if (dynamic) {
2107 ph = &phdr[phnum - 1 - (roinf != NULL)];
2109 ph->p_type = PT_DYNAMIC;
2110 ph->p_offset = dynamic->sh_offset;
2111 ph->p_vaddr = dynamic->sh_addr;
2112 ph->p_paddr = ph->p_vaddr;
2113 ph->p_filesz = dynamic->sh_size;
2114 ph->p_memsz = dynamic->sh_size;
2115 ph->p_flags = PF_R | PF_W;
2116 ph->p_align = dynamic->sh_addralign;
2119 if (roinf) {
2120 ph = &phdr[phnum - 1];
2122 ph->p_type = PT_GNU_RELRO;
2123 ph->p_offset = roinf->sh_offset;
2124 ph->p_vaddr = roinf->sh_addr;
2125 ph->p_paddr = ph->p_vaddr;
2126 ph->p_filesz = roinf->sh_size;
2127 ph->p_memsz = roinf->sh_size;
2128 ph->p_flags = PF_R;
2129 ph->p_align = 1;
2133 /* Fill the dynamic section with tags describing the address and size of
2134 sections */
2135 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2137 Section *dynamic = dyninf->dynamic;
2138 Section *s;
2140 /* put dynamic section entries */
2141 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2142 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2143 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2144 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2145 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2146 #if PTR_SIZE == 8
2147 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2148 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2149 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2150 if (s1->got && s1->got->relocplt) {
2151 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2152 put_dt(dynamic, DT_PLTRELSZ, s1->got->relocplt->data_offset);
2153 put_dt(dynamic, DT_JMPREL, s1->got->relocplt->sh_addr);
2154 put_dt(dynamic, DT_PLTREL, DT_RELA);
2156 put_dt(dynamic, DT_RELACOUNT, 0);
2157 #else
2158 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2159 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2160 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2161 if (s1->got && s1->got->relocplt) {
2162 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2163 put_dt(dynamic, DT_PLTRELSZ, s1->got->relocplt->data_offset);
2164 put_dt(dynamic, DT_JMPREL, s1->got->relocplt->sh_addr);
2165 put_dt(dynamic, DT_PLTREL, DT_REL);
2167 put_dt(dynamic, DT_RELCOUNT, 0);
2168 #endif
2169 if (versym_section && verneed_section) {
2170 /* The dynamic linker can not handle VERSYM without VERNEED */
2171 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2172 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2173 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2175 s = find_section_create (s1, ".preinit_array", 0);
2176 if (s && s->data_offset) {
2177 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2178 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2180 s = find_section_create (s1, ".init_array", 0);
2181 if (s && s->data_offset) {
2182 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2183 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2185 s = find_section_create (s1, ".fini_array", 0);
2186 if (s && s->data_offset) {
2187 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2188 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2190 s = find_section_create (s1, ".init", 0);
2191 if (s && s->data_offset) {
2192 put_dt(dynamic, DT_INIT, s->sh_addr);
2194 s = find_section_create (s1, ".fini", 0);
2195 if (s && s->data_offset) {
2196 put_dt(dynamic, DT_FINI, s->sh_addr);
2198 if (s1->do_debug)
2199 put_dt(dynamic, DT_DEBUG, 0);
2200 put_dt(dynamic, DT_NULL, 0);
2203 /* Relocate remaining sections and symbols (that is those not related to
2204 dynamic linking) */
2205 static int final_sections_reloc(TCCState *s1)
2207 int i;
2208 Section *s;
2210 relocate_syms(s1, s1->symtab, 0);
2212 if (s1->nb_errors != 0)
2213 return -1;
2215 /* relocate sections */
2216 /* XXX: ignore sections with allocated relocations ? */
2217 for(i = 1; i < s1->nb_sections; i++) {
2218 s = s1->sections[i];
2219 if (s->reloc && (s != s1->got || s1->static_link))
2220 relocate_section(s1, s);
2223 /* relocate relocation entries if the relocation tables are
2224 allocated in the executable */
2225 for(i = 1; i < s1->nb_sections; i++) {
2226 s = s1->sections[i];
2227 if ((s->sh_flags & SHF_ALLOC) &&
2228 s->sh_type == SHT_RELX) {
2229 relocate_rel(s1, s);
2232 return 0;
2234 #endif
2236 /* Create an ELF file on disk.
2237 This function handle ELF specific layout requirements */
2238 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2239 int file_offset, int *sec_order)
2241 int i, shnum, offset, size, file_type;
2242 Section *s;
2243 ElfW(Ehdr) ehdr;
2244 ElfW(Shdr) shdr, *sh;
2246 file_type = s1->output_type;
2247 shnum = s1->nb_sections;
2249 memset(&ehdr, 0, sizeof(ehdr));
2251 if (phnum > 0) {
2252 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2253 ehdr.e_phnum = phnum;
2254 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2257 /* align to 4 */
2258 file_offset = (file_offset + 3) & -4;
2260 /* fill header */
2261 ehdr.e_ident[0] = ELFMAG0;
2262 ehdr.e_ident[1] = ELFMAG1;
2263 ehdr.e_ident[2] = ELFMAG2;
2264 ehdr.e_ident[3] = ELFMAG3;
2265 ehdr.e_ident[4] = ELFCLASSW;
2266 ehdr.e_ident[5] = ELFDATA2LSB;
2267 ehdr.e_ident[6] = EV_CURRENT;
2268 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2269 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2270 #endif
2271 #ifdef TCC_TARGET_ARM
2272 #ifdef TCC_ARM_EABI
2273 ehdr.e_ident[EI_OSABI] = 0;
2274 ehdr.e_flags = EF_ARM_EABI_VER4;
2275 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2276 ehdr.e_flags |= EF_ARM_HASENTRY;
2277 if (s1->float_abi == ARM_HARD_FLOAT)
2278 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2279 else
2280 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2281 #else
2282 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2283 #endif
2284 #elif defined TCC_TARGET_RISCV64
2285 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2286 #endif
2287 switch(file_type) {
2288 default:
2289 case TCC_OUTPUT_EXE:
2290 ehdr.e_type = ET_EXEC;
2291 ehdr.e_entry = get_sym_addr(s1, "_start", 1, 0);
2292 break;
2293 case TCC_OUTPUT_DLL:
2294 ehdr.e_type = ET_DYN;
2295 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2296 break;
2297 case TCC_OUTPUT_OBJ:
2298 ehdr.e_type = ET_REL;
2299 break;
2301 ehdr.e_machine = EM_TCC_TARGET;
2302 ehdr.e_version = EV_CURRENT;
2303 ehdr.e_shoff = file_offset;
2304 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2305 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2306 ehdr.e_shnum = shnum;
2307 ehdr.e_shstrndx = shnum - 1;
2309 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2310 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2311 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2313 sort_syms(s1, symtab_section);
2314 for(i = 1; i < s1->nb_sections; i++) {
2315 s = s1->sections[sec_order[i]];
2316 if (s->sh_type != SHT_NOBITS) {
2317 while (offset < s->sh_offset) {
2318 fputc(0, f);
2319 offset++;
2321 size = s->sh_size;
2322 if (size)
2323 fwrite(s->data, 1, size, f);
2324 offset += size;
2328 /* output section headers */
2329 while (offset < ehdr.e_shoff) {
2330 fputc(0, f);
2331 offset++;
2334 for(i = 0; i < s1->nb_sections; i++) {
2335 sh = &shdr;
2336 memset(sh, 0, sizeof(ElfW(Shdr)));
2337 s = s1->sections[i];
2338 if (s) {
2339 sh->sh_name = s->sh_name;
2340 sh->sh_type = s->sh_type;
2341 sh->sh_flags = s->sh_flags;
2342 sh->sh_entsize = s->sh_entsize;
2343 sh->sh_info = s->sh_info;
2344 if (s->link)
2345 sh->sh_link = s->link->sh_num;
2346 sh->sh_addralign = s->sh_addralign;
2347 sh->sh_addr = s->sh_addr;
2348 sh->sh_offset = s->sh_offset;
2349 sh->sh_size = s->sh_size;
2351 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2355 /* Write an elf, coff or "binary" file */
2356 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2357 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2359 int fd, mode, file_type;
2360 FILE *f;
2362 file_type = s1->output_type;
2363 if (file_type == TCC_OUTPUT_OBJ)
2364 mode = 0666;
2365 else
2366 mode = 0777;
2367 unlink(filename);
2368 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2369 if (fd < 0) {
2370 tcc_error_noabort("could not write '%s'", filename);
2371 return -1;
2373 f = fdopen(fd, "wb");
2374 if (s1->verbose)
2375 printf("<- %s\n", filename);
2377 #ifdef TCC_TARGET_COFF
2378 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2379 tcc_output_coff(s1, f);
2380 else
2381 #endif
2382 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2383 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2384 else
2385 tcc_output_binary(s1, f, sec_order);
2386 fclose(f);
2388 return 0;
2391 #ifndef ELF_OBJ_ONLY
2392 /* Sort section headers by assigned sh_addr, remove sections
2393 that we aren't going to output. */
2394 static void tidy_section_headers(TCCState *s1, int *sec_order)
2396 int i, nnew, l, *backmap;
2397 Section **snew, *s;
2398 ElfW(Sym) *sym;
2400 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2401 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2402 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2403 s = s1->sections[sec_order[i]];
2404 if (!i || s->sh_name) {
2405 backmap[sec_order[i]] = nnew;
2406 snew[nnew] = s;
2407 ++nnew;
2408 } else {
2409 backmap[sec_order[i]] = 0;
2410 snew[--l] = s;
2413 for (i = 0; i < nnew; i++) {
2414 s = snew[i];
2415 if (s) {
2416 s->sh_num = i;
2417 if (s->sh_type == SHT_RELX)
2418 s->sh_info = backmap[s->sh_info];
2422 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2423 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2424 sym->st_shndx = backmap[sym->st_shndx];
2425 if ( !s1->static_link ) {
2426 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2427 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2428 sym->st_shndx = backmap[sym->st_shndx];
2430 for (i = 0; i < s1->nb_sections; i++)
2431 sec_order[i] = i;
2432 tcc_free(s1->sections);
2433 s1->sections = snew;
2434 s1->nb_sections = nnew;
2435 tcc_free(backmap);
2437 #endif
2439 #ifdef TCC_TARGET_ARM
2440 static void create_arm_attribute_section(TCCState *s1)
2442 // Needed for DLL support.
2443 static const unsigned char arm_attr[] = {
2444 0x41, // 'A'
2445 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2446 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2447 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2448 0x05, 0x36, 0x00, // 'CPU_name', "6"
2449 0x06, 0x06, // 'CPU_arch', 'v6'
2450 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2451 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2452 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2453 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2454 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2455 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2456 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2457 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2458 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2459 0x1a, 0x02, // 'ABI_enum_size', 'int'
2460 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2461 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2463 Section *attr = new_section(s1, ".ARM.attributes", SHT_ARM_ATTRIBUTES, 0);
2464 unsigned char *ptr = section_ptr_add(attr, sizeof(arm_attr));
2465 attr->sh_addralign = 1;
2466 memcpy(ptr, arm_attr, sizeof(arm_attr));
2467 if (s1->float_abi != ARM_HARD_FLOAT) {
2468 ptr[26] = 0x00; // 'FP_arch', 'No'
2469 ptr[41] = 0x1e; // 'ABI_optimization_goals'
2470 ptr[42] = 0x06; // 'Aggressive Debug'
2473 #endif
2475 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2476 static Section *create_bsd_note_section(TCCState *s1,
2477 const char *name,
2478 const char *value)
2480 Section *s = find_section (s1, name);
2482 if (s->data_offset == 0) {
2483 char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
2484 ElfW(Nhdr) *note = (ElfW(Nhdr) *) ptr;
2486 s->sh_type = SHT_NOTE;
2487 note->n_namesz = 8;
2488 note->n_descsz = 4;
2489 note->n_type = ELF_NOTE_OS_GNU;
2490 strcpy (ptr + sizeof(ElfW(Nhdr)), value);
2492 return s;
2494 #endif
2496 /* Output an elf, coff or binary file */
2497 /* XXX: suppress unneeded sections */
2498 static int elf_output_file(TCCState *s1, const char *filename)
2500 int i, ret, phnum, phfill, shnum, file_type, file_offset, *sec_order;
2501 struct dyn_inf dyninf = {0};
2502 struct ro_inf roinf;
2503 #if !TARGETOS_FreeBSD && !TARGETOS_NetBSD && !defined(__APPLE__) && !defined(_WIN32)
2504 struct ro_inf *roinf_use = NULL;
2505 #endif
2506 ElfW(Phdr) *phdr;
2507 Section *strsec, *interp, *dynamic, *dynstr, *note = NULL;
2509 file_type = s1->output_type;
2511 #ifdef TCC_TARGET_ARM
2512 create_arm_attribute_section (s1);
2513 #endif
2514 #if TARGETOS_OpenBSD
2515 if (file_type != TCC_OUTPUT_OBJ)
2516 note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
2517 #endif
2518 #if TARGETOS_NetBSD
2519 if (file_type != TCC_OUTPUT_OBJ)
2520 note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD");
2521 #endif
2523 s1->nb_errors = 0;
2524 ret = -1;
2525 phdr = NULL;
2526 sec_order = NULL;
2527 interp = dynamic = dynstr = NULL; /* avoid warning */
2529 #ifndef ELF_OBJ_ONLY
2530 if (file_type != TCC_OUTPUT_OBJ) {
2531 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2532 tcc_add_runtime(s1);
2533 resolve_common_syms(s1);
2535 if (!s1->static_link) {
2536 if (file_type == TCC_OUTPUT_EXE) {
2537 char *ptr;
2538 /* allow override the dynamic loader */
2539 const char *elfint = getenv("LD_SO");
2540 if (elfint == NULL)
2541 elfint = DEFAULT_ELFINTERP(s1);
2542 /* add interpreter section only if executable */
2543 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2544 interp->sh_addralign = 1;
2545 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2546 strcpy(ptr, elfint);
2549 /* add dynamic symbol table */
2550 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2551 ".dynstr",
2552 ".hash", SHF_ALLOC);
2553 /* Number of local symbols (readelf complains if not set) */
2554 s1->dynsym->sh_info = 1;
2555 dynstr = s1->dynsym->link;
2556 /* add dynamic section */
2557 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2558 SHF_ALLOC | SHF_WRITE);
2559 dynamic->link = dynstr;
2560 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2562 build_got(s1);
2564 if (file_type == TCC_OUTPUT_EXE) {
2565 bind_exe_dynsyms(s1);
2566 if (s1->nb_errors)
2567 goto the_end;
2568 bind_libs_dynsyms(s1);
2569 } else {
2570 /* shared library case: simply export all global symbols */
2571 export_global_syms(s1);
2574 build_got_entries(s1);
2575 version_add (s1);
2577 #endif
2579 /* we add a section for symbols */
2580 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2581 put_elf_str(strsec, "");
2583 /* Allocate strings for section names */
2584 ret = alloc_sec_names(s1, file_type, strsec);
2586 #ifndef ELF_OBJ_ONLY
2587 if (dynamic) {
2588 int i;
2589 /* add a list of needed dlls */
2590 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2591 DLLReference *dllref = s1->loaded_dlls[i];
2592 if (dllref->level == 0)
2593 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2596 if (s1->rpath)
2597 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2598 put_elf_str(dynstr, s1->rpath));
2600 if (file_type == TCC_OUTPUT_DLL) {
2601 if (s1->soname)
2602 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2603 /* XXX: currently, since we do not handle PIC code, we
2604 must relocate the readonly segments */
2605 if (ret)
2606 put_dt(dynamic, DT_TEXTREL, 0);
2609 if (s1->symbolic)
2610 put_dt(dynamic, DT_SYMBOLIC, 0);
2612 dyninf.dynamic = dynamic;
2613 dyninf.dynstr = dynstr;
2614 /* remember offset and reserve space for 2nd call below */
2615 dyninf.data_offset = dynamic->data_offset;
2616 fill_dynamic(s1, &dyninf);
2617 dynamic->sh_size = dynamic->data_offset;
2618 dynstr->sh_size = dynstr->data_offset;
2620 #endif
2622 for (i = 1; i < s1->nb_sections &&
2623 !(s1->sections[i]->sh_flags & SHF_TLS); i++);
2624 phfill = 2 + (i < s1->nb_sections);
2626 /* compute number of program headers */
2627 if (file_type == TCC_OUTPUT_OBJ)
2628 phnum = phfill = 0;
2629 else if (file_type == TCC_OUTPUT_DLL)
2630 phnum = 3;
2631 else if (s1->static_link)
2632 phnum = 2;
2633 else {
2634 phnum = 5 + (i < s1->nb_sections);
2637 phnum += note != NULL;
2639 #if !TARGETOS_FreeBSD && !TARGETOS_NetBSD && !defined(__APPLE__) && !defined(_WIN32)
2640 /* GNU_RELRO */
2641 if (file_type != TCC_OUTPUT_OBJ) {
2642 phnum++;
2643 roinf_use = &roinf;
2645 #endif
2647 /* allocate program segment headers */
2648 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2650 /* compute number of sections */
2651 shnum = s1->nb_sections;
2653 /* this array is used to reorder sections in the output file */
2654 sec_order = tcc_malloc(sizeof(int) * shnum);
2655 sec_order[0] = 0;
2657 /* compute section to program header mapping */
2658 file_offset = layout_sections(s1, phdr, phnum, phfill, interp, strsec,
2659 &dyninf, &roinf, sec_order);
2661 #ifndef ELF_OBJ_ONLY
2662 /* Fill remaining program header and finalize relocation related to dynamic
2663 linking. */
2664 if (file_type != TCC_OUTPUT_OBJ) {
2665 fill_unloadable_phdr(phdr, phnum, interp, dynamic, note, roinf_use);
2666 if (dynamic) {
2667 ElfW(Sym) *sym;
2668 dynamic->data_offset = dyninf.data_offset;
2669 fill_dynamic(s1, &dyninf);
2671 /* put in GOT the dynamic section address and relocate PLT */
2672 write32le(s1->got->data, dynamic->sh_addr);
2673 if (file_type == TCC_OUTPUT_EXE
2674 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2675 relocate_plt(s1);
2677 /* relocate symbols in .dynsym now that final addresses are known */
2678 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2679 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2680 /* do symbol relocation */
2681 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2686 /* if building executable or DLL, then relocate each section
2687 except the GOT which is already relocated */
2688 ret = final_sections_reloc(s1);
2689 if (ret)
2690 goto the_end;
2691 tidy_section_headers(s1, sec_order);
2693 /* Perform relocation to GOT or PLT entries */
2694 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2695 fill_got(s1);
2696 else if (s1->got)
2697 fill_local_got_entries(s1);
2699 #endif
2701 /* Create the ELF file with name 'filename' */
2702 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2703 s1->nb_sections = shnum;
2704 goto the_end;
2705 the_end:
2706 tcc_free(sec_order);
2707 tcc_free(phdr);
2708 return ret;
2711 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2713 int ret;
2714 #ifdef TCC_TARGET_PE
2715 if (s->output_type != TCC_OUTPUT_OBJ) {
2716 ret = pe_output_file(s, filename);
2717 } else
2718 #elif TCC_TARGET_MACHO
2719 if (s->output_type != TCC_OUTPUT_OBJ) {
2720 ret = macho_output_file(s, filename);
2721 } else
2722 #endif
2723 ret = elf_output_file(s, filename);
2724 return ret;
2727 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
2728 char *cbuf = buf;
2729 size_t rnum = 0;
2730 while (1) {
2731 ssize_t num = read(fd, cbuf, count-rnum);
2732 if (num < 0) return num;
2733 if (num == 0) return rnum;
2734 rnum += num;
2735 cbuf += num;
2739 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
2741 void *data;
2743 data = tcc_malloc(size);
2744 lseek(fd, file_offset, SEEK_SET);
2745 full_read(fd, data, size);
2746 return data;
2749 typedef struct SectionMergeInfo {
2750 Section *s; /* corresponding existing section */
2751 unsigned long offset; /* offset of the new section in the existing section */
2752 unsigned long size; /* size of the new section in the existing section */
2753 uint8_t new_section; /* true if section 's' was added */
2754 uint8_t link_once; /* true if link once section */
2755 } SectionMergeInfo;
2757 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2759 int size = full_read(fd, h, sizeof *h);
2760 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2761 if (h->e_type == ET_REL)
2762 return AFF_BINTYPE_REL;
2763 if (h->e_type == ET_DYN)
2764 return AFF_BINTYPE_DYN;
2765 } else if (size >= 8) {
2766 if (0 == memcmp(h, ARMAG, 8))
2767 return AFF_BINTYPE_AR;
2768 #ifdef TCC_TARGET_COFF
2769 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2770 return AFF_BINTYPE_C67;
2771 #endif
2773 return 0;
2776 /* load an object file and merge it with current files */
2777 /* XXX: handle correctly stab (debug) info */
2778 ST_FUNC int tcc_load_object_file(TCCState *s1,
2779 int fd, unsigned long file_offset)
2781 ElfW(Ehdr) ehdr;
2782 ElfW(Shdr) *shdr, *sh;
2783 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2784 char *strsec, *strtab;
2785 int stab_index, stabstr_index;
2786 int *old_to_new_syms;
2787 char *sh_name, *name;
2788 SectionMergeInfo *sm_table, *sm;
2789 ElfW(Sym) *sym, *symtab;
2790 ElfW_Rel *rel;
2791 Section *s;
2793 lseek(fd, file_offset, SEEK_SET);
2794 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2795 goto fail1;
2796 /* test CPU specific stuff */
2797 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2798 ehdr.e_machine != EM_TCC_TARGET) {
2799 fail1:
2800 tcc_error_noabort("invalid object file");
2801 return -1;
2803 /* read sections */
2804 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2805 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2806 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2808 /* load section names */
2809 sh = &shdr[ehdr.e_shstrndx];
2810 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2812 /* load symtab and strtab */
2813 old_to_new_syms = NULL;
2814 symtab = NULL;
2815 strtab = NULL;
2816 nb_syms = 0;
2817 seencompressed = 0;
2818 stab_index = stabstr_index = 0;
2820 for(i = 1; i < ehdr.e_shnum; i++) {
2821 sh = &shdr[i];
2822 if (sh->sh_type == SHT_SYMTAB) {
2823 if (symtab) {
2824 tcc_error_noabort("object must contain only one symtab");
2825 fail:
2826 ret = -1;
2827 goto the_end;
2829 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2830 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2831 sm_table[i].s = symtab_section;
2833 /* now load strtab */
2834 sh = &shdr[sh->sh_link];
2835 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2837 if (sh->sh_flags & SHF_COMPRESSED)
2838 seencompressed = 1;
2841 /* now examine each section and try to merge its content with the
2842 ones in memory */
2843 for(i = 1; i < ehdr.e_shnum; i++) {
2844 /* no need to examine section name strtab */
2845 if (i == ehdr.e_shstrndx)
2846 continue;
2847 sh = &shdr[i];
2848 if (sh->sh_type == SHT_RELX)
2849 sh = &shdr[sh->sh_info];
2850 /* ignore sections types we do not handle (plus relocs to those) */
2851 if (sh->sh_type != SHT_PROGBITS &&
2852 #ifdef TCC_ARM_EABI
2853 sh->sh_type != SHT_ARM_EXIDX &&
2854 #endif
2855 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2856 sh->sh_type != SHT_X86_64_UNWIND &&
2857 #endif
2858 sh->sh_type != SHT_NOTE &&
2859 sh->sh_type != SHT_NOBITS &&
2860 sh->sh_type != SHT_PREINIT_ARRAY &&
2861 sh->sh_type != SHT_INIT_ARRAY &&
2862 sh->sh_type != SHT_FINI_ARRAY &&
2863 strcmp(strsec + sh->sh_name, ".stabstr")
2865 continue;
2866 if (seencompressed
2867 && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
2868 continue;
2870 sh = &shdr[i];
2871 sh_name = strsec + sh->sh_name;
2872 if (sh->sh_addralign < 1)
2873 sh->sh_addralign = 1;
2874 /* find corresponding section, if any */
2875 for(j = 1; j < s1->nb_sections;j++) {
2876 s = s1->sections[j];
2877 if (!strcmp(s->name, sh_name)) {
2878 if (!strncmp(sh_name, ".gnu.linkonce",
2879 sizeof(".gnu.linkonce") - 1)) {
2880 /* if a 'linkonce' section is already present, we
2881 do not add it again. It is a little tricky as
2882 symbols can still be defined in
2883 it. */
2884 sm_table[i].link_once = 1;
2885 goto next;
2887 if (stab_section) {
2888 if (s == stab_section)
2889 stab_index = i;
2890 if (s == stab_section->link)
2891 stabstr_index = i;
2893 goto found;
2896 /* not found: create new section */
2897 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2898 /* take as much info as possible from the section. sh_link and
2899 sh_info will be updated later */
2900 s->sh_addralign = sh->sh_addralign;
2901 s->sh_entsize = sh->sh_entsize;
2902 sm_table[i].new_section = 1;
2903 found:
2904 if (sh->sh_type != s->sh_type) {
2905 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2906 if (strcmp (s->name, ".eh_frame"))
2907 #endif
2909 tcc_error_noabort("invalid section type");
2910 goto fail;
2913 /* align start of section */
2914 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
2915 if (sh->sh_addralign > s->sh_addralign)
2916 s->sh_addralign = sh->sh_addralign;
2917 sm_table[i].offset = s->data_offset;
2918 sm_table[i].size = sh->sh_size;
2919 sm_table[i].s = s;
2920 /* concatenate sections */
2921 size = sh->sh_size;
2922 if (sh->sh_type != SHT_NOBITS) {
2923 unsigned char *ptr;
2924 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2925 ptr = section_ptr_add(s, size);
2926 full_read(fd, ptr, size);
2927 } else {
2928 s->data_offset += size;
2930 next: ;
2933 /* gr relocate stab strings */
2934 if (stab_index && stabstr_index) {
2935 Stab_Sym *a, *b;
2936 unsigned o;
2937 s = sm_table[stab_index].s;
2938 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2939 b = (Stab_Sym *)(s->data + s->data_offset);
2940 o = sm_table[stabstr_index].offset;
2941 while (a < b) {
2942 if (a->n_strx)
2943 a->n_strx += o;
2944 a++;
2948 /* second short pass to update sh_link and sh_info fields of new
2949 sections */
2950 for(i = 1; i < ehdr.e_shnum; i++) {
2951 s = sm_table[i].s;
2952 if (!s || !sm_table[i].new_section)
2953 continue;
2954 sh = &shdr[i];
2955 if (sh->sh_link > 0)
2956 s->link = sm_table[sh->sh_link].s;
2957 if (sh->sh_type == SHT_RELX) {
2958 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2959 /* update backward link */
2960 s1->sections[s->sh_info]->reloc = s;
2964 /* resolve symbols */
2965 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2967 sym = symtab + 1;
2968 for(i = 1; i < nb_syms; i++, sym++) {
2969 if (sym->st_shndx != SHN_UNDEF &&
2970 sym->st_shndx < SHN_LORESERVE) {
2971 sm = &sm_table[sym->st_shndx];
2972 if (sm->link_once) {
2973 /* if a symbol is in a link once section, we use the
2974 already defined symbol. It is very important to get
2975 correct relocations */
2976 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2977 name = strtab + sym->st_name;
2978 sym_index = find_elf_sym(symtab_section, name);
2979 if (sym_index)
2980 old_to_new_syms[i] = sym_index;
2982 continue;
2984 /* if no corresponding section added, no need to add symbol */
2985 if (!sm->s)
2986 continue;
2987 /* convert section number */
2988 sym->st_shndx = sm->s->sh_num;
2989 /* offset value */
2990 sym->st_value += sm->offset;
2992 /* add symbol */
2993 name = strtab + sym->st_name;
2994 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2995 sym->st_info, sym->st_other,
2996 sym->st_shndx, name);
2997 old_to_new_syms[i] = sym_index;
3000 /* third pass to patch relocation entries */
3001 for(i = 1; i < ehdr.e_shnum; i++) {
3002 s = sm_table[i].s;
3003 if (!s)
3004 continue;
3005 sh = &shdr[i];
3006 offset = sm_table[i].offset;
3007 size = sm_table[i].size;
3008 switch(s->sh_type) {
3009 case SHT_RELX:
3010 /* take relocation offset information */
3011 offseti = sm_table[sh->sh_info].offset;
3012 for (rel = (ElfW_Rel *) s->data + (offset / sizeof(*rel));
3013 rel < (ElfW_Rel *) s->data + ((offset + size) / sizeof(*rel));
3014 rel++) {
3015 int type;
3016 unsigned sym_index;
3017 /* convert symbol index */
3018 type = ELFW(R_TYPE)(rel->r_info);
3019 sym_index = ELFW(R_SYM)(rel->r_info);
3020 /* NOTE: only one symtab assumed */
3021 if (sym_index >= nb_syms)
3022 goto invalid_reloc;
3023 sym_index = old_to_new_syms[sym_index];
3024 /* ignore link_once in rel section. */
3025 if (!sym_index && !sm_table[sh->sh_info].link_once
3026 #ifdef TCC_TARGET_ARM
3027 && type != R_ARM_V4BX
3028 #elif defined TCC_TARGET_RISCV64
3029 && type != R_RISCV_ALIGN
3030 && type != R_RISCV_RELAX
3031 #endif
3033 invalid_reloc:
3034 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3035 i, strsec + sh->sh_name, (int)rel->r_offset);
3036 goto fail;
3038 rel->r_info = ELFW(R_INFO)(sym_index, type);
3039 /* offset the relocation offset */
3040 rel->r_offset += offseti;
3041 #ifdef TCC_TARGET_ARM
3042 /* Jumps and branches from a Thumb code to a PLT entry need
3043 special handling since PLT entries are ARM code.
3044 Unconditional bl instructions referencing PLT entries are
3045 handled by converting these instructions into blx
3046 instructions. Other case of instructions referencing a PLT
3047 entry require to add a Thumb stub before the PLT entry to
3048 switch to ARM mode. We set bit plt_thumb_stub of the
3049 attribute of a symbol to indicate such a case. */
3050 if (type == R_ARM_THM_JUMP24)
3051 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
3052 #endif
3054 break;
3055 default:
3056 break;
3060 ret = 0;
3061 the_end:
3062 tcc_free(symtab);
3063 tcc_free(strtab);
3064 tcc_free(old_to_new_syms);
3065 tcc_free(sm_table);
3066 tcc_free(strsec);
3067 tcc_free(shdr);
3068 return ret;
3071 typedef struct ArchiveHeader {
3072 char ar_name[16]; /* name of this member */
3073 char ar_date[12]; /* file mtime */
3074 char ar_uid[6]; /* owner uid; printed as decimal */
3075 char ar_gid[6]; /* owner gid; printed as decimal */
3076 char ar_mode[8]; /* file mode, printed as octal */
3077 char ar_size[10]; /* file size, printed as decimal */
3078 char ar_fmag[2]; /* should contain ARFMAG */
3079 } ArchiveHeader;
3081 #define ARFMAG "`\n"
3083 static unsigned long long get_be(const uint8_t *b, int n)
3085 unsigned long long ret = 0;
3086 while (n)
3087 ret = (ret << 8) | *b++, --n;
3088 return ret;
3091 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
3093 char *p, *e;
3094 int len;
3095 lseek(fd, offset, SEEK_SET);
3096 len = full_read(fd, hdr, sizeof(ArchiveHeader));
3097 if (len != sizeof(ArchiveHeader))
3098 return len ? -1 : 0;
3099 p = hdr->ar_name;
3100 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
3101 --e;
3102 *e = '\0';
3103 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
3104 return len;
3107 /* load only the objects which resolve undefined symbols */
3108 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
3110 int i, bound, nsyms, sym_index, len, ret = -1;
3111 unsigned long long off;
3112 uint8_t *data;
3113 const char *ar_names, *p;
3114 const uint8_t *ar_index;
3115 ElfW(Sym) *sym;
3116 ArchiveHeader hdr;
3118 data = tcc_malloc(size);
3119 if (full_read(fd, data, size) != size)
3120 goto the_end;
3121 nsyms = get_be(data, entrysize);
3122 ar_index = data + entrysize;
3123 ar_names = (char *) ar_index + nsyms * entrysize;
3125 do {
3126 bound = 0;
3127 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
3128 Section *s = symtab_section;
3129 sym_index = find_elf_sym(s, p);
3130 if (!sym_index)
3131 continue;
3132 sym = &((ElfW(Sym) *)s->data)[sym_index];
3133 if(sym->st_shndx != SHN_UNDEF)
3134 continue;
3135 off = get_be(ar_index + i * entrysize, entrysize);
3136 len = read_ar_header(fd, off, &hdr);
3137 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
3138 tcc_error_noabort("invalid archive");
3139 goto the_end;
3141 off += len;
3142 if (s1->verbose == 2)
3143 printf(" -> %s\n", hdr.ar_name);
3144 if (tcc_load_object_file(s1, fd, off) < 0)
3145 goto the_end;
3146 ++bound;
3148 } while(bound);
3149 ret = 0;
3150 the_end:
3151 tcc_free(data);
3152 return ret;
3155 /* load a '.a' file */
3156 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
3158 ArchiveHeader hdr;
3159 /* char magic[8]; */
3160 int size, len;
3161 unsigned long file_offset;
3162 ElfW(Ehdr) ehdr;
3164 /* skip magic which was already checked */
3165 /* full_read(fd, magic, sizeof(magic)); */
3166 file_offset = sizeof ARMAG - 1;
3168 for(;;) {
3169 len = read_ar_header(fd, file_offset, &hdr);
3170 if (len == 0)
3171 return 0;
3172 if (len < 0) {
3173 tcc_error_noabort("invalid archive");
3174 return -1;
3176 file_offset += len;
3177 size = strtol(hdr.ar_size, NULL, 0);
3178 /* align to even */
3179 size = (size + 1) & ~1;
3180 if (alacarte) {
3181 /* coff symbol table : we handle it */
3182 if (!strcmp(hdr.ar_name, "/"))
3183 return tcc_load_alacarte(s1, fd, size, 4);
3184 if (!strcmp(hdr.ar_name, "/SYM64/"))
3185 return tcc_load_alacarte(s1, fd, size, 8);
3186 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3187 if (s1->verbose == 2)
3188 printf(" -> %s\n", hdr.ar_name);
3189 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3190 return -1;
3192 file_offset += size;
3196 #ifndef ELF_OBJ_ONLY
3197 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3198 LV, maybe create a new entry for (LIB,VERSION). */
3199 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3201 while (i >= *n) {
3202 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3203 (*lv)[(*n)++] = -1;
3205 if ((*lv)[i] == -1) {
3206 int v, prev_same_lib = -1;
3207 for (v = 0; v < nb_sym_versions; v++) {
3208 if (strcmp(sym_versions[v].lib, lib))
3209 continue;
3210 prev_same_lib = v;
3211 if (!strcmp(sym_versions[v].version, version))
3212 break;
3214 if (v == nb_sym_versions) {
3215 sym_versions = tcc_realloc (sym_versions,
3216 (v + 1) * sizeof(*sym_versions));
3217 sym_versions[v].lib = tcc_strdup(lib);
3218 sym_versions[v].version = tcc_strdup(version);
3219 sym_versions[v].out_index = 0;
3220 sym_versions[v].prev_same_lib = prev_same_lib;
3221 nb_sym_versions++;
3223 (*lv)[i] = v;
3227 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3228 VERNDX. */
3229 static void
3230 set_sym_version(TCCState *s1, int sym_index, int verndx)
3232 if (sym_index >= nb_sym_to_version) {
3233 int newelems = sym_index ? sym_index * 2 : 1;
3234 sym_to_version = tcc_realloc(sym_to_version,
3235 newelems * sizeof(*sym_to_version));
3236 memset(sym_to_version + nb_sym_to_version, -1,
3237 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3238 nb_sym_to_version = newelems;
3240 if (sym_to_version[sym_index] < 0)
3241 sym_to_version[sym_index] = verndx;
3244 struct versym_info {
3245 int nb_versyms;
3246 ElfW(Verdef) *verdef;
3247 ElfW(Verneed) *verneed;
3248 ElfW(Half) *versym;
3249 int nb_local_ver, *local_ver;
3253 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3255 char *lib, *version;
3256 uint32_t next;
3257 int i;
3259 #define DEBUG_VERSION 0
3261 if (v->versym && v->verdef) {
3262 ElfW(Verdef) *vdef = v->verdef;
3263 lib = NULL;
3264 do {
3265 ElfW(Verdaux) *verdaux =
3266 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3268 #if DEBUG_VERSION
3269 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3270 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3271 vdef->vd_hash);
3272 #endif
3273 if (vdef->vd_cnt) {
3274 version = dynstr + verdaux->vda_name;
3276 if (lib == NULL)
3277 lib = version;
3278 else
3279 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3280 lib, version);
3281 #if DEBUG_VERSION
3282 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3283 #endif
3285 next = vdef->vd_next;
3286 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3287 } while (next);
3289 if (v->versym && v->verneed) {
3290 ElfW(Verneed) *vneed = v->verneed;
3291 do {
3292 ElfW(Vernaux) *vernaux =
3293 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3295 lib = dynstr + vneed->vn_file;
3296 #if DEBUG_VERSION
3297 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3298 #endif
3299 for (i = 0; i < vneed->vn_cnt; i++) {
3300 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3301 version = dynstr + vernaux->vna_name;
3302 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3303 lib, version);
3304 #if DEBUG_VERSION
3305 printf (" vernaux(%u): %u %u %s\n",
3306 vernaux->vna_other, vernaux->vna_hash,
3307 vernaux->vna_flags, version);
3308 #endif
3310 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3312 next = vneed->vn_next;
3313 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3314 } while (next);
3317 #if DEBUG_VERSION
3318 for (i = 0; i < v->nb_local_ver; i++) {
3319 if (v->local_ver[i] > 0) {
3320 printf ("%d: lib: %s, version %s\n",
3321 i, sym_versions[v->local_ver[i]].lib,
3322 sym_versions[v->local_ver[i]].version);
3325 #endif
3328 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3329 is referenced by the user (so it should be added as DT_NEEDED in
3330 the generated ELF file) */
3331 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3333 ElfW(Ehdr) ehdr;
3334 ElfW(Shdr) *shdr, *sh, *sh1;
3335 int i, j, nb_syms, nb_dts, sym_bind, ret;
3336 ElfW(Sym) *sym, *dynsym;
3337 ElfW(Dyn) *dt, *dynamic;
3339 char *dynstr;
3340 int sym_index;
3341 const char *name, *soname;
3342 DLLReference *dllref;
3343 struct versym_info v;
3345 full_read(fd, &ehdr, sizeof(ehdr));
3347 /* test CPU specific stuff */
3348 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3349 ehdr.e_machine != EM_TCC_TARGET) {
3350 tcc_error_noabort("bad architecture");
3351 return -1;
3354 /* read sections */
3355 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3357 /* load dynamic section and dynamic symbols */
3358 nb_syms = 0;
3359 nb_dts = 0;
3360 dynamic = NULL;
3361 dynsym = NULL; /* avoid warning */
3362 dynstr = NULL; /* avoid warning */
3363 memset(&v, 0, sizeof v);
3365 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3366 switch(sh->sh_type) {
3367 case SHT_DYNAMIC:
3368 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3369 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3370 break;
3371 case SHT_DYNSYM:
3372 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3373 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3374 sh1 = &shdr[sh->sh_link];
3375 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3376 break;
3377 case SHT_GNU_verdef:
3378 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3379 break;
3380 case SHT_GNU_verneed:
3381 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3382 break;
3383 case SHT_GNU_versym:
3384 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3385 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3386 break;
3387 default:
3388 break;
3392 /* compute the real library name */
3393 soname = tcc_basename(filename);
3395 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3396 if (dt->d_tag == DT_SONAME) {
3397 soname = dynstr + dt->d_un.d_val;
3401 /* if the dll is already loaded, do not load it */
3402 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3403 dllref = s1->loaded_dlls[i];
3404 if (!strcmp(soname, dllref->name)) {
3405 /* but update level if needed */
3406 if (level < dllref->level)
3407 dllref->level = level;
3408 ret = 0;
3409 goto the_end;
3413 if (v.nb_versyms != nb_syms)
3414 tcc_free (v.versym), v.versym = NULL;
3415 else
3416 store_version(s1, &v, dynstr);
3418 /* add the dll and its level */
3419 tcc_add_dllref(s1, soname)->level = level;
3421 /* add dynamic symbols in dynsym_section */
3422 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3423 sym_bind = ELFW(ST_BIND)(sym->st_info);
3424 if (sym_bind == STB_LOCAL)
3425 continue;
3426 name = dynstr + sym->st_name;
3427 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3428 sym->st_info, sym->st_other, sym->st_shndx, name);
3429 if (v.versym) {
3430 ElfW(Half) vsym = v.versym[i];
3431 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3432 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3436 /* load all referenced DLLs */
3437 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3438 switch(dt->d_tag) {
3439 case DT_NEEDED:
3440 name = dynstr + dt->d_un.d_val;
3441 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3442 dllref = s1->loaded_dlls[j];
3443 if (!strcmp(name, dllref->name))
3444 goto already_loaded;
3446 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3447 tcc_error_noabort("referenced dll '%s' not found", name);
3448 ret = -1;
3449 goto the_end;
3451 already_loaded:
3452 break;
3455 ret = 0;
3456 the_end:
3457 tcc_free(dynstr);
3458 tcc_free(dynsym);
3459 tcc_free(dynamic);
3460 tcc_free(shdr);
3461 tcc_free(v.local_ver);
3462 tcc_free(v.verdef);
3463 tcc_free(v.verneed);
3464 tcc_free(v.versym);
3465 return ret;
3468 #define LD_TOK_NAME 256
3469 #define LD_TOK_EOF (-1)
3471 static int ld_inp(TCCState *s1)
3473 char b;
3474 if (s1->cc != -1) {
3475 int c = s1->cc;
3476 s1->cc = -1;
3477 return c;
3479 if (1 == read(s1->fd, &b, 1))
3480 return b;
3481 return CH_EOF;
3484 /* return next ld script token */
3485 static int ld_next(TCCState *s1, char *name, int name_size)
3487 int c, d, ch;
3488 char *q;
3490 redo:
3491 ch = ld_inp(s1);
3492 switch(ch) {
3493 case ' ':
3494 case '\t':
3495 case '\f':
3496 case '\v':
3497 case '\r':
3498 case '\n':
3499 goto redo;
3500 case '/':
3501 ch = ld_inp(s1);
3502 if (ch == '*') { /* comment */
3503 for (d = 0;; d = ch) {
3504 ch = ld_inp(s1);
3505 if (ch == CH_EOF || (ch == '/' && d == '*'))
3506 break;
3508 goto redo;
3509 } else {
3510 q = name;
3511 *q++ = '/';
3512 goto parse_name;
3514 break;
3515 case '\\':
3516 /* case 'a' ... 'z': */
3517 case 'a':
3518 case 'b':
3519 case 'c':
3520 case 'd':
3521 case 'e':
3522 case 'f':
3523 case 'g':
3524 case 'h':
3525 case 'i':
3526 case 'j':
3527 case 'k':
3528 case 'l':
3529 case 'm':
3530 case 'n':
3531 case 'o':
3532 case 'p':
3533 case 'q':
3534 case 'r':
3535 case 's':
3536 case 't':
3537 case 'u':
3538 case 'v':
3539 case 'w':
3540 case 'x':
3541 case 'y':
3542 case 'z':
3543 /* case 'A' ... 'z': */
3544 case 'A':
3545 case 'B':
3546 case 'C':
3547 case 'D':
3548 case 'E':
3549 case 'F':
3550 case 'G':
3551 case 'H':
3552 case 'I':
3553 case 'J':
3554 case 'K':
3555 case 'L':
3556 case 'M':
3557 case 'N':
3558 case 'O':
3559 case 'P':
3560 case 'Q':
3561 case 'R':
3562 case 'S':
3563 case 'T':
3564 case 'U':
3565 case 'V':
3566 case 'W':
3567 case 'X':
3568 case 'Y':
3569 case 'Z':
3570 case '_':
3571 case '.':
3572 case '$':
3573 case '~':
3574 q = name;
3575 parse_name:
3576 for(;;) {
3577 if (!((ch >= 'a' && ch <= 'z') ||
3578 (ch >= 'A' && ch <= 'Z') ||
3579 (ch >= '0' && ch <= '9') ||
3580 strchr("/.-_+=$:\\,~", ch)))
3581 break;
3582 if ((q - name) < name_size - 1) {
3583 *q++ = ch;
3585 ch = ld_inp(s1);
3587 s1->cc = ch;
3588 *q = '\0';
3589 c = LD_TOK_NAME;
3590 break;
3591 case CH_EOF:
3592 c = LD_TOK_EOF;
3593 break;
3594 default:
3595 c = ch;
3596 break;
3598 return c;
3601 static int ld_add_file(TCCState *s1, const char filename[])
3603 if (filename[0] == '/') {
3604 if (CONFIG_SYSROOT[0] == '\0'
3605 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3606 return 0;
3607 filename = tcc_basename(filename);
3609 return tcc_add_dll(s1, filename, 0);
3612 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3614 char filename[1024], libname[1024];
3615 int t, group, nblibs = 0, ret = 0;
3616 char **libs = NULL;
3618 group = !strcmp(cmd, "GROUP");
3619 if (!as_needed)
3620 s1->new_undef_sym = 0;
3621 t = ld_next(s1, filename, sizeof(filename));
3622 if (t != '(') {
3623 tcc_error_noabort("( expected");
3624 ret = -1;
3625 goto lib_parse_error;
3627 t = ld_next(s1, filename, sizeof(filename));
3628 for(;;) {
3629 libname[0] = '\0';
3630 if (t == LD_TOK_EOF) {
3631 tcc_error_noabort("unexpected end of file");
3632 ret = -1;
3633 goto lib_parse_error;
3634 } else if (t == ')') {
3635 break;
3636 } else if (t == '-') {
3637 t = ld_next(s1, filename, sizeof(filename));
3638 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3639 tcc_error_noabort("library name expected");
3640 ret = -1;
3641 goto lib_parse_error;
3643 pstrcpy(libname, sizeof libname, &filename[1]);
3644 if (s1->static_link) {
3645 snprintf(filename, sizeof filename, "lib%s.a", libname);
3646 } else {
3647 snprintf(filename, sizeof filename, "lib%s.so", libname);
3649 } else if (t != LD_TOK_NAME) {
3650 tcc_error_noabort("filename expected");
3651 ret = -1;
3652 goto lib_parse_error;
3654 if (!strcmp(filename, "AS_NEEDED")) {
3655 ret = ld_add_file_list(s1, cmd, 1);
3656 if (ret)
3657 goto lib_parse_error;
3658 } else {
3659 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3660 if (!as_needed) {
3661 ret = ld_add_file(s1, filename);
3662 if (ret)
3663 goto lib_parse_error;
3664 if (group) {
3665 /* Add the filename *and* the libname to avoid future conversions */
3666 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3667 if (libname[0] != '\0')
3668 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3672 t = ld_next(s1, filename, sizeof(filename));
3673 if (t == ',') {
3674 t = ld_next(s1, filename, sizeof(filename));
3677 if (group && !as_needed) {
3678 while (s1->new_undef_sym) {
3679 int i;
3680 s1->new_undef_sym = 0;
3681 for (i = 0; i < nblibs; i ++)
3682 ld_add_file(s1, libs[i]);
3685 lib_parse_error:
3686 dynarray_reset(&libs, &nblibs);
3687 return ret;
3690 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3691 files */
3692 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3694 char cmd[64];
3695 char filename[1024];
3696 int t, ret;
3698 s1->fd = fd;
3699 s1->cc = -1;
3700 for(;;) {
3701 t = ld_next(s1, cmd, sizeof(cmd));
3702 if (t == LD_TOK_EOF)
3703 return 0;
3704 else if (t != LD_TOK_NAME)
3705 return -1;
3706 if (!strcmp(cmd, "INPUT") ||
3707 !strcmp(cmd, "GROUP")) {
3708 ret = ld_add_file_list(s1, cmd, 0);
3709 if (ret)
3710 return ret;
3711 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3712 !strcmp(cmd, "TARGET")) {
3713 /* ignore some commands */
3714 t = ld_next(s1, cmd, sizeof(cmd));
3715 if (t != '(') {
3716 tcc_error_noabort("( expected");
3717 return -1;
3719 for(;;) {
3720 t = ld_next(s1, filename, sizeof(filename));
3721 if (t == LD_TOK_EOF) {
3722 tcc_error_noabort("unexpected end of file");
3723 return -1;
3724 } else if (t == ')') {
3725 break;
3728 } else {
3729 return -1;
3732 return 0;
3734 #endif /* !ELF_OBJ_ONLY */