tcc.h: Extend search path for include, lib and crt.
[tinycc.git] / tccelf.c
blob9e860b59899f3dc13cbde0eab68148a1dabaabd2
1 /*
2 * ELF file handling for TCC
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "tcc.h"
23 /* Define this to get some debug output during relocation processing. */
24 #undef DEBUG_RELOC
26 /********************************************************/
27 /* global variables */
29 /* elf version information */
30 struct sym_version {
31 char *lib;
32 char *version;
33 int out_index;
34 int prev_same_lib;
37 #define nb_sym_versions s1->nb_sym_versions
38 #define sym_versions s1->sym_versions
39 #define nb_sym_to_version s1->nb_sym_to_version
40 #define sym_to_version s1->sym_to_version
41 #define dt_verneednum s1->dt_verneednum
42 #define versym_section s1->versym_section
43 #define verneed_section s1->verneed_section
45 /* special flag to indicate that the section should not be linked to the other ones */
46 #define SHF_PRIVATE 0x80000000
47 /* section is dynsymtab_section */
48 #define SHF_DYNSYM 0x40000000
50 /* ------------------------------------------------------------------------- */
52 ST_FUNC void tccelf_new(TCCState *s)
54 TCCState *s1 = s;
55 /* no section zero */
56 dynarray_add(&s->sections, &s->nb_sections, NULL);
58 /* create standard sections */
59 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
60 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
61 #ifdef TCC_TARGET_PE
62 rodata_section = new_section(s, ".rdata", SHT_PROGBITS, SHF_ALLOC);
63 #else
64 /* create ro data section (make ro after relocation done with GNU_RELRO) */
65 rodata_section = new_section(s, ".data.ro", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
66 #endif
67 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
68 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
69 common_section->sh_num = SHN_COMMON;
71 /* symbols are always generated for linking stage */
72 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
73 ".strtab",
74 ".hashtab", SHF_PRIVATE);
75 s->symtab = symtab_section;
77 /* private symbol table for dynamic symbols */
78 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
79 ".dynstrtab",
80 ".dynhashtab", SHF_PRIVATE);
81 get_sym_attr(s, 0, 1);
84 #ifdef CONFIG_TCC_BCHECK
85 ST_FUNC void tccelf_bounds_new(TCCState *s)
87 TCCState *s1 = s;
88 /* create bounds sections (make ro after relocation done with GNU_RELRO) */
89 bounds_section = new_section(s, ".bounds",
90 SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
91 lbounds_section = new_section(s, ".lbounds",
92 SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
94 #endif
96 ST_FUNC void tccelf_stab_new(TCCState *s)
98 TCCState *s1 = s;
99 int shf = 0;
100 #ifdef CONFIG_TCC_BACKTRACE
101 /* include stab info with standalone backtrace support */
102 if (s->do_backtrace && s->output_type != TCC_OUTPUT_MEMORY)
103 shf = SHF_ALLOC | SHF_WRITE; // SHF_WRITE needed for musl/SELINUX
104 #endif
105 stab_section = new_section(s, ".stab", SHT_PROGBITS, shf);
106 stab_section->sh_entsize = sizeof(Stab_Sym);
107 stab_section->sh_addralign = sizeof ((Stab_Sym*)0)->n_value;
108 stab_section->link = new_section(s, ".stabstr", SHT_STRTAB, shf);
109 /* put first entry */
110 put_stabs(s, "", 0, 0, 0, 0);
113 static void free_section(Section *s)
115 tcc_free(s->data);
118 ST_FUNC void tccelf_delete(TCCState *s1)
120 int i;
122 #ifndef ELF_OBJ_ONLY
123 /* free symbol versions */
124 for (i = 0; i < nb_sym_versions; i++) {
125 tcc_free(sym_versions[i].version);
126 tcc_free(sym_versions[i].lib);
128 tcc_free(sym_versions);
129 tcc_free(sym_to_version);
130 #endif
132 /* free all sections */
133 for(i = 1; i < s1->nb_sections; i++)
134 free_section(s1->sections[i]);
135 dynarray_reset(&s1->sections, &s1->nb_sections);
137 for(i = 0; i < s1->nb_priv_sections; i++)
138 free_section(s1->priv_sections[i]);
139 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
141 /* free any loaded DLLs */
142 #ifdef TCC_IS_NATIVE
143 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
144 DLLReference *ref = s1->loaded_dlls[i];
145 if ( ref->handle )
146 # ifdef _WIN32
147 FreeLibrary((HMODULE)ref->handle);
148 # else
149 dlclose(ref->handle);
150 # endif
152 #endif
153 /* free loaded dlls array */
154 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
155 tcc_free(s1->sym_attrs);
157 symtab_section = NULL; /* for tccrun.c:rt_printline() */
160 /* save section data state */
161 ST_FUNC void tccelf_begin_file(TCCState *s1)
163 Section *s; int i;
164 for (i = 1; i < s1->nb_sections; i++) {
165 s = s1->sections[i];
166 s->sh_offset = s->data_offset;
168 /* disable symbol hashing during compilation */
169 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
170 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
171 s1->uw_sym = 0;
172 #endif
175 /* At the end of compilation, convert any UNDEF syms to global, and merge
176 with previously existing symbols */
177 ST_FUNC void tccelf_end_file(TCCState *s1)
179 Section *s = s1->symtab;
180 int first_sym, nb_syms, *tr, i;
182 first_sym = s->sh_offset / sizeof (ElfSym);
183 nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
184 s->data_offset = s->sh_offset;
185 s->link->data_offset = s->link->sh_offset;
186 s->hash = s->reloc, s->reloc = NULL;
187 tr = tcc_mallocz(nb_syms * sizeof *tr);
189 for (i = 0; i < nb_syms; ++i) {
190 ElfSym *sym = (ElfSym*)s->data + first_sym + i;
191 if (sym->st_shndx == SHN_UNDEF
192 && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
193 sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
194 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
195 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
197 /* now update relocations */
198 for (i = 1; i < s1->nb_sections; i++) {
199 Section *sr = s1->sections[i];
200 if (sr->sh_type == SHT_RELX && sr->link == s) {
201 ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
202 ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
203 for (; rel < rel_end; ++rel) {
204 int n = ELFW(R_SYM)(rel->r_info) - first_sym;
205 //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
206 rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
210 tcc_free(tr);
212 /* record text/data/bss output for -bench info */
213 for (i = 0; i < 4; ++i) {
214 s = s1->sections[i + 1];
215 s1->total_output[i] += s->data_offset - s->sh_offset;
219 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
221 Section *sec;
223 sec = tcc_mallocz(sizeof(Section) + strlen(name));
224 sec->s1 = s1;
225 strcpy(sec->name, name);
226 sec->sh_type = sh_type;
227 sec->sh_flags = sh_flags;
228 switch(sh_type) {
229 case SHT_GNU_versym:
230 sec->sh_addralign = 2;
231 break;
232 case SHT_HASH:
233 case SHT_REL:
234 case SHT_RELA:
235 case SHT_DYNSYM:
236 case SHT_SYMTAB:
237 case SHT_DYNAMIC:
238 case SHT_GNU_verneed:
239 case SHT_GNU_verdef:
240 sec->sh_addralign = PTR_SIZE;
241 break;
242 case SHT_STRTAB:
243 sec->sh_addralign = 1;
244 break;
245 default:
246 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */
247 break;
250 if (sh_flags & SHF_PRIVATE) {
251 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
252 } else {
253 sec->sh_num = s1->nb_sections;
254 dynarray_add(&s1->sections, &s1->nb_sections, sec);
257 return sec;
260 ST_FUNC Section *new_symtab(TCCState *s1,
261 const char *symtab_name, int sh_type, int sh_flags,
262 const char *strtab_name,
263 const char *hash_name, int hash_sh_flags)
265 Section *symtab, *strtab, *hash;
266 int *ptr, nb_buckets;
268 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
269 symtab->sh_entsize = sizeof(ElfW(Sym));
270 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
271 put_elf_str(strtab, "");
272 symtab->link = strtab;
273 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
275 nb_buckets = 1;
277 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
278 hash->sh_entsize = sizeof(int);
279 symtab->hash = hash;
280 hash->link = symtab;
282 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
283 ptr[0] = nb_buckets;
284 ptr[1] = 1;
285 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
286 return symtab;
289 /* realloc section and set its content to zero */
290 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
292 unsigned long size;
293 unsigned char *data;
295 size = sec->data_allocated;
296 if (size == 0)
297 size = 1;
298 while (size < new_size)
299 size = size * 2;
300 data = tcc_realloc(sec->data, size);
301 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
302 sec->data = data;
303 sec->data_allocated = size;
306 /* reserve at least 'size' bytes aligned per 'align' in section
307 'sec' from current offset, and return the aligned offset */
308 ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
310 size_t offset, offset1;
312 offset = (sec->data_offset + align - 1) & -align;
313 offset1 = offset + size;
314 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
315 section_realloc(sec, offset1);
316 sec->data_offset = offset1;
317 if (align > sec->sh_addralign)
318 sec->sh_addralign = align;
319 return offset;
322 /* reserve at least 'size' bytes in section 'sec' from
323 sec->data_offset. */
324 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
326 size_t offset = section_add(sec, size, 1);
327 return sec->data + offset;
330 #ifndef ELF_OBJ_ONLY
331 /* reserve at least 'size' bytes from section start */
332 static void section_reserve(Section *sec, unsigned long size)
334 if (size > sec->data_allocated)
335 section_realloc(sec, size);
336 if (size > sec->data_offset)
337 sec->data_offset = size;
339 #endif
341 static Section *find_section_create (TCCState *s1, const char *name, int create)
343 Section *sec;
344 int i;
345 for(i = 1; i < s1->nb_sections; i++) {
346 sec = s1->sections[i];
347 if (!strcmp(name, sec->name))
348 return sec;
350 /* sections are created as PROGBITS */
351 return create ? new_section(s1, name, SHT_PROGBITS, SHF_ALLOC) : NULL;
354 /* return a reference to a section, and create it if it does not
355 exists */
356 ST_FUNC Section *find_section(TCCState *s1, const char *name)
358 return find_section_create (s1, name, 1);
361 /* ------------------------------------------------------------------------- */
363 ST_FUNC int put_elf_str(Section *s, const char *sym)
365 int offset, len;
366 char *ptr;
368 len = strlen(sym) + 1;
369 offset = s->data_offset;
370 ptr = section_ptr_add(s, len);
371 memmove(ptr, sym, len);
372 return offset;
375 /* elf symbol hashing function */
376 static unsigned long elf_hash(const unsigned char *name)
378 unsigned long h = 0, g;
380 while (*name) {
381 h = (h << 4) + *name++;
382 g = h & 0xf0000000;
383 if (g)
384 h ^= g >> 24;
385 h &= ~g;
387 return h;
390 /* rebuild hash table of section s */
391 /* NOTE: we do factorize the hash table code to go faster */
392 static void rebuild_hash(Section *s, unsigned int nb_buckets)
394 ElfW(Sym) *sym;
395 int *ptr, *hash, nb_syms, sym_index, h;
396 unsigned char *strtab;
398 strtab = s->link->data;
399 nb_syms = s->data_offset / sizeof(ElfW(Sym));
401 if (!nb_buckets)
402 nb_buckets = ((int*)s->hash->data)[0];
404 s->hash->data_offset = 0;
405 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
406 ptr[0] = nb_buckets;
407 ptr[1] = nb_syms;
408 ptr += 2;
409 hash = ptr;
410 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
411 ptr += nb_buckets + 1;
413 sym = (ElfW(Sym) *)s->data + 1;
414 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
415 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
416 h = elf_hash(strtab + sym->st_name) % nb_buckets;
417 *ptr = hash[h];
418 hash[h] = sym_index;
419 } else {
420 *ptr = 0;
422 ptr++;
423 sym++;
427 /* return the symbol number */
428 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
429 int info, int other, int shndx, const char *name)
431 int name_offset, sym_index;
432 int nbuckets, h;
433 ElfW(Sym) *sym;
434 Section *hs;
436 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
437 if (name && name[0])
438 name_offset = put_elf_str(s->link, name);
439 else
440 name_offset = 0;
441 /* XXX: endianness */
442 sym->st_name = name_offset;
443 sym->st_value = value;
444 sym->st_size = size;
445 sym->st_info = info;
446 sym->st_other = other;
447 sym->st_shndx = shndx;
448 sym_index = sym - (ElfW(Sym) *)s->data;
449 hs = s->hash;
450 if (hs) {
451 int *ptr, *base;
452 ptr = section_ptr_add(hs, sizeof(int));
453 base = (int *)hs->data;
454 /* only add global or weak symbols. */
455 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
456 /* add another hashing entry */
457 nbuckets = base[0];
458 h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
459 *ptr = base[2 + h];
460 base[2 + h] = sym_index;
461 base[1]++;
462 /* we resize the hash table */
463 hs->nb_hashed_syms++;
464 if (hs->nb_hashed_syms > 2 * nbuckets) {
465 rebuild_hash(s, 2 * nbuckets);
467 } else {
468 *ptr = 0;
469 base[1]++;
472 return sym_index;
475 ST_FUNC int find_elf_sym(Section *s, const char *name)
477 ElfW(Sym) *sym;
478 Section *hs;
479 int nbuckets, sym_index, h;
480 const char *name1;
482 hs = s->hash;
483 if (!hs)
484 return 0;
485 nbuckets = ((int *)hs->data)[0];
486 h = elf_hash((unsigned char *) name) % nbuckets;
487 sym_index = ((int *)hs->data)[2 + h];
488 while (sym_index != 0) {
489 sym = &((ElfW(Sym) *)s->data)[sym_index];
490 name1 = (char *) s->link->data + sym->st_name;
491 if (!strcmp(name, name1))
492 return sym_index;
493 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
495 return 0;
498 /* return elf symbol value, signal error if 'err' is nonzero, decorate
499 name if FORC */
500 ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
502 int sym_index;
503 ElfW(Sym) *sym;
504 char buf[256];
505 if (forc && s1->leading_underscore
506 #ifdef TCC_TARGET_PE
507 /* win32-32bit stdcall symbols always have _ already */
508 && !strchr(name, '@')
509 #endif
511 buf[0] = '_';
512 pstrcpy(buf + 1, sizeof(buf) - 1, name);
513 name = buf;
515 sym_index = find_elf_sym(s1->symtab, name);
516 sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
517 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
518 if (err)
519 tcc_error("%s not defined", name);
520 return (addr_t)-1;
522 return sym->st_value;
525 /* return elf symbol value */
526 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
528 addr_t addr = get_sym_addr(s, name, 0, 1);
529 return addr == -1 ? NULL : (void*)(uintptr_t)addr;
532 /* list elf symbol names and values */
533 ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
534 void (*symbol_cb)(void *ctx, const char *name, const void *val))
536 ElfW(Sym) *sym;
537 Section *symtab;
538 int sym_index, end_sym;
539 const char *name;
540 unsigned char sym_vis, sym_bind;
542 symtab = s->symtab;
543 end_sym = symtab->data_offset / sizeof (ElfSym);
544 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
545 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
546 if (sym->st_value) {
547 name = (char *) symtab->link->data + sym->st_name;
548 sym_bind = ELFW(ST_BIND)(sym->st_info);
549 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
550 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
551 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
556 /* list elf symbol names and values */
557 LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
558 void (*symbol_cb)(void *ctx, const char *name, const void *val))
560 list_elf_symbols(s, ctx, symbol_cb);
563 #ifndef ELF_OBJ_ONLY
564 static void
565 version_add (TCCState *s1)
567 int i;
568 ElfW(Sym) *sym;
569 ElfW(Verneed) *vn = NULL;
570 Section *symtab;
571 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
572 ElfW(Half) *versym;
573 const char *name;
575 if (0 == nb_sym_versions)
576 return;
577 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
578 versym_section->sh_entsize = sizeof(ElfW(Half));
579 versym_section->link = s1->dynsym;
581 /* add needed symbols */
582 symtab = s1->dynsym;
583 end_sym = symtab->data_offset / sizeof (ElfSym);
584 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
585 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
586 int dllindex, verndx;
587 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
588 name = (char *) symtab->link->data + sym->st_name;
589 dllindex = find_elf_sym(s1->dynsymtab_section, name);
590 verndx = (dllindex && dllindex < nb_sym_to_version)
591 ? sym_to_version[dllindex] : -1;
592 if (verndx >= 0) {
593 if (!sym_versions[verndx].out_index)
594 sym_versions[verndx].out_index = nb_versions++;
595 versym[sym_index] = sym_versions[verndx].out_index;
596 } else
597 versym[sym_index] = 0;
599 /* generate verneed section, but not when it will be empty. Some
600 dynamic linkers look at their contents even when DTVERNEEDNUM and
601 section size is zero. */
602 if (nb_versions > 2) {
603 verneed_section = new_section(s1, ".gnu.version_r",
604 SHT_GNU_verneed, SHF_ALLOC);
605 verneed_section->link = s1->dynsym->link;
606 for (i = nb_sym_versions; i-- > 0;) {
607 struct sym_version *sv = &sym_versions[i];
608 int n_same_libs = 0, prev;
609 size_t vnofs;
610 ElfW(Vernaux) *vna = 0;
611 if (sv->out_index < 1)
612 continue;
613 vnofs = section_add(verneed_section, sizeof(*vn), 1);
614 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
615 vn->vn_version = 1;
616 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
617 vn->vn_aux = sizeof (*vn);
618 do {
619 prev = sv->prev_same_lib;
620 if (sv->out_index > 0) {
621 vna = section_ptr_add(verneed_section, sizeof(*vna));
622 vna->vna_hash = elf_hash ((const unsigned char *)sv->version);
623 vna->vna_flags = 0;
624 vna->vna_other = sv->out_index;
625 sv->out_index = -2;
626 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
627 vna->vna_next = sizeof (*vna);
628 n_same_libs++;
630 if (prev >= 0)
631 sv = &sym_versions[prev];
632 } while(prev >= 0);
633 vna->vna_next = 0;
634 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
635 vn->vn_cnt = n_same_libs;
636 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
637 nb_entries++;
639 if (vn)
640 vn->vn_next = 0;
641 verneed_section->sh_info = nb_entries;
643 dt_verneednum = nb_entries;
645 #endif
647 /* add an elf symbol : check if it is already defined and patch
648 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
649 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
650 int info, int other, int shndx, const char *name)
652 TCCState *s1 = s->s1;
653 ElfW(Sym) *esym;
654 int sym_bind, sym_index, sym_type, esym_bind;
655 unsigned char sym_vis, esym_vis, new_vis;
657 sym_bind = ELFW(ST_BIND)(info);
658 sym_type = ELFW(ST_TYPE)(info);
659 sym_vis = ELFW(ST_VISIBILITY)(other);
661 if (sym_bind != STB_LOCAL) {
662 /* we search global or weak symbols */
663 sym_index = find_elf_sym(s, name);
664 if (!sym_index)
665 goto do_def;
666 esym = &((ElfW(Sym) *)s->data)[sym_index];
667 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
668 && esym->st_other == other && esym->st_shndx == shndx)
669 return sym_index;
670 if (esym->st_shndx != SHN_UNDEF) {
671 esym_bind = ELFW(ST_BIND)(esym->st_info);
672 /* propagate the most constraining visibility */
673 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
674 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
675 if (esym_vis == STV_DEFAULT) {
676 new_vis = sym_vis;
677 } else if (sym_vis == STV_DEFAULT) {
678 new_vis = esym_vis;
679 } else {
680 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
682 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
683 | new_vis;
684 other = esym->st_other; /* in case we have to patch esym */
685 if (shndx == SHN_UNDEF) {
686 /* ignore adding of undefined symbol if the
687 corresponding symbol is already defined */
688 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
689 /* global overrides weak, so patch */
690 goto do_patch;
691 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
692 /* weak is ignored if already global */
693 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
694 /* keep first-found weak definition, ignore subsequents */
695 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
696 /* ignore hidden symbols after */
697 } else if ((esym->st_shndx == SHN_COMMON
698 || esym->st_shndx == bss_section->sh_num)
699 && (shndx < SHN_LORESERVE
700 && shndx != bss_section->sh_num)) {
701 /* data symbol gets precedence over common/bss */
702 goto do_patch;
703 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
704 /* data symbol keeps precedence over common/bss */
705 } else if (s->sh_flags & SHF_DYNSYM) {
706 /* we accept that two DLL define the same symbol */
707 } else if (esym->st_other & ST_ASM_SET) {
708 /* If the existing symbol came from an asm .set
709 we can override. */
710 goto do_patch;
711 } else {
712 #if 0
713 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
714 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
715 #endif
716 tcc_error_noabort("'%s' defined twice", name);
718 } else {
719 do_patch:
720 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
721 esym->st_shndx = shndx;
722 s1->new_undef_sym = 1;
723 esym->st_value = value;
724 esym->st_size = size;
725 esym->st_other = other;
727 } else {
728 do_def:
729 sym_index = put_elf_sym(s, value, size,
730 ELFW(ST_INFO)(sym_bind, sym_type), other,
731 shndx, name);
733 return sym_index;
736 /* put relocation */
737 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
738 int type, int symbol, addr_t addend)
740 TCCState *s1 = s->s1;
741 char buf[256];
742 Section *sr;
743 ElfW_Rel *rel;
745 sr = s->reloc;
746 if (!sr) {
747 /* if no relocation section, create it */
748 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
749 /* if the symtab is allocated, then we consider the relocation
750 are also */
751 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
752 sr->sh_entsize = sizeof(ElfW_Rel);
753 sr->link = symtab;
754 sr->sh_info = s->sh_num;
755 s->reloc = sr;
757 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
758 rel->r_offset = offset;
759 rel->r_info = ELFW(R_INFO)(symbol, type);
760 #if SHT_RELX == SHT_RELA
761 rel->r_addend = addend;
762 #endif
763 if (SHT_RELX != SHT_RELA && addend)
764 tcc_error("non-zero addend on REL architecture");
767 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
768 int type, int symbol)
770 put_elf_reloca(symtab, s, offset, type, symbol, 0);
773 /* put stab debug information */
774 ST_FUNC void put_stabs(TCCState *s1, const char *str, int type, int other, int desc,
775 unsigned long value)
777 Stab_Sym *sym;
779 unsigned offset;
780 if (type == N_SLINE
781 && (offset = stab_section->data_offset)
782 && (sym = (Stab_Sym*)(stab_section->data + offset) - 1)
783 && sym->n_type == type
784 && sym->n_value == value) {
785 /* just update line_number in previous entry */
786 sym->n_desc = desc;
787 return;
790 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
791 if (str) {
792 sym->n_strx = put_elf_str(stab_section->link, str);
793 } else {
794 sym->n_strx = 0;
796 sym->n_type = type;
797 sym->n_other = other;
798 sym->n_desc = desc;
799 sym->n_value = value;
802 ST_FUNC void put_stabs_r(TCCState *s1, const char *str, int type, int other, int desc,
803 unsigned long value, Section *sec, int sym_index)
805 put_elf_reloc(symtab_section, stab_section,
806 stab_section->data_offset + 8,
807 sizeof ((Stab_Sym*)0)->n_value == PTR_SIZE ? R_DATA_PTR : R_DATA_32,
808 sym_index);
809 put_stabs(s1, str, type, other, desc, value);
812 ST_FUNC void put_stabn(TCCState *s1, int type, int other, int desc, int value)
814 put_stabs(s1, NULL, type, other, desc, value);
817 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
819 int n;
820 struct sym_attr *tab;
822 if (index >= s1->nb_sym_attrs) {
823 if (!alloc)
824 return s1->sym_attrs;
825 /* find immediately bigger power of 2 and reallocate array */
826 n = 1;
827 while (index >= n)
828 n *= 2;
829 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
830 s1->sym_attrs = tab;
831 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
832 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
833 s1->nb_sym_attrs = n;
835 return &s1->sym_attrs[index];
838 /* In an ELF file symbol table, the local symbols must appear below
839 the global and weak ones. Since TCC cannot sort it while generating
840 the code, we must do it after. All the relocation tables are also
841 modified to take into account the symbol table sorting */
842 static void sort_syms(TCCState *s1, Section *s)
844 int *old_to_new_syms;
845 ElfW(Sym) *new_syms;
846 int nb_syms, i;
847 ElfW(Sym) *p, *q;
848 ElfW_Rel *rel;
849 Section *sr;
850 int type, sym_index;
852 nb_syms = s->data_offset / sizeof(ElfW(Sym));
853 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
854 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
856 /* first pass for local symbols */
857 p = (ElfW(Sym) *)s->data;
858 q = new_syms;
859 for(i = 0; i < nb_syms; i++) {
860 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
861 old_to_new_syms[i] = q - new_syms;
862 *q++ = *p;
864 p++;
866 /* save the number of local symbols in section header */
867 if( s->sh_size ) /* this 'if' makes IDA happy */
868 s->sh_info = q - new_syms;
870 /* then second pass for non local symbols */
871 p = (ElfW(Sym) *)s->data;
872 for(i = 0; i < nb_syms; i++) {
873 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
874 old_to_new_syms[i] = q - new_syms;
875 *q++ = *p;
877 p++;
880 /* we copy the new symbols to the old */
881 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
882 tcc_free(new_syms);
884 /* now we modify all the relocations */
885 for(i = 1; i < s1->nb_sections; i++) {
886 sr = s1->sections[i];
887 if (sr->sh_type == SHT_RELX && sr->link == s) {
888 for_each_elem(sr, 0, rel, ElfW_Rel) {
889 sym_index = ELFW(R_SYM)(rel->r_info);
890 type = ELFW(R_TYPE)(rel->r_info);
891 sym_index = old_to_new_syms[sym_index];
892 rel->r_info = ELFW(R_INFO)(sym_index, type);
897 tcc_free(old_to_new_syms);
900 /* relocate symbol table, resolve undefined symbols if do_resolve is
901 true and output error if undefined symbol. */
902 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
904 ElfW(Sym) *sym;
905 int sym_bind, sh_num;
906 const char *name;
908 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
909 sh_num = sym->st_shndx;
910 if (sh_num == SHN_UNDEF) {
911 name = (char *) s1->symtab->link->data + sym->st_name;
912 /* Use ld.so to resolve symbol for us (for tcc -run) */
913 if (do_resolve) {
914 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
915 /* dlsym() needs the undecorated name. */
916 void *addr = dlsym(RTLD_DEFAULT, &name[s1->leading_underscore]);
917 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
918 if (addr == NULL) {
919 int i;
920 for (i = 0; i < s1->nb_loaded_dlls; i++)
921 if ((addr = dlsym(s1->loaded_dlls[i]->handle, name)))
922 break;
924 #endif
925 if (addr) {
926 sym->st_value = (addr_t) addr;
927 #ifdef DEBUG_RELOC
928 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
929 #endif
930 goto found;
932 #endif
933 /* if dynamic symbol exist, it will be used in relocate_section */
934 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
935 goto found;
936 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
937 it */
938 if (!strcmp(name, "_fp_hw"))
939 goto found;
940 /* only weak symbols are accepted to be undefined. Their
941 value is zero */
942 sym_bind = ELFW(ST_BIND)(sym->st_info);
943 if (sym_bind == STB_WEAK)
944 sym->st_value = 0;
945 else
946 tcc_error_noabort("undefined symbol '%s'", name);
947 } else if (sh_num < SHN_LORESERVE) {
948 /* add section base */
949 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
951 found: ;
955 /* relocate a given section (CPU dependent) by applying the relocations
956 in the associated relocation section */
957 static void relocate_section(TCCState *s1, Section *s, Section *sr)
959 ElfW_Rel *rel;
960 ElfW(Sym) *sym;
961 int type, sym_index;
962 unsigned char *ptr;
963 addr_t tgt, addr;
965 qrel = (ElfW_Rel *)sr->data;
966 for_each_elem(sr, 0, rel, ElfW_Rel) {
967 ptr = s->data + rel->r_offset;
968 sym_index = ELFW(R_SYM)(rel->r_info);
969 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
970 type = ELFW(R_TYPE)(rel->r_info);
971 tgt = sym->st_value;
972 #if SHT_RELX == SHT_RELA
973 tgt += rel->r_addend;
974 #endif
975 addr = s->sh_addr + rel->r_offset;
976 relocate(s1, rel, type, ptr, addr, tgt);
978 #ifndef ELF_OBJ_ONLY
979 /* if the relocation is allocated, we change its symbol table */
980 if (sr->sh_flags & SHF_ALLOC) {
981 sr->link = s1->dynsym;
982 if (s1->output_type == TCC_OUTPUT_DLL) {
983 size_t r = (uint8_t*)qrel - sr->data;
984 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
985 && 0 == strcmp(s->name, ".stab"))
986 r = 0; /* cannot apply 64bit relocation to 32bit value */
987 sr->data_offset = sr->sh_size = r;
990 #endif
993 /* relocate all sections */
994 ST_FUNC void relocate_sections(TCCState *s1)
996 int i;
997 Section *s, *sr;
999 for (i = 1; i < s1->nb_sections; ++i) {
1000 sr = s1->sections[i];
1001 if (sr->sh_type != SHT_RELX)
1002 continue;
1003 s = s1->sections[sr->sh_info];
1004 #ifndef TCC_TARGET_MACHO
1005 if (s != s1->got
1006 || s1->static_link
1007 || s1->output_type == TCC_OUTPUT_MEMORY)
1008 #endif
1010 relocate_section(s1, s, sr);
1012 #ifndef ELF_OBJ_ONLY
1013 if (sr->sh_flags & SHF_ALLOC) {
1014 ElfW_Rel *rel;
1015 /* relocate relocation table in 'sr' */
1016 for_each_elem(sr, 0, rel, ElfW_Rel)
1017 rel->r_offset += s->sh_addr;
1019 #endif
1023 #ifndef ELF_OBJ_ONLY
1024 /* count the number of dynamic relocations so that we can reserve
1025 their space */
1026 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
1028 int count = 0;
1029 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1030 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1031 defined(TCC_TARGET_RISCV64)
1032 ElfW_Rel *rel;
1033 for_each_elem(sr, 0, rel, ElfW_Rel) {
1034 int sym_index = ELFW(R_SYM)(rel->r_info);
1035 int type = ELFW(R_TYPE)(rel->r_info);
1036 switch(type) {
1037 #if defined(TCC_TARGET_I386)
1038 case R_386_32:
1039 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
1040 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
1041 /* don't fixup unresolved (weak) symbols */
1042 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
1043 break;
1045 #elif defined(TCC_TARGET_X86_64)
1046 case R_X86_64_32:
1047 case R_X86_64_32S:
1048 case R_X86_64_64:
1049 #elif defined(TCC_TARGET_ARM)
1050 case R_ARM_ABS32:
1051 case R_ARM_TARGET1:
1052 #elif defined(TCC_TARGET_ARM64)
1053 case R_AARCH64_ABS32:
1054 case R_AARCH64_ABS64:
1055 #elif defined(TCC_TARGET_RISCV64)
1056 case R_RISCV_32:
1057 case R_RISCV_64:
1058 #endif
1059 count++;
1060 break;
1061 #if defined(TCC_TARGET_I386)
1062 case R_386_PC32:
1063 #elif defined(TCC_TARGET_X86_64)
1064 case R_X86_64_PC32:
1066 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1068 /* Hidden defined symbols can and must be resolved locally.
1069 We're misusing a PLT32 reloc for this, as that's always
1070 resolved to its address even in shared libs. */
1071 if (sym->st_shndx != SHN_UNDEF &&
1072 ELFW(ST_VISIBILITY)(sym->st_other) == STV_HIDDEN) {
1073 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PLT32);
1074 break;
1077 #elif defined(TCC_TARGET_ARM64)
1078 case R_AARCH64_PREL32:
1079 #endif
1080 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1081 count++;
1082 break;
1083 default:
1084 break;
1087 #endif
1088 return count;
1090 #endif
1092 #if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE)
1093 static void build_got(TCCState *s1)
1095 /* if no got, then create it */
1096 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1097 s1->got->sh_entsize = 4;
1098 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1099 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1100 /* keep space for _DYNAMIC pointer and two dummy got entries */
1101 section_ptr_add(s1->got, 3 * PTR_SIZE);
1104 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1105 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1106 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1107 Returns the offset of the GOT or (if any) PLT entry. */
1108 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1109 int sym_index)
1111 int need_plt_entry;
1112 const char *name;
1113 ElfW(Sym) *sym;
1114 struct sym_attr *attr;
1115 unsigned got_offset;
1116 char plt_name[100];
1117 int len;
1118 Section *s_rel;
1120 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1121 attr = get_sym_attr(s1, sym_index, 1);
1123 /* In case a function is both called and its address taken 2 GOT entries
1124 are created, one for taking the address (GOT) and the other for the PLT
1125 entry (PLTGOT). */
1126 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1127 return attr;
1129 s_rel = s1->got;
1130 if (need_plt_entry) {
1131 if (!s1->plt) {
1132 s1->plt = new_section(s1, ".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
1133 s1->plt->sh_entsize = 4;
1135 s_rel = s1->plt;
1138 /* create the GOT entry */
1139 got_offset = s1->got->data_offset;
1140 section_ptr_add(s1->got, PTR_SIZE);
1142 /* Create the GOT relocation that will insert the address of the object or
1143 function of interest in the GOT entry. This is a static relocation for
1144 memory output (dlsym will give us the address of symbols) and dynamic
1145 relocation otherwise (executable and DLLs). The relocation should be
1146 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1147 associated to a PLT entry) but is currently done at load time for an
1148 unknown reason. */
1150 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1151 name = (char *) symtab_section->link->data + sym->st_name;
1152 //printf("sym %d %s\n", need_plt_entry, name);
1154 if (s1->dynsym) {
1155 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1156 /* Hack alarm. We don't want to emit dynamic symbols
1157 and symbol based relocs for STB_LOCAL symbols, but rather
1158 want to resolve them directly. At this point the symbol
1159 values aren't final yet, so we must defer this. We will later
1160 have to create a RELATIVE reloc anyway, so we misuse the
1161 relocation slot to smuggle the symbol reference until
1162 fill_local_got_entries. Not that the sym_index is
1163 relative to symtab_section, not s1->dynsym! Nevertheless
1164 we use s1->dyn_sym so that if this is the first call
1165 that got->reloc is correctly created. Also note that
1166 RELATIVE relocs are not normally created for the .got,
1167 so the types serves as a marker for later (and is retained
1168 also for the final output, which is okay because then the
1169 got is just normal data). */
1170 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1171 sym_index);
1172 } else {
1173 if (0 == attr->dyn_index)
1174 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1175 sym->st_size, sym->st_info, 0,
1176 sym->st_shndx, name);
1177 put_elf_reloc(s1->dynsym, s_rel, got_offset, dyn_reloc_type,
1178 attr->dyn_index);
1180 } else {
1181 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1182 sym_index);
1185 if (need_plt_entry) {
1186 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1188 /* create a symbol 'sym@plt' for the PLT jump vector */
1189 len = strlen(name);
1190 if (len > sizeof plt_name - 5)
1191 len = sizeof plt_name - 5;
1192 memcpy(plt_name, name, len);
1193 strcpy(plt_name + len, "@plt");
1194 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
1195 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1196 } else {
1197 attr->got_offset = got_offset;
1200 return attr;
1203 /* build GOT and PLT entries */
1204 /* Two passes because R_JMP_SLOT should become first. Some targets
1205 (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1206 ST_FUNC void build_got_entries(TCCState *s1)
1208 Section *s;
1209 ElfW_Rel *rel;
1210 ElfW(Sym) *sym;
1211 int i, type, gotplt_entry, reloc_type, sym_index;
1212 struct sym_attr *attr;
1213 int pass = 0;
1215 redo:
1216 for(i = 1; i < s1->nb_sections; i++) {
1217 s = s1->sections[i];
1218 if (s->sh_type != SHT_RELX)
1219 continue;
1220 /* no need to handle got relocations */
1221 if (s->link != symtab_section)
1222 continue;
1223 for_each_elem(s, 0, rel, ElfW_Rel) {
1224 type = ELFW(R_TYPE)(rel->r_info);
1225 gotplt_entry = gotplt_entry_type(type);
1226 if (gotplt_entry == -1)
1227 tcc_error ("Unknown relocation type for got: %d", type);
1228 sym_index = ELFW(R_SYM)(rel->r_info);
1229 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1231 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1232 continue;
1235 /* Automatically create PLT/GOT [entry] if it is an undefined
1236 reference (resolved at runtime), or the symbol is absolute,
1237 probably created by tcc_add_symbol, and thus on 64-bit
1238 targets might be too far from application code. */
1239 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1240 if (sym->st_shndx == SHN_UNDEF) {
1241 ElfW(Sym) *esym;
1242 int dynindex;
1243 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1244 continue;
1245 /* Relocations for UNDEF symbols would normally need
1246 to be transferred into the executable or shared object.
1247 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1248 But TCC doesn't do that (at least for exes), so we
1249 need to resolve all such relocs locally. And that
1250 means PLT slots for functions in DLLs and COPY relocs for
1251 data symbols. COPY relocs were generated in
1252 bind_exe_dynsyms (and the symbol adjusted to be defined),
1253 and for functions we were generated a dynamic symbol
1254 of function type. */
1255 if (s1->dynsym) {
1256 /* dynsym isn't set for -run :-/ */
1257 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1258 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1259 if (dynindex
1260 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1261 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1262 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1263 goto jmp_slot;
1265 } else if (sym->st_shndx == SHN_ABS) {
1266 if (sym->st_value == 0) /* from tcc_add_btstub() */
1267 continue;
1268 #ifndef TCC_TARGET_ARM
1269 if (PTR_SIZE != 8)
1270 continue;
1271 #endif
1272 /* from tcc_add_symbol(): on 64 bit platforms these
1273 need to go through .got */
1274 } else
1275 continue;
1278 #ifdef TCC_TARGET_X86_64
1279 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1280 sym->st_shndx != SHN_UNDEF &&
1281 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1282 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1283 s1->output_type == TCC_OUTPUT_EXE)) {
1284 if (pass != 0)
1285 continue;
1286 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1287 continue;
1289 #endif
1290 reloc_type = code_reloc(type);
1291 if (reloc_type == -1)
1292 tcc_error ("Unknown relocation type: %d", type);
1294 if (reloc_type != 0) {
1295 jmp_slot:
1296 if (pass != 0)
1297 continue;
1298 reloc_type = R_JMP_SLOT;
1299 } else {
1300 if (pass != 1)
1301 continue;
1302 reloc_type = R_GLOB_DAT;
1305 if (!s1->got)
1306 build_got(s1);
1308 if (gotplt_entry == BUILD_GOT_ONLY)
1309 continue;
1311 attr = put_got_entry(s1, reloc_type, sym_index);
1313 if (reloc_type == R_JMP_SLOT)
1314 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1317 if (++pass < 2)
1318 goto redo;
1320 /* .rel.plt refers to .got actually */
1321 if (s1->plt && s1->plt->reloc)
1322 s1->plt->reloc->sh_info = s1->got->sh_num;
1325 #endif
1327 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
1329 int shn = sec ? sec->sh_num : offs || !name ? SHN_ABS : SHN_UNDEF;
1330 if (sec && offs == -1)
1331 offs = sec->data_offset;
1332 return set_elf_sym(symtab_section, offs, 0,
1333 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1336 static void add_init_array_defines(TCCState *s1, const char *section_name)
1338 Section *s;
1339 addr_t end_offset;
1340 char buf[1024];
1341 s = find_section_create(s1, section_name, 0);
1342 if (!s) {
1343 end_offset = 0;
1344 s = data_section;
1345 } else {
1346 end_offset = s->data_offset;
1348 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1349 set_global_sym(s1, buf, s, 0);
1350 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1351 set_global_sym(s1, buf, s, end_offset);
1354 #ifndef TCC_TARGET_PE
1355 static void tcc_add_support(TCCState *s1, const char *filename)
1357 char buf[1024];
1358 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1359 tcc_add_file(s1, buf);
1361 #endif
1363 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1365 Section *s;
1366 s = find_section(s1, sec);
1367 s->sh_flags |= SHF_WRITE;
1368 #ifndef TCC_TARGET_PE
1369 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1370 #endif
1371 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1372 section_ptr_add(s, PTR_SIZE);
1375 #ifdef CONFIG_TCC_BCHECK
1376 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1378 if (0 == s1->do_bounds_check)
1379 return;
1380 section_ptr_add(bounds_section, sizeof(addr_t));
1382 #endif
1384 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1385 a dynamic symbol to allow so's to have one each with a different value. */
1386 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1388 int c = find_elf_sym(s1->symtab, name);
1389 if (c) {
1390 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1391 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1392 esym->st_value = offset;
1393 esym->st_shndx = s->sh_num;
1397 #ifdef CONFIG_TCC_BACKTRACE
1398 static void put_ptr(TCCState *s1, Section *s, int offs)
1400 int c;
1401 c = set_global_sym(s1, NULL, s, offs);
1402 s = data_section;
1403 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1404 section_ptr_add(s, PTR_SIZE);
1407 ST_FUNC void tcc_add_btstub(TCCState *s1)
1409 Section *s;
1410 int n, o;
1411 CString cstr;
1413 s = data_section;
1414 /* Align to PTR_SIZE */
1415 section_ptr_add(s, -s->data_offset & (PTR_SIZE - 1));
1416 o = s->data_offset;
1417 /* create (part of) a struct rt_context (see tccrun.c) */
1418 put_ptr(s1, stab_section, 0);
1419 put_ptr(s1, stab_section, -1);
1420 put_ptr(s1, stab_section->link, 0);
1421 section_ptr_add(s, 3 * PTR_SIZE);
1422 /* prog_base : local nameless symbol with offset 0 at SHN_ABS */
1423 put_ptr(s1, NULL, 0);
1424 n = 2 * PTR_SIZE;
1425 #ifdef CONFIG_TCC_BCHECK
1426 if (s1->do_bounds_check) {
1427 put_ptr(s1, bounds_section, 0);
1428 n -= PTR_SIZE;
1430 #endif
1431 section_ptr_add(s, n);
1432 cstr_new(&cstr);
1433 cstr_printf(&cstr,
1434 "extern void __bt_init(),__bt_init_dll();"
1435 "static void *__rt_info[];"
1436 "__attribute__((constructor)) static void __bt_init_rt(){");
1437 #ifdef TCC_TARGET_PE
1438 if (s1->output_type == TCC_OUTPUT_DLL)
1439 #ifdef CONFIG_TCC_BCHECK
1440 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1441 #else
1442 cstr_printf(&cstr, "__bt_init_dll(0);");
1443 #endif
1444 #endif
1445 cstr_printf(&cstr, "__bt_init(__rt_info,%d);}",
1446 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1447 tcc_compile_string(s1, cstr.data);
1448 cstr_free(&cstr);
1449 set_local_sym(s1, &"___rt_info"[!s1->leading_underscore], s, o);
1451 #endif
1453 static void tcc_tcov_add_file(TCCState *s1, const char *filename)
1455 CString cstr;
1456 void *ptr;
1457 char wd[1024];
1459 if (tcov_section == NULL)
1460 return;
1461 section_ptr_add(tcov_section, 1);
1462 write32le (tcov_section->data, tcov_section->data_offset);
1464 cstr_new (&cstr);
1465 if (filename[0] == '/')
1466 cstr_printf (&cstr, "%s.tcov", filename);
1467 else {
1468 getcwd (wd, sizeof(wd));
1469 cstr_printf (&cstr, "%s/%s.tcov", wd, filename);
1471 ptr = section_ptr_add(tcov_section, cstr.size + 1);
1472 strcpy((char *)ptr, cstr.data);
1473 unlink((char *)ptr);
1474 #ifdef _WIN32
1475 normalize_slashes((char *)ptr);
1476 #endif
1477 cstr_free (&cstr);
1479 cstr_new(&cstr);
1480 cstr_printf(&cstr,
1481 "extern char *__tcov_data[];"
1482 "extern void __store_test_coverage ();"
1483 "__attribute__((destructor)) static void __tcov_exit() {"
1484 "__store_test_coverage(__tcov_data);"
1485 "}");
1486 tcc_compile_string(s1, cstr.data);
1487 cstr_free(&cstr);
1488 set_local_sym(s1, &"___tcov_data"[!s1->leading_underscore], tcov_section, 0);
1491 #ifndef TCC_TARGET_PE
1492 /* add tcc runtime libraries */
1493 ST_FUNC void tcc_add_runtime(TCCState *s1)
1495 s1->filetype = 0;
1496 #ifdef CONFIG_TCC_BCHECK
1497 tcc_add_bcheck(s1);
1498 #endif
1499 tcc_add_pragma_libs(s1);
1500 /* add libc */
1501 if (!s1->nostdlib) {
1502 if (s1->option_pthread)
1503 tcc_add_library_err(s1, "pthread");
1504 tcc_add_library_err(s1, "c");
1505 #ifdef TCC_LIBGCC
1506 if (!s1->static_link) {
1507 if (TCC_LIBGCC[0] == '/')
1508 tcc_add_file(s1, TCC_LIBGCC);
1509 else
1510 tcc_add_dll(s1, TCC_LIBGCC, 0);
1512 #endif
1513 #if TCC_TARGET_ARM && TARGETOS_FreeBSD
1514 tcc_add_library_err(s1, "gcc_s"); // unwind code
1515 #endif
1516 #ifdef CONFIG_TCC_BCHECK
1517 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1518 tcc_add_library_err(s1, "pthread");
1519 #if !TARGETOS_OpenBSD && !TARGETOS_NetBSD
1520 tcc_add_library_err(s1, "dl");
1521 #endif
1522 tcc_add_support(s1, "bcheck.o");
1523 if (s1->static_link)
1524 tcc_add_library_err(s1, "c");
1526 #endif
1527 #ifdef CONFIG_TCC_BACKTRACE
1528 if (s1->do_backtrace) {
1529 if (s1->output_type == TCC_OUTPUT_EXE)
1530 tcc_add_support(s1, "bt-exe.o");
1531 if (s1->output_type != TCC_OUTPUT_DLL)
1532 tcc_add_support(s1, "bt-log.o");
1533 if (s1->output_type != TCC_OUTPUT_MEMORY)
1534 tcc_add_btstub(s1);
1536 #endif
1537 if (TCC_LIBTCC1[0])
1538 tcc_add_support(s1, TCC_LIBTCC1);
1540 #if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO
1541 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
1542 /* add crt end if not memory output */
1543 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1544 if (s1->output_type == TCC_OUTPUT_DLL)
1545 tcc_add_crt(s1, "crtendS.o");
1546 else
1547 tcc_add_crt(s1, "crtend.o");
1548 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
1549 tcc_add_crt(s1, "crtn.o");
1550 #endif
1552 #elif !defined(TCC_TARGET_MACHO)
1553 /* add crt end if not memory output */
1554 if (s1->output_type != TCC_OUTPUT_MEMORY)
1555 tcc_add_crt(s1, "crtn.o");
1556 #endif
1557 #endif
1560 #endif
1562 /* add various standard linker symbols (must be done after the
1563 sections are filled (for example after allocating common
1564 symbols)) */
1565 static void tcc_add_linker_symbols(TCCState *s1)
1567 char buf[1024];
1568 int i;
1569 Section *s;
1571 set_global_sym(s1, "_etext", text_section, -1);
1572 set_global_sym(s1, "_edata", data_section, -1);
1573 set_global_sym(s1, "_end", bss_section, -1);
1574 #if TARGETOS_OpenBSD
1575 set_global_sym(s1, "__executable_start", NULL, ELF_START_ADDR);
1576 #endif
1577 #ifdef TCC_TARGET_RISCV64
1578 /* XXX should be .sdata+0x800, not .data+0x800 */
1579 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1580 #endif
1581 /* horrible new standard ldscript defines */
1582 #ifndef TCC_TARGET_PE
1583 add_init_array_defines(s1, ".preinit_array");
1584 #endif
1585 add_init_array_defines(s1, ".init_array");
1586 add_init_array_defines(s1, ".fini_array");
1587 /* add start and stop symbols for sections whose name can be
1588 expressed in C */
1589 for(i = 1; i < s1->nb_sections; i++) {
1590 s = s1->sections[i];
1591 if ((s->sh_flags & SHF_ALLOC)
1592 && (s->sh_type == SHT_PROGBITS
1593 || s->sh_type == SHT_STRTAB)) {
1594 const char *p;
1595 /* check if section name can be expressed in C */
1596 p = s->name;
1597 for(;;) {
1598 int c = *p;
1599 if (!c)
1600 break;
1601 if (!isid(c) && !isnum(c))
1602 goto next_sec;
1603 p++;
1605 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1606 set_global_sym(s1, buf, s, 0);
1607 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1608 set_global_sym(s1, buf, s, -1);
1610 next_sec: ;
1614 ST_FUNC void resolve_common_syms(TCCState *s1)
1616 ElfW(Sym) *sym;
1618 /* Allocate common symbols in BSS. */
1619 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1620 if (sym->st_shndx == SHN_COMMON) {
1621 /* symbol alignment is in st_value for SHN_COMMONs */
1622 sym->st_value = section_add(bss_section, sym->st_size,
1623 sym->st_value);
1624 sym->st_shndx = bss_section->sh_num;
1628 /* Now assign linker provided symbols their value. */
1629 tcc_add_linker_symbols(s1);
1632 #ifndef ELF_OBJ_ONLY
1634 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1636 int sym_index = ELFW(R_SYM) (rel->r_info);
1637 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1638 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1639 unsigned offset = attr->got_offset;
1641 if (0 == offset)
1642 return;
1643 section_reserve(s1->got, offset + PTR_SIZE);
1644 #if PTR_SIZE == 8
1645 write64le(s1->got->data + offset, sym->st_value);
1646 #else
1647 write32le(s1->got->data + offset, sym->st_value);
1648 #endif
1651 /* Perform relocation to GOT or PLT entries */
1652 ST_FUNC void fill_got(TCCState *s1)
1654 Section *s;
1655 ElfW_Rel *rel;
1656 int i;
1658 for(i = 1; i < s1->nb_sections; i++) {
1659 s = s1->sections[i];
1660 if (s->sh_type != SHT_RELX)
1661 continue;
1662 /* no need to handle got relocations */
1663 if (s->link != symtab_section)
1664 continue;
1665 for_each_elem(s, 0, rel, ElfW_Rel) {
1666 switch (ELFW(R_TYPE) (rel->r_info)) {
1667 case R_X86_64_GOT32:
1668 case R_X86_64_GOTPCREL:
1669 case R_X86_64_GOTPCRELX:
1670 case R_X86_64_REX_GOTPCRELX:
1671 case R_X86_64_PLT32:
1672 fill_got_entry(s1, rel);
1673 break;
1679 /* See put_got_entry for a description. This is the second stage
1680 where GOT references to local defined symbols are rewritten. */
1681 static void fill_local_got_entries(TCCState *s1)
1683 ElfW_Rel *rel;
1684 if (!s1->got->reloc)
1685 return;
1686 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1687 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1688 int sym_index = ELFW(R_SYM) (rel->r_info);
1689 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1690 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1691 unsigned offset = attr->got_offset;
1692 if (offset != rel->r_offset - s1->got->sh_addr)
1693 tcc_error_noabort("huh");
1694 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1695 #if SHT_RELX == SHT_RELA
1696 rel->r_addend = sym->st_value;
1697 #else
1698 /* All our REL architectures also happen to be 32bit LE. */
1699 write32le(s1->got->data + offset, sym->st_value);
1700 #endif
1705 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1706 in shared libraries and export non local defined symbols to shared libraries
1707 if -rdynamic switch was given on command line */
1708 static void bind_exe_dynsyms(TCCState *s1)
1710 const char *name;
1711 int sym_index, index;
1712 ElfW(Sym) *sym, *esym;
1713 int type;
1715 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1716 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1717 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1718 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1719 if (sym->st_shndx == SHN_UNDEF) {
1720 name = (char *) symtab_section->link->data + sym->st_name;
1721 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1722 if (sym_index) {
1723 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1724 type = ELFW(ST_TYPE)(esym->st_info);
1725 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1726 /* Indirect functions shall have STT_FUNC type in executable
1727 * dynsym section. Indeed, a dlsym call following a lazy
1728 * resolution would pick the symbol value from the
1729 * executable dynsym entry which would contain the address
1730 * of the function wanted by the caller of dlsym instead of
1731 * the address of the function that would return that
1732 * address */
1733 int dynindex
1734 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1735 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1736 name);
1737 int index = sym - (ElfW(Sym) *) symtab_section->data;
1738 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1739 } else if (type == STT_OBJECT) {
1740 unsigned long offset;
1741 ElfW(Sym) *dynsym;
1742 offset = bss_section->data_offset;
1743 /* XXX: which alignment ? */
1744 offset = (offset + 16 - 1) & -16;
1745 set_elf_sym (s1->symtab, offset, esym->st_size,
1746 esym->st_info, 0, bss_section->sh_num, name);
1747 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1748 esym->st_info, 0, bss_section->sh_num,
1749 name);
1751 /* Ensure R_COPY works for weak symbol aliases */
1752 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1753 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1754 if ((dynsym->st_value == esym->st_value)
1755 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1756 char *dynname = (char *) s1->dynsymtab_section->link->data
1757 + dynsym->st_name;
1758 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1759 dynsym->st_info, 0,
1760 bss_section->sh_num, dynname);
1761 break;
1766 put_elf_reloc(s1->dynsym, bss_section,
1767 offset, R_COPY, index);
1768 offset += esym->st_size;
1769 bss_section->data_offset = offset;
1771 } else {
1772 /* STB_WEAK undefined symbols are accepted */
1773 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1774 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1775 !strcmp(name, "_fp_hw")) {
1776 } else {
1777 tcc_error_noabort("undefined symbol '%s'", name);
1780 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1781 /* if -rdynamic option, then export all non local symbols */
1782 name = (char *) symtab_section->link->data + sym->st_name;
1783 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1784 0, sym->st_shndx, name);
1789 /* Bind symbols of libraries: export all non local symbols of executable that
1790 are referenced by shared libraries. The reason is that the dynamic loader
1791 search symbol first in executable and then in libraries. Therefore a
1792 reference to a symbol already defined by a library can still be resolved by
1793 a symbol in the executable. */
1794 static void bind_libs_dynsyms(TCCState *s1)
1796 const char *name;
1797 int sym_index;
1798 ElfW(Sym) *sym, *esym;
1800 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1801 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1802 sym_index = find_elf_sym(symtab_section, name);
1803 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1804 if (sym_index && sym->st_shndx != SHN_UNDEF
1805 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1806 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1807 sym->st_info, 0, sym->st_shndx, name);
1808 } else if (esym->st_shndx == SHN_UNDEF) {
1809 /* weak symbols can stay undefined */
1810 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1811 tcc_warning("undefined dynamic symbol '%s'", name);
1816 /* Export all non local symbols. This is used by shared libraries so that the
1817 non local symbols they define can resolve a reference in another shared
1818 library or in the executable. Correspondingly, it allows undefined local
1819 symbols to be resolved by other shared libraries or by the executable. */
1820 static void export_global_syms(TCCState *s1)
1822 int dynindex, index;
1823 const char *name;
1824 ElfW(Sym) *sym;
1826 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1827 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1828 name = (char *) symtab_section->link->data + sym->st_name;
1829 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1830 sym->st_info, 0, sym->st_shndx, name);
1831 index = sym - (ElfW(Sym) *) symtab_section->data;
1832 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1837 /* decide if an unallocated section should be output. */
1838 static int set_sec_sizes(TCCState *s1)
1840 int i;
1841 Section *s;
1842 int textrel = 0;
1843 int file_type = s1->output_type;
1845 /* Allocate strings for section names */
1846 for(i = 1; i < s1->nb_sections; i++) {
1847 s = s1->sections[i];
1848 if (s->sh_type == SHT_RELX && !(s->sh_flags & SHF_ALLOC)) {
1849 /* when generating a DLL, we include relocations but
1850 we may patch them */
1851 if (file_type == TCC_OUTPUT_DLL
1852 && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) {
1853 int count = prepare_dynamic_rel(s1, s);
1854 if (count) {
1855 /* allocate the section */
1856 s->sh_flags |= SHF_ALLOC;
1857 s->sh_size = count * sizeof(ElfW_Rel);
1858 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1859 textrel = 1;
1862 } else if ((s->sh_flags & SHF_ALLOC)
1863 #ifdef TCC_TARGET_ARM
1864 || s->sh_type == SHT_ARM_ATTRIBUTES
1865 #endif
1866 || s1->do_debug) {
1867 s->sh_size = s->data_offset;
1870 #ifdef TCC_TARGET_ARM
1871 /* XXX: Suppress stack unwinding section. */
1872 if (s->sh_type == SHT_ARM_EXIDX) {
1873 s->sh_flags = 0;
1874 s->sh_size = 0;
1876 #endif
1879 return textrel;
1883 /* Info to be copied in dynamic section */
1884 struct dyn_inf {
1885 Section *dynamic;
1886 Section *dynstr;
1887 unsigned long data_offset;
1888 addr_t rel_addr;
1889 addr_t rel_size;
1892 /* Info for GNU_RELRO */
1893 struct ro_inf {
1894 addr_t sh_offset;
1895 addr_t sh_addr;
1896 addr_t sh_size;
1899 static void alloc_sec_names(
1900 TCCState *s1, int is_obj
1903 static int layout_any_sections(
1904 TCCState *s1, int file_offset, int *sec_order, int is_obj
1907 /* Assign sections to segments and decide how are sections laid out when loaded
1908 in memory. This function also fills corresponding program headers. */
1909 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr,
1910 int phnum, int phfill,
1911 Section *interp,
1912 struct ro_inf *roinf, int *sec_order)
1914 int i, file_offset;
1915 Section *s;
1917 file_offset = 0;
1918 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1919 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1922 unsigned long s_align;
1923 long long tmp;
1924 addr_t addr;
1925 ElfW(Phdr) *ph;
1926 int j, k, f, file_type = s1->output_type;
1928 s_align = ELF_PAGE_SIZE;
1929 if (s1->section_align)
1930 s_align = s1->section_align;
1932 if (s1->has_text_addr) {
1933 int a_offset, p_offset;
1934 addr = s1->text_addr;
1935 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1936 ELF_PAGE_SIZE */
1937 a_offset = (int) (addr & (s_align - 1));
1938 p_offset = file_offset & (s_align - 1);
1939 if (a_offset < p_offset)
1940 a_offset += s_align;
1941 file_offset += (a_offset - p_offset);
1942 } else {
1943 if (file_type == TCC_OUTPUT_DLL)
1944 addr = 0;
1945 else
1946 addr = ELF_START_ADDR;
1947 /* compute address after headers */
1948 addr += (file_offset & (s_align - 1));
1951 ph = &phdr[0];
1952 /* Leave one program headers for the program interpreter and one for
1953 the program header table itself if needed. These are done later as
1954 they require section layout to be done first. */
1955 if (interp)
1956 ph += 2;
1958 /* read only segment mapping for GNU_RELRO */
1959 roinf->sh_offset = roinf->sh_addr = roinf->sh_size = 0;
1961 for(j = 0; j < phfill; j++) {
1962 ph->p_type = j == 2 ? PT_TLS : PT_LOAD;
1963 if (j == 0)
1964 ph->p_flags = PF_R | PF_X;
1965 else
1966 ph->p_flags = PF_R | PF_W;
1967 ph->p_align = j == 2 ? 4 : s_align;
1969 /* Decide the layout of sections loaded in memory. This must
1970 be done before program headers are filled since they contain
1971 info about the layout. We do the following ordering: interp,
1972 symbol tables, relocations, progbits, nobits */
1973 /* XXX: do faster and simpler sorting */
1974 f = -1;
1975 for(k = 0; k < 7; k++) {
1976 for(i = 1; i < s1->nb_sections; i++) {
1977 s = s1->sections[i];
1978 /* compute if section should be included */
1979 if (j == 0) {
1980 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1981 SHF_ALLOC)
1982 continue;
1983 } else if (j == 1) {
1984 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1985 (SHF_ALLOC | SHF_WRITE))
1986 continue;
1987 } else {
1988 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1989 (SHF_ALLOC | SHF_WRITE | SHF_TLS))
1990 continue;
1992 if (s == interp) {
1993 if (k != 0)
1994 continue;
1995 } else if ((s->sh_type == SHT_DYNSYM ||
1996 s->sh_type == SHT_STRTAB ||
1997 s->sh_type == SHT_HASH)
1998 && !strstr(s->name, ".stab")) {
1999 if (k != 1)
2000 continue;
2001 } else if (s->sh_type == SHT_RELX) {
2002 if (s1->plt && s == s1->plt->reloc) {
2003 if (k != 3)
2004 continue;
2005 } else {
2006 if (k != 2)
2007 continue;
2009 } else if (s->sh_type == SHT_NOBITS) {
2010 if (k != 6)
2011 continue;
2012 } else if ((s == rodata_section
2013 #ifdef CONFIG_TCC_BCHECK
2014 || s == bounds_section
2015 || s == lbounds_section
2016 #endif
2017 ) && (s->sh_flags & SHF_WRITE)) {
2018 if (k != 4)
2019 continue;
2020 /* Align next section on page size.
2021 This is needed to remap roinf section ro. */
2022 f = 1;
2023 } else {
2024 if (k != 5)
2025 continue;
2027 *sec_order++ = i;
2029 /* section matches: we align it and add its size */
2030 tmp = addr;
2031 if (f-- == 0)
2032 s->sh_addralign = PAGESIZE;
2033 addr = (addr + s->sh_addralign - 1) &
2034 ~(s->sh_addralign - 1);
2035 file_offset += (int) ( addr - tmp );
2036 s->sh_offset = file_offset;
2037 s->sh_addr = addr;
2039 /* update program header infos */
2040 if (ph->p_offset == 0) {
2041 ph->p_offset = file_offset;
2042 ph->p_vaddr = addr;
2043 ph->p_paddr = ph->p_vaddr;
2046 if (k == 4) {
2047 if (roinf->sh_size == 0) {
2048 roinf->sh_offset = s->sh_offset;
2049 roinf->sh_addr = s->sh_addr;
2051 roinf->sh_size = (addr - roinf->sh_addr) + s->sh_size;
2054 addr += s->sh_size;
2055 if (s->sh_type != SHT_NOBITS)
2056 file_offset += s->sh_size;
2059 if (j == 0) {
2060 /* Make the first PT_LOAD segment include the program
2061 headers itself (and the ELF header as well), it'll
2062 come out with same memory use but will make various
2063 tools like binutils strip work better. */
2064 ph->p_offset &= ~(ph->p_align - 1);
2065 ph->p_vaddr &= ~(ph->p_align - 1);
2066 ph->p_paddr &= ~(ph->p_align - 1);
2068 ph->p_filesz = file_offset - ph->p_offset;
2069 ph->p_memsz = addr - ph->p_vaddr;
2070 ph++;
2071 if (j == 0) {
2072 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
2073 /* if in the middle of a page, we duplicate the page in
2074 memory so that one copy is RX and the other is RW */
2075 if ((addr & (s_align - 1)) != 0)
2076 addr += s_align;
2077 } else {
2078 addr = (addr + s_align - 1) & ~(s_align - 1);
2079 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
2085 /* all other sections come after */
2086 return layout_any_sections(s1, file_offset, sec_order, 0);
2089 /* put dynamic tag */
2090 static void put_dt(Section *dynamic, int dt, addr_t val)
2092 ElfW(Dyn) *dyn;
2093 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
2094 dyn->d_tag = dt;
2095 dyn->d_un.d_val = val;
2098 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
2099 Section *dynamic, Section *note, struct ro_inf *roinf)
2101 ElfW(Phdr) *ph;
2103 /* if interpreter, then add corresponding program header */
2104 if (interp) {
2105 ph = &phdr[0];
2107 ph->p_type = PT_PHDR;
2108 ph->p_offset = sizeof(ElfW(Ehdr));
2109 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
2110 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
2111 ph->p_paddr = ph->p_vaddr;
2112 ph->p_flags = PF_R | PF_X;
2113 ph->p_align = 4; /* interp->sh_addralign; */
2114 ph++;
2116 ph->p_type = PT_INTERP;
2117 ph->p_offset = interp->sh_offset;
2118 ph->p_vaddr = interp->sh_addr;
2119 ph->p_paddr = ph->p_vaddr;
2120 ph->p_filesz = interp->sh_size;
2121 ph->p_memsz = interp->sh_size;
2122 ph->p_flags = PF_R;
2123 ph->p_align = interp->sh_addralign;
2126 if (note) {
2127 ph = &phdr[phnum - 2 - (roinf != NULL)];
2129 ph->p_type = PT_NOTE;
2130 ph->p_offset = note->sh_offset;
2131 ph->p_vaddr = note->sh_addr;
2132 ph->p_paddr = ph->p_vaddr;
2133 ph->p_filesz = note->sh_size;
2134 ph->p_memsz = note->sh_size;
2135 ph->p_flags = PF_R;
2136 ph->p_align = note->sh_addralign;
2139 /* if dynamic section, then add corresponding program header */
2140 if (dynamic) {
2141 ph = &phdr[phnum - 1 - (roinf != NULL)];
2143 ph->p_type = PT_DYNAMIC;
2144 ph->p_offset = dynamic->sh_offset;
2145 ph->p_vaddr = dynamic->sh_addr;
2146 ph->p_paddr = ph->p_vaddr;
2147 ph->p_filesz = dynamic->sh_size;
2148 ph->p_memsz = dynamic->sh_size;
2149 ph->p_flags = PF_R | PF_W;
2150 ph->p_align = dynamic->sh_addralign;
2153 if (roinf) {
2154 ph = &phdr[phnum - 1];
2156 ph->p_type = PT_GNU_RELRO;
2157 ph->p_offset = roinf->sh_offset;
2158 ph->p_vaddr = roinf->sh_addr;
2159 ph->p_paddr = ph->p_vaddr;
2160 ph->p_filesz = roinf->sh_size;
2161 ph->p_memsz = roinf->sh_size;
2162 ph->p_flags = PF_R;
2163 ph->p_align = 1;
2167 /* Fill the dynamic section with tags describing the address and size of
2168 sections */
2169 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2171 Section *dynamic = dyninf->dynamic;
2172 Section *s;
2174 /* put dynamic section entries */
2175 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2176 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2177 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2178 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2179 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2180 #if PTR_SIZE == 8
2181 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2182 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2183 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2184 if (s1->plt && s1->plt->reloc) {
2185 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2186 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2187 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2188 put_dt(dynamic, DT_PLTREL, DT_RELA);
2190 put_dt(dynamic, DT_RELACOUNT, 0);
2191 #else
2192 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2193 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2194 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2195 if (s1->plt && s1->plt->reloc) {
2196 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2197 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2198 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2199 put_dt(dynamic, DT_PLTREL, DT_REL);
2201 put_dt(dynamic, DT_RELCOUNT, 0);
2202 #endif
2203 if (versym_section && verneed_section) {
2204 /* The dynamic linker can not handle VERSYM without VERNEED */
2205 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2206 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2207 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2209 s = find_section_create (s1, ".preinit_array", 0);
2210 if (s && s->data_offset) {
2211 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2212 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2214 s = find_section_create (s1, ".init_array", 0);
2215 if (s && s->data_offset) {
2216 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2217 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2219 s = find_section_create (s1, ".fini_array", 0);
2220 if (s && s->data_offset) {
2221 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2222 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2224 s = find_section_create (s1, ".init", 0);
2225 if (s && s->data_offset) {
2226 put_dt(dynamic, DT_INIT, s->sh_addr);
2228 s = find_section_create (s1, ".fini", 0);
2229 if (s && s->data_offset) {
2230 put_dt(dynamic, DT_FINI, s->sh_addr);
2232 if (s1->do_debug)
2233 put_dt(dynamic, DT_DEBUG, 0);
2234 put_dt(dynamic, DT_NULL, 0);
2237 /* Remove gaps between RELX sections.
2238 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2239 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2240 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2241 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2242 static void update_reloc_sections(TCCState *s1, struct dyn_inf *dyninf)
2244 int i;
2245 unsigned long file_offset = 0;
2246 Section *s;
2247 Section *relocplt = s1->plt ? s1->plt->reloc : NULL;
2249 /* dynamic relocation table information, for .dynamic section */
2250 dyninf->rel_addr = dyninf->rel_size = 0;
2252 for(i = 1; i < s1->nb_sections; i++) {
2253 s = s1->sections[i];
2254 if (s->sh_type == SHT_RELX && s != relocplt) {
2255 if (dyninf->rel_size == 0) {
2256 dyninf->rel_addr = s->sh_addr;
2257 file_offset = s->sh_offset;
2259 else {
2260 s->sh_addr = dyninf->rel_addr + dyninf->rel_size;
2261 s->sh_offset = file_offset + dyninf->rel_size;
2263 dyninf->rel_size += s->sh_size;
2268 #endif /* ndef ELF_OBJ_ONLY */
2270 /* Create an ELF file on disk.
2271 This function handle ELF specific layout requirements */
2272 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2273 int file_offset, int *sec_order)
2275 int i, shnum, offset, size, file_type;
2276 Section *s;
2277 ElfW(Ehdr) ehdr;
2278 ElfW(Shdr) shdr, *sh;
2280 file_type = s1->output_type;
2281 shnum = s1->nb_sections;
2283 memset(&ehdr, 0, sizeof(ehdr));
2285 if (phnum > 0) {
2286 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2287 ehdr.e_phnum = phnum;
2288 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2291 /* align to 4 */
2292 file_offset = (file_offset + 3) & -4;
2294 /* fill header */
2295 ehdr.e_ident[0] = ELFMAG0;
2296 ehdr.e_ident[1] = ELFMAG1;
2297 ehdr.e_ident[2] = ELFMAG2;
2298 ehdr.e_ident[3] = ELFMAG3;
2299 ehdr.e_ident[4] = ELFCLASSW;
2300 ehdr.e_ident[5] = ELFDATA2LSB;
2301 ehdr.e_ident[6] = EV_CURRENT;
2302 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2303 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2304 #endif
2305 #ifdef TCC_TARGET_ARM
2306 #ifdef TCC_ARM_EABI
2307 ehdr.e_ident[EI_OSABI] = 0;
2308 ehdr.e_flags = EF_ARM_EABI_VER4;
2309 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2310 ehdr.e_flags |= EF_ARM_HASENTRY;
2311 if (s1->float_abi == ARM_HARD_FLOAT)
2312 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2313 else
2314 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2315 #else
2316 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2317 #endif
2318 #elif defined TCC_TARGET_RISCV64
2319 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2320 #endif
2321 switch(file_type) {
2322 default:
2323 case TCC_OUTPUT_EXE:
2324 ehdr.e_type = ET_EXEC;
2325 ehdr.e_entry = get_sym_addr(s1,
2326 s1->elf_entryname ?
2327 s1->elf_entryname : "_start",
2328 1, 0);
2329 break;
2330 case TCC_OUTPUT_DLL:
2331 ehdr.e_type = ET_DYN;
2332 ehdr.e_entry = s1->elf_entryname ?
2333 get_sym_addr(s1,s1->elf_entryname,1,0) :
2334 text_section->sh_addr;
2335 /* XXX: is it correct ? */
2336 break;
2337 case TCC_OUTPUT_OBJ:
2338 ehdr.e_type = ET_REL;
2339 break;
2341 ehdr.e_machine = EM_TCC_TARGET;
2342 ehdr.e_version = EV_CURRENT;
2343 ehdr.e_shoff = file_offset;
2344 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2345 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2346 ehdr.e_shnum = shnum;
2347 ehdr.e_shstrndx = shnum - 1;
2349 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2350 if (phdr)
2351 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2352 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2354 sort_syms(s1, symtab_section);
2355 for(i = 1; i < s1->nb_sections; i++) {
2356 s = s1->sections[sec_order[i]];
2357 if (s->sh_type != SHT_NOBITS) {
2358 while (offset < s->sh_offset) {
2359 fputc(0, f);
2360 offset++;
2362 size = s->sh_size;
2363 if (size)
2364 fwrite(s->data, 1, size, f);
2365 offset += size;
2369 /* output section headers */
2370 while (offset < ehdr.e_shoff) {
2371 fputc(0, f);
2372 offset++;
2375 for(i = 0; i < s1->nb_sections; i++) {
2376 sh = &shdr;
2377 memset(sh, 0, sizeof(ElfW(Shdr)));
2378 s = s1->sections[i];
2379 if (s) {
2380 sh->sh_name = s->sh_name;
2381 sh->sh_type = s->sh_type;
2382 sh->sh_flags = s->sh_flags;
2383 sh->sh_entsize = s->sh_entsize;
2384 sh->sh_info = s->sh_info;
2385 if (s->link)
2386 sh->sh_link = s->link->sh_num;
2387 sh->sh_addralign = s->sh_addralign;
2388 sh->sh_addr = s->sh_addr;
2389 sh->sh_offset = s->sh_offset;
2390 sh->sh_size = s->sh_size;
2392 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2396 static void tcc_output_binary(TCCState *s1, FILE *f,
2397 const int *sec_order)
2399 Section *s;
2400 int i, offset, size;
2402 offset = 0;
2403 for(i=1;i<s1->nb_sections;i++) {
2404 s = s1->sections[sec_order[i]];
2405 if (s->sh_type != SHT_NOBITS &&
2406 (s->sh_flags & SHF_ALLOC)) {
2407 while (offset < s->sh_offset) {
2408 fputc(0, f);
2409 offset++;
2411 size = s->sh_size;
2412 fwrite(s->data, 1, size, f);
2413 offset += size;
2418 /* Write an elf, coff or "binary" file */
2419 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2420 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2422 int fd, mode, file_type;
2423 FILE *f;
2425 file_type = s1->output_type;
2426 if (file_type == TCC_OUTPUT_OBJ)
2427 mode = 0666;
2428 else
2429 mode = 0777;
2430 unlink(filename);
2431 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2432 if (fd < 0 || (f = fdopen(fd, "wb")) == NULL) {
2433 tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno));
2434 return -1;
2436 if (s1->verbose)
2437 printf("<- %s\n", filename);
2439 #ifdef TCC_TARGET_COFF
2440 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2441 tcc_output_coff(s1, f);
2442 else
2443 #endif
2444 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2445 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2446 else
2447 tcc_output_binary(s1, f, sec_order);
2448 fclose(f);
2450 return 0;
2453 #ifndef ELF_OBJ_ONLY
2454 /* Sort section headers by assigned sh_addr, remove sections
2455 that we aren't going to output. */
2456 static void tidy_section_headers(TCCState *s1, int *sec_order)
2458 int i, nnew, l, *backmap;
2459 Section **snew, *s;
2460 ElfW(Sym) *sym;
2462 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2463 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2464 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2465 s = s1->sections[sec_order[i]];
2466 if (!i || s->sh_name) {
2467 backmap[sec_order[i]] = nnew;
2468 snew[nnew] = s;
2469 ++nnew;
2470 } else {
2471 backmap[sec_order[i]] = 0;
2472 snew[--l] = s;
2475 for (i = 0; i < nnew; i++) {
2476 s = snew[i];
2477 if (s) {
2478 s->sh_num = i;
2479 if (s->sh_type == SHT_RELX)
2480 s->sh_info = backmap[s->sh_info];
2484 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2485 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2486 sym->st_shndx = backmap[sym->st_shndx];
2487 if ( !s1->static_link ) {
2488 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2489 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2490 sym->st_shndx = backmap[sym->st_shndx];
2492 for (i = 0; i < s1->nb_sections; i++)
2493 sec_order[i] = i;
2494 tcc_free(s1->sections);
2495 s1->sections = snew;
2496 s1->nb_sections = nnew;
2497 tcc_free(backmap);
2500 #ifdef TCC_TARGET_ARM
2501 static void create_arm_attribute_section(TCCState *s1)
2503 // Needed for DLL support.
2504 static const unsigned char arm_attr[] = {
2505 0x41, // 'A'
2506 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2507 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2508 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2509 0x05, 0x36, 0x00, // 'CPU_name', "6"
2510 0x06, 0x06, // 'CPU_arch', 'v6'
2511 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2512 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2513 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2514 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2515 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2516 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2517 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2518 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2519 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2520 0x1a, 0x02, // 'ABI_enum_size', 'int'
2521 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2522 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2524 Section *attr = new_section(s1, ".ARM.attributes", SHT_ARM_ATTRIBUTES, 0);
2525 unsigned char *ptr = section_ptr_add(attr, sizeof(arm_attr));
2526 attr->sh_addralign = 1;
2527 memcpy(ptr, arm_attr, sizeof(arm_attr));
2528 if (s1->float_abi != ARM_HARD_FLOAT) {
2529 ptr[26] = 0x00; // 'FP_arch', 'No'
2530 ptr[41] = 0x1e; // 'ABI_optimization_goals'
2531 ptr[42] = 0x06; // 'Aggressive Debug'
2534 #endif
2536 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2537 static Section *create_bsd_note_section(TCCState *s1,
2538 const char *name,
2539 const char *value)
2541 Section *s = find_section (s1, name);
2543 if (s->data_offset == 0) {
2544 char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
2545 ElfW(Nhdr) *note = (ElfW(Nhdr) *) ptr;
2547 s->sh_type = SHT_NOTE;
2548 note->n_namesz = 8;
2549 note->n_descsz = 4;
2550 note->n_type = ELF_NOTE_OS_GNU;
2551 strcpy (ptr + sizeof(ElfW(Nhdr)), value);
2553 return s;
2555 #endif
2557 /* Output an elf, coff or binary file */
2558 /* XXX: suppress unneeded sections */
2559 static int elf_output_file(TCCState *s1, const char *filename)
2561 int i, ret, phnum, phfill, shnum, file_type, file_offset, *sec_order;
2562 struct dyn_inf dyninf = {0};
2563 struct ro_inf roinf;
2564 ElfW(Phdr) *phdr;
2565 Section *interp, *dynamic, *dynstr, *note;
2566 struct ro_inf *roinf_use = NULL;
2567 int textrel;
2569 file_type = s1->output_type;
2570 s1->nb_errors = 0;
2571 ret = -1;
2572 phdr = NULL;
2573 sec_order = NULL;
2574 interp = dynamic = dynstr = note = NULL;
2576 #ifdef TCC_TARGET_ARM
2577 create_arm_attribute_section (s1);
2578 #endif
2580 #if TARGETOS_OpenBSD
2581 note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
2582 #endif
2584 #if TARGETOS_NetBSD
2585 note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD");
2586 #endif
2589 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2590 tcc_add_runtime(s1);
2591 resolve_common_syms(s1);
2593 if (!s1->static_link) {
2594 if (file_type == TCC_OUTPUT_EXE) {
2595 char *ptr;
2596 /* allow override the dynamic loader */
2597 const char *elfint = getenv("LD_SO");
2598 if (elfint == NULL)
2599 elfint = DEFAULT_ELFINTERP(s1);
2600 /* add interpreter section only if executable */
2601 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2602 interp->sh_addralign = 1;
2603 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2604 strcpy(ptr, elfint);
2607 /* add dynamic symbol table */
2608 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2609 ".dynstr",
2610 ".hash", SHF_ALLOC);
2611 /* Number of local symbols (readelf complains if not set) */
2612 s1->dynsym->sh_info = 1;
2613 dynstr = s1->dynsym->link;
2614 /* add dynamic section */
2615 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2616 SHF_ALLOC | SHF_WRITE);
2617 dynamic->link = dynstr;
2618 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2620 build_got(s1);
2622 if (file_type == TCC_OUTPUT_EXE) {
2623 bind_exe_dynsyms(s1);
2624 if (s1->nb_errors)
2625 goto the_end;
2626 bind_libs_dynsyms(s1);
2627 } else {
2628 /* shared library case: simply export all global symbols */
2629 export_global_syms(s1);
2632 build_got_entries(s1);
2633 version_add (s1);
2636 textrel = set_sec_sizes(s1);
2637 alloc_sec_names(s1, 0);
2639 if (!s1->static_link) {
2640 int i;
2641 /* add a list of needed dlls */
2642 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2643 DLLReference *dllref = s1->loaded_dlls[i];
2644 if (dllref->level == 0)
2645 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2648 if (s1->rpath)
2649 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2650 put_elf_str(dynstr, s1->rpath));
2652 if (file_type == TCC_OUTPUT_DLL) {
2653 if (s1->soname)
2654 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2655 /* XXX: currently, since we do not handle PIC code, we
2656 must relocate the readonly segments */
2657 if (textrel)
2658 put_dt(dynamic, DT_TEXTREL, 0);
2661 if (s1->symbolic)
2662 put_dt(dynamic, DT_SYMBOLIC, 0);
2664 dyninf.dynamic = dynamic;
2665 dyninf.dynstr = dynstr;
2666 /* remember offset and reserve space for 2nd call below */
2667 dyninf.data_offset = dynamic->data_offset;
2668 fill_dynamic(s1, &dyninf);
2669 dynamic->sh_size = dynamic->data_offset;
2670 dynstr->sh_size = dynstr->data_offset;
2673 for (i = 1; i < s1->nb_sections &&
2674 !(s1->sections[i]->sh_flags & SHF_TLS); i++);
2675 phfill = 2 + (i < s1->nb_sections);
2677 /* compute number of program headers */
2678 if (file_type == TCC_OUTPUT_DLL)
2679 phnum = 3;
2680 else if (s1->static_link)
2681 phnum = 3;
2682 else {
2683 phnum = 5 + (i < s1->nb_sections);
2686 phnum += note != NULL;
2687 #if !TARGETOS_FreeBSD && !TARGETOS_NetBSD
2688 /* GNU_RELRO */
2689 phnum++, roinf_use = &roinf;
2690 #endif
2692 /* allocate program segment headers */
2693 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2694 /* compute number of sections */
2695 shnum = s1->nb_sections;
2696 /* this array is used to reorder sections in the output file */
2697 sec_order = tcc_malloc(sizeof(int) * shnum);
2698 sec_order[0] = 0;
2700 /* compute section to program header mapping */
2701 file_offset = layout_sections(s1, phdr, phnum, phfill, interp, &roinf, sec_order + 1);
2703 /* Fill remaining program header and finalize relocation related to dynamic
2704 linking. */
2706 fill_unloadable_phdr(phdr, phnum, interp, dynamic, note, roinf_use);
2707 if (dynamic) {
2708 ElfW(Sym) *sym;
2710 /* put in GOT the dynamic section address and relocate PLT */
2711 write32le(s1->got->data, dynamic->sh_addr);
2712 if (file_type == TCC_OUTPUT_EXE
2713 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2714 relocate_plt(s1);
2716 /* relocate symbols in .dynsym now that final addresses are known */
2717 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2718 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2719 /* do symbol relocation */
2720 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2725 /* if building executable or DLL, then relocate each section
2726 except the GOT which is already relocated */
2727 relocate_syms(s1, s1->symtab, 0);
2728 ret = -1;
2729 if (s1->nb_errors != 0)
2730 goto the_end;
2731 relocate_sections(s1);
2732 if (dynamic) {
2733 update_reloc_sections (s1, &dyninf);
2734 dynamic->data_offset = dyninf.data_offset;
2735 fill_dynamic(s1, &dyninf);
2737 tidy_section_headers(s1, sec_order);
2739 /* Perform relocation to GOT or PLT entries */
2740 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2741 fill_got(s1);
2742 else if (s1->got)
2743 fill_local_got_entries(s1);
2745 /* Create the ELF file with name 'filename' */
2746 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2747 s1->nb_sections = shnum;
2749 the_end:
2750 tcc_free(sec_order);
2751 tcc_free(phdr);
2752 return ret;
2754 #endif /* ndef ELF_OBJ_ONLY */
2756 /* Allocate strings for section names */
2757 static void alloc_sec_names(TCCState *s1, int is_obj)
2759 int i;
2760 Section *s, *strsec;
2762 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2763 put_elf_str(strsec, "");
2764 for(i = 1; i < s1->nb_sections; i++) {
2765 s = s1->sections[i];
2766 if (is_obj)
2767 s->sh_size = s->data_offset;
2768 if (s == strsec || s->sh_size || (s->sh_flags & SHF_ALLOC))
2769 s->sh_name = put_elf_str(strsec, s->name);
2771 strsec->sh_size = strsec->data_offset;
2774 static int layout_any_sections(TCCState *s1, int file_offset, int *sec_order, int is_obj)
2776 int i;
2777 Section *s;
2778 for(i = 1; i < s1->nb_sections; i++) {
2779 s = s1->sections[i];
2780 if (!is_obj && (s->sh_flags & SHF_ALLOC))
2781 continue;
2782 *sec_order++ = i;
2783 file_offset = (file_offset + s->sh_addralign - 1) &
2784 ~(s->sh_addralign - 1);
2785 s->sh_offset = file_offset;
2786 if (s->sh_type != SHT_NOBITS)
2787 file_offset += s->sh_size;
2789 return file_offset;
2792 /* Output an elf .o file */
2793 static int elf_output_obj(TCCState *s1, const char *filename)
2795 int ret, file_offset;
2796 int *sec_order;
2797 s1->nb_errors = 0;
2799 /* Allocate strings for section names */
2800 alloc_sec_names(s1, 1);
2802 /* this array is used to reorder sections in the output file */
2803 sec_order = tcc_malloc(sizeof(int) * s1->nb_sections);
2804 sec_order[0] = 0;
2805 file_offset = layout_any_sections(s1, sizeof (ElfW(Ehdr)), sec_order + 1, 1);
2807 /* Create the ELF file with name 'filename' */
2808 ret = tcc_write_elf_file(s1, filename, 0, NULL, file_offset, sec_order);
2809 tcc_free(sec_order);
2810 return ret;
2813 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2815 if (s->test_coverage)
2816 tcc_tcov_add_file(s, filename);
2817 if (s->output_type == TCC_OUTPUT_OBJ)
2818 return elf_output_obj(s, filename);
2819 #ifdef TCC_TARGET_PE
2820 return pe_output_file(s, filename);
2821 #elif TCC_TARGET_MACHO
2822 return macho_output_file(s, filename);
2823 #else
2824 return elf_output_file(s, filename);
2825 #endif
2828 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
2829 char *cbuf = buf;
2830 size_t rnum = 0;
2831 while (1) {
2832 ssize_t num = read(fd, cbuf, count-rnum);
2833 if (num < 0) return num;
2834 if (num == 0) return rnum;
2835 rnum += num;
2836 cbuf += num;
2840 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
2842 void *data;
2844 data = tcc_malloc(size);
2845 lseek(fd, file_offset, SEEK_SET);
2846 full_read(fd, data, size);
2847 return data;
2850 typedef struct SectionMergeInfo {
2851 Section *s; /* corresponding existing section */
2852 unsigned long offset; /* offset of the new section in the existing section */
2853 uint8_t new_section; /* true if section 's' was added */
2854 uint8_t link_once; /* true if link once section */
2855 } SectionMergeInfo;
2857 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2859 int size = full_read(fd, h, sizeof *h);
2860 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2861 if (h->e_type == ET_REL)
2862 return AFF_BINTYPE_REL;
2863 if (h->e_type == ET_DYN)
2864 return AFF_BINTYPE_DYN;
2865 } else if (size >= 8) {
2866 if (0 == memcmp(h, ARMAG, 8))
2867 return AFF_BINTYPE_AR;
2868 #ifdef TCC_TARGET_COFF
2869 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2870 return AFF_BINTYPE_C67;
2871 #endif
2873 return 0;
2876 /* load an object file and merge it with current files */
2877 /* XXX: handle correctly stab (debug) info */
2878 ST_FUNC int tcc_load_object_file(TCCState *s1,
2879 int fd, unsigned long file_offset)
2881 ElfW(Ehdr) ehdr;
2882 ElfW(Shdr) *shdr, *sh;
2883 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2884 char *strsec, *strtab;
2885 int stab_index, stabstr_index;
2886 int *old_to_new_syms;
2887 char *sh_name, *name;
2888 SectionMergeInfo *sm_table, *sm;
2889 ElfW(Sym) *sym, *symtab;
2890 ElfW_Rel *rel;
2891 Section *s;
2893 lseek(fd, file_offset, SEEK_SET);
2894 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2895 goto fail1;
2896 /* test CPU specific stuff */
2897 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2898 ehdr.e_machine != EM_TCC_TARGET) {
2899 fail1:
2900 tcc_error_noabort("invalid object file");
2901 return -1;
2903 /* read sections */
2904 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2905 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2906 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2908 /* load section names */
2909 sh = &shdr[ehdr.e_shstrndx];
2910 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2912 /* load symtab and strtab */
2913 old_to_new_syms = NULL;
2914 symtab = NULL;
2915 strtab = NULL;
2916 nb_syms = 0;
2917 seencompressed = 0;
2918 stab_index = stabstr_index = 0;
2920 for(i = 1; i < ehdr.e_shnum; i++) {
2921 sh = &shdr[i];
2922 if (sh->sh_type == SHT_SYMTAB) {
2923 if (symtab) {
2924 tcc_error_noabort("object must contain only one symtab");
2925 fail:
2926 ret = -1;
2927 goto the_end;
2929 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2930 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2931 sm_table[i].s = symtab_section;
2933 /* now load strtab */
2934 sh = &shdr[sh->sh_link];
2935 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2937 if (sh->sh_flags & SHF_COMPRESSED)
2938 seencompressed = 1;
2941 /* now examine each section and try to merge its content with the
2942 ones in memory */
2943 for(i = 1; i < ehdr.e_shnum; i++) {
2944 /* no need to examine section name strtab */
2945 if (i == ehdr.e_shstrndx)
2946 continue;
2947 sh = &shdr[i];
2948 if (sh->sh_type == SHT_RELX)
2949 sh = &shdr[sh->sh_info];
2950 /* ignore sections types we do not handle (plus relocs to those) */
2951 if (sh->sh_type != SHT_PROGBITS &&
2952 #ifdef TCC_ARM_EABI
2953 sh->sh_type != SHT_ARM_EXIDX &&
2954 #endif
2955 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2956 sh->sh_type != SHT_X86_64_UNWIND &&
2957 #endif
2958 sh->sh_type != SHT_NOTE &&
2959 sh->sh_type != SHT_NOBITS &&
2960 sh->sh_type != SHT_PREINIT_ARRAY &&
2961 sh->sh_type != SHT_INIT_ARRAY &&
2962 sh->sh_type != SHT_FINI_ARRAY &&
2963 strcmp(strsec + sh->sh_name, ".stabstr")
2965 continue;
2966 if (seencompressed
2967 && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
2968 continue;
2970 sh = &shdr[i];
2971 sh_name = strsec + sh->sh_name;
2972 if (sh->sh_addralign < 1)
2973 sh->sh_addralign = 1;
2974 /* find corresponding section, if any */
2975 for(j = 1; j < s1->nb_sections;j++) {
2976 s = s1->sections[j];
2977 if (!strcmp(s->name, sh_name)) {
2978 if (!strncmp(sh_name, ".gnu.linkonce",
2979 sizeof(".gnu.linkonce") - 1)) {
2980 /* if a 'linkonce' section is already present, we
2981 do not add it again. It is a little tricky as
2982 symbols can still be defined in
2983 it. */
2984 sm_table[i].link_once = 1;
2985 goto next;
2987 if (stab_section) {
2988 if (s == stab_section)
2989 stab_index = i;
2990 if (s == stab_section->link)
2991 stabstr_index = i;
2993 goto found;
2996 /* not found: create new section */
2997 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2998 /* take as much info as possible from the section. sh_link and
2999 sh_info will be updated later */
3000 s->sh_addralign = sh->sh_addralign;
3001 s->sh_entsize = sh->sh_entsize;
3002 sm_table[i].new_section = 1;
3003 found:
3004 if (sh->sh_type != s->sh_type) {
3005 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3006 if (strcmp (s->name, ".eh_frame"))
3007 #endif
3009 tcc_error_noabort("invalid section type");
3010 goto fail;
3013 /* align start of section */
3014 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
3015 if (sh->sh_addralign > s->sh_addralign)
3016 s->sh_addralign = sh->sh_addralign;
3017 sm_table[i].offset = s->data_offset;
3018 sm_table[i].s = s;
3019 /* concatenate sections */
3020 size = sh->sh_size;
3021 if (sh->sh_type != SHT_NOBITS) {
3022 unsigned char *ptr;
3023 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
3024 ptr = section_ptr_add(s, size);
3025 full_read(fd, ptr, size);
3026 } else {
3027 s->data_offset += size;
3029 next: ;
3032 /* gr relocate stab strings */
3033 if (stab_index && stabstr_index) {
3034 Stab_Sym *a, *b;
3035 unsigned o;
3036 s = sm_table[stab_index].s;
3037 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
3038 b = (Stab_Sym *)(s->data + s->data_offset);
3039 o = sm_table[stabstr_index].offset;
3040 while (a < b) {
3041 if (a->n_strx)
3042 a->n_strx += o;
3043 a++;
3047 /* second short pass to update sh_link and sh_info fields of new
3048 sections */
3049 for(i = 1; i < ehdr.e_shnum; i++) {
3050 s = sm_table[i].s;
3051 if (!s || !sm_table[i].new_section)
3052 continue;
3053 sh = &shdr[i];
3054 if (sh->sh_link > 0)
3055 s->link = sm_table[sh->sh_link].s;
3056 if (sh->sh_type == SHT_RELX) {
3057 s->sh_info = sm_table[sh->sh_info].s->sh_num;
3058 /* update backward link */
3059 s1->sections[s->sh_info]->reloc = s;
3063 /* resolve symbols */
3064 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
3066 sym = symtab + 1;
3067 for(i = 1; i < nb_syms; i++, sym++) {
3068 if (sym->st_shndx != SHN_UNDEF &&
3069 sym->st_shndx < SHN_LORESERVE) {
3070 sm = &sm_table[sym->st_shndx];
3071 if (sm->link_once) {
3072 /* if a symbol is in a link once section, we use the
3073 already defined symbol. It is very important to get
3074 correct relocations */
3075 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
3076 name = strtab + sym->st_name;
3077 sym_index = find_elf_sym(symtab_section, name);
3078 if (sym_index)
3079 old_to_new_syms[i] = sym_index;
3081 continue;
3083 /* if no corresponding section added, no need to add symbol */
3084 if (!sm->s)
3085 continue;
3086 /* convert section number */
3087 sym->st_shndx = sm->s->sh_num;
3088 /* offset value */
3089 sym->st_value += sm->offset;
3091 /* add symbol */
3092 name = strtab + sym->st_name;
3093 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
3094 sym->st_info, sym->st_other,
3095 sym->st_shndx, name);
3096 old_to_new_syms[i] = sym_index;
3099 /* third pass to patch relocation entries */
3100 for(i = 1; i < ehdr.e_shnum; i++) {
3101 s = sm_table[i].s;
3102 if (!s)
3103 continue;
3104 sh = &shdr[i];
3105 offset = sm_table[i].offset;
3106 size = sh->sh_size;
3107 switch(s->sh_type) {
3108 case SHT_RELX:
3109 /* take relocation offset information */
3110 offseti = sm_table[sh->sh_info].offset;
3111 for (rel = (ElfW_Rel *) s->data + (offset / sizeof(*rel));
3112 rel < (ElfW_Rel *) s->data + ((offset + size) / sizeof(*rel));
3113 rel++) {
3114 int type;
3115 unsigned sym_index;
3116 /* convert symbol index */
3117 type = ELFW(R_TYPE)(rel->r_info);
3118 sym_index = ELFW(R_SYM)(rel->r_info);
3119 /* NOTE: only one symtab assumed */
3120 if (sym_index >= nb_syms)
3121 goto invalid_reloc;
3122 sym_index = old_to_new_syms[sym_index];
3123 /* ignore link_once in rel section. */
3124 if (!sym_index && !sm_table[sh->sh_info].link_once
3125 #ifdef TCC_TARGET_ARM
3126 && type != R_ARM_V4BX
3127 #elif defined TCC_TARGET_RISCV64
3128 && type != R_RISCV_ALIGN
3129 && type != R_RISCV_RELAX
3130 #endif
3132 invalid_reloc:
3133 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3134 i, strsec + sh->sh_name, (int)rel->r_offset);
3135 goto fail;
3137 rel->r_info = ELFW(R_INFO)(sym_index, type);
3138 /* offset the relocation offset */
3139 rel->r_offset += offseti;
3140 #ifdef TCC_TARGET_ARM
3141 /* Jumps and branches from a Thumb code to a PLT entry need
3142 special handling since PLT entries are ARM code.
3143 Unconditional bl instructions referencing PLT entries are
3144 handled by converting these instructions into blx
3145 instructions. Other case of instructions referencing a PLT
3146 entry require to add a Thumb stub before the PLT entry to
3147 switch to ARM mode. We set bit plt_thumb_stub of the
3148 attribute of a symbol to indicate such a case. */
3149 if (type == R_ARM_THM_JUMP24)
3150 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
3151 #endif
3153 break;
3154 default:
3155 break;
3159 ret = 0;
3160 the_end:
3161 tcc_free(symtab);
3162 tcc_free(strtab);
3163 tcc_free(old_to_new_syms);
3164 tcc_free(sm_table);
3165 tcc_free(strsec);
3166 tcc_free(shdr);
3167 return ret;
3170 typedef struct ArchiveHeader {
3171 char ar_name[16]; /* name of this member */
3172 char ar_date[12]; /* file mtime */
3173 char ar_uid[6]; /* owner uid; printed as decimal */
3174 char ar_gid[6]; /* owner gid; printed as decimal */
3175 char ar_mode[8]; /* file mode, printed as octal */
3176 char ar_size[10]; /* file size, printed as decimal */
3177 char ar_fmag[2]; /* should contain ARFMAG */
3178 } ArchiveHeader;
3180 #define ARFMAG "`\n"
3182 static unsigned long long get_be(const uint8_t *b, int n)
3184 unsigned long long ret = 0;
3185 while (n)
3186 ret = (ret << 8) | *b++, --n;
3187 return ret;
3190 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
3192 char *p, *e;
3193 int len;
3194 lseek(fd, offset, SEEK_SET);
3195 len = full_read(fd, hdr, sizeof(ArchiveHeader));
3196 if (len != sizeof(ArchiveHeader))
3197 return len ? -1 : 0;
3198 p = hdr->ar_name;
3199 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
3200 --e;
3201 *e = '\0';
3202 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
3203 return len;
3206 /* load only the objects which resolve undefined symbols */
3207 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
3209 int i, bound, nsyms, sym_index, len, ret = -1;
3210 unsigned long long off;
3211 uint8_t *data;
3212 const char *ar_names, *p;
3213 const uint8_t *ar_index;
3214 ElfW(Sym) *sym;
3215 ArchiveHeader hdr;
3217 data = tcc_malloc(size);
3218 if (full_read(fd, data, size) != size)
3219 goto the_end;
3220 nsyms = get_be(data, entrysize);
3221 ar_index = data + entrysize;
3222 ar_names = (char *) ar_index + nsyms * entrysize;
3224 do {
3225 bound = 0;
3226 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
3227 Section *s = symtab_section;
3228 sym_index = find_elf_sym(s, p);
3229 if (!sym_index)
3230 continue;
3231 sym = &((ElfW(Sym) *)s->data)[sym_index];
3232 if(sym->st_shndx != SHN_UNDEF)
3233 continue;
3234 off = get_be(ar_index + i * entrysize, entrysize);
3235 len = read_ar_header(fd, off, &hdr);
3236 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
3237 tcc_error_noabort("invalid archive");
3238 goto the_end;
3240 off += len;
3241 if (s1->verbose == 2)
3242 printf(" -> %s\n", hdr.ar_name);
3243 if (tcc_load_object_file(s1, fd, off) < 0)
3244 goto the_end;
3245 ++bound;
3247 } while(bound);
3248 ret = 0;
3249 the_end:
3250 tcc_free(data);
3251 return ret;
3254 /* load a '.a' file */
3255 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
3257 ArchiveHeader hdr;
3258 /* char magic[8]; */
3259 int size, len;
3260 unsigned long file_offset;
3261 ElfW(Ehdr) ehdr;
3263 /* skip magic which was already checked */
3264 /* full_read(fd, magic, sizeof(magic)); */
3265 file_offset = sizeof ARMAG - 1;
3267 for(;;) {
3268 len = read_ar_header(fd, file_offset, &hdr);
3269 if (len == 0)
3270 return 0;
3271 if (len < 0) {
3272 tcc_error_noabort("invalid archive");
3273 return -1;
3275 file_offset += len;
3276 size = strtol(hdr.ar_size, NULL, 0);
3277 /* align to even */
3278 size = (size + 1) & ~1;
3279 if (alacarte) {
3280 /* coff symbol table : we handle it */
3281 if (!strcmp(hdr.ar_name, "/"))
3282 return tcc_load_alacarte(s1, fd, size, 4);
3283 if (!strcmp(hdr.ar_name, "/SYM64/"))
3284 return tcc_load_alacarte(s1, fd, size, 8);
3285 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3286 if (s1->verbose == 2)
3287 printf(" -> %s\n", hdr.ar_name);
3288 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3289 return -1;
3291 file_offset += size;
3295 #ifndef ELF_OBJ_ONLY
3296 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3297 LV, maybe create a new entry for (LIB,VERSION). */
3298 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3300 while (i >= *n) {
3301 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3302 (*lv)[(*n)++] = -1;
3304 if ((*lv)[i] == -1) {
3305 int v, prev_same_lib = -1;
3306 for (v = 0; v < nb_sym_versions; v++) {
3307 if (strcmp(sym_versions[v].lib, lib))
3308 continue;
3309 prev_same_lib = v;
3310 if (!strcmp(sym_versions[v].version, version))
3311 break;
3313 if (v == nb_sym_versions) {
3314 sym_versions = tcc_realloc (sym_versions,
3315 (v + 1) * sizeof(*sym_versions));
3316 sym_versions[v].lib = tcc_strdup(lib);
3317 sym_versions[v].version = tcc_strdup(version);
3318 sym_versions[v].out_index = 0;
3319 sym_versions[v].prev_same_lib = prev_same_lib;
3320 nb_sym_versions++;
3322 (*lv)[i] = v;
3326 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3327 VERNDX. */
3328 static void
3329 set_sym_version(TCCState *s1, int sym_index, int verndx)
3331 if (sym_index >= nb_sym_to_version) {
3332 int newelems = sym_index ? sym_index * 2 : 1;
3333 sym_to_version = tcc_realloc(sym_to_version,
3334 newelems * sizeof(*sym_to_version));
3335 memset(sym_to_version + nb_sym_to_version, -1,
3336 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3337 nb_sym_to_version = newelems;
3339 if (sym_to_version[sym_index] < 0)
3340 sym_to_version[sym_index] = verndx;
3343 struct versym_info {
3344 int nb_versyms;
3345 ElfW(Verdef) *verdef;
3346 ElfW(Verneed) *verneed;
3347 ElfW(Half) *versym;
3348 int nb_local_ver, *local_ver;
3352 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3354 char *lib, *version;
3355 uint32_t next;
3356 int i;
3358 #define DEBUG_VERSION 0
3360 if (v->versym && v->verdef) {
3361 ElfW(Verdef) *vdef = v->verdef;
3362 lib = NULL;
3363 do {
3364 ElfW(Verdaux) *verdaux =
3365 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3367 #if DEBUG_VERSION
3368 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3369 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3370 vdef->vd_hash);
3371 #endif
3372 if (vdef->vd_cnt) {
3373 version = dynstr + verdaux->vda_name;
3375 if (lib == NULL)
3376 lib = version;
3377 else
3378 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3379 lib, version);
3380 #if DEBUG_VERSION
3381 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3382 #endif
3384 next = vdef->vd_next;
3385 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3386 } while (next);
3388 if (v->versym && v->verneed) {
3389 ElfW(Verneed) *vneed = v->verneed;
3390 do {
3391 ElfW(Vernaux) *vernaux =
3392 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3394 lib = dynstr + vneed->vn_file;
3395 #if DEBUG_VERSION
3396 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3397 #endif
3398 for (i = 0; i < vneed->vn_cnt; i++) {
3399 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3400 version = dynstr + vernaux->vna_name;
3401 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3402 lib, version);
3403 #if DEBUG_VERSION
3404 printf (" vernaux(%u): %u %u %s\n",
3405 vernaux->vna_other, vernaux->vna_hash,
3406 vernaux->vna_flags, version);
3407 #endif
3409 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3411 next = vneed->vn_next;
3412 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3413 } while (next);
3416 #if DEBUG_VERSION
3417 for (i = 0; i < v->nb_local_ver; i++) {
3418 if (v->local_ver[i] > 0) {
3419 printf ("%d: lib: %s, version %s\n",
3420 i, sym_versions[v->local_ver[i]].lib,
3421 sym_versions[v->local_ver[i]].version);
3424 #endif
3427 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3428 is referenced by the user (so it should be added as DT_NEEDED in
3429 the generated ELF file) */
3430 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3432 ElfW(Ehdr) ehdr;
3433 ElfW(Shdr) *shdr, *sh, *sh1;
3434 int i, j, nb_syms, nb_dts, sym_bind, ret;
3435 ElfW(Sym) *sym, *dynsym;
3436 ElfW(Dyn) *dt, *dynamic;
3438 char *dynstr;
3439 int sym_index;
3440 const char *name, *soname;
3441 DLLReference *dllref;
3442 struct versym_info v;
3444 full_read(fd, &ehdr, sizeof(ehdr));
3446 /* test CPU specific stuff */
3447 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3448 ehdr.e_machine != EM_TCC_TARGET) {
3449 tcc_error_noabort("bad architecture");
3450 return -1;
3453 /* read sections */
3454 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3456 /* load dynamic section and dynamic symbols */
3457 nb_syms = 0;
3458 nb_dts = 0;
3459 dynamic = NULL;
3460 dynsym = NULL; /* avoid warning */
3461 dynstr = NULL; /* avoid warning */
3462 memset(&v, 0, sizeof v);
3464 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3465 switch(sh->sh_type) {
3466 case SHT_DYNAMIC:
3467 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3468 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3469 break;
3470 case SHT_DYNSYM:
3471 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3472 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3473 sh1 = &shdr[sh->sh_link];
3474 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3475 break;
3476 case SHT_GNU_verdef:
3477 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3478 break;
3479 case SHT_GNU_verneed:
3480 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3481 break;
3482 case SHT_GNU_versym:
3483 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3484 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3485 break;
3486 default:
3487 break;
3491 /* compute the real library name */
3492 soname = tcc_basename(filename);
3494 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3495 if (dt->d_tag == DT_SONAME) {
3496 soname = dynstr + dt->d_un.d_val;
3497 } else if (dt->d_tag == DT_RPATH) {
3498 tcc_add_library_path(s1, dynstr + dt->d_un.d_val);
3502 /* if the dll is already loaded, do not load it */
3503 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3504 dllref = s1->loaded_dlls[i];
3505 if (!strcmp(soname, dllref->name)) {
3506 /* but update level if needed */
3507 if (level < dllref->level)
3508 dllref->level = level;
3509 ret = 0;
3510 goto the_end;
3514 if (v.nb_versyms != nb_syms)
3515 tcc_free (v.versym), v.versym = NULL;
3516 else
3517 store_version(s1, &v, dynstr);
3519 /* add the dll and its level */
3520 tcc_add_dllref(s1, soname)->level = level;
3522 /* add dynamic symbols in dynsym_section */
3523 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3524 sym_bind = ELFW(ST_BIND)(sym->st_info);
3525 if (sym_bind == STB_LOCAL)
3526 continue;
3527 name = dynstr + sym->st_name;
3528 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3529 sym->st_info, sym->st_other, sym->st_shndx, name);
3530 if (v.versym) {
3531 ElfW(Half) vsym = v.versym[i];
3532 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3533 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3537 /* load all referenced DLLs */
3538 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3539 switch(dt->d_tag) {
3540 case DT_NEEDED:
3541 name = dynstr + dt->d_un.d_val;
3542 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3543 dllref = s1->loaded_dlls[j];
3544 if (!strcmp(name, dllref->name))
3545 goto already_loaded;
3547 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3548 tcc_error_noabort("referenced dll '%s' not found", name);
3549 ret = -1;
3550 goto the_end;
3552 already_loaded:
3553 break;
3556 ret = 0;
3557 the_end:
3558 tcc_free(dynstr);
3559 tcc_free(dynsym);
3560 tcc_free(dynamic);
3561 tcc_free(shdr);
3562 tcc_free(v.local_ver);
3563 tcc_free(v.verdef);
3564 tcc_free(v.verneed);
3565 tcc_free(v.versym);
3566 return ret;
3569 #define LD_TOK_NAME 256
3570 #define LD_TOK_EOF (-1)
3572 static int ld_inp(TCCState *s1)
3574 char b;
3575 if (s1->cc != -1) {
3576 int c = s1->cc;
3577 s1->cc = -1;
3578 return c;
3580 if (1 == read(s1->fd, &b, 1))
3581 return b;
3582 return CH_EOF;
3585 /* return next ld script token */
3586 static int ld_next(TCCState *s1, char *name, int name_size)
3588 int c, d, ch;
3589 char *q;
3591 redo:
3592 ch = ld_inp(s1);
3593 switch(ch) {
3594 case ' ':
3595 case '\t':
3596 case '\f':
3597 case '\v':
3598 case '\r':
3599 case '\n':
3600 goto redo;
3601 case '/':
3602 ch = ld_inp(s1);
3603 if (ch == '*') { /* comment */
3604 for (d = 0;; d = ch) {
3605 ch = ld_inp(s1);
3606 if (ch == CH_EOF || (ch == '/' && d == '*'))
3607 break;
3609 goto redo;
3610 } else {
3611 q = name;
3612 *q++ = '/';
3613 goto parse_name;
3615 break;
3616 case '\\':
3617 /* case 'a' ... 'z': */
3618 case 'a':
3619 case 'b':
3620 case 'c':
3621 case 'd':
3622 case 'e':
3623 case 'f':
3624 case 'g':
3625 case 'h':
3626 case 'i':
3627 case 'j':
3628 case 'k':
3629 case 'l':
3630 case 'm':
3631 case 'n':
3632 case 'o':
3633 case 'p':
3634 case 'q':
3635 case 'r':
3636 case 's':
3637 case 't':
3638 case 'u':
3639 case 'v':
3640 case 'w':
3641 case 'x':
3642 case 'y':
3643 case 'z':
3644 /* case 'A' ... 'z': */
3645 case 'A':
3646 case 'B':
3647 case 'C':
3648 case 'D':
3649 case 'E':
3650 case 'F':
3651 case 'G':
3652 case 'H':
3653 case 'I':
3654 case 'J':
3655 case 'K':
3656 case 'L':
3657 case 'M':
3658 case 'N':
3659 case 'O':
3660 case 'P':
3661 case 'Q':
3662 case 'R':
3663 case 'S':
3664 case 'T':
3665 case 'U':
3666 case 'V':
3667 case 'W':
3668 case 'X':
3669 case 'Y':
3670 case 'Z':
3671 case '_':
3672 case '.':
3673 case '$':
3674 case '~':
3675 q = name;
3676 parse_name:
3677 for(;;) {
3678 if (!((ch >= 'a' && ch <= 'z') ||
3679 (ch >= 'A' && ch <= 'Z') ||
3680 (ch >= '0' && ch <= '9') ||
3681 strchr("/.-_+=$:\\,~", ch)))
3682 break;
3683 if ((q - name) < name_size - 1) {
3684 *q++ = ch;
3686 ch = ld_inp(s1);
3688 s1->cc = ch;
3689 *q = '\0';
3690 c = LD_TOK_NAME;
3691 break;
3692 case CH_EOF:
3693 c = LD_TOK_EOF;
3694 break;
3695 default:
3696 c = ch;
3697 break;
3699 return c;
3702 static int ld_add_file(TCCState *s1, const char filename[])
3704 if (filename[0] == '/') {
3705 if (CONFIG_SYSROOT[0] == '\0'
3706 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3707 return 0;
3708 filename = tcc_basename(filename);
3710 return tcc_add_dll(s1, filename, 0);
3713 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3715 char filename[1024], libname[1016];
3716 int t, group, nblibs = 0, ret = 0;
3717 char **libs = NULL;
3719 group = !strcmp(cmd, "GROUP");
3720 if (!as_needed)
3721 s1->new_undef_sym = 0;
3722 t = ld_next(s1, filename, sizeof(filename));
3723 if (t != '(') {
3724 tcc_error_noabort("( expected");
3725 ret = -1;
3726 goto lib_parse_error;
3728 t = ld_next(s1, filename, sizeof(filename));
3729 for(;;) {
3730 libname[0] = '\0';
3731 if (t == LD_TOK_EOF) {
3732 tcc_error_noabort("unexpected end of file");
3733 ret = -1;
3734 goto lib_parse_error;
3735 } else if (t == ')') {
3736 break;
3737 } else if (t == '-') {
3738 t = ld_next(s1, filename, sizeof(filename));
3739 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3740 tcc_error_noabort("library name expected");
3741 ret = -1;
3742 goto lib_parse_error;
3744 pstrcpy(libname, sizeof libname, &filename[1]);
3745 if (s1->static_link) {
3746 snprintf(filename, sizeof filename, "lib%s.a", libname);
3747 } else {
3748 snprintf(filename, sizeof filename, "lib%s.so", libname);
3750 } else if (t != LD_TOK_NAME) {
3751 tcc_error_noabort("filename expected");
3752 ret = -1;
3753 goto lib_parse_error;
3755 if (!strcmp(filename, "AS_NEEDED")) {
3756 ret = ld_add_file_list(s1, cmd, 1);
3757 if (ret)
3758 goto lib_parse_error;
3759 } else {
3760 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3761 if (!as_needed) {
3762 ret = ld_add_file(s1, filename);
3763 if (ret)
3764 goto lib_parse_error;
3765 if (group) {
3766 /* Add the filename *and* the libname to avoid future conversions */
3767 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3768 if (libname[0] != '\0')
3769 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3773 t = ld_next(s1, filename, sizeof(filename));
3774 if (t == ',') {
3775 t = ld_next(s1, filename, sizeof(filename));
3778 if (group && !as_needed) {
3779 while (s1->new_undef_sym) {
3780 int i;
3781 s1->new_undef_sym = 0;
3782 for (i = 0; i < nblibs; i ++)
3783 ld_add_file(s1, libs[i]);
3786 lib_parse_error:
3787 dynarray_reset(&libs, &nblibs);
3788 return ret;
3791 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3792 files */
3793 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3795 char cmd[64];
3796 char filename[1024];
3797 int t, ret;
3799 s1->fd = fd;
3800 s1->cc = -1;
3801 for(;;) {
3802 t = ld_next(s1, cmd, sizeof(cmd));
3803 if (t == LD_TOK_EOF)
3804 return 0;
3805 else if (t != LD_TOK_NAME)
3806 return -1;
3807 if (!strcmp(cmd, "INPUT") ||
3808 !strcmp(cmd, "GROUP")) {
3809 ret = ld_add_file_list(s1, cmd, 0);
3810 if (ret)
3811 return ret;
3812 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3813 !strcmp(cmd, "TARGET")) {
3814 /* ignore some commands */
3815 t = ld_next(s1, cmd, sizeof(cmd));
3816 if (t != '(') {
3817 tcc_error_noabort("( expected");
3818 return -1;
3820 for(;;) {
3821 t = ld_next(s1, filename, sizeof(filename));
3822 if (t == LD_TOK_EOF) {
3823 tcc_error_noabort("unexpected end of file");
3824 return -1;
3825 } else if (t == ')') {
3826 break;
3829 } else {
3830 return -1;
3833 return 0;
3835 #endif /* !ELF_OBJ_ONLY */