Workaround false positive warning
[tinycc.git] / tccelf.c
blob93021aff98173f7a43498f7cdc4f413a9dce5ae7
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 ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
30 ST_DATA Section *common_section;
31 ST_DATA Section *cur_text_section; /* current section where function code is generated */
32 #ifdef CONFIG_TCC_ASM
33 ST_DATA Section *last_text_section; /* to handle .previous asm directive */
34 #endif
35 #ifdef CONFIG_TCC_BCHECK
36 /* bound check related sections */
37 ST_DATA Section *bounds_section; /* contains global data bound description */
38 ST_DATA Section *lbounds_section; /* contains local data bound description */
39 #endif
40 /* symbol sections */
41 ST_DATA Section *symtab_section;
42 /* debug sections */
43 ST_DATA Section *stab_section, *stabstr_section;
45 /* elf version information */
46 struct sym_version {
47 char *lib;
48 char *version;
49 int out_index;
50 int prev_same_lib;
52 static int nb_sym_versions;
53 static struct sym_version *sym_versions;
54 static int nb_sym_to_version;
55 static int *sym_to_version;
56 static int dt_verneednum;
57 static Section *versym_section;
58 static Section *verneed_section;
60 /* XXX: avoid static variable */
61 static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */
63 /* special flag to indicate that the section should not be linked to the other ones */
64 #define SHF_PRIVATE 0x80000000
65 /* section is dynsymtab_section */
66 #define SHF_DYNSYM 0x40000000
68 /* ------------------------------------------------------------------------- */
70 ST_FUNC void tccelf_new(TCCState *s)
72 /* no section zero */
73 dynarray_add(&s->sections, &s->nb_sections, NULL);
75 /* create standard sections */
76 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
77 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
78 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
79 versym_section = new_section(s, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
80 versym_section->sh_entsize = sizeof(ElfW(Half));
81 verneed_section = new_section(s, ".gnu.version_r", SHT_GNU_verneed, SHF_ALLOC);
82 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
83 common_section->sh_num = SHN_COMMON;
85 /* symbols are always generated for linking stage */
86 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
87 ".strtab",
88 ".hashtab", SHF_PRIVATE);
89 s->symtab = symtab_section;
91 /* private symbol table for dynamic symbols */
92 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
93 ".dynstrtab",
94 ".dynhashtab", SHF_PRIVATE);
95 get_sym_attr(s, 0, 1);
98 #ifdef CONFIG_TCC_BCHECK
99 ST_FUNC void tccelf_bounds_new(TCCState *s)
101 /* create bounds sections */
102 bounds_section = new_section(s, ".bounds",
103 SHT_PROGBITS, SHF_ALLOC);
104 lbounds_section = new_section(s, ".lbounds",
105 SHT_PROGBITS, SHF_ALLOC);
107 #endif
109 ST_FUNC void tccelf_stab_new(TCCState *s)
111 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
112 stab_section->sh_entsize = sizeof(Stab_Sym);
113 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
114 put_elf_str(stabstr_section, "");
115 stab_section->link = stabstr_section;
116 /* put first entry */
117 put_stabs("", 0, 0, 0, 0);
120 static void free_section(Section *s)
122 tcc_free(s->data);
125 ST_FUNC void tccelf_delete(TCCState *s1)
127 int i;
129 /* free symbol versions */
130 for (i = 0; i < nb_sym_versions; i++) {
131 tcc_free(sym_versions[i].version);
132 tcc_free(sym_versions[i].lib);
134 tcc_free(sym_versions);
135 sym_versions = NULL;
136 nb_sym_versions = 0;
137 tcc_free(sym_to_version);
138 sym_to_version = NULL;
139 nb_sym_to_version = 0;
141 /* free all sections */
142 for(i = 1; i < s1->nb_sections; i++)
143 free_section(s1->sections[i]);
144 dynarray_reset(&s1->sections, &s1->nb_sections);
146 for(i = 0; i < s1->nb_priv_sections; i++)
147 free_section(s1->priv_sections[i]);
148 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
150 /* free any loaded DLLs */
151 #ifdef TCC_IS_NATIVE
152 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
153 DLLReference *ref = s1->loaded_dlls[i];
154 if ( ref->handle )
155 # ifdef _WIN32
156 FreeLibrary((HMODULE)ref->handle);
157 # else
158 dlclose(ref->handle);
159 # endif
161 #endif
162 /* free loaded dlls array */
163 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
164 tcc_free(s1->sym_attrs);
166 symtab_section = NULL; /* for tccrun.c:rt_printline() */
169 /* save section data state */
170 ST_FUNC void tccelf_begin_file(TCCState *s1)
172 Section *s; int i;
173 for (i = 1; i < s1->nb_sections; i++) {
174 s = s1->sections[i];
175 s->sh_offset = s->data_offset;
177 /* disable symbol hashing during compilation */
178 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
179 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
180 s1->uw_sym = 0;
181 #endif
184 /* At the end of compilation, convert any UNDEF syms to global, and merge
185 with previously existing symbols */
186 ST_FUNC void tccelf_end_file(TCCState *s1)
188 Section *s = s1->symtab;
189 int first_sym, nb_syms, *tr, i;
191 first_sym = s->sh_offset / sizeof (ElfSym);
192 nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
193 s->data_offset = s->sh_offset;
194 s->link->data_offset = s->link->sh_offset;
195 s->hash = s->reloc, s->reloc = NULL;
196 tr = tcc_mallocz(nb_syms * sizeof *tr);
198 for (i = 0; i < nb_syms; ++i) {
199 ElfSym *sym = (ElfSym*)s->data + first_sym + i;
200 if (sym->st_shndx == SHN_UNDEF
201 && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
202 sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
203 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
204 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
206 /* now update relocations */
207 for (i = 1; i < s1->nb_sections; i++) {
208 Section *sr = s1->sections[i];
209 if (sr->sh_type == SHT_RELX && sr->link == s) {
210 ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
211 ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
212 for (; rel < rel_end; ++rel) {
213 int n = ELFW(R_SYM)(rel->r_info) - first_sym;
214 //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
215 rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
219 tcc_free(tr);
222 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
224 Section *sec;
226 sec = tcc_mallocz(sizeof(Section) + strlen(name));
227 strcpy(sec->name, name);
228 sec->sh_type = sh_type;
229 sec->sh_flags = sh_flags;
230 switch(sh_type) {
231 case SHT_GNU_versym:
232 sec->sh_addralign = 2;
233 break;
234 case SHT_HASH:
235 case SHT_REL:
236 case SHT_RELA:
237 case SHT_DYNSYM:
238 case SHT_SYMTAB:
239 case SHT_DYNAMIC:
240 case SHT_GNU_verneed:
241 case SHT_GNU_verdef:
242 sec->sh_addralign = PTR_SIZE;
243 break;
244 case SHT_STRTAB:
245 sec->sh_addralign = 1;
246 break;
247 default:
248 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */
249 break;
252 if (sh_flags & SHF_PRIVATE) {
253 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
254 } else {
255 sec->sh_num = s1->nb_sections;
256 dynarray_add(&s1->sections, &s1->nb_sections, sec);
259 return sec;
262 ST_FUNC Section *new_symtab(TCCState *s1,
263 const char *symtab_name, int sh_type, int sh_flags,
264 const char *strtab_name,
265 const char *hash_name, int hash_sh_flags)
267 Section *symtab, *strtab, *hash;
268 int *ptr, nb_buckets;
270 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
271 symtab->sh_entsize = sizeof(ElfW(Sym));
272 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
273 put_elf_str(strtab, "");
274 symtab->link = strtab;
275 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
277 nb_buckets = 1;
279 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
280 hash->sh_entsize = sizeof(int);
281 symtab->hash = hash;
282 hash->link = symtab;
284 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
285 ptr[0] = nb_buckets;
286 ptr[1] = 1;
287 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
288 return symtab;
291 /* realloc section and set its content to zero */
292 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
294 unsigned long size;
295 unsigned char *data;
297 size = sec->data_allocated;
298 if (size == 0)
299 size = 1;
300 while (size < new_size)
301 size = size * 2;
302 data = tcc_realloc(sec->data, size);
303 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
304 sec->data = data;
305 sec->data_allocated = size;
308 /* reserve at least 'size' bytes aligned per 'align' in section
309 'sec' from current offset, and return the aligned offset */
310 ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
312 size_t offset, offset1;
314 offset = (sec->data_offset + align - 1) & -align;
315 offset1 = offset + size;
316 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
317 section_realloc(sec, offset1);
318 sec->data_offset = offset1;
319 if (align > sec->sh_addralign)
320 sec->sh_addralign = align;
321 return offset;
324 /* reserve at least 'size' bytes in section 'sec' from
325 sec->data_offset. */
326 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
328 size_t offset = section_add(sec, size, 1);
329 return sec->data + offset;
332 /* reserve at least 'size' bytes from section start */
333 ST_FUNC void section_reserve(Section *sec, unsigned long size)
335 if (size > sec->data_allocated)
336 section_realloc(sec, size);
337 if (size > sec->data_offset)
338 sec->data_offset = size;
341 static Section *find_section_create (TCCState *s1, const char *name, int create)
343 Section *sec;
344 int i;
345 for(i = 1; i < s1->nb_sections; i++) {
346 sec = s1->sections[i];
347 if (!strcmp(name, sec->name))
348 return sec;
350 /* sections are created as PROGBITS */
351 return create ? new_section(s1, name, SHT_PROGBITS, SHF_ALLOC) : NULL;
354 /* return a reference to a section, and create it if it does not
355 exists */
356 ST_FUNC Section *find_section(TCCState *s1, const char *name)
358 return find_section_create (s1, name, 1);
361 /* ------------------------------------------------------------------------- */
363 ST_FUNC int put_elf_str(Section *s, const char *sym)
365 int offset, len;
366 char *ptr;
368 len = strlen(sym) + 1;
369 offset = s->data_offset;
370 ptr = section_ptr_add(s, len);
371 memmove(ptr, sym, len);
372 return offset;
375 /* elf symbol hashing function */
376 static unsigned long elf_hash(const unsigned char *name)
378 unsigned long h = 0, g;
380 while (*name) {
381 h = (h << 4) + *name++;
382 g = h & 0xf0000000;
383 if (g)
384 h ^= g >> 24;
385 h &= ~g;
387 return h;
390 /* rebuild hash table of section s */
391 /* NOTE: we do factorize the hash table code to go faster */
392 static void rebuild_hash(Section *s, unsigned int nb_buckets)
394 ElfW(Sym) *sym;
395 int *ptr, *hash, nb_syms, sym_index, h;
396 unsigned char *strtab;
398 strtab = s->link->data;
399 nb_syms = s->data_offset / sizeof(ElfW(Sym));
401 if (!nb_buckets)
402 nb_buckets = ((int*)s->hash->data)[0];
404 s->hash->data_offset = 0;
405 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
406 ptr[0] = nb_buckets;
407 ptr[1] = nb_syms;
408 ptr += 2;
409 hash = ptr;
410 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
411 ptr += nb_buckets + 1;
413 sym = (ElfW(Sym) *)s->data + 1;
414 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
415 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
416 h = elf_hash(strtab + sym->st_name) % nb_buckets;
417 *ptr = hash[h];
418 hash[h] = sym_index;
419 } else {
420 *ptr = 0;
422 ptr++;
423 sym++;
427 /* return the symbol number */
428 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
429 int info, int other, int shndx, const char *name)
431 int name_offset, sym_index;
432 int nbuckets, h;
433 ElfW(Sym) *sym;
434 Section *hs;
436 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
437 if (name && name[0])
438 name_offset = put_elf_str(s->link, name);
439 else
440 name_offset = 0;
441 /* XXX: endianness */
442 sym->st_name = name_offset;
443 sym->st_value = value;
444 sym->st_size = size;
445 sym->st_info = info;
446 sym->st_other = other;
447 sym->st_shndx = shndx;
448 sym_index = sym - (ElfW(Sym) *)s->data;
449 hs = s->hash;
450 if (hs) {
451 int *ptr, *base;
452 ptr = section_ptr_add(hs, sizeof(int));
453 base = (int *)hs->data;
454 /* only add global or weak symbols. */
455 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
456 /* add another hashing entry */
457 nbuckets = base[0];
458 h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
459 *ptr = base[2 + h];
460 base[2 + h] = sym_index;
461 base[1]++;
462 /* we resize the hash table */
463 hs->nb_hashed_syms++;
464 if (hs->nb_hashed_syms > 2 * nbuckets) {
465 rebuild_hash(s, 2 * nbuckets);
467 } else {
468 *ptr = 0;
469 base[1]++;
472 return sym_index;
475 ST_FUNC int find_elf_sym(Section *s, const char *name)
477 ElfW(Sym) *sym;
478 Section *hs;
479 int nbuckets, sym_index, h;
480 const char *name1;
482 hs = s->hash;
483 if (!hs)
484 return 0;
485 nbuckets = ((int *)hs->data)[0];
486 h = elf_hash((unsigned char *) name) % nbuckets;
487 sym_index = ((int *)hs->data)[2 + h];
488 while (sym_index != 0) {
489 sym = &((ElfW(Sym) *)s->data)[sym_index];
490 name1 = (char *) s->link->data + sym->st_name;
491 if (!strcmp(name, name1))
492 return sym_index;
493 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
495 return 0;
498 /* return elf symbol value, signal error if 'err' is nonzero */
499 ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err)
501 int sym_index;
502 ElfW(Sym) *sym;
504 sym_index = find_elf_sym(s->symtab, name);
505 sym = &((ElfW(Sym) *)s->symtab->data)[sym_index];
506 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
507 if (err)
508 tcc_error("%s not defined", name);
509 return 0;
511 return sym->st_value;
514 /* list elf symbol names and values */
515 ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
516 void (*symbol_cb)(void *ctx, const char *name, const void *val))
518 ElfW(Sym) *sym;
519 Section *symtab;
520 int sym_index, end_sym;
521 const char *name;
522 unsigned char sym_vis, sym_bind;
524 symtab = s->symtab;
525 end_sym = symtab->data_offset / sizeof (ElfSym);
526 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
527 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
528 if (sym->st_value) {
529 name = (char *) symtab->link->data + sym->st_name;
530 sym_bind = ELFW(ST_BIND)(sym->st_info);
531 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
532 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
533 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
538 /* return elf symbol value */
539 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
541 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0);
544 /* list elf symbol names and values */
545 LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
546 void (*symbol_cb)(void *ctx, const char *name, const void *val))
548 list_elf_symbols(s, ctx, symbol_cb);
551 #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
552 /* return elf symbol value or error */
553 ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
555 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1);
557 #endif
559 static void
560 version_add (TCCState *s)
562 int i;
563 ElfW(Sym) *sym;
564 ElfW(Verneed) *vn = NULL;
565 Section *symtab;
566 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
567 ElfW(Half) *versym;
568 const char *name;
570 /* add needed symbols */
571 symtab = s->dynsym;
572 end_sym = symtab->data_offset / sizeof (ElfSym);
573 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
574 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
575 int dllindex, verndx;
576 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
577 name = (char *) symtab->link->data + sym->st_name;
578 dllindex = find_elf_sym(s->dynsymtab_section, name);
579 verndx = (dllindex && dllindex < nb_sym_to_version)
580 ? sym_to_version[dllindex] : -1;
581 if (verndx >= 0) {
582 if (!sym_versions[verndx].out_index)
583 sym_versions[verndx].out_index = nb_versions++;
584 versym[sym_index] = sym_versions[verndx].out_index;
585 } else
586 versym[sym_index] = 0;
588 /* generate verneed section */
589 for (i = nb_sym_versions; i-- > 0;) {
590 struct sym_version *sv = &sym_versions[i];
591 int n_same_libs = 0, prev;
592 size_t vnofs;
593 ElfW(Vernaux) *vna = vna;
594 if (sv->out_index < 1)
595 continue;
596 vnofs = section_add(verneed_section, sizeof(*vn), 1);
597 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
598 vn->vn_version = 1;
599 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
600 vn->vn_aux = sizeof (*vn);
601 do {
602 prev = sv->prev_same_lib;
603 if (sv->out_index > 0) {
604 vna = section_ptr_add(verneed_section, sizeof(*vna));
605 vna->vna_hash = elf_hash (sv->version);
606 vna->vna_flags = 0;
607 vna->vna_other = sv->out_index;
608 sv->out_index = -2;
609 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
610 vna->vna_next = sizeof (*vna);
611 n_same_libs++;
613 sv = &sym_versions[prev];
614 } while(prev >= 0);
615 vna->vna_next = 0;
616 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
617 vn->vn_cnt = n_same_libs;
618 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
619 nb_entries++;
621 if (vn)
622 vn->vn_next = 0;
623 verneed_section->sh_info = nb_entries;
624 dt_verneednum = nb_entries;
627 /* add an elf symbol : check if it is already defined and patch
628 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
629 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
630 int info, int other, int shndx, const char *name)
632 ElfW(Sym) *esym;
633 int sym_bind, sym_index, sym_type, esym_bind;
634 unsigned char sym_vis, esym_vis, new_vis;
636 sym_bind = ELFW(ST_BIND)(info);
637 sym_type = ELFW(ST_TYPE)(info);
638 sym_vis = ELFW(ST_VISIBILITY)(other);
640 if (sym_bind != STB_LOCAL) {
641 /* we search global or weak symbols */
642 sym_index = find_elf_sym(s, name);
643 if (!sym_index)
644 goto do_def;
645 esym = &((ElfW(Sym) *)s->data)[sym_index];
646 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
647 && esym->st_other == other && esym->st_shndx == shndx)
648 return sym_index;
649 if (esym->st_shndx != SHN_UNDEF) {
650 esym_bind = ELFW(ST_BIND)(esym->st_info);
651 /* propagate the most constraining visibility */
652 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
653 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
654 if (esym_vis == STV_DEFAULT) {
655 new_vis = sym_vis;
656 } else if (sym_vis == STV_DEFAULT) {
657 new_vis = esym_vis;
658 } else {
659 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
661 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
662 | new_vis;
663 other = esym->st_other; /* in case we have to patch esym */
664 if (shndx == SHN_UNDEF) {
665 /* ignore adding of undefined symbol if the
666 corresponding symbol is already defined */
667 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
668 /* global overrides weak, so patch */
669 goto do_patch;
670 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
671 /* weak is ignored if already global */
672 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
673 /* keep first-found weak definition, ignore subsequents */
674 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
675 /* ignore hidden symbols after */
676 } else if ((esym->st_shndx == SHN_COMMON
677 || esym->st_shndx == bss_section->sh_num)
678 && (shndx < SHN_LORESERVE
679 && shndx != bss_section->sh_num)) {
680 /* data symbol gets precedence over common/bss */
681 goto do_patch;
682 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
683 /* data symbol keeps precedence over common/bss */
684 } else if (s->sh_flags & SHF_DYNSYM) {
685 /* we accept that two DLL define the same symbol */
686 } else if (esym->st_other & ST_ASM_SET) {
687 /* If the existing symbol came from an asm .set
688 we can override. */
689 goto do_patch;
690 } else {
691 #if 0
692 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
693 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
694 #endif
695 tcc_error_noabort("'%s' defined twice", name);
697 } else {
698 do_patch:
699 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
700 esym->st_shndx = shndx;
701 new_undef_sym = 1;
702 esym->st_value = value;
703 esym->st_size = size;
704 esym->st_other = other;
706 } else {
707 do_def:
708 sym_index = put_elf_sym(s, value, size,
709 ELFW(ST_INFO)(sym_bind, sym_type), other,
710 shndx, name);
712 return sym_index;
715 /* put relocation */
716 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
717 int type, int symbol, addr_t addend)
719 char buf[256];
720 Section *sr;
721 ElfW_Rel *rel;
723 sr = s->reloc;
724 if (!sr) {
725 /* if no relocation section, create it */
726 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
727 /* if the symtab is allocated, then we consider the relocation
728 are also */
729 sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
730 sr->sh_entsize = sizeof(ElfW_Rel);
731 sr->link = symtab;
732 sr->sh_info = s->sh_num;
733 s->reloc = sr;
735 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
736 rel->r_offset = offset;
737 rel->r_info = ELFW(R_INFO)(symbol, type);
738 #if SHT_RELX == SHT_RELA
739 rel->r_addend = addend;
740 #else
741 if (addend)
742 tcc_error("non-zero addend on REL architecture");
743 #endif
746 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
747 int type, int symbol)
749 put_elf_reloca(symtab, s, offset, type, symbol, 0);
752 /* Remove relocations for section S->reloc starting at oldrelocoffset
753 that are to the same place, retaining the last of them. As side effect
754 the relocations are sorted. Possibly reduces the number of relocs. */
755 ST_FUNC void squeeze_multi_relocs(Section *s, size_t oldrelocoffset)
757 Section *sr = s->reloc;
758 ElfW_Rel *r, *dest;
759 ssize_t a;
760 ElfW(Addr) addr;
762 if (oldrelocoffset + sizeof(*r) >= sr->data_offset)
763 return;
764 /* The relocs we're dealing with are the result of initializer parsing.
765 So they will be mostly in order and there aren't many of them.
766 Secondly we need a stable sort (which qsort isn't). We use
767 a simple insertion sort. */
768 for (a = oldrelocoffset + sizeof(*r); a < sr->data_offset; a += sizeof(*r)) {
769 ssize_t i = a - sizeof(*r);
770 addr = ((ElfW_Rel*)(sr->data + a))->r_offset;
771 for (; i >= (ssize_t)oldrelocoffset &&
772 ((ElfW_Rel*)(sr->data + i))->r_offset > addr; i -= sizeof(*r)) {
773 ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a);
774 *(ElfW_Rel*)(sr->data + a) = *(ElfW_Rel*)(sr->data + i);
775 *(ElfW_Rel*)(sr->data + i) = tmp;
779 r = (ElfW_Rel*)(sr->data + oldrelocoffset);
780 dest = r;
781 for (; r < (ElfW_Rel*)(sr->data + sr->data_offset); r++) {
782 if (dest->r_offset != r->r_offset)
783 dest++;
784 *dest = *r;
786 sr->data_offset = (unsigned char*)dest - sr->data + sizeof(*r);
789 /* put stab debug information */
791 ST_FUNC void put_stabs(const char *str, int type, int other, int desc,
792 unsigned long value)
794 Stab_Sym *sym;
796 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
797 if (str) {
798 sym->n_strx = put_elf_str(stabstr_section, str);
799 } else {
800 sym->n_strx = 0;
802 sym->n_type = type;
803 sym->n_other = other;
804 sym->n_desc = desc;
805 sym->n_value = value;
808 ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc,
809 unsigned long value, Section *sec, int sym_index)
811 put_stabs(str, type, other, desc, value);
812 put_elf_reloc(symtab_section, stab_section,
813 stab_section->data_offset - sizeof(unsigned int),
814 R_DATA_32, sym_index);
817 ST_FUNC void put_stabn(int type, int other, int desc, int value)
819 put_stabs(NULL, type, other, desc, value);
822 ST_FUNC void put_stabd(int type, int other, int desc)
824 put_stabs(NULL, type, other, desc, 0);
827 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
829 int n;
830 struct sym_attr *tab;
832 if (index >= s1->nb_sym_attrs) {
833 if (!alloc)
834 return s1->sym_attrs;
835 /* find immediately bigger power of 2 and reallocate array */
836 n = 1;
837 while (index >= n)
838 n *= 2;
839 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
840 s1->sym_attrs = tab;
841 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
842 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
843 s1->nb_sym_attrs = n;
845 return &s1->sym_attrs[index];
848 /* Browse each elem of type <type> in section <sec> starting at elem <startoff>
849 using variable <elem> */
850 #define for_each_elem(sec, startoff, elem, type) \
851 for (elem = (type *) sec->data + startoff; \
852 elem < (type *) (sec->data + sec->data_offset); elem++)
854 /* In an ELF file symbol table, the local symbols must appear below
855 the global and weak ones. Since TCC cannot sort it while generating
856 the code, we must do it after. All the relocation tables are also
857 modified to take into account the symbol table sorting */
858 static void sort_syms(TCCState *s1, Section *s)
860 int *old_to_new_syms;
861 ElfW(Sym) *new_syms;
862 int nb_syms, i;
863 ElfW(Sym) *p, *q;
864 ElfW_Rel *rel;
865 Section *sr;
866 int type, sym_index;
868 nb_syms = s->data_offset / sizeof(ElfW(Sym));
869 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
870 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
872 /* first pass for local symbols */
873 p = (ElfW(Sym) *)s->data;
874 q = new_syms;
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++;
882 /* save the number of local symbols in section header */
883 if( s->sh_size ) /* this 'if' makes IDA happy */
884 s->sh_info = q - new_syms;
886 /* then second pass for non local symbols */
887 p = (ElfW(Sym) *)s->data;
888 for(i = 0; i < nb_syms; i++) {
889 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
890 old_to_new_syms[i] = q - new_syms;
891 *q++ = *p;
893 p++;
896 /* we copy the new symbols to the old */
897 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
898 tcc_free(new_syms);
900 /* now we modify all the relocations */
901 for(i = 1; i < s1->nb_sections; i++) {
902 sr = s1->sections[i];
903 if (sr->sh_type == SHT_RELX && sr->link == s) {
904 for_each_elem(sr, 0, rel, ElfW_Rel) {
905 sym_index = ELFW(R_SYM)(rel->r_info);
906 type = ELFW(R_TYPE)(rel->r_info);
907 sym_index = old_to_new_syms[sym_index];
908 rel->r_info = ELFW(R_INFO)(sym_index, type);
913 tcc_free(old_to_new_syms);
916 /* relocate symbol table, resolve undefined symbols if do_resolve is
917 true and output error if undefined symbol. */
918 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
920 ElfW(Sym) *sym;
921 int sym_bind, sh_num;
922 const char *name;
924 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
925 sh_num = sym->st_shndx;
926 if (sh_num == SHN_UNDEF) {
927 name = (char *) s1->symtab->link->data + sym->st_name;
928 /* Use ld.so to resolve symbol for us (for tcc -run) */
929 if (do_resolve) {
930 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
931 void *addr = dlsym(RTLD_DEFAULT, name);
932 if (addr) {
933 sym->st_value = (addr_t) addr;
934 #ifdef DEBUG_RELOC
935 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
936 #endif
937 goto found;
939 #endif
940 /* if dynamic symbol exist, it will be used in relocate_section */
941 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
942 goto found;
943 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
944 it */
945 if (!strcmp(name, "_fp_hw"))
946 goto found;
947 /* only weak symbols are accepted to be undefined. Their
948 value is zero */
949 sym_bind = ELFW(ST_BIND)(sym->st_info);
950 if (sym_bind == STB_WEAK)
951 sym->st_value = 0;
952 else
953 tcc_error_noabort("undefined symbol '%s'", name);
954 } else if (sh_num < SHN_LORESERVE) {
955 /* add section base */
956 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
958 found: ;
962 /* relocate a given section (CPU dependent) by applying the relocations
963 in the associated relocation section */
964 ST_FUNC void relocate_section(TCCState *s1, Section *s)
966 Section *sr = s->reloc;
967 ElfW_Rel *rel;
968 ElfW(Sym) *sym;
969 int type, sym_index;
970 unsigned char *ptr;
971 addr_t tgt, addr;
973 relocate_init(sr);
975 for_each_elem(sr, 0, rel, ElfW_Rel) {
976 ptr = s->data + rel->r_offset;
977 sym_index = ELFW(R_SYM)(rel->r_info);
978 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
979 type = ELFW(R_TYPE)(rel->r_info);
980 tgt = sym->st_value;
981 #if SHT_RELX == SHT_RELA
982 tgt += rel->r_addend;
983 #endif
984 addr = s->sh_addr + rel->r_offset;
985 relocate(s1, rel, type, ptr, addr, tgt);
987 /* if the relocation is allocated, we change its symbol table */
988 if (sr->sh_flags & SHF_ALLOC)
989 sr->link = s1->dynsym;
992 /* relocate relocation table in 'sr' */
993 static void relocate_rel(TCCState *s1, Section *sr)
995 Section *s;
996 ElfW_Rel *rel;
998 s = s1->sections[sr->sh_info];
999 for_each_elem(sr, 0, rel, ElfW_Rel)
1000 rel->r_offset += s->sh_addr;
1003 /* count the number of dynamic relocations so that we can reserve
1004 their space */
1005 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
1007 int count = 0;
1008 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1009 ElfW_Rel *rel;
1010 for_each_elem(sr, 0, rel, ElfW_Rel) {
1011 int sym_index = ELFW(R_SYM)(rel->r_info);
1012 int type = ELFW(R_TYPE)(rel->r_info);
1013 switch(type) {
1014 #if defined(TCC_TARGET_I386)
1015 case R_386_32:
1016 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
1017 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
1018 /* don't fixup unresolved (weak) symbols */
1019 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
1020 break;
1022 #elif defined(TCC_TARGET_X86_64)
1023 case R_X86_64_32:
1024 case R_X86_64_32S:
1025 case R_X86_64_64:
1026 #endif
1027 count++;
1028 break;
1029 #if defined(TCC_TARGET_I386)
1030 case R_386_PC32:
1031 #elif defined(TCC_TARGET_X86_64)
1032 case R_X86_64_PC32:
1033 #endif
1034 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1035 count++;
1036 break;
1037 default:
1038 break;
1041 if (count) {
1042 /* allocate the section */
1043 sr->sh_flags |= SHF_ALLOC;
1044 sr->sh_size = count * sizeof(ElfW_Rel);
1046 #endif
1047 return count;
1050 static void build_got(TCCState *s1)
1052 /* if no got, then create it */
1053 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1054 s1->got->sh_entsize = 4;
1055 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1056 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1057 /* keep space for _DYNAMIC pointer and two dummy got entries */
1058 section_ptr_add(s1->got, 3 * PTR_SIZE);
1061 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1062 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1063 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1064 Returns the offset of the GOT or (if any) PLT entry. */
1065 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1066 int sym_index)
1068 int need_plt_entry;
1069 const char *name;
1070 ElfW(Sym) *sym;
1071 struct sym_attr *attr;
1072 unsigned got_offset;
1073 char plt_name[100];
1074 int len;
1076 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1077 attr = get_sym_attr(s1, sym_index, 1);
1079 /* In case a function is both called and its address taken 2 GOT entries
1080 are created, one for taking the address (GOT) and the other for the PLT
1081 entry (PLTGOT). */
1082 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1083 return attr;
1085 /* create the GOT entry */
1086 got_offset = s1->got->data_offset;
1087 section_ptr_add(s1->got, PTR_SIZE);
1089 /* Create the GOT relocation that will insert the address of the object or
1090 function of interest in the GOT entry. This is a static relocation for
1091 memory output (dlsym will give us the address of symbols) and dynamic
1092 relocation otherwise (executable and DLLs). The relocation should be
1093 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1094 associated to a PLT entry) but is currently done at load time for an
1095 unknown reason. */
1097 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1098 name = (char *) symtab_section->link->data + sym->st_name;
1100 if (s1->dynsym) {
1101 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1102 /* Hack alarm. We don't want to emit dynamic symbols
1103 and symbol based relocs for STB_LOCAL symbols, but rather
1104 want to resolve them directly. At this point the symbol
1105 values aren't final yet, so we must defer this. We will later
1106 have to create a RELATIVE reloc anyway, so we misuse the
1107 relocation slot to smuggle the symbol reference until
1108 fill_local_got_entries. Not that the sym_index is
1109 relative to symtab_section, not s1->dynsym! Nevertheless
1110 we use s1->dyn_sym so that if this is the first call
1111 that got->reloc is correctly created. Also note that
1112 RELATIVE relocs are not normally created for the .got,
1113 so the types serves as a marker for later (and is retained
1114 also for the final output, which is okay because then the
1115 got is just normal data). */
1116 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1117 sym_index);
1118 } else {
1119 if (0 == attr->dyn_index)
1120 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1121 sym->st_size, sym->st_info, 0,
1122 sym->st_shndx, name);
1123 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
1124 attr->dyn_index);
1126 } else {
1127 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1128 sym_index);
1131 if (need_plt_entry) {
1132 if (!s1->plt) {
1133 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1134 SHF_ALLOC | SHF_EXECINSTR);
1135 s1->plt->sh_entsize = 4;
1138 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1140 /* create a symbol 'sym@plt' for the PLT jump vector */
1141 len = strlen(name);
1142 if (len > sizeof plt_name - 5)
1143 len = sizeof plt_name - 5;
1144 memcpy(plt_name, name, len);
1145 strcpy(plt_name + len, "@plt");
1146 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
1147 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1149 } else {
1150 attr->got_offset = got_offset;
1153 return attr;
1156 /* build GOT and PLT entries */
1157 ST_FUNC void build_got_entries(TCCState *s1)
1159 Section *s;
1160 ElfW_Rel *rel;
1161 ElfW(Sym) *sym;
1162 int i, type, gotplt_entry, reloc_type, sym_index;
1163 struct sym_attr *attr;
1165 for(i = 1; i < s1->nb_sections; i++) {
1166 s = s1->sections[i];
1167 if (s->sh_type != SHT_RELX)
1168 continue;
1169 /* no need to handle got relocations */
1170 if (s->link != symtab_section)
1171 continue;
1172 for_each_elem(s, 0, rel, ElfW_Rel) {
1173 type = ELFW(R_TYPE)(rel->r_info);
1174 gotplt_entry = gotplt_entry_type(type);
1175 sym_index = ELFW(R_SYM)(rel->r_info);
1176 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1178 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1179 continue;
1182 /* Automatically create PLT/GOT [entry] if it is an undefined
1183 reference (resolved at runtime), or the symbol is absolute,
1184 probably created by tcc_add_symbol, and thus on 64-bit
1185 targets might be too far from application code. */
1186 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1187 if (sym->st_shndx == SHN_UNDEF) {
1188 ElfW(Sym) *esym;
1189 int dynindex;
1190 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1191 continue;
1192 /* Relocations for UNDEF symbols would normally need
1193 to be transferred into the executable or shared object.
1194 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1195 But TCC doesn't do that (at least for exes), so we
1196 need to resolve all such relocs locally. And that
1197 means PLT slots for functions in DLLs and COPY relocs for
1198 data symbols. COPY relocs were generated in
1199 bind_exe_dynsyms (and the symbol adjusted to be defined),
1200 and for functions we were generated a dynamic symbol
1201 of function type. */
1202 if (s1->dynsym) {
1203 /* dynsym isn't set for -run :-/ */
1204 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1205 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1206 if (dynindex
1207 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1208 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1209 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1210 goto jmp_slot;
1212 } else if (!(sym->st_shndx == SHN_ABS
1213 #ifndef TCC_TARGET_ARM
1214 && PTR_SIZE == 8
1215 #endif
1217 continue;
1220 #ifdef TCC_TARGET_X86_64
1221 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1222 sym->st_shndx != SHN_UNDEF &&
1223 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1224 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1225 s1->output_type == TCC_OUTPUT_EXE)) {
1226 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1227 continue;
1229 #endif
1230 if (code_reloc(type)) {
1231 jmp_slot:
1232 reloc_type = R_JMP_SLOT;
1233 } else
1234 reloc_type = R_GLOB_DAT;
1236 if (!s1->got)
1237 build_got(s1);
1239 if (gotplt_entry == BUILD_GOT_ONLY)
1240 continue;
1242 attr = put_got_entry(s1, reloc_type, sym_index);
1244 if (reloc_type == R_JMP_SLOT)
1245 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1250 /* put dynamic tag */
1251 static void put_dt(Section *dynamic, int dt, addr_t val)
1253 ElfW(Dyn) *dyn;
1254 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1255 dyn->d_tag = dt;
1256 dyn->d_un.d_val = val;
1259 #ifndef TCC_TARGET_PE
1260 static void add_init_array_defines(TCCState *s1, const char *section_name)
1262 Section *s;
1263 long end_offset;
1264 char sym_start[1024];
1265 char sym_end[1024];
1267 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1268 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1270 s = find_section(s1, section_name);
1271 if (!s) {
1272 end_offset = 0;
1273 s = data_section;
1274 } else {
1275 end_offset = s->data_offset;
1278 set_elf_sym(symtab_section,
1279 0, 0,
1280 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1281 s->sh_num, sym_start);
1282 set_elf_sym(symtab_section,
1283 end_offset, 0,
1284 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1285 s->sh_num, sym_end);
1288 static int tcc_add_support(TCCState *s1, const char *filename)
1290 char buf[1024];
1291 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1292 return tcc_add_file(s1, buf);
1294 #endif
1296 static void add_array (const char *section, TCCState *s1, Sym *sym)
1298 Section *s;
1299 unsigned char *ptr;
1301 s = find_section(s1, section);
1302 if (s) {
1303 s->sh_flags |= SHF_WRITE;
1304 ptr = section_ptr_add(s, PTR_SIZE);
1305 memset (ptr, 0, PTR_SIZE);
1306 put_elf_reloc (s1->symtab, s, ptr - s->data, R_DATA_PTR, sym->c);
1310 ST_FUNC void add_init_array (TCCState *s1, Sym *sym)
1312 add_array (".init_array", s1, sym);
1315 ST_FUNC void add_fini_array (TCCState *s1, Sym *sym)
1317 add_array (".fini_array", s1, sym);
1320 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1322 #ifdef CONFIG_TCC_BCHECK
1323 addr_t *ptr;
1324 int sym_index;
1326 if (0 == s1->do_bounds_check)
1327 return;
1328 /* XXX: add an object file to do that */
1329 ptr = section_ptr_add(bounds_section, sizeof(*ptr));
1330 *ptr = 0;
1331 set_elf_sym(symtab_section, 0, 0,
1332 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1333 bounds_section->sh_num, "__bounds_start");
1334 /* pull bcheck.o from libtcc1.a */
1335 sym_index = set_elf_sym(symtab_section, 0, 0,
1336 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1337 SHN_UNDEF, "__bound_init");
1338 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1339 /* add 'call __bound_init()' in .init section */
1340 Section *init_section = find_section(s1, ".init");
1341 unsigned char *pinit = section_ptr_add(init_section, 5);
1342 pinit[0] = 0xe8;
1343 write32le(pinit + 1, -4);
1344 put_elf_reloc(symtab_section, init_section,
1345 init_section->data_offset - 4, R_386_PC32, sym_index);
1346 /* R_386_PC32 = R_X86_64_PC32 = 2 */
1348 #endif
1351 /* add tcc runtime libraries */
1352 ST_FUNC void tcc_add_runtime(TCCState *s1)
1354 s1->filetype = 0;
1355 tcc_add_bcheck(s1);
1356 tcc_add_pragma_libs(s1);
1357 #ifndef TCC_TARGET_PE
1358 /* add libc */
1359 if (!s1->nostdlib) {
1360 tcc_add_library_err(s1, "c");
1361 #ifdef TCC_LIBGCC
1362 if (!s1->static_link) {
1363 if (TCC_LIBGCC[0] == '/')
1364 tcc_add_file(s1, TCC_LIBGCC);
1365 else
1366 tcc_add_dll(s1, TCC_LIBGCC, 0);
1368 #endif
1369 tcc_add_support(s1, TCC_LIBTCC1);
1370 /* add crt end if not memory output */
1371 if (s1->output_type != TCC_OUTPUT_MEMORY)
1372 tcc_add_crt(s1, "crtn.o");
1374 #endif
1377 /* add various standard linker symbols (must be done after the
1378 sections are filled (for example after allocating common
1379 symbols)) */
1380 static void tcc_add_linker_symbols(TCCState *s1)
1382 char buf[1024];
1383 int i;
1384 Section *s;
1386 set_elf_sym(symtab_section,
1387 text_section->data_offset, 0,
1388 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1389 text_section->sh_num, "_etext");
1390 set_elf_sym(symtab_section,
1391 data_section->data_offset, 0,
1392 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1393 data_section->sh_num, "_edata");
1394 set_elf_sym(symtab_section,
1395 bss_section->data_offset, 0,
1396 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1397 bss_section->sh_num, "_end");
1398 #ifdef TCC_TARGET_RISCV64
1399 /* XXX should be .sdata+0x800, not .data+0x800 */
1400 set_elf_sym(symtab_section,
1401 0x800, 0,
1402 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1403 data_section->sh_num, "__global_pointer$");
1404 #endif
1405 #ifndef TCC_TARGET_PE
1406 /* horrible new standard ldscript defines */
1407 add_init_array_defines(s1, ".preinit_array");
1408 add_init_array_defines(s1, ".init_array");
1409 add_init_array_defines(s1, ".fini_array");
1410 #endif
1412 /* add start and stop symbols for sections whose name can be
1413 expressed in C */
1414 for(i = 1; i < s1->nb_sections; i++) {
1415 s = s1->sections[i];
1416 if (s->sh_type == SHT_PROGBITS &&
1417 (s->sh_flags & SHF_ALLOC)) {
1418 const char *p;
1419 int ch;
1421 /* check if section name can be expressed in C */
1422 p = s->name;
1423 for(;;) {
1424 ch = *p;
1425 if (!ch)
1426 break;
1427 if (!isid(ch) && !isnum(ch))
1428 goto next_sec;
1429 p++;
1431 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1432 set_elf_sym(symtab_section,
1433 0, 0,
1434 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1435 s->sh_num, buf);
1436 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1437 set_elf_sym(symtab_section,
1438 s->data_offset, 0,
1439 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1440 s->sh_num, buf);
1442 next_sec: ;
1446 ST_FUNC void resolve_common_syms(TCCState *s1)
1448 ElfW(Sym) *sym;
1450 /* Allocate common symbols in BSS. */
1451 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1452 if (sym->st_shndx == SHN_COMMON) {
1453 /* symbol alignment is in st_value for SHN_COMMONs */
1454 sym->st_value = section_add(bss_section, sym->st_size,
1455 sym->st_value);
1456 sym->st_shndx = bss_section->sh_num;
1460 /* Now assign linker provided symbols their value. */
1461 tcc_add_linker_symbols(s1);
1464 static void tcc_output_binary(TCCState *s1, FILE *f,
1465 const int *sec_order)
1467 Section *s;
1468 int i, offset, size;
1470 offset = 0;
1471 for(i=1;i<s1->nb_sections;i++) {
1472 s = s1->sections[sec_order[i]];
1473 if (s->sh_type != SHT_NOBITS &&
1474 (s->sh_flags & SHF_ALLOC)) {
1475 while (offset < s->sh_offset) {
1476 fputc(0, f);
1477 offset++;
1479 size = s->sh_size;
1480 fwrite(s->data, 1, size, f);
1481 offset += size;
1486 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1488 int sym_index = ELFW(R_SYM) (rel->r_info);
1489 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1490 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1491 unsigned offset = attr->got_offset;
1493 if (0 == offset)
1494 return;
1495 section_reserve(s1->got, offset + PTR_SIZE);
1496 #ifdef TCC_TARGET_X86_64
1497 write64le(s1->got->data + offset, sym->st_value);
1498 #else
1499 write32le(s1->got->data + offset, sym->st_value);
1500 #endif
1503 /* Perform relocation to GOT or PLT entries */
1504 ST_FUNC void fill_got(TCCState *s1)
1506 Section *s;
1507 ElfW_Rel *rel;
1508 int i;
1510 for(i = 1; i < s1->nb_sections; i++) {
1511 s = s1->sections[i];
1512 if (s->sh_type != SHT_RELX)
1513 continue;
1514 /* no need to handle got relocations */
1515 if (s->link != symtab_section)
1516 continue;
1517 for_each_elem(s, 0, rel, ElfW_Rel) {
1518 switch (ELFW(R_TYPE) (rel->r_info)) {
1519 case R_X86_64_GOT32:
1520 case R_X86_64_GOTPCREL:
1521 case R_X86_64_GOTPCRELX:
1522 case R_X86_64_REX_GOTPCRELX:
1523 case R_X86_64_PLT32:
1524 fill_got_entry(s1, rel);
1525 break;
1531 /* See put_got_entry for a description. This is the second stage
1532 where GOT references to local defined symbols are rewritten. */
1533 static void fill_local_got_entries(TCCState *s1)
1535 ElfW_Rel *rel;
1536 if (!s1->got->reloc)
1537 return;
1538 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1539 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1540 int sym_index = ELFW(R_SYM) (rel->r_info);
1541 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1542 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1543 unsigned offset = attr->got_offset;
1544 if (offset != rel->r_offset - s1->got->sh_addr)
1545 tcc_error_noabort("huh");
1546 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1547 #if SHT_RELX == SHT_RELA
1548 rel->r_addend = sym->st_value;
1549 #else
1550 /* All our REL architectures also happen to be 32bit LE. */
1551 write32le(s1->got->data + offset, sym->st_value);
1552 #endif
1557 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1558 in shared libraries and export non local defined symbols to shared libraries
1559 if -rdynamic switch was given on command line */
1560 static void bind_exe_dynsyms(TCCState *s1)
1562 const char *name;
1563 int sym_index, index;
1564 ElfW(Sym) *sym, *esym;
1565 int type;
1567 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1568 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1569 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1570 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1571 if (sym->st_shndx == SHN_UNDEF) {
1572 name = (char *) symtab_section->link->data + sym->st_name;
1573 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1574 if (sym_index) {
1575 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1576 type = ELFW(ST_TYPE)(esym->st_info);
1577 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1578 /* Indirect functions shall have STT_FUNC type in executable
1579 * dynsym section. Indeed, a dlsym call following a lazy
1580 * resolution would pick the symbol value from the
1581 * executable dynsym entry which would contain the address
1582 * of the function wanted by the caller of dlsym instead of
1583 * the address of the function that would return that
1584 * address */
1585 int dynindex
1586 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1587 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1588 name);
1589 int index = sym - (ElfW(Sym) *) symtab_section->data;
1590 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1591 } else if (type == STT_OBJECT) {
1592 unsigned long offset;
1593 ElfW(Sym) *dynsym;
1594 offset = bss_section->data_offset;
1595 /* XXX: which alignment ? */
1596 offset = (offset + 16 - 1) & -16;
1597 set_elf_sym (s1->symtab, offset, esym->st_size,
1598 esym->st_info, 0, bss_section->sh_num, name);
1599 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1600 esym->st_info, 0, bss_section->sh_num,
1601 name);
1603 /* Ensure R_COPY works for weak symbol aliases */
1604 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1605 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1606 if ((dynsym->st_value == esym->st_value)
1607 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1608 char *dynname = (char *) s1->dynsymtab_section->link->data
1609 + dynsym->st_name;
1610 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1611 dynsym->st_info, 0,
1612 bss_section->sh_num, dynname);
1613 break;
1618 put_elf_reloc(s1->dynsym, bss_section,
1619 offset, R_COPY, index);
1620 offset += esym->st_size;
1621 bss_section->data_offset = offset;
1623 } else {
1624 /* STB_WEAK undefined symbols are accepted */
1625 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1626 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1627 !strcmp(name, "_fp_hw")) {
1628 } else {
1629 tcc_error_noabort("undefined symbol '%s'", name);
1632 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1633 /* if -rdynamic option, then export all non local symbols */
1634 name = (char *) symtab_section->link->data + sym->st_name;
1635 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1636 0, sym->st_shndx, name);
1641 /* Bind symbols of libraries: export all non local symbols of executable that
1642 are referenced by shared libraries. The reason is that the dynamic loader
1643 search symbol first in executable and then in libraries. Therefore a
1644 reference to a symbol already defined by a library can still be resolved by
1645 a symbol in the executable. */
1646 static void bind_libs_dynsyms(TCCState *s1)
1648 const char *name;
1649 int sym_index;
1650 ElfW(Sym) *sym, *esym;
1652 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1653 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1654 sym_index = find_elf_sym(symtab_section, name);
1655 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1656 if (sym_index && sym->st_shndx != SHN_UNDEF
1657 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1658 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1659 sym->st_info, 0, sym->st_shndx, name);
1660 } else if (esym->st_shndx == SHN_UNDEF) {
1661 /* weak symbols can stay undefined */
1662 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1663 tcc_warning("undefined dynamic symbol '%s'", name);
1668 /* Export all non local symbols. This is used by shared libraries so that the
1669 non local symbols they define can resolve a reference in another shared
1670 library or in the executable. Correspondingly, it allows undefined local
1671 symbols to be resolved by other shared libraries or by the executable. */
1672 static void export_global_syms(TCCState *s1)
1674 int dynindex, index;
1675 const char *name;
1676 ElfW(Sym) *sym;
1678 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1679 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1680 name = (char *) symtab_section->link->data + sym->st_name;
1681 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1682 sym->st_info, 0, sym->st_shndx, name);
1683 index = sym - (ElfW(Sym) *) symtab_section->data;
1684 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1689 /* Allocate strings for section names and decide if an unallocated section
1690 should be output.
1691 NOTE: the strsec section comes last, so its size is also correct ! */
1692 static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1694 int i;
1695 Section *s;
1696 int textrel = 0;
1698 /* Allocate strings for section names */
1699 for(i = 1; i < s1->nb_sections; i++) {
1700 s = s1->sections[i];
1701 /* when generating a DLL, we include relocations but we may
1702 patch them */
1703 if (file_type == TCC_OUTPUT_DLL &&
1704 s->sh_type == SHT_RELX &&
1705 !(s->sh_flags & SHF_ALLOC) &&
1706 (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
1707 prepare_dynamic_rel(s1, s)) {
1708 if (s1->sections[s->sh_info]->sh_flags & SHF_EXECINSTR)
1709 textrel = 1;
1710 } else if ((s1->do_debug && s->sh_type != SHT_RELX) ||
1711 file_type == TCC_OUTPUT_OBJ ||
1712 (s->sh_flags & SHF_ALLOC) ||
1713 i == (s1->nb_sections - 1)) {
1714 /* we output all sections if debug or object file */
1715 s->sh_size = s->data_offset;
1717 if (s->sh_size || (s->sh_flags & SHF_ALLOC))
1718 s->sh_name = put_elf_str(strsec, s->name);
1720 strsec->sh_size = strsec->data_offset;
1721 return textrel;
1724 /* Info to be copied in dynamic section */
1725 struct dyn_inf {
1726 Section *dynamic;
1727 Section *dynstr;
1728 unsigned long data_offset;
1729 addr_t rel_addr;
1730 addr_t rel_size;
1731 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1732 addr_t bss_addr;
1733 addr_t bss_size;
1734 #endif
1737 /* Assign sections to segments and decide how are sections laid out when loaded
1738 in memory. This function also fills corresponding program headers. */
1739 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1740 Section *interp, Section* strsec,
1741 struct dyn_inf *dyninf, int *sec_order)
1743 int i, j, k, file_type, sh_order_index, file_offset;
1744 unsigned long s_align;
1745 long long tmp;
1746 addr_t addr;
1747 ElfW(Phdr) *ph;
1748 Section *s;
1750 file_type = s1->output_type;
1751 sh_order_index = 1;
1752 file_offset = 0;
1753 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1754 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1755 s_align = ELF_PAGE_SIZE;
1756 if (s1->section_align)
1757 s_align = s1->section_align;
1759 if (phnum > 0) {
1760 if (s1->has_text_addr) {
1761 int a_offset, p_offset;
1762 addr = s1->text_addr;
1763 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1764 ELF_PAGE_SIZE */
1765 a_offset = (int) (addr & (s_align - 1));
1766 p_offset = file_offset & (s_align - 1);
1767 if (a_offset < p_offset)
1768 a_offset += s_align;
1769 file_offset += (a_offset - p_offset);
1770 } else {
1771 if (file_type == TCC_OUTPUT_DLL)
1772 addr = 0;
1773 else
1774 addr = ELF_START_ADDR;
1775 /* compute address after headers */
1776 addr += (file_offset & (s_align - 1));
1779 ph = &phdr[0];
1780 /* Leave one program headers for the program interpreter and one for
1781 the program header table itself if needed. These are done later as
1782 they require section layout to be done first. */
1783 if (interp)
1784 ph += 2;
1786 /* dynamic relocation table information, for .dynamic section */
1787 dyninf->rel_addr = dyninf->rel_size = 0;
1788 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1789 dyninf->bss_addr = dyninf->bss_size = 0;
1790 #endif
1792 for(j = 0; j < 2; j++) {
1793 ph->p_type = PT_LOAD;
1794 if (j == 0)
1795 ph->p_flags = PF_R | PF_X;
1796 else
1797 ph->p_flags = PF_R | PF_W;
1798 ph->p_align = s_align;
1800 /* Decide the layout of sections loaded in memory. This must
1801 be done before program headers are filled since they contain
1802 info about the layout. We do the following ordering: interp,
1803 symbol tables, relocations, progbits, nobits */
1804 /* XXX: do faster and simpler sorting */
1805 for(k = 0; k < 5; k++) {
1806 for(i = 1; i < s1->nb_sections; i++) {
1807 s = s1->sections[i];
1808 /* compute if section should be included */
1809 if (j == 0) {
1810 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1811 SHF_ALLOC)
1812 continue;
1813 } else {
1814 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1815 (SHF_ALLOC | SHF_WRITE))
1816 continue;
1818 if (s == interp) {
1819 if (k != 0)
1820 continue;
1821 } else if (s->sh_type == SHT_DYNSYM ||
1822 s->sh_type == SHT_STRTAB ||
1823 s->sh_type == SHT_HASH) {
1824 if (k != 1)
1825 continue;
1826 } else if (s->sh_type == SHT_RELX) {
1827 if (k != 2)
1828 continue;
1829 } else if (s->sh_type == SHT_NOBITS) {
1830 if (k != 4)
1831 continue;
1832 } else {
1833 if (k != 3)
1834 continue;
1836 sec_order[sh_order_index++] = i;
1838 /* section matches: we align it and add its size */
1839 tmp = addr;
1840 addr = (addr + s->sh_addralign - 1) &
1841 ~(s->sh_addralign - 1);
1842 file_offset += (int) ( addr - tmp );
1843 s->sh_offset = file_offset;
1844 s->sh_addr = addr;
1846 /* update program header infos */
1847 if (ph->p_offset == 0) {
1848 ph->p_offset = file_offset;
1849 ph->p_vaddr = addr;
1850 ph->p_paddr = ph->p_vaddr;
1852 /* update dynamic relocation infos */
1853 if (s->sh_type == SHT_RELX) {
1854 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1855 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1856 dyninf->rel_addr = addr;
1857 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1859 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1860 dyninf->bss_addr = addr;
1861 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1863 #else
1864 if (dyninf->rel_size == 0)
1865 dyninf->rel_addr = addr;
1866 dyninf->rel_size += s->sh_size;
1867 #endif
1869 addr += s->sh_size;
1870 if (s->sh_type != SHT_NOBITS)
1871 file_offset += s->sh_size;
1874 if (j == 0) {
1875 /* Make the first PT_LOAD segment include the program
1876 headers itself (and the ELF header as well), it'll
1877 come out with same memory use but will make various
1878 tools like binutils strip work better. */
1879 ph->p_offset &= ~(ph->p_align - 1);
1880 ph->p_vaddr &= ~(ph->p_align - 1);
1881 ph->p_paddr &= ~(ph->p_align - 1);
1883 ph->p_filesz = file_offset - ph->p_offset;
1884 ph->p_memsz = addr - ph->p_vaddr;
1885 ph++;
1886 if (j == 0) {
1887 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1888 /* if in the middle of a page, we duplicate the page in
1889 memory so that one copy is RX and the other is RW */
1890 if ((addr & (s_align - 1)) != 0)
1891 addr += s_align;
1892 } else {
1893 addr = (addr + s_align - 1) & ~(s_align - 1);
1894 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1900 /* all other sections come after */
1901 for(i = 1; i < s1->nb_sections; i++) {
1902 s = s1->sections[i];
1903 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1904 continue;
1905 sec_order[sh_order_index++] = i;
1907 file_offset = (file_offset + s->sh_addralign - 1) &
1908 ~(s->sh_addralign - 1);
1909 s->sh_offset = file_offset;
1910 if (s->sh_type != SHT_NOBITS)
1911 file_offset += s->sh_size;
1914 return file_offset;
1917 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1918 Section *dynamic)
1920 ElfW(Phdr) *ph;
1922 /* if interpreter, then add corresponding program header */
1923 if (interp) {
1924 ph = &phdr[0];
1926 ph->p_type = PT_PHDR;
1927 ph->p_offset = sizeof(ElfW(Ehdr));
1928 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
1929 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
1930 ph->p_paddr = ph->p_vaddr;
1931 ph->p_flags = PF_R | PF_X;
1932 ph->p_align = 4; /* interp->sh_addralign; */
1933 ph++;
1935 ph->p_type = PT_INTERP;
1936 ph->p_offset = interp->sh_offset;
1937 ph->p_vaddr = interp->sh_addr;
1938 ph->p_paddr = ph->p_vaddr;
1939 ph->p_filesz = interp->sh_size;
1940 ph->p_memsz = interp->sh_size;
1941 ph->p_flags = PF_R;
1942 ph->p_align = interp->sh_addralign;
1945 /* if dynamic section, then add corresponding program header */
1946 if (dynamic) {
1947 ph = &phdr[phnum - 1];
1949 ph->p_type = PT_DYNAMIC;
1950 ph->p_offset = dynamic->sh_offset;
1951 ph->p_vaddr = dynamic->sh_addr;
1952 ph->p_paddr = ph->p_vaddr;
1953 ph->p_filesz = dynamic->sh_size;
1954 ph->p_memsz = dynamic->sh_size;
1955 ph->p_flags = PF_R | PF_W;
1956 ph->p_align = dynamic->sh_addralign;
1960 /* Fill the dynamic section with tags describing the address and size of
1961 sections */
1962 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
1964 Section *dynamic = dyninf->dynamic;
1965 Section *s;
1967 /* put dynamic section entries */
1968 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1969 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
1970 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1971 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
1972 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1973 #if PTR_SIZE == 8
1974 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
1975 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
1976 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
1977 #else
1978 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1979 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
1980 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
1981 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
1982 put_dt(dynamic, DT_PLTREL, DT_REL);
1983 put_dt(dynamic, DT_REL, dyninf->bss_addr);
1984 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
1985 #else
1986 put_dt(dynamic, DT_REL, dyninf->rel_addr);
1987 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
1988 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1989 #endif
1990 #endif
1991 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
1992 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
1993 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
1994 s = find_section_create (s1, ".preinit_array", 0);
1995 if (s && s->data_offset) {
1996 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
1997 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
1999 s = find_section_create (s1, ".init_array", 0);
2000 if (s && s->data_offset) {
2001 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2002 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2004 s = find_section_create (s1, ".fini_array", 0);
2005 if (s && s->data_offset) {
2006 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2007 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2009 s = find_section_create (s1, ".init", 0);
2010 if (s && s->data_offset) {
2011 put_dt(dynamic, DT_INIT, s->sh_addr);
2013 s = find_section_create (s1, ".fini", 0);
2014 if (s && s->data_offset) {
2015 put_dt(dynamic, DT_FINI, s->sh_addr);
2017 if (s1->do_debug)
2018 put_dt(dynamic, DT_DEBUG, 0);
2019 put_dt(dynamic, DT_NULL, 0);
2022 /* Relocate remaining sections and symbols (that is those not related to
2023 dynamic linking) */
2024 static int final_sections_reloc(TCCState *s1)
2026 int i;
2027 Section *s;
2029 relocate_syms(s1, s1->symtab, 0);
2031 if (s1->nb_errors != 0)
2032 return -1;
2034 /* relocate sections */
2035 /* XXX: ignore sections with allocated relocations ? */
2036 for(i = 1; i < s1->nb_sections; i++) {
2037 s = s1->sections[i];
2038 if (s->reloc && (s != s1->got || s1->static_link))
2039 relocate_section(s1, s);
2042 /* relocate relocation entries if the relocation tables are
2043 allocated in the executable */
2044 for(i = 1; i < s1->nb_sections; i++) {
2045 s = s1->sections[i];
2046 if ((s->sh_flags & SHF_ALLOC) &&
2047 s->sh_type == SHT_RELX) {
2048 relocate_rel(s1, s);
2051 return 0;
2054 /* Create an ELF file on disk.
2055 This function handle ELF specific layout requirements */
2056 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2057 int file_offset, int *sec_order)
2059 int i, shnum, offset, size, file_type;
2060 Section *s;
2061 ElfW(Ehdr) ehdr;
2062 ElfW(Shdr) shdr, *sh;
2064 file_type = s1->output_type;
2065 shnum = s1->nb_sections;
2067 memset(&ehdr, 0, sizeof(ehdr));
2069 if (phnum > 0) {
2070 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2071 ehdr.e_phnum = phnum;
2072 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2075 /* align to 4 */
2076 file_offset = (file_offset + 3) & -4;
2078 /* fill header */
2079 ehdr.e_ident[0] = ELFMAG0;
2080 ehdr.e_ident[1] = ELFMAG1;
2081 ehdr.e_ident[2] = ELFMAG2;
2082 ehdr.e_ident[3] = ELFMAG3;
2083 ehdr.e_ident[4] = ELFCLASSW;
2084 ehdr.e_ident[5] = ELFDATA2LSB;
2085 ehdr.e_ident[6] = EV_CURRENT;
2086 #if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
2087 /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
2088 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2089 #endif
2090 #ifdef TCC_TARGET_ARM
2091 #ifdef TCC_ARM_EABI
2092 ehdr.e_ident[EI_OSABI] = 0;
2093 ehdr.e_flags = EF_ARM_EABI_VER4;
2094 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2095 ehdr.e_flags |= EF_ARM_HASENTRY;
2096 if (s1->float_abi == ARM_HARD_FLOAT)
2097 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2098 else
2099 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2100 #else
2101 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2102 #endif
2103 #elif defined TCC_TARGET_RISCV64
2104 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2105 #endif
2106 switch(file_type) {
2107 default:
2108 case TCC_OUTPUT_EXE:
2109 ehdr.e_type = ET_EXEC;
2110 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
2111 break;
2112 case TCC_OUTPUT_DLL:
2113 ehdr.e_type = ET_DYN;
2114 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2115 break;
2116 case TCC_OUTPUT_OBJ:
2117 ehdr.e_type = ET_REL;
2118 break;
2120 ehdr.e_machine = EM_TCC_TARGET;
2121 ehdr.e_version = EV_CURRENT;
2122 ehdr.e_shoff = file_offset;
2123 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2124 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2125 ehdr.e_shnum = shnum;
2126 ehdr.e_shstrndx = shnum - 1;
2128 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2129 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2130 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2132 sort_syms(s1, symtab_section);
2133 for(i = 1; i < s1->nb_sections; i++) {
2134 s = s1->sections[sec_order[i]];
2135 if (s->sh_type != SHT_NOBITS) {
2136 while (offset < s->sh_offset) {
2137 fputc(0, f);
2138 offset++;
2140 size = s->sh_size;
2141 if (size)
2142 fwrite(s->data, 1, size, f);
2143 offset += size;
2147 /* output section headers */
2148 while (offset < ehdr.e_shoff) {
2149 fputc(0, f);
2150 offset++;
2153 for(i = 0; i < s1->nb_sections; i++) {
2154 sh = &shdr;
2155 memset(sh, 0, sizeof(ElfW(Shdr)));
2156 s = s1->sections[i];
2157 if (s) {
2158 sh->sh_name = s->sh_name;
2159 sh->sh_type = s->sh_type;
2160 sh->sh_flags = s->sh_flags;
2161 sh->sh_entsize = s->sh_entsize;
2162 sh->sh_info = s->sh_info;
2163 if (s->link)
2164 sh->sh_link = s->link->sh_num;
2165 sh->sh_addralign = s->sh_addralign;
2166 sh->sh_addr = s->sh_addr;
2167 sh->sh_offset = s->sh_offset;
2168 sh->sh_size = s->sh_size;
2170 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2174 /* Write an elf, coff or "binary" file */
2175 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2176 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2178 int fd, mode, file_type;
2179 FILE *f;
2181 file_type = s1->output_type;
2182 if (file_type == TCC_OUTPUT_OBJ)
2183 mode = 0666;
2184 else
2185 mode = 0777;
2186 unlink(filename);
2187 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2188 if (fd < 0) {
2189 tcc_error_noabort("could not write '%s'", filename);
2190 return -1;
2192 f = fdopen(fd, "wb");
2193 if (s1->verbose)
2194 printf("<- %s\n", filename);
2196 #ifdef TCC_TARGET_COFF
2197 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2198 tcc_output_coff(s1, f);
2199 else
2200 #endif
2201 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2202 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2203 else
2204 tcc_output_binary(s1, f, sec_order);
2205 fclose(f);
2207 return 0;
2210 /* Sort section headers by assigned sh_addr, remove sections
2211 that we aren't going to output. */
2212 static void tidy_section_headers(TCCState *s1, int *sec_order)
2214 int i, nnew, l, *backmap;
2215 Section **snew, *s;
2216 ElfW(Sym) *sym;
2218 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2219 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2220 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2221 s = s1->sections[sec_order[i]];
2222 if (!i || s->sh_name) {
2223 backmap[sec_order[i]] = nnew;
2224 snew[nnew] = s;
2225 ++nnew;
2226 } else {
2227 backmap[sec_order[i]] = 0;
2228 snew[--l] = s;
2231 for (i = 0; i < nnew; i++) {
2232 s = snew[i];
2233 if (s) {
2234 s->sh_num = i;
2235 if (s->sh_type == SHT_RELX)
2236 s->sh_info = backmap[s->sh_info];
2240 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2241 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2242 sym->st_shndx = backmap[sym->st_shndx];
2243 if( !s1->static_link ) {
2244 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2245 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2246 sym->st_shndx = backmap[sym->st_shndx];
2248 for (i = 0; i < s1->nb_sections; i++)
2249 sec_order[i] = i;
2250 tcc_free(s1->sections);
2251 s1->sections = snew;
2252 s1->nb_sections = nnew;
2253 tcc_free(backmap);
2256 /* Output an elf, coff or binary file */
2257 /* XXX: suppress unneeded sections */
2258 static int elf_output_file(TCCState *s1, const char *filename)
2260 int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
2261 struct dyn_inf dyninf = {0};
2262 ElfW(Phdr) *phdr;
2263 ElfW(Sym) *sym;
2264 Section *strsec, *interp, *dynamic, *dynstr;
2265 int textrel;
2267 file_type = s1->output_type;
2268 s1->nb_errors = 0;
2269 ret = -1;
2270 phdr = NULL;
2271 sec_order = NULL;
2272 interp = dynamic = dynstr = NULL; /* avoid warning */
2273 textrel = 0;
2275 if (file_type != TCC_OUTPUT_OBJ) {
2276 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2277 tcc_add_runtime(s1);
2278 resolve_common_syms(s1);
2280 if (!s1->static_link) {
2281 if (file_type == TCC_OUTPUT_EXE) {
2282 char *ptr;
2283 /* allow override the dynamic loader */
2284 const char *elfint = getenv("LD_SO");
2285 if (elfint == NULL)
2286 elfint = DEFAULT_ELFINTERP(s1);
2287 /* add interpreter section only if executable */
2288 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2289 interp->sh_addralign = 1;
2290 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2291 strcpy(ptr, elfint);
2294 /* add dynamic symbol table */
2295 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2296 ".dynstr",
2297 ".hash", SHF_ALLOC);
2298 dynstr = s1->dynsym->link;
2299 versym_section->link = s1->dynsym;
2300 verneed_section->link = dynstr;
2302 /* add dynamic section */
2303 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2304 SHF_ALLOC | SHF_WRITE);
2305 dynamic->link = dynstr;
2306 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2308 build_got(s1);
2310 if (file_type == TCC_OUTPUT_EXE) {
2311 bind_exe_dynsyms(s1);
2312 if (s1->nb_errors)
2313 goto the_end;
2314 bind_libs_dynsyms(s1);
2315 } else {
2316 /* shared library case: simply export all global symbols */
2317 export_global_syms(s1);
2320 build_got_entries(s1);
2321 version_add (s1);
2324 /* we add a section for symbols */
2325 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2326 put_elf_str(strsec, "");
2328 /* Allocate strings for section names */
2329 textrel = alloc_sec_names(s1, file_type, strsec);
2331 if (dynamic) {
2332 /* add a list of needed dlls */
2333 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2334 DLLReference *dllref = s1->loaded_dlls[i];
2335 if (dllref->level == 0)
2336 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2339 if (s1->rpath)
2340 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2341 put_elf_str(dynstr, s1->rpath));
2343 if (file_type == TCC_OUTPUT_DLL) {
2344 if (s1->soname)
2345 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2346 /* XXX: currently, since we do not handle PIC code, we
2347 must relocate the readonly segments */
2348 if (textrel)
2349 put_dt(dynamic, DT_TEXTREL, 0);
2352 if (s1->symbolic)
2353 put_dt(dynamic, DT_SYMBOLIC, 0);
2355 dyninf.dynamic = dynamic;
2356 dyninf.dynstr = dynstr;
2357 /* remember offset and reserve space for 2nd call below */
2358 dyninf.data_offset = dynamic->data_offset;
2359 fill_dynamic(s1, &dyninf);
2360 dynamic->sh_size = dynamic->data_offset;
2361 dynstr->sh_size = dynstr->data_offset;
2364 /* compute number of program headers */
2365 if (file_type == TCC_OUTPUT_OBJ)
2366 phnum = 0;
2367 else if (file_type == TCC_OUTPUT_DLL)
2368 phnum = 3;
2369 else if (s1->static_link)
2370 phnum = 2;
2371 else
2372 phnum = 5;
2374 /* allocate program segment headers */
2375 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2377 /* compute number of sections */
2378 shnum = s1->nb_sections;
2380 /* this array is used to reorder sections in the output file */
2381 sec_order = tcc_malloc(sizeof(int) * shnum);
2382 sec_order[0] = 0;
2384 /* compute section to program header mapping */
2385 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2386 sec_order);
2388 /* Fill remaining program header and finalize relocation related to dynamic
2389 linking. */
2390 if (file_type != TCC_OUTPUT_OBJ) {
2391 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2392 if (dynamic) {
2393 dynamic->data_offset = dyninf.data_offset;
2394 fill_dynamic(s1, &dyninf);
2396 /* put in GOT the dynamic section address and relocate PLT */
2397 write32le(s1->got->data, dynamic->sh_addr);
2398 if (file_type == TCC_OUTPUT_EXE
2399 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2400 relocate_plt(s1);
2402 /* relocate symbols in .dynsym now that final addresses are known */
2403 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2404 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2405 /* do symbol relocation */
2406 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2411 /* if building executable or DLL, then relocate each section
2412 except the GOT which is already relocated */
2413 ret = final_sections_reloc(s1);
2414 if (ret)
2415 goto the_end;
2416 tidy_section_headers(s1, sec_order);
2418 /* Perform relocation to GOT or PLT entries */
2419 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2420 fill_got(s1);
2421 else if (s1->got)
2422 fill_local_got_entries(s1);
2425 /* Create the ELF file with name 'filename' */
2426 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2427 s1->nb_sections = shnum;
2428 the_end:
2429 tcc_free(sec_order);
2430 tcc_free(phdr);
2431 return ret;
2434 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2436 int ret;
2437 #ifdef TCC_TARGET_PE
2438 if (s->output_type != TCC_OUTPUT_OBJ) {
2439 ret = pe_output_file(s, filename);
2440 } else
2441 #endif
2442 ret = elf_output_file(s, filename);
2443 return ret;
2446 ssize_t full_read(int fd, void *buf, size_t count) {
2447 char *cbuf = buf;
2448 size_t rnum = 0;
2449 while (1) {
2450 ssize_t num = read(fd, cbuf, count-rnum);
2451 if (num < 0) return num;
2452 if (num == 0) return rnum;
2453 rnum += num;
2454 cbuf += num;
2458 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2460 void *data;
2462 data = tcc_malloc(size);
2463 lseek(fd, file_offset, SEEK_SET);
2464 full_read(fd, data, size);
2465 return data;
2468 typedef struct SectionMergeInfo {
2469 Section *s; /* corresponding existing section */
2470 unsigned long offset; /* offset of the new section in the existing section */
2471 uint8_t new_section; /* true if section 's' was added */
2472 uint8_t link_once; /* true if link once section */
2473 } SectionMergeInfo;
2475 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2477 int size = full_read(fd, h, sizeof *h);
2478 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2479 if (h->e_type == ET_REL)
2480 return AFF_BINTYPE_REL;
2481 if (h->e_type == ET_DYN)
2482 return AFF_BINTYPE_DYN;
2483 } else if (size >= 8) {
2484 if (0 == memcmp(h, ARMAG, 8))
2485 return AFF_BINTYPE_AR;
2486 #ifdef TCC_TARGET_COFF
2487 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2488 return AFF_BINTYPE_C67;
2489 #endif
2491 return 0;
2494 /* load an object file and merge it with current files */
2495 /* XXX: handle correctly stab (debug) info */
2496 ST_FUNC int tcc_load_object_file(TCCState *s1,
2497 int fd, unsigned long file_offset)
2499 ElfW(Ehdr) ehdr;
2500 ElfW(Shdr) *shdr, *sh;
2501 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2502 char *strsec, *strtab;
2503 int *old_to_new_syms;
2504 char *sh_name, *name;
2505 SectionMergeInfo *sm_table, *sm;
2506 ElfW(Sym) *sym, *symtab;
2507 ElfW_Rel *rel;
2508 Section *s;
2510 int stab_index;
2511 int stabstr_index;
2513 stab_index = stabstr_index = 0;
2515 lseek(fd, file_offset, SEEK_SET);
2516 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2517 goto fail1;
2518 /* test CPU specific stuff */
2519 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2520 ehdr.e_machine != EM_TCC_TARGET) {
2521 fail1:
2522 tcc_error_noabort("invalid object file");
2523 return -1;
2525 /* read sections */
2526 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2527 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2528 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2530 /* load section names */
2531 sh = &shdr[ehdr.e_shstrndx];
2532 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2534 /* load symtab and strtab */
2535 old_to_new_syms = NULL;
2536 symtab = NULL;
2537 strtab = NULL;
2538 nb_syms = 0;
2539 seencompressed = 0;
2540 for(i = 1; i < ehdr.e_shnum; i++) {
2541 sh = &shdr[i];
2542 if (sh->sh_type == SHT_SYMTAB) {
2543 if (symtab) {
2544 tcc_error_noabort("object must contain only one symtab");
2545 fail:
2546 ret = -1;
2547 goto the_end;
2549 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2550 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2551 sm_table[i].s = symtab_section;
2553 /* now load strtab */
2554 sh = &shdr[sh->sh_link];
2555 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2557 if (sh->sh_flags & SHF_COMPRESSED)
2558 seencompressed = 1;
2561 /* now examine each section and try to merge its content with the
2562 ones in memory */
2563 for(i = 1; i < ehdr.e_shnum; i++) {
2564 /* no need to examine section name strtab */
2565 if (i == ehdr.e_shstrndx)
2566 continue;
2567 sh = &shdr[i];
2568 if (sh->sh_type == SHT_RELX)
2569 sh = &shdr[sh->sh_info];
2570 /* ignore sections types we do not handle (plus relocs to those) */
2571 if (sh->sh_type != SHT_PROGBITS &&
2572 #ifdef TCC_ARM_EABI
2573 sh->sh_type != SHT_ARM_EXIDX &&
2574 #endif
2575 sh->sh_type != SHT_NOBITS &&
2576 sh->sh_type != SHT_PREINIT_ARRAY &&
2577 sh->sh_type != SHT_INIT_ARRAY &&
2578 sh->sh_type != SHT_FINI_ARRAY &&
2579 strcmp(strsec + sh->sh_name, ".stabstr")
2581 continue;
2582 if (seencompressed
2583 && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
2584 continue;
2586 sh = &shdr[i];
2587 sh_name = strsec + sh->sh_name;
2588 if (sh->sh_addralign < 1)
2589 sh->sh_addralign = 1;
2590 /* find corresponding section, if any */
2591 for(j = 1; j < s1->nb_sections;j++) {
2592 s = s1->sections[j];
2593 if (!strcmp(s->name, sh_name)) {
2594 if (!strncmp(sh_name, ".gnu.linkonce",
2595 sizeof(".gnu.linkonce") - 1)) {
2596 /* if a 'linkonce' section is already present, we
2597 do not add it again. It is a little tricky as
2598 symbols can still be defined in
2599 it. */
2600 sm_table[i].link_once = 1;
2601 goto next;
2602 } else {
2603 goto found;
2607 /* not found: create new section */
2608 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2609 /* take as much info as possible from the section. sh_link and
2610 sh_info will be updated later */
2611 s->sh_addralign = sh->sh_addralign;
2612 s->sh_entsize = sh->sh_entsize;
2613 sm_table[i].new_section = 1;
2614 found:
2615 if (sh->sh_type != s->sh_type) {
2616 tcc_error_noabort("invalid section type");
2617 goto fail;
2620 /* align start of section */
2621 offset = s->data_offset;
2623 if (0 == strcmp(sh_name, ".stab")) {
2624 stab_index = i;
2625 goto no_align;
2627 if (0 == strcmp(sh_name, ".stabstr")) {
2628 stabstr_index = i;
2629 goto no_align;
2632 size = sh->sh_addralign - 1;
2633 offset = (offset + size) & ~size;
2634 if (sh->sh_addralign > s->sh_addralign)
2635 s->sh_addralign = sh->sh_addralign;
2636 s->data_offset = offset;
2637 no_align:
2638 sm_table[i].offset = offset;
2639 sm_table[i].s = s;
2640 /* concatenate sections */
2641 size = sh->sh_size;
2642 if (sh->sh_type != SHT_NOBITS) {
2643 unsigned char *ptr;
2644 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2645 ptr = section_ptr_add(s, size);
2646 full_read(fd, ptr, size);
2647 } else {
2648 s->data_offset += size;
2650 next: ;
2653 /* gr relocate stab strings */
2654 if (stab_index && stabstr_index) {
2655 Stab_Sym *a, *b;
2656 unsigned o;
2657 s = sm_table[stab_index].s;
2658 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2659 b = (Stab_Sym *)(s->data + s->data_offset);
2660 o = sm_table[stabstr_index].offset;
2661 while (a < b) {
2662 if (a->n_strx)
2663 a->n_strx += o;
2664 a++;
2668 /* second short pass to update sh_link and sh_info fields of new
2669 sections */
2670 for(i = 1; i < ehdr.e_shnum; i++) {
2671 s = sm_table[i].s;
2672 if (!s || !sm_table[i].new_section)
2673 continue;
2674 sh = &shdr[i];
2675 if (sh->sh_link > 0)
2676 s->link = sm_table[sh->sh_link].s;
2677 if (sh->sh_type == SHT_RELX) {
2678 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2679 /* update backward link */
2680 s1->sections[s->sh_info]->reloc = s;
2683 sm = sm_table;
2685 /* resolve symbols */
2686 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2688 sym = symtab + 1;
2689 for(i = 1; i < nb_syms; i++, sym++) {
2690 if (sym->st_shndx != SHN_UNDEF &&
2691 sym->st_shndx < SHN_LORESERVE) {
2692 sm = &sm_table[sym->st_shndx];
2693 if (sm->link_once) {
2694 /* if a symbol is in a link once section, we use the
2695 already defined symbol. It is very important to get
2696 correct relocations */
2697 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2698 name = strtab + sym->st_name;
2699 sym_index = find_elf_sym(symtab_section, name);
2700 if (sym_index)
2701 old_to_new_syms[i] = sym_index;
2703 continue;
2705 /* if no corresponding section added, no need to add symbol */
2706 if (!sm->s)
2707 continue;
2708 /* convert section number */
2709 sym->st_shndx = sm->s->sh_num;
2710 /* offset value */
2711 sym->st_value += sm->offset;
2713 /* add symbol */
2714 name = strtab + sym->st_name;
2715 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2716 sym->st_info, sym->st_other,
2717 sym->st_shndx, name);
2718 old_to_new_syms[i] = sym_index;
2721 /* third pass to patch relocation entries */
2722 for(i = 1; i < ehdr.e_shnum; i++) {
2723 s = sm_table[i].s;
2724 if (!s)
2725 continue;
2726 sh = &shdr[i];
2727 offset = sm_table[i].offset;
2728 switch(s->sh_type) {
2729 case SHT_RELX:
2730 /* take relocation offset information */
2731 offseti = sm_table[sh->sh_info].offset;
2732 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2733 int type;
2734 unsigned sym_index;
2735 /* convert symbol index */
2736 type = ELFW(R_TYPE)(rel->r_info);
2737 sym_index = ELFW(R_SYM)(rel->r_info);
2738 /* NOTE: only one symtab assumed */
2739 if (sym_index >= nb_syms)
2740 goto invalid_reloc;
2741 sym_index = old_to_new_syms[sym_index];
2742 /* ignore link_once in rel section. */
2743 if (!sym_index && !sm->link_once
2744 #ifdef TCC_TARGET_ARM
2745 && type != R_ARM_V4BX
2746 #elif defined TCC_TARGET_RISCV64
2747 && type != R_RISCV_ALIGN
2748 && type != R_RISCV_RELAX
2749 #endif
2751 invalid_reloc:
2752 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2753 i, strsec + sh->sh_name, rel->r_offset);
2754 goto fail;
2756 rel->r_info = ELFW(R_INFO)(sym_index, type);
2757 /* offset the relocation offset */
2758 rel->r_offset += offseti;
2759 #ifdef TCC_TARGET_ARM
2760 /* Jumps and branches from a Thumb code to a PLT entry need
2761 special handling since PLT entries are ARM code.
2762 Unconditional bl instructions referencing PLT entries are
2763 handled by converting these instructions into blx
2764 instructions. Other case of instructions referencing a PLT
2765 entry require to add a Thumb stub before the PLT entry to
2766 switch to ARM mode. We set bit plt_thumb_stub of the
2767 attribute of a symbol to indicate such a case. */
2768 if (type == R_ARM_THM_JUMP24)
2769 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2770 #endif
2772 break;
2773 default:
2774 break;
2778 ret = 0;
2779 the_end:
2780 tcc_free(symtab);
2781 tcc_free(strtab);
2782 tcc_free(old_to_new_syms);
2783 tcc_free(sm_table);
2784 tcc_free(strsec);
2785 tcc_free(shdr);
2786 return ret;
2789 typedef struct ArchiveHeader {
2790 char ar_name[16]; /* name of this member */
2791 char ar_date[12]; /* file mtime */
2792 char ar_uid[6]; /* owner uid; printed as decimal */
2793 char ar_gid[6]; /* owner gid; printed as decimal */
2794 char ar_mode[8]; /* file mode, printed as octal */
2795 char ar_size[10]; /* file size, printed as decimal */
2796 char ar_fmag[2]; /* should contain ARFMAG */
2797 } ArchiveHeader;
2799 static int get_be32(const uint8_t *b)
2801 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2804 static long get_be64(const uint8_t *b)
2806 long long ret = get_be32(b);
2807 ret = (ret << 32) | (unsigned)get_be32(b+4);
2808 return (long)ret;
2811 /* load only the objects which resolve undefined symbols */
2812 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2814 long i, bound, nsyms, sym_index, off, ret;
2815 uint8_t *data;
2816 const char *ar_names, *p;
2817 const uint8_t *ar_index;
2818 ElfW(Sym) *sym;
2820 data = tcc_malloc(size);
2821 if (full_read(fd, data, size) != size)
2822 goto fail;
2823 nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
2824 ar_index = data + entrysize;
2825 ar_names = (char *) ar_index + nsyms * entrysize;
2827 do {
2828 bound = 0;
2829 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2830 sym_index = find_elf_sym(symtab_section, p);
2831 if(sym_index) {
2832 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2833 if(sym->st_shndx == SHN_UNDEF) {
2834 off = (entrysize == 4
2835 ? get_be32(ar_index + i * 4)
2836 : get_be64(ar_index + i * 8))
2837 + sizeof(ArchiveHeader);
2838 ++bound;
2839 if(tcc_load_object_file(s1, fd, off) < 0) {
2840 fail:
2841 ret = -1;
2842 goto the_end;
2847 } while(bound);
2848 ret = 0;
2849 the_end:
2850 tcc_free(data);
2851 return ret;
2854 /* load a '.a' file */
2855 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
2857 ArchiveHeader hdr;
2858 char ar_size[11];
2859 char ar_name[17];
2860 char magic[8];
2861 int size, len, i;
2862 unsigned long file_offset;
2864 /* skip magic which was already checked */
2865 full_read(fd, magic, sizeof(magic));
2867 for(;;) {
2868 len = full_read(fd, &hdr, sizeof(hdr));
2869 if (len == 0)
2870 break;
2871 if (len != sizeof(hdr)) {
2872 tcc_error_noabort("invalid archive");
2873 return -1;
2875 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2876 ar_size[sizeof(hdr.ar_size)] = '\0';
2877 size = strtol(ar_size, NULL, 0);
2878 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2879 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2880 if (ar_name[i] != ' ')
2881 break;
2883 ar_name[i + 1] = '\0';
2884 file_offset = lseek(fd, 0, SEEK_CUR);
2885 /* align to even */
2886 size = (size + 1) & ~1;
2887 if (!strcmp(ar_name, "/")) {
2888 /* coff symbol table : we handle it */
2889 if (alacarte)
2890 return tcc_load_alacarte(s1, fd, size, 4);
2891 } else if (!strcmp(ar_name, "/SYM64/")) {
2892 if (alacarte)
2893 return tcc_load_alacarte(s1, fd, size, 8);
2894 } else {
2895 ElfW(Ehdr) ehdr;
2896 if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2897 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2898 return -1;
2901 lseek(fd, file_offset + size, SEEK_SET);
2903 return 0;
2906 #ifndef TCC_TARGET_PE
2907 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
2908 LV, maybe create a new entry for (LIB,VERSION). */
2909 static void set_ver_to_ver(int *n, int **lv, int i, char *lib, char *version)
2911 while (i >= *n) {
2912 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
2913 (*lv)[(*n)++] = -1;
2915 if ((*lv)[i] == -1) {
2916 int v, prev_same_lib = -1;
2917 for (v = 0; v < nb_sym_versions; v++) {
2918 if (strcmp(sym_versions[v].lib, lib))
2919 continue;
2920 prev_same_lib = v;
2921 if (!strcmp(sym_versions[v].version, version))
2922 break;
2924 if (v == nb_sym_versions) {
2925 sym_versions = tcc_realloc (sym_versions,
2926 (v + 1) * sizeof(*sym_versions));
2927 sym_versions[v].lib = tcc_strdup(lib);
2928 sym_versions[v].version = tcc_strdup(version);
2929 sym_versions[v].out_index = 0;
2930 sym_versions[v].prev_same_lib = prev_same_lib;
2931 nb_sym_versions++;
2933 (*lv)[i] = v;
2937 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
2938 VERNDX. */
2939 static void
2940 set_sym_version(int sym_index, int verndx)
2942 if (sym_index >= nb_sym_to_version) {
2943 int newelems = sym_index ? sym_index * 2 : 1;
2944 sym_to_version = tcc_realloc(sym_to_version,
2945 newelems * sizeof(*sym_to_version));
2946 memset(sym_to_version + nb_sym_to_version, -1,
2947 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
2948 nb_sym_to_version = newelems;
2950 if (sym_to_version[sym_index] < 0)
2951 sym_to_version[sym_index] = verndx;
2954 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2955 is referenced by the user (so it should be added as DT_NEEDED in
2956 the generated ELF file) */
2957 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2959 ElfW(Ehdr) ehdr;
2960 ElfW(Shdr) *shdr, *sh, *sh1;
2961 int i, j, nb_syms, nb_dts, sym_bind, ret;
2962 ElfW(Sym) *sym, *dynsym;
2963 ElfW(Dyn) *dt, *dynamic;
2964 int nb_versyms;
2965 ElfW(Verdef) *verdef, *vdef;
2966 ElfW(Verneed) *verneed, *vneed;
2967 ElfW(Half) *versym, *vsym;
2968 char *dynstr;
2969 uint32_t next;
2970 int sym_index;
2971 char *lib, *version;
2972 int nb_local_ver = 0, *local_ver = NULL;
2973 const char *name, *soname;
2974 DLLReference *dllref;
2976 full_read(fd, &ehdr, sizeof(ehdr));
2978 /* test CPU specific stuff */
2979 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2980 ehdr.e_machine != EM_TCC_TARGET) {
2981 tcc_error_noabort("bad architecture");
2982 return -1;
2985 /* read sections */
2986 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2988 /* load dynamic section and dynamic symbols */
2989 nb_syms = 0;
2990 nb_dts = 0;
2991 dynamic = NULL;
2992 dynsym = NULL; /* avoid warning */
2993 dynstr = NULL; /* avoid warning */
2994 nb_versyms = 0;
2995 verdef = NULL;
2996 verneed = NULL;
2997 versym = NULL;
2998 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2999 switch(sh->sh_type) {
3000 case SHT_DYNAMIC:
3001 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3002 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3003 break;
3004 case SHT_DYNSYM:
3005 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3006 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3007 sh1 = &shdr[sh->sh_link];
3008 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3009 break;
3010 case SHT_GNU_verdef:
3011 verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3012 break;
3013 case SHT_GNU_verneed:
3014 verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3015 break;
3016 case SHT_GNU_versym:
3017 nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3018 versym = load_data(fd, sh->sh_offset, sh->sh_size);
3019 break;
3020 default:
3021 break;
3025 /* compute the real library name */
3026 soname = tcc_basename(filename);
3028 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3029 if (dt->d_tag == DT_SONAME) {
3030 soname = dynstr + dt->d_un.d_val;
3034 /* if the dll is already loaded, do not load it */
3035 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3036 dllref = s1->loaded_dlls[i];
3037 if (!strcmp(soname, dllref->name)) {
3038 /* but update level if needed */
3039 if (level < dllref->level)
3040 dllref->level = level;
3041 ret = 0;
3042 goto the_end;
3046 if (nb_versyms != nb_syms) {
3047 tcc_free (versym);
3048 versym = NULL;
3051 #define DEBUG_VERSION 0
3053 if (versym && verdef) {
3054 lib = NULL;
3055 vdef = verdef;
3056 do {
3057 ElfW(Verdaux) *verdaux =
3058 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3060 #if DEBUG_VERSION
3061 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3062 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3063 vdef->vd_hash);
3064 #endif
3065 if (vdef->vd_cnt) {
3066 version = dynstr + verdaux->vda_name;
3068 if (lib == NULL)
3069 lib = version;
3070 else
3071 set_ver_to_ver(&nb_local_ver, &local_ver, vdef->vd_ndx,
3072 lib, version);
3073 #if DEBUG_VERSION
3074 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3075 #endif
3077 next = vdef->vd_next;
3078 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3079 } while (next);
3081 if (versym && verneed) {
3082 vneed = verneed;
3083 do {
3084 ElfW(Vernaux) *vernaux =
3085 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3087 lib = dynstr + vneed->vn_file;
3088 #if DEBUG_VERSION
3089 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3090 #endif
3091 for (i = 0; i < vneed->vn_cnt; i++) {
3092 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3093 version = dynstr + vernaux->vna_name;
3094 set_ver_to_ver(&nb_local_ver, &local_ver, vernaux->vna_other,
3095 lib, version);
3096 #if DEBUG_VERSION
3097 printf (" vernaux(%u): %u %u %s\n",
3098 vernaux->vna_other, vernaux->vna_hash,
3099 vernaux->vna_flags, version);
3100 #endif
3102 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3104 next = vneed->vn_next;
3105 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3106 } while (next);
3109 #if DEBUG_VERSION
3110 for (i = 0; i < nb_local_ver; i++) {
3111 if (local_ver[i] > 0) {
3112 printf ("%d: lib: %s, version %s\n",
3113 i, sym_versions[local_ver[i]].lib,
3114 sym_version[local_ver[i]].version);
3117 #endif
3119 /* add the dll and its level */
3120 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
3121 dllref->level = level;
3122 strcpy(dllref->name, soname);
3123 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
3125 /* add dynamic symbols in dynsym_section */
3126 for(i = 1, sym = dynsym + 1, vsym = versym + 1; i < nb_syms; i++, sym++, vsym++) {
3127 sym_bind = ELFW(ST_BIND)(sym->st_info);
3128 if (sym_bind == STB_LOCAL)
3129 continue;
3130 name = dynstr + sym->st_name;
3131 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3132 sym->st_info, sym->st_other, sym->st_shndx, name);
3133 if (versym && (*vsym & 0x8000) == 0 &&
3134 *vsym > 0 && *vsym < nb_local_ver) {
3135 set_sym_version(sym_index, local_ver[*vsym]);
3139 /* load all referenced DLLs */
3140 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3141 switch(dt->d_tag) {
3142 case DT_NEEDED:
3143 name = dynstr + dt->d_un.d_val;
3144 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3145 dllref = s1->loaded_dlls[j];
3146 if (!strcmp(name, dllref->name))
3147 goto already_loaded;
3149 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3150 tcc_error_noabort("referenced dll '%s' not found", name);
3151 ret = -1;
3152 goto the_end;
3154 already_loaded:
3155 break;
3158 ret = 0;
3159 the_end:
3160 tcc_free(local_ver);
3161 tcc_free(dynstr);
3162 tcc_free(dynsym);
3163 tcc_free(dynamic);
3164 tcc_free(verdef);
3165 tcc_free(verneed);
3166 tcc_free(versym);
3167 tcc_free(shdr);
3168 return ret;
3171 #define LD_TOK_NAME 256
3172 #define LD_TOK_EOF (-1)
3174 /* return next ld script token */
3175 static int ld_next(TCCState *s1, char *name, int name_size)
3177 int c;
3178 char *q;
3180 redo:
3181 switch(ch) {
3182 case ' ':
3183 case '\t':
3184 case '\f':
3185 case '\v':
3186 case '\r':
3187 case '\n':
3188 inp();
3189 goto redo;
3190 case '/':
3191 minp();
3192 if (ch == '*') {
3193 file->buf_ptr = parse_comment(file->buf_ptr);
3194 ch = file->buf_ptr[0];
3195 goto redo;
3196 } else {
3197 q = name;
3198 *q++ = '/';
3199 goto parse_name;
3201 break;
3202 case '\\':
3203 ch = handle_eob();
3204 if (ch != '\\')
3205 goto redo;
3206 /* fall through */
3207 /* case 'a' ... 'z': */
3208 case 'a':
3209 case 'b':
3210 case 'c':
3211 case 'd':
3212 case 'e':
3213 case 'f':
3214 case 'g':
3215 case 'h':
3216 case 'i':
3217 case 'j':
3218 case 'k':
3219 case 'l':
3220 case 'm':
3221 case 'n':
3222 case 'o':
3223 case 'p':
3224 case 'q':
3225 case 'r':
3226 case 's':
3227 case 't':
3228 case 'u':
3229 case 'v':
3230 case 'w':
3231 case 'x':
3232 case 'y':
3233 case 'z':
3234 /* case 'A' ... 'z': */
3235 case 'A':
3236 case 'B':
3237 case 'C':
3238 case 'D':
3239 case 'E':
3240 case 'F':
3241 case 'G':
3242 case 'H':
3243 case 'I':
3244 case 'J':
3245 case 'K':
3246 case 'L':
3247 case 'M':
3248 case 'N':
3249 case 'O':
3250 case 'P':
3251 case 'Q':
3252 case 'R':
3253 case 'S':
3254 case 'T':
3255 case 'U':
3256 case 'V':
3257 case 'W':
3258 case 'X':
3259 case 'Y':
3260 case 'Z':
3261 case '_':
3262 case '.':
3263 case '$':
3264 case '~':
3265 q = name;
3266 parse_name:
3267 for(;;) {
3268 if (!((ch >= 'a' && ch <= 'z') ||
3269 (ch >= 'A' && ch <= 'Z') ||
3270 (ch >= '0' && ch <= '9') ||
3271 strchr("/.-_+=$:\\,~", ch)))
3272 break;
3273 if ((q - name) < name_size - 1) {
3274 *q++ = ch;
3276 minp();
3278 *q = '\0';
3279 c = LD_TOK_NAME;
3280 break;
3281 case CH_EOF:
3282 c = LD_TOK_EOF;
3283 break;
3284 default:
3285 c = ch;
3286 inp();
3287 break;
3289 return c;
3292 static int ld_add_file(TCCState *s1, const char filename[])
3294 if (filename[0] == '/') {
3295 if (CONFIG_SYSROOT[0] == '\0'
3296 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3297 return 0;
3298 filename = tcc_basename(filename);
3300 return tcc_add_dll(s1, filename, 0);
3303 static inline int new_undef_syms(void)
3305 int ret = 0;
3306 ret = new_undef_sym;
3307 new_undef_sym = 0;
3308 return ret;
3311 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3313 char filename[1024], libname[1024];
3314 int t, group, nblibs = 0, ret = 0;
3315 char **libs = NULL;
3317 group = !strcmp(cmd, "GROUP");
3318 if (!as_needed)
3319 new_undef_syms();
3320 t = ld_next(s1, filename, sizeof(filename));
3321 if (t != '(')
3322 expect("(");
3323 t = ld_next(s1, filename, sizeof(filename));
3324 for(;;) {
3325 libname[0] = '\0';
3326 if (t == LD_TOK_EOF) {
3327 tcc_error_noabort("unexpected end of file");
3328 ret = -1;
3329 goto lib_parse_error;
3330 } else if (t == ')') {
3331 break;
3332 } else if (t == '-') {
3333 t = ld_next(s1, filename, sizeof(filename));
3334 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3335 tcc_error_noabort("library name expected");
3336 ret = -1;
3337 goto lib_parse_error;
3339 pstrcpy(libname, sizeof libname, &filename[1]);
3340 if (s1->static_link) {
3341 snprintf(filename, sizeof filename, "lib%s.a", libname);
3342 } else {
3343 snprintf(filename, sizeof filename, "lib%s.so", libname);
3345 } else if (t != LD_TOK_NAME) {
3346 tcc_error_noabort("filename expected");
3347 ret = -1;
3348 goto lib_parse_error;
3350 if (!strcmp(filename, "AS_NEEDED")) {
3351 ret = ld_add_file_list(s1, cmd, 1);
3352 if (ret)
3353 goto lib_parse_error;
3354 } else {
3355 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3356 if (!as_needed) {
3357 ret = ld_add_file(s1, filename);
3358 if (ret)
3359 goto lib_parse_error;
3360 if (group) {
3361 /* Add the filename *and* the libname to avoid future conversions */
3362 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3363 if (libname[0] != '\0')
3364 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3368 t = ld_next(s1, filename, sizeof(filename));
3369 if (t == ',') {
3370 t = ld_next(s1, filename, sizeof(filename));
3373 if (group && !as_needed) {
3374 while (new_undef_syms()) {
3375 int i;
3377 for (i = 0; i < nblibs; i ++)
3378 ld_add_file(s1, libs[i]);
3381 lib_parse_error:
3382 dynarray_reset(&libs, &nblibs);
3383 return ret;
3386 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3387 files */
3388 ST_FUNC int tcc_load_ldscript(TCCState *s1)
3390 char cmd[64];
3391 char filename[1024];
3392 int t, ret;
3394 ch = handle_eob();
3395 for(;;) {
3396 t = ld_next(s1, cmd, sizeof(cmd));
3397 if (t == LD_TOK_EOF)
3398 return 0;
3399 else if (t != LD_TOK_NAME)
3400 return -1;
3401 if (!strcmp(cmd, "INPUT") ||
3402 !strcmp(cmd, "GROUP")) {
3403 ret = ld_add_file_list(s1, cmd, 0);
3404 if (ret)
3405 return ret;
3406 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3407 !strcmp(cmd, "TARGET")) {
3408 /* ignore some commands */
3409 t = ld_next(s1, cmd, sizeof(cmd));
3410 if (t != '(')
3411 expect("(");
3412 for(;;) {
3413 t = ld_next(s1, filename, sizeof(filename));
3414 if (t == LD_TOK_EOF) {
3415 tcc_error_noabort("unexpected end of file");
3416 return -1;
3417 } else if (t == ')') {
3418 break;
3421 } else {
3422 return -1;
3425 return 0;
3427 #endif /* !TCC_TARGET_PE */