allow libtcc states to be used concurrently
[tinycc.git] / tccelf.c
blob2f149225ad5d1aa99df90c4bf615831573888cfb
1 /*
2 * ELF file handling for TCC
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "tcc.h"
23 /* Define this to get some debug output during relocation processing. */
24 #undef DEBUG_RELOC
26 /********************************************************/
27 /* global variables */
29 /* elf version information */
30 struct sym_version {
31 char *lib;
32 char *version;
33 int out_index;
34 int prev_same_lib;
37 #define nb_sym_versions s1->nb_sym_versions
38 #define sym_versions s1->sym_versions
39 #define nb_sym_to_version s1->nb_sym_to_version
40 #define sym_to_version s1->sym_to_version
41 #define dt_verneednum s1->dt_verneednum
42 #define versym_section s1->versym_section
43 #define verneed_section s1->verneed_section
45 /* special flag to indicate that the section should not be linked to the other ones */
46 #define SHF_PRIVATE 0x80000000
47 /* section is dynsymtab_section */
48 #define SHF_DYNSYM 0x40000000
50 /* ------------------------------------------------------------------------- */
52 ST_FUNC void tccelf_new(TCCState *s)
54 TCCState *s1 = s;
55 /* no section zero */
56 dynarray_add(&s->sections, &s->nb_sections, NULL);
58 /* create standard sections */
59 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
60 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
61 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
62 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
63 common_section->sh_num = SHN_COMMON;
65 /* symbols are always generated for linking stage */
66 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
67 ".strtab",
68 ".hashtab", SHF_PRIVATE);
69 s->symtab = symtab_section;
71 /* private symbol table for dynamic symbols */
72 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
73 ".dynstrtab",
74 ".dynhashtab", SHF_PRIVATE);
75 get_sym_attr(s, 0, 1);
78 #ifdef CONFIG_TCC_BCHECK
79 ST_FUNC void tccelf_bounds_new(TCCState *s)
81 TCCState *s1 = s;
82 /* create bounds sections */
83 bounds_section = new_section(s, ".bounds",
84 SHT_PROGBITS, SHF_ALLOC);
85 lbounds_section = new_section(s, ".lbounds",
86 SHT_PROGBITS, SHF_ALLOC);
88 #endif
90 ST_FUNC void tccelf_stab_new(TCCState *s)
92 TCCState *s1 = s;
93 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
94 stab_section->sh_entsize = sizeof(Stab_Sym);
95 stab_section->link = new_section(s, ".stabstr", SHT_STRTAB, 0);
96 put_elf_str(stab_section->link, "");
97 /* put first entry */
98 put_stabs(s, "", 0, 0, 0, 0);
101 static void free_section(Section *s)
103 tcc_free(s->data);
106 ST_FUNC void tccelf_delete(TCCState *s1)
108 int i;
110 #ifndef ELF_OBJ_ONLY
111 /* free symbol versions */
112 for (i = 0; i < nb_sym_versions; i++) {
113 tcc_free(sym_versions[i].version);
114 tcc_free(sym_versions[i].lib);
116 tcc_free(sym_versions);
117 tcc_free(sym_to_version);
118 #endif
120 /* free all sections */
121 for(i = 1; i < s1->nb_sections; i++)
122 free_section(s1->sections[i]);
123 dynarray_reset(&s1->sections, &s1->nb_sections);
125 for(i = 0; i < s1->nb_priv_sections; i++)
126 free_section(s1->priv_sections[i]);
127 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
129 /* free any loaded DLLs */
130 #ifdef TCC_IS_NATIVE
131 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
132 DLLReference *ref = s1->loaded_dlls[i];
133 if ( ref->handle )
134 # ifdef _WIN32
135 FreeLibrary((HMODULE)ref->handle);
136 # else
137 dlclose(ref->handle);
138 # endif
140 #endif
141 /* free loaded dlls array */
142 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
143 tcc_free(s1->sym_attrs);
145 symtab_section = NULL; /* for tccrun.c:rt_printline() */
148 /* save section data state */
149 ST_FUNC void tccelf_begin_file(TCCState *s1)
151 Section *s; int i;
152 for (i = 1; i < s1->nb_sections; i++) {
153 s = s1->sections[i];
154 s->sh_offset = s->data_offset;
156 /* disable symbol hashing during compilation */
157 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
158 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
159 s1->uw_sym = 0;
160 #endif
163 /* At the end of compilation, convert any UNDEF syms to global, and merge
164 with previously existing symbols */
165 ST_FUNC void tccelf_end_file(TCCState *s1)
167 Section *s = s1->symtab;
168 int first_sym, nb_syms, *tr, i;
170 first_sym = s->sh_offset / sizeof (ElfSym);
171 nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
172 s->data_offset = s->sh_offset;
173 s->link->data_offset = s->link->sh_offset;
174 s->hash = s->reloc, s->reloc = NULL;
175 tr = tcc_mallocz(nb_syms * sizeof *tr);
177 for (i = 0; i < nb_syms; ++i) {
178 ElfSym *sym = (ElfSym*)s->data + first_sym + i;
179 if (sym->st_shndx == SHN_UNDEF
180 && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
181 sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
182 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
183 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
185 /* now update relocations */
186 for (i = 1; i < s1->nb_sections; i++) {
187 Section *sr = s1->sections[i];
188 if (sr->sh_type == SHT_RELX && sr->link == s) {
189 ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
190 ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
191 for (; rel < rel_end; ++rel) {
192 int n = ELFW(R_SYM)(rel->r_info) - first_sym;
193 //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
194 rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
198 tcc_free(tr);
201 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
203 Section *sec;
205 sec = tcc_mallocz(sizeof(Section) + strlen(name));
206 sec->s1 = s1;
207 strcpy(sec->name, name);
208 sec->sh_type = sh_type;
209 sec->sh_flags = sh_flags;
210 switch(sh_type) {
211 case SHT_GNU_versym:
212 sec->sh_addralign = 2;
213 break;
214 case SHT_HASH:
215 case SHT_REL:
216 case SHT_RELA:
217 case SHT_DYNSYM:
218 case SHT_SYMTAB:
219 case SHT_DYNAMIC:
220 case SHT_GNU_verneed:
221 case SHT_GNU_verdef:
222 sec->sh_addralign = PTR_SIZE;
223 break;
224 case SHT_STRTAB:
225 sec->sh_addralign = 1;
226 break;
227 default:
228 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */
229 break;
232 if (sh_flags & SHF_PRIVATE) {
233 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
234 } else {
235 sec->sh_num = s1->nb_sections;
236 dynarray_add(&s1->sections, &s1->nb_sections, sec);
239 return sec;
242 ST_FUNC Section *new_symtab(TCCState *s1,
243 const char *symtab_name, int sh_type, int sh_flags,
244 const char *strtab_name,
245 const char *hash_name, int hash_sh_flags)
247 Section *symtab, *strtab, *hash;
248 int *ptr, nb_buckets;
250 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
251 symtab->sh_entsize = sizeof(ElfW(Sym));
252 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
253 put_elf_str(strtab, "");
254 symtab->link = strtab;
255 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
257 nb_buckets = 1;
259 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
260 hash->sh_entsize = sizeof(int);
261 symtab->hash = hash;
262 hash->link = symtab;
264 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
265 ptr[0] = nb_buckets;
266 ptr[1] = 1;
267 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
268 return symtab;
271 /* realloc section and set its content to zero */
272 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
274 unsigned long size;
275 unsigned char *data;
277 size = sec->data_allocated;
278 if (size == 0)
279 size = 1;
280 while (size < new_size)
281 size = size * 2;
282 data = tcc_realloc(sec->data, size);
283 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
284 sec->data = data;
285 sec->data_allocated = size;
288 /* reserve at least 'size' bytes aligned per 'align' in section
289 'sec' from current offset, and return the aligned offset */
290 ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
292 size_t offset, offset1;
294 offset = (sec->data_offset + align - 1) & -align;
295 offset1 = offset + size;
296 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
297 section_realloc(sec, offset1);
298 sec->data_offset = offset1;
299 if (align > sec->sh_addralign)
300 sec->sh_addralign = align;
301 return offset;
304 /* reserve at least 'size' bytes in section 'sec' from
305 sec->data_offset. */
306 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
308 size_t offset = section_add(sec, size, 1);
309 return sec->data + offset;
312 /* reserve at least 'size' bytes from section start */
313 ST_FUNC void section_reserve(Section *sec, unsigned long size)
315 if (size > sec->data_allocated)
316 section_realloc(sec, size);
317 if (size > sec->data_offset)
318 sec->data_offset = size;
321 static Section *find_section_create (TCCState *s1, const char *name, int create)
323 Section *sec;
324 int i;
325 for(i = 1; i < s1->nb_sections; i++) {
326 sec = s1->sections[i];
327 if (!strcmp(name, sec->name))
328 return sec;
330 /* sections are created as PROGBITS */
331 return create ? new_section(s1, name, SHT_PROGBITS, SHF_ALLOC) : NULL;
334 /* return a reference to a section, and create it if it does not
335 exists */
336 ST_FUNC Section *find_section(TCCState *s1, const char *name)
338 return find_section_create (s1, name, 1);
341 /* ------------------------------------------------------------------------- */
343 ST_FUNC int put_elf_str(Section *s, const char *sym)
345 int offset, len;
346 char *ptr;
348 len = strlen(sym) + 1;
349 offset = s->data_offset;
350 ptr = section_ptr_add(s, len);
351 memmove(ptr, sym, len);
352 return offset;
355 /* elf symbol hashing function */
356 static unsigned long elf_hash(const unsigned char *name)
358 unsigned long h = 0, g;
360 while (*name) {
361 h = (h << 4) + *name++;
362 g = h & 0xf0000000;
363 if (g)
364 h ^= g >> 24;
365 h &= ~g;
367 return h;
370 /* rebuild hash table of section s */
371 /* NOTE: we do factorize the hash table code to go faster */
372 static void rebuild_hash(Section *s, unsigned int nb_buckets)
374 ElfW(Sym) *sym;
375 int *ptr, *hash, nb_syms, sym_index, h;
376 unsigned char *strtab;
378 strtab = s->link->data;
379 nb_syms = s->data_offset / sizeof(ElfW(Sym));
381 if (!nb_buckets)
382 nb_buckets = ((int*)s->hash->data)[0];
384 s->hash->data_offset = 0;
385 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
386 ptr[0] = nb_buckets;
387 ptr[1] = nb_syms;
388 ptr += 2;
389 hash = ptr;
390 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
391 ptr += nb_buckets + 1;
393 sym = (ElfW(Sym) *)s->data + 1;
394 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
395 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
396 h = elf_hash(strtab + sym->st_name) % nb_buckets;
397 *ptr = hash[h];
398 hash[h] = sym_index;
399 } else {
400 *ptr = 0;
402 ptr++;
403 sym++;
407 /* return the symbol number */
408 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
409 int info, int other, int shndx, const char *name)
411 int name_offset, sym_index;
412 int nbuckets, h;
413 ElfW(Sym) *sym;
414 Section *hs;
416 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
417 if (name && name[0])
418 name_offset = put_elf_str(s->link, name);
419 else
420 name_offset = 0;
421 /* XXX: endianness */
422 sym->st_name = name_offset;
423 sym->st_value = value;
424 sym->st_size = size;
425 sym->st_info = info;
426 sym->st_other = other;
427 sym->st_shndx = shndx;
428 sym_index = sym - (ElfW(Sym) *)s->data;
429 hs = s->hash;
430 if (hs) {
431 int *ptr, *base;
432 ptr = section_ptr_add(hs, sizeof(int));
433 base = (int *)hs->data;
434 /* only add global or weak symbols. */
435 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
436 /* add another hashing entry */
437 nbuckets = base[0];
438 h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
439 *ptr = base[2 + h];
440 base[2 + h] = sym_index;
441 base[1]++;
442 /* we resize the hash table */
443 hs->nb_hashed_syms++;
444 if (hs->nb_hashed_syms > 2 * nbuckets) {
445 rebuild_hash(s, 2 * nbuckets);
447 } else {
448 *ptr = 0;
449 base[1]++;
452 return sym_index;
455 ST_FUNC int find_elf_sym(Section *s, const char *name)
457 ElfW(Sym) *sym;
458 Section *hs;
459 int nbuckets, sym_index, h;
460 const char *name1;
462 hs = s->hash;
463 if (!hs)
464 return 0;
465 nbuckets = ((int *)hs->data)[0];
466 h = elf_hash((unsigned char *) name) % nbuckets;
467 sym_index = ((int *)hs->data)[2 + h];
468 while (sym_index != 0) {
469 sym = &((ElfW(Sym) *)s->data)[sym_index];
470 name1 = (char *) s->link->data + sym->st_name;
471 if (!strcmp(name, name1))
472 return sym_index;
473 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
475 return 0;
478 /* return elf symbol value, signal error if 'err' is nonzero */
479 ST_FUNC addr_t get_elf_sym_addr(TCCState *s1, const char *name, int err)
481 int sym_index;
482 ElfW(Sym) *sym;
484 sym_index = find_elf_sym(s1->symtab, name);
485 sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
486 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
487 if (err)
488 tcc_error("%s not defined", name);
489 return 0;
491 return sym->st_value;
494 /* list elf symbol names and values */
495 ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
496 void (*symbol_cb)(void *ctx, const char *name, const void *val))
498 ElfW(Sym) *sym;
499 Section *symtab;
500 int sym_index, end_sym;
501 const char *name;
502 unsigned char sym_vis, sym_bind;
504 symtab = s->symtab;
505 end_sym = symtab->data_offset / sizeof (ElfSym);
506 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
507 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
508 if (sym->st_value) {
509 name = (char *) symtab->link->data + sym->st_name;
510 sym_bind = ELFW(ST_BIND)(sym->st_info);
511 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
512 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
513 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
518 /* return elf symbol value */
519 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
521 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0);
524 /* list elf symbol names and values */
525 LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
526 void (*symbol_cb)(void *ctx, const char *name, const void *val))
528 list_elf_symbols(s, ctx, symbol_cb);
531 #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
532 /* return elf symbol value or error */
533 ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
535 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1);
537 #endif
539 #ifndef ELF_OBJ_ONLY
540 static void
541 version_add (TCCState *s1)
543 int i;
544 ElfW(Sym) *sym;
545 ElfW(Verneed) *vn = NULL;
546 Section *symtab;
547 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
548 ElfW(Half) *versym;
549 const char *name;
551 if (0 == nb_sym_versions)
552 return;
553 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
554 versym_section->sh_entsize = sizeof(ElfW(Half));
555 verneed_section = new_section(s1, ".gnu.version_r", SHT_GNU_verneed, SHF_ALLOC);
556 versym_section->link = s1->dynsym;
557 verneed_section->link = s1->dynsym->link;
559 /* add needed symbols */
560 symtab = s1->dynsym;
561 end_sym = symtab->data_offset / sizeof (ElfSym);
562 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
563 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
564 int dllindex, verndx;
565 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
566 name = (char *) symtab->link->data + sym->st_name;
567 dllindex = find_elf_sym(s1->dynsymtab_section, name);
568 verndx = (dllindex && dllindex < nb_sym_to_version)
569 ? sym_to_version[dllindex] : -1;
570 if (verndx >= 0) {
571 if (!sym_versions[verndx].out_index)
572 sym_versions[verndx].out_index = nb_versions++;
573 versym[sym_index] = sym_versions[verndx].out_index;
574 } else
575 versym[sym_index] = 0;
577 /* generate verneed section */
578 for (i = nb_sym_versions; i-- > 0;) {
579 struct sym_version *sv = &sym_versions[i];
580 int n_same_libs = 0, prev;
581 size_t vnofs;
582 ElfW(Vernaux) *vna = 0;
583 if (sv->out_index < 1)
584 continue;
585 vnofs = section_add(verneed_section, sizeof(*vn), 1);
586 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
587 vn->vn_version = 1;
588 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
589 vn->vn_aux = sizeof (*vn);
590 do {
591 prev = sv->prev_same_lib;
592 if (sv->out_index > 0) {
593 vna = section_ptr_add(verneed_section, sizeof(*vna));
594 vna->vna_hash = elf_hash (sv->version);
595 vna->vna_flags = 0;
596 vna->vna_other = sv->out_index;
597 sv->out_index = -2;
598 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
599 vna->vna_next = sizeof (*vna);
600 n_same_libs++;
602 sv = &sym_versions[prev];
603 } while(prev >= 0);
604 vna->vna_next = 0;
605 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
606 vn->vn_cnt = n_same_libs;
607 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
608 nb_entries++;
610 if (vn)
611 vn->vn_next = 0;
612 verneed_section->sh_info = nb_entries;
613 dt_verneednum = nb_entries;
615 #endif
617 /* add an elf symbol : check if it is already defined and patch
618 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
619 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
620 int info, int other, int shndx, const char *name)
622 TCCState *s1 = s->s1;
623 ElfW(Sym) *esym;
624 int sym_bind, sym_index, sym_type, esym_bind;
625 unsigned char sym_vis, esym_vis, new_vis;
627 sym_bind = ELFW(ST_BIND)(info);
628 sym_type = ELFW(ST_TYPE)(info);
629 sym_vis = ELFW(ST_VISIBILITY)(other);
631 if (sym_bind != STB_LOCAL) {
632 /* we search global or weak symbols */
633 sym_index = find_elf_sym(s, name);
634 if (!sym_index)
635 goto do_def;
636 esym = &((ElfW(Sym) *)s->data)[sym_index];
637 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
638 && esym->st_other == other && esym->st_shndx == shndx)
639 return sym_index;
640 if (esym->st_shndx != SHN_UNDEF) {
641 esym_bind = ELFW(ST_BIND)(esym->st_info);
642 /* propagate the most constraining visibility */
643 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
644 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
645 if (esym_vis == STV_DEFAULT) {
646 new_vis = sym_vis;
647 } else if (sym_vis == STV_DEFAULT) {
648 new_vis = esym_vis;
649 } else {
650 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
652 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
653 | new_vis;
654 other = esym->st_other; /* in case we have to patch esym */
655 if (shndx == SHN_UNDEF) {
656 /* ignore adding of undefined symbol if the
657 corresponding symbol is already defined */
658 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
659 /* global overrides weak, so patch */
660 goto do_patch;
661 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
662 /* weak is ignored if already global */
663 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
664 /* keep first-found weak definition, ignore subsequents */
665 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
666 /* ignore hidden symbols after */
667 } else if ((esym->st_shndx == SHN_COMMON
668 || esym->st_shndx == bss_section->sh_num)
669 && (shndx < SHN_LORESERVE
670 && shndx != bss_section->sh_num)) {
671 /* data symbol gets precedence over common/bss */
672 goto do_patch;
673 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
674 /* data symbol keeps precedence over common/bss */
675 } else if (s->sh_flags & SHF_DYNSYM) {
676 /* we accept that two DLL define the same symbol */
677 } else if (esym->st_other & ST_ASM_SET) {
678 /* If the existing symbol came from an asm .set
679 we can override. */
680 goto do_patch;
681 } else {
682 #if 0
683 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
684 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
685 #endif
686 tcc_error_noabort("'%s' defined twice", name);
688 } else {
689 do_patch:
690 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
691 esym->st_shndx = shndx;
692 s1->new_undef_sym = 1;
693 esym->st_value = value;
694 esym->st_size = size;
695 esym->st_other = other;
697 } else {
698 do_def:
699 sym_index = put_elf_sym(s, value, size,
700 ELFW(ST_INFO)(sym_bind, sym_type), other,
701 shndx, name);
703 return sym_index;
706 /* put relocation */
707 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
708 int type, int symbol, addr_t addend)
710 TCCState *s1 = s->s1;
711 char buf[256];
712 Section *sr;
713 ElfW_Rel *rel;
715 sr = s->reloc;
716 if (!sr) {
717 /* if no relocation section, create it */
718 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
719 /* if the symtab is allocated, then we consider the relocation
720 are also */
721 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
722 sr->sh_entsize = sizeof(ElfW_Rel);
723 sr->link = symtab;
724 sr->sh_info = s->sh_num;
725 s->reloc = sr;
727 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
728 rel->r_offset = offset;
729 rel->r_info = ELFW(R_INFO)(symbol, type);
730 #if SHT_RELX == SHT_RELA
731 rel->r_addend = addend;
732 #endif
733 if (SHT_RELX != SHT_RELA && addend)
734 tcc_error("non-zero addend on REL architecture");
737 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
738 int type, int symbol)
740 put_elf_reloca(symtab, s, offset, type, symbol, 0);
743 /* Remove relocations for section S->reloc starting at oldrelocoffset
744 that are to the same place, retaining the last of them. As side effect
745 the relocations are sorted. Possibly reduces the number of relocs. */
746 ST_FUNC void squeeze_multi_relocs(Section *s, size_t oldrelocoffset)
748 Section *sr = s->reloc;
749 ElfW_Rel *r, *dest;
750 ssize_t a;
751 ElfW(Addr) addr;
753 if (oldrelocoffset + sizeof(*r) >= sr->data_offset)
754 return;
755 /* The relocs we're dealing with are the result of initializer parsing.
756 So they will be mostly in order and there aren't many of them.
757 Secondly we need a stable sort (which qsort isn't). We use
758 a simple insertion sort. */
759 for (a = oldrelocoffset + sizeof(*r); a < sr->data_offset; a += sizeof(*r)) {
760 ssize_t i = a - sizeof(*r);
761 addr = ((ElfW_Rel*)(sr->data + a))->r_offset;
762 for (; i >= (ssize_t)oldrelocoffset &&
763 ((ElfW_Rel*)(sr->data + i))->r_offset > addr; i -= sizeof(*r)) {
764 ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a);
765 *(ElfW_Rel*)(sr->data + a) = *(ElfW_Rel*)(sr->data + i);
766 *(ElfW_Rel*)(sr->data + i) = tmp;
770 r = (ElfW_Rel*)(sr->data + oldrelocoffset);
771 dest = r;
772 for (; r < (ElfW_Rel*)(sr->data + sr->data_offset); r++) {
773 if (dest->r_offset != r->r_offset)
774 dest++;
775 *dest = *r;
777 sr->data_offset = (unsigned char*)dest - sr->data + sizeof(*r);
780 /* put stab debug information */
782 ST_FUNC void put_stabs(TCCState *s1, const char *str, int type, int other, int desc,
783 unsigned long value)
785 Stab_Sym *sym;
787 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
788 if (str) {
789 sym->n_strx = put_elf_str(stab_section->link, str);
790 } else {
791 sym->n_strx = 0;
793 sym->n_type = type;
794 sym->n_other = other;
795 sym->n_desc = desc;
796 sym->n_value = value;
799 ST_FUNC void put_stabs_r(TCCState *s1, const char *str, int type, int other, int desc,
800 unsigned long value, Section *sec, int sym_index)
802 put_stabs(s1, str, type, other, desc, value);
803 put_elf_reloc(symtab_section, stab_section,
804 stab_section->data_offset - sizeof(unsigned int),
805 R_DATA_32, sym_index);
808 ST_FUNC void put_stabn(TCCState *s1, int type, int other, int desc, int value)
810 put_stabs(s1, NULL, type, other, desc, value);
813 ST_FUNC void put_stabd(TCCState *s1, int type, int other, int desc)
815 put_stabs(s1, NULL, type, other, desc, 0);
818 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
820 int n;
821 struct sym_attr *tab;
823 if (index >= s1->nb_sym_attrs) {
824 if (!alloc)
825 return s1->sym_attrs;
826 /* find immediately bigger power of 2 and reallocate array */
827 n = 1;
828 while (index >= n)
829 n *= 2;
830 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
831 s1->sym_attrs = tab;
832 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
833 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
834 s1->nb_sym_attrs = n;
836 return &s1->sym_attrs[index];
839 /* Browse each elem of type <type> in section <sec> starting at elem <startoff>
840 using variable <elem> */
841 #define for_each_elem(sec, startoff, elem, type) \
842 for (elem = (type *) sec->data + startoff; \
843 elem < (type *) (sec->data + sec->data_offset); elem++)
845 /* In an ELF file symbol table, the local symbols must appear below
846 the global and weak ones. Since TCC cannot sort it while generating
847 the code, we must do it after. All the relocation tables are also
848 modified to take into account the symbol table sorting */
849 static void sort_syms(TCCState *s1, Section *s)
851 int *old_to_new_syms;
852 ElfW(Sym) *new_syms;
853 int nb_syms, i;
854 ElfW(Sym) *p, *q;
855 ElfW_Rel *rel;
856 Section *sr;
857 int type, sym_index;
859 nb_syms = s->data_offset / sizeof(ElfW(Sym));
860 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
861 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
863 /* first pass for local symbols */
864 p = (ElfW(Sym) *)s->data;
865 q = new_syms;
866 for(i = 0; i < nb_syms; i++) {
867 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
868 old_to_new_syms[i] = q - new_syms;
869 *q++ = *p;
871 p++;
873 /* save the number of local symbols in section header */
874 if( s->sh_size ) /* this 'if' makes IDA happy */
875 s->sh_info = q - new_syms;
877 /* then second pass for non local symbols */
878 p = (ElfW(Sym) *)s->data;
879 for(i = 0; i < nb_syms; i++) {
880 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
881 old_to_new_syms[i] = q - new_syms;
882 *q++ = *p;
884 p++;
887 /* we copy the new symbols to the old */
888 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
889 tcc_free(new_syms);
891 /* now we modify all the relocations */
892 for(i = 1; i < s1->nb_sections; i++) {
893 sr = s1->sections[i];
894 if (sr->sh_type == SHT_RELX && sr->link == s) {
895 for_each_elem(sr, 0, rel, ElfW_Rel) {
896 sym_index = ELFW(R_SYM)(rel->r_info);
897 type = ELFW(R_TYPE)(rel->r_info);
898 sym_index = old_to_new_syms[sym_index];
899 rel->r_info = ELFW(R_INFO)(sym_index, type);
904 tcc_free(old_to_new_syms);
907 /* relocate symbol table, resolve undefined symbols if do_resolve is
908 true and output error if undefined symbol. */
909 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
911 ElfW(Sym) *sym;
912 int sym_bind, sh_num;
913 const char *name;
915 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
916 sh_num = sym->st_shndx;
917 if (sh_num == SHN_UNDEF) {
918 name = (char *) s1->symtab->link->data + sym->st_name;
919 /* Use ld.so to resolve symbol for us (for tcc -run) */
920 if (do_resolve) {
921 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
922 void *addr = dlsym(RTLD_DEFAULT, name);
923 if (addr) {
924 sym->st_value = (addr_t) addr;
925 #ifdef DEBUG_RELOC
926 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
927 #endif
928 goto found;
930 #endif
931 /* if dynamic symbol exist, it will be used in relocate_section */
932 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
933 goto found;
934 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
935 it */
936 if (!strcmp(name, "_fp_hw"))
937 goto found;
938 /* only weak symbols are accepted to be undefined. Their
939 value is zero */
940 sym_bind = ELFW(ST_BIND)(sym->st_info);
941 if (sym_bind == STB_WEAK)
942 sym->st_value = 0;
943 else
944 tcc_error_noabort("undefined symbol '%s'", name);
945 } else if (sh_num < SHN_LORESERVE) {
946 /* add section base */
947 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
949 found: ;
953 /* relocate a given section (CPU dependent) by applying the relocations
954 in the associated relocation section */
955 ST_FUNC void relocate_section(TCCState *s1, Section *s)
957 Section *sr = s->reloc;
958 ElfW_Rel *rel;
959 ElfW(Sym) *sym;
960 int type, sym_index;
961 unsigned char *ptr;
962 addr_t tgt, addr;
964 qrel = (ElfW_Rel *)sr->data;
966 for_each_elem(sr, 0, rel, ElfW_Rel) {
967 ptr = s->data + rel->r_offset;
968 sym_index = ELFW(R_SYM)(rel->r_info);
969 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
970 type = ELFW(R_TYPE)(rel->r_info);
971 tgt = sym->st_value;
972 #if SHT_RELX == SHT_RELA
973 tgt += rel->r_addend;
974 #endif
975 addr = s->sh_addr + rel->r_offset;
976 relocate(s1, rel, type, ptr, addr, tgt);
978 /* if the relocation is allocated, we change its symbol table */
979 if (sr->sh_flags & SHF_ALLOC)
980 sr->link = s1->dynsym;
983 #ifndef ELF_OBJ_ONLY
984 /* relocate relocation table in 'sr' */
985 static void relocate_rel(TCCState *s1, Section *sr)
987 Section *s;
988 ElfW_Rel *rel;
990 s = s1->sections[sr->sh_info];
991 for_each_elem(sr, 0, rel, ElfW_Rel)
992 rel->r_offset += s->sh_addr;
995 /* count the number of dynamic relocations so that we can reserve
996 their space */
997 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
999 int count = 0;
1000 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1001 ElfW_Rel *rel;
1002 for_each_elem(sr, 0, rel, ElfW_Rel) {
1003 int sym_index = ELFW(R_SYM)(rel->r_info);
1004 int type = ELFW(R_TYPE)(rel->r_info);
1005 switch(type) {
1006 #if defined(TCC_TARGET_I386)
1007 case R_386_32:
1008 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
1009 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
1010 /* don't fixup unresolved (weak) symbols */
1011 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
1012 break;
1014 #elif defined(TCC_TARGET_X86_64)
1015 case R_X86_64_32:
1016 case R_X86_64_32S:
1017 case R_X86_64_64:
1018 #endif
1019 count++;
1020 break;
1021 #if defined(TCC_TARGET_I386)
1022 case R_386_PC32:
1023 #elif defined(TCC_TARGET_X86_64)
1024 case R_X86_64_PC32:
1025 #endif
1026 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1027 count++;
1028 break;
1029 default:
1030 break;
1033 if (count) {
1034 /* allocate the section */
1035 sr->sh_flags |= SHF_ALLOC;
1036 sr->sh_size = count * sizeof(ElfW_Rel);
1038 #endif
1039 return count;
1042 static void build_got(TCCState *s1)
1044 /* if no got, then create it */
1045 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1046 s1->got->sh_entsize = 4;
1047 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1048 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1049 /* keep space for _DYNAMIC pointer and two dummy got entries */
1050 section_ptr_add(s1->got, 3 * PTR_SIZE);
1053 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1054 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1055 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1056 Returns the offset of the GOT or (if any) PLT entry. */
1057 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1058 int sym_index)
1060 int need_plt_entry;
1061 const char *name;
1062 ElfW(Sym) *sym;
1063 struct sym_attr *attr;
1064 unsigned got_offset;
1065 char plt_name[100];
1066 int len;
1068 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1069 attr = get_sym_attr(s1, sym_index, 1);
1071 /* In case a function is both called and its address taken 2 GOT entries
1072 are created, one for taking the address (GOT) and the other for the PLT
1073 entry (PLTGOT). */
1074 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1075 return attr;
1077 /* create the GOT entry */
1078 got_offset = s1->got->data_offset;
1079 section_ptr_add(s1->got, PTR_SIZE);
1081 /* Create the GOT relocation that will insert the address of the object or
1082 function of interest in the GOT entry. This is a static relocation for
1083 memory output (dlsym will give us the address of symbols) and dynamic
1084 relocation otherwise (executable and DLLs). The relocation should be
1085 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1086 associated to a PLT entry) but is currently done at load time for an
1087 unknown reason. */
1089 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1090 name = (char *) symtab_section->link->data + sym->st_name;
1092 if (s1->dynsym) {
1093 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1094 /* Hack alarm. We don't want to emit dynamic symbols
1095 and symbol based relocs for STB_LOCAL symbols, but rather
1096 want to resolve them directly. At this point the symbol
1097 values aren't final yet, so we must defer this. We will later
1098 have to create a RELATIVE reloc anyway, so we misuse the
1099 relocation slot to smuggle the symbol reference until
1100 fill_local_got_entries. Not that the sym_index is
1101 relative to symtab_section, not s1->dynsym! Nevertheless
1102 we use s1->dyn_sym so that if this is the first call
1103 that got->reloc is correctly created. Also note that
1104 RELATIVE relocs are not normally created for the .got,
1105 so the types serves as a marker for later (and is retained
1106 also for the final output, which is okay because then the
1107 got is just normal data). */
1108 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1109 sym_index);
1110 } else {
1111 if (0 == attr->dyn_index)
1112 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1113 sym->st_size, sym->st_info, 0,
1114 sym->st_shndx, name);
1115 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
1116 attr->dyn_index);
1118 } else {
1119 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1120 sym_index);
1123 if (need_plt_entry) {
1124 if (!s1->plt) {
1125 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1126 SHF_ALLOC | SHF_EXECINSTR);
1127 s1->plt->sh_entsize = 4;
1130 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1132 /* create a symbol 'sym@plt' for the PLT jump vector */
1133 len = strlen(name);
1134 if (len > sizeof plt_name - 5)
1135 len = sizeof plt_name - 5;
1136 memcpy(plt_name, name, len);
1137 strcpy(plt_name + len, "@plt");
1138 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
1139 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1141 } else {
1142 attr->got_offset = got_offset;
1145 return attr;
1148 /* build GOT and PLT entries */
1149 ST_FUNC void build_got_entries(TCCState *s1)
1151 Section *s;
1152 ElfW_Rel *rel;
1153 ElfW(Sym) *sym;
1154 int i, type, gotplt_entry, reloc_type, sym_index;
1155 struct sym_attr *attr;
1157 for(i = 1; i < s1->nb_sections; i++) {
1158 s = s1->sections[i];
1159 if (s->sh_type != SHT_RELX)
1160 continue;
1161 /* no need to handle got relocations */
1162 if (s->link != symtab_section)
1163 continue;
1164 for_each_elem(s, 0, rel, ElfW_Rel) {
1165 type = ELFW(R_TYPE)(rel->r_info);
1166 gotplt_entry = gotplt_entry_type(type);
1167 if (gotplt_entry == -1)
1168 tcc_error ("Unknown relocation type for got: %d", type);
1169 sym_index = ELFW(R_SYM)(rel->r_info);
1170 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1172 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1173 continue;
1176 /* Automatically create PLT/GOT [entry] if it is an undefined
1177 reference (resolved at runtime), or the symbol is absolute,
1178 probably created by tcc_add_symbol, and thus on 64-bit
1179 targets might be too far from application code. */
1180 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1181 if (sym->st_shndx == SHN_UNDEF) {
1182 ElfW(Sym) *esym;
1183 int dynindex;
1184 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1185 continue;
1186 /* Relocations for UNDEF symbols would normally need
1187 to be transferred into the executable or shared object.
1188 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1189 But TCC doesn't do that (at least for exes), so we
1190 need to resolve all such relocs locally. And that
1191 means PLT slots for functions in DLLs and COPY relocs for
1192 data symbols. COPY relocs were generated in
1193 bind_exe_dynsyms (and the symbol adjusted to be defined),
1194 and for functions we were generated a dynamic symbol
1195 of function type. */
1196 if (s1->dynsym) {
1197 /* dynsym isn't set for -run :-/ */
1198 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1199 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1200 if (dynindex
1201 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1202 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1203 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1204 goto jmp_slot;
1206 } else if (!(sym->st_shndx == SHN_ABS
1207 #ifndef TCC_TARGET_ARM
1208 && PTR_SIZE == 8
1209 #endif
1211 continue;
1214 #ifdef TCC_TARGET_X86_64
1215 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1216 sym->st_shndx != SHN_UNDEF &&
1217 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1218 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1219 s1->output_type == TCC_OUTPUT_EXE)) {
1220 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1221 continue;
1223 #endif
1224 reloc_type = code_reloc(type);
1225 if (reloc_type == -1)
1226 tcc_error ("Unknown relocation type: %d", type);
1227 else if (reloc_type != 0) {
1228 jmp_slot:
1229 reloc_type = R_JMP_SLOT;
1230 } else
1231 reloc_type = R_GLOB_DAT;
1233 if (!s1->got)
1234 build_got(s1);
1236 if (gotplt_entry == BUILD_GOT_ONLY)
1237 continue;
1239 attr = put_got_entry(s1, reloc_type, sym_index);
1241 if (reloc_type == R_JMP_SLOT)
1242 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1247 /* put dynamic tag */
1248 static void put_dt(Section *dynamic, int dt, addr_t val)
1250 ElfW(Dyn) *dyn;
1251 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1252 dyn->d_tag = dt;
1253 dyn->d_un.d_val = val;
1255 #endif
1257 static void add_init_array_defines(TCCState *s1, const char *section_name)
1259 Section *s;
1260 long end_offset;
1261 char sym_start[1024];
1262 char sym_end[1024];
1264 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1265 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1267 s = find_section(s1, section_name);
1268 if (!s) {
1269 end_offset = 0;
1270 s = data_section;
1271 } else {
1272 end_offset = s->data_offset;
1275 set_elf_sym(symtab_section,
1276 0, 0,
1277 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1278 s->sh_num, sym_start);
1279 set_elf_sym(symtab_section,
1280 end_offset, 0,
1281 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1282 s->sh_num, sym_end);
1285 #ifndef TCC_TARGET_PE
1286 static int tcc_add_support(TCCState *s1, const char *filename)
1288 char buf[1024];
1289 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1290 return tcc_add_file(s1, buf);
1292 #endif
1294 static void add_array (const char *section, TCCState *s1, Sym *sym)
1296 Section *s;
1297 unsigned char *ptr;
1299 s = find_section(s1, section);
1300 if (s) {
1301 s->sh_flags |= SHF_WRITE;
1302 ptr = section_ptr_add(s, PTR_SIZE);
1303 memset (ptr, 0, PTR_SIZE);
1304 put_elf_reloc (s1->symtab, s, ptr - s->data, R_DATA_PTR, sym->c);
1308 ST_FUNC void add_init_array (TCCState *s1, Sym *sym)
1310 add_array (".init_array", s1, sym);
1313 ST_FUNC void add_fini_array (TCCState *s1, Sym *sym)
1315 add_array (".fini_array", s1, sym);
1318 /* add tcc runtime libraries */
1319 ST_FUNC void tcc_add_runtime(TCCState *s1)
1321 s1->filetype = 0;
1322 #ifdef CONFIG_TCC_BCHECK
1323 tcc_add_bcheck(s1);
1324 #endif
1325 tcc_add_pragma_libs(s1);
1326 #ifndef TCC_TARGET_PE
1327 /* add libc */
1328 if (!s1->nostdlib) {
1329 tcc_add_library_err(s1, "c");
1330 #ifdef TCC_LIBGCC
1331 if (!s1->static_link) {
1332 if (TCC_LIBGCC[0] == '/')
1333 tcc_add_file(s1, TCC_LIBGCC);
1334 else
1335 tcc_add_dll(s1, TCC_LIBGCC, 0);
1337 #endif
1338 #ifdef CONFIG_TCC_BCHECK
1339 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1340 tcc_add_library_err(s1, "pthread");
1341 tcc_add_library_err(s1, "dl");
1342 tcc_add_support(s1, TCC_LIBTCCB1);
1344 #endif
1345 tcc_add_support(s1, TCC_LIBTCC1);
1346 /* add crt end if not memory output */
1347 if (s1->output_type != TCC_OUTPUT_MEMORY)
1348 tcc_add_crt(s1, "crtn.o");
1350 #endif
1353 /* add various standard linker symbols (must be done after the
1354 sections are filled (for example after allocating common
1355 symbols)) */
1356 static void tcc_add_linker_symbols(TCCState *s1)
1358 char buf[1024];
1359 int i;
1360 Section *s;
1362 set_elf_sym(symtab_section,
1363 text_section->data_offset, 0,
1364 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1365 text_section->sh_num, "_etext");
1366 set_elf_sym(symtab_section,
1367 data_section->data_offset, 0,
1368 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1369 data_section->sh_num, "_edata");
1370 set_elf_sym(symtab_section,
1371 bss_section->data_offset, 0,
1372 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1373 bss_section->sh_num, "_end");
1374 #ifdef TCC_TARGET_RISCV64
1375 /* XXX should be .sdata+0x800, not .data+0x800 */
1376 set_elf_sym(symtab_section,
1377 0x800, 0,
1378 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1379 data_section->sh_num, "__global_pointer$");
1380 #endif
1381 /* horrible new standard ldscript defines */
1382 add_init_array_defines(s1, ".preinit_array");
1383 add_init_array_defines(s1, ".init_array");
1384 add_init_array_defines(s1, ".fini_array");
1386 /* add start and stop symbols for sections whose name can be
1387 expressed in C */
1388 for(i = 1; i < s1->nb_sections; i++) {
1389 s = s1->sections[i];
1390 if (s->sh_type == SHT_PROGBITS &&
1391 (s->sh_flags & SHF_ALLOC)) {
1392 const char *p;
1393 int ch;
1395 /* check if section name can be expressed in C */
1396 p = s->name;
1397 for(;;) {
1398 ch = *p;
1399 if (!ch)
1400 break;
1401 if (!isid(ch) && !isnum(ch))
1402 goto next_sec;
1403 p++;
1405 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1406 set_elf_sym(symtab_section,
1407 0, 0,
1408 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1409 s->sh_num, buf);
1410 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1411 set_elf_sym(symtab_section,
1412 s->data_offset, 0,
1413 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1414 s->sh_num, buf);
1416 next_sec: ;
1420 ST_FUNC void resolve_common_syms(TCCState *s1)
1422 ElfW(Sym) *sym;
1424 /* Allocate common symbols in BSS. */
1425 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1426 if (sym->st_shndx == SHN_COMMON) {
1427 /* symbol alignment is in st_value for SHN_COMMONs */
1428 sym->st_value = section_add(bss_section, sym->st_size,
1429 sym->st_value);
1430 sym->st_shndx = bss_section->sh_num;
1434 /* Now assign linker provided symbols their value. */
1435 tcc_add_linker_symbols(s1);
1438 static void tcc_output_binary(TCCState *s1, FILE *f,
1439 const int *sec_order)
1441 Section *s;
1442 int i, offset, size;
1444 offset = 0;
1445 for(i=1;i<s1->nb_sections;i++) {
1446 s = s1->sections[sec_order[i]];
1447 if (s->sh_type != SHT_NOBITS &&
1448 (s->sh_flags & SHF_ALLOC)) {
1449 while (offset < s->sh_offset) {
1450 fputc(0, f);
1451 offset++;
1453 size = s->sh_size;
1454 fwrite(s->data, 1, size, f);
1455 offset += size;
1460 #ifndef ELF_OBJ_ONLY
1461 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1463 int sym_index = ELFW(R_SYM) (rel->r_info);
1464 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1465 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1466 unsigned offset = attr->got_offset;
1468 if (0 == offset)
1469 return;
1470 section_reserve(s1->got, offset + PTR_SIZE);
1471 #ifdef TCC_TARGET_X86_64
1472 write64le(s1->got->data + offset, sym->st_value);
1473 #else
1474 write32le(s1->got->data + offset, sym->st_value);
1475 #endif
1478 /* Perform relocation to GOT or PLT entries */
1479 ST_FUNC void fill_got(TCCState *s1)
1481 Section *s;
1482 ElfW_Rel *rel;
1483 int i;
1485 for(i = 1; i < s1->nb_sections; i++) {
1486 s = s1->sections[i];
1487 if (s->sh_type != SHT_RELX)
1488 continue;
1489 /* no need to handle got relocations */
1490 if (s->link != symtab_section)
1491 continue;
1492 for_each_elem(s, 0, rel, ElfW_Rel) {
1493 switch (ELFW(R_TYPE) (rel->r_info)) {
1494 case R_X86_64_GOT32:
1495 case R_X86_64_GOTPCREL:
1496 case R_X86_64_GOTPCRELX:
1497 case R_X86_64_REX_GOTPCRELX:
1498 case R_X86_64_PLT32:
1499 fill_got_entry(s1, rel);
1500 break;
1506 /* See put_got_entry for a description. This is the second stage
1507 where GOT references to local defined symbols are rewritten. */
1508 static void fill_local_got_entries(TCCState *s1)
1510 ElfW_Rel *rel;
1511 if (!s1->got->reloc)
1512 return;
1513 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1514 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1515 int sym_index = ELFW(R_SYM) (rel->r_info);
1516 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1517 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1518 unsigned offset = attr->got_offset;
1519 if (offset != rel->r_offset - s1->got->sh_addr)
1520 tcc_error_noabort("huh");
1521 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1522 #if SHT_RELX == SHT_RELA
1523 rel->r_addend = sym->st_value;
1524 #else
1525 /* All our REL architectures also happen to be 32bit LE. */
1526 write32le(s1->got->data + offset, sym->st_value);
1527 #endif
1532 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1533 in shared libraries and export non local defined symbols to shared libraries
1534 if -rdynamic switch was given on command line */
1535 static void bind_exe_dynsyms(TCCState *s1)
1537 const char *name;
1538 int sym_index, index;
1539 ElfW(Sym) *sym, *esym;
1540 int type;
1542 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1543 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1544 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1545 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1546 if (sym->st_shndx == SHN_UNDEF) {
1547 name = (char *) symtab_section->link->data + sym->st_name;
1548 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1549 if (sym_index) {
1550 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1551 type = ELFW(ST_TYPE)(esym->st_info);
1552 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1553 /* Indirect functions shall have STT_FUNC type in executable
1554 * dynsym section. Indeed, a dlsym call following a lazy
1555 * resolution would pick the symbol value from the
1556 * executable dynsym entry which would contain the address
1557 * of the function wanted by the caller of dlsym instead of
1558 * the address of the function that would return that
1559 * address */
1560 int dynindex
1561 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1562 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1563 name);
1564 int index = sym - (ElfW(Sym) *) symtab_section->data;
1565 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1566 } else if (type == STT_OBJECT) {
1567 unsigned long offset;
1568 ElfW(Sym) *dynsym;
1569 offset = bss_section->data_offset;
1570 /* XXX: which alignment ? */
1571 offset = (offset + 16 - 1) & -16;
1572 set_elf_sym (s1->symtab, offset, esym->st_size,
1573 esym->st_info, 0, bss_section->sh_num, name);
1574 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1575 esym->st_info, 0, bss_section->sh_num,
1576 name);
1578 /* Ensure R_COPY works for weak symbol aliases */
1579 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1580 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1581 if ((dynsym->st_value == esym->st_value)
1582 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1583 char *dynname = (char *) s1->dynsymtab_section->link->data
1584 + dynsym->st_name;
1585 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1586 dynsym->st_info, 0,
1587 bss_section->sh_num, dynname);
1588 break;
1593 put_elf_reloc(s1->dynsym, bss_section,
1594 offset, R_COPY, index);
1595 offset += esym->st_size;
1596 bss_section->data_offset = offset;
1598 } else {
1599 /* STB_WEAK undefined symbols are accepted */
1600 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1601 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1602 !strcmp(name, "_fp_hw")) {
1603 } else {
1604 tcc_error_noabort("undefined symbol '%s'", name);
1607 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1608 /* if -rdynamic option, then export all non local symbols */
1609 name = (char *) symtab_section->link->data + sym->st_name;
1610 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1611 0, sym->st_shndx, name);
1616 /* Bind symbols of libraries: export all non local symbols of executable that
1617 are referenced by shared libraries. The reason is that the dynamic loader
1618 search symbol first in executable and then in libraries. Therefore a
1619 reference to a symbol already defined by a library can still be resolved by
1620 a symbol in the executable. */
1621 static void bind_libs_dynsyms(TCCState *s1)
1623 const char *name;
1624 int sym_index;
1625 ElfW(Sym) *sym, *esym;
1627 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1628 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1629 sym_index = find_elf_sym(symtab_section, name);
1630 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1631 if (sym_index && sym->st_shndx != SHN_UNDEF
1632 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1633 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1634 sym->st_info, 0, sym->st_shndx, name);
1635 } else if (esym->st_shndx == SHN_UNDEF) {
1636 /* weak symbols can stay undefined */
1637 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1638 tcc_warning("undefined dynamic symbol '%s'", name);
1643 /* Export all non local symbols. This is used by shared libraries so that the
1644 non local symbols they define can resolve a reference in another shared
1645 library or in the executable. Correspondingly, it allows undefined local
1646 symbols to be resolved by other shared libraries or by the executable. */
1647 static void export_global_syms(TCCState *s1)
1649 int dynindex, index;
1650 const char *name;
1651 ElfW(Sym) *sym;
1653 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1654 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1655 name = (char *) symtab_section->link->data + sym->st_name;
1656 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1657 sym->st_info, 0, sym->st_shndx, name);
1658 index = sym - (ElfW(Sym) *) symtab_section->data;
1659 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1663 #endif
1665 /* Allocate strings for section names and decide if an unallocated section
1666 should be output.
1667 NOTE: the strsec section comes last, so its size is also correct ! */
1668 static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1670 int i;
1671 Section *s;
1672 int textrel = 0;
1674 /* Allocate strings for section names */
1675 for(i = 1; i < s1->nb_sections; i++) {
1676 s = s1->sections[i];
1677 /* when generating a DLL, we include relocations but we may
1678 patch them */
1679 #ifndef ELF_OBJ_ONLY
1680 if (file_type == TCC_OUTPUT_DLL &&
1681 s->sh_type == SHT_RELX &&
1682 !(s->sh_flags & SHF_ALLOC) &&
1683 (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
1684 prepare_dynamic_rel(s1, s)) {
1685 if (s1->sections[s->sh_info]->sh_flags & SHF_EXECINSTR)
1686 textrel = 1;
1687 } else
1688 #endif
1689 if ((s1->do_debug && s->sh_type != SHT_RELX) ||
1690 file_type == TCC_OUTPUT_OBJ ||
1691 (s->sh_flags & SHF_ALLOC) ||
1692 i == (s1->nb_sections - 1)) {
1693 /* we output all sections if debug or object file */
1694 s->sh_size = s->data_offset;
1696 if (s->sh_size || (s->sh_flags & SHF_ALLOC))
1697 s->sh_name = put_elf_str(strsec, s->name);
1699 strsec->sh_size = strsec->data_offset;
1700 return textrel;
1703 /* Info to be copied in dynamic section */
1704 struct dyn_inf {
1705 Section *dynamic;
1706 Section *dynstr;
1707 unsigned long data_offset;
1708 addr_t rel_addr;
1709 addr_t rel_size;
1710 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1711 addr_t bss_addr;
1712 addr_t bss_size;
1713 #endif
1716 /* Assign sections to segments and decide how are sections laid out when loaded
1717 in memory. This function also fills corresponding program headers. */
1718 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1719 Section *interp, Section* strsec,
1720 struct dyn_inf *dyninf, int *sec_order)
1722 int i, j, k, file_type, sh_order_index, file_offset;
1723 unsigned long s_align;
1724 long long tmp;
1725 addr_t addr;
1726 ElfW(Phdr) *ph;
1727 Section *s;
1729 file_type = s1->output_type;
1730 sh_order_index = 1;
1731 file_offset = 0;
1732 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1733 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1734 s_align = ELF_PAGE_SIZE;
1735 if (s1->section_align)
1736 s_align = s1->section_align;
1738 if (phnum > 0) {
1739 if (s1->has_text_addr) {
1740 int a_offset, p_offset;
1741 addr = s1->text_addr;
1742 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1743 ELF_PAGE_SIZE */
1744 a_offset = (int) (addr & (s_align - 1));
1745 p_offset = file_offset & (s_align - 1);
1746 if (a_offset < p_offset)
1747 a_offset += s_align;
1748 file_offset += (a_offset - p_offset);
1749 } else {
1750 if (file_type == TCC_OUTPUT_DLL)
1751 addr = 0;
1752 else
1753 addr = ELF_START_ADDR;
1754 /* compute address after headers */
1755 addr += (file_offset & (s_align - 1));
1758 ph = &phdr[0];
1759 /* Leave one program headers for the program interpreter and one for
1760 the program header table itself if needed. These are done later as
1761 they require section layout to be done first. */
1762 if (interp)
1763 ph += 2;
1765 /* dynamic relocation table information, for .dynamic section */
1766 dyninf->rel_addr = dyninf->rel_size = 0;
1767 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1768 dyninf->bss_addr = dyninf->bss_size = 0;
1769 #endif
1771 for(j = 0; j < 2; j++) {
1772 ph->p_type = PT_LOAD;
1773 if (j == 0)
1774 ph->p_flags = PF_R | PF_X;
1775 else
1776 ph->p_flags = PF_R | PF_W;
1777 ph->p_align = s_align;
1779 /* Decide the layout of sections loaded in memory. This must
1780 be done before program headers are filled since they contain
1781 info about the layout. We do the following ordering: interp,
1782 symbol tables, relocations, progbits, nobits */
1783 /* XXX: do faster and simpler sorting */
1784 for(k = 0; k < 5; k++) {
1785 for(i = 1; i < s1->nb_sections; i++) {
1786 s = s1->sections[i];
1787 /* compute if section should be included */
1788 if (j == 0) {
1789 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1790 SHF_ALLOC)
1791 continue;
1792 } else {
1793 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1794 (SHF_ALLOC | SHF_WRITE))
1795 continue;
1797 if (s == interp) {
1798 if (k != 0)
1799 continue;
1800 } else if (s->sh_type == SHT_DYNSYM ||
1801 s->sh_type == SHT_STRTAB ||
1802 s->sh_type == SHT_HASH) {
1803 if (k != 1)
1804 continue;
1805 } else if (s->sh_type == SHT_RELX) {
1806 if (k != 2)
1807 continue;
1808 } else if (s->sh_type == SHT_NOBITS) {
1809 if (k != 4)
1810 continue;
1811 } else {
1812 if (k != 3)
1813 continue;
1815 sec_order[sh_order_index++] = i;
1817 /* section matches: we align it and add its size */
1818 tmp = addr;
1819 addr = (addr + s->sh_addralign - 1) &
1820 ~(s->sh_addralign - 1);
1821 file_offset += (int) ( addr - tmp );
1822 s->sh_offset = file_offset;
1823 s->sh_addr = addr;
1825 /* update program header infos */
1826 if (ph->p_offset == 0) {
1827 ph->p_offset = file_offset;
1828 ph->p_vaddr = addr;
1829 ph->p_paddr = ph->p_vaddr;
1831 /* update dynamic relocation infos */
1832 if (s->sh_type == SHT_RELX) {
1833 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1834 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1835 dyninf->rel_addr = addr;
1836 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1838 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1839 dyninf->bss_addr = addr;
1840 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1842 #else
1843 if (dyninf->rel_size == 0)
1844 dyninf->rel_addr = addr;
1845 dyninf->rel_size += s->sh_size;
1846 #endif
1848 addr += s->sh_size;
1849 if (s->sh_type != SHT_NOBITS)
1850 file_offset += s->sh_size;
1853 if (j == 0) {
1854 /* Make the first PT_LOAD segment include the program
1855 headers itself (and the ELF header as well), it'll
1856 come out with same memory use but will make various
1857 tools like binutils strip work better. */
1858 ph->p_offset &= ~(ph->p_align - 1);
1859 ph->p_vaddr &= ~(ph->p_align - 1);
1860 ph->p_paddr &= ~(ph->p_align - 1);
1862 ph->p_filesz = file_offset - ph->p_offset;
1863 ph->p_memsz = addr - ph->p_vaddr;
1864 ph++;
1865 if (j == 0) {
1866 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1867 /* if in the middle of a page, we duplicate the page in
1868 memory so that one copy is RX and the other is RW */
1869 if ((addr & (s_align - 1)) != 0)
1870 addr += s_align;
1871 } else {
1872 addr = (addr + s_align - 1) & ~(s_align - 1);
1873 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1879 /* all other sections come after */
1880 for(i = 1; i < s1->nb_sections; i++) {
1881 s = s1->sections[i];
1882 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1883 continue;
1884 sec_order[sh_order_index++] = i;
1886 file_offset = (file_offset + s->sh_addralign - 1) &
1887 ~(s->sh_addralign - 1);
1888 s->sh_offset = file_offset;
1889 if (s->sh_type != SHT_NOBITS)
1890 file_offset += s->sh_size;
1893 return file_offset;
1896 #ifndef ELF_OBJ_ONLY
1897 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1898 Section *dynamic)
1900 ElfW(Phdr) *ph;
1902 /* if interpreter, then add corresponding program header */
1903 if (interp) {
1904 ph = &phdr[0];
1906 ph->p_type = PT_PHDR;
1907 ph->p_offset = sizeof(ElfW(Ehdr));
1908 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
1909 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
1910 ph->p_paddr = ph->p_vaddr;
1911 ph->p_flags = PF_R | PF_X;
1912 ph->p_align = 4; /* interp->sh_addralign; */
1913 ph++;
1915 ph->p_type = PT_INTERP;
1916 ph->p_offset = interp->sh_offset;
1917 ph->p_vaddr = interp->sh_addr;
1918 ph->p_paddr = ph->p_vaddr;
1919 ph->p_filesz = interp->sh_size;
1920 ph->p_memsz = interp->sh_size;
1921 ph->p_flags = PF_R;
1922 ph->p_align = interp->sh_addralign;
1925 /* if dynamic section, then add corresponding program header */
1926 if (dynamic) {
1927 ph = &phdr[phnum - 1];
1929 ph->p_type = PT_DYNAMIC;
1930 ph->p_offset = dynamic->sh_offset;
1931 ph->p_vaddr = dynamic->sh_addr;
1932 ph->p_paddr = ph->p_vaddr;
1933 ph->p_filesz = dynamic->sh_size;
1934 ph->p_memsz = dynamic->sh_size;
1935 ph->p_flags = PF_R | PF_W;
1936 ph->p_align = dynamic->sh_addralign;
1940 /* Fill the dynamic section with tags describing the address and size of
1941 sections */
1942 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
1944 Section *dynamic = dyninf->dynamic;
1945 Section *s;
1947 /* put dynamic section entries */
1948 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1949 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
1950 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1951 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
1952 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1953 #if PTR_SIZE == 8
1954 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
1955 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
1956 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
1957 #else
1958 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1959 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
1960 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
1961 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
1962 put_dt(dynamic, DT_PLTREL, DT_REL);
1963 put_dt(dynamic, DT_REL, dyninf->bss_addr);
1964 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
1965 #else
1966 put_dt(dynamic, DT_REL, dyninf->rel_addr);
1967 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
1968 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1969 #endif
1970 #endif
1971 if (versym_section) {
1972 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
1973 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
1974 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
1976 s = find_section_create (s1, ".preinit_array", 0);
1977 if (s && s->data_offset) {
1978 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
1979 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
1981 s = find_section_create (s1, ".init_array", 0);
1982 if (s && s->data_offset) {
1983 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
1984 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
1986 s = find_section_create (s1, ".fini_array", 0);
1987 if (s && s->data_offset) {
1988 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
1989 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
1991 s = find_section_create (s1, ".init", 0);
1992 if (s && s->data_offset) {
1993 put_dt(dynamic, DT_INIT, s->sh_addr);
1995 s = find_section_create (s1, ".fini", 0);
1996 if (s && s->data_offset) {
1997 put_dt(dynamic, DT_FINI, s->sh_addr);
1999 if (s1->do_debug)
2000 put_dt(dynamic, DT_DEBUG, 0);
2001 put_dt(dynamic, DT_NULL, 0);
2004 /* Relocate remaining sections and symbols (that is those not related to
2005 dynamic linking) */
2006 static int final_sections_reloc(TCCState *s1)
2008 int i;
2009 Section *s;
2011 relocate_syms(s1, s1->symtab, 0);
2013 if (s1->nb_errors != 0)
2014 return -1;
2016 /* relocate sections */
2017 /* XXX: ignore sections with allocated relocations ? */
2018 for(i = 1; i < s1->nb_sections; i++) {
2019 s = s1->sections[i];
2020 if (s->reloc && (s != s1->got || s1->static_link))
2021 relocate_section(s1, s);
2024 /* relocate relocation entries if the relocation tables are
2025 allocated in the executable */
2026 for(i = 1; i < s1->nb_sections; i++) {
2027 s = s1->sections[i];
2028 if ((s->sh_flags & SHF_ALLOC) &&
2029 s->sh_type == SHT_RELX) {
2030 relocate_rel(s1, s);
2033 return 0;
2035 #endif
2037 /* Create an ELF file on disk.
2038 This function handle ELF specific layout requirements */
2039 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2040 int file_offset, int *sec_order)
2042 int i, shnum, offset, size, file_type;
2043 Section *s;
2044 ElfW(Ehdr) ehdr;
2045 ElfW(Shdr) shdr, *sh;
2047 file_type = s1->output_type;
2048 shnum = s1->nb_sections;
2050 memset(&ehdr, 0, sizeof(ehdr));
2052 if (phnum > 0) {
2053 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2054 ehdr.e_phnum = phnum;
2055 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2058 /* align to 4 */
2059 file_offset = (file_offset + 3) & -4;
2061 /* fill header */
2062 ehdr.e_ident[0] = ELFMAG0;
2063 ehdr.e_ident[1] = ELFMAG1;
2064 ehdr.e_ident[2] = ELFMAG2;
2065 ehdr.e_ident[3] = ELFMAG3;
2066 ehdr.e_ident[4] = ELFCLASSW;
2067 ehdr.e_ident[5] = ELFDATA2LSB;
2068 ehdr.e_ident[6] = EV_CURRENT;
2069 #if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
2070 /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
2071 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2072 #endif
2073 #ifdef TCC_TARGET_ARM
2074 #ifdef TCC_ARM_EABI
2075 ehdr.e_ident[EI_OSABI] = 0;
2076 ehdr.e_flags = EF_ARM_EABI_VER4;
2077 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2078 ehdr.e_flags |= EF_ARM_HASENTRY;
2079 if (s1->float_abi == ARM_HARD_FLOAT)
2080 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2081 else
2082 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2083 #else
2084 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2085 #endif
2086 #elif defined TCC_TARGET_RISCV64
2087 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2088 #endif
2089 switch(file_type) {
2090 default:
2091 case TCC_OUTPUT_EXE:
2092 ehdr.e_type = ET_EXEC;
2093 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
2094 break;
2095 case TCC_OUTPUT_DLL:
2096 ehdr.e_type = ET_DYN;
2097 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2098 break;
2099 case TCC_OUTPUT_OBJ:
2100 ehdr.e_type = ET_REL;
2101 break;
2103 ehdr.e_machine = EM_TCC_TARGET;
2104 ehdr.e_version = EV_CURRENT;
2105 ehdr.e_shoff = file_offset;
2106 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2107 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2108 ehdr.e_shnum = shnum;
2109 ehdr.e_shstrndx = shnum - 1;
2111 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2112 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2113 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2115 sort_syms(s1, symtab_section);
2116 for(i = 1; i < s1->nb_sections; i++) {
2117 s = s1->sections[sec_order[i]];
2118 if (s->sh_type != SHT_NOBITS) {
2119 while (offset < s->sh_offset) {
2120 fputc(0, f);
2121 offset++;
2123 size = s->sh_size;
2124 if (size)
2125 fwrite(s->data, 1, size, f);
2126 offset += size;
2130 /* output section headers */
2131 while (offset < ehdr.e_shoff) {
2132 fputc(0, f);
2133 offset++;
2136 for(i = 0; i < s1->nb_sections; i++) {
2137 sh = &shdr;
2138 memset(sh, 0, sizeof(ElfW(Shdr)));
2139 s = s1->sections[i];
2140 if (s) {
2141 sh->sh_name = s->sh_name;
2142 sh->sh_type = s->sh_type;
2143 sh->sh_flags = s->sh_flags;
2144 sh->sh_entsize = s->sh_entsize;
2145 sh->sh_info = s->sh_info;
2146 if (s->link)
2147 sh->sh_link = s->link->sh_num;
2148 sh->sh_addralign = s->sh_addralign;
2149 sh->sh_addr = s->sh_addr;
2150 sh->sh_offset = s->sh_offset;
2151 sh->sh_size = s->sh_size;
2153 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2157 /* Write an elf, coff or "binary" file */
2158 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2159 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2161 int fd, mode, file_type;
2162 FILE *f;
2164 file_type = s1->output_type;
2165 if (file_type == TCC_OUTPUT_OBJ)
2166 mode = 0666;
2167 else
2168 mode = 0777;
2169 unlink(filename);
2170 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2171 if (fd < 0) {
2172 tcc_error_noabort("could not write '%s'", filename);
2173 return -1;
2175 f = fdopen(fd, "wb");
2176 if (s1->verbose)
2177 printf("<- %s\n", filename);
2179 #ifdef TCC_TARGET_COFF
2180 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2181 tcc_output_coff(s1, f);
2182 else
2183 #endif
2184 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2185 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2186 else
2187 tcc_output_binary(s1, f, sec_order);
2188 fclose(f);
2190 return 0;
2193 #ifndef ELF_OBJ_ONLY
2194 /* Sort section headers by assigned sh_addr, remove sections
2195 that we aren't going to output. */
2196 static void tidy_section_headers(TCCState *s1, int *sec_order)
2198 int i, nnew, l, *backmap;
2199 Section **snew, *s;
2200 ElfW(Sym) *sym;
2202 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2203 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2204 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2205 s = s1->sections[sec_order[i]];
2206 if (!i || s->sh_name) {
2207 backmap[sec_order[i]] = nnew;
2208 snew[nnew] = s;
2209 ++nnew;
2210 } else {
2211 backmap[sec_order[i]] = 0;
2212 snew[--l] = s;
2215 for (i = 0; i < nnew; i++) {
2216 s = snew[i];
2217 if (s) {
2218 s->sh_num = i;
2219 if (s->sh_type == SHT_RELX)
2220 s->sh_info = backmap[s->sh_info];
2224 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2225 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2226 sym->st_shndx = backmap[sym->st_shndx];
2227 if( !s1->static_link ) {
2228 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2229 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2230 sym->st_shndx = backmap[sym->st_shndx];
2232 for (i = 0; i < s1->nb_sections; i++)
2233 sec_order[i] = i;
2234 tcc_free(s1->sections);
2235 s1->sections = snew;
2236 s1->nb_sections = nnew;
2237 tcc_free(backmap);
2239 #endif
2241 /* Output an elf, coff or binary file */
2242 /* XXX: suppress unneeded sections */
2243 static int elf_output_file(TCCState *s1, const char *filename)
2245 int ret, phnum, shnum, file_type, file_offset, *sec_order;
2246 struct dyn_inf dyninf = {0};
2247 ElfW(Phdr) *phdr;
2248 Section *strsec, *interp, *dynamic, *dynstr;
2250 file_type = s1->output_type;
2251 s1->nb_errors = 0;
2252 ret = -1;
2253 phdr = NULL;
2254 sec_order = NULL;
2255 interp = dynamic = dynstr = NULL; /* avoid warning */
2257 #ifndef ELF_OBJ_ONLY
2258 if (file_type != TCC_OUTPUT_OBJ) {
2259 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2260 tcc_add_runtime(s1);
2261 resolve_common_syms(s1);
2263 if (!s1->static_link) {
2264 if (file_type == TCC_OUTPUT_EXE) {
2265 char *ptr;
2266 /* allow override the dynamic loader */
2267 const char *elfint = getenv("LD_SO");
2268 if (elfint == NULL)
2269 elfint = DEFAULT_ELFINTERP(s1);
2270 /* add interpreter section only if executable */
2271 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2272 interp->sh_addralign = 1;
2273 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2274 strcpy(ptr, elfint);
2277 /* add dynamic symbol table */
2278 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2279 ".dynstr",
2280 ".hash", SHF_ALLOC);
2281 dynstr = s1->dynsym->link;
2282 /* add dynamic section */
2283 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2284 SHF_ALLOC | SHF_WRITE);
2285 dynamic->link = dynstr;
2286 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2288 build_got(s1);
2290 if (file_type == TCC_OUTPUT_EXE) {
2291 bind_exe_dynsyms(s1);
2292 if (s1->nb_errors)
2293 goto the_end;
2294 bind_libs_dynsyms(s1);
2295 } else {
2296 /* shared library case: simply export all global symbols */
2297 export_global_syms(s1);
2300 build_got_entries(s1);
2301 version_add (s1);
2303 #endif
2305 /* we add a section for symbols */
2306 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2307 put_elf_str(strsec, "");
2309 /* Allocate strings for section names */
2310 ret = alloc_sec_names(s1, file_type, strsec);
2312 #ifndef ELF_OBJ_ONLY
2313 if (dynamic) {
2314 int i;
2315 /* add a list of needed dlls */
2316 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2317 DLLReference *dllref = s1->loaded_dlls[i];
2318 if (dllref->level == 0)
2319 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2322 if (s1->rpath)
2323 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2324 put_elf_str(dynstr, s1->rpath));
2326 if (file_type == TCC_OUTPUT_DLL) {
2327 if (s1->soname)
2328 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2329 /* XXX: currently, since we do not handle PIC code, we
2330 must relocate the readonly segments */
2331 if (ret)
2332 put_dt(dynamic, DT_TEXTREL, 0);
2335 if (s1->symbolic)
2336 put_dt(dynamic, DT_SYMBOLIC, 0);
2338 dyninf.dynamic = dynamic;
2339 dyninf.dynstr = dynstr;
2340 /* remember offset and reserve space for 2nd call below */
2341 dyninf.data_offset = dynamic->data_offset;
2342 fill_dynamic(s1, &dyninf);
2343 dynamic->sh_size = dynamic->data_offset;
2344 dynstr->sh_size = dynstr->data_offset;
2346 #endif
2348 /* compute number of program headers */
2349 if (file_type == TCC_OUTPUT_OBJ)
2350 phnum = 0;
2351 else if (file_type == TCC_OUTPUT_DLL)
2352 phnum = 3;
2353 else if (s1->static_link)
2354 phnum = 2;
2355 else
2356 phnum = 5;
2358 /* allocate program segment headers */
2359 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2361 /* compute number of sections */
2362 shnum = s1->nb_sections;
2364 /* this array is used to reorder sections in the output file */
2365 sec_order = tcc_malloc(sizeof(int) * shnum);
2366 sec_order[0] = 0;
2368 /* compute section to program header mapping */
2369 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2370 sec_order);
2372 #ifndef ELF_OBJ_ONLY
2373 /* Fill remaining program header and finalize relocation related to dynamic
2374 linking. */
2375 if (file_type != TCC_OUTPUT_OBJ) {
2376 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2377 if (dynamic) {
2378 ElfW(Sym) *sym;
2379 dynamic->data_offset = dyninf.data_offset;
2380 fill_dynamic(s1, &dyninf);
2382 /* put in GOT the dynamic section address and relocate PLT */
2383 write32le(s1->got->data, dynamic->sh_addr);
2384 if (file_type == TCC_OUTPUT_EXE
2385 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2386 relocate_plt(s1);
2388 /* relocate symbols in .dynsym now that final addresses are known */
2389 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2390 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2391 /* do symbol relocation */
2392 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2397 /* if building executable or DLL, then relocate each section
2398 except the GOT which is already relocated */
2399 ret = final_sections_reloc(s1);
2400 if (ret)
2401 goto the_end;
2402 tidy_section_headers(s1, sec_order);
2404 /* Perform relocation to GOT or PLT entries */
2405 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2406 fill_got(s1);
2407 else if (s1->got)
2408 fill_local_got_entries(s1);
2410 #endif
2412 /* Create the ELF file with name 'filename' */
2413 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2414 s1->nb_sections = shnum;
2415 goto the_end;
2416 the_end:
2417 tcc_free(sec_order);
2418 tcc_free(phdr);
2419 return ret;
2422 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2424 int ret;
2425 #ifdef TCC_TARGET_PE
2426 if (s->output_type != TCC_OUTPUT_OBJ) {
2427 ret = pe_output_file(s, filename);
2428 } else
2429 #endif
2430 ret = elf_output_file(s, filename);
2431 return ret;
2434 ssize_t full_read(int fd, void *buf, size_t count) {
2435 char *cbuf = buf;
2436 size_t rnum = 0;
2437 while (1) {
2438 ssize_t num = read(fd, cbuf, count-rnum);
2439 if (num < 0) return num;
2440 if (num == 0) return rnum;
2441 rnum += num;
2442 cbuf += num;
2446 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2448 void *data;
2450 data = tcc_malloc(size);
2451 lseek(fd, file_offset, SEEK_SET);
2452 full_read(fd, data, size);
2453 return data;
2456 typedef struct SectionMergeInfo {
2457 Section *s; /* corresponding existing section */
2458 unsigned long offset; /* offset of the new section in the existing section */
2459 uint8_t new_section; /* true if section 's' was added */
2460 uint8_t link_once; /* true if link once section */
2461 } SectionMergeInfo;
2463 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2465 int size = full_read(fd, h, sizeof *h);
2466 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2467 if (h->e_type == ET_REL)
2468 return AFF_BINTYPE_REL;
2469 if (h->e_type == ET_DYN)
2470 return AFF_BINTYPE_DYN;
2471 } else if (size >= 8) {
2472 if (0 == memcmp(h, ARMAG, 8))
2473 return AFF_BINTYPE_AR;
2474 #ifdef TCC_TARGET_COFF
2475 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2476 return AFF_BINTYPE_C67;
2477 #endif
2479 return 0;
2482 /* load an object file and merge it with current files */
2483 /* XXX: handle correctly stab (debug) info */
2484 ST_FUNC int tcc_load_object_file(TCCState *s1,
2485 int fd, unsigned long file_offset)
2487 ElfW(Ehdr) ehdr;
2488 ElfW(Shdr) *shdr, *sh;
2489 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2490 char *strsec, *strtab;
2491 int *old_to_new_syms;
2492 char *sh_name, *name;
2493 SectionMergeInfo *sm_table, *sm;
2494 ElfW(Sym) *sym, *symtab;
2495 ElfW_Rel *rel;
2496 Section *s;
2498 int stab_index;
2499 int stabstr_index;
2501 stab_index = stabstr_index = 0;
2503 lseek(fd, file_offset, SEEK_SET);
2504 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2505 goto fail1;
2506 /* test CPU specific stuff */
2507 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2508 ehdr.e_machine != EM_TCC_TARGET) {
2509 fail1:
2510 tcc_error_noabort("invalid object file");
2511 return -1;
2513 /* read sections */
2514 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2515 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2516 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2518 /* load section names */
2519 sh = &shdr[ehdr.e_shstrndx];
2520 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2522 /* load symtab and strtab */
2523 old_to_new_syms = NULL;
2524 symtab = NULL;
2525 strtab = NULL;
2526 nb_syms = 0;
2527 seencompressed = 0;
2528 for(i = 1; i < ehdr.e_shnum; i++) {
2529 sh = &shdr[i];
2530 if (sh->sh_type == SHT_SYMTAB) {
2531 if (symtab) {
2532 tcc_error_noabort("object must contain only one symtab");
2533 fail:
2534 ret = -1;
2535 goto the_end;
2537 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2538 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2539 sm_table[i].s = symtab_section;
2541 /* now load strtab */
2542 sh = &shdr[sh->sh_link];
2543 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2545 if (sh->sh_flags & SHF_COMPRESSED)
2546 seencompressed = 1;
2549 /* now examine each section and try to merge its content with the
2550 ones in memory */
2551 for(i = 1; i < ehdr.e_shnum; i++) {
2552 /* no need to examine section name strtab */
2553 if (i == ehdr.e_shstrndx)
2554 continue;
2555 sh = &shdr[i];
2556 if (sh->sh_type == SHT_RELX)
2557 sh = &shdr[sh->sh_info];
2558 /* ignore sections types we do not handle (plus relocs to those) */
2559 if (sh->sh_type != SHT_PROGBITS &&
2560 #ifdef TCC_ARM_EABI
2561 sh->sh_type != SHT_ARM_EXIDX &&
2562 #endif
2563 sh->sh_type != SHT_NOBITS &&
2564 sh->sh_type != SHT_PREINIT_ARRAY &&
2565 sh->sh_type != SHT_INIT_ARRAY &&
2566 sh->sh_type != SHT_FINI_ARRAY &&
2567 strcmp(strsec + sh->sh_name, ".stabstr")
2569 continue;
2570 if (seencompressed
2571 && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
2572 continue;
2574 sh = &shdr[i];
2575 sh_name = strsec + sh->sh_name;
2576 if (sh->sh_addralign < 1)
2577 sh->sh_addralign = 1;
2578 /* find corresponding section, if any */
2579 for(j = 1; j < s1->nb_sections;j++) {
2580 s = s1->sections[j];
2581 if (!strcmp(s->name, sh_name)) {
2582 if (!strncmp(sh_name, ".gnu.linkonce",
2583 sizeof(".gnu.linkonce") - 1)) {
2584 /* if a 'linkonce' section is already present, we
2585 do not add it again. It is a little tricky as
2586 symbols can still be defined in
2587 it. */
2588 sm_table[i].link_once = 1;
2589 goto next;
2590 } else {
2591 goto found;
2595 /* not found: create new section */
2596 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2597 /* take as much info as possible from the section. sh_link and
2598 sh_info will be updated later */
2599 s->sh_addralign = sh->sh_addralign;
2600 s->sh_entsize = sh->sh_entsize;
2601 sm_table[i].new_section = 1;
2602 found:
2603 if (sh->sh_type != s->sh_type) {
2604 tcc_error_noabort("invalid section type");
2605 goto fail;
2608 /* align start of section */
2609 offset = s->data_offset;
2611 if (0 == strcmp(sh_name, ".stab")) {
2612 stab_index = i;
2613 goto no_align;
2615 if (0 == strcmp(sh_name, ".stabstr")) {
2616 stabstr_index = i;
2617 goto no_align;
2620 size = sh->sh_addralign - 1;
2621 offset = (offset + size) & ~size;
2622 if (sh->sh_addralign > s->sh_addralign)
2623 s->sh_addralign = sh->sh_addralign;
2624 s->data_offset = offset;
2625 no_align:
2626 sm_table[i].offset = offset;
2627 sm_table[i].s = s;
2628 /* concatenate sections */
2629 size = sh->sh_size;
2630 if (sh->sh_type != SHT_NOBITS) {
2631 unsigned char *ptr;
2632 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2633 ptr = section_ptr_add(s, size);
2634 full_read(fd, ptr, size);
2635 } else {
2636 s->data_offset += size;
2638 next: ;
2641 /* gr relocate stab strings */
2642 if (stab_index && stabstr_index) {
2643 Stab_Sym *a, *b;
2644 unsigned o;
2645 s = sm_table[stab_index].s;
2646 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2647 b = (Stab_Sym *)(s->data + s->data_offset);
2648 o = sm_table[stabstr_index].offset;
2649 while (a < b) {
2650 if (a->n_strx)
2651 a->n_strx += o;
2652 a++;
2656 /* second short pass to update sh_link and sh_info fields of new
2657 sections */
2658 for(i = 1; i < ehdr.e_shnum; i++) {
2659 s = sm_table[i].s;
2660 if (!s || !sm_table[i].new_section)
2661 continue;
2662 sh = &shdr[i];
2663 if (sh->sh_link > 0)
2664 s->link = sm_table[sh->sh_link].s;
2665 if (sh->sh_type == SHT_RELX) {
2666 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2667 /* update backward link */
2668 s1->sections[s->sh_info]->reloc = s;
2671 sm = sm_table;
2673 /* resolve symbols */
2674 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2676 sym = symtab + 1;
2677 for(i = 1; i < nb_syms; i++, sym++) {
2678 if (sym->st_shndx != SHN_UNDEF &&
2679 sym->st_shndx < SHN_LORESERVE) {
2680 sm = &sm_table[sym->st_shndx];
2681 if (sm->link_once) {
2682 /* if a symbol is in a link once section, we use the
2683 already defined symbol. It is very important to get
2684 correct relocations */
2685 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2686 name = strtab + sym->st_name;
2687 sym_index = find_elf_sym(symtab_section, name);
2688 if (sym_index)
2689 old_to_new_syms[i] = sym_index;
2691 continue;
2693 /* if no corresponding section added, no need to add symbol */
2694 if (!sm->s)
2695 continue;
2696 /* convert section number */
2697 sym->st_shndx = sm->s->sh_num;
2698 /* offset value */
2699 sym->st_value += sm->offset;
2701 /* add symbol */
2702 name = strtab + sym->st_name;
2703 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2704 sym->st_info, sym->st_other,
2705 sym->st_shndx, name);
2706 old_to_new_syms[i] = sym_index;
2709 /* third pass to patch relocation entries */
2710 for(i = 1; i < ehdr.e_shnum; i++) {
2711 s = sm_table[i].s;
2712 if (!s)
2713 continue;
2714 sh = &shdr[i];
2715 offset = sm_table[i].offset;
2716 switch(s->sh_type) {
2717 case SHT_RELX:
2718 /* take relocation offset information */
2719 offseti = sm_table[sh->sh_info].offset;
2720 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2721 int type;
2722 unsigned sym_index;
2723 /* convert symbol index */
2724 type = ELFW(R_TYPE)(rel->r_info);
2725 sym_index = ELFW(R_SYM)(rel->r_info);
2726 /* NOTE: only one symtab assumed */
2727 if (sym_index >= nb_syms)
2728 goto invalid_reloc;
2729 sym_index = old_to_new_syms[sym_index];
2730 /* ignore link_once in rel section. */
2731 if (!sym_index && !sm->link_once
2732 #ifdef TCC_TARGET_ARM
2733 && type != R_ARM_V4BX
2734 #elif defined TCC_TARGET_RISCV64
2735 && type != R_RISCV_ALIGN
2736 && type != R_RISCV_RELAX
2737 #endif
2739 invalid_reloc:
2740 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2741 i, strsec + sh->sh_name, rel->r_offset);
2742 goto fail;
2744 rel->r_info = ELFW(R_INFO)(sym_index, type);
2745 /* offset the relocation offset */
2746 rel->r_offset += offseti;
2747 #ifdef TCC_TARGET_ARM
2748 /* Jumps and branches from a Thumb code to a PLT entry need
2749 special handling since PLT entries are ARM code.
2750 Unconditional bl instructions referencing PLT entries are
2751 handled by converting these instructions into blx
2752 instructions. Other case of instructions referencing a PLT
2753 entry require to add a Thumb stub before the PLT entry to
2754 switch to ARM mode. We set bit plt_thumb_stub of the
2755 attribute of a symbol to indicate such a case. */
2756 if (type == R_ARM_THM_JUMP24)
2757 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2758 #endif
2760 break;
2761 default:
2762 break;
2766 ret = 0;
2767 the_end:
2768 tcc_free(symtab);
2769 tcc_free(strtab);
2770 tcc_free(old_to_new_syms);
2771 tcc_free(sm_table);
2772 tcc_free(strsec);
2773 tcc_free(shdr);
2774 return ret;
2777 typedef struct ArchiveHeader {
2778 char ar_name[16]; /* name of this member */
2779 char ar_date[12]; /* file mtime */
2780 char ar_uid[6]; /* owner uid; printed as decimal */
2781 char ar_gid[6]; /* owner gid; printed as decimal */
2782 char ar_mode[8]; /* file mode, printed as octal */
2783 char ar_size[10]; /* file size, printed as decimal */
2784 char ar_fmag[2]; /* should contain ARFMAG */
2785 } ArchiveHeader;
2787 #define ARFMAG "`\n"
2789 static unsigned long long get_be(const uint8_t *b, int n)
2791 unsigned long long ret = 0;
2792 while (n)
2793 ret = (ret << 8) | *b++, --n;
2794 return ret;
2797 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
2799 char *p, *e;
2800 int len;
2801 lseek(fd, offset, SEEK_SET);
2802 len = full_read(fd, hdr, sizeof(ArchiveHeader));
2803 if (len != sizeof(ArchiveHeader))
2804 return len ? -1 : 0;
2805 p = hdr->ar_name;
2806 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
2807 --e;
2808 *e = '\0';
2809 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
2810 return len;
2813 /* load only the objects which resolve undefined symbols */
2814 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2816 int i, bound, nsyms, sym_index, len, ret = -1;
2817 unsigned long long off;
2818 uint8_t *data;
2819 const char *ar_names, *p;
2820 const uint8_t *ar_index;
2821 ElfW(Sym) *sym;
2822 ArchiveHeader hdr;
2824 data = tcc_malloc(size);
2825 if (full_read(fd, data, size) != size)
2826 goto the_end;
2827 nsyms = get_be(data, entrysize);
2828 ar_index = data + entrysize;
2829 ar_names = (char *) ar_index + nsyms * entrysize;
2831 do {
2832 bound = 0;
2833 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2834 Section *s = symtab_section;
2835 sym_index = find_elf_sym(s, p);
2836 #ifdef TCC_TARGET_PE /* windows DLL's don't have UNDEF syms */
2837 if (sym_index == 0) {
2838 s = s1->dynsymtab_section;
2839 sym_index = find_elf_sym(s, p);
2841 #endif
2842 if (!sym_index)
2843 continue;
2844 sym = &((ElfW(Sym) *)s->data)[sym_index];
2845 if(sym->st_shndx != SHN_UNDEF)
2846 continue;
2847 off = get_be(ar_index + i * entrysize, entrysize);
2848 len = read_ar_header(fd, off, &hdr);
2849 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
2850 tcc_error_noabort("invalid archive");
2851 goto the_end;
2853 off += len;
2854 if (s1->verbose == 2)
2855 printf(" -> %s\n", hdr.ar_name);
2856 if (tcc_load_object_file(s1, fd, off) < 0)
2857 goto the_end;
2858 ++bound;
2860 } while(bound);
2861 ret = 0;
2862 the_end:
2863 tcc_free(data);
2864 return ret;
2867 /* load a '.a' file */
2868 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
2870 ArchiveHeader hdr;
2871 /* char magic[8]; */
2872 int size, len;
2873 unsigned long file_offset;
2874 ElfW(Ehdr) ehdr;
2876 /* skip magic which was already checked */
2877 /* full_read(fd, magic, sizeof(magic)); */
2878 file_offset = sizeof ARMAG - 1;
2880 for(;;) {
2881 len = read_ar_header(fd, file_offset, &hdr);
2882 if (len == 0)
2883 return 0;
2884 if (len < 0) {
2885 tcc_error_noabort("invalid archive");
2886 return -1;
2888 file_offset += len;
2889 size = strtol(hdr.ar_size, NULL, 0);
2890 /* align to even */
2891 size = (size + 1) & ~1;
2892 if (alacarte) {
2893 /* coff symbol table : we handle it */
2894 if (!strcmp(hdr.ar_name, "/"))
2895 return tcc_load_alacarte(s1, fd, size, 4);
2896 if (!strcmp(hdr.ar_name, "/SYM64/"))
2897 return tcc_load_alacarte(s1, fd, size, 8);
2898 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2899 if (s1->verbose == 2)
2900 printf(" -> %s\n", hdr.ar_name);
2901 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2902 return -1;
2904 file_offset += size;
2908 #ifndef ELF_OBJ_ONLY
2909 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
2910 LV, maybe create a new entry for (LIB,VERSION). */
2911 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
2913 while (i >= *n) {
2914 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
2915 (*lv)[(*n)++] = -1;
2917 if ((*lv)[i] == -1) {
2918 int v, prev_same_lib = -1;
2919 for (v = 0; v < nb_sym_versions; v++) {
2920 if (strcmp(sym_versions[v].lib, lib))
2921 continue;
2922 prev_same_lib = v;
2923 if (!strcmp(sym_versions[v].version, version))
2924 break;
2926 if (v == nb_sym_versions) {
2927 sym_versions = tcc_realloc (sym_versions,
2928 (v + 1) * sizeof(*sym_versions));
2929 sym_versions[v].lib = tcc_strdup(lib);
2930 sym_versions[v].version = tcc_strdup(version);
2931 sym_versions[v].out_index = 0;
2932 sym_versions[v].prev_same_lib = prev_same_lib;
2933 nb_sym_versions++;
2935 (*lv)[i] = v;
2939 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
2940 VERNDX. */
2941 static void
2942 set_sym_version(TCCState *s1, int sym_index, int verndx)
2944 if (sym_index >= nb_sym_to_version) {
2945 int newelems = sym_index ? sym_index * 2 : 1;
2946 sym_to_version = tcc_realloc(sym_to_version,
2947 newelems * sizeof(*sym_to_version));
2948 memset(sym_to_version + nb_sym_to_version, -1,
2949 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
2950 nb_sym_to_version = newelems;
2952 if (sym_to_version[sym_index] < 0)
2953 sym_to_version[sym_index] = verndx;
2956 struct versym_info {
2957 int nb_versyms;
2958 ElfW(Verdef) *verdef;
2959 ElfW(Verneed) *verneed;
2960 ElfW(Half) *versym;
2961 int nb_local_ver, *local_ver;
2965 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
2967 char *lib, *version;
2968 uint32_t next;
2969 int i;
2971 #define DEBUG_VERSION 0
2973 if (v->versym && v->verdef) {
2974 ElfW(Verdef) *vdef = v->verdef;
2975 lib = NULL;
2976 do {
2977 ElfW(Verdaux) *verdaux =
2978 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
2980 #if DEBUG_VERSION
2981 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
2982 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
2983 vdef->vd_hash);
2984 #endif
2985 if (vdef->vd_cnt) {
2986 version = dynstr + verdaux->vda_name;
2988 if (lib == NULL)
2989 lib = version;
2990 else
2991 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
2992 lib, version);
2993 #if DEBUG_VERSION
2994 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
2995 #endif
2997 next = vdef->vd_next;
2998 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
2999 } while (next);
3001 if (v->versym && v->verneed) {
3002 ElfW(Verneed) *vneed = v->verneed;
3003 do {
3004 ElfW(Vernaux) *vernaux =
3005 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3007 lib = dynstr + vneed->vn_file;
3008 #if DEBUG_VERSION
3009 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3010 #endif
3011 for (i = 0; i < vneed->vn_cnt; i++) {
3012 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3013 version = dynstr + vernaux->vna_name;
3014 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3015 lib, version);
3016 #if DEBUG_VERSION
3017 printf (" vernaux(%u): %u %u %s\n",
3018 vernaux->vna_other, vernaux->vna_hash,
3019 vernaux->vna_flags, version);
3020 #endif
3022 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3024 next = vneed->vn_next;
3025 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3026 } while (next);
3029 #if DEBUG_VERSION
3030 for (i = 0; i < v->nb_local_ver; i++) {
3031 if (v->local_ver[i] > 0) {
3032 printf ("%d: lib: %s, version %s\n",
3033 i, sym_versions[v->local_ver[i]].lib,
3034 sym_versions[v->local_ver[i]].version);
3037 #endif
3040 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3041 is referenced by the user (so it should be added as DT_NEEDED in
3042 the generated ELF file) */
3043 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3045 ElfW(Ehdr) ehdr;
3046 ElfW(Shdr) *shdr, *sh, *sh1;
3047 int i, j, nb_syms, nb_dts, sym_bind, ret;
3048 ElfW(Sym) *sym, *dynsym;
3049 ElfW(Dyn) *dt, *dynamic;
3051 char *dynstr;
3052 int sym_index;
3053 const char *name, *soname;
3054 DLLReference *dllref;
3055 struct versym_info v;
3057 full_read(fd, &ehdr, sizeof(ehdr));
3059 /* test CPU specific stuff */
3060 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3061 ehdr.e_machine != EM_TCC_TARGET) {
3062 tcc_error_noabort("bad architecture");
3063 return -1;
3066 /* read sections */
3067 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3069 /* load dynamic section and dynamic symbols */
3070 nb_syms = 0;
3071 nb_dts = 0;
3072 dynamic = NULL;
3073 dynsym = NULL; /* avoid warning */
3074 dynstr = NULL; /* avoid warning */
3075 memset(&v, 0, sizeof v);
3077 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3078 switch(sh->sh_type) {
3079 case SHT_DYNAMIC:
3080 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3081 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3082 break;
3083 case SHT_DYNSYM:
3084 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3085 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3086 sh1 = &shdr[sh->sh_link];
3087 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3088 break;
3089 case SHT_GNU_verdef:
3090 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3091 break;
3092 case SHT_GNU_verneed:
3093 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3094 break;
3095 case SHT_GNU_versym:
3096 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3097 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3098 break;
3099 default:
3100 break;
3104 /* compute the real library name */
3105 soname = tcc_basename(filename);
3107 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3108 if (dt->d_tag == DT_SONAME) {
3109 soname = dynstr + dt->d_un.d_val;
3113 /* if the dll is already loaded, do not load it */
3114 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3115 dllref = s1->loaded_dlls[i];
3116 if (!strcmp(soname, dllref->name)) {
3117 /* but update level if needed */
3118 if (level < dllref->level)
3119 dllref->level = level;
3120 ret = 0;
3121 goto the_end;
3125 if (v.nb_versyms != nb_syms)
3126 tcc_free (v.versym), v.versym = NULL;
3127 else
3128 store_version(s1, &v, dynstr);
3130 /* add the dll and its level */
3131 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
3132 dllref->level = level;
3133 strcpy(dllref->name, soname);
3134 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
3136 /* add dynamic symbols in dynsym_section */
3137 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3138 sym_bind = ELFW(ST_BIND)(sym->st_info);
3139 if (sym_bind == STB_LOCAL)
3140 continue;
3141 name = dynstr + sym->st_name;
3142 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3143 sym->st_info, sym->st_other, sym->st_shndx, name);
3144 if (v.versym) {
3145 ElfW(Half) vsym = v.versym[i];
3146 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3147 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3151 /* load all referenced DLLs */
3152 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3153 switch(dt->d_tag) {
3154 case DT_NEEDED:
3155 name = dynstr + dt->d_un.d_val;
3156 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3157 dllref = s1->loaded_dlls[j];
3158 if (!strcmp(name, dllref->name))
3159 goto already_loaded;
3161 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3162 tcc_error_noabort("referenced dll '%s' not found", name);
3163 ret = -1;
3164 goto the_end;
3166 already_loaded:
3167 break;
3170 ret = 0;
3171 the_end:
3172 tcc_free(dynstr);
3173 tcc_free(dynsym);
3174 tcc_free(dynamic);
3175 tcc_free(shdr);
3176 tcc_free(v.local_ver);
3177 tcc_free(v.verdef);
3178 tcc_free(v.verneed);
3179 tcc_free(v.versym);
3180 return ret;
3183 #define LD_TOK_NAME 256
3184 #define LD_TOK_EOF (-1)
3186 static int ld_inp(TCCState *s1)
3188 char b;
3189 if (s1->cc != -1) {
3190 int c = s1->cc;
3191 s1->cc = -1;
3192 return c;
3194 if (1 == read(s1->fd, &b, 1))
3195 return b;
3196 return CH_EOF;
3199 /* return next ld script token */
3200 static int ld_next(TCCState *s1, char *name, int name_size)
3202 int c, d, ch;
3203 char *q;
3205 redo:
3206 ch = ld_inp(s1);
3207 switch(ch) {
3208 case ' ':
3209 case '\t':
3210 case '\f':
3211 case '\v':
3212 case '\r':
3213 case '\n':
3214 goto redo;
3215 case '/':
3216 ch = ld_inp(s1);
3217 if (ch == '*') { /* comment */
3218 for (d = 0;; d = ch) {
3219 ch = ld_inp(s1);
3220 if (ch == CH_EOF || (ch == '/' && d == '*'))
3221 break;
3223 goto redo;
3224 } else {
3225 q = name;
3226 *q++ = '/';
3227 goto parse_name;
3229 break;
3230 case '\\':
3231 /* case 'a' ... 'z': */
3232 case 'a':
3233 case 'b':
3234 case 'c':
3235 case 'd':
3236 case 'e':
3237 case 'f':
3238 case 'g':
3239 case 'h':
3240 case 'i':
3241 case 'j':
3242 case 'k':
3243 case 'l':
3244 case 'm':
3245 case 'n':
3246 case 'o':
3247 case 'p':
3248 case 'q':
3249 case 'r':
3250 case 's':
3251 case 't':
3252 case 'u':
3253 case 'v':
3254 case 'w':
3255 case 'x':
3256 case 'y':
3257 case 'z':
3258 /* case 'A' ... 'z': */
3259 case 'A':
3260 case 'B':
3261 case 'C':
3262 case 'D':
3263 case 'E':
3264 case 'F':
3265 case 'G':
3266 case 'H':
3267 case 'I':
3268 case 'J':
3269 case 'K':
3270 case 'L':
3271 case 'M':
3272 case 'N':
3273 case 'O':
3274 case 'P':
3275 case 'Q':
3276 case 'R':
3277 case 'S':
3278 case 'T':
3279 case 'U':
3280 case 'V':
3281 case 'W':
3282 case 'X':
3283 case 'Y':
3284 case 'Z':
3285 case '_':
3286 case '.':
3287 case '$':
3288 case '~':
3289 q = name;
3290 parse_name:
3291 for(;;) {
3292 if (!((ch >= 'a' && ch <= 'z') ||
3293 (ch >= 'A' && ch <= 'Z') ||
3294 (ch >= '0' && ch <= '9') ||
3295 strchr("/.-_+=$:\\,~", ch)))
3296 break;
3297 if ((q - name) < name_size - 1) {
3298 *q++ = ch;
3300 ch = ld_inp(s1);
3302 s1->cc = ch;
3303 *q = '\0';
3304 c = LD_TOK_NAME;
3305 break;
3306 case CH_EOF:
3307 c = LD_TOK_EOF;
3308 break;
3309 default:
3310 c = ch;
3311 break;
3313 return c;
3316 static int ld_add_file(TCCState *s1, const char filename[])
3318 if (filename[0] == '/') {
3319 if (CONFIG_SYSROOT[0] == '\0'
3320 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3321 return 0;
3322 filename = tcc_basename(filename);
3324 return tcc_add_dll(s1, filename, 0);
3327 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3329 char filename[1024], libname[1024];
3330 int t, group, nblibs = 0, ret = 0;
3331 char **libs = NULL;
3333 group = !strcmp(cmd, "GROUP");
3334 if (!as_needed)
3335 s1->new_undef_sym = 0;
3336 t = ld_next(s1, filename, sizeof(filename));
3337 if (t != '(')
3338 expect("(");
3339 t = ld_next(s1, filename, sizeof(filename));
3340 for(;;) {
3341 libname[0] = '\0';
3342 if (t == LD_TOK_EOF) {
3343 tcc_error_noabort("unexpected end of file");
3344 ret = -1;
3345 goto lib_parse_error;
3346 } else if (t == ')') {
3347 break;
3348 } else if (t == '-') {
3349 t = ld_next(s1, filename, sizeof(filename));
3350 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3351 tcc_error_noabort("library name expected");
3352 ret = -1;
3353 goto lib_parse_error;
3355 pstrcpy(libname, sizeof libname, &filename[1]);
3356 if (s1->static_link) {
3357 snprintf(filename, sizeof filename, "lib%s.a", libname);
3358 } else {
3359 snprintf(filename, sizeof filename, "lib%s.so", libname);
3361 } else if (t != LD_TOK_NAME) {
3362 tcc_error_noabort("filename expected");
3363 ret = -1;
3364 goto lib_parse_error;
3366 if (!strcmp(filename, "AS_NEEDED")) {
3367 ret = ld_add_file_list(s1, cmd, 1);
3368 if (ret)
3369 goto lib_parse_error;
3370 } else {
3371 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3372 if (!as_needed) {
3373 ret = ld_add_file(s1, filename);
3374 if (ret)
3375 goto lib_parse_error;
3376 if (group) {
3377 /* Add the filename *and* the libname to avoid future conversions */
3378 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3379 if (libname[0] != '\0')
3380 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3384 t = ld_next(s1, filename, sizeof(filename));
3385 if (t == ',') {
3386 t = ld_next(s1, filename, sizeof(filename));
3389 if (group && !as_needed) {
3390 while (s1->new_undef_sym) {
3391 int i;
3392 s1->new_undef_sym = 0;
3393 for (i = 0; i < nblibs; i ++)
3394 ld_add_file(s1, libs[i]);
3397 lib_parse_error:
3398 dynarray_reset(&libs, &nblibs);
3399 return ret;
3402 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3403 files */
3404 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3406 char cmd[64];
3407 char filename[1024];
3408 int t, ret;
3410 s1->fd = fd;
3411 s1->cc = -1;
3412 for(;;) {
3413 t = ld_next(s1, cmd, sizeof(cmd));
3414 if (t == LD_TOK_EOF)
3415 return 0;
3416 else if (t != LD_TOK_NAME)
3417 return -1;
3418 if (!strcmp(cmd, "INPUT") ||
3419 !strcmp(cmd, "GROUP")) {
3420 ret = ld_add_file_list(s1, cmd, 0);
3421 if (ret)
3422 return ret;
3423 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3424 !strcmp(cmd, "TARGET")) {
3425 /* ignore some commands */
3426 t = ld_next(s1, cmd, sizeof(cmd));
3427 if (t != '(')
3428 expect("(");
3429 for(;;) {
3430 t = ld_next(s1, filename, sizeof(filename));
3431 if (t == LD_TOK_EOF) {
3432 tcc_error_noabort("unexpected end of file");
3433 return -1;
3434 } else if (t == ')') {
3435 break;
3438 } else {
3439 return -1;
3442 return 0;
3444 #endif /* !ELF_OBJ_ONLY */