Fix Extended Asm ignored constraints
[tinycc.git] / tccelf.c
blobfab49c487a8964d1f616d059e90dd69ce3e74c42
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 #ifdef TCC_TARGET_PE
51 #define shf_RELRO SHF_ALLOC
52 static const char rdata[] = ".rdata";
53 #else
54 #define shf_RELRO s1->shf_RELRO
55 static const char rdata[] = ".data.ro";
56 #endif
58 /* ------------------------------------------------------------------------- */
60 ST_FUNC void tccelf_new(TCCState *s)
62 TCCState *s1 = s;
64 #ifndef TCC_TARGET_PE
65 shf_RELRO = SHF_ALLOC;
66 if (s1->output_type != TCC_OUTPUT_MEMORY)
67 shf_RELRO |= SHF_WRITE; /* the ELF loader will set it to RO at runtime */
68 #endif
70 /* no section zero */
71 dynarray_add(&s->sections, &s->nb_sections, NULL);
73 /* create standard sections */
74 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
75 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
76 /* create ro data section (make ro after relocation done with GNU_RELRO) */
77 rodata_section = new_section(s, rdata, SHT_PROGBITS, shf_RELRO);
78 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
79 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
80 common_section->sh_num = SHN_COMMON;
82 /* symbols are always generated for linking stage */
83 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
84 ".strtab",
85 ".hashtab", SHF_PRIVATE);
87 /* private symbol table for dynamic symbols */
88 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
89 ".dynstrtab",
90 ".dynhashtab", SHF_PRIVATE);
91 get_sym_attr(s, 0, 1);
93 if (s->do_debug) {
94 /* add debug sections */
95 tcc_debug_new(s);
98 #ifdef CONFIG_TCC_BCHECK
99 if (s->do_bounds_check) {
100 /* if bound checking, then add corresponding sections */
101 /* (make ro after relocation done with GNU_RELRO) */
102 bounds_section = new_section(s, ".bounds", SHT_PROGBITS, shf_RELRO);
103 lbounds_section = new_section(s, ".lbounds", SHT_PROGBITS, shf_RELRO);
105 #endif
108 ST_FUNC void free_section(Section *s)
110 if (!s)
111 return;
112 tcc_free(s->data);
113 s->data = NULL;
114 s->data_allocated = s->data_offset = 0;
117 ST_FUNC void tccelf_delete(TCCState *s1)
119 int i;
121 #ifndef ELF_OBJ_ONLY
122 /* free symbol versions */
123 for (i = 0; i < nb_sym_versions; i++) {
124 tcc_free(sym_versions[i].version);
125 tcc_free(sym_versions[i].lib);
127 tcc_free(sym_versions);
128 tcc_free(sym_to_version);
129 #endif
131 /* free all sections */
132 for(i = 1; i < s1->nb_sections; i++)
133 free_section(s1->sections[i]);
134 dynarray_reset(&s1->sections, &s1->nb_sections);
136 for(i = 0; i < s1->nb_priv_sections; i++)
137 free_section(s1->priv_sections[i]);
138 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
140 tcc_free(s1->sym_attrs);
141 symtab_section = NULL; /* for tccrun.c:rt_printline() */
144 /* save section data state */
145 ST_FUNC void tccelf_begin_file(TCCState *s1)
147 Section *s; int i;
148 for (i = 1; i < s1->nb_sections; i++) {
149 s = s1->sections[i];
150 s->sh_offset = s->data_offset;
152 /* disable symbol hashing during compilation */
153 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
154 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
155 s1->uw_sym = 0;
156 #endif
159 /* At the end of compilation, convert any UNDEF syms to global, and merge
160 with previously existing symbols */
161 ST_FUNC void tccelf_end_file(TCCState *s1)
163 Section *s = s1->symtab;
164 int first_sym, nb_syms, *tr, i;
166 first_sym = s->sh_offset / sizeof (ElfSym);
167 nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
168 s->data_offset = s->sh_offset;
169 s->link->data_offset = s->link->sh_offset;
170 s->hash = s->reloc, s->reloc = NULL;
171 tr = tcc_mallocz(nb_syms * sizeof *tr);
173 for (i = 0; i < nb_syms; ++i) {
174 ElfSym *sym = (ElfSym*)s->data + first_sym + i;
176 if (sym->st_shndx == SHN_UNDEF) {
177 int sym_bind = ELFW(ST_BIND)(sym->st_info);
178 int sym_type = ELFW(ST_TYPE)(sym->st_info);
179 if (sym_bind == STB_LOCAL)
180 sym_bind = STB_GLOBAL;
181 #ifndef TCC_TARGET_PE
182 if (sym_bind == STB_GLOBAL && s1->output_type == TCC_OUTPUT_OBJ) {
183 /* undefined symbols with STT_FUNC are confusing gnu ld when
184 linking statically to STT_GNU_IFUNC */
185 sym_type = STT_NOTYPE;
187 #endif
188 sym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
191 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
192 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
194 /* now update relocations */
195 for (i = 1; i < s1->nb_sections; i++) {
196 Section *sr = s1->sections[i];
197 if (sr->sh_type == SHT_RELX && sr->link == s) {
198 ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
199 ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
200 for (; rel < rel_end; ++rel) {
201 int n = ELFW(R_SYM)(rel->r_info) - first_sym;
202 if (n < 0) /* zero sym_index in reloc (can happen with asm) */
203 continue;
204 rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
208 tcc_free(tr);
210 /* record text/data/bss output for -bench info */
211 for (i = 0; i < 4; ++i) {
212 s = s1->sections[i + 1];
213 s1->total_output[i] += s->data_offset - s->sh_offset;
217 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
219 Section *sec;
221 sec = tcc_mallocz(sizeof(Section) + strlen(name));
222 sec->s1 = s1;
223 strcpy(sec->name, name);
224 sec->sh_type = sh_type;
225 sec->sh_flags = sh_flags;
226 switch(sh_type) {
227 case SHT_GNU_versym:
228 sec->sh_addralign = 2;
229 break;
230 case SHT_HASH:
231 case SHT_GNU_HASH:
232 case SHT_REL:
233 case SHT_RELA:
234 case SHT_DYNSYM:
235 case SHT_SYMTAB:
236 case SHT_DYNAMIC:
237 case SHT_GNU_verneed:
238 case SHT_GNU_verdef:
239 sec->sh_addralign = PTR_SIZE;
240 break;
241 case SHT_STRTAB:
242 sec->sh_addralign = 1;
243 break;
244 default:
245 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */
246 break;
249 if (sh_flags & SHF_PRIVATE) {
250 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
251 } else {
252 sec->sh_num = s1->nb_sections;
253 dynarray_add(&s1->sections, &s1->nb_sections, sec);
256 return sec;
259 ST_FUNC void init_symtab(Section *s)
261 int *ptr, nb_buckets = 1;
262 put_elf_str(s->link, "");
263 section_ptr_add(s, sizeof (ElfW(Sym)));
264 ptr = section_ptr_add(s->hash, (2 + nb_buckets + 1) * sizeof(int));
265 ptr[0] = nb_buckets;
266 ptr[1] = 1;
267 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
270 ST_FUNC Section *new_symtab(TCCState *s1,
271 const char *symtab_name, int sh_type, int sh_flags,
272 const char *strtab_name,
273 const char *hash_name, int hash_sh_flags)
275 Section *symtab, *strtab, *hash;
276 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
277 symtab->sh_entsize = sizeof(ElfW(Sym));
278 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
279 symtab->link = strtab;
280 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
281 hash->sh_entsize = sizeof(int);
282 symtab->hash = hash;
283 hash->link = symtab;
284 init_symtab(symtab);
285 return symtab;
288 /* realloc section and set its content to zero */
289 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
291 unsigned long size;
292 unsigned char *data;
294 size = sec->data_allocated;
295 if (size == 0)
296 size = 1;
297 while (size < new_size)
298 size = size * 2;
299 data = tcc_realloc(sec->data, size);
300 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
301 sec->data = data;
302 sec->data_allocated = size;
305 /* reserve at least 'size' bytes aligned per 'align' in section
306 'sec' from current offset, and return the aligned offset */
307 ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
309 size_t offset, offset1;
311 offset = (sec->data_offset + align - 1) & -align;
312 offset1 = offset + size;
313 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
314 section_realloc(sec, offset1);
315 sec->data_offset = offset1;
316 if (align > sec->sh_addralign)
317 sec->sh_addralign = align;
318 return offset;
321 /* reserve at least 'size' bytes in section 'sec' from
322 sec->data_offset. */
323 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
325 size_t offset = section_add(sec, size, 1);
326 return sec->data + offset;
329 #ifndef ELF_OBJ_ONLY
330 /* reserve at least 'size' bytes from section start */
331 static void section_reserve(Section *sec, unsigned long size)
333 if (size > sec->data_allocated)
334 section_realloc(sec, size);
335 if (size > sec->data_offset)
336 sec->data_offset = size;
338 #endif
340 static Section *have_section(TCCState *s1, const char *name)
342 Section *sec;
343 int i;
344 for(i = 1; i < s1->nb_sections; i++) {
345 sec = s1->sections[i];
346 if (!strcmp(name, sec->name))
347 return sec;
349 return NULL;
352 /* return a reference to a section, and create it if it does not
353 exists */
354 ST_FUNC Section *find_section(TCCState *s1, const char *name)
356 Section *sec = have_section(s1, name);
357 if (sec)
358 return sec;
359 /* sections are created as PROGBITS */
360 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
363 /* ------------------------------------------------------------------------- */
365 ST_FUNC int put_elf_str(Section *s, const char *sym)
367 int offset, len;
368 char *ptr;
370 len = strlen(sym) + 1;
371 offset = s->data_offset;
372 ptr = section_ptr_add(s, len);
373 memmove(ptr, sym, len);
374 return offset;
377 /* elf symbol hashing function */
378 static ElfW(Word) elf_hash(const unsigned char *name)
380 ElfW(Word) h = 0, g;
382 while (*name) {
383 h = (h << 4) + *name++;
384 g = h & 0xf0000000;
385 if (g)
386 h ^= g >> 24;
387 h &= ~g;
389 return h;
392 /* rebuild hash table of section s */
393 /* NOTE: we do factorize the hash table code to go faster */
394 static void rebuild_hash(Section *s, unsigned int nb_buckets)
396 ElfW(Sym) *sym;
397 int *ptr, *hash, nb_syms, sym_index, h;
398 unsigned char *strtab;
400 strtab = s->link->data;
401 nb_syms = s->data_offset / sizeof(ElfW(Sym));
403 if (!nb_buckets)
404 nb_buckets = ((int*)s->hash->data)[0];
406 s->hash->data_offset = 0;
407 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
408 ptr[0] = nb_buckets;
409 ptr[1] = nb_syms;
410 ptr += 2;
411 hash = ptr;
412 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
413 ptr += nb_buckets + 1;
415 sym = (ElfW(Sym) *)s->data + 1;
416 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
417 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
418 h = elf_hash(strtab + sym->st_name) % nb_buckets;
419 *ptr = hash[h];
420 hash[h] = sym_index;
421 } else {
422 *ptr = 0;
424 ptr++;
425 sym++;
429 /* return the symbol number */
430 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
431 int info, int other, int shndx, const char *name)
433 int name_offset, sym_index;
434 int nbuckets, h;
435 ElfW(Sym) *sym;
436 Section *hs;
438 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
439 if (name && name[0])
440 name_offset = put_elf_str(s->link, name);
441 else
442 name_offset = 0;
443 /* XXX: endianness */
444 sym->st_name = name_offset;
445 sym->st_value = value;
446 sym->st_size = size;
447 sym->st_info = info;
448 sym->st_other = other;
449 sym->st_shndx = shndx;
450 sym_index = sym - (ElfW(Sym) *)s->data;
451 hs = s->hash;
452 if (hs) {
453 int *ptr, *base;
454 ptr = section_ptr_add(hs, sizeof(int));
455 base = (int *)hs->data;
456 /* only add global or weak symbols. */
457 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
458 /* add another hashing entry */
459 nbuckets = base[0];
460 h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
461 *ptr = base[2 + h];
462 base[2 + h] = sym_index;
463 base[1]++;
464 /* we resize the hash table */
465 hs->nb_hashed_syms++;
466 if (hs->nb_hashed_syms > 2 * nbuckets) {
467 rebuild_hash(s, 2 * nbuckets);
469 } else {
470 *ptr = 0;
471 base[1]++;
474 return sym_index;
477 ST_FUNC int find_elf_sym(Section *s, const char *name)
479 ElfW(Sym) *sym;
480 Section *hs;
481 int nbuckets, sym_index, h;
482 const char *name1;
484 hs = s->hash;
485 if (!hs)
486 return 0;
487 nbuckets = ((int *)hs->data)[0];
488 h = elf_hash((unsigned char *) name) % nbuckets;
489 sym_index = ((int *)hs->data)[2 + h];
490 while (sym_index != 0) {
491 sym = &((ElfW(Sym) *)s->data)[sym_index];
492 name1 = (char *) s->link->data + sym->st_name;
493 if (!strcmp(name, name1))
494 return sym_index;
495 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
497 return 0;
500 /* return elf symbol value, signal error if 'err' is nonzero, decorate
501 name if FORC */
502 ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
504 int sym_index;
505 ElfW(Sym) *sym;
506 char buf[256];
507 if (forc && s1->leading_underscore
508 #ifdef TCC_TARGET_PE
509 /* win32-32bit stdcall symbols always have _ already */
510 && !strchr(name, '@')
511 #endif
513 buf[0] = '_';
514 pstrcpy(buf + 1, sizeof(buf) - 1, name);
515 name = buf;
517 sym_index = find_elf_sym(s1->symtab, name);
518 sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
519 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
520 if (err)
521 tcc_error_noabort("%s not defined", name);
522 return (addr_t)-1;
524 return sym->st_value;
527 /* return elf symbol value */
528 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
530 addr_t addr = get_sym_addr(s, name, 0, 1);
531 return addr == -1 ? NULL : (void*)(uintptr_t)addr;
534 /* list elf symbol names and values */
535 ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
536 void (*symbol_cb)(void *ctx, const char *name, const void *val))
538 ElfW(Sym) *sym;
539 Section *symtab;
540 int sym_index, end_sym;
541 const char *name;
542 unsigned char sym_vis, sym_bind;
544 symtab = s->symtab;
545 end_sym = symtab->data_offset / sizeof (ElfSym);
546 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
547 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
548 if (sym->st_value) {
549 name = (char *) symtab->link->data + sym->st_name;
550 sym_bind = ELFW(ST_BIND)(sym->st_info);
551 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
552 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
553 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
558 /* list elf symbol names and values */
559 LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
560 void (*symbol_cb)(void *ctx, const char *name, const void *val))
562 list_elf_symbols(s, ctx, symbol_cb);
565 #ifndef ELF_OBJ_ONLY
566 static void
567 version_add (TCCState *s1)
569 int i;
570 ElfW(Sym) *sym;
571 ElfW(Verneed) *vn = NULL;
572 Section *symtab;
573 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
574 ElfW(Half) *versym;
575 const char *name;
577 if (0 == nb_sym_versions)
578 return;
579 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
580 versym_section->sh_entsize = sizeof(ElfW(Half));
581 versym_section->link = s1->dynsym;
583 /* add needed symbols */
584 symtab = s1->dynsym;
585 end_sym = symtab->data_offset / sizeof (ElfSym);
586 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
587 for (sym_index = 1; sym_index < end_sym; ++sym_index) {
588 int dllindex, verndx;
589 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
590 if (sym->st_shndx != SHN_UNDEF)
591 continue; /* defined symbol doesn't need library version */
592 name = (char *) symtab->link->data + sym->st_name;
593 dllindex = find_elf_sym(s1->dynsymtab_section, name);
594 verndx = (dllindex && dllindex < nb_sym_to_version)
595 ? sym_to_version[dllindex] : -1;
596 if (verndx >= 0) {
597 if (!sym_versions[verndx].out_index)
598 sym_versions[verndx].out_index = nb_versions++;
599 versym[sym_index] = sym_versions[verndx].out_index;
602 /* generate verneed section, but not when it will be empty. Some
603 dynamic linkers look at their contents even when DTVERNEEDNUM and
604 section size is zero. */
605 if (nb_versions > 2) {
606 verneed_section = new_section(s1, ".gnu.version_r",
607 SHT_GNU_verneed, SHF_ALLOC);
608 verneed_section->link = s1->dynsym->link;
609 for (i = nb_sym_versions; i-- > 0;) {
610 struct sym_version *sv = &sym_versions[i];
611 int n_same_libs = 0, prev;
612 size_t vnofs;
613 ElfW(Vernaux) *vna = 0;
614 if (sv->out_index < 1)
615 continue;
617 /* make sure that a DT_NEEDED tag is put */
618 /* abitest-tcc fails on older i386-linux with "ld-linux.so.2" DT_NEEDED
619 ret_int_test... Inconsistency detected by ld.so: dl-minimal.c: 148:
620 realloc: Assertion `ptr == alloc_last_block' failed! */
621 if (strcmp(sv->lib, "ld-linux.so.2"))
622 tcc_add_dllref(s1, sv->lib, 0);
624 vnofs = section_add(verneed_section, sizeof(*vn), 1);
625 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
626 vn->vn_version = 1;
627 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
628 vn->vn_aux = sizeof (*vn);
629 do {
630 prev = sv->prev_same_lib;
631 if (sv->out_index > 0) {
632 vna = section_ptr_add(verneed_section, sizeof(*vna));
633 vna->vna_hash = elf_hash ((const unsigned char *)sv->version);
634 vna->vna_flags = 0;
635 vna->vna_other = sv->out_index;
636 sv->out_index = -2;
637 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
638 vna->vna_next = sizeof (*vna);
639 n_same_libs++;
641 if (prev >= 0)
642 sv = &sym_versions[prev];
643 } while(prev >= 0);
644 vna->vna_next = 0;
645 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
646 vn->vn_cnt = n_same_libs;
647 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
648 nb_entries++;
650 if (vn)
651 vn->vn_next = 0;
652 verneed_section->sh_info = nb_entries;
654 dt_verneednum = nb_entries;
656 #endif /* ndef ELF_OBJ_ONLY */
658 /* add an elf symbol : check if it is already defined and patch
659 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
660 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
661 int info, int other, int shndx, const char *name)
663 TCCState *s1 = s->s1;
664 ElfW(Sym) *esym;
665 int sym_bind, sym_index, sym_type, esym_bind;
666 unsigned char sym_vis, esym_vis, new_vis;
668 sym_bind = ELFW(ST_BIND)(info);
669 sym_type = ELFW(ST_TYPE)(info);
670 sym_vis = ELFW(ST_VISIBILITY)(other);
672 if (sym_bind != STB_LOCAL) {
673 /* we search global or weak symbols */
674 sym_index = find_elf_sym(s, name);
675 if (!sym_index)
676 goto do_def;
677 esym = &((ElfW(Sym) *)s->data)[sym_index];
678 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
679 && esym->st_other == other && esym->st_shndx == shndx)
680 return sym_index;
681 if (esym->st_shndx != SHN_UNDEF) {
682 esym_bind = ELFW(ST_BIND)(esym->st_info);
683 /* propagate the most constraining visibility */
684 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
685 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
686 if (esym_vis == STV_DEFAULT) {
687 new_vis = sym_vis;
688 } else if (sym_vis == STV_DEFAULT) {
689 new_vis = esym_vis;
690 } else {
691 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
693 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
694 | new_vis;
695 if (shndx == SHN_UNDEF) {
696 /* ignore adding of undefined symbol if the
697 corresponding symbol is already defined */
698 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
699 /* global overrides weak, so patch */
700 goto do_patch;
701 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
702 /* weak is ignored if already global */
703 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
704 /* keep first-found weak definition, ignore subsequents */
705 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
706 /* ignore hidden symbols after */
707 } else if ((esym->st_shndx == SHN_COMMON
708 || esym->st_shndx == bss_section->sh_num)
709 && (shndx < SHN_LORESERVE
710 && shndx != bss_section->sh_num)) {
711 /* data symbol gets precedence over common/bss */
712 goto do_patch;
713 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
714 /* data symbol keeps precedence over common/bss */
715 } else if (s->sh_flags & SHF_DYNSYM) {
716 /* we accept that two DLL define the same symbol */
717 } else if (esym->st_other & ST_ASM_SET) {
718 /* If the existing symbol came from an asm .set
719 we can override. */
720 goto do_patch;
721 } else {
722 #if 0
723 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
724 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
725 #endif
726 tcc_error_noabort("'%s' defined twice", name);
728 } else {
729 esym->st_other = other;
730 do_patch:
731 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
732 esym->st_shndx = shndx;
733 s1->new_undef_sym = 1;
734 esym->st_value = value;
735 esym->st_size = size;
737 } else {
738 do_def:
739 sym_index = put_elf_sym(s, value, size,
740 ELFW(ST_INFO)(sym_bind, sym_type), other,
741 shndx, name);
743 return sym_index;
746 /* put relocation */
747 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
748 int type, int symbol, addr_t addend)
750 TCCState *s1 = s->s1;
751 char buf[256];
752 Section *sr;
753 ElfW_Rel *rel;
755 sr = s->reloc;
756 if (!sr) {
757 /* if no relocation section, create it */
758 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
759 /* if the symtab is allocated, then we consider the relocation
760 are also */
761 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
762 sr->sh_entsize = sizeof(ElfW_Rel);
763 sr->link = symtab;
764 sr->sh_info = s->sh_num;
765 s->reloc = sr;
767 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
768 rel->r_offset = offset;
769 rel->r_info = ELFW(R_INFO)(symbol, type);
770 #if SHT_RELX == SHT_RELA
771 rel->r_addend = addend;
772 #endif
773 if (SHT_RELX != SHT_RELA && addend)
774 tcc_error_noabort("non-zero addend on REL architecture");
777 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
778 int type, int symbol)
780 put_elf_reloca(symtab, s, offset, type, symbol, 0);
783 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
785 int n;
786 struct sym_attr *tab;
788 if (index >= s1->nb_sym_attrs) {
789 if (!alloc)
790 return s1->sym_attrs;
791 /* find immediately bigger power of 2 and reallocate array */
792 n = 1;
793 while (index >= n)
794 n *= 2;
795 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
796 s1->sym_attrs = tab;
797 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
798 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
799 s1->nb_sym_attrs = n;
801 return &s1->sym_attrs[index];
804 static void modify_reloctions_old_to_new(TCCState *s1, Section *s, int *old_to_new_syms)
806 int i, type, sym_index;
807 Section *sr;
808 ElfW_Rel *rel;
810 for(i = 1; i < s1->nb_sections; i++) {
811 sr = s1->sections[i];
812 if (sr->sh_type == SHT_RELX && sr->link == s) {
813 for_each_elem(sr, 0, rel, ElfW_Rel) {
814 sym_index = ELFW(R_SYM)(rel->r_info);
815 type = ELFW(R_TYPE)(rel->r_info);
816 sym_index = old_to_new_syms[sym_index];
817 rel->r_info = ELFW(R_INFO)(sym_index, type);
823 /* In an ELF file symbol table, the local symbols must appear below
824 the global and weak ones. Since TCC cannot sort it while generating
825 the code, we must do it after. All the relocation tables are also
826 modified to take into account the symbol table sorting */
827 static void sort_syms(TCCState *s1, Section *s)
829 int *old_to_new_syms;
830 ElfW(Sym) *new_syms;
831 int nb_syms, i;
832 ElfW(Sym) *p, *q;
834 nb_syms = s->data_offset / sizeof(ElfW(Sym));
835 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
836 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
838 /* first pass for local symbols */
839 p = (ElfW(Sym) *)s->data;
840 q = new_syms;
841 for(i = 0; i < nb_syms; i++) {
842 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
843 old_to_new_syms[i] = q - new_syms;
844 *q++ = *p;
846 p++;
848 /* save the number of local symbols in section header */
849 if( s->sh_size ) /* this 'if' makes IDA happy */
850 s->sh_info = q - new_syms;
852 /* then second pass for non local symbols */
853 p = (ElfW(Sym) *)s->data;
854 for(i = 0; i < nb_syms; i++) {
855 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
856 old_to_new_syms[i] = q - new_syms;
857 *q++ = *p;
859 p++;
862 /* we copy the new symbols to the old */
863 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
864 tcc_free(new_syms);
866 modify_reloctions_old_to_new(s1, s, old_to_new_syms);
868 tcc_free(old_to_new_syms);
871 #ifndef ELF_OBJ_ONLY
872 /* See: https://flapenguin.me/elf-dt-gnu-hash */
873 #define ELFCLASS_BITS (PTR_SIZE * 8)
875 static Section *create_gnu_hash(TCCState *s1)
877 int nb_syms, i, ndef, nbuckets, symoffset, bloom_size, bloom_shift;
878 ElfW(Sym) *p;
879 Section *gnu_hash;
880 Section *dynsym = s1->dynsym;
881 Elf32_Word *ptr;
883 gnu_hash = new_section(s1, ".gnu.hash", SHT_GNU_HASH, SHF_ALLOC);
884 gnu_hash->link = dynsym->hash->link;
886 nb_syms = dynsym->data_offset / sizeof(ElfW(Sym));
888 /* count def symbols */
889 ndef = 0;
890 p = (ElfW(Sym) *)dynsym->data;
891 for(i = 0; i < nb_syms; i++, p++)
892 ndef += p->st_shndx != SHN_UNDEF;
894 /* calculate gnu hash sizes and fill header */
895 nbuckets = ndef / 4 + 1;
896 symoffset = nb_syms - ndef;
897 bloom_shift = PTR_SIZE == 8 ? 6 : 5;
898 bloom_size = 1; /* must be power of two */
899 while (ndef >= bloom_size * (1 << (bloom_shift - 3)))
900 bloom_size *= 2;
901 ptr = section_ptr_add(gnu_hash, 4 * 4 +
902 PTR_SIZE * bloom_size +
903 nbuckets * 4 +
904 ndef * 4);
905 ptr[0] = nbuckets;
906 ptr[1] = symoffset;
907 ptr[2] = bloom_size;
908 ptr[3] = bloom_shift;
909 return gnu_hash;
912 static Elf32_Word elf_gnu_hash (const unsigned char *name)
914 Elf32_Word h = 5381;
915 unsigned char c;
917 while ((c = *name++))
918 h = h * 33 + c;
919 return h;
922 static void update_gnu_hash(TCCState *s1, Section *gnu_hash)
924 int *old_to_new_syms;
925 ElfW(Sym) *new_syms;
926 int nb_syms, i, nbuckets, bloom_size, bloom_shift;
927 ElfW(Sym) *p, *q;
928 Section *vs;
929 Section *dynsym = s1->dynsym;
930 Elf32_Word *ptr, *buckets, *chain, *hash;
931 unsigned int *nextbuck;
932 addr_t *bloom;
933 unsigned char *strtab;
934 struct { int first, last; } *buck;
936 strtab = dynsym->link->data;
937 nb_syms = dynsym->data_offset / sizeof(ElfW(Sym));
938 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
939 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
940 hash = tcc_malloc(nb_syms * sizeof(Elf32_Word));
941 nextbuck = tcc_malloc(nb_syms * sizeof(int));
943 /* calculate hashes and copy undefs */
944 p = (ElfW(Sym) *)dynsym->data;
945 q = new_syms;
946 for(i = 0; i < nb_syms; i++, p++) {
947 if (p->st_shndx == SHN_UNDEF) {
948 old_to_new_syms[i] = q - new_syms;
949 *q++ = *p;
951 else
952 hash[i] = elf_gnu_hash(strtab + p->st_name);
955 ptr = (Elf32_Word *) gnu_hash->data;
956 nbuckets = ptr[0];
957 bloom_size = ptr[2];
958 bloom_shift = ptr[3];
959 bloom = (addr_t *) (void *) &ptr[4];
960 buckets = (Elf32_Word*) (void *) &bloom[bloom_size];
961 chain = &buckets[nbuckets];
962 buck = tcc_malloc(nbuckets * sizeof(*buck));
964 if (gnu_hash->data_offset != 4 * 4 +
965 PTR_SIZE * bloom_size +
966 nbuckets * 4 +
967 (nb_syms - (q - new_syms)) * 4)
968 tcc_error_noabort ("gnu_hash size incorrect");
970 /* find buckets */
971 for(i = 0; i < nbuckets; i++)
972 buck[i].first = -1;
974 p = (ElfW(Sym) *)dynsym->data;
975 for(i = 0; i < nb_syms; i++, p++)
976 if (p->st_shndx != SHN_UNDEF) {
977 int bucket = hash[i] % nbuckets;
979 if (buck[bucket].first == -1)
980 buck[bucket].first = buck[bucket].last = i;
981 else {
982 nextbuck[buck[bucket].last] = i;
983 buck[bucket].last = i;
987 /* fill buckets/chains/bloom and sort symbols */
988 p = (ElfW(Sym) *)dynsym->data;
989 for(i = 0; i < nbuckets; i++) {
990 int cur = buck[i].first;
992 if (cur != -1) {
993 buckets[i] = q - new_syms;
994 for (;;) {
995 old_to_new_syms[cur] = q - new_syms;
996 *q++ = p[cur];
997 *chain++ = hash[cur] & ~1;
998 bloom[(hash[cur] / ELFCLASS_BITS) % bloom_size] |=
999 (addr_t)1 << (hash[cur] % ELFCLASS_BITS) |
1000 (addr_t)1 << ((hash[cur] >> bloom_shift) % ELFCLASS_BITS);
1001 if (cur == buck[i].last)
1002 break;
1003 cur = nextbuck[cur];
1005 chain[-1] |= 1;
1009 memcpy(dynsym->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
1010 tcc_free(new_syms);
1011 tcc_free(hash);
1012 tcc_free(buck);
1013 tcc_free(nextbuck);
1015 modify_reloctions_old_to_new(s1, dynsym, old_to_new_syms);
1017 /* modify the versions */
1018 vs = versym_section;
1019 if (vs) {
1020 ElfW(Half) *newver, *versym = (ElfW(Half) *)vs->data;
1022 if (1/*versym*/) {
1023 newver = tcc_malloc(nb_syms * sizeof(*newver));
1024 for (i = 0; i < nb_syms; i++)
1025 newver[old_to_new_syms[i]] = versym[i];
1026 memcpy(vs->data, newver, nb_syms * sizeof(*newver));
1027 tcc_free(newver);
1031 tcc_free(old_to_new_syms);
1033 /* rebuild hash */
1034 ptr = (Elf32_Word *) dynsym->hash->data;
1035 rebuild_hash(dynsym, ptr[0]);
1037 #endif /* ELF_OBJ_ONLY */
1039 /* relocate symbol table, resolve undefined symbols if do_resolve is
1040 true and output error if undefined symbol. */
1041 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
1043 ElfW(Sym) *sym;
1044 int sym_bind, sh_num;
1045 const char *name;
1047 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
1048 sh_num = sym->st_shndx;
1049 if (sh_num == SHN_UNDEF) {
1050 if (do_resolve == 2) /* relocating dynsym */
1051 continue;
1052 name = (char *) s1->symtab->link->data + sym->st_name;
1053 /* Use ld.so to resolve symbol for us (for tcc -run) */
1054 if (do_resolve) {
1055 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
1056 /* dlsym() needs the undecorated name. */
1057 void *addr = dlsym(RTLD_DEFAULT, &name[s1->leading_underscore]);
1058 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD || TARGETOS_ANDROID
1059 if (addr == NULL) {
1060 int i;
1061 for (i = 0; i < s1->nb_loaded_dlls; i++)
1062 if ((addr = dlsym(s1->loaded_dlls[i]->handle, name)))
1063 break;
1065 #endif
1066 if (addr) {
1067 sym->st_value = (addr_t) addr;
1068 #ifdef DEBUG_RELOC
1069 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
1070 #endif
1071 goto found;
1073 #endif
1074 /* if dynamic symbol exist, it will be used in relocate_section */
1075 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
1076 goto found;
1077 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1078 it */
1079 if (!strcmp(name, "_fp_hw"))
1080 goto found;
1081 /* only weak symbols are accepted to be undefined. Their
1082 value is zero */
1083 sym_bind = ELFW(ST_BIND)(sym->st_info);
1084 if (sym_bind == STB_WEAK)
1085 sym->st_value = 0;
1086 else
1087 tcc_error_noabort("undefined symbol '%s'", name);
1089 } else if (sh_num < SHN_LORESERVE) {
1090 /* add section base */
1091 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1093 found: ;
1097 /* relocate a given section (CPU dependent) by applying the relocations
1098 in the associated relocation section */
1099 static void relocate_section(TCCState *s1, Section *s, Section *sr)
1101 ElfW_Rel *rel;
1102 ElfW(Sym) *sym;
1103 int type, sym_index;
1104 unsigned char *ptr;
1105 addr_t tgt, addr;
1106 int is_dwarf = s->sh_num >= s1->dwlo && s->sh_num < s1->dwhi;
1108 qrel = (ElfW_Rel *)sr->data;
1109 for_each_elem(sr, 0, rel, ElfW_Rel) {
1110 ptr = s->data + rel->r_offset;
1111 sym_index = ELFW(R_SYM)(rel->r_info);
1112 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1113 type = ELFW(R_TYPE)(rel->r_info);
1114 tgt = sym->st_value;
1115 #if SHT_RELX == SHT_RELA
1116 tgt += rel->r_addend;
1117 #endif
1118 if (is_dwarf && type == R_DATA_32DW
1119 && sym->st_shndx >= s1->dwlo && sym->st_shndx < s1->dwhi) {
1120 /* dwarf section relocation to each other */
1121 add32le(ptr, tgt - s1->sections[sym->st_shndx]->sh_addr);
1122 continue;
1124 addr = s->sh_addr + rel->r_offset;
1125 relocate(s1, rel, type, ptr, addr, tgt);
1127 #ifndef ELF_OBJ_ONLY
1128 /* if the relocation is allocated, we change its symbol table */
1129 if (sr->sh_flags & SHF_ALLOC) {
1130 sr->link = s1->dynsym;
1131 if (s1->output_type & TCC_OUTPUT_DYN) {
1132 size_t r = (uint8_t*)qrel - sr->data;
1133 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
1134 && 0 == strcmp(s->name, ".stab"))
1135 r = 0; /* cannot apply 64bit relocation to 32bit value */
1136 sr->data_offset = sr->sh_size = r;
1137 #ifdef CONFIG_TCC_PIE
1138 if (r && 0 == (s->sh_flags & SHF_WRITE))
1139 tcc_warning("%d relocations to ro-section %s", (unsigned)(r / sizeof *qrel), s->name);
1140 #endif
1143 #endif
1146 /* relocate all sections */
1147 ST_FUNC void relocate_sections(TCCState *s1)
1149 int i;
1150 Section *s, *sr;
1152 for (i = 1; i < s1->nb_sections; ++i) {
1153 sr = s1->sections[i];
1154 if (sr->sh_type != SHT_RELX)
1155 continue;
1156 s = s1->sections[sr->sh_info];
1157 #ifndef TCC_TARGET_MACHO
1158 if (s != s1->got
1159 || s1->static_link
1160 || s1->output_type == TCC_OUTPUT_MEMORY)
1161 #endif
1163 relocate_section(s1, s, sr);
1165 #ifndef ELF_OBJ_ONLY
1166 if (sr->sh_flags & SHF_ALLOC) {
1167 ElfW_Rel *rel;
1168 /* relocate relocation table in 'sr' */
1169 for_each_elem(sr, 0, rel, ElfW_Rel)
1170 rel->r_offset += s->sh_addr;
1172 #endif
1176 #ifndef ELF_OBJ_ONLY
1177 /* count the number of dynamic relocations so that we can reserve
1178 their space */
1179 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
1181 int count = 0;
1182 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1183 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1184 defined(TCC_TARGET_RISCV64)
1185 ElfW_Rel *rel;
1186 for_each_elem(sr, 0, rel, ElfW_Rel) {
1187 int sym_index = ELFW(R_SYM)(rel->r_info);
1188 int type = ELFW(R_TYPE)(rel->r_info);
1189 switch(type) {
1190 #if defined(TCC_TARGET_I386)
1191 case R_386_32:
1192 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
1193 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
1194 /* don't fixup unresolved (weak) symbols */
1195 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
1196 break;
1198 #elif defined(TCC_TARGET_X86_64)
1199 case R_X86_64_32:
1200 case R_X86_64_32S:
1201 case R_X86_64_64:
1202 #elif defined(TCC_TARGET_ARM)
1203 case R_ARM_ABS32:
1204 case R_ARM_TARGET1:
1205 #elif defined(TCC_TARGET_ARM64)
1206 case R_AARCH64_ABS32:
1207 case R_AARCH64_ABS64:
1208 #elif defined(TCC_TARGET_RISCV64)
1209 case R_RISCV_32:
1210 case R_RISCV_64:
1211 #endif
1212 count++;
1213 break;
1214 #if defined(TCC_TARGET_I386)
1215 case R_386_PC32:
1216 #elif defined(TCC_TARGET_X86_64)
1217 case R_X86_64_PC32:
1219 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1220 /* Hidden defined symbols can and must be resolved locally.
1221 We're misusing a PLT32 reloc for this, as that's always
1222 resolved to its address even in shared libs. */
1223 if (sym->st_shndx != SHN_UNDEF &&
1224 ELFW(ST_VISIBILITY)(sym->st_other) == STV_HIDDEN) {
1225 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PLT32);
1226 break;
1229 #elif defined(TCC_TARGET_ARM64)
1230 case R_AARCH64_PREL32:
1231 #endif
1232 if (s1->output_type != TCC_OUTPUT_DLL)
1233 break;
1234 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1235 count++;
1236 break;
1237 default:
1238 break;
1241 #endif
1242 return count;
1244 #endif
1246 #ifdef NEED_BUILD_GOT
1247 static int build_got(TCCState *s1)
1249 /* if no got, then create it */
1250 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1251 s1->got->sh_entsize = 4;
1252 /* keep space for _DYNAMIC pointer and two dummy got entries */
1253 section_ptr_add(s1->got, 3 * PTR_SIZE);
1254 return set_elf_sym(symtab_section, 0, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1255 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1258 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1259 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1260 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1261 Returns the offset of the GOT or (if any) PLT entry. */
1262 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1263 int sym_index)
1265 int need_plt_entry;
1266 const char *name;
1267 ElfW(Sym) *sym;
1268 struct sym_attr *attr;
1269 unsigned got_offset;
1270 char plt_name[200];
1271 int len;
1272 Section *s_rel;
1274 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1275 attr = get_sym_attr(s1, sym_index, 1);
1277 /* In case a function is both called and its address taken 2 GOT entries
1278 are created, one for taking the address (GOT) and the other for the PLT
1279 entry (PLTGOT). */
1280 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1281 return attr;
1283 s_rel = s1->got;
1284 if (need_plt_entry) {
1285 if (!s1->plt) {
1286 s1->plt = new_section(s1, ".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
1287 s1->plt->sh_entsize = 4;
1289 s_rel = s1->plt;
1292 /* create the GOT entry */
1293 got_offset = s1->got->data_offset;
1294 section_ptr_add(s1->got, PTR_SIZE);
1296 /* Create the GOT relocation that will insert the address of the object or
1297 function of interest in the GOT entry. This is a static relocation for
1298 memory output (dlsym will give us the address of symbols) and dynamic
1299 relocation otherwise (executable and DLLs). The relocation should be
1300 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1301 associated to a PLT entry) but is currently done at load time for an
1302 unknown reason. */
1304 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1305 name = (char *) symtab_section->link->data + sym->st_name;
1306 //printf("sym %d %s\n", need_plt_entry, name);
1308 if (s1->dynsym) {
1309 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1310 /* Hack alarm. We don't want to emit dynamic symbols
1311 and symbol based relocs for STB_LOCAL symbols, but rather
1312 want to resolve them directly. At this point the symbol
1313 values aren't final yet, so we must defer this. We will later
1314 have to create a RELATIVE reloc anyway, so we misuse the
1315 relocation slot to smuggle the symbol reference until
1316 fill_local_got_entries. Not that the sym_index is
1317 relative to symtab_section, not s1->dynsym! Nevertheless
1318 we use s1->dyn_sym so that if this is the first call
1319 that got->reloc is correctly created. Also note that
1320 RELATIVE relocs are not normally created for the .got,
1321 so the types serves as a marker for later (and is retained
1322 also for the final output, which is okay because then the
1323 got is just normal data). */
1324 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1325 sym_index);
1326 } else {
1327 if (0 == attr->dyn_index)
1328 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1329 sym->st_size, sym->st_info, 0,
1330 sym->st_shndx, name);
1331 put_elf_reloc(s1->dynsym, s_rel, got_offset, dyn_reloc_type,
1332 attr->dyn_index);
1334 } else {
1335 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1336 sym_index);
1339 if (need_plt_entry) {
1340 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1342 /* create a symbol 'sym@plt' for the PLT jump vector */
1343 len = strlen(name);
1344 if (len > sizeof plt_name - 5)
1345 len = sizeof plt_name - 5;
1346 memcpy(plt_name, name, len);
1347 strcpy(plt_name + len, "@plt");
1348 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, 0,
1349 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1350 } else {
1351 attr->got_offset = got_offset;
1354 return attr;
1357 /* build GOT and PLT entries */
1358 /* Two passes because R_JMP_SLOT should become first. Some targets
1359 (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1360 ST_FUNC void build_got_entries(TCCState *s1, int got_sym)
1362 Section *s;
1363 ElfW_Rel *rel;
1364 ElfW(Sym) *sym;
1365 int i, type, gotplt_entry, reloc_type, sym_index;
1366 struct sym_attr *attr;
1367 int pass = 0;
1368 redo:
1369 for(i = 1; i < s1->nb_sections; i++) {
1370 s = s1->sections[i];
1371 if (s->sh_type != SHT_RELX)
1372 continue;
1373 /* no need to handle got relocations */
1374 if (s->link != symtab_section)
1375 continue;
1376 for_each_elem(s, 0, rel, ElfW_Rel) {
1377 type = ELFW(R_TYPE)(rel->r_info);
1378 gotplt_entry = gotplt_entry_type(type);
1379 if (gotplt_entry == -1) {
1380 tcc_error_noabort ("Unknown relocation type for got: %d", type);
1381 continue;
1383 sym_index = ELFW(R_SYM)(rel->r_info);
1384 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1386 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1387 continue;
1390 /* Automatically create PLT/GOT [entry] if it is an undefined
1391 reference (resolved at runtime), or the symbol is absolute,
1392 probably created by tcc_add_symbol, and thus on 64-bit
1393 targets might be too far from application code. */
1394 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1395 if (sym->st_shndx == SHN_UNDEF) {
1396 ElfW(Sym) *esym;
1397 int dynindex;
1398 if (!PCRELATIVE_DLLPLT
1399 && (s1->output_type & TCC_OUTPUT_DYN))
1400 continue;
1401 /* Relocations for UNDEF symbols would normally need
1402 to be transferred into the executable or shared object.
1403 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1404 But TCC doesn't do that (at least for exes), so we
1405 need to resolve all such relocs locally. And that
1406 means PLT slots for functions in DLLs and COPY relocs for
1407 data symbols. COPY relocs were generated in
1408 bind_exe_dynsyms (and the symbol adjusted to be defined),
1409 and for functions we were generated a dynamic symbol
1410 of function type. */
1411 if (s1->dynsym) {
1412 /* dynsym isn't set for -run :-/ */
1413 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1414 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1415 if (dynindex
1416 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1417 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1418 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1419 goto jmp_slot;
1421 } else if (sym->st_shndx == SHN_ABS) {
1422 if (sym->st_value == 0) /* from tcc_add_btstub() */
1423 continue;
1424 #ifndef TCC_TARGET_ARM
1425 if (PTR_SIZE != 8)
1426 continue;
1427 #endif
1428 /* from tcc_add_symbol(): on 64 bit platforms these
1429 need to go through .got */
1430 } else
1431 continue;
1434 #ifdef TCC_TARGET_X86_64
1435 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1436 sym->st_shndx != SHN_UNDEF &&
1437 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1438 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1439 s1->output_type & TCC_OUTPUT_EXE)) {
1440 if (pass != 0)
1441 continue;
1442 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1443 continue;
1445 #endif
1446 reloc_type = code_reloc(type);
1447 if (reloc_type == -1) {
1448 tcc_error_noabort ("Unknown relocation type: %d", type);
1449 continue;
1452 if (reloc_type != 0) {
1453 jmp_slot:
1454 if (pass != 0)
1455 continue;
1456 reloc_type = R_JMP_SLOT;
1457 } else {
1458 if (pass != 1)
1459 continue;
1460 reloc_type = R_GLOB_DAT;
1463 if (!s1->got)
1464 got_sym = build_got(s1);
1466 if (gotplt_entry == BUILD_GOT_ONLY)
1467 continue;
1469 attr = put_got_entry(s1, reloc_type, sym_index);
1471 if (reloc_type == R_JMP_SLOT)
1472 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1475 if (++pass < 2)
1476 goto redo;
1477 /* .rel.plt refers to .got actually */
1478 if (s1->plt && s1->plt->reloc)
1479 s1->plt->reloc->sh_info = s1->got->sh_num;
1480 if (got_sym) /* set size */
1481 ((ElfW(Sym)*)symtab_section->data)[got_sym].st_size = s1->got->data_offset;
1483 #endif /* def NEED_BUILD_GOT */
1485 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
1487 int shn = sec ? sec->sh_num : offs || !name ? SHN_ABS : SHN_UNDEF;
1488 if (sec && offs == -1)
1489 offs = sec->data_offset;
1490 return set_elf_sym(symtab_section, offs, 0,
1491 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1494 static void add_init_array_defines(TCCState *s1, const char *section_name)
1496 Section *s;
1497 addr_t end_offset;
1498 char buf[1024];
1499 s = have_section(s1, section_name);
1500 if (!s || !(s->sh_flags & SHF_ALLOC)) {
1501 end_offset = 0;
1502 s = data_section;
1503 } else {
1504 end_offset = s->data_offset;
1506 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1507 set_global_sym(s1, buf, s, 0);
1508 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1509 set_global_sym(s1, buf, s, end_offset);
1512 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1514 Section *s;
1515 s = find_section(s1, sec);
1516 s->sh_flags = shf_RELRO;
1517 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1518 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1519 section_ptr_add(s, PTR_SIZE);
1522 #ifdef CONFIG_TCC_BCHECK
1523 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1525 if (0 == s1->do_bounds_check)
1526 return;
1527 section_ptr_add(bounds_section, sizeof(addr_t));
1529 #endif
1531 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1532 a dynamic symbol to allow so's to have one each with a different value. */
1533 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1535 int c = find_elf_sym(s1->symtab, name);
1536 if (c) {
1537 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1538 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1539 esym->st_value = offset;
1540 esym->st_shndx = s->sh_num;
1544 /* avoid generating debug/test_coverage code for stub functions */
1545 static void tcc_compile_string_no_debug(TCCState *s, const char *str)
1547 int save_do_debug = s->do_debug;
1548 int save_test_coverage = s->test_coverage;
1550 s->do_debug = 0;
1551 s->test_coverage = 0;
1552 tcc_compile_string(s, str);
1553 s->do_debug = save_do_debug;
1554 s->test_coverage = save_test_coverage;
1557 #ifdef CONFIG_TCC_BACKTRACE
1558 static void put_ptr(TCCState *s1, Section *s, int offs)
1560 int c;
1561 c = set_global_sym(s1, NULL, s, offs);
1562 s = data_section;
1563 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1564 section_ptr_add(s, PTR_SIZE);
1567 ST_FUNC void tcc_add_btstub(TCCState *s1)
1569 Section *s;
1570 int n, o, *p;
1571 CString cstr;
1572 const char *__rt_info = &"___rt_info"[!s1->leading_underscore];
1574 s = data_section;
1575 /* Align to PTR_SIZE */
1576 section_ptr_add(s, -s->data_offset & (PTR_SIZE - 1));
1577 o = s->data_offset;
1578 /* create a struct rt_context (see tccrun.c) */
1579 if (s1->dwarf) {
1580 put_ptr(s1, dwarf_line_section, 0);
1581 put_ptr(s1, dwarf_line_section, -1);
1582 if (s1->dwarf >= 5)
1583 put_ptr(s1, dwarf_line_str_section, 0);
1584 else
1585 put_ptr(s1, dwarf_str_section, 0);
1587 else
1589 put_ptr(s1, stab_section, 0);
1590 put_ptr(s1, stab_section, -1);
1591 put_ptr(s1, stab_section->link, 0);
1594 /* skip esym_start/esym_end/elf_str (not loaded) */
1595 section_ptr_add(s, 3 * PTR_SIZE);
1597 if (s1->output_type == TCC_OUTPUT_MEMORY && 0 == s1->dwarf) {
1598 put_ptr(s1, text_section, 0);
1599 } else {
1600 /* prog_base : local nameless symbol with offset 0 at SHN_ABS */
1601 put_ptr(s1, NULL, 0);
1602 #if defined TCC_TARGET_MACHO
1603 /* adjust for __PAGEZERO */
1604 if (s1->dwarf == 0 && s1->output_type == TCC_OUTPUT_EXE)
1605 write64le(data_section->data + data_section->data_offset - PTR_SIZE,
1606 (uint64_t)1 << 32);
1607 #endif
1609 n = 3 * PTR_SIZE;
1610 #ifdef CONFIG_TCC_BCHECK
1611 if (s1->do_bounds_check) {
1612 put_ptr(s1, bounds_section, 0);
1613 n -= PTR_SIZE;
1615 #endif
1616 section_ptr_add(s, n);
1617 p = section_ptr_add(s, 2 * sizeof (int));
1618 p[0] = s1->rt_num_callers;
1619 p[1] = s1->dwarf;
1620 // if (s->data_offset - o != 10*PTR_SIZE + 2*sizeof (int)) exit(99);
1622 if (s1->output_type == TCC_OUTPUT_MEMORY) {
1623 set_global_sym(s1, __rt_info, s, o);
1624 return;
1627 cstr_new(&cstr);
1628 cstr_printf(&cstr,
1629 "extern void __bt_init(),__bt_exit(),__bt_init_dll();"
1630 "static void *__rt_info[];"
1631 "__attribute__((constructor)) static void __bt_init_rt(){");
1632 #ifdef TCC_TARGET_PE
1633 if (s1->output_type == TCC_OUTPUT_DLL)
1634 #ifdef CONFIG_TCC_BCHECK
1635 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1636 #else
1637 cstr_printf(&cstr, "__bt_init_dll(0);");
1638 #endif
1639 #endif
1640 cstr_printf(&cstr, "__bt_init(__rt_info,%d);}",
1641 s1->output_type != TCC_OUTPUT_DLL);
1642 /* In case dlcose is called by application */
1643 cstr_printf(&cstr,
1644 "__attribute__((destructor)) static void __bt_exit_rt(){"
1645 "__bt_exit(__rt_info);}");
1646 tcc_compile_string_no_debug(s1, cstr.data);
1647 cstr_free(&cstr);
1648 set_local_sym(s1, __rt_info, s, o);
1650 #endif /* def CONFIG_TCC_BACKTRACE */
1652 static void tcc_tcov_add_file(TCCState *s1, const char *filename)
1654 CString cstr;
1655 void *ptr;
1656 char wd[1024];
1658 if (tcov_section == NULL)
1659 return;
1660 section_ptr_add(tcov_section, 1);
1661 write32le (tcov_section->data, tcov_section->data_offset);
1663 cstr_new (&cstr);
1664 if (filename[0] == '/')
1665 cstr_printf (&cstr, "%s.tcov", filename);
1666 else {
1667 getcwd (wd, sizeof(wd));
1668 cstr_printf (&cstr, "%s/%s.tcov", wd, filename);
1670 ptr = section_ptr_add(tcov_section, cstr.size + 1);
1671 strcpy((char *)ptr, cstr.data);
1672 unlink((char *)ptr);
1673 #ifdef _WIN32
1674 normalize_slashes((char *)ptr);
1675 #endif
1676 cstr_free (&cstr);
1678 cstr_new(&cstr);
1679 cstr_printf(&cstr,
1680 "extern char *__tcov_data[];"
1681 "extern void __store_test_coverage ();"
1682 "__attribute__((destructor)) static void __tcov_exit() {"
1683 "__store_test_coverage(__tcov_data);"
1684 "}");
1685 tcc_compile_string_no_debug(s1, cstr.data);
1686 cstr_free(&cstr);
1687 set_local_sym(s1, &"___tcov_data"[!s1->leading_underscore], tcov_section, 0);
1690 #if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO
1691 /* add libc crt1/crti objects */
1692 ST_FUNC void tccelf_add_crtbegin(TCCState *s1)
1694 #if TARGETOS_OpenBSD
1695 if (s1->output_type != TCC_OUTPUT_DLL)
1696 tcc_add_crt(s1, "crt0.o");
1697 if (s1->output_type == TCC_OUTPUT_DLL)
1698 tcc_add_crt(s1, "crtbeginS.o");
1699 else
1700 tcc_add_crt(s1, "crtbegin.o");
1701 #elif TARGETOS_FreeBSD || TARGETOS_NetBSD
1702 if (s1->output_type != TCC_OUTPUT_DLL)
1703 #if TARGETOS_FreeBSD
1704 tcc_add_crt(s1, "crt1.o");
1705 #else
1706 tcc_add_crt(s1, "crt0.o");
1707 #endif
1708 tcc_add_crt(s1, "crti.o");
1709 if (s1->static_link)
1710 tcc_add_crt(s1, "crtbeginT.o");
1711 else if (s1->output_type == TCC_OUTPUT_DLL)
1712 tcc_add_crt(s1, "crtbeginS.o");
1713 else
1714 tcc_add_crt(s1, "crtbegin.o");
1715 #elif TARGETOS_ANDROID
1716 if (s1->output_type == TCC_OUTPUT_DLL)
1717 tcc_add_crt(s1, "crtbegin_so.o");
1718 else
1719 tcc_add_crt(s1, "crtbegin_dynamic.o");
1720 #else
1721 if (s1->output_type != TCC_OUTPUT_DLL)
1722 tcc_add_crt(s1, "crt1.o");
1723 tcc_add_crt(s1, "crti.o");
1724 #endif
1727 ST_FUNC void tccelf_add_crtend(TCCState *s1)
1729 #if TARGETOS_OpenBSD
1730 if (s1->output_type == TCC_OUTPUT_DLL)
1731 tcc_add_crt(s1, "crtendS.o");
1732 else
1733 tcc_add_crt(s1, "crtend.o");
1734 #elif TARGETOS_FreeBSD || TARGETOS_NetBSD
1735 if (s1->output_type == TCC_OUTPUT_DLL)
1736 tcc_add_crt(s1, "crtendS.o");
1737 else
1738 tcc_add_crt(s1, "crtend.o");
1739 tcc_add_crt(s1, "crtn.o");
1740 #elif TARGETOS_ANDROID
1741 if (s1->output_type == TCC_OUTPUT_DLL)
1742 tcc_add_crt(s1, "crtend_so.o");
1743 else
1744 tcc_add_crt(s1, "crtend_android.o");
1745 #else
1746 tcc_add_crt(s1, "crtn.o");
1747 #endif
1749 #endif /* !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO */
1751 #ifndef TCC_TARGET_PE
1752 /* add tcc runtime libraries */
1753 ST_FUNC void tcc_add_runtime(TCCState *s1)
1755 s1->filetype = 0;
1757 #ifdef CONFIG_TCC_BCHECK
1758 tcc_add_bcheck(s1);
1759 #endif
1760 tcc_add_pragma_libs(s1);
1762 /* add libc */
1763 if (!s1->nostdlib) {
1764 int lpthread = s1->option_pthread;
1766 #ifdef CONFIG_TCC_BCHECK
1767 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1768 tcc_add_support(s1, "bcheck.o");
1769 # if !(TARGETOS_OpenBSD || TARGETOS_NetBSD)
1770 tcc_add_library_err(s1, "dl");
1771 # endif
1772 lpthread = 1;
1774 #endif
1775 #ifdef CONFIG_TCC_BACKTRACE
1776 if (s1->do_backtrace) {
1777 if (s1->output_type & TCC_OUTPUT_EXE)
1778 tcc_add_support(s1, "bt-exe.o");
1779 if (s1->output_type != TCC_OUTPUT_DLL)
1780 tcc_add_support(s1, "bt-log.o");
1781 tcc_add_btstub(s1);
1782 lpthread = 1;
1784 #endif
1785 if (lpthread)
1786 tcc_add_library_err(s1, "pthread");
1787 tcc_add_library_err(s1, "c");
1788 #ifdef TCC_LIBGCC
1789 if (!s1->static_link) {
1790 if (TCC_LIBGCC[0] == '/')
1791 tcc_add_file(s1, TCC_LIBGCC);
1792 else
1793 tcc_add_dll(s1, TCC_LIBGCC, AFF_PRINT_ERROR);
1795 #endif
1796 #if defined TCC_TARGET_ARM && TARGETOS_FreeBSD
1797 tcc_add_library_err(s1, "gcc_s"); // unwind code
1798 #endif
1799 if (TCC_LIBTCC1[0])
1800 tcc_add_support(s1, TCC_LIBTCC1);
1801 #ifndef TCC_TARGET_MACHO
1802 if (s1->output_type != TCC_OUTPUT_MEMORY)
1803 tccelf_add_crtend(s1);
1804 #endif
1807 #endif /* ndef TCC_TARGET_PE */
1809 /* add various standard linker symbols (must be done after the
1810 sections are filled (for example after allocating common
1811 symbols)) */
1812 static void tcc_add_linker_symbols(TCCState *s1)
1814 char buf[1024];
1815 int i;
1816 Section *s;
1818 set_global_sym(s1, "_etext", text_section, -1);
1819 set_global_sym(s1, "_edata", data_section, -1);
1820 set_global_sym(s1, "_end", bss_section, -1);
1821 #if TARGETOS_OpenBSD
1822 set_global_sym(s1, "__executable_start", NULL, ELF_START_ADDR);
1823 #endif
1824 #ifdef TCC_TARGET_RISCV64
1825 /* XXX should be .sdata+0x800, not .data+0x800 */
1826 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1827 #endif
1828 /* horrible new standard ldscript defines */
1829 add_init_array_defines(s1, ".preinit_array");
1830 add_init_array_defines(s1, ".init_array");
1831 add_init_array_defines(s1, ".fini_array");
1832 /* add start and stop symbols for sections whose name can be
1833 expressed in C */
1834 for(i = 1; i < s1->nb_sections; i++) {
1835 s = s1->sections[i];
1836 if ((s->sh_flags & SHF_ALLOC)
1837 && (s->sh_type == SHT_PROGBITS
1838 || s->sh_type == SHT_STRTAB)) {
1839 const char *p;
1840 /* check if section name can be expressed in C */
1841 p = s->name;
1842 for(;;) {
1843 int c = *p;
1844 if (!c)
1845 break;
1846 if (!isid(c) && !isnum(c))
1847 goto next_sec;
1848 p++;
1850 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1851 set_global_sym(s1, buf, s, 0);
1852 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1853 set_global_sym(s1, buf, s, -1);
1855 next_sec: ;
1859 ST_FUNC void resolve_common_syms(TCCState *s1)
1861 ElfW(Sym) *sym;
1863 /* Allocate common symbols in BSS. */
1864 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1865 if (sym->st_shndx == SHN_COMMON) {
1866 /* symbol alignment is in st_value for SHN_COMMONs */
1867 sym->st_value = section_add(bss_section, sym->st_size,
1868 sym->st_value);
1869 sym->st_shndx = bss_section->sh_num;
1873 /* Now assign linker provided symbols their value. */
1874 tcc_add_linker_symbols(s1);
1877 #ifndef ELF_OBJ_ONLY
1878 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1880 int sym_index = ELFW(R_SYM) (rel->r_info);
1881 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1882 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1883 unsigned offset = attr->got_offset;
1885 if (0 == offset)
1886 return;
1887 section_reserve(s1->got, offset + PTR_SIZE);
1888 #if PTR_SIZE == 8
1889 write64le(s1->got->data + offset, sym->st_value);
1890 #else
1891 write32le(s1->got->data + offset, sym->st_value);
1892 #endif
1895 /* Perform relocation to GOT or PLT entries */
1896 ST_FUNC void fill_got(TCCState *s1)
1898 Section *s;
1899 ElfW_Rel *rel;
1900 int i;
1902 for(i = 1; i < s1->nb_sections; i++) {
1903 s = s1->sections[i];
1904 if (s->sh_type != SHT_RELX)
1905 continue;
1906 /* no need to handle got relocations */
1907 if (s->link != symtab_section)
1908 continue;
1909 for_each_elem(s, 0, rel, ElfW_Rel) {
1910 switch (ELFW(R_TYPE) (rel->r_info)) {
1911 case R_X86_64_GOT32:
1912 case R_X86_64_GOTPCREL:
1913 case R_X86_64_GOTPCRELX:
1914 case R_X86_64_REX_GOTPCRELX:
1915 case R_X86_64_PLT32:
1916 fill_got_entry(s1, rel);
1917 break;
1923 /* See put_got_entry for a description. This is the second stage
1924 where GOT references to local defined symbols are rewritten. */
1925 static void fill_local_got_entries(TCCState *s1)
1927 ElfW_Rel *rel;
1928 if (!s1->got->reloc)
1929 return;
1930 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1931 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1932 int sym_index = ELFW(R_SYM) (rel->r_info);
1933 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1934 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1935 unsigned offset = attr->got_offset;
1936 if (offset != rel->r_offset - s1->got->sh_addr)
1937 tcc_error_noabort("fill_local_got_entries: huh?");
1938 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1939 #if SHT_RELX == SHT_RELA
1940 rel->r_addend = sym->st_value;
1941 #else
1942 /* All our REL architectures also happen to be 32bit LE. */
1943 write32le(s1->got->data + offset, sym->st_value);
1944 #endif
1949 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1950 in shared libraries */
1951 static void bind_exe_dynsyms(TCCState *s1, int is_PIE)
1953 const char *name;
1954 int sym_index, index;
1955 ElfW(Sym) *sym, *esym;
1956 int type;
1958 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1959 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1960 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1961 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1962 if (sym->st_shndx == SHN_UNDEF) {
1963 name = (char *) symtab_section->link->data + sym->st_name;
1964 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1965 if (sym_index) {
1966 if (is_PIE)
1967 continue;
1968 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1969 type = ELFW(ST_TYPE)(esym->st_info);
1970 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1971 /* Indirect functions shall have STT_FUNC type in executable
1972 * dynsym section. Indeed, a dlsym call following a lazy
1973 * resolution would pick the symbol value from the
1974 * executable dynsym entry which would contain the address
1975 * of the function wanted by the caller of dlsym instead of
1976 * the address of the function that would return that
1977 * address */
1978 int dynindex
1979 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1980 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1981 name);
1982 int index = sym - (ElfW(Sym) *) symtab_section->data;
1983 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1984 } else if (type == STT_OBJECT) {
1985 unsigned long offset;
1986 ElfW(Sym) *dynsym;
1987 offset = bss_section->data_offset;
1988 /* XXX: which alignment ? */
1989 offset = (offset + 16 - 1) & -16;
1990 set_elf_sym (s1->symtab, offset, esym->st_size,
1991 esym->st_info, 0, bss_section->sh_num, name);
1992 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1993 esym->st_info, 0, bss_section->sh_num,
1994 name);
1996 /* Ensure R_COPY works for weak symbol aliases */
1997 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1998 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1999 if ((dynsym->st_value == esym->st_value)
2000 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
2001 char *dynname = (char *) s1->dynsymtab_section->link->data
2002 + dynsym->st_name;
2003 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
2004 dynsym->st_info, 0,
2005 bss_section->sh_num, dynname);
2006 break;
2011 put_elf_reloc(s1->dynsym, bss_section,
2012 offset, R_COPY, index);
2013 offset += esym->st_size;
2014 bss_section->data_offset = offset;
2016 } else {
2017 /* STB_WEAK undefined symbols are accepted */
2018 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
2019 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
2020 !strcmp(name, "_fp_hw")) {
2021 } else {
2022 tcc_error_noabort("undefined symbol '%s'", name);
2029 /* Bind symbols of libraries: export all non local symbols of executable that
2030 are referenced by shared libraries. The reason is that the dynamic loader
2031 search symbol first in executable and then in libraries. Therefore a
2032 reference to a symbol already defined by a library can still be resolved by
2033 a symbol in the executable. With -rdynamic, export all defined symbols */
2034 static void bind_libs_dynsyms(TCCState *s1)
2036 const char *name;
2037 int dynsym_index;
2038 ElfW(Sym) *sym, *esym;
2040 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
2041 name = (char *)symtab_section->link->data + sym->st_name;
2042 dynsym_index = find_elf_sym(s1->dynsymtab_section, name);
2043 if (sym->st_shndx != SHN_UNDEF) {
2044 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL
2045 && (dynsym_index || s1->rdynamic))
2046 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
2047 sym->st_info, 0, sym->st_shndx, name);
2048 } else if (dynsym_index) {
2049 esym = (ElfW(Sym) *)s1->dynsymtab_section->data + dynsym_index;
2050 if (esym->st_shndx == SHN_UNDEF) {
2051 /* weak symbols can stay undefined */
2052 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
2053 tcc_warning("undefined dynamic symbol '%s'", name);
2059 /* Export all non local symbols. This is used by shared libraries so that the
2060 non local symbols they define can resolve a reference in another shared
2061 library or in the executable. Correspondingly, it allows undefined local
2062 symbols to be resolved by other shared libraries or by the executable. */
2063 static void export_global_syms(TCCState *s1)
2065 int dynindex, index;
2066 const char *name;
2067 ElfW(Sym) *sym;
2068 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
2069 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2070 name = (char *) symtab_section->link->data + sym->st_name;
2071 dynindex = set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
2072 sym->st_info, 0, sym->st_shndx, name);
2073 index = sym - (ElfW(Sym) *) symtab_section->data;
2074 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
2079 /* decide if an unallocated section should be output. */
2080 static int set_sec_sizes(TCCState *s1)
2082 int i;
2083 Section *s;
2084 int textrel = 0;
2085 int file_type = s1->output_type;
2087 /* Allocate strings for section names */
2088 for(i = 1; i < s1->nb_sections; i++) {
2089 s = s1->sections[i];
2090 if (s->sh_type == SHT_RELX && !(s->sh_flags & SHF_ALLOC)) {
2091 /* when generating a DLL, we include relocations but
2092 we may patch them */
2093 if ((file_type & TCC_OUTPUT_DYN)
2094 && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) {
2095 int count = prepare_dynamic_rel(s1, s);
2096 if (count) {
2097 /* allocate the section */
2098 s->sh_flags |= SHF_ALLOC;
2099 s->sh_size = count * sizeof(ElfW_Rel);
2100 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
2101 textrel += count;
2104 } else if ((s->sh_flags & SHF_ALLOC)
2105 #ifdef TCC_TARGET_ARM
2106 || s->sh_type == SHT_ARM_ATTRIBUTES
2107 #endif
2108 || s1->do_debug) {
2109 s->sh_size = s->data_offset;
2112 #ifdef TCC_TARGET_ARM
2113 /* XXX: Suppress stack unwinding section. */
2114 if (s->sh_type == SHT_ARM_EXIDX) {
2115 s->sh_flags = 0;
2116 s->sh_size = 0;
2118 #endif
2121 return textrel;
2124 /* various data used under elf_output_file() */
2125 struct dyn_inf {
2126 Section *dynamic;
2127 Section *dynstr;
2128 struct {
2129 /* Info to be copied in dynamic section */
2130 unsigned long data_offset;
2131 addr_t rel_addr;
2132 addr_t rel_size;
2135 ElfW(Phdr) *phdr;
2136 int phnum;
2137 Section *interp;
2138 Section *note;
2139 Section *gnu_hash;
2141 /* read only segment mapping for GNU_RELRO */
2142 Section _roinf, *roinf;
2145 /* Decide the layout of sections loaded in memory. This must be done before
2146 program headers are filled since they contain info about the layout.
2147 We do the following ordering: interp, symbol tables, relocations, progbits,
2148 nobits */
2149 static int sort_sections(TCCState *s1, int *sec_order, Section *interp)
2151 Section *s;
2152 int i, j, k, f, f0, n;
2153 int nb_sections = s1->nb_sections;
2154 int *sec_cls = sec_order + nb_sections;
2156 for (i = 1; i < nb_sections; i++) {
2157 s = s1->sections[i];
2158 if (s->sh_flags & SHF_ALLOC) {
2159 j = 0x100;
2160 if (s->sh_flags & SHF_WRITE)
2161 j = 0x200;
2162 if (s->sh_flags & SHF_TLS)
2163 j += 0x200;
2164 } else if (s->sh_name) {
2165 j = 0x700;
2166 } else {
2167 j = 0x900; /* no sh_name: won't go to file */
2169 if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_DYNSYM) {
2170 k = 0x10;
2171 } else if (s->sh_type == SHT_STRTAB && strcmp(s->name, ".stabstr")) {
2172 k = 0x11;
2173 if (i == nb_sections - 1) /* ".shstrtab" assumed to remain last */
2174 k = 0xff;
2175 } else if (s->sh_type == SHT_HASH || s->sh_type == SHT_GNU_HASH) {
2176 k = 0x12;
2177 } else if (s->sh_type == SHT_RELX) {
2178 k = 0x20;
2179 if (s1->plt && s == s1->plt->reloc)
2180 k = 0x21;
2181 } else if (s->sh_type == SHT_PREINIT_ARRAY) {
2182 k = 0x41;
2183 } else if (s->sh_type == SHT_INIT_ARRAY) {
2184 k = 0x42;
2185 } else if (s->sh_type == SHT_FINI_ARRAY) {
2186 k = 0x43;
2187 #ifdef CONFIG_TCC_BCHECK
2188 } else if (s == bounds_section || s == lbounds_section) {
2189 k = 0x44;
2190 #endif
2191 } else if (s == rodata_section || 0 == strcmp(s->name, ".data.rel.ro")) {
2192 k = 0x45;
2193 } else if (s->sh_type == SHT_DYNAMIC) {
2194 k = 0x46;
2195 } else if (s == s1->got) {
2196 k = 0x47; /* .got as RELRO needs BIND_NOW in DT_FLAGS */
2197 } else {
2198 k = 0x50;
2199 if (s->sh_type == SHT_NOTE)
2200 k = 0x60;
2201 if (s->sh_flags & SHF_EXECINSTR)
2202 k = 0x70;
2203 if (s->sh_type == SHT_NOBITS)
2204 k = 0x80;
2205 if (s == interp)
2206 k = 0x00;
2208 k += j;
2210 for (n = i; n > 1 && k < (f = sec_cls[n - 1]); --n)
2211 sec_cls[n] = f, sec_order[n] = sec_order[n - 1];
2212 sec_cls[n] = k, sec_order[n] = i;
2214 sec_order[0] = 0;
2216 /* count PT_LOAD headers needed */
2217 n = f0 = 0;
2218 for (i = 1; i < nb_sections; i++) {
2219 s = s1->sections[sec_order[i]];
2220 k = sec_cls[i];
2221 f = 0;
2222 if (k < 0x700) {
2223 f = s->sh_flags & (SHF_ALLOC|SHF_WRITE|SHF_EXECINSTR|SHF_TLS);
2224 #if TARGETOS_NetBSD
2225 /* NetBSD only supports 2 PT_LOAD sections.
2226 See: https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */
2227 if ((f & SHF_WRITE) == 0) f |= SHF_EXECINSTR;
2228 #else
2229 if ((k & 0xfff0) == 0x240) /* RELRO sections */
2230 f |= 1<<4;
2231 #endif
2232 if (f != f0) /* start new header when flags changed or relro */
2233 f0 = f, ++n, f |= 1<<8;
2235 sec_cls[i] = f;
2236 //printf("ph %d sec %02d : %3X %3X %8.2X %04X %s\n", !!f * n, i, f, k, s->sh_type, s->sh_size, s->name);
2238 return n;
2241 static ElfW(Phdr) *fill_phdr(ElfW(Phdr) *ph, int type, Section *s)
2243 if (s) {
2244 ph->p_offset = s->sh_offset;
2245 ph->p_vaddr = s->sh_addr;
2246 ph->p_filesz = s->sh_size;
2247 ph->p_align = s->sh_addralign;
2249 ph->p_type = type;
2250 ph->p_flags = PF_R;
2251 ph->p_paddr = ph->p_vaddr;
2252 ph->p_memsz = ph->p_filesz;
2253 return ph;
2256 /* Assign sections to segments and decide how are sections laid out when loaded
2257 in memory. This function also fills corresponding program headers. */
2258 static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
2260 Section *s;
2261 addr_t addr, tmp, align, s_align, base;
2262 ElfW(Phdr) *ph = NULL;
2263 int i, f, n, phnum, phfill;
2264 int file_offset;
2266 /* compute number of program headers */
2267 phnum = sort_sections(s1, sec_order, d->interp);
2268 phfill = 0; /* set to 1 to have dll's with a PT_PHDR */
2269 if (d->interp)
2270 phfill = 2;
2271 phnum += phfill;
2272 if (d->note)
2273 ++phnum;
2274 if (d->dynamic)
2275 ++phnum;
2276 if (d->roinf)
2277 ++phnum;
2278 d->phnum = phnum;
2279 d->phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2281 file_offset = 0;
2282 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2283 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2285 s_align = ELF_PAGE_SIZE;
2286 if (s1->section_align)
2287 s_align = s1->section_align;
2289 addr = ELF_START_ADDR;
2290 if (s1->output_type & TCC_OUTPUT_DYN)
2291 addr = 0;
2293 if (s1->has_text_addr) {
2294 addr = s1->text_addr;
2295 if (0) {
2296 int a_offset, p_offset;
2297 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
2298 ELF_PAGE_SIZE */
2299 a_offset = (int) (addr & (s_align - 1));
2300 p_offset = file_offset & (s_align - 1);
2301 if (a_offset < p_offset)
2302 a_offset += s_align;
2303 file_offset += (a_offset - p_offset);
2306 base = addr;
2307 /* compute address after headers */
2308 addr = addr + (file_offset & (s_align - 1));
2310 n = 0;
2311 for(i = 1; i < s1->nb_sections; i++) {
2312 s = s1->sections[sec_order[i]];
2313 f = sec_order[i + s1->nb_sections];
2314 align = s->sh_addralign - 1;
2316 if (f == 0) { /* no alloc */
2317 file_offset = (file_offset + align) & ~align;
2318 s->sh_offset = file_offset;
2319 if (s->sh_type != SHT_NOBITS)
2320 file_offset += s->sh_size;
2321 continue;
2324 if ((f & 1<<8) && n) {
2325 /* different rwx section flags */
2326 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
2327 /* if in the middle of a page, w e duplicate the page in
2328 memory so that one copy is RX and the other is RW */
2329 if ((addr & (s_align - 1)) != 0)
2330 addr += s_align;
2331 } else {
2332 align = s_align - 1;
2336 tmp = addr;
2337 addr = (addr + align) & ~align;
2338 file_offset += (int)(addr - tmp);
2339 s->sh_offset = file_offset;
2340 s->sh_addr = addr;
2342 if (f & 1<<8) {
2343 /* set new program header */
2344 ph = &d->phdr[phfill + n];
2345 ph->p_type = PT_LOAD;
2346 ph->p_align = s_align;
2347 ph->p_flags = PF_R;
2348 if (f & SHF_WRITE)
2349 ph->p_flags |= PF_W;
2350 if (f & SHF_EXECINSTR)
2351 ph->p_flags |= PF_X;
2352 if (f & SHF_TLS) {
2353 ph->p_type = PT_TLS;
2354 ph->p_align = align + 1;
2357 ph->p_offset = file_offset;
2358 ph->p_vaddr = addr;
2359 if (n == 0) {
2360 /* Make the first PT_LOAD segment include the program
2361 headers itself (and the ELF header as well), it'll
2362 come out with same memory use but will make various
2363 tools like binutils strip work better. */
2364 ph->p_offset = 0;
2365 ph->p_vaddr = base;
2367 ph->p_paddr = ph->p_vaddr;
2368 ++n;
2371 if (f & 1<<4) {
2372 Section *roinf = &d->_roinf;
2373 if (roinf->sh_size == 0) {
2374 roinf->sh_offset = s->sh_offset;
2375 roinf->sh_addr = s->sh_addr;
2376 roinf->sh_addralign = 1;
2378 roinf->sh_size = (addr - roinf->sh_addr) + s->sh_size;
2381 addr += s->sh_size;
2382 if (s->sh_type != SHT_NOBITS)
2383 file_offset += s->sh_size;
2385 ph->p_filesz = file_offset - ph->p_offset;
2386 ph->p_memsz = addr - ph->p_vaddr;
2389 /* Fill other headers */
2390 if (d->note)
2391 fill_phdr(++ph, PT_NOTE, d->note);
2392 if (d->dynamic)
2393 fill_phdr(++ph, PT_DYNAMIC, d->dynamic)->p_flags |= PF_W;
2394 if (d->roinf)
2395 fill_phdr(++ph, PT_GNU_RELRO, d->roinf)->p_flags |= PF_W;
2396 if (d->interp)
2397 fill_phdr(&d->phdr[1], PT_INTERP, d->interp);
2398 if (phfill) {
2399 ph = &d->phdr[0];
2400 ph->p_offset = sizeof(ElfW(Ehdr));
2401 ph->p_vaddr = base + ph->p_offset;
2402 ph->p_filesz = phnum * sizeof(ElfW(Phdr));
2403 ph->p_align = 4;
2404 fill_phdr(ph, PT_PHDR, NULL);
2406 return file_offset;
2409 /* put dynamic tag */
2410 static void put_dt(Section *dynamic, int dt, addr_t val)
2412 ElfW(Dyn) *dyn;
2413 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
2414 dyn->d_tag = dt;
2415 dyn->d_un.d_val = val;
2418 /* Fill the dynamic section with tags describing the address and size of
2419 sections */
2420 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2422 Section *dynamic = dyninf->dynamic;
2423 Section *s;
2425 /* put dynamic section entries */
2426 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2427 put_dt(dynamic, DT_GNU_HASH, dyninf->gnu_hash->sh_addr);
2428 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2429 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2430 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2431 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2432 #if PTR_SIZE == 8
2433 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2434 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2435 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2436 if (s1->plt && s1->plt->reloc) {
2437 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2438 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2439 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2440 put_dt(dynamic, DT_PLTREL, DT_RELA);
2442 put_dt(dynamic, DT_RELACOUNT, 0);
2443 #else
2444 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2445 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2446 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2447 if (s1->plt && s1->plt->reloc) {
2448 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2449 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2450 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2451 put_dt(dynamic, DT_PLTREL, DT_REL);
2453 put_dt(dynamic, DT_RELCOUNT, 0);
2454 #endif
2455 if (versym_section && verneed_section) {
2456 /* The dynamic linker can not handle VERSYM without VERNEED */
2457 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2458 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2459 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2461 s = have_section(s1, ".preinit_array");
2462 if (s && s->data_offset) {
2463 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2464 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2466 s = have_section(s1, ".init_array");
2467 if (s && s->data_offset) {
2468 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2469 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2471 s = have_section(s1, ".fini_array");
2472 if (s && s->data_offset) {
2473 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2474 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2476 s = have_section(s1, ".init");
2477 if (s && s->data_offset) {
2478 put_dt(dynamic, DT_INIT, s->sh_addr);
2480 s = have_section(s1, ".fini");
2481 if (s && s->data_offset) {
2482 put_dt(dynamic, DT_FINI, s->sh_addr);
2484 if (s1->do_debug)
2485 put_dt(dynamic, DT_DEBUG, 0);
2486 put_dt(dynamic, DT_NULL, 0);
2489 /* Remove gaps between RELX sections.
2490 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2491 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2492 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2493 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2494 static void update_reloc_sections(TCCState *s1, struct dyn_inf *dyninf)
2496 int i;
2497 unsigned long file_offset = 0;
2498 Section *s;
2499 Section *relocplt = s1->plt ? s1->plt->reloc : NULL;
2501 /* dynamic relocation table information, for .dynamic section */
2502 dyninf->rel_addr = dyninf->rel_size = 0;
2504 for(i = 1; i < s1->nb_sections; i++) {
2505 s = s1->sections[i];
2506 if (s->sh_type == SHT_RELX && s != relocplt) {
2507 if (dyninf->rel_size == 0) {
2508 dyninf->rel_addr = s->sh_addr;
2509 file_offset = s->sh_offset;
2511 else {
2512 s->sh_addr = dyninf->rel_addr + dyninf->rel_size;
2513 s->sh_offset = file_offset + dyninf->rel_size;
2515 dyninf->rel_size += s->sh_size;
2520 static int tidy_section_headers(TCCState *s1, int *sec_order);
2521 #endif /* ndef ELF_OBJ_ONLY */
2523 /* Create an ELF file on disk.
2524 This function handle ELF specific layout requirements */
2525 static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2526 int file_offset, int *sec_order)
2528 int i, shnum, offset, size, file_type;
2529 Section *s;
2530 ElfW(Ehdr) ehdr;
2531 ElfW(Shdr) shdr, *sh;
2533 file_type = s1->output_type;
2534 shnum = s1->nb_sections;
2536 memset(&ehdr, 0, sizeof(ehdr));
2538 if (phnum > 0) {
2539 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2540 ehdr.e_phnum = phnum;
2541 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2542 #ifndef ELF_OBJ_ONLY
2543 shnum = tidy_section_headers(s1, sec_order);
2544 #endif
2547 /* align to 4 */
2548 file_offset = (file_offset + 3) & -4;
2550 /* fill header */
2551 ehdr.e_ident[0] = ELFMAG0;
2552 ehdr.e_ident[1] = ELFMAG1;
2553 ehdr.e_ident[2] = ELFMAG2;
2554 ehdr.e_ident[3] = ELFMAG3;
2555 ehdr.e_ident[4] = ELFCLASSW;
2556 ehdr.e_ident[5] = ELFDATA2LSB;
2557 ehdr.e_ident[6] = EV_CURRENT;
2559 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2560 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2561 #elif defined TCC_TARGET_ARM && defined TCC_ARM_EABI
2562 ehdr.e_flags = EF_ARM_EABI_VER5;
2563 ehdr.e_flags |= s1->float_abi == ARM_HARD_FLOAT
2564 ? EF_ARM_VFP_FLOAT : EF_ARM_SOFT_FLOAT;
2565 #elif defined TCC_TARGET_ARM
2566 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2567 #elif defined TCC_TARGET_RISCV64
2568 /* XXX should be configurable */
2569 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2570 #endif
2572 if (file_type == TCC_OUTPUT_OBJ) {
2573 ehdr.e_type = ET_REL;
2574 } else {
2575 if (file_type & TCC_OUTPUT_DYN)
2576 ehdr.e_type = ET_DYN;
2577 else
2578 ehdr.e_type = ET_EXEC;
2579 if (s1->elf_entryname)
2580 ehdr.e_entry = get_sym_addr(s1, s1->elf_entryname, 1, 0);
2581 else
2582 ehdr.e_entry = get_sym_addr(s1, "_start", !!(file_type & TCC_OUTPUT_EXE), 0);
2583 if (ehdr.e_entry == (addr_t)-1)
2584 ehdr.e_entry = text_section->sh_addr;
2585 if (s1->nb_errors)
2586 return -1;
2589 ehdr.e_machine = EM_TCC_TARGET;
2590 ehdr.e_version = EV_CURRENT;
2591 ehdr.e_shoff = file_offset;
2592 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2593 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2594 ehdr.e_shnum = shnum;
2595 ehdr.e_shstrndx = shnum - 1;
2597 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2598 if (phdr)
2599 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2600 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2602 sort_syms(s1, symtab_section);
2604 for(i = 1; i < shnum; i++) {
2605 s = s1->sections[sec_order ? sec_order[i] : i];
2606 if (s->sh_type != SHT_NOBITS) {
2607 while (offset < s->sh_offset) {
2608 fputc(0, f);
2609 offset++;
2611 size = s->sh_size;
2612 if (size)
2613 fwrite(s->data, 1, size, f);
2614 offset += size;
2618 /* output section headers */
2619 while (offset < ehdr.e_shoff) {
2620 fputc(0, f);
2621 offset++;
2624 for(i = 0; i < shnum; i++) {
2625 sh = &shdr;
2626 memset(sh, 0, sizeof(ElfW(Shdr)));
2627 s = s1->sections[i];
2628 if (s) {
2629 sh->sh_name = s->sh_name;
2630 sh->sh_type = s->sh_type;
2631 sh->sh_flags = s->sh_flags;
2632 sh->sh_entsize = s->sh_entsize;
2633 sh->sh_info = s->sh_info;
2634 if (s->link)
2635 sh->sh_link = s->link->sh_num;
2636 sh->sh_addralign = s->sh_addralign;
2637 sh->sh_addr = s->sh_addr;
2638 sh->sh_offset = s->sh_offset;
2639 sh->sh_size = s->sh_size;
2641 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2643 return 0;
2646 static int tcc_output_binary(TCCState *s1, FILE *f,
2647 const int *sec_order)
2649 Section *s;
2650 int i, offset, size;
2652 offset = 0;
2653 for(i=1;i<s1->nb_sections;i++) {
2654 s = s1->sections[sec_order[i]];
2655 if (s->sh_type != SHT_NOBITS &&
2656 (s->sh_flags & SHF_ALLOC)) {
2657 while (offset < s->sh_offset) {
2658 fputc(0, f);
2659 offset++;
2661 size = s->sh_size;
2662 fwrite(s->data, 1, size, f);
2663 offset += size;
2666 return 0;
2669 /* Write an elf, coff or "binary" file */
2670 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2671 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2673 int fd, mode, file_type, ret;
2674 FILE *f;
2676 file_type = s1->output_type;
2677 if (file_type == TCC_OUTPUT_OBJ)
2678 mode = 0666;
2679 else
2680 mode = 0777;
2681 unlink(filename);
2682 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2683 if (fd < 0 || (f = fdopen(fd, "wb")) == NULL)
2684 return tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno));
2685 if (s1->verbose)
2686 printf("<- %s\n", filename);
2687 #ifdef TCC_TARGET_COFF
2688 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2689 tcc_output_coff(s1, f);
2690 else
2691 #endif
2692 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2693 ret = tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2694 else
2695 ret = tcc_output_binary(s1, f, sec_order);
2696 fclose(f);
2698 return ret;
2701 #ifndef ELF_OBJ_ONLY
2702 /* Sort section headers by assigned sh_addr, remove sections
2703 that we aren't going to output. */
2704 static int tidy_section_headers(TCCState *s1, int *sec_order)
2706 int i, nnew, l, *backmap;
2707 Section **snew, *s;
2708 ElfW(Sym) *sym;
2710 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2711 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2712 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2713 s = s1->sections[sec_order[i]];
2714 if (!i || s->sh_name) {
2715 backmap[sec_order[i]] = nnew;
2716 snew[nnew] = s;
2717 ++nnew;
2718 } else {
2719 backmap[sec_order[i]] = 0;
2720 snew[--l] = s;
2723 for (i = 0; i < nnew; i++) {
2724 s = snew[i];
2725 if (s) {
2726 s->sh_num = i;
2727 if (s->sh_type == SHT_RELX)
2728 s->sh_info = backmap[s->sh_info];
2732 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2733 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2734 sym->st_shndx = backmap[sym->st_shndx];
2735 if ( !s1->static_link ) {
2736 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2737 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2738 sym->st_shndx = backmap[sym->st_shndx];
2740 for (i = 0; i < s1->nb_sections; i++)
2741 sec_order[i] = i;
2742 tcc_free(s1->sections);
2743 s1->sections = snew;
2744 tcc_free(backmap);
2745 return nnew;
2748 #ifdef TCC_TARGET_ARM
2749 static void create_arm_attribute_section(TCCState *s1)
2751 // Needed for DLL support.
2752 static const unsigned char arm_attr[] = {
2753 0x41, // 'A'
2754 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2755 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2756 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2757 0x05, 0x36, 0x00, // 'CPU_name', "6"
2758 0x06, 0x06, // 'CPU_arch', 'v6'
2759 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2760 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2761 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2762 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2763 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2764 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2765 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2766 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2767 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2768 0x1a, 0x02, // 'ABI_enum_size', 'int'
2769 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2770 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2772 Section *attr = new_section(s1, ".ARM.attributes", SHT_ARM_ATTRIBUTES, 0);
2773 unsigned char *ptr = section_ptr_add(attr, sizeof(arm_attr));
2774 attr->sh_addralign = 1;
2775 memcpy(ptr, arm_attr, sizeof(arm_attr));
2776 if (s1->float_abi != ARM_HARD_FLOAT) {
2777 ptr[26] = 0x00; // 'FP_arch', 'No'
2778 ptr[41] = 0x1e; // 'ABI_optimization_goals'
2779 ptr[42] = 0x06; // 'Aggressive Debug'
2782 #endif
2784 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2785 static Section *create_bsd_note_section(TCCState *s1,
2786 const char *name,
2787 const char *value)
2789 Section *s = find_section (s1, name);
2791 if (s->data_offset == 0) {
2792 char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
2793 ElfW(Nhdr) *note = (ElfW(Nhdr) *) ptr;
2795 s->sh_type = SHT_NOTE;
2796 note->n_namesz = 8;
2797 note->n_descsz = 4;
2798 note->n_type = ELF_NOTE_OS_GNU;
2799 strcpy (ptr + sizeof(ElfW(Nhdr)), value);
2801 return s;
2803 #endif
2805 static void alloc_sec_names(TCCState *s1, int is_obj);
2807 /* Output an elf, coff or binary file */
2808 /* XXX: suppress unneeded sections */
2809 static int elf_output_file(TCCState *s1, const char *filename)
2811 int i, ret, file_type, file_offset, *sec_order;
2812 struct dyn_inf dyninf = {0};
2813 Section *interp, *dynstr, *dynamic;
2814 int textrel, got_sym, dt_flags_1;
2816 file_type = s1->output_type;
2817 s1->nb_errors = 0;
2818 ret = -1;
2819 interp = dynstr = dynamic = NULL;
2820 sec_order = NULL;
2821 dyninf.roinf = &dyninf._roinf;
2823 #ifdef TCC_TARGET_ARM
2824 create_arm_attribute_section (s1);
2825 #endif
2827 #if TARGETOS_OpenBSD
2828 dyninf.note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
2829 #endif
2831 #if TARGETOS_NetBSD
2832 dyninf.note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD");
2833 #endif
2835 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
2836 dyninf.roinf = NULL;
2837 #endif
2838 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2839 tcc_add_runtime(s1);
2840 resolve_common_syms(s1);
2842 if (!s1->static_link) {
2843 if (file_type & TCC_OUTPUT_EXE) {
2844 char *ptr;
2845 /* allow override the dynamic loader */
2846 const char *elfint = getenv("LD_SO");
2847 if (elfint == NULL)
2848 elfint = DEFAULT_ELFINTERP(s1);
2849 /* add interpreter section only if executable */
2850 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2851 interp->sh_addralign = 1;
2852 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2853 strcpy(ptr, elfint);
2854 dyninf.interp = interp;
2857 /* add dynamic symbol table */
2858 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2859 ".dynstr",
2860 ".hash", SHF_ALLOC);
2861 /* Number of local symbols (readelf complains if not set) */
2862 s1->dynsym->sh_info = 1;
2863 dynstr = s1->dynsym->link;
2864 /* add dynamic section */
2865 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2866 SHF_ALLOC | SHF_WRITE);
2867 dynamic->link = dynstr;
2868 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2870 got_sym = build_got(s1);
2871 if (file_type & TCC_OUTPUT_EXE) {
2872 bind_exe_dynsyms(s1, file_type & TCC_OUTPUT_DYN);
2873 if (s1->nb_errors)
2874 goto the_end;
2876 build_got_entries(s1, got_sym);
2877 if (file_type & TCC_OUTPUT_EXE) {
2878 bind_libs_dynsyms(s1);
2879 } else {
2880 /* shared library case: simply export all global symbols */
2881 export_global_syms(s1);
2883 dyninf.gnu_hash = create_gnu_hash(s1);
2884 } else {
2885 build_got_entries(s1, 0);
2887 version_add (s1);
2889 textrel = set_sec_sizes(s1);
2890 alloc_sec_names(s1, 0);
2892 if (!s1->static_link) {
2893 /* add a list of needed dlls */
2894 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2895 DLLReference *dllref = s1->loaded_dlls[i];
2896 if (dllref->level == 0)
2897 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2900 if (s1->rpath)
2901 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2902 put_elf_str(dynstr, s1->rpath));
2904 dt_flags_1 = DF_1_NOW;
2905 if (file_type & TCC_OUTPUT_DYN) {
2906 if (s1->soname)
2907 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2908 /* XXX: currently, since we do not handle PIC code, we
2909 must relocate the readonly segments */
2910 if (textrel)
2911 put_dt(dynamic, DT_TEXTREL, 0);
2912 if (file_type & TCC_OUTPUT_EXE)
2913 dt_flags_1 = DF_1_NOW | DF_1_PIE;
2915 put_dt(dynamic, DT_FLAGS, DF_BIND_NOW);
2916 put_dt(dynamic, DT_FLAGS_1, dt_flags_1);
2917 if (s1->symbolic)
2918 put_dt(dynamic, DT_SYMBOLIC, 0);
2920 dyninf.dynamic = dynamic;
2921 dyninf.dynstr = dynstr;
2922 /* remember offset and reserve space for 2nd call below */
2923 dyninf.data_offset = dynamic->data_offset;
2924 fill_dynamic(s1, &dyninf);
2925 dynamic->sh_size = dynamic->data_offset;
2926 dynstr->sh_size = dynstr->data_offset;
2929 /* this array is used to reorder sections in the output file */
2930 sec_order = tcc_malloc(sizeof(int) * 2 * s1->nb_sections);
2931 /* compute section to program header mapping */
2932 file_offset = layout_sections(s1, sec_order, &dyninf);
2934 if (dynamic) {
2935 /* put in GOT the dynamic section address and relocate PLT */
2936 write32le(s1->got->data, dynamic->sh_addr);
2937 if (file_type == TCC_OUTPUT_EXE
2938 || (RELOCATE_DLLPLT && (file_type & TCC_OUTPUT_DYN)))
2939 relocate_plt(s1);
2940 /* relocate symbols in .dynsym now that final addresses are known */
2941 relocate_syms(s1, s1->dynsym, 2);
2944 /* if building executable or DLL, then relocate each section
2945 except the GOT which is already relocated */
2946 relocate_syms(s1, s1->symtab, 0);
2947 if (s1->nb_errors != 0)
2948 goto the_end;
2949 relocate_sections(s1);
2950 if (dynamic) {
2951 update_reloc_sections (s1, &dyninf);
2952 dynamic->data_offset = dyninf.data_offset;
2953 fill_dynamic(s1, &dyninf);
2955 /* Perform relocation to GOT or PLT entries */
2956 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2957 fill_got(s1);
2958 else if (s1->got)
2959 fill_local_got_entries(s1);
2961 if (dyninf.gnu_hash)
2962 update_gnu_hash(s1, dyninf.gnu_hash);
2964 /* Create the ELF file with name 'filename' */
2965 ret = tcc_write_elf_file(s1, filename, dyninf.phnum, dyninf.phdr, file_offset, sec_order);
2966 the_end:
2967 tcc_free(sec_order);
2968 tcc_free(dyninf.phdr);
2969 return ret;
2971 #endif /* ndef ELF_OBJ_ONLY */
2973 /* Allocate strings for section names */
2974 static void alloc_sec_names(TCCState *s1, int is_obj)
2976 int i;
2977 Section *s, *strsec;
2979 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2980 put_elf_str(strsec, "");
2981 for(i = 1; i < s1->nb_sections; i++) {
2982 s = s1->sections[i];
2983 if (is_obj)
2984 s->sh_size = s->data_offset;
2985 if (s == strsec || s->sh_size || (s->sh_flags & SHF_ALLOC))
2986 s->sh_name = put_elf_str(strsec, s->name);
2988 strsec->sh_size = strsec->data_offset;
2991 /* Output an elf .o file */
2992 static int elf_output_obj(TCCState *s1, const char *filename)
2994 Section *s;
2995 int i, ret, file_offset;
2996 s1->nb_errors = 0;
2997 /* Allocate strings for section names */
2998 alloc_sec_names(s1, 1);
2999 file_offset = sizeof (ElfW(Ehdr));
3000 for(i = 1; i < s1->nb_sections; i++) {
3001 s = s1->sections[i];
3002 file_offset = (file_offset + 15) & -16;
3003 s->sh_offset = file_offset;
3004 if (s->sh_type != SHT_NOBITS)
3005 file_offset += s->sh_size;
3007 /* Create the ELF file with name 'filename' */
3008 ret = tcc_write_elf_file(s1, filename, 0, NULL, file_offset, NULL);
3009 return ret;
3012 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
3014 if (s->test_coverage)
3015 tcc_tcov_add_file(s, filename);
3016 if (s->output_type == TCC_OUTPUT_OBJ)
3017 return elf_output_obj(s, filename);
3018 #ifdef TCC_TARGET_PE
3019 return pe_output_file(s, filename);
3020 #elif TCC_TARGET_MACHO
3021 return macho_output_file(s, filename);
3022 #else
3023 return elf_output_file(s, filename);
3024 #endif
3027 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
3028 char *cbuf = buf;
3029 size_t rnum = 0;
3030 while (1) {
3031 ssize_t num = read(fd, cbuf, count-rnum);
3032 if (num < 0) return num;
3033 if (num == 0) return rnum;
3034 rnum += num;
3035 cbuf += num;
3039 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
3041 void *data;
3043 data = tcc_malloc(size);
3044 lseek(fd, file_offset, SEEK_SET);
3045 full_read(fd, data, size);
3046 return data;
3049 typedef struct SectionMergeInfo {
3050 Section *s; /* corresponding existing section */
3051 unsigned long offset; /* offset of the new section in the existing section */
3052 uint8_t new_section; /* true if section 's' was added */
3053 uint8_t link_once; /* true if link once section */
3054 } SectionMergeInfo;
3056 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
3058 int size = full_read(fd, h, sizeof *h);
3059 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
3060 if (h->e_type == ET_REL)
3061 return AFF_BINTYPE_REL;
3062 if (h->e_type == ET_DYN)
3063 return AFF_BINTYPE_DYN;
3064 } else if (size >= 8) {
3065 if (0 == memcmp(h, ARMAG, 8))
3066 return AFF_BINTYPE_AR;
3067 #ifdef TCC_TARGET_COFF
3068 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
3069 return AFF_BINTYPE_C67;
3070 #endif
3072 return 0;
3075 /* load an object file and merge it with current files */
3076 /* XXX: handle correctly stab (debug) info */
3077 ST_FUNC int tcc_load_object_file(TCCState *s1,
3078 int fd, unsigned long file_offset)
3080 ElfW(Ehdr) ehdr;
3081 ElfW(Shdr) *shdr, *sh;
3082 unsigned long size, offset, offseti;
3083 int i, j, nb_syms, sym_index, ret, seencompressed;
3084 char *strsec, *strtab;
3085 int stab_index, stabstr_index;
3086 int *old_to_new_syms;
3087 char *sh_name, *name;
3088 SectionMergeInfo *sm_table, *sm;
3089 ElfW(Sym) *sym, *symtab;
3090 ElfW_Rel *rel;
3091 Section *s;
3093 lseek(fd, file_offset, SEEK_SET);
3094 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
3095 goto invalid;
3096 /* test CPU specific stuff */
3097 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3098 ehdr.e_machine != EM_TCC_TARGET) {
3099 invalid:
3100 return tcc_error_noabort("invalid object file");
3102 /* read sections */
3103 shdr = load_data(fd, file_offset + ehdr.e_shoff,
3104 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3105 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
3107 /* load section names */
3108 sh = &shdr[ehdr.e_shstrndx];
3109 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3111 /* load symtab and strtab */
3112 old_to_new_syms = NULL;
3113 symtab = NULL;
3114 strtab = NULL;
3115 nb_syms = 0;
3116 seencompressed = 0;
3117 stab_index = stabstr_index = 0;
3118 ret = -1;
3120 for(i = 1; i < ehdr.e_shnum; i++) {
3121 sh = &shdr[i];
3122 if (sh->sh_type == SHT_SYMTAB) {
3123 if (symtab) {
3124 tcc_error_noabort("object must contain only one symtab");
3125 goto the_end;
3127 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3128 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3129 sm_table[i].s = symtab_section;
3131 /* now load strtab */
3132 sh = &shdr[sh->sh_link];
3133 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3135 if (sh->sh_flags & SHF_COMPRESSED)
3136 seencompressed = 1;
3139 /* now examine each section and try to merge its content with the
3140 ones in memory */
3141 for(i = 1; i < ehdr.e_shnum; i++) {
3142 /* no need to examine section name strtab */
3143 if (i == ehdr.e_shstrndx)
3144 continue;
3145 sh = &shdr[i];
3146 if (sh->sh_type == SHT_RELX)
3147 sh = &shdr[sh->sh_info];
3148 /* ignore sections types we do not handle (plus relocs to those) */
3149 if (sh->sh_type != SHT_PROGBITS &&
3150 #ifdef TCC_ARM_EABI
3151 sh->sh_type != SHT_ARM_EXIDX &&
3152 #endif
3153 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3154 sh->sh_type != SHT_X86_64_UNWIND &&
3155 #endif
3156 sh->sh_type != SHT_NOTE &&
3157 sh->sh_type != SHT_NOBITS &&
3158 sh->sh_type != SHT_PREINIT_ARRAY &&
3159 sh->sh_type != SHT_INIT_ARRAY &&
3160 sh->sh_type != SHT_FINI_ARRAY &&
3161 strcmp(strsec + sh->sh_name, ".stabstr")
3163 continue;
3164 if (seencompressed && 0 == strncmp(strsec + sh->sh_name, ".debug_", 7))
3165 continue;
3167 sh = &shdr[i];
3168 sh_name = strsec + sh->sh_name;
3169 if (sh->sh_addralign < 1)
3170 sh->sh_addralign = 1;
3171 /* find corresponding section, if any */
3172 for(j = 1; j < s1->nb_sections;j++) {
3173 s = s1->sections[j];
3174 if (!strcmp(s->name, sh_name)) {
3175 if (!strncmp(sh_name, ".gnu.linkonce",
3176 sizeof(".gnu.linkonce") - 1)) {
3177 /* if a 'linkonce' section is already present, we
3178 do not add it again. It is a little tricky as
3179 symbols can still be defined in
3180 it. */
3181 sm_table[i].link_once = 1;
3182 goto next;
3184 if (stab_section) {
3185 if (s == stab_section)
3186 stab_index = i;
3187 if (s == stab_section->link)
3188 stabstr_index = i;
3190 goto found;
3193 /* not found: create new section */
3194 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
3195 /* take as much info as possible from the section. sh_link and
3196 sh_info will be updated later */
3197 s->sh_addralign = sh->sh_addralign;
3198 s->sh_entsize = sh->sh_entsize;
3199 sm_table[i].new_section = 1;
3200 found:
3201 if (sh->sh_type != s->sh_type
3202 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3203 && strcmp (s->name, ".eh_frame")
3204 #endif
3206 tcc_error_noabort("invalid section type");
3207 goto the_end;
3209 /* align start of section */
3210 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
3211 if (sh->sh_addralign > s->sh_addralign)
3212 s->sh_addralign = sh->sh_addralign;
3213 sm_table[i].offset = s->data_offset;
3214 sm_table[i].s = s;
3215 /* concatenate sections */
3216 size = sh->sh_size;
3217 if (sh->sh_type != SHT_NOBITS) {
3218 unsigned char *ptr;
3219 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
3220 ptr = section_ptr_add(s, size);
3221 full_read(fd, ptr, size);
3222 } else {
3223 s->data_offset += size;
3225 next: ;
3228 /* gr relocate stab strings */
3229 if (stab_index && stabstr_index) {
3230 Stab_Sym *a, *b;
3231 unsigned o;
3232 s = sm_table[stab_index].s;
3233 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
3234 b = (Stab_Sym *)(s->data + s->data_offset);
3235 o = sm_table[stabstr_index].offset;
3236 while (a < b) {
3237 if (a->n_strx)
3238 a->n_strx += o;
3239 a++;
3243 /* second short pass to update sh_link and sh_info fields of new
3244 sections */
3245 for(i = 1; i < ehdr.e_shnum; i++) {
3246 s = sm_table[i].s;
3247 if (!s || !sm_table[i].new_section)
3248 continue;
3249 sh = &shdr[i];
3250 if (sh->sh_link > 0)
3251 s->link = sm_table[sh->sh_link].s;
3252 if (sh->sh_type == SHT_RELX) {
3253 s->sh_info = sm_table[sh->sh_info].s->sh_num;
3254 /* update backward link */
3255 s1->sections[s->sh_info]->reloc = s;
3259 /* resolve symbols */
3260 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
3262 sym = symtab + 1;
3263 for(i = 1; i < nb_syms; i++, sym++) {
3264 if (sym->st_shndx != SHN_UNDEF &&
3265 sym->st_shndx < SHN_LORESERVE) {
3266 sm = &sm_table[sym->st_shndx];
3267 if (sm->link_once) {
3268 /* if a symbol is in a link once section, we use the
3269 already defined symbol. It is very important to get
3270 correct relocations */
3271 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
3272 name = strtab + sym->st_name;
3273 sym_index = find_elf_sym(symtab_section, name);
3274 if (sym_index)
3275 old_to_new_syms[i] = sym_index;
3277 continue;
3279 /* if no corresponding section added, no need to add symbol */
3280 if (!sm->s)
3281 continue;
3282 /* convert section number */
3283 sym->st_shndx = sm->s->sh_num;
3284 /* offset value */
3285 sym->st_value += sm->offset;
3287 /* add symbol */
3288 name = strtab + sym->st_name;
3289 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
3290 sym->st_info, sym->st_other,
3291 sym->st_shndx, name);
3292 old_to_new_syms[i] = sym_index;
3295 /* third pass to patch relocation entries */
3296 for(i = 1; i < ehdr.e_shnum; i++) {
3297 s = sm_table[i].s;
3298 if (!s)
3299 continue;
3300 sh = &shdr[i];
3301 offset = sm_table[i].offset;
3302 size = sh->sh_size;
3303 switch(s->sh_type) {
3304 case SHT_RELX:
3305 /* take relocation offset information */
3306 offseti = sm_table[sh->sh_info].offset;
3307 for (rel = (ElfW_Rel *) s->data + (offset / sizeof(*rel));
3308 rel < (ElfW_Rel *) s->data + ((offset + size) / sizeof(*rel));
3309 rel++) {
3310 int type;
3311 unsigned sym_index;
3312 /* convert symbol index */
3313 type = ELFW(R_TYPE)(rel->r_info);
3314 sym_index = ELFW(R_SYM)(rel->r_info);
3315 /* NOTE: only one symtab assumed */
3316 if (sym_index >= nb_syms)
3317 goto invalid_reloc;
3318 sym_index = old_to_new_syms[sym_index];
3319 /* ignore link_once in rel section. */
3320 if (!sym_index && !sm_table[sh->sh_info].link_once
3321 #ifdef TCC_TARGET_ARM
3322 && type != R_ARM_V4BX
3323 #elif defined TCC_TARGET_RISCV64
3324 && type != R_RISCV_ALIGN
3325 && type != R_RISCV_RELAX
3326 #endif
3328 invalid_reloc:
3329 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3330 i, strsec + sh->sh_name, (int)rel->r_offset);
3331 goto the_end;
3333 rel->r_info = ELFW(R_INFO)(sym_index, type);
3334 /* offset the relocation offset */
3335 rel->r_offset += offseti;
3336 #ifdef TCC_TARGET_ARM
3337 /* Jumps and branches from a Thumb code to a PLT entry need
3338 special handling since PLT entries are ARM code.
3339 Unconditional bl instructions referencing PLT entries are
3340 handled by converting these instructions into blx
3341 instructions. Other case of instructions referencing a PLT
3342 entry require to add a Thumb stub before the PLT entry to
3343 switch to ARM mode. We set bit plt_thumb_stub of the
3344 attribute of a symbol to indicate such a case. */
3345 if (type == R_ARM_THM_JUMP24)
3346 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
3347 #endif
3349 break;
3350 default:
3351 break;
3355 ret = 0;
3356 the_end:
3357 tcc_free(symtab);
3358 tcc_free(strtab);
3359 tcc_free(old_to_new_syms);
3360 tcc_free(sm_table);
3361 tcc_free(strsec);
3362 tcc_free(shdr);
3363 return ret;
3366 typedef struct ArchiveHeader {
3367 char ar_name[16]; /* name of this member */
3368 char ar_date[12]; /* file mtime */
3369 char ar_uid[6]; /* owner uid; printed as decimal */
3370 char ar_gid[6]; /* owner gid; printed as decimal */
3371 char ar_mode[8]; /* file mode, printed as octal */
3372 char ar_size[10]; /* file size, printed as decimal */
3373 char ar_fmag[2]; /* should contain ARFMAG */
3374 } ArchiveHeader;
3376 #define ARFMAG "`\n"
3378 static unsigned long long get_be(const uint8_t *b, int n)
3380 unsigned long long ret = 0;
3381 while (n)
3382 ret = (ret << 8) | *b++, --n;
3383 return ret;
3386 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
3388 char *p, *e;
3389 int len;
3390 lseek(fd, offset, SEEK_SET);
3391 len = full_read(fd, hdr, sizeof(ArchiveHeader));
3392 if (len != sizeof(ArchiveHeader))
3393 return len ? -1 : 0;
3394 p = hdr->ar_name;
3395 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
3396 --e;
3397 *e = '\0';
3398 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
3399 return len;
3402 /* load only the objects which resolve undefined symbols */
3403 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
3405 int i, bound, nsyms, sym_index, len, ret = -1;
3406 unsigned long long off;
3407 uint8_t *data;
3408 const char *ar_names, *p;
3409 const uint8_t *ar_index;
3410 ElfW(Sym) *sym;
3411 ArchiveHeader hdr;
3413 data = tcc_malloc(size);
3414 if (full_read(fd, data, size) != size)
3415 goto the_end;
3416 nsyms = get_be(data, entrysize);
3417 ar_index = data + entrysize;
3418 ar_names = (char *) ar_index + nsyms * entrysize;
3420 do {
3421 bound = 0;
3422 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
3423 Section *s = symtab_section;
3424 sym_index = find_elf_sym(s, p);
3425 if (!sym_index)
3426 continue;
3427 sym = &((ElfW(Sym) *)s->data)[sym_index];
3428 if(sym->st_shndx != SHN_UNDEF)
3429 continue;
3430 off = get_be(ar_index + i * entrysize, entrysize);
3431 len = read_ar_header(fd, off, &hdr);
3432 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
3433 tcc_error_noabort("invalid archive");
3434 goto the_end;
3436 off += len;
3437 if (s1->verbose == 2)
3438 printf(" -> %s\n", hdr.ar_name);
3439 if (tcc_load_object_file(s1, fd, off) < 0)
3440 goto the_end;
3441 ++bound;
3443 } while(bound);
3444 ret = 0;
3445 the_end:
3446 tcc_free(data);
3447 return ret;
3450 /* load a '.a' file */
3451 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
3453 ArchiveHeader hdr;
3454 /* char magic[8]; */
3455 int size, len;
3456 unsigned long file_offset;
3457 ElfW(Ehdr) ehdr;
3459 /* skip magic which was already checked */
3460 /* full_read(fd, magic, sizeof(magic)); */
3461 file_offset = sizeof ARMAG - 1;
3463 for(;;) {
3464 len = read_ar_header(fd, file_offset, &hdr);
3465 if (len == 0)
3466 return 0;
3467 if (len < 0)
3468 return tcc_error_noabort("invalid archive");
3469 file_offset += len;
3470 size = strtol(hdr.ar_size, NULL, 0);
3471 /* align to even */
3472 size = (size + 1) & ~1;
3473 if (alacarte) {
3474 /* coff symbol table : we handle it */
3475 if (!strcmp(hdr.ar_name, "/"))
3476 return tcc_load_alacarte(s1, fd, size, 4);
3477 if (!strcmp(hdr.ar_name, "/SYM64/"))
3478 return tcc_load_alacarte(s1, fd, size, 8);
3479 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3480 if (s1->verbose == 2)
3481 printf(" -> %s\n", hdr.ar_name);
3482 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3483 return -1;
3485 file_offset += size;
3489 #ifndef ELF_OBJ_ONLY
3490 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3491 LV, maybe create a new entry for (LIB,VERSION). */
3492 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3494 while (i >= *n) {
3495 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3496 (*lv)[(*n)++] = -1;
3498 if ((*lv)[i] == -1) {
3499 int v, prev_same_lib = -1;
3500 for (v = 0; v < nb_sym_versions; v++) {
3501 if (strcmp(sym_versions[v].lib, lib))
3502 continue;
3503 prev_same_lib = v;
3504 if (!strcmp(sym_versions[v].version, version))
3505 break;
3507 if (v == nb_sym_versions) {
3508 sym_versions = tcc_realloc (sym_versions,
3509 (v + 1) * sizeof(*sym_versions));
3510 sym_versions[v].lib = tcc_strdup(lib);
3511 sym_versions[v].version = tcc_strdup(version);
3512 sym_versions[v].out_index = 0;
3513 sym_versions[v].prev_same_lib = prev_same_lib;
3514 nb_sym_versions++;
3516 (*lv)[i] = v;
3520 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3521 VERNDX. */
3522 static void
3523 set_sym_version(TCCState *s1, int sym_index, int verndx)
3525 if (sym_index >= nb_sym_to_version) {
3526 int newelems = sym_index ? sym_index * 2 : 1;
3527 sym_to_version = tcc_realloc(sym_to_version,
3528 newelems * sizeof(*sym_to_version));
3529 memset(sym_to_version + nb_sym_to_version, -1,
3530 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3531 nb_sym_to_version = newelems;
3533 if (sym_to_version[sym_index] < 0)
3534 sym_to_version[sym_index] = verndx;
3537 struct versym_info {
3538 int nb_versyms;
3539 ElfW(Verdef) *verdef;
3540 ElfW(Verneed) *verneed;
3541 ElfW(Half) *versym;
3542 int nb_local_ver, *local_ver;
3546 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3548 char *lib, *version;
3549 uint32_t next;
3550 int i;
3552 #define DEBUG_VERSION 0
3554 if (v->versym && v->verdef) {
3555 ElfW(Verdef) *vdef = v->verdef;
3556 lib = NULL;
3557 do {
3558 ElfW(Verdaux) *verdaux =
3559 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3561 #if DEBUG_VERSION
3562 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3563 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3564 vdef->vd_hash);
3565 #endif
3566 if (vdef->vd_cnt) {
3567 version = dynstr + verdaux->vda_name;
3569 if (lib == NULL)
3570 lib = version;
3571 else
3572 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3573 lib, version);
3574 #if DEBUG_VERSION
3575 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3576 #endif
3578 next = vdef->vd_next;
3579 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3580 } while (next);
3582 if (v->versym && v->verneed) {
3583 ElfW(Verneed) *vneed = v->verneed;
3584 do {
3585 ElfW(Vernaux) *vernaux =
3586 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3588 lib = dynstr + vneed->vn_file;
3589 #if DEBUG_VERSION
3590 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3591 #endif
3592 for (i = 0; i < vneed->vn_cnt; i++) {
3593 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3594 version = dynstr + vernaux->vna_name;
3595 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3596 lib, version);
3597 #if DEBUG_VERSION
3598 printf (" vernaux(%u): %u %u %s\n",
3599 vernaux->vna_other, vernaux->vna_hash,
3600 vernaux->vna_flags, version);
3601 #endif
3603 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3605 next = vneed->vn_next;
3606 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3607 } while (next);
3610 #if DEBUG_VERSION
3611 for (i = 0; i < v->nb_local_ver; i++) {
3612 if (v->local_ver[i] > 0) {
3613 printf ("%d: lib: %s, version %s\n",
3614 i, sym_versions[v->local_ver[i]].lib,
3615 sym_versions[v->local_ver[i]].version);
3618 #endif
3621 /* load a library / DLL
3622 'level = 0' means that the DLL is referenced by the user
3623 (so it should be added as DT_NEEDED in the generated ELF file) */
3624 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3626 ElfW(Ehdr) ehdr;
3627 ElfW(Shdr) *shdr, *sh, *sh1;
3628 int i, nb_syms, nb_dts, sym_bind, ret = -1;
3629 ElfW(Sym) *sym, *dynsym;
3630 ElfW(Dyn) *dt, *dynamic;
3632 char *dynstr;
3633 int sym_index;
3634 const char *name, *soname;
3635 struct versym_info v;
3637 full_read(fd, &ehdr, sizeof(ehdr));
3639 /* test CPU specific stuff */
3640 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3641 ehdr.e_machine != EM_TCC_TARGET) {
3642 return tcc_error_noabort("bad architecture");
3645 /* read sections */
3646 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3648 /* load dynamic section and dynamic symbols */
3649 nb_syms = 0;
3650 nb_dts = 0;
3651 dynamic = NULL;
3652 dynsym = NULL; /* avoid warning */
3653 dynstr = NULL; /* avoid warning */
3654 memset(&v, 0, sizeof v);
3656 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3657 switch(sh->sh_type) {
3658 case SHT_DYNAMIC:
3659 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3660 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3661 break;
3662 case SHT_DYNSYM:
3663 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3664 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3665 sh1 = &shdr[sh->sh_link];
3666 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3667 break;
3668 case SHT_GNU_verdef:
3669 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3670 break;
3671 case SHT_GNU_verneed:
3672 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3673 break;
3674 case SHT_GNU_versym:
3675 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3676 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3677 break;
3678 default:
3679 break;
3683 if (!dynamic)
3684 goto the_end;
3686 /* compute the real library name */
3687 soname = tcc_basename(filename);
3688 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
3689 if (dt->d_tag == DT_SONAME)
3690 soname = dynstr + dt->d_un.d_val;
3692 /* if the dll is already loaded, do not load it */
3693 if (tcc_add_dllref(s1, soname, level)->found)
3694 goto ret_success;
3696 if (v.nb_versyms != nb_syms)
3697 tcc_free (v.versym), v.versym = NULL;
3698 else
3699 store_version(s1, &v, dynstr);
3701 /* add dynamic symbols in dynsym_section */
3702 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3703 sym_bind = ELFW(ST_BIND)(sym->st_info);
3704 if (sym_bind == STB_LOCAL)
3705 continue;
3706 name = dynstr + sym->st_name;
3707 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3708 sym->st_info, sym->st_other, sym->st_shndx, name);
3709 if (v.versym) {
3710 ElfW(Half) vsym = v.versym[i];
3711 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3712 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3716 /* do not load all referenced libraries
3717 (recursive loading can break linking of libraries) */
3718 /* following DT_NEEDED is needed for the dynamic loader (libdl.so),
3719 but it is no longer needed, when linking a library or a program.
3720 When tcc output mode is OUTPUT_MEM,
3721 tcc calls dlopen, which handles DT_NEEDED for us */
3723 #if 0
3724 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
3725 if (dt->d_tag == DT_RPATH)
3726 tcc_add_library_path(s1, dynstr + dt->d_un.d_val);
3728 /* load all referenced DLLs */
3729 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3730 switch(dt->d_tag) {
3731 case DT_NEEDED:
3732 name = dynstr + dt->d_un.d_val;
3733 if (tcc_add_dllref(s1, name, -1))
3734 continue;
3735 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3736 ret = tcc_error_noabort("referenced dll '%s' not found", name);
3737 goto the_end;
3741 #endif
3743 ret_success:
3744 ret = 0;
3745 the_end:
3746 tcc_free(dynstr);
3747 tcc_free(dynsym);
3748 tcc_free(dynamic);
3749 tcc_free(shdr);
3750 tcc_free(v.local_ver);
3751 tcc_free(v.verdef);
3752 tcc_free(v.verneed);
3753 tcc_free(v.versym);
3754 return ret;
3757 #define LD_TOK_NAME 256
3758 #define LD_TOK_EOF (-1)
3760 static int ld_inp(TCCState *s1)
3762 char b;
3763 if (s1->cc != -1) {
3764 int c = s1->cc;
3765 s1->cc = -1;
3766 return c;
3768 if (1 == read(s1->fd, &b, 1))
3769 return b;
3770 return CH_EOF;
3773 /* return next ld script token */
3774 static int ld_next(TCCState *s1, char *name, int name_size)
3776 int c, d, ch;
3777 char *q;
3779 redo:
3780 ch = ld_inp(s1);
3781 switch(ch) {
3782 case ' ':
3783 case '\t':
3784 case '\f':
3785 case '\v':
3786 case '\r':
3787 case '\n':
3788 goto redo;
3789 case '/':
3790 ch = ld_inp(s1);
3791 if (ch == '*') { /* comment */
3792 for (d = 0;; d = ch) {
3793 ch = ld_inp(s1);
3794 if (ch == CH_EOF || (ch == '/' && d == '*'))
3795 break;
3797 goto redo;
3798 } else {
3799 q = name;
3800 *q++ = '/';
3801 goto parse_name;
3803 break;
3804 case '\\':
3805 /* case 'a' ... 'z': */
3806 case 'a':
3807 case 'b':
3808 case 'c':
3809 case 'd':
3810 case 'e':
3811 case 'f':
3812 case 'g':
3813 case 'h':
3814 case 'i':
3815 case 'j':
3816 case 'k':
3817 case 'l':
3818 case 'm':
3819 case 'n':
3820 case 'o':
3821 case 'p':
3822 case 'q':
3823 case 'r':
3824 case 's':
3825 case 't':
3826 case 'u':
3827 case 'v':
3828 case 'w':
3829 case 'x':
3830 case 'y':
3831 case 'z':
3832 /* case 'A' ... 'z': */
3833 case 'A':
3834 case 'B':
3835 case 'C':
3836 case 'D':
3837 case 'E':
3838 case 'F':
3839 case 'G':
3840 case 'H':
3841 case 'I':
3842 case 'J':
3843 case 'K':
3844 case 'L':
3845 case 'M':
3846 case 'N':
3847 case 'O':
3848 case 'P':
3849 case 'Q':
3850 case 'R':
3851 case 'S':
3852 case 'T':
3853 case 'U':
3854 case 'V':
3855 case 'W':
3856 case 'X':
3857 case 'Y':
3858 case 'Z':
3859 case '_':
3860 case '.':
3861 case '$':
3862 case '~':
3863 q = name;
3864 parse_name:
3865 for(;;) {
3866 if (!((ch >= 'a' && ch <= 'z') ||
3867 (ch >= 'A' && ch <= 'Z') ||
3868 (ch >= '0' && ch <= '9') ||
3869 strchr("/.-_+=$:\\,~", ch)))
3870 break;
3871 if ((q - name) < name_size - 1) {
3872 *q++ = ch;
3874 ch = ld_inp(s1);
3876 s1->cc = ch;
3877 *q = '\0';
3878 c = LD_TOK_NAME;
3879 break;
3880 case CH_EOF:
3881 c = LD_TOK_EOF;
3882 break;
3883 default:
3884 c = ch;
3885 break;
3887 return c;
3890 static int ld_add_file(TCCState *s1, const char filename[])
3892 if (filename[0] == '/') {
3893 if (CONFIG_SYSROOT[0] == '\0'
3894 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3895 return 0;
3896 filename = tcc_basename(filename);
3898 return tcc_add_dll(s1, filename, AFF_PRINT_ERROR);
3901 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3903 char filename[1024], libname[1024];
3904 int t, group, nblibs = 0, ret = 0;
3905 char **libs = NULL;
3907 group = !strcmp(cmd, "GROUP");
3908 if (!as_needed)
3909 s1->new_undef_sym = 0;
3910 t = ld_next(s1, filename, sizeof(filename));
3911 if (t != '(') {
3912 ret = tcc_error_noabort("( expected");
3913 goto lib_parse_error;
3915 t = ld_next(s1, filename, sizeof(filename));
3916 for(;;) {
3917 libname[0] = '\0';
3918 if (t == LD_TOK_EOF) {
3919 ret = tcc_error_noabort("unexpected end of file");
3920 goto lib_parse_error;
3921 } else if (t == ')') {
3922 break;
3923 } else if (t == '-') {
3924 t = ld_next(s1, filename, sizeof(filename));
3925 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3926 ret = tcc_error_noabort("library name expected");
3927 goto lib_parse_error;
3929 pstrcpy(libname, sizeof libname, &filename[1]);
3930 if (s1->static_link) {
3931 snprintf(filename, sizeof filename, "lib%s.a", libname);
3932 } else {
3933 snprintf(filename, sizeof filename, "lib%s.so", libname);
3935 } else if (t != LD_TOK_NAME) {
3936 ret = tcc_error_noabort("filename expected");
3937 goto lib_parse_error;
3939 if (!strcmp(filename, "AS_NEEDED")) {
3940 ret = ld_add_file_list(s1, cmd, 1);
3941 if (ret)
3942 goto lib_parse_error;
3943 } else {
3944 /* TODO: Implement AS_NEEDED support. */
3945 /* DT_NEEDED is not used any more so ignore as_needed */
3946 if (1 || !as_needed) {
3947 ret = ld_add_file(s1, filename);
3948 if (ret)
3949 goto lib_parse_error;
3950 if (group) {
3951 /* Add the filename *and* the libname to avoid future conversions */
3952 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3953 if (libname[0] != '\0')
3954 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3958 t = ld_next(s1, filename, sizeof(filename));
3959 if (t == ',') {
3960 t = ld_next(s1, filename, sizeof(filename));
3963 if (group && !as_needed) {
3964 while (s1->new_undef_sym) {
3965 int i;
3966 s1->new_undef_sym = 0;
3967 for (i = 0; i < nblibs; i ++)
3968 ld_add_file(s1, libs[i]);
3971 lib_parse_error:
3972 dynarray_reset(&libs, &nblibs);
3973 return ret;
3976 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3977 files */
3978 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3980 char cmd[64];
3981 char filename[1024];
3982 int t, ret;
3984 s1->fd = fd;
3985 s1->cc = -1;
3986 for(;;) {
3987 t = ld_next(s1, cmd, sizeof(cmd));
3988 if (t == LD_TOK_EOF)
3989 return 0;
3990 else if (t != LD_TOK_NAME)
3991 return -1;
3992 if (!strcmp(cmd, "INPUT") ||
3993 !strcmp(cmd, "GROUP")) {
3994 ret = ld_add_file_list(s1, cmd, 0);
3995 if (ret)
3996 return ret;
3997 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3998 !strcmp(cmd, "TARGET")) {
3999 /* ignore some commands */
4000 t = ld_next(s1, cmd, sizeof(cmd));
4001 if (t != '(')
4002 return tcc_error_noabort("( expected");
4003 for(;;) {
4004 t = ld_next(s1, filename, sizeof(filename));
4005 if (t == LD_TOK_EOF) {
4006 return tcc_error_noabort("unexpected end of file");
4007 } else if (t == ')') {
4008 break;
4011 } else {
4012 return -1;
4015 return 0;
4017 #endif /* !ELF_OBJ_ONLY */