tccgen: fix "Allow declared arrays to be initialized..."
[tinycc.git] / tccelf.c
blob64623cacb63b27a0f04514b845981ca2012d71fb
1 /*
2 * ELF file handling for TCC
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "tcc.h"
23 /* Define this to get some debug output during relocation processing. */
24 #undef DEBUG_RELOC
26 /********************************************************/
27 /* global variables */
29 /* elf version information */
30 struct sym_version {
31 char *lib;
32 char *version;
33 int out_index;
34 int prev_same_lib;
37 #define nb_sym_versions s1->nb_sym_versions
38 #define sym_versions s1->sym_versions
39 #define nb_sym_to_version s1->nb_sym_to_version
40 #define sym_to_version s1->sym_to_version
41 #define dt_verneednum s1->dt_verneednum
42 #define versym_section s1->versym_section
43 #define verneed_section s1->verneed_section
45 /* special flag to indicate that the section should not be linked to the other ones */
46 #define SHF_PRIVATE 0x80000000
47 /* section is dynsymtab_section */
48 #define SHF_DYNSYM 0x40000000
50 /* ------------------------------------------------------------------------- */
52 ST_FUNC void tccelf_new(TCCState *s)
54 TCCState *s1 = s;
55 /* no section zero */
56 dynarray_add(&s->sections, &s->nb_sections, NULL);
58 /* create standard sections */
59 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
60 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
61 /* create ro data section (make ro after relocation done with GNU_RELRO) */
62 data_ro_section = new_section(s, ".data.ro", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
63 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
64 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
65 common_section->sh_num = SHN_COMMON;
67 /* symbols are always generated for linking stage */
68 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
69 ".strtab",
70 ".hashtab", SHF_PRIVATE);
71 s->symtab = symtab_section;
73 /* private symbol table for dynamic symbols */
74 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
75 ".dynstrtab",
76 ".dynhashtab", SHF_PRIVATE);
77 get_sym_attr(s, 0, 1);
80 #ifdef CONFIG_TCC_BCHECK
81 ST_FUNC void tccelf_bounds_new(TCCState *s)
83 TCCState *s1 = s;
84 /* create bounds sections (make ro after relocation done with GNU_RELRO) */
85 bounds_section = new_section(s, ".bounds",
86 SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
87 lbounds_section = new_section(s, ".lbounds",
88 SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
90 #endif
92 ST_FUNC void tccelf_stab_new(TCCState *s)
94 TCCState *s1 = s;
95 int shf = 0;
96 #ifdef CONFIG_TCC_BACKTRACE
97 /* include stab info with standalone backtrace support */
98 if (s->do_backtrace && s->output_type != TCC_OUTPUT_MEMORY)
99 shf = SHF_ALLOC | SHF_WRITE; // SHF_WRITE needed for musl/SELINUX
100 #endif
101 stab_section = new_section(s, ".stab", SHT_PROGBITS, shf);
102 stab_section->sh_entsize = sizeof(Stab_Sym);
103 stab_section->sh_addralign = sizeof ((Stab_Sym*)0)->n_value;
104 stab_section->link = new_section(s, ".stabstr", SHT_STRTAB, shf);
105 /* put first entry */
106 put_stabs(s, "", 0, 0, 0, 0);
109 static void free_section(Section *s)
111 tcc_free(s->data);
114 ST_FUNC void tccelf_delete(TCCState *s1)
116 int i;
118 #ifndef ELF_OBJ_ONLY
119 /* free symbol versions */
120 for (i = 0; i < nb_sym_versions; i++) {
121 tcc_free(sym_versions[i].version);
122 tcc_free(sym_versions[i].lib);
124 tcc_free(sym_versions);
125 tcc_free(sym_to_version);
126 #endif
128 /* free all sections */
129 for(i = 1; i < s1->nb_sections; i++)
130 free_section(s1->sections[i]);
131 dynarray_reset(&s1->sections, &s1->nb_sections);
133 for(i = 0; i < s1->nb_priv_sections; i++)
134 free_section(s1->priv_sections[i]);
135 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
137 /* free any loaded DLLs */
138 #ifdef TCC_IS_NATIVE
139 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
140 DLLReference *ref = s1->loaded_dlls[i];
141 if ( ref->handle )
142 # ifdef _WIN32
143 FreeLibrary((HMODULE)ref->handle);
144 # else
145 dlclose(ref->handle);
146 # endif
148 #endif
149 /* free loaded dlls array */
150 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
151 tcc_free(s1->sym_attrs);
153 symtab_section = NULL; /* for tccrun.c:rt_printline() */
156 /* save section data state */
157 ST_FUNC void tccelf_begin_file(TCCState *s1)
159 Section *s; int i;
160 for (i = 1; i < s1->nb_sections; i++) {
161 s = s1->sections[i];
162 s->sh_offset = s->data_offset;
164 /* disable symbol hashing during compilation */
165 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
166 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
167 s1->uw_sym = 0;
168 #endif
171 /* At the end of compilation, convert any UNDEF syms to global, and merge
172 with previously existing symbols */
173 ST_FUNC void tccelf_end_file(TCCState *s1)
175 Section *s = s1->symtab;
176 int first_sym, nb_syms, *tr, i;
178 first_sym = s->sh_offset / sizeof (ElfSym);
179 nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
180 s->data_offset = s->sh_offset;
181 s->link->data_offset = s->link->sh_offset;
182 s->hash = s->reloc, s->reloc = NULL;
183 tr = tcc_mallocz(nb_syms * sizeof *tr);
185 for (i = 0; i < nb_syms; ++i) {
186 ElfSym *sym = (ElfSym*)s->data + first_sym + i;
187 if (sym->st_shndx == SHN_UNDEF
188 && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
189 sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
190 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
191 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
193 /* now update relocations */
194 for (i = 1; i < s1->nb_sections; i++) {
195 Section *sr = s1->sections[i];
196 if (sr->sh_type == SHT_RELX && sr->link == s) {
197 ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
198 ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
199 for (; rel < rel_end; ++rel) {
200 int n = ELFW(R_SYM)(rel->r_info) - first_sym;
201 //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
202 rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
206 tcc_free(tr);
208 /* record text/data/bss output for -bench info */
209 for (i = 0; i < 3; ++i) {
210 s = s1->sections[i + 1];
211 s1->total_output[i] += s->data_offset - s->sh_offset;
215 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
217 Section *sec;
219 sec = tcc_mallocz(sizeof(Section) + strlen(name));
220 sec->s1 = s1;
221 strcpy(sec->name, name);
222 sec->sh_type = sh_type;
223 sec->sh_flags = sh_flags;
224 switch(sh_type) {
225 case SHT_GNU_versym:
226 sec->sh_addralign = 2;
227 break;
228 case SHT_HASH:
229 case SHT_REL:
230 case SHT_RELA:
231 case SHT_DYNSYM:
232 case SHT_SYMTAB:
233 case SHT_DYNAMIC:
234 case SHT_GNU_verneed:
235 case SHT_GNU_verdef:
236 sec->sh_addralign = PTR_SIZE;
237 break;
238 case SHT_STRTAB:
239 sec->sh_addralign = 1;
240 break;
241 default:
242 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */
243 break;
246 if (sh_flags & SHF_PRIVATE) {
247 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
248 } else {
249 sec->sh_num = s1->nb_sections;
250 dynarray_add(&s1->sections, &s1->nb_sections, sec);
253 return sec;
256 ST_FUNC Section *new_symtab(TCCState *s1,
257 const char *symtab_name, int sh_type, int sh_flags,
258 const char *strtab_name,
259 const char *hash_name, int hash_sh_flags)
261 Section *symtab, *strtab, *hash;
262 int *ptr, nb_buckets;
264 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
265 symtab->sh_entsize = sizeof(ElfW(Sym));
266 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
267 put_elf_str(strtab, "");
268 symtab->link = strtab;
269 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
271 nb_buckets = 1;
273 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
274 hash->sh_entsize = sizeof(int);
275 symtab->hash = hash;
276 hash->link = symtab;
278 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
279 ptr[0] = nb_buckets;
280 ptr[1] = 1;
281 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
282 return symtab;
285 /* realloc section and set its content to zero */
286 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
288 unsigned long size;
289 unsigned char *data;
291 size = sec->data_allocated;
292 if (size == 0)
293 size = 1;
294 while (size < new_size)
295 size = size * 2;
296 data = tcc_realloc(sec->data, size);
297 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
298 sec->data = data;
299 sec->data_allocated = size;
302 /* reserve at least 'size' bytes aligned per 'align' in section
303 'sec' from current offset, and return the aligned offset */
304 ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
306 size_t offset, offset1;
308 offset = (sec->data_offset + align - 1) & -align;
309 offset1 = offset + size;
310 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
311 section_realloc(sec, offset1);
312 sec->data_offset = offset1;
313 if (align > sec->sh_addralign)
314 sec->sh_addralign = align;
315 return offset;
318 /* reserve at least 'size' bytes in section 'sec' from
319 sec->data_offset. */
320 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
322 size_t offset = section_add(sec, size, 1);
323 return sec->data + offset;
326 #ifndef ELF_OBJ_ONLY
327 /* reserve at least 'size' bytes from section start */
328 static void section_reserve(Section *sec, unsigned long size)
330 if (size > sec->data_allocated)
331 section_realloc(sec, size);
332 if (size > sec->data_offset)
333 sec->data_offset = size;
335 #endif
337 static Section *find_section_create (TCCState *s1, const char *name, int create)
339 Section *sec;
340 int i;
341 for(i = 1; i < s1->nb_sections; i++) {
342 sec = s1->sections[i];
343 if (!strcmp(name, sec->name))
344 return sec;
346 /* sections are created as PROGBITS */
347 return create ? new_section(s1, name, SHT_PROGBITS, SHF_ALLOC) : NULL;
350 /* return a reference to a section, and create it if it does not
351 exists */
352 ST_FUNC Section *find_section(TCCState *s1, const char *name)
354 return find_section_create (s1, name, 1);
357 /* ------------------------------------------------------------------------- */
359 ST_FUNC int put_elf_str(Section *s, const char *sym)
361 int offset, len;
362 char *ptr;
364 len = strlen(sym) + 1;
365 offset = s->data_offset;
366 ptr = section_ptr_add(s, len);
367 memmove(ptr, sym, len);
368 return offset;
371 /* elf symbol hashing function */
372 static unsigned long elf_hash(const unsigned char *name)
374 unsigned long h = 0, g;
376 while (*name) {
377 h = (h << 4) + *name++;
378 g = h & 0xf0000000;
379 if (g)
380 h ^= g >> 24;
381 h &= ~g;
383 return h;
386 /* rebuild hash table of section s */
387 /* NOTE: we do factorize the hash table code to go faster */
388 static void rebuild_hash(Section *s, unsigned int nb_buckets)
390 ElfW(Sym) *sym;
391 int *ptr, *hash, nb_syms, sym_index, h;
392 unsigned char *strtab;
394 strtab = s->link->data;
395 nb_syms = s->data_offset / sizeof(ElfW(Sym));
397 if (!nb_buckets)
398 nb_buckets = ((int*)s->hash->data)[0];
400 s->hash->data_offset = 0;
401 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
402 ptr[0] = nb_buckets;
403 ptr[1] = nb_syms;
404 ptr += 2;
405 hash = ptr;
406 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
407 ptr += nb_buckets + 1;
409 sym = (ElfW(Sym) *)s->data + 1;
410 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
411 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
412 h = elf_hash(strtab + sym->st_name) % nb_buckets;
413 *ptr = hash[h];
414 hash[h] = sym_index;
415 } else {
416 *ptr = 0;
418 ptr++;
419 sym++;
423 /* return the symbol number */
424 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
425 int info, int other, int shndx, const char *name)
427 int name_offset, sym_index;
428 int nbuckets, h;
429 ElfW(Sym) *sym;
430 Section *hs;
432 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
433 if (name && name[0])
434 name_offset = put_elf_str(s->link, name);
435 else
436 name_offset = 0;
437 /* XXX: endianness */
438 sym->st_name = name_offset;
439 sym->st_value = value;
440 sym->st_size = size;
441 sym->st_info = info;
442 sym->st_other = other;
443 sym->st_shndx = shndx;
444 sym_index = sym - (ElfW(Sym) *)s->data;
445 hs = s->hash;
446 if (hs) {
447 int *ptr, *base;
448 ptr = section_ptr_add(hs, sizeof(int));
449 base = (int *)hs->data;
450 /* only add global or weak symbols. */
451 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
452 /* add another hashing entry */
453 nbuckets = base[0];
454 h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
455 *ptr = base[2 + h];
456 base[2 + h] = sym_index;
457 base[1]++;
458 /* we resize the hash table */
459 hs->nb_hashed_syms++;
460 if (hs->nb_hashed_syms > 2 * nbuckets) {
461 rebuild_hash(s, 2 * nbuckets);
463 } else {
464 *ptr = 0;
465 base[1]++;
468 return sym_index;
471 ST_FUNC int find_elf_sym(Section *s, const char *name)
473 ElfW(Sym) *sym;
474 Section *hs;
475 int nbuckets, sym_index, h;
476 const char *name1;
478 hs = s->hash;
479 if (!hs)
480 return 0;
481 nbuckets = ((int *)hs->data)[0];
482 h = elf_hash((unsigned char *) name) % nbuckets;
483 sym_index = ((int *)hs->data)[2 + h];
484 while (sym_index != 0) {
485 sym = &((ElfW(Sym) *)s->data)[sym_index];
486 name1 = (char *) s->link->data + sym->st_name;
487 if (!strcmp(name, name1))
488 return sym_index;
489 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
491 return 0;
494 /* return elf symbol value, signal error if 'err' is nonzero, decorate
495 name if FORC */
496 ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
498 int sym_index;
499 ElfW(Sym) *sym;
500 char buf[256];
501 if (forc && s1->leading_underscore
502 #ifdef TCC_TARGET_PE
503 /* win32-32bit stdcall symbols always have _ already */
504 && !strchr(name, '@')
505 #endif
507 buf[0] = '_';
508 pstrcpy(buf + 1, sizeof(buf) - 1, name);
509 name = buf;
511 sym_index = find_elf_sym(s1->symtab, name);
512 sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
513 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
514 if (err)
515 tcc_error("%s not defined", name);
516 return (addr_t)-1;
518 return sym->st_value;
521 /* return elf symbol value */
522 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
524 addr_t addr = get_sym_addr(s, name, 0, 1);
525 return addr == -1 ? NULL : (void*)(uintptr_t)addr;
528 /* list elf symbol names and values */
529 ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
530 void (*symbol_cb)(void *ctx, const char *name, const void *val))
532 ElfW(Sym) *sym;
533 Section *symtab;
534 int sym_index, end_sym;
535 const char *name;
536 unsigned char sym_vis, sym_bind;
538 symtab = s->symtab;
539 end_sym = symtab->data_offset / sizeof (ElfSym);
540 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
541 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
542 if (sym->st_value) {
543 name = (char *) symtab->link->data + sym->st_name;
544 sym_bind = ELFW(ST_BIND)(sym->st_info);
545 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
546 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
547 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
552 /* list elf symbol names and values */
553 LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
554 void (*symbol_cb)(void *ctx, const char *name, const void *val))
556 list_elf_symbols(s, ctx, symbol_cb);
559 #ifndef ELF_OBJ_ONLY
560 static void
561 version_add (TCCState *s1)
563 int i;
564 ElfW(Sym) *sym;
565 ElfW(Verneed) *vn = NULL;
566 Section *symtab;
567 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
568 ElfW(Half) *versym;
569 const char *name;
571 if (0 == nb_sym_versions)
572 return;
573 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
574 versym_section->sh_entsize = sizeof(ElfW(Half));
575 versym_section->link = s1->dynsym;
577 /* add needed symbols */
578 symtab = s1->dynsym;
579 end_sym = symtab->data_offset / sizeof (ElfSym);
580 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
581 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
582 int dllindex, verndx;
583 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
584 name = (char *) symtab->link->data + sym->st_name;
585 dllindex = find_elf_sym(s1->dynsymtab_section, name);
586 verndx = (dllindex && dllindex < nb_sym_to_version)
587 ? sym_to_version[dllindex] : -1;
588 if (verndx >= 0) {
589 if (!sym_versions[verndx].out_index)
590 sym_versions[verndx].out_index = nb_versions++;
591 versym[sym_index] = sym_versions[verndx].out_index;
592 } else
593 versym[sym_index] = 0;
595 /* generate verneed section, but not when it will be empty. Some
596 dynamic linkers look at their contents even when DTVERNEEDNUM and
597 section size is zero. */
598 if (nb_versions > 2) {
599 verneed_section = new_section(s1, ".gnu.version_r",
600 SHT_GNU_verneed, SHF_ALLOC);
601 verneed_section->link = s1->dynsym->link;
602 for (i = nb_sym_versions; i-- > 0;) {
603 struct sym_version *sv = &sym_versions[i];
604 int n_same_libs = 0, prev;
605 size_t vnofs;
606 ElfW(Vernaux) *vna = 0;
607 if (sv->out_index < 1)
608 continue;
609 vnofs = section_add(verneed_section, sizeof(*vn), 1);
610 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
611 vn->vn_version = 1;
612 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
613 vn->vn_aux = sizeof (*vn);
614 do {
615 prev = sv->prev_same_lib;
616 if (sv->out_index > 0) {
617 vna = section_ptr_add(verneed_section, sizeof(*vna));
618 vna->vna_hash = elf_hash ((const unsigned char *)sv->version);
619 vna->vna_flags = 0;
620 vna->vna_other = sv->out_index;
621 sv->out_index = -2;
622 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
623 vna->vna_next = sizeof (*vna);
624 n_same_libs++;
626 if (prev >= 0)
627 sv = &sym_versions[prev];
628 } while(prev >= 0);
629 vna->vna_next = 0;
630 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
631 vn->vn_cnt = n_same_libs;
632 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
633 nb_entries++;
635 if (vn)
636 vn->vn_next = 0;
637 verneed_section->sh_info = nb_entries;
639 dt_verneednum = nb_entries;
641 #endif
643 /* add an elf symbol : check if it is already defined and patch
644 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
645 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
646 int info, int other, int shndx, const char *name)
648 TCCState *s1 = s->s1;
649 ElfW(Sym) *esym;
650 int sym_bind, sym_index, sym_type, esym_bind;
651 unsigned char sym_vis, esym_vis, new_vis;
653 sym_bind = ELFW(ST_BIND)(info);
654 sym_type = ELFW(ST_TYPE)(info);
655 sym_vis = ELFW(ST_VISIBILITY)(other);
657 if (sym_bind != STB_LOCAL) {
658 /* we search global or weak symbols */
659 sym_index = find_elf_sym(s, name);
660 if (!sym_index)
661 goto do_def;
662 esym = &((ElfW(Sym) *)s->data)[sym_index];
663 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
664 && esym->st_other == other && esym->st_shndx == shndx)
665 return sym_index;
666 if (esym->st_shndx != SHN_UNDEF) {
667 esym_bind = ELFW(ST_BIND)(esym->st_info);
668 /* propagate the most constraining visibility */
669 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
670 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
671 if (esym_vis == STV_DEFAULT) {
672 new_vis = sym_vis;
673 } else if (sym_vis == STV_DEFAULT) {
674 new_vis = esym_vis;
675 } else {
676 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
678 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
679 | new_vis;
680 other = esym->st_other; /* in case we have to patch esym */
681 if (shndx == SHN_UNDEF) {
682 /* ignore adding of undefined symbol if the
683 corresponding symbol is already defined */
684 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
685 /* global overrides weak, so patch */
686 goto do_patch;
687 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
688 /* weak is ignored if already global */
689 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
690 /* keep first-found weak definition, ignore subsequents */
691 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
692 /* ignore hidden symbols after */
693 } else if ((esym->st_shndx == SHN_COMMON
694 || esym->st_shndx == bss_section->sh_num)
695 && (shndx < SHN_LORESERVE
696 && shndx != bss_section->sh_num)) {
697 /* data symbol gets precedence over common/bss */
698 goto do_patch;
699 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
700 /* data symbol keeps precedence over common/bss */
701 } else if (s->sh_flags & SHF_DYNSYM) {
702 /* we accept that two DLL define the same symbol */
703 } else if (esym->st_other & ST_ASM_SET) {
704 /* If the existing symbol came from an asm .set
705 we can override. */
706 goto do_patch;
707 } else {
708 #if 0
709 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
710 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
711 #endif
712 tcc_error_noabort("'%s' defined twice", name);
714 } else {
715 do_patch:
716 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
717 esym->st_shndx = shndx;
718 s1->new_undef_sym = 1;
719 esym->st_value = value;
720 esym->st_size = size;
721 esym->st_other = other;
723 } else {
724 do_def:
725 sym_index = put_elf_sym(s, value, size,
726 ELFW(ST_INFO)(sym_bind, sym_type), other,
727 shndx, name);
729 return sym_index;
732 /* put relocation */
733 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
734 int type, int symbol, addr_t addend)
736 TCCState *s1 = s->s1;
737 char buf[256];
738 Section *sr;
739 ElfW_Rel *rel;
740 int jmp_slot = type == R_JMP_SLOT;
742 sr = jmp_slot ? s->relocplt : s->reloc;
743 if (!sr) {
744 /* if no relocation section, create it */
745 if (jmp_slot)
746 snprintf(buf, sizeof(buf), RELPLT_SECTION_FMT);
747 else
748 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
749 /* if the symtab is allocated, then we consider the relocation
750 are also */
751 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
752 sr->sh_entsize = sizeof(ElfW_Rel);
753 sr->link = symtab;
754 sr->sh_info = s->sh_num;
755 if (jmp_slot)
756 s->relocplt = sr;
757 else
758 s->reloc = sr;
760 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
761 rel->r_offset = offset;
762 rel->r_info = ELFW(R_INFO)(symbol, type);
763 #if SHT_RELX == SHT_RELA
764 rel->r_addend = addend;
765 #endif
766 if (SHT_RELX != SHT_RELA && addend)
767 tcc_error("non-zero addend on REL architecture");
770 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
771 int type, int symbol)
773 put_elf_reloca(symtab, s, offset, type, symbol, 0);
776 /* put stab debug information */
777 ST_FUNC void put_stabs(TCCState *s1, const char *str, int type, int other, int desc,
778 unsigned long value)
780 Stab_Sym *sym;
782 unsigned offset;
783 if (type == N_SLINE
784 && (offset = stab_section->data_offset)
785 && (sym = (Stab_Sym*)(stab_section->data + offset) - 1)
786 && sym->n_type == type
787 && sym->n_value == value) {
788 /* just update line_number in previous entry */
789 sym->n_desc = desc;
790 return;
793 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
794 if (str) {
795 sym->n_strx = put_elf_str(stab_section->link, str);
796 } else {
797 sym->n_strx = 0;
799 sym->n_type = type;
800 sym->n_other = other;
801 sym->n_desc = desc;
802 sym->n_value = value;
805 ST_FUNC void put_stabs_r(TCCState *s1, const char *str, int type, int other, int desc,
806 unsigned long value, Section *sec, int sym_index)
808 put_elf_reloc(symtab_section, stab_section,
809 stab_section->data_offset + 8,
810 sizeof ((Stab_Sym*)0)->n_value == PTR_SIZE ? R_DATA_PTR : R_DATA_32,
811 sym_index);
812 put_stabs(s1, str, type, other, desc, value);
815 ST_FUNC void put_stabn(TCCState *s1, int type, int other, int desc, int value)
817 put_stabs(s1, NULL, type, other, desc, value);
820 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
822 int n;
823 struct sym_attr *tab;
825 if (index >= s1->nb_sym_attrs) {
826 if (!alloc)
827 return s1->sym_attrs;
828 /* find immediately bigger power of 2 and reallocate array */
829 n = 1;
830 while (index >= n)
831 n *= 2;
832 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
833 s1->sym_attrs = tab;
834 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
835 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
836 s1->nb_sym_attrs = n;
838 return &s1->sym_attrs[index];
841 /* In an ELF file symbol table, the local symbols must appear below
842 the global and weak ones. Since TCC cannot sort it while generating
843 the code, we must do it after. All the relocation tables are also
844 modified to take into account the symbol table sorting */
845 static void sort_syms(TCCState *s1, Section *s)
847 int *old_to_new_syms;
848 ElfW(Sym) *new_syms;
849 int nb_syms, i;
850 ElfW(Sym) *p, *q;
851 ElfW_Rel *rel;
852 Section *sr;
853 int type, sym_index;
855 nb_syms = s->data_offset / sizeof(ElfW(Sym));
856 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
857 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
859 /* first pass for local symbols */
860 p = (ElfW(Sym) *)s->data;
861 q = new_syms;
862 for(i = 0; i < nb_syms; i++) {
863 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
864 old_to_new_syms[i] = q - new_syms;
865 *q++ = *p;
867 p++;
869 /* save the number of local symbols in section header */
870 if( s->sh_size ) /* this 'if' makes IDA happy */
871 s->sh_info = q - new_syms;
873 /* then second pass for non local symbols */
874 p = (ElfW(Sym) *)s->data;
875 for(i = 0; i < nb_syms; i++) {
876 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
877 old_to_new_syms[i] = q - new_syms;
878 *q++ = *p;
880 p++;
883 /* we copy the new symbols to the old */
884 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
885 tcc_free(new_syms);
887 /* now we modify all the relocations */
888 for(i = 1; i < s1->nb_sections; i++) {
889 sr = s1->sections[i];
890 if (sr->sh_type == SHT_RELX && sr->link == s) {
891 for_each_elem(sr, 0, rel, ElfW_Rel) {
892 sym_index = ELFW(R_SYM)(rel->r_info);
893 type = ELFW(R_TYPE)(rel->r_info);
894 sym_index = old_to_new_syms[sym_index];
895 rel->r_info = ELFW(R_INFO)(sym_index, type);
900 tcc_free(old_to_new_syms);
903 /* relocate symbol table, resolve undefined symbols if do_resolve is
904 true and output error if undefined symbol. */
905 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
907 ElfW(Sym) *sym;
908 int sym_bind, sh_num;
909 const char *name;
911 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
912 sh_num = sym->st_shndx;
913 if (sh_num == SHN_UNDEF) {
914 name = (char *) s1->symtab->link->data + sym->st_name;
915 /* Use ld.so to resolve symbol for us (for tcc -run) */
916 if (do_resolve) {
917 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
918 /* dlsym() needs the undecorated name. */
919 void *addr = dlsym(RTLD_DEFAULT, &name[s1->leading_underscore]);
920 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
921 if (addr == NULL) {
922 int i;
923 for (i = 0; i < s1->nb_loaded_dlls; i++)
924 if ((addr = dlsym(s1->loaded_dlls[i]->handle, name)))
925 break;
927 #endif
928 if (addr) {
929 sym->st_value = (addr_t) addr;
930 #ifdef DEBUG_RELOC
931 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
932 #endif
933 goto found;
935 #endif
936 /* if dynamic symbol exist, it will be used in relocate_section */
937 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
938 goto found;
939 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
940 it */
941 if (!strcmp(name, "_fp_hw"))
942 goto found;
943 /* only weak symbols are accepted to be undefined. Their
944 value is zero */
945 sym_bind = ELFW(ST_BIND)(sym->st_info);
946 if (sym_bind == STB_WEAK)
947 sym->st_value = 0;
948 else
949 tcc_error_noabort("undefined symbol '%s'", name);
950 } else if (sh_num < SHN_LORESERVE) {
951 /* add section base */
952 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
954 found: ;
958 /* relocate a given section (CPU dependent) by applying the relocations
959 in the associated relocation section */
960 ST_FUNC void relocate_section(TCCState *s1, Section *s)
962 Section *sr = s->reloc;
963 ElfW_Rel *rel;
964 ElfW(Sym) *sym;
965 int type, sym_index;
966 unsigned char *ptr;
967 addr_t tgt, addr;
969 qrel = (ElfW_Rel *)sr->data;
971 for_each_elem(sr, 0, rel, ElfW_Rel) {
972 ptr = s->data + rel->r_offset;
973 sym_index = ELFW(R_SYM)(rel->r_info);
974 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
975 type = ELFW(R_TYPE)(rel->r_info);
976 tgt = sym->st_value;
977 #if SHT_RELX == SHT_RELA
978 tgt += rel->r_addend;
979 #endif
980 addr = s->sh_addr + rel->r_offset;
981 relocate(s1, rel, type, ptr, addr, tgt);
983 /* if the relocation is allocated, we change its symbol table */
984 if (sr->sh_flags & SHF_ALLOC) {
985 sr->link = s1->dynsym;
986 if (s1->output_type == TCC_OUTPUT_DLL) {
987 size_t r = (uint8_t*)qrel - sr->data;
988 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
989 && 0 == strcmp(s->name, ".stab"))
990 r = 0; /* cannot apply 64bit relocation to 32bit value */
991 sr->data_offset = sr->sh_size = r;
996 #ifndef ELF_OBJ_ONLY
997 /* relocate relocation table in 'sr' */
998 static void relocate_rel(TCCState *s1, Section *sr)
1000 Section *s;
1001 ElfW_Rel *rel;
1003 s = s1->sections[sr->sh_info];
1004 for_each_elem(sr, 0, rel, ElfW_Rel)
1005 rel->r_offset += s->sh_addr;
1008 /* count the number of dynamic relocations so that we can reserve
1009 their space */
1010 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
1012 int count = 0;
1013 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1014 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1015 defined(TCC_TARGET_RISCV64)
1016 ElfW_Rel *rel;
1017 for_each_elem(sr, 0, rel, ElfW_Rel) {
1018 int sym_index = ELFW(R_SYM)(rel->r_info);
1019 int type = ELFW(R_TYPE)(rel->r_info);
1020 switch(type) {
1021 #if defined(TCC_TARGET_I386)
1022 case R_386_32:
1023 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
1024 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
1025 /* don't fixup unresolved (weak) symbols */
1026 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
1027 break;
1029 #elif defined(TCC_TARGET_X86_64)
1030 case R_X86_64_32:
1031 case R_X86_64_32S:
1032 case R_X86_64_64:
1033 #elif defined(TCC_TARGET_ARM)
1034 case R_ARM_ABS32:
1035 case R_ARM_TARGET1:
1036 #elif defined(TCC_TARGET_ARM64)
1037 case R_AARCH64_ABS32:
1038 case R_AARCH64_ABS64:
1039 #elif defined(TCC_TARGET_RISCV64)
1040 case R_RISCV_32:
1041 case R_RISCV_64:
1042 #endif
1043 count++;
1044 break;
1045 #if defined(TCC_TARGET_I386)
1046 case R_386_PC32:
1047 #elif defined(TCC_TARGET_X86_64)
1048 case R_X86_64_PC32:
1050 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1052 /* Hidden defined symbols can and must be resolved locally.
1053 We're misusing a PLT32 reloc for this, as that's always
1054 resolved to its address even in shared libs. */
1055 if (sym->st_shndx != SHN_UNDEF &&
1056 ELFW(ST_VISIBILITY)(sym->st_other) == STV_HIDDEN) {
1057 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PLT32);
1058 break;
1061 #elif defined(TCC_TARGET_ARM64)
1062 case R_AARCH64_PREL32:
1063 #endif
1064 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1065 count++;
1066 break;
1067 default:
1068 break;
1071 #endif
1072 return count;
1074 #endif
1076 #if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE)
1077 static void build_got(TCCState *s1)
1079 /* if no got, then create it */
1080 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1081 s1->got->sh_entsize = 4;
1082 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1083 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1084 /* keep space for _DYNAMIC pointer and two dummy got entries */
1085 section_ptr_add(s1->got, 3 * PTR_SIZE);
1088 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1089 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1090 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1091 Returns the offset of the GOT or (if any) PLT entry. */
1092 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1093 int sym_index)
1095 int need_plt_entry;
1096 const char *name;
1097 ElfW(Sym) *sym;
1098 struct sym_attr *attr;
1099 unsigned got_offset;
1100 char plt_name[100];
1101 int len;
1103 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1104 attr = get_sym_attr(s1, sym_index, 1);
1106 /* In case a function is both called and its address taken 2 GOT entries
1107 are created, one for taking the address (GOT) and the other for the PLT
1108 entry (PLTGOT). */
1109 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1110 return attr;
1112 /* create the GOT entry */
1113 got_offset = s1->got->data_offset;
1114 section_ptr_add(s1->got, PTR_SIZE);
1116 /* Create the GOT relocation that will insert the address of the object or
1117 function of interest in the GOT entry. This is a static relocation for
1118 memory output (dlsym will give us the address of symbols) and dynamic
1119 relocation otherwise (executable and DLLs). The relocation should be
1120 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1121 associated to a PLT entry) but is currently done at load time for an
1122 unknown reason. */
1124 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1125 name = (char *) symtab_section->link->data + sym->st_name;
1127 if (s1->dynsym) {
1128 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1129 /* Hack alarm. We don't want to emit dynamic symbols
1130 and symbol based relocs for STB_LOCAL symbols, but rather
1131 want to resolve them directly. At this point the symbol
1132 values aren't final yet, so we must defer this. We will later
1133 have to create a RELATIVE reloc anyway, so we misuse the
1134 relocation slot to smuggle the symbol reference until
1135 fill_local_got_entries. Not that the sym_index is
1136 relative to symtab_section, not s1->dynsym! Nevertheless
1137 we use s1->dyn_sym so that if this is the first call
1138 that got->reloc is correctly created. Also note that
1139 RELATIVE relocs are not normally created for the .got,
1140 so the types serves as a marker for later (and is retained
1141 also for the final output, which is okay because then the
1142 got is just normal data). */
1143 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1144 sym_index);
1145 } else {
1146 if (0 == attr->dyn_index)
1147 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1148 sym->st_size, sym->st_info, 0,
1149 sym->st_shndx, name);
1150 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
1151 attr->dyn_index);
1153 } else {
1154 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1155 sym_index);
1158 if (need_plt_entry) {
1159 if (!s1->plt) {
1160 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1161 SHF_ALLOC | SHF_EXECINSTR);
1162 s1->plt->sh_entsize = 4;
1165 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1167 /* create a symbol 'sym@plt' for the PLT jump vector */
1168 len = strlen(name);
1169 if (len > sizeof plt_name - 5)
1170 len = sizeof plt_name - 5;
1171 memcpy(plt_name, name, len);
1172 strcpy(plt_name + len, "@plt");
1173 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
1174 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1176 } else {
1177 attr->got_offset = got_offset;
1180 return attr;
1183 /* build GOT and PLT entries */
1184 static void build_got_entries_pass(TCCState *s1, int pass)
1186 Section *s;
1187 ElfW_Rel *rel;
1188 ElfW(Sym) *sym;
1189 int i, type, gotplt_entry, reloc_type, sym_index;
1190 struct sym_attr *attr;
1192 for(i = 1; i < s1->nb_sections; i++) {
1193 s = s1->sections[i];
1194 if (s->sh_type != SHT_RELX)
1195 continue;
1196 /* no need to handle got relocations */
1197 if (s->link != symtab_section)
1198 continue;
1199 for_each_elem(s, 0, rel, ElfW_Rel) {
1200 type = ELFW(R_TYPE)(rel->r_info);
1201 gotplt_entry = gotplt_entry_type(type);
1202 if (gotplt_entry == -1)
1203 tcc_error ("Unknown relocation type for got: %d", type);
1204 sym_index = ELFW(R_SYM)(rel->r_info);
1205 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1207 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1208 continue;
1211 /* Automatically create PLT/GOT [entry] if it is an undefined
1212 reference (resolved at runtime), or the symbol is absolute,
1213 probably created by tcc_add_symbol, and thus on 64-bit
1214 targets might be too far from application code. */
1215 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1216 if (sym->st_shndx == SHN_UNDEF) {
1217 ElfW(Sym) *esym;
1218 int dynindex;
1219 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1220 continue;
1221 /* Relocations for UNDEF symbols would normally need
1222 to be transferred into the executable or shared object.
1223 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1224 But TCC doesn't do that (at least for exes), so we
1225 need to resolve all such relocs locally. And that
1226 means PLT slots for functions in DLLs and COPY relocs for
1227 data symbols. COPY relocs were generated in
1228 bind_exe_dynsyms (and the symbol adjusted to be defined),
1229 and for functions we were generated a dynamic symbol
1230 of function type. */
1231 if (s1->dynsym) {
1232 /* dynsym isn't set for -run :-/ */
1233 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1234 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1235 if (dynindex
1236 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1237 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1238 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1239 goto jmp_slot;
1241 } else if (!(sym->st_shndx == SHN_ABS
1242 #ifndef TCC_TARGET_ARM
1243 && PTR_SIZE == 8
1244 #endif
1246 continue;
1249 #ifdef TCC_TARGET_X86_64
1250 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1251 sym->st_shndx != SHN_UNDEF &&
1252 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1253 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1254 s1->output_type == TCC_OUTPUT_EXE)) {
1255 if (pass == 0)
1256 continue;
1257 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1258 continue;
1260 #endif
1261 reloc_type = code_reloc(type);
1262 if (reloc_type == -1)
1263 tcc_error ("Unknown relocation type: %d", type);
1264 else if (reloc_type != 0) {
1265 jmp_slot:
1266 reloc_type = R_JMP_SLOT;
1267 } else
1268 reloc_type = R_GLOB_DAT;
1271 if ((pass == 0 && reloc_type == R_GLOB_DAT) ||
1272 (pass == 1 && reloc_type == R_JMP_SLOT))
1273 continue;
1275 if (!s1->got)
1276 build_got(s1);
1278 if (gotplt_entry == BUILD_GOT_ONLY)
1279 continue;
1281 attr = put_got_entry(s1, reloc_type, sym_index);
1283 if (reloc_type == R_JMP_SLOT)
1284 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1289 ST_FUNC void build_got_entries(TCCState *s1)
1291 int i;
1293 /* Two passes because R_JMP_SLOT should become first.
1294 Some targets (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1295 for (i = 0; i < 2; i++)
1296 build_got_entries_pass(s1, i);
1298 #endif
1300 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
1302 int shn = sec ? sec->sh_num : offs ? SHN_ABS : SHN_UNDEF;
1303 if (sec && offs == -1)
1304 offs = sec->data_offset;
1305 return set_elf_sym(symtab_section, offs, 0,
1306 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1309 static void add_init_array_defines(TCCState *s1, const char *section_name)
1311 Section *s;
1312 addr_t end_offset;
1313 char buf[1024];
1314 s = find_section(s1, section_name);
1315 if (!s) {
1316 end_offset = 0;
1317 s = data_section;
1318 } else {
1319 end_offset = s->data_offset;
1321 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1322 set_global_sym(s1, buf, s, 0);
1323 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1324 set_global_sym(s1, buf, s, end_offset);
1327 #ifndef TCC_TARGET_PE
1328 static void tcc_add_support(TCCState *s1, const char *filename)
1330 char buf[1024];
1331 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1332 tcc_add_file(s1, buf);
1334 #endif
1336 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1338 Section *s;
1339 s = find_section(s1, sec);
1340 s->sh_flags |= SHF_WRITE;
1341 #ifndef TCC_TARGET_PE
1342 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1343 #endif
1344 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1345 section_ptr_add(s, PTR_SIZE);
1348 #ifdef CONFIG_TCC_BCHECK
1349 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1351 if (0 == s1->do_bounds_check)
1352 return;
1353 section_ptr_add(bounds_section, sizeof(addr_t));
1355 #endif
1357 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1358 a dynamic symbol to allow so's to have one each with a different value. */
1359 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1361 int c = find_elf_sym(s1->symtab, name);
1362 if (c) {
1363 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1364 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1365 esym->st_value = offset;
1366 esym->st_shndx = s->sh_num;
1370 #ifdef CONFIG_TCC_BACKTRACE
1371 static void put_ptr(TCCState *s1, Section *s, int offs)
1373 int c;
1374 c = set_global_sym(s1, NULL, s, offs);
1375 s = data_section;
1376 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1377 section_ptr_add(s, PTR_SIZE);
1380 ST_FUNC void tcc_add_btstub(TCCState *s1)
1382 Section *s;
1383 int n, o;
1384 CString cstr;
1386 s = data_section;
1387 /* Align to PTR_SIZE */
1388 section_ptr_add(s, -s->data_offset & (PTR_SIZE - 1));
1389 o = s->data_offset;
1390 /* create (part of) a struct rt_context (see tccrun.c) */
1391 put_ptr(s1, stab_section, 0);
1392 put_ptr(s1, stab_section, -1);
1393 put_ptr(s1, stab_section->link, 0);
1394 section_ptr_add(s, 3 * PTR_SIZE);
1395 /* prog_base */
1396 #ifndef TCC_TARGET_MACHO
1397 /* XXX this relocation is wrong, it uses sym-index 0 (local,undef) */
1398 put_elf_reloc(s1->symtab, s, s->data_offset, R_DATA_PTR, 0);
1399 #endif
1400 section_ptr_add(s, PTR_SIZE);
1401 n = 2 * PTR_SIZE;
1402 #ifdef CONFIG_TCC_BCHECK
1403 if (s1->do_bounds_check) {
1404 put_ptr(s1, bounds_section, 0);
1405 n -= PTR_SIZE;
1407 #endif
1408 section_ptr_add(s, n);
1410 cstr_new(&cstr);
1411 cstr_printf(&cstr,
1412 " extern void __bt_init(),*__rt_info[],__bt_init_dll();"
1413 "__attribute__((constructor)) static void __bt_init_rt(){");
1414 #ifdef TCC_TARGET_PE
1415 if (s1->output_type == TCC_OUTPUT_DLL)
1416 #ifdef CONFIG_TCC_BCHECK
1417 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1418 #else
1419 cstr_printf(&cstr, "__bt_init_dll(0);");
1420 #endif
1421 #endif
1422 cstr_printf(&cstr, "__bt_init(__rt_info,%d);}",
1423 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1424 tcc_compile_string(s1, cstr.data);
1425 cstr_free(&cstr);
1426 set_local_sym(s1, &"___rt_info"[!s1->leading_underscore], s, o);
1428 #endif
1430 static void tcc_tcov_add_file(TCCState *s1, const char *filename)
1432 CString cstr;
1433 void *ptr;
1434 char wd[1024];
1436 if (tcov_section == NULL)
1437 return;
1438 section_ptr_add(tcov_section, 1);
1439 write32le (tcov_section->data, tcov_section->data_offset);
1441 cstr_new (&cstr);
1442 if (filename[0] == '/')
1443 cstr_printf (&cstr, "%s.tcov", filename);
1444 else {
1445 getcwd (wd, sizeof(wd));
1446 cstr_printf (&cstr, "%s/%s.tcov", wd, filename);
1448 ptr = section_ptr_add(tcov_section, cstr.size + 1);
1449 strncpy((char *)ptr, cstr.data, cstr.size);
1450 unlink((char *)ptr);
1451 #ifdef _WIN32
1452 normalize_slashes((char *)ptr);
1453 #endif
1454 cstr_free (&cstr);
1456 cstr_new(&cstr);
1457 cstr_printf(&cstr,
1458 "extern char *__tcov_data[];"
1459 "extern void __store_test_coverage ();"
1460 "__attribute__((destructor)) static void __tcov_exit() {"
1461 "__store_test_coverage(__tcov_data);"
1462 "}");
1463 tcc_compile_string(s1, cstr.data);
1464 cstr_free(&cstr);
1465 set_local_sym(s1, &"___tcov_data"[!s1->leading_underscore], tcov_section, 0);
1468 #ifndef TCC_TARGET_PE
1469 /* add tcc runtime libraries */
1470 ST_FUNC void tcc_add_runtime(TCCState *s1)
1472 s1->filetype = 0;
1473 #ifdef CONFIG_TCC_BCHECK
1474 tcc_add_bcheck(s1);
1475 #endif
1476 tcc_add_pragma_libs(s1);
1477 /* add libc */
1478 if (!s1->nostdlib) {
1479 if (s1->option_pthread)
1480 tcc_add_library_err(s1, "pthread");
1481 tcc_add_library_err(s1, "c");
1482 #ifdef TCC_LIBGCC
1483 if (!s1->static_link) {
1484 if (TCC_LIBGCC[0] == '/')
1485 tcc_add_file(s1, TCC_LIBGCC);
1486 else
1487 tcc_add_dll(s1, TCC_LIBGCC, 0);
1489 #endif
1490 #if TCC_TARGET_ARM && TARGETOS_FreeBSD
1491 tcc_add_library_err(s1, "gcc_s"); // unwind code
1492 #endif
1493 #ifdef CONFIG_TCC_BCHECK
1494 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1495 tcc_add_library_err(s1, "pthread");
1496 #if !TARGETOS_OpenBSD && !TARGETOS_NetBSD
1497 tcc_add_library_err(s1, "dl");
1498 #endif
1499 tcc_add_support(s1, "bcheck.o");
1500 if (s1->static_link)
1501 tcc_add_library_err(s1, "c");
1503 #endif
1504 #ifdef CONFIG_TCC_BACKTRACE
1505 if (s1->do_backtrace) {
1506 if (s1->output_type == TCC_OUTPUT_EXE)
1507 tcc_add_support(s1, "bt-exe.o");
1508 if (s1->output_type != TCC_OUTPUT_DLL)
1509 tcc_add_support(s1, "bt-log.o");
1510 if (s1->output_type != TCC_OUTPUT_MEMORY)
1511 tcc_add_btstub(s1);
1513 #endif
1514 if (strlen(TCC_LIBTCC1) > 0)
1515 tcc_add_support(s1, TCC_LIBTCC1);
1516 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
1517 /* add crt end if not memory output */
1518 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1519 if (s1->output_type == TCC_OUTPUT_DLL)
1520 tcc_add_crt(s1, "crtendS.o");
1521 else
1522 tcc_add_crt(s1, "crtend.o");
1523 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
1524 tcc_add_crt(s1, "crtn.o");
1525 #endif
1527 #elif !defined(TCC_TARGET_MACHO)
1528 /* add crt end if not memory output */
1529 if (s1->output_type != TCC_OUTPUT_MEMORY)
1530 tcc_add_crt(s1, "crtn.o");
1531 #endif
1534 #endif
1536 /* add various standard linker symbols (must be done after the
1537 sections are filled (for example after allocating common
1538 symbols)) */
1539 static void tcc_add_linker_symbols(TCCState *s1)
1541 char buf[1024];
1542 int i;
1543 Section *s;
1545 set_global_sym(s1, "_etext", text_section, -1);
1546 set_global_sym(s1, "_edata", data_section, -1);
1547 set_global_sym(s1, "_end", bss_section, -1);
1548 #if TARGETOS_OpenBSD
1549 set_global_sym(s1, "__executable_start", NULL, ELF_START_ADDR);
1550 #endif
1551 #ifdef TCC_TARGET_RISCV64
1552 /* XXX should be .sdata+0x800, not .data+0x800 */
1553 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1554 #endif
1555 /* horrible new standard ldscript defines */
1556 add_init_array_defines(s1, ".preinit_array");
1557 add_init_array_defines(s1, ".init_array");
1558 add_init_array_defines(s1, ".fini_array");
1559 /* add start and stop symbols for sections whose name can be
1560 expressed in C */
1561 for(i = 1; i < s1->nb_sections; i++) {
1562 s = s1->sections[i];
1563 if ((s->sh_flags & SHF_ALLOC)
1564 && (s->sh_type == SHT_PROGBITS
1565 || s->sh_type == SHT_STRTAB)) {
1566 const char *p;
1567 /* check if section name can be expressed in C */
1568 p = s->name;
1569 for(;;) {
1570 int c = *p;
1571 if (!c)
1572 break;
1573 if (!isid(c) && !isnum(c))
1574 goto next_sec;
1575 p++;
1577 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1578 set_global_sym(s1, buf, s, 0);
1579 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1580 set_global_sym(s1, buf, s, -1);
1582 next_sec: ;
1586 ST_FUNC void resolve_common_syms(TCCState *s1)
1588 ElfW(Sym) *sym;
1590 /* Allocate common symbols in BSS. */
1591 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1592 if (sym->st_shndx == SHN_COMMON) {
1593 /* symbol alignment is in st_value for SHN_COMMONs */
1594 sym->st_value = section_add(bss_section, sym->st_size,
1595 sym->st_value);
1596 sym->st_shndx = bss_section->sh_num;
1600 /* Now assign linker provided symbols their value. */
1601 tcc_add_linker_symbols(s1);
1604 #ifndef ELF_OBJ_ONLY
1606 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1608 int sym_index = ELFW(R_SYM) (rel->r_info);
1609 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1610 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1611 unsigned offset = attr->got_offset;
1613 if (0 == offset)
1614 return;
1615 section_reserve(s1->got, offset + PTR_SIZE);
1616 #if PTR_SIZE == 8
1617 write64le(s1->got->data + offset, sym->st_value);
1618 #else
1619 write32le(s1->got->data + offset, sym->st_value);
1620 #endif
1623 /* Perform relocation to GOT or PLT entries */
1624 ST_FUNC void fill_got(TCCState *s1)
1626 Section *s;
1627 ElfW_Rel *rel;
1628 int i;
1630 for(i = 1; i < s1->nb_sections; i++) {
1631 s = s1->sections[i];
1632 if (s->sh_type != SHT_RELX)
1633 continue;
1634 /* no need to handle got relocations */
1635 if (s->link != symtab_section)
1636 continue;
1637 for_each_elem(s, 0, rel, ElfW_Rel) {
1638 switch (ELFW(R_TYPE) (rel->r_info)) {
1639 case R_X86_64_GOT32:
1640 case R_X86_64_GOTPCREL:
1641 case R_X86_64_GOTPCRELX:
1642 case R_X86_64_REX_GOTPCRELX:
1643 case R_X86_64_PLT32:
1644 fill_got_entry(s1, rel);
1645 break;
1651 /* See put_got_entry for a description. This is the second stage
1652 where GOT references to local defined symbols are rewritten. */
1653 static void fill_local_got_entries(TCCState *s1)
1655 ElfW_Rel *rel;
1656 if (!s1->got->reloc)
1657 return;
1658 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1659 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1660 int sym_index = ELFW(R_SYM) (rel->r_info);
1661 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1662 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1663 unsigned offset = attr->got_offset;
1664 if (offset != rel->r_offset - s1->got->sh_addr)
1665 tcc_error_noabort("huh");
1666 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1667 #if SHT_RELX == SHT_RELA
1668 rel->r_addend = sym->st_value;
1669 #else
1670 /* All our REL architectures also happen to be 32bit LE. */
1671 write32le(s1->got->data + offset, sym->st_value);
1672 #endif
1677 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1678 in shared libraries and export non local defined symbols to shared libraries
1679 if -rdynamic switch was given on command line */
1680 static void bind_exe_dynsyms(TCCState *s1)
1682 const char *name;
1683 int sym_index, index;
1684 ElfW(Sym) *sym, *esym;
1685 int type;
1687 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1688 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1689 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1690 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1691 if (sym->st_shndx == SHN_UNDEF) {
1692 name = (char *) symtab_section->link->data + sym->st_name;
1693 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1694 if (sym_index) {
1695 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1696 type = ELFW(ST_TYPE)(esym->st_info);
1697 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1698 /* Indirect functions shall have STT_FUNC type in executable
1699 * dynsym section. Indeed, a dlsym call following a lazy
1700 * resolution would pick the symbol value from the
1701 * executable dynsym entry which would contain the address
1702 * of the function wanted by the caller of dlsym instead of
1703 * the address of the function that would return that
1704 * address */
1705 int dynindex
1706 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1707 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1708 name);
1709 int index = sym - (ElfW(Sym) *) symtab_section->data;
1710 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1711 } else if (type == STT_OBJECT) {
1712 unsigned long offset;
1713 ElfW(Sym) *dynsym;
1714 offset = bss_section->data_offset;
1715 /* XXX: which alignment ? */
1716 offset = (offset + 16 - 1) & -16;
1717 set_elf_sym (s1->symtab, offset, esym->st_size,
1718 esym->st_info, 0, bss_section->sh_num, name);
1719 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1720 esym->st_info, 0, bss_section->sh_num,
1721 name);
1723 /* Ensure R_COPY works for weak symbol aliases */
1724 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1725 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1726 if ((dynsym->st_value == esym->st_value)
1727 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1728 char *dynname = (char *) s1->dynsymtab_section->link->data
1729 + dynsym->st_name;
1730 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1731 dynsym->st_info, 0,
1732 bss_section->sh_num, dynname);
1733 break;
1738 put_elf_reloc(s1->dynsym, bss_section,
1739 offset, R_COPY, index);
1740 offset += esym->st_size;
1741 bss_section->data_offset = offset;
1743 } else {
1744 /* STB_WEAK undefined symbols are accepted */
1745 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1746 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1747 !strcmp(name, "_fp_hw")) {
1748 } else {
1749 tcc_error_noabort("undefined symbol '%s'", name);
1752 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1753 /* if -rdynamic option, then export all non local symbols */
1754 name = (char *) symtab_section->link->data + sym->st_name;
1755 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1756 0, sym->st_shndx, name);
1761 /* Bind symbols of libraries: export all non local symbols of executable that
1762 are referenced by shared libraries. The reason is that the dynamic loader
1763 search symbol first in executable and then in libraries. Therefore a
1764 reference to a symbol already defined by a library can still be resolved by
1765 a symbol in the executable. */
1766 static void bind_libs_dynsyms(TCCState *s1)
1768 const char *name;
1769 int sym_index;
1770 ElfW(Sym) *sym, *esym;
1772 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1773 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1774 sym_index = find_elf_sym(symtab_section, name);
1775 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1776 if (sym_index && sym->st_shndx != SHN_UNDEF
1777 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1778 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1779 sym->st_info, 0, sym->st_shndx, name);
1780 } else if (esym->st_shndx == SHN_UNDEF) {
1781 /* weak symbols can stay undefined */
1782 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1783 tcc_warning("undefined dynamic symbol '%s'", name);
1788 /* Export all non local symbols. This is used by shared libraries so that the
1789 non local symbols they define can resolve a reference in another shared
1790 library or in the executable. Correspondingly, it allows undefined local
1791 symbols to be resolved by other shared libraries or by the executable. */
1792 static void export_global_syms(TCCState *s1)
1794 int dynindex, index;
1795 const char *name;
1796 ElfW(Sym) *sym;
1798 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1799 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1800 name = (char *) symtab_section->link->data + sym->st_name;
1801 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1802 sym->st_info, 0, sym->st_shndx, name);
1803 index = sym - (ElfW(Sym) *) symtab_section->data;
1804 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1809 /* decide if an unallocated section should be output. */
1810 static int set_sec_sizes(TCCState *s1)
1812 int i;
1813 Section *s;
1814 int textrel = 0;
1815 int file_type = s1->output_type;
1817 /* Allocate strings for section names */
1818 for(i = 1; i < s1->nb_sections; i++) {
1819 s = s1->sections[i];
1820 if (s->sh_type == SHT_RELX && !(s->sh_flags & SHF_ALLOC)) {
1821 /* when generating a DLL, we include relocations but
1822 we may patch them */
1823 if (file_type == TCC_OUTPUT_DLL
1824 && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) {
1825 int count = prepare_dynamic_rel(s1, s);
1826 if (count) {
1827 /* allocate the section */
1828 s->sh_flags |= SHF_ALLOC;
1829 s->sh_size = count * sizeof(ElfW_Rel);
1830 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1831 textrel = 1;
1834 } else if ((s->sh_flags & SHF_ALLOC)
1835 #ifdef TCC_TARGET_ARM
1836 || s->sh_type == SHT_ARM_ATTRIBUTES
1837 #endif
1838 || s1->do_debug) {
1839 s->sh_size = s->data_offset;
1842 #ifdef TCC_TARGET_ARM
1843 /* XXX: Suppress stack unwinding section. */
1844 if (s->sh_type == SHT_ARM_EXIDX) {
1845 s->sh_flags = 0;
1846 s->sh_size = 0;
1848 #endif
1851 return textrel;
1855 /* Info to be copied in dynamic section */
1856 struct dyn_inf {
1857 Section *dynamic;
1858 Section *dynstr;
1859 unsigned long data_offset;
1860 addr_t rel_addr;
1861 addr_t rel_size;
1864 /* Info for GNU_RELRO */
1865 struct ro_inf {
1866 addr_t sh_offset;
1867 addr_t sh_addr;
1868 addr_t sh_size;
1871 static void alloc_sec_names(
1872 TCCState *s1, int is_obj
1875 static int layout_any_sections(
1876 TCCState *s1, int file_offset, int *sec_order, int is_obj
1879 /* Assign sections to segments and decide how are sections laid out when loaded
1880 in memory. This function also fills corresponding program headers. */
1881 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr,
1882 int phnum, int phfill,
1883 Section *interp,
1884 struct ro_inf *roinf, int *sec_order)
1886 int i, file_offset;
1887 Section *s;
1889 file_offset = 0;
1890 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1891 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1894 unsigned long s_align;
1895 long long tmp;
1896 addr_t addr;
1897 ElfW(Phdr) *ph;
1898 int j, k, f, file_type = s1->output_type;
1900 s_align = ELF_PAGE_SIZE;
1901 if (s1->section_align)
1902 s_align = s1->section_align;
1904 if (s1->has_text_addr) {
1905 int a_offset, p_offset;
1906 addr = s1->text_addr;
1907 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1908 ELF_PAGE_SIZE */
1909 a_offset = (int) (addr & (s_align - 1));
1910 p_offset = file_offset & (s_align - 1);
1911 if (a_offset < p_offset)
1912 a_offset += s_align;
1913 file_offset += (a_offset - p_offset);
1914 } else {
1915 if (file_type == TCC_OUTPUT_DLL)
1916 addr = 0;
1917 else
1918 addr = ELF_START_ADDR;
1919 /* compute address after headers */
1920 addr += (file_offset & (s_align - 1));
1923 ph = &phdr[0];
1924 /* Leave one program headers for the program interpreter and one for
1925 the program header table itself if needed. These are done later as
1926 they require section layout to be done first. */
1927 if (interp)
1928 ph += 2;
1930 /* read only segment mapping for GNU_RELRO */
1931 roinf->sh_offset = roinf->sh_addr = roinf->sh_size = 0;
1933 for(j = 0; j < phfill; j++) {
1934 Section *relocplt = s1->got ? s1->got->relocplt : NULL;
1936 ph->p_type = j == 2 ? PT_TLS : PT_LOAD;
1937 if (j == 0)
1938 ph->p_flags = PF_R | PF_X;
1939 else
1940 ph->p_flags = PF_R | PF_W;
1941 ph->p_align = j == 2 ? 4 : s_align;
1943 /* Decide the layout of sections loaded in memory. This must
1944 be done before program headers are filled since they contain
1945 info about the layout. We do the following ordering: interp,
1946 symbol tables, relocations, progbits, nobits */
1947 /* XXX: do faster and simpler sorting */
1948 f = -1;
1949 for(k = 0; k < 7; k++) {
1950 for(i = 1; i < s1->nb_sections; i++) {
1951 s = s1->sections[i];
1952 /* compute if section should be included */
1953 if (j == 0) {
1954 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1955 SHF_ALLOC)
1956 continue;
1957 } else if (j == 1) {
1958 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1959 (SHF_ALLOC | SHF_WRITE))
1960 continue;
1961 } else {
1962 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
1963 (SHF_ALLOC | SHF_WRITE | SHF_TLS))
1964 continue;
1966 if (s == interp) {
1967 if (k != 0)
1968 continue;
1969 } else if ((s->sh_type == SHT_DYNSYM ||
1970 s->sh_type == SHT_STRTAB ||
1971 s->sh_type == SHT_HASH)
1972 && !strstr(s->name, ".stab")) {
1973 if (k != 1)
1974 continue;
1975 } else if (s->sh_type == SHT_RELX) {
1976 if (k != 2 && s != relocplt)
1977 continue;
1978 else if (k != 3 && s == relocplt)
1979 continue;
1980 } else if (s->sh_type == SHT_NOBITS) {
1981 if (k != 6)
1982 continue;
1983 } else if (s == data_ro_section ||
1984 #ifdef CONFIG_TCC_BCHECK
1985 s == bounds_section ||
1986 s == lbounds_section ||
1987 #endif
1988 0) {
1989 if (k != 4)
1990 continue;
1991 /* Align next section on page size.
1992 This is needed to remap roinf section ro. */
1993 f = 1;
1994 } else {
1995 if (k != 5)
1996 continue;
1998 *sec_order++ = i;
2000 /* section matches: we align it and add its size */
2001 tmp = addr;
2002 if (f-- == 0)
2003 s->sh_addralign = PAGESIZE;
2004 addr = (addr + s->sh_addralign - 1) &
2005 ~(s->sh_addralign - 1);
2006 file_offset += (int) ( addr - tmp );
2007 s->sh_offset = file_offset;
2008 s->sh_addr = addr;
2010 /* update program header infos */
2011 if (ph->p_offset == 0) {
2012 ph->p_offset = file_offset;
2013 ph->p_vaddr = addr;
2014 ph->p_paddr = ph->p_vaddr;
2016 if (s == data_ro_section ||
2017 #ifdef CONFIG_TCC_BCHECK
2018 s == bounds_section ||
2019 s == lbounds_section ||
2020 #endif
2021 0) {
2022 if (roinf->sh_size == 0) {
2023 roinf->sh_offset = s->sh_offset;
2024 roinf->sh_addr = s->sh_addr;
2026 roinf->sh_size = (addr - roinf->sh_addr) + s->sh_size;
2028 addr += s->sh_size;
2029 if (s->sh_type != SHT_NOBITS)
2030 file_offset += s->sh_size;
2033 if (j == 0) {
2034 /* Make the first PT_LOAD segment include the program
2035 headers itself (and the ELF header as well), it'll
2036 come out with same memory use but will make various
2037 tools like binutils strip work better. */
2038 ph->p_offset &= ~(ph->p_align - 1);
2039 ph->p_vaddr &= ~(ph->p_align - 1);
2040 ph->p_paddr &= ~(ph->p_align - 1);
2042 ph->p_filesz = file_offset - ph->p_offset;
2043 ph->p_memsz = addr - ph->p_vaddr;
2044 ph++;
2045 if (j == 0) {
2046 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
2047 /* if in the middle of a page, we duplicate the page in
2048 memory so that one copy is RX and the other is RW */
2049 if ((addr & (s_align - 1)) != 0)
2050 addr += s_align;
2051 } else {
2052 addr = (addr + s_align - 1) & ~(s_align - 1);
2053 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
2059 /* all other sections come after */
2060 return layout_any_sections(s1, file_offset, sec_order, 0);
2063 /* put dynamic tag */
2064 static void put_dt(Section *dynamic, int dt, addr_t val)
2066 ElfW(Dyn) *dyn;
2067 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
2068 dyn->d_tag = dt;
2069 dyn->d_un.d_val = val;
2072 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
2073 Section *dynamic, Section *note, struct ro_inf *roinf)
2075 ElfW(Phdr) *ph;
2077 /* if interpreter, then add corresponding program header */
2078 if (interp) {
2079 ph = &phdr[0];
2081 ph->p_type = PT_PHDR;
2082 ph->p_offset = sizeof(ElfW(Ehdr));
2083 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
2084 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
2085 ph->p_paddr = ph->p_vaddr;
2086 ph->p_flags = PF_R | PF_X;
2087 ph->p_align = 4; /* interp->sh_addralign; */
2088 ph++;
2090 ph->p_type = PT_INTERP;
2091 ph->p_offset = interp->sh_offset;
2092 ph->p_vaddr = interp->sh_addr;
2093 ph->p_paddr = ph->p_vaddr;
2094 ph->p_filesz = interp->sh_size;
2095 ph->p_memsz = interp->sh_size;
2096 ph->p_flags = PF_R;
2097 ph->p_align = interp->sh_addralign;
2100 if (note) {
2101 ph = &phdr[phnum - 2 - (roinf != NULL)];
2103 ph->p_type = PT_NOTE;
2104 ph->p_offset = note->sh_offset;
2105 ph->p_vaddr = note->sh_addr;
2106 ph->p_paddr = ph->p_vaddr;
2107 ph->p_filesz = note->sh_size;
2108 ph->p_memsz = note->sh_size;
2109 ph->p_flags = PF_R;
2110 ph->p_align = note->sh_addralign;
2113 /* if dynamic section, then add corresponding program header */
2114 if (dynamic) {
2115 ph = &phdr[phnum - 1 - (roinf != NULL)];
2117 ph->p_type = PT_DYNAMIC;
2118 ph->p_offset = dynamic->sh_offset;
2119 ph->p_vaddr = dynamic->sh_addr;
2120 ph->p_paddr = ph->p_vaddr;
2121 ph->p_filesz = dynamic->sh_size;
2122 ph->p_memsz = dynamic->sh_size;
2123 ph->p_flags = PF_R | PF_W;
2124 ph->p_align = dynamic->sh_addralign;
2127 if (roinf) {
2128 ph = &phdr[phnum - 1];
2130 ph->p_type = PT_GNU_RELRO;
2131 ph->p_offset = roinf->sh_offset;
2132 ph->p_vaddr = roinf->sh_addr;
2133 ph->p_paddr = ph->p_vaddr;
2134 ph->p_filesz = roinf->sh_size;
2135 ph->p_memsz = roinf->sh_size;
2136 ph->p_flags = PF_R;
2137 ph->p_align = 1;
2141 /* Fill the dynamic section with tags describing the address and size of
2142 sections */
2143 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2145 Section *dynamic = dyninf->dynamic;
2146 Section *s;
2148 /* put dynamic section entries */
2149 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2150 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2151 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2152 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2153 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2154 #if PTR_SIZE == 8
2155 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2156 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2157 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2158 if (s1->got && s1->got->relocplt) {
2159 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2160 put_dt(dynamic, DT_PLTRELSZ, s1->got->relocplt->data_offset);
2161 put_dt(dynamic, DT_JMPREL, s1->got->relocplt->sh_addr);
2162 put_dt(dynamic, DT_PLTREL, DT_RELA);
2164 put_dt(dynamic, DT_RELACOUNT, 0);
2165 #else
2166 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2167 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2168 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2169 if (s1->got && s1->got->relocplt) {
2170 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2171 put_dt(dynamic, DT_PLTRELSZ, s1->got->relocplt->data_offset);
2172 put_dt(dynamic, DT_JMPREL, s1->got->relocplt->sh_addr);
2173 put_dt(dynamic, DT_PLTREL, DT_REL);
2175 put_dt(dynamic, DT_RELCOUNT, 0);
2176 #endif
2177 if (versym_section && verneed_section) {
2178 /* The dynamic linker can not handle VERSYM without VERNEED */
2179 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2180 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2181 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2183 s = find_section_create (s1, ".preinit_array", 0);
2184 if (s && s->data_offset) {
2185 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2186 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2188 s = find_section_create (s1, ".init_array", 0);
2189 if (s && s->data_offset) {
2190 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2191 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2193 s = find_section_create (s1, ".fini_array", 0);
2194 if (s && s->data_offset) {
2195 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2196 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2198 s = find_section_create (s1, ".init", 0);
2199 if (s && s->data_offset) {
2200 put_dt(dynamic, DT_INIT, s->sh_addr);
2202 s = find_section_create (s1, ".fini", 0);
2203 if (s && s->data_offset) {
2204 put_dt(dynamic, DT_FINI, s->sh_addr);
2206 if (s1->do_debug)
2207 put_dt(dynamic, DT_DEBUG, 0);
2208 put_dt(dynamic, DT_NULL, 0);
2211 /* Relocate remaining sections and symbols (that is those not related to
2212 dynamic linking) */
2213 static int final_sections_reloc(TCCState *s1)
2215 int i;
2216 Section *s;
2218 relocate_syms(s1, s1->symtab, 0);
2220 if (s1->nb_errors != 0)
2221 return -1;
2223 /* relocate sections */
2224 /* XXX: ignore sections with allocated relocations ? */
2225 for(i = 1; i < s1->nb_sections; i++) {
2226 s = s1->sections[i];
2227 if (s->reloc && (s != s1->got || s1->static_link))
2228 relocate_section(s1, s);
2231 /* relocate relocation entries if the relocation tables are
2232 allocated in the executable */
2233 for(i = 1; i < s1->nb_sections; i++) {
2234 s = s1->sections[i];
2235 if ((s->sh_flags & SHF_ALLOC) &&
2236 s->sh_type == SHT_RELX) {
2237 relocate_rel(s1, s);
2240 return 0;
2243 /* Remove gaps between RELX sections.
2244 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2245 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2246 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2247 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2248 static void update_reloc_sections(TCCState *s1, struct dyn_inf *dyninf)
2250 int i;
2251 unsigned long file_offset = 0;
2252 Section *s;
2253 Section *relocplt = s1->got ? s1->got->relocplt : NULL;
2255 /* dynamic relocation table information, for .dynamic section */
2256 dyninf->rel_addr = dyninf->rel_size = 0;
2258 for(i = 1; i < s1->nb_sections; i++) {
2259 s = s1->sections[i];
2260 if (s->sh_type == SHT_RELX && s != relocplt) {
2261 if (dyninf->rel_size == 0) {
2262 dyninf->rel_addr = s->sh_addr;
2263 file_offset = s->sh_offset;
2265 else {
2266 s->sh_addr = dyninf->rel_addr + dyninf->rel_size;
2267 s->sh_offset = file_offset + dyninf->rel_size;
2269 dyninf->rel_size += s->sh_size;
2274 #endif /* ndef ELF_OBJ_ONLY */
2276 /* Create an ELF file on disk.
2277 This function handle ELF specific layout requirements */
2278 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2279 int file_offset, int *sec_order)
2281 int i, shnum, offset, size, file_type;
2282 Section *s;
2283 ElfW(Ehdr) ehdr;
2284 ElfW(Shdr) shdr, *sh;
2286 file_type = s1->output_type;
2287 shnum = s1->nb_sections;
2289 memset(&ehdr, 0, sizeof(ehdr));
2291 if (phnum > 0) {
2292 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2293 ehdr.e_phnum = phnum;
2294 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2297 /* align to 4 */
2298 file_offset = (file_offset + 3) & -4;
2300 /* fill header */
2301 ehdr.e_ident[0] = ELFMAG0;
2302 ehdr.e_ident[1] = ELFMAG1;
2303 ehdr.e_ident[2] = ELFMAG2;
2304 ehdr.e_ident[3] = ELFMAG3;
2305 ehdr.e_ident[4] = ELFCLASSW;
2306 ehdr.e_ident[5] = ELFDATA2LSB;
2307 ehdr.e_ident[6] = EV_CURRENT;
2308 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2309 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2310 #endif
2311 #ifdef TCC_TARGET_ARM
2312 #ifdef TCC_ARM_EABI
2313 ehdr.e_ident[EI_OSABI] = 0;
2314 ehdr.e_flags = EF_ARM_EABI_VER4;
2315 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2316 ehdr.e_flags |= EF_ARM_HASENTRY;
2317 if (s1->float_abi == ARM_HARD_FLOAT)
2318 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2319 else
2320 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2321 #else
2322 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2323 #endif
2324 #elif defined TCC_TARGET_RISCV64
2325 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2326 #endif
2327 switch(file_type) {
2328 default:
2329 case TCC_OUTPUT_EXE:
2330 ehdr.e_type = ET_EXEC;
2331 ehdr.e_entry = get_sym_addr(s1, "_start", 1, 0);
2332 break;
2333 case TCC_OUTPUT_DLL:
2334 ehdr.e_type = ET_DYN;
2335 ehdr.e_entry = text_section->sh_addr; /* 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 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2351 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2353 sort_syms(s1, symtab_section);
2354 for(i = 1; i < s1->nb_sections; i++) {
2355 s = s1->sections[sec_order[i]];
2356 if (s->sh_type != SHT_NOBITS) {
2357 while (offset < s->sh_offset) {
2358 fputc(0, f);
2359 offset++;
2361 size = s->sh_size;
2362 if (size)
2363 fwrite(s->data, 1, size, f);
2364 offset += size;
2368 /* output section headers */
2369 while (offset < ehdr.e_shoff) {
2370 fputc(0, f);
2371 offset++;
2374 for(i = 0; i < s1->nb_sections; i++) {
2375 sh = &shdr;
2376 memset(sh, 0, sizeof(ElfW(Shdr)));
2377 s = s1->sections[i];
2378 if (s) {
2379 sh->sh_name = s->sh_name;
2380 sh->sh_type = s->sh_type;
2381 sh->sh_flags = s->sh_flags;
2382 sh->sh_entsize = s->sh_entsize;
2383 sh->sh_info = s->sh_info;
2384 if (s->link)
2385 sh->sh_link = s->link->sh_num;
2386 sh->sh_addralign = s->sh_addralign;
2387 sh->sh_addr = s->sh_addr;
2388 sh->sh_offset = s->sh_offset;
2389 sh->sh_size = s->sh_size;
2391 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2395 static void tcc_output_binary(TCCState *s1, FILE *f,
2396 const int *sec_order)
2398 Section *s;
2399 int i, offset, size;
2401 offset = 0;
2402 for(i=1;i<s1->nb_sections;i++) {
2403 s = s1->sections[sec_order[i]];
2404 if (s->sh_type != SHT_NOBITS &&
2405 (s->sh_flags & SHF_ALLOC)) {
2406 while (offset < s->sh_offset) {
2407 fputc(0, f);
2408 offset++;
2410 size = s->sh_size;
2411 fwrite(s->data, 1, size, f);
2412 offset += size;
2417 /* Write an elf, coff or "binary" file */
2418 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2419 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2421 int fd, mode, file_type;
2422 FILE *f;
2424 file_type = s1->output_type;
2425 if (file_type == TCC_OUTPUT_OBJ)
2426 mode = 0666;
2427 else
2428 mode = 0777;
2429 unlink(filename);
2430 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2431 if (fd < 0) {
2432 tcc_error_noabort("could not write '%s'", filename);
2433 return -1;
2435 f = fdopen(fd, "wb");
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 ret = final_sections_reloc(s1);
2728 if (ret)
2729 goto the_end;
2730 if (dynamic) {
2731 update_reloc_sections (s1, &dyninf);
2732 dynamic->data_offset = dyninf.data_offset;
2733 fill_dynamic(s1, &dyninf);
2735 tidy_section_headers(s1, sec_order);
2737 /* Perform relocation to GOT or PLT entries */
2738 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2739 fill_got(s1);
2740 else if (s1->got)
2741 fill_local_got_entries(s1);
2743 /* Create the ELF file with name 'filename' */
2744 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2745 s1->nb_sections = shnum;
2747 the_end:
2748 tcc_free(sec_order);
2749 tcc_free(phdr);
2750 return ret;
2752 #endif /* ndef ELF_OBJ_ONLY */
2754 /* Allocate strings for section names */
2755 static void alloc_sec_names(TCCState *s1, int is_obj)
2757 int i;
2758 Section *s, *strsec;
2760 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2761 put_elf_str(strsec, "");
2762 for(i = 1; i < s1->nb_sections; i++) {
2763 s = s1->sections[i];
2764 if (is_obj)
2765 s->sh_size = s->data_offset;
2766 if (s == strsec || s->sh_size || (s->sh_flags & SHF_ALLOC))
2767 s->sh_name = put_elf_str(strsec, s->name);
2769 strsec->sh_size = strsec->data_offset;
2772 static int layout_any_sections(TCCState *s1, int file_offset, int *sec_order, int is_obj)
2774 int i;
2775 Section *s;
2776 for(i = 1; i < s1->nb_sections; i++) {
2777 s = s1->sections[i];
2778 if (!is_obj && (s->sh_flags & SHF_ALLOC))
2779 continue;
2780 *sec_order++ = i;
2781 file_offset = (file_offset + s->sh_addralign - 1) &
2782 ~(s->sh_addralign - 1);
2783 s->sh_offset = file_offset;
2784 if (s->sh_type != SHT_NOBITS)
2785 file_offset += s->sh_size;
2787 return file_offset;
2790 /* Output an elf .o file */
2791 static int elf_output_obj(TCCState *s1, const char *filename)
2793 int ret, file_offset;
2794 int *sec_order;
2795 s1->nb_errors = 0;
2797 /* Allocate strings for section names */
2798 alloc_sec_names(s1, 1);
2800 /* this array is used to reorder sections in the output file */
2801 sec_order = tcc_malloc(sizeof(int) * s1->nb_sections);
2802 sec_order[0] = 0;
2803 file_offset = layout_any_sections(s1, sizeof (ElfW(Ehdr)), sec_order + 1, 1);
2805 /* Create the ELF file with name 'filename' */
2806 ret = tcc_write_elf_file(s1, filename, 0, NULL, file_offset, sec_order);
2807 tcc_free(sec_order);
2808 return ret;
2811 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2813 if (s->test_coverage)
2814 tcc_tcov_add_file(s, filename);
2815 if (s->output_type == TCC_OUTPUT_OBJ)
2816 return elf_output_obj(s, filename);
2817 #ifdef TCC_TARGET_PE
2818 return pe_output_file(s, filename);
2819 #elif TCC_TARGET_MACHO
2820 return macho_output_file(s, filename);
2821 #else
2822 return elf_output_file(s, filename);
2823 #endif
2826 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
2827 char *cbuf = buf;
2828 size_t rnum = 0;
2829 while (1) {
2830 ssize_t num = read(fd, cbuf, count-rnum);
2831 if (num < 0) return num;
2832 if (num == 0) return rnum;
2833 rnum += num;
2834 cbuf += num;
2838 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
2840 void *data;
2842 data = tcc_malloc(size);
2843 lseek(fd, file_offset, SEEK_SET);
2844 full_read(fd, data, size);
2845 return data;
2848 typedef struct SectionMergeInfo {
2849 Section *s; /* corresponding existing section */
2850 unsigned long offset; /* offset of the new section in the existing section */
2851 uint8_t new_section; /* true if section 's' was added */
2852 uint8_t link_once; /* true if link once section */
2853 } SectionMergeInfo;
2855 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2857 int size = full_read(fd, h, sizeof *h);
2858 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2859 if (h->e_type == ET_REL)
2860 return AFF_BINTYPE_REL;
2861 if (h->e_type == ET_DYN)
2862 return AFF_BINTYPE_DYN;
2863 } else if (size >= 8) {
2864 if (0 == memcmp(h, ARMAG, 8))
2865 return AFF_BINTYPE_AR;
2866 #ifdef TCC_TARGET_COFF
2867 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2868 return AFF_BINTYPE_C67;
2869 #endif
2871 return 0;
2874 /* load an object file and merge it with current files */
2875 /* XXX: handle correctly stab (debug) info */
2876 ST_FUNC int tcc_load_object_file(TCCState *s1,
2877 int fd, unsigned long file_offset)
2879 ElfW(Ehdr) ehdr;
2880 ElfW(Shdr) *shdr, *sh;
2881 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2882 char *strsec, *strtab;
2883 int stab_index, stabstr_index;
2884 int *old_to_new_syms;
2885 char *sh_name, *name;
2886 SectionMergeInfo *sm_table, *sm;
2887 ElfW(Sym) *sym, *symtab;
2888 ElfW_Rel *rel;
2889 Section *s;
2891 lseek(fd, file_offset, SEEK_SET);
2892 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2893 goto fail1;
2894 /* test CPU specific stuff */
2895 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2896 ehdr.e_machine != EM_TCC_TARGET) {
2897 fail1:
2898 tcc_error_noabort("invalid object file");
2899 return -1;
2901 /* read sections */
2902 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2903 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2904 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2906 /* load section names */
2907 sh = &shdr[ehdr.e_shstrndx];
2908 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2910 /* load symtab and strtab */
2911 old_to_new_syms = NULL;
2912 symtab = NULL;
2913 strtab = NULL;
2914 nb_syms = 0;
2915 seencompressed = 0;
2916 stab_index = stabstr_index = 0;
2918 for(i = 1; i < ehdr.e_shnum; i++) {
2919 sh = &shdr[i];
2920 if (sh->sh_type == SHT_SYMTAB) {
2921 if (symtab) {
2922 tcc_error_noabort("object must contain only one symtab");
2923 fail:
2924 ret = -1;
2925 goto the_end;
2927 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2928 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2929 sm_table[i].s = symtab_section;
2931 /* now load strtab */
2932 sh = &shdr[sh->sh_link];
2933 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2935 if (sh->sh_flags & SHF_COMPRESSED)
2936 seencompressed = 1;
2939 /* now examine each section and try to merge its content with the
2940 ones in memory */
2941 for(i = 1; i < ehdr.e_shnum; i++) {
2942 /* no need to examine section name strtab */
2943 if (i == ehdr.e_shstrndx)
2944 continue;
2945 sh = &shdr[i];
2946 if (sh->sh_type == SHT_RELX)
2947 sh = &shdr[sh->sh_info];
2948 /* ignore sections types we do not handle (plus relocs to those) */
2949 if (sh->sh_type != SHT_PROGBITS &&
2950 #ifdef TCC_ARM_EABI
2951 sh->sh_type != SHT_ARM_EXIDX &&
2952 #endif
2953 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2954 sh->sh_type != SHT_X86_64_UNWIND &&
2955 #endif
2956 sh->sh_type != SHT_NOTE &&
2957 sh->sh_type != SHT_NOBITS &&
2958 sh->sh_type != SHT_PREINIT_ARRAY &&
2959 sh->sh_type != SHT_INIT_ARRAY &&
2960 sh->sh_type != SHT_FINI_ARRAY &&
2961 strcmp(strsec + sh->sh_name, ".stabstr")
2963 continue;
2964 if (seencompressed
2965 && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
2966 continue;
2968 sh = &shdr[i];
2969 sh_name = strsec + sh->sh_name;
2970 if (sh->sh_addralign < 1)
2971 sh->sh_addralign = 1;
2972 /* find corresponding section, if any */
2973 for(j = 1; j < s1->nb_sections;j++) {
2974 s = s1->sections[j];
2975 if (!strcmp(s->name, sh_name)) {
2976 if (!strncmp(sh_name, ".gnu.linkonce",
2977 sizeof(".gnu.linkonce") - 1)) {
2978 /* if a 'linkonce' section is already present, we
2979 do not add it again. It is a little tricky as
2980 symbols can still be defined in
2981 it. */
2982 sm_table[i].link_once = 1;
2983 goto next;
2985 if (stab_section) {
2986 if (s == stab_section)
2987 stab_index = i;
2988 if (s == stab_section->link)
2989 stabstr_index = i;
2991 goto found;
2994 /* not found: create new section */
2995 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2996 /* take as much info as possible from the section. sh_link and
2997 sh_info will be updated later */
2998 s->sh_addralign = sh->sh_addralign;
2999 s->sh_entsize = sh->sh_entsize;
3000 sm_table[i].new_section = 1;
3001 found:
3002 if (sh->sh_type != s->sh_type) {
3003 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3004 if (strcmp (s->name, ".eh_frame"))
3005 #endif
3007 tcc_error_noabort("invalid section type");
3008 goto fail;
3011 /* align start of section */
3012 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
3013 if (sh->sh_addralign > s->sh_addralign)
3014 s->sh_addralign = sh->sh_addralign;
3015 sm_table[i].offset = s->data_offset;
3016 sm_table[i].s = s;
3017 /* concatenate sections */
3018 size = sh->sh_size;
3019 if (sh->sh_type != SHT_NOBITS) {
3020 unsigned char *ptr;
3021 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
3022 ptr = section_ptr_add(s, size);
3023 full_read(fd, ptr, size);
3024 } else {
3025 s->data_offset += size;
3027 next: ;
3030 /* gr relocate stab strings */
3031 if (stab_index && stabstr_index) {
3032 Stab_Sym *a, *b;
3033 unsigned o;
3034 s = sm_table[stab_index].s;
3035 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
3036 b = (Stab_Sym *)(s->data + s->data_offset);
3037 o = sm_table[stabstr_index].offset;
3038 while (a < b) {
3039 if (a->n_strx)
3040 a->n_strx += o;
3041 a++;
3045 /* second short pass to update sh_link and sh_info fields of new
3046 sections */
3047 for(i = 1; i < ehdr.e_shnum; i++) {
3048 s = sm_table[i].s;
3049 if (!s || !sm_table[i].new_section)
3050 continue;
3051 sh = &shdr[i];
3052 if (sh->sh_link > 0)
3053 s->link = sm_table[sh->sh_link].s;
3054 if (sh->sh_type == SHT_RELX) {
3055 s->sh_info = sm_table[sh->sh_info].s->sh_num;
3056 /* update backward link */
3057 s1->sections[s->sh_info]->reloc = s;
3061 /* resolve symbols */
3062 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
3064 sym = symtab + 1;
3065 for(i = 1; i < nb_syms; i++, sym++) {
3066 if (sym->st_shndx != SHN_UNDEF &&
3067 sym->st_shndx < SHN_LORESERVE) {
3068 sm = &sm_table[sym->st_shndx];
3069 if (sm->link_once) {
3070 /* if a symbol is in a link once section, we use the
3071 already defined symbol. It is very important to get
3072 correct relocations */
3073 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
3074 name = strtab + sym->st_name;
3075 sym_index = find_elf_sym(symtab_section, name);
3076 if (sym_index)
3077 old_to_new_syms[i] = sym_index;
3079 continue;
3081 /* if no corresponding section added, no need to add symbol */
3082 if (!sm->s)
3083 continue;
3084 /* convert section number */
3085 sym->st_shndx = sm->s->sh_num;
3086 /* offset value */
3087 sym->st_value += sm->offset;
3089 /* add symbol */
3090 name = strtab + sym->st_name;
3091 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
3092 sym->st_info, sym->st_other,
3093 sym->st_shndx, name);
3094 old_to_new_syms[i] = sym_index;
3097 /* third pass to patch relocation entries */
3098 for(i = 1; i < ehdr.e_shnum; i++) {
3099 s = sm_table[i].s;
3100 if (!s)
3101 continue;
3102 sh = &shdr[i];
3103 offset = sm_table[i].offset;
3104 size = sh->sh_size;
3105 switch(s->sh_type) {
3106 case SHT_RELX:
3107 /* take relocation offset information */
3108 offseti = sm_table[sh->sh_info].offset;
3109 for (rel = (ElfW_Rel *) s->data + (offset / sizeof(*rel));
3110 rel < (ElfW_Rel *) s->data + ((offset + size) / sizeof(*rel));
3111 rel++) {
3112 int type;
3113 unsigned sym_index;
3114 /* convert symbol index */
3115 type = ELFW(R_TYPE)(rel->r_info);
3116 sym_index = ELFW(R_SYM)(rel->r_info);
3117 /* NOTE: only one symtab assumed */
3118 if (sym_index >= nb_syms)
3119 goto invalid_reloc;
3120 sym_index = old_to_new_syms[sym_index];
3121 /* ignore link_once in rel section. */
3122 if (!sym_index && !sm_table[sh->sh_info].link_once
3123 #ifdef TCC_TARGET_ARM
3124 && type != R_ARM_V4BX
3125 #elif defined TCC_TARGET_RISCV64
3126 && type != R_RISCV_ALIGN
3127 && type != R_RISCV_RELAX
3128 #endif
3130 invalid_reloc:
3131 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3132 i, strsec + sh->sh_name, (int)rel->r_offset);
3133 goto fail;
3135 rel->r_info = ELFW(R_INFO)(sym_index, type);
3136 /* offset the relocation offset */
3137 rel->r_offset += offseti;
3138 #ifdef TCC_TARGET_ARM
3139 /* Jumps and branches from a Thumb code to a PLT entry need
3140 special handling since PLT entries are ARM code.
3141 Unconditional bl instructions referencing PLT entries are
3142 handled by converting these instructions into blx
3143 instructions. Other case of instructions referencing a PLT
3144 entry require to add a Thumb stub before the PLT entry to
3145 switch to ARM mode. We set bit plt_thumb_stub of the
3146 attribute of a symbol to indicate such a case. */
3147 if (type == R_ARM_THM_JUMP24)
3148 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
3149 #endif
3151 break;
3152 default:
3153 break;
3157 ret = 0;
3158 the_end:
3159 tcc_free(symtab);
3160 tcc_free(strtab);
3161 tcc_free(old_to_new_syms);
3162 tcc_free(sm_table);
3163 tcc_free(strsec);
3164 tcc_free(shdr);
3165 return ret;
3168 typedef struct ArchiveHeader {
3169 char ar_name[16]; /* name of this member */
3170 char ar_date[12]; /* file mtime */
3171 char ar_uid[6]; /* owner uid; printed as decimal */
3172 char ar_gid[6]; /* owner gid; printed as decimal */
3173 char ar_mode[8]; /* file mode, printed as octal */
3174 char ar_size[10]; /* file size, printed as decimal */
3175 char ar_fmag[2]; /* should contain ARFMAG */
3176 } ArchiveHeader;
3178 #define ARFMAG "`\n"
3180 static unsigned long long get_be(const uint8_t *b, int n)
3182 unsigned long long ret = 0;
3183 while (n)
3184 ret = (ret << 8) | *b++, --n;
3185 return ret;
3188 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
3190 char *p, *e;
3191 int len;
3192 lseek(fd, offset, SEEK_SET);
3193 len = full_read(fd, hdr, sizeof(ArchiveHeader));
3194 if (len != sizeof(ArchiveHeader))
3195 return len ? -1 : 0;
3196 p = hdr->ar_name;
3197 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
3198 --e;
3199 *e = '\0';
3200 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
3201 return len;
3204 /* load only the objects which resolve undefined symbols */
3205 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
3207 int i, bound, nsyms, sym_index, len, ret = -1;
3208 unsigned long long off;
3209 uint8_t *data;
3210 const char *ar_names, *p;
3211 const uint8_t *ar_index;
3212 ElfW(Sym) *sym;
3213 ArchiveHeader hdr;
3215 data = tcc_malloc(size);
3216 if (full_read(fd, data, size) != size)
3217 goto the_end;
3218 nsyms = get_be(data, entrysize);
3219 ar_index = data + entrysize;
3220 ar_names = (char *) ar_index + nsyms * entrysize;
3222 do {
3223 bound = 0;
3224 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
3225 Section *s = symtab_section;
3226 sym_index = find_elf_sym(s, p);
3227 if (!sym_index)
3228 continue;
3229 sym = &((ElfW(Sym) *)s->data)[sym_index];
3230 if(sym->st_shndx != SHN_UNDEF)
3231 continue;
3232 off = get_be(ar_index + i * entrysize, entrysize);
3233 len = read_ar_header(fd, off, &hdr);
3234 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
3235 tcc_error_noabort("invalid archive");
3236 goto the_end;
3238 off += len;
3239 if (s1->verbose == 2)
3240 printf(" -> %s\n", hdr.ar_name);
3241 if (tcc_load_object_file(s1, fd, off) < 0)
3242 goto the_end;
3243 ++bound;
3245 } while(bound);
3246 ret = 0;
3247 the_end:
3248 tcc_free(data);
3249 return ret;
3252 /* load a '.a' file */
3253 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
3255 ArchiveHeader hdr;
3256 /* char magic[8]; */
3257 int size, len;
3258 unsigned long file_offset;
3259 ElfW(Ehdr) ehdr;
3261 /* skip magic which was already checked */
3262 /* full_read(fd, magic, sizeof(magic)); */
3263 file_offset = sizeof ARMAG - 1;
3265 for(;;) {
3266 len = read_ar_header(fd, file_offset, &hdr);
3267 if (len == 0)
3268 return 0;
3269 if (len < 0) {
3270 tcc_error_noabort("invalid archive");
3271 return -1;
3273 file_offset += len;
3274 size = strtol(hdr.ar_size, NULL, 0);
3275 /* align to even */
3276 size = (size + 1) & ~1;
3277 if (alacarte) {
3278 /* coff symbol table : we handle it */
3279 if (!strcmp(hdr.ar_name, "/"))
3280 return tcc_load_alacarte(s1, fd, size, 4);
3281 if (!strcmp(hdr.ar_name, "/SYM64/"))
3282 return tcc_load_alacarte(s1, fd, size, 8);
3283 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3284 if (s1->verbose == 2)
3285 printf(" -> %s\n", hdr.ar_name);
3286 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3287 return -1;
3289 file_offset += size;
3293 #ifndef ELF_OBJ_ONLY
3294 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3295 LV, maybe create a new entry for (LIB,VERSION). */
3296 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3298 while (i >= *n) {
3299 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3300 (*lv)[(*n)++] = -1;
3302 if ((*lv)[i] == -1) {
3303 int v, prev_same_lib = -1;
3304 for (v = 0; v < nb_sym_versions; v++) {
3305 if (strcmp(sym_versions[v].lib, lib))
3306 continue;
3307 prev_same_lib = v;
3308 if (!strcmp(sym_versions[v].version, version))
3309 break;
3311 if (v == nb_sym_versions) {
3312 sym_versions = tcc_realloc (sym_versions,
3313 (v + 1) * sizeof(*sym_versions));
3314 sym_versions[v].lib = tcc_strdup(lib);
3315 sym_versions[v].version = tcc_strdup(version);
3316 sym_versions[v].out_index = 0;
3317 sym_versions[v].prev_same_lib = prev_same_lib;
3318 nb_sym_versions++;
3320 (*lv)[i] = v;
3324 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3325 VERNDX. */
3326 static void
3327 set_sym_version(TCCState *s1, int sym_index, int verndx)
3329 if (sym_index >= nb_sym_to_version) {
3330 int newelems = sym_index ? sym_index * 2 : 1;
3331 sym_to_version = tcc_realloc(sym_to_version,
3332 newelems * sizeof(*sym_to_version));
3333 memset(sym_to_version + nb_sym_to_version, -1,
3334 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3335 nb_sym_to_version = newelems;
3337 if (sym_to_version[sym_index] < 0)
3338 sym_to_version[sym_index] = verndx;
3341 struct versym_info {
3342 int nb_versyms;
3343 ElfW(Verdef) *verdef;
3344 ElfW(Verneed) *verneed;
3345 ElfW(Half) *versym;
3346 int nb_local_ver, *local_ver;
3350 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3352 char *lib, *version;
3353 uint32_t next;
3354 int i;
3356 #define DEBUG_VERSION 0
3358 if (v->versym && v->verdef) {
3359 ElfW(Verdef) *vdef = v->verdef;
3360 lib = NULL;
3361 do {
3362 ElfW(Verdaux) *verdaux =
3363 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3365 #if DEBUG_VERSION
3366 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3367 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3368 vdef->vd_hash);
3369 #endif
3370 if (vdef->vd_cnt) {
3371 version = dynstr + verdaux->vda_name;
3373 if (lib == NULL)
3374 lib = version;
3375 else
3376 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3377 lib, version);
3378 #if DEBUG_VERSION
3379 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3380 #endif
3382 next = vdef->vd_next;
3383 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3384 } while (next);
3386 if (v->versym && v->verneed) {
3387 ElfW(Verneed) *vneed = v->verneed;
3388 do {
3389 ElfW(Vernaux) *vernaux =
3390 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3392 lib = dynstr + vneed->vn_file;
3393 #if DEBUG_VERSION
3394 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3395 #endif
3396 for (i = 0; i < vneed->vn_cnt; i++) {
3397 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3398 version = dynstr + vernaux->vna_name;
3399 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3400 lib, version);
3401 #if DEBUG_VERSION
3402 printf (" vernaux(%u): %u %u %s\n",
3403 vernaux->vna_other, vernaux->vna_hash,
3404 vernaux->vna_flags, version);
3405 #endif
3407 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3409 next = vneed->vn_next;
3410 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3411 } while (next);
3414 #if DEBUG_VERSION
3415 for (i = 0; i < v->nb_local_ver; i++) {
3416 if (v->local_ver[i] > 0) {
3417 printf ("%d: lib: %s, version %s\n",
3418 i, sym_versions[v->local_ver[i]].lib,
3419 sym_versions[v->local_ver[i]].version);
3422 #endif
3425 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3426 is referenced by the user (so it should be added as DT_NEEDED in
3427 the generated ELF file) */
3428 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3430 ElfW(Ehdr) ehdr;
3431 ElfW(Shdr) *shdr, *sh, *sh1;
3432 int i, j, nb_syms, nb_dts, sym_bind, ret;
3433 ElfW(Sym) *sym, *dynsym;
3434 ElfW(Dyn) *dt, *dynamic;
3436 char *dynstr;
3437 int sym_index;
3438 const char *name, *soname;
3439 DLLReference *dllref;
3440 struct versym_info v;
3442 full_read(fd, &ehdr, sizeof(ehdr));
3444 /* test CPU specific stuff */
3445 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3446 ehdr.e_machine != EM_TCC_TARGET) {
3447 tcc_error_noabort("bad architecture");
3448 return -1;
3451 /* read sections */
3452 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3454 /* load dynamic section and dynamic symbols */
3455 nb_syms = 0;
3456 nb_dts = 0;
3457 dynamic = NULL;
3458 dynsym = NULL; /* avoid warning */
3459 dynstr = NULL; /* avoid warning */
3460 memset(&v, 0, sizeof v);
3462 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3463 switch(sh->sh_type) {
3464 case SHT_DYNAMIC:
3465 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3466 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3467 break;
3468 case SHT_DYNSYM:
3469 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3470 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3471 sh1 = &shdr[sh->sh_link];
3472 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3473 break;
3474 case SHT_GNU_verdef:
3475 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3476 break;
3477 case SHT_GNU_verneed:
3478 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3479 break;
3480 case SHT_GNU_versym:
3481 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3482 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3483 break;
3484 default:
3485 break;
3489 /* compute the real library name */
3490 soname = tcc_basename(filename);
3492 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3493 if (dt->d_tag == DT_SONAME) {
3494 soname = dynstr + dt->d_un.d_val;
3498 /* if the dll is already loaded, do not load it */
3499 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3500 dllref = s1->loaded_dlls[i];
3501 if (!strcmp(soname, dllref->name)) {
3502 /* but update level if needed */
3503 if (level < dllref->level)
3504 dllref->level = level;
3505 ret = 0;
3506 goto the_end;
3510 if (v.nb_versyms != nb_syms)
3511 tcc_free (v.versym), v.versym = NULL;
3512 else
3513 store_version(s1, &v, dynstr);
3515 /* add the dll and its level */
3516 tcc_add_dllref(s1, soname)->level = level;
3518 /* add dynamic symbols in dynsym_section */
3519 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3520 sym_bind = ELFW(ST_BIND)(sym->st_info);
3521 if (sym_bind == STB_LOCAL)
3522 continue;
3523 name = dynstr + sym->st_name;
3524 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3525 sym->st_info, sym->st_other, sym->st_shndx, name);
3526 if (v.versym) {
3527 ElfW(Half) vsym = v.versym[i];
3528 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3529 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3533 /* load all referenced DLLs */
3534 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3535 switch(dt->d_tag) {
3536 case DT_NEEDED:
3537 name = dynstr + dt->d_un.d_val;
3538 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3539 dllref = s1->loaded_dlls[j];
3540 if (!strcmp(name, dllref->name))
3541 goto already_loaded;
3543 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3544 tcc_error_noabort("referenced dll '%s' not found", name);
3545 ret = -1;
3546 goto the_end;
3548 already_loaded:
3549 break;
3552 ret = 0;
3553 the_end:
3554 tcc_free(dynstr);
3555 tcc_free(dynsym);
3556 tcc_free(dynamic);
3557 tcc_free(shdr);
3558 tcc_free(v.local_ver);
3559 tcc_free(v.verdef);
3560 tcc_free(v.verneed);
3561 tcc_free(v.versym);
3562 return ret;
3565 #define LD_TOK_NAME 256
3566 #define LD_TOK_EOF (-1)
3568 static int ld_inp(TCCState *s1)
3570 char b;
3571 if (s1->cc != -1) {
3572 int c = s1->cc;
3573 s1->cc = -1;
3574 return c;
3576 if (1 == read(s1->fd, &b, 1))
3577 return b;
3578 return CH_EOF;
3581 /* return next ld script token */
3582 static int ld_next(TCCState *s1, char *name, int name_size)
3584 int c, d, ch;
3585 char *q;
3587 redo:
3588 ch = ld_inp(s1);
3589 switch(ch) {
3590 case ' ':
3591 case '\t':
3592 case '\f':
3593 case '\v':
3594 case '\r':
3595 case '\n':
3596 goto redo;
3597 case '/':
3598 ch = ld_inp(s1);
3599 if (ch == '*') { /* comment */
3600 for (d = 0;; d = ch) {
3601 ch = ld_inp(s1);
3602 if (ch == CH_EOF || (ch == '/' && d == '*'))
3603 break;
3605 goto redo;
3606 } else {
3607 q = name;
3608 *q++ = '/';
3609 goto parse_name;
3611 break;
3612 case '\\':
3613 /* case 'a' ... 'z': */
3614 case 'a':
3615 case 'b':
3616 case 'c':
3617 case 'd':
3618 case 'e':
3619 case 'f':
3620 case 'g':
3621 case 'h':
3622 case 'i':
3623 case 'j':
3624 case 'k':
3625 case 'l':
3626 case 'm':
3627 case 'n':
3628 case 'o':
3629 case 'p':
3630 case 'q':
3631 case 'r':
3632 case 's':
3633 case 't':
3634 case 'u':
3635 case 'v':
3636 case 'w':
3637 case 'x':
3638 case 'y':
3639 case 'z':
3640 /* case 'A' ... 'z': */
3641 case 'A':
3642 case 'B':
3643 case 'C':
3644 case 'D':
3645 case 'E':
3646 case 'F':
3647 case 'G':
3648 case 'H':
3649 case 'I':
3650 case 'J':
3651 case 'K':
3652 case 'L':
3653 case 'M':
3654 case 'N':
3655 case 'O':
3656 case 'P':
3657 case 'Q':
3658 case 'R':
3659 case 'S':
3660 case 'T':
3661 case 'U':
3662 case 'V':
3663 case 'W':
3664 case 'X':
3665 case 'Y':
3666 case 'Z':
3667 case '_':
3668 case '.':
3669 case '$':
3670 case '~':
3671 q = name;
3672 parse_name:
3673 for(;;) {
3674 if (!((ch >= 'a' && ch <= 'z') ||
3675 (ch >= 'A' && ch <= 'Z') ||
3676 (ch >= '0' && ch <= '9') ||
3677 strchr("/.-_+=$:\\,~", ch)))
3678 break;
3679 if ((q - name) < name_size - 1) {
3680 *q++ = ch;
3682 ch = ld_inp(s1);
3684 s1->cc = ch;
3685 *q = '\0';
3686 c = LD_TOK_NAME;
3687 break;
3688 case CH_EOF:
3689 c = LD_TOK_EOF;
3690 break;
3691 default:
3692 c = ch;
3693 break;
3695 return c;
3698 static int ld_add_file(TCCState *s1, const char filename[])
3700 if (filename[0] == '/') {
3701 if (CONFIG_SYSROOT[0] == '\0'
3702 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3703 return 0;
3704 filename = tcc_basename(filename);
3706 return tcc_add_dll(s1, filename, 0);
3709 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3711 char filename[1024], libname[1024];
3712 int t, group, nblibs = 0, ret = 0;
3713 char **libs = NULL;
3715 group = !strcmp(cmd, "GROUP");
3716 if (!as_needed)
3717 s1->new_undef_sym = 0;
3718 t = ld_next(s1, filename, sizeof(filename));
3719 if (t != '(') {
3720 tcc_error_noabort("( expected");
3721 ret = -1;
3722 goto lib_parse_error;
3724 t = ld_next(s1, filename, sizeof(filename));
3725 for(;;) {
3726 libname[0] = '\0';
3727 if (t == LD_TOK_EOF) {
3728 tcc_error_noabort("unexpected end of file");
3729 ret = -1;
3730 goto lib_parse_error;
3731 } else if (t == ')') {
3732 break;
3733 } else if (t == '-') {
3734 t = ld_next(s1, filename, sizeof(filename));
3735 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3736 tcc_error_noabort("library name expected");
3737 ret = -1;
3738 goto lib_parse_error;
3740 pstrcpy(libname, sizeof libname, &filename[1]);
3741 if (s1->static_link) {
3742 snprintf(filename, sizeof filename, "lib%s.a", libname);
3743 } else {
3744 snprintf(filename, sizeof filename, "lib%s.so", libname);
3746 } else if (t != LD_TOK_NAME) {
3747 tcc_error_noabort("filename expected");
3748 ret = -1;
3749 goto lib_parse_error;
3751 if (!strcmp(filename, "AS_NEEDED")) {
3752 ret = ld_add_file_list(s1, cmd, 1);
3753 if (ret)
3754 goto lib_parse_error;
3755 } else {
3756 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3757 if (!as_needed) {
3758 ret = ld_add_file(s1, filename);
3759 if (ret)
3760 goto lib_parse_error;
3761 if (group) {
3762 /* Add the filename *and* the libname to avoid future conversions */
3763 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3764 if (libname[0] != '\0')
3765 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3769 t = ld_next(s1, filename, sizeof(filename));
3770 if (t == ',') {
3771 t = ld_next(s1, filename, sizeof(filename));
3774 if (group && !as_needed) {
3775 while (s1->new_undef_sym) {
3776 int i;
3777 s1->new_undef_sym = 0;
3778 for (i = 0; i < nblibs; i ++)
3779 ld_add_file(s1, libs[i]);
3782 lib_parse_error:
3783 dynarray_reset(&libs, &nblibs);
3784 return ret;
3787 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3788 files */
3789 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3791 char cmd[64];
3792 char filename[1024];
3793 int t, ret;
3795 s1->fd = fd;
3796 s1->cc = -1;
3797 for(;;) {
3798 t = ld_next(s1, cmd, sizeof(cmd));
3799 if (t == LD_TOK_EOF)
3800 return 0;
3801 else if (t != LD_TOK_NAME)
3802 return -1;
3803 if (!strcmp(cmd, "INPUT") ||
3804 !strcmp(cmd, "GROUP")) {
3805 ret = ld_add_file_list(s1, cmd, 0);
3806 if (ret)
3807 return ret;
3808 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3809 !strcmp(cmd, "TARGET")) {
3810 /* ignore some commands */
3811 t = ld_next(s1, cmd, sizeof(cmd));
3812 if (t != '(') {
3813 tcc_error_noabort("( expected");
3814 return -1;
3816 for(;;) {
3817 t = ld_next(s1, filename, sizeof(filename));
3818 if (t == LD_TOK_EOF) {
3819 tcc_error_noabort("unexpected end of file");
3820 return -1;
3821 } else if (t == ')') {
3822 break;
3825 } else {
3826 return -1;
3829 return 0;
3831 #endif /* !ELF_OBJ_ONLY */