Add _ISOCxx_SOURCE glibc compatible macros.
[tinycc.git] / tccelf.c
blob2577ac5bf5774ef5038bd788ec46ff612a7e1bf0
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);
89 ST_FUNC void tcc_add_bcheck(TCCState *s1)
91 addr_t *ptr;
93 if (0 == s1->do_bounds_check)
94 return;
95 ptr = section_ptr_add(bounds_section, sizeof(*ptr));
96 *ptr = 0;
97 set_elf_sym(symtab_section, 0, 0,
98 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
99 bounds_section->sh_num, "__bounds_start");
100 /* pull bcheck.o from libtcc1.a */
101 set_elf_sym(symtab_section, 0, 0,
102 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
103 SHN_UNDEF, "__bound_init");
105 #endif
107 ST_FUNC void tccelf_stab_new(TCCState *s)
109 TCCState *s1 = s;
110 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
111 stab_section->sh_entsize = sizeof(Stab_Sym);
112 stab_section->sh_addralign = 4;
113 stab_section->link = new_section(s, ".stabstr", SHT_STRTAB, 0);
114 put_elf_str(stab_section->link, "");
115 /* put first entry */
116 put_stabs(s, "", 0, 0, 0, 0);
119 static void free_section(Section *s)
121 tcc_free(s->data);
124 ST_FUNC void tccelf_delete(TCCState *s1)
126 int i;
128 #ifndef ELF_OBJ_ONLY
129 /* free symbol versions */
130 for (i = 0; i < nb_sym_versions; i++) {
131 tcc_free(sym_versions[i].version);
132 tcc_free(sym_versions[i].lib);
134 tcc_free(sym_versions);
135 tcc_free(sym_to_version);
136 #endif
138 /* free all sections */
139 for(i = 1; i < s1->nb_sections; i++)
140 free_section(s1->sections[i]);
141 dynarray_reset(&s1->sections, &s1->nb_sections);
143 for(i = 0; i < s1->nb_priv_sections; i++)
144 free_section(s1->priv_sections[i]);
145 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
147 /* free any loaded DLLs */
148 #ifdef TCC_IS_NATIVE
149 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
150 DLLReference *ref = s1->loaded_dlls[i];
151 if ( ref->handle )
152 # ifdef _WIN32
153 FreeLibrary((HMODULE)ref->handle);
154 # else
155 dlclose(ref->handle);
156 # endif
158 #endif
159 /* free loaded dlls array */
160 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
161 tcc_free(s1->sym_attrs);
163 symtab_section = NULL; /* for tccrun.c:rt_printline() */
166 /* save section data state */
167 ST_FUNC void tccelf_begin_file(TCCState *s1)
169 Section *s; int i;
170 for (i = 1; i < s1->nb_sections; i++) {
171 s = s1->sections[i];
172 s->sh_offset = s->data_offset;
174 /* disable symbol hashing during compilation */
175 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
176 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
177 s1->uw_sym = 0;
178 #endif
181 /* At the end of compilation, convert any UNDEF syms to global, and merge
182 with previously existing symbols */
183 ST_FUNC void tccelf_end_file(TCCState *s1)
185 Section *s = s1->symtab;
186 int first_sym, nb_syms, *tr, i;
188 first_sym = s->sh_offset / sizeof (ElfSym);
189 nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
190 s->data_offset = s->sh_offset;
191 s->link->data_offset = s->link->sh_offset;
192 s->hash = s->reloc, s->reloc = NULL;
193 tr = tcc_mallocz(nb_syms * sizeof *tr);
195 for (i = 0; i < nb_syms; ++i) {
196 ElfSym *sym = (ElfSym*)s->data + first_sym + i;
197 if (sym->st_shndx == SHN_UNDEF
198 && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
199 sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
200 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
201 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
203 /* now update relocations */
204 for (i = 1; i < s1->nb_sections; i++) {
205 Section *sr = s1->sections[i];
206 if (sr->sh_type == SHT_RELX && sr->link == s) {
207 ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
208 ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
209 for (; rel < rel_end; ++rel) {
210 int n = ELFW(R_SYM)(rel->r_info) - first_sym;
211 //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
212 rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
216 tcc_free(tr);
219 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
221 Section *sec;
223 sec = tcc_mallocz(sizeof(Section) + strlen(name));
224 sec->s1 = s1;
225 strcpy(sec->name, name);
226 sec->sh_type = sh_type;
227 sec->sh_flags = sh_flags;
228 switch(sh_type) {
229 case SHT_GNU_versym:
230 sec->sh_addralign = 2;
231 break;
232 case SHT_HASH:
233 case SHT_REL:
234 case SHT_RELA:
235 case SHT_DYNSYM:
236 case SHT_SYMTAB:
237 case SHT_DYNAMIC:
238 case SHT_GNU_verneed:
239 case SHT_GNU_verdef:
240 sec->sh_addralign = PTR_SIZE;
241 break;
242 case SHT_STRTAB:
243 sec->sh_addralign = 1;
244 break;
245 default:
246 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */
247 break;
250 if (sh_flags & SHF_PRIVATE) {
251 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
252 } else {
253 sec->sh_num = s1->nb_sections;
254 dynarray_add(&s1->sections, &s1->nb_sections, sec);
257 return sec;
260 ST_FUNC Section *new_symtab(TCCState *s1,
261 const char *symtab_name, int sh_type, int sh_flags,
262 const char *strtab_name,
263 const char *hash_name, int hash_sh_flags)
265 Section *symtab, *strtab, *hash;
266 int *ptr, nb_buckets;
268 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
269 symtab->sh_entsize = sizeof(ElfW(Sym));
270 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
271 put_elf_str(strtab, "");
272 symtab->link = strtab;
273 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
275 nb_buckets = 1;
277 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
278 hash->sh_entsize = sizeof(int);
279 symtab->hash = hash;
280 hash->link = symtab;
282 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
283 ptr[0] = nb_buckets;
284 ptr[1] = 1;
285 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
286 return symtab;
289 /* realloc section and set its content to zero */
290 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
292 unsigned long size;
293 unsigned char *data;
295 size = sec->data_allocated;
296 if (size == 0)
297 size = 1;
298 while (size < new_size)
299 size = size * 2;
300 data = tcc_realloc(sec->data, size);
301 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
302 sec->data = data;
303 sec->data_allocated = size;
306 /* reserve at least 'size' bytes aligned per 'align' in section
307 'sec' from current offset, and return the aligned offset */
308 ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
310 size_t offset, offset1;
312 offset = (sec->data_offset + align - 1) & -align;
313 offset1 = offset + size;
314 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
315 section_realloc(sec, offset1);
316 sec->data_offset = offset1;
317 if (align > sec->sh_addralign)
318 sec->sh_addralign = align;
319 return offset;
322 /* reserve at least 'size' bytes in section 'sec' from
323 sec->data_offset. */
324 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
326 size_t offset = section_add(sec, size, 1);
327 return sec->data + offset;
330 /* reserve at least 'size' bytes from section start */
331 ST_FUNC void section_reserve(Section *sec, unsigned long size)
333 if (size > sec->data_allocated)
334 section_realloc(sec, size);
335 if (size > sec->data_offset)
336 sec->data_offset = size;
339 static Section *find_section_create (TCCState *s1, const char *name, int create)
341 Section *sec;
342 int i;
343 for(i = 1; i < s1->nb_sections; i++) {
344 sec = s1->sections[i];
345 if (!strcmp(name, sec->name))
346 return sec;
348 /* sections are created as PROGBITS */
349 return create ? new_section(s1, name, SHT_PROGBITS, SHF_ALLOC) : NULL;
352 /* return a reference to a section, and create it if it does not
353 exists */
354 ST_FUNC Section *find_section(TCCState *s1, const char *name)
356 return find_section_create (s1, name, 1);
359 /* ------------------------------------------------------------------------- */
361 ST_FUNC int put_elf_str(Section *s, const char *sym)
363 int offset, len;
364 char *ptr;
366 len = strlen(sym) + 1;
367 offset = s->data_offset;
368 ptr = section_ptr_add(s, len);
369 memmove(ptr, sym, len);
370 return offset;
373 /* elf symbol hashing function */
374 static unsigned long elf_hash(const unsigned char *name)
376 unsigned long h = 0, g;
378 while (*name) {
379 h = (h << 4) + *name++;
380 g = h & 0xf0000000;
381 if (g)
382 h ^= g >> 24;
383 h &= ~g;
385 return h;
388 /* rebuild hash table of section s */
389 /* NOTE: we do factorize the hash table code to go faster */
390 static void rebuild_hash(Section *s, unsigned int nb_buckets)
392 ElfW(Sym) *sym;
393 int *ptr, *hash, nb_syms, sym_index, h;
394 unsigned char *strtab;
396 strtab = s->link->data;
397 nb_syms = s->data_offset / sizeof(ElfW(Sym));
399 if (!nb_buckets)
400 nb_buckets = ((int*)s->hash->data)[0];
402 s->hash->data_offset = 0;
403 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
404 ptr[0] = nb_buckets;
405 ptr[1] = nb_syms;
406 ptr += 2;
407 hash = ptr;
408 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
409 ptr += nb_buckets + 1;
411 sym = (ElfW(Sym) *)s->data + 1;
412 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
413 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
414 h = elf_hash(strtab + sym->st_name) % nb_buckets;
415 *ptr = hash[h];
416 hash[h] = sym_index;
417 } else {
418 *ptr = 0;
420 ptr++;
421 sym++;
425 /* return the symbol number */
426 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
427 int info, int other, int shndx, const char *name)
429 int name_offset, sym_index;
430 int nbuckets, h;
431 ElfW(Sym) *sym;
432 Section *hs;
434 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
435 if (name && name[0])
436 name_offset = put_elf_str(s->link, name);
437 else
438 name_offset = 0;
439 /* XXX: endianness */
440 sym->st_name = name_offset;
441 sym->st_value = value;
442 sym->st_size = size;
443 sym->st_info = info;
444 sym->st_other = other;
445 sym->st_shndx = shndx;
446 sym_index = sym - (ElfW(Sym) *)s->data;
447 hs = s->hash;
448 if (hs) {
449 int *ptr, *base;
450 ptr = section_ptr_add(hs, sizeof(int));
451 base = (int *)hs->data;
452 /* only add global or weak symbols. */
453 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
454 /* add another hashing entry */
455 nbuckets = base[0];
456 h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
457 *ptr = base[2 + h];
458 base[2 + h] = sym_index;
459 base[1]++;
460 /* we resize the hash table */
461 hs->nb_hashed_syms++;
462 if (hs->nb_hashed_syms > 2 * nbuckets) {
463 rebuild_hash(s, 2 * nbuckets);
465 } else {
466 *ptr = 0;
467 base[1]++;
470 return sym_index;
473 ST_FUNC int find_elf_sym(Section *s, const char *name)
475 ElfW(Sym) *sym;
476 Section *hs;
477 int nbuckets, sym_index, h;
478 const char *name1;
480 hs = s->hash;
481 if (!hs)
482 return 0;
483 nbuckets = ((int *)hs->data)[0];
484 h = elf_hash((unsigned char *) name) % nbuckets;
485 sym_index = ((int *)hs->data)[2 + h];
486 while (sym_index != 0) {
487 sym = &((ElfW(Sym) *)s->data)[sym_index];
488 name1 = (char *) s->link->data + sym->st_name;
489 if (!strcmp(name, name1))
490 return sym_index;
491 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
493 return 0;
496 /* return elf symbol value, signal error if 'err' is nonzero */
497 ST_FUNC addr_t get_elf_sym_addr(TCCState *s1, const char *name, int err)
499 int sym_index;
500 ElfW(Sym) *sym;
502 sym_index = find_elf_sym(s1->symtab, name);
503 sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
504 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
505 if (err)
506 tcc_error("%s not defined", name);
507 return 0;
509 return sym->st_value;
512 /* list elf symbol names and values */
513 ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
514 void (*symbol_cb)(void *ctx, const char *name, const void *val))
516 ElfW(Sym) *sym;
517 Section *symtab;
518 int sym_index, end_sym;
519 const char *name;
520 unsigned char sym_vis, sym_bind;
522 symtab = s->symtab;
523 end_sym = symtab->data_offset / sizeof (ElfSym);
524 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
525 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
526 if (sym->st_value) {
527 name = (char *) symtab->link->data + sym->st_name;
528 sym_bind = ELFW(ST_BIND)(sym->st_info);
529 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
530 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
531 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
536 /* return elf symbol value */
537 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
539 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0);
542 /* list elf symbol names and values */
543 LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
544 void (*symbol_cb)(void *ctx, const char *name, const void *val))
546 list_elf_symbols(s, ctx, symbol_cb);
549 #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
550 /* return elf symbol value or error */
551 ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
553 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1);
555 #endif
557 #ifndef ELF_OBJ_ONLY
558 static void
559 version_add (TCCState *s1)
561 int i;
562 ElfW(Sym) *sym;
563 ElfW(Verneed) *vn = NULL;
564 Section *symtab;
565 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
566 ElfW(Half) *versym;
567 const char *name;
569 if (0 == nb_sym_versions)
570 return;
571 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
572 versym_section->sh_entsize = sizeof(ElfW(Half));
573 verneed_section = new_section(s1, ".gnu.version_r", SHT_GNU_verneed, SHF_ALLOC);
574 versym_section->link = s1->dynsym;
575 verneed_section->link = s1->dynsym->link;
577 /* add needed symbols */
578 symtab = s1->dynsym;
579 end_sym = symtab->data_offset / sizeof (ElfSym);
580 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
581 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
582 int dllindex, verndx;
583 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
584 name = (char *) symtab->link->data + sym->st_name;
585 dllindex = find_elf_sym(s1->dynsymtab_section, name);
586 verndx = (dllindex && dllindex < nb_sym_to_version)
587 ? sym_to_version[dllindex] : -1;
588 if (verndx >= 0) {
589 if (!sym_versions[verndx].out_index)
590 sym_versions[verndx].out_index = nb_versions++;
591 versym[sym_index] = sym_versions[verndx].out_index;
592 } else
593 versym[sym_index] = 0;
595 /* generate verneed section */
596 for (i = nb_sym_versions; i-- > 0;) {
597 struct sym_version *sv = &sym_versions[i];
598 int n_same_libs = 0, prev;
599 size_t vnofs;
600 ElfW(Vernaux) *vna = 0;
601 if (sv->out_index < 1)
602 continue;
603 vnofs = section_add(verneed_section, sizeof(*vn), 1);
604 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
605 vn->vn_version = 1;
606 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
607 vn->vn_aux = sizeof (*vn);
608 do {
609 prev = sv->prev_same_lib;
610 if (sv->out_index > 0) {
611 vna = section_ptr_add(verneed_section, sizeof(*vna));
612 vna->vna_hash = elf_hash ((const unsigned char *)sv->version);
613 vna->vna_flags = 0;
614 vna->vna_other = sv->out_index;
615 sv->out_index = -2;
616 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
617 vna->vna_next = sizeof (*vna);
618 n_same_libs++;
620 if (prev >= 0)
621 sv = &sym_versions[prev];
622 } while(prev >= 0);
623 vna->vna_next = 0;
624 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
625 vn->vn_cnt = n_same_libs;
626 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
627 nb_entries++;
629 if (vn)
630 vn->vn_next = 0;
631 verneed_section->sh_info = nb_entries;
632 dt_verneednum = nb_entries;
634 #endif
636 /* add an elf symbol : check if it is already defined and patch
637 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
638 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
639 int info, int other, int shndx, const char *name)
641 TCCState *s1 = s->s1;
642 ElfW(Sym) *esym;
643 int sym_bind, sym_index, sym_type, esym_bind;
644 unsigned char sym_vis, esym_vis, new_vis;
646 sym_bind = ELFW(ST_BIND)(info);
647 sym_type = ELFW(ST_TYPE)(info);
648 sym_vis = ELFW(ST_VISIBILITY)(other);
650 if (sym_bind != STB_LOCAL) {
651 /* we search global or weak symbols */
652 sym_index = find_elf_sym(s, name);
653 if (!sym_index)
654 goto do_def;
655 esym = &((ElfW(Sym) *)s->data)[sym_index];
656 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
657 && esym->st_other == other && esym->st_shndx == shndx)
658 return sym_index;
659 if (esym->st_shndx != SHN_UNDEF) {
660 esym_bind = ELFW(ST_BIND)(esym->st_info);
661 /* propagate the most constraining visibility */
662 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
663 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
664 if (esym_vis == STV_DEFAULT) {
665 new_vis = sym_vis;
666 } else if (sym_vis == STV_DEFAULT) {
667 new_vis = esym_vis;
668 } else {
669 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
671 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
672 | new_vis;
673 other = esym->st_other; /* in case we have to patch esym */
674 if (shndx == SHN_UNDEF) {
675 /* ignore adding of undefined symbol if the
676 corresponding symbol is already defined */
677 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
678 /* global overrides weak, so patch */
679 goto do_patch;
680 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
681 /* weak is ignored if already global */
682 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
683 /* keep first-found weak definition, ignore subsequents */
684 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
685 /* ignore hidden symbols after */
686 } else if ((esym->st_shndx == SHN_COMMON
687 || esym->st_shndx == bss_section->sh_num)
688 && (shndx < SHN_LORESERVE
689 && shndx != bss_section->sh_num)) {
690 /* data symbol gets precedence over common/bss */
691 goto do_patch;
692 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
693 /* data symbol keeps precedence over common/bss */
694 } else if (s->sh_flags & SHF_DYNSYM) {
695 /* we accept that two DLL define the same symbol */
696 } else if (esym->st_other & ST_ASM_SET) {
697 /* If the existing symbol came from an asm .set
698 we can override. */
699 goto do_patch;
700 } else {
701 #if 0
702 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
703 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
704 #endif
705 tcc_error_noabort("'%s' defined twice", name);
707 } else {
708 do_patch:
709 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
710 esym->st_shndx = shndx;
711 s1->new_undef_sym = 1;
712 esym->st_value = value;
713 esym->st_size = size;
714 esym->st_other = other;
716 } else {
717 do_def:
718 sym_index = put_elf_sym(s, value, size,
719 ELFW(ST_INFO)(sym_bind, sym_type), other,
720 shndx, name);
722 return sym_index;
725 /* put relocation */
726 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
727 int type, int symbol, addr_t addend)
729 TCCState *s1 = s->s1;
730 char buf[256];
731 Section *sr;
732 ElfW_Rel *rel;
734 sr = s->reloc;
735 if (!sr) {
736 /* if no relocation section, create it */
737 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
738 /* if the symtab is allocated, then we consider the relocation
739 are also */
740 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
741 sr->sh_entsize = sizeof(ElfW_Rel);
742 sr->link = symtab;
743 sr->sh_info = s->sh_num;
744 s->reloc = sr;
746 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
747 rel->r_offset = offset;
748 rel->r_info = ELFW(R_INFO)(symbol, type);
749 #if SHT_RELX == SHT_RELA
750 rel->r_addend = addend;
751 #endif
752 if (SHT_RELX != SHT_RELA && addend)
753 tcc_error("non-zero addend on REL architecture");
756 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
757 int type, int symbol)
759 put_elf_reloca(symtab, s, offset, type, symbol, 0);
762 /* Remove relocations for section S->reloc starting at oldrelocoffset
763 that are to the same place, retaining the last of them. As side effect
764 the relocations are sorted. Possibly reduces the number of relocs. */
765 ST_FUNC void squeeze_multi_relocs(Section *s, size_t oldrelocoffset)
767 Section *sr = s->reloc;
768 ElfW_Rel *r, *dest;
769 ssize_t a;
770 ElfW(Addr) addr;
772 if (oldrelocoffset + sizeof(*r) >= sr->data_offset)
773 return;
774 /* The relocs we're dealing with are the result of initializer parsing.
775 So they will be mostly in order and there aren't many of them.
776 Secondly we need a stable sort (which qsort isn't). We use
777 a simple insertion sort. */
778 for (a = oldrelocoffset + sizeof(*r); a < sr->data_offset; a += sizeof(*r)) {
779 ssize_t i = a - sizeof(*r);
780 addr = ((ElfW_Rel*)(sr->data + a))->r_offset;
781 for (; i >= (ssize_t)oldrelocoffset &&
782 ((ElfW_Rel*)(sr->data + i))->r_offset > addr; i -= sizeof(*r)) {
783 ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a);
784 *(ElfW_Rel*)(sr->data + a) = *(ElfW_Rel*)(sr->data + i);
785 *(ElfW_Rel*)(sr->data + i) = tmp;
789 r = (ElfW_Rel*)(sr->data + oldrelocoffset);
790 dest = r;
791 for (; r < (ElfW_Rel*)(sr->data + sr->data_offset); r++) {
792 if (dest->r_offset != r->r_offset)
793 dest++;
794 *dest = *r;
796 sr->data_offset = (unsigned char*)dest - sr->data + sizeof(*r);
799 /* put stab debug information */
801 ST_FUNC void put_stabs(TCCState *s1, const char *str, int type, int other, int desc,
802 unsigned long value)
804 Stab_Sym *sym;
806 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
807 if (str) {
808 sym->n_strx = put_elf_str(stab_section->link, str);
809 } else {
810 sym->n_strx = 0;
812 sym->n_type = type;
813 sym->n_other = other;
814 sym->n_desc = desc;
815 sym->n_value = value;
818 ST_FUNC void put_stabs_r(TCCState *s1, const char *str, int type, int other, int desc,
819 unsigned long value, Section *sec, int sym_index)
821 put_stabs(s1, str, type, other, desc, value);
822 put_elf_reloc(symtab_section, stab_section,
823 stab_section->data_offset - sizeof(unsigned int),
824 R_DATA_32, sym_index);
827 ST_FUNC void put_stabn(TCCState *s1, int type, int other, int desc, int value)
829 put_stabs(s1, NULL, type, other, desc, value);
832 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
834 int n;
835 struct sym_attr *tab;
837 if (index >= s1->nb_sym_attrs) {
838 if (!alloc)
839 return s1->sym_attrs;
840 /* find immediately bigger power of 2 and reallocate array */
841 n = 1;
842 while (index >= n)
843 n *= 2;
844 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
845 s1->sym_attrs = tab;
846 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
847 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
848 s1->nb_sym_attrs = n;
850 return &s1->sym_attrs[index];
853 /* Browse each elem of type <type> in section <sec> starting at elem <startoff>
854 using variable <elem> */
855 #define for_each_elem(sec, startoff, elem, type) \
856 for (elem = (type *) sec->data + startoff; \
857 elem < (type *) (sec->data + sec->data_offset); elem++)
859 /* In an ELF file symbol table, the local symbols must appear below
860 the global and weak ones. Since TCC cannot sort it while generating
861 the code, we must do it after. All the relocation tables are also
862 modified to take into account the symbol table sorting */
863 static void sort_syms(TCCState *s1, Section *s)
865 int *old_to_new_syms;
866 ElfW(Sym) *new_syms;
867 int nb_syms, i;
868 ElfW(Sym) *p, *q;
869 ElfW_Rel *rel;
870 Section *sr;
871 int type, sym_index;
873 nb_syms = s->data_offset / sizeof(ElfW(Sym));
874 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
875 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
877 /* first pass for local symbols */
878 p = (ElfW(Sym) *)s->data;
879 q = new_syms;
880 for(i = 0; i < nb_syms; i++) {
881 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
882 old_to_new_syms[i] = q - new_syms;
883 *q++ = *p;
885 p++;
887 /* save the number of local symbols in section header */
888 if( s->sh_size ) /* this 'if' makes IDA happy */
889 s->sh_info = q - new_syms;
891 /* then second pass for non local symbols */
892 p = (ElfW(Sym) *)s->data;
893 for(i = 0; i < nb_syms; i++) {
894 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
895 old_to_new_syms[i] = q - new_syms;
896 *q++ = *p;
898 p++;
901 /* we copy the new symbols to the old */
902 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
903 tcc_free(new_syms);
905 /* now we modify all the relocations */
906 for(i = 1; i < s1->nb_sections; i++) {
907 sr = s1->sections[i];
908 if (sr->sh_type == SHT_RELX && sr->link == s) {
909 for_each_elem(sr, 0, rel, ElfW_Rel) {
910 sym_index = ELFW(R_SYM)(rel->r_info);
911 type = ELFW(R_TYPE)(rel->r_info);
912 sym_index = old_to_new_syms[sym_index];
913 rel->r_info = ELFW(R_INFO)(sym_index, type);
918 tcc_free(old_to_new_syms);
921 /* relocate symbol table, resolve undefined symbols if do_resolve is
922 true and output error if undefined symbol. */
923 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
925 ElfW(Sym) *sym;
926 int sym_bind, sh_num;
927 const char *name;
929 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
930 sh_num = sym->st_shndx;
931 if (sh_num == SHN_UNDEF) {
932 name = (char *) s1->symtab->link->data + sym->st_name;
933 /* Use ld.so to resolve symbol for us (for tcc -run) */
934 if (do_resolve) {
935 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
936 void *addr = dlsym(RTLD_DEFAULT, name);
937 if (addr) {
938 sym->st_value = (addr_t) addr;
939 #ifdef DEBUG_RELOC
940 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
941 #endif
942 goto found;
944 #endif
945 /* if dynamic symbol exist, it will be used in relocate_section */
946 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
947 goto found;
948 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
949 it */
950 if (!strcmp(name, "_fp_hw"))
951 goto found;
952 /* only weak symbols are accepted to be undefined. Their
953 value is zero */
954 sym_bind = ELFW(ST_BIND)(sym->st_info);
955 if (sym_bind == STB_WEAK)
956 sym->st_value = 0;
957 else
958 tcc_error_noabort("undefined symbol '%s'", name);
959 } else if (sh_num < SHN_LORESERVE) {
960 /* add section base */
961 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
963 found: ;
967 /* relocate a given section (CPU dependent) by applying the relocations
968 in the associated relocation section */
969 ST_FUNC void relocate_section(TCCState *s1, Section *s)
971 Section *sr = s->reloc;
972 ElfW_Rel *rel;
973 ElfW(Sym) *sym;
974 int type, sym_index;
975 unsigned char *ptr;
976 addr_t tgt, addr;
978 qrel = (ElfW_Rel *)sr->data;
980 for_each_elem(sr, 0, rel, ElfW_Rel) {
981 ptr = s->data + rel->r_offset;
982 sym_index = ELFW(R_SYM)(rel->r_info);
983 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
984 type = ELFW(R_TYPE)(rel->r_info);
985 tgt = sym->st_value;
986 #if SHT_RELX == SHT_RELA
987 tgt += rel->r_addend;
988 #endif
989 addr = s->sh_addr + rel->r_offset;
990 relocate(s1, rel, type, ptr, addr, tgt);
992 /* if the relocation is allocated, we change its symbol table */
993 if (sr->sh_flags & SHF_ALLOC)
994 sr->link = s1->dynsym;
997 #ifndef ELF_OBJ_ONLY
998 /* relocate relocation table in 'sr' */
999 static void relocate_rel(TCCState *s1, Section *sr)
1001 Section *s;
1002 ElfW_Rel *rel;
1004 s = s1->sections[sr->sh_info];
1005 for_each_elem(sr, 0, rel, ElfW_Rel)
1006 rel->r_offset += s->sh_addr;
1009 /* count the number of dynamic relocations so that we can reserve
1010 their space */
1011 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
1013 int count = 0;
1014 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1015 ElfW_Rel *rel;
1016 for_each_elem(sr, 0, rel, ElfW_Rel) {
1017 int sym_index = ELFW(R_SYM)(rel->r_info);
1018 int type = ELFW(R_TYPE)(rel->r_info);
1019 switch(type) {
1020 #if defined(TCC_TARGET_I386)
1021 case R_386_32:
1022 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
1023 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
1024 /* don't fixup unresolved (weak) symbols */
1025 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
1026 break;
1028 #elif defined(TCC_TARGET_X86_64)
1029 case R_X86_64_32:
1030 case R_X86_64_32S:
1031 case R_X86_64_64:
1032 #endif
1033 count++;
1034 break;
1035 #if defined(TCC_TARGET_I386)
1036 case R_386_PC32:
1037 #elif defined(TCC_TARGET_X86_64)
1038 case R_X86_64_PC32:
1039 #endif
1040 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1041 count++;
1042 break;
1043 default:
1044 break;
1047 if (count) {
1048 /* allocate the section */
1049 sr->sh_flags |= SHF_ALLOC;
1050 sr->sh_size = count * sizeof(ElfW_Rel);
1052 #endif
1053 return count;
1056 static void build_got(TCCState *s1)
1058 /* if no got, then create it */
1059 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1060 s1->got->sh_entsize = 4;
1061 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1062 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1063 /* keep space for _DYNAMIC pointer and two dummy got entries */
1064 section_ptr_add(s1->got, 3 * PTR_SIZE);
1067 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1068 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1069 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1070 Returns the offset of the GOT or (if any) PLT entry. */
1071 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1072 int sym_index)
1074 int need_plt_entry;
1075 const char *name;
1076 ElfW(Sym) *sym;
1077 struct sym_attr *attr;
1078 unsigned got_offset;
1079 char plt_name[100];
1080 int len;
1082 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1083 attr = get_sym_attr(s1, sym_index, 1);
1085 /* In case a function is both called and its address taken 2 GOT entries
1086 are created, one for taking the address (GOT) and the other for the PLT
1087 entry (PLTGOT). */
1088 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1089 return attr;
1091 /* create the GOT entry */
1092 got_offset = s1->got->data_offset;
1093 section_ptr_add(s1->got, PTR_SIZE);
1095 /* Create the GOT relocation that will insert the address of the object or
1096 function of interest in the GOT entry. This is a static relocation for
1097 memory output (dlsym will give us the address of symbols) and dynamic
1098 relocation otherwise (executable and DLLs). The relocation should be
1099 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1100 associated to a PLT entry) but is currently done at load time for an
1101 unknown reason. */
1103 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1104 name = (char *) symtab_section->link->data + sym->st_name;
1106 if (s1->dynsym) {
1107 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1108 /* Hack alarm. We don't want to emit dynamic symbols
1109 and symbol based relocs for STB_LOCAL symbols, but rather
1110 want to resolve them directly. At this point the symbol
1111 values aren't final yet, so we must defer this. We will later
1112 have to create a RELATIVE reloc anyway, so we misuse the
1113 relocation slot to smuggle the symbol reference until
1114 fill_local_got_entries. Not that the sym_index is
1115 relative to symtab_section, not s1->dynsym! Nevertheless
1116 we use s1->dyn_sym so that if this is the first call
1117 that got->reloc is correctly created. Also note that
1118 RELATIVE relocs are not normally created for the .got,
1119 so the types serves as a marker for later (and is retained
1120 also for the final output, which is okay because then the
1121 got is just normal data). */
1122 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1123 sym_index);
1124 } else {
1125 if (0 == attr->dyn_index)
1126 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1127 sym->st_size, sym->st_info, 0,
1128 sym->st_shndx, name);
1129 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
1130 attr->dyn_index);
1132 } else {
1133 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1134 sym_index);
1137 if (need_plt_entry) {
1138 if (!s1->plt) {
1139 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1140 SHF_ALLOC | SHF_EXECINSTR);
1141 s1->plt->sh_entsize = 4;
1144 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1146 /* create a symbol 'sym@plt' for the PLT jump vector */
1147 len = strlen(name);
1148 if (len > sizeof plt_name - 5)
1149 len = sizeof plt_name - 5;
1150 memcpy(plt_name, name, len);
1151 strcpy(plt_name + len, "@plt");
1152 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
1153 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1155 } else {
1156 attr->got_offset = got_offset;
1159 return attr;
1162 /* build GOT and PLT entries */
1163 ST_FUNC void build_got_entries(TCCState *s1)
1165 Section *s;
1166 ElfW_Rel *rel;
1167 ElfW(Sym) *sym;
1168 int i, type, gotplt_entry, reloc_type, sym_index;
1169 struct sym_attr *attr;
1171 for(i = 1; i < s1->nb_sections; i++) {
1172 s = s1->sections[i];
1173 if (s->sh_type != SHT_RELX)
1174 continue;
1175 /* no need to handle got relocations */
1176 if (s->link != symtab_section)
1177 continue;
1178 for_each_elem(s, 0, rel, ElfW_Rel) {
1179 type = ELFW(R_TYPE)(rel->r_info);
1180 gotplt_entry = gotplt_entry_type(type);
1181 if (gotplt_entry == -1)
1182 tcc_error ("Unknown relocation type for got: %d", type);
1183 sym_index = ELFW(R_SYM)(rel->r_info);
1184 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1186 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1187 continue;
1190 /* Automatically create PLT/GOT [entry] if it is an undefined
1191 reference (resolved at runtime), or the symbol is absolute,
1192 probably created by tcc_add_symbol, and thus on 64-bit
1193 targets might be too far from application code. */
1194 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1195 if (sym->st_shndx == SHN_UNDEF) {
1196 ElfW(Sym) *esym;
1197 int dynindex;
1198 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1199 continue;
1200 /* Relocations for UNDEF symbols would normally need
1201 to be transferred into the executable or shared object.
1202 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1203 But TCC doesn't do that (at least for exes), so we
1204 need to resolve all such relocs locally. And that
1205 means PLT slots for functions in DLLs and COPY relocs for
1206 data symbols. COPY relocs were generated in
1207 bind_exe_dynsyms (and the symbol adjusted to be defined),
1208 and for functions we were generated a dynamic symbol
1209 of function type. */
1210 if (s1->dynsym) {
1211 /* dynsym isn't set for -run :-/ */
1212 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1213 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1214 if (dynindex
1215 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1216 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1217 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1218 goto jmp_slot;
1220 } else if (!(sym->st_shndx == SHN_ABS
1221 #ifndef TCC_TARGET_ARM
1222 && PTR_SIZE == 8
1223 #endif
1225 continue;
1228 #ifdef TCC_TARGET_X86_64
1229 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1230 sym->st_shndx != SHN_UNDEF &&
1231 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1232 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1233 s1->output_type == TCC_OUTPUT_EXE)) {
1234 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1235 continue;
1237 #endif
1238 reloc_type = code_reloc(type);
1239 if (reloc_type == -1)
1240 tcc_error ("Unknown relocation type: %d", type);
1241 else if (reloc_type != 0) {
1242 jmp_slot:
1243 reloc_type = R_JMP_SLOT;
1244 } else
1245 reloc_type = R_GLOB_DAT;
1247 if (!s1->got)
1248 build_got(s1);
1250 if (gotplt_entry == BUILD_GOT_ONLY)
1251 continue;
1253 attr = put_got_entry(s1, reloc_type, sym_index);
1255 if (reloc_type == R_JMP_SLOT)
1256 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1261 /* put dynamic tag */
1262 static void put_dt(Section *dynamic, int dt, addr_t val)
1264 ElfW(Dyn) *dyn;
1265 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1266 dyn->d_tag = dt;
1267 dyn->d_un.d_val = val;
1269 #endif
1271 static void add_init_array_defines(TCCState *s1, const char *section_name)
1273 Section *s;
1274 long end_offset;
1275 char sym_start[1024];
1276 char sym_end[1024];
1278 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1279 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1281 s = find_section(s1, section_name);
1282 if (!s) {
1283 end_offset = 0;
1284 s = data_section;
1285 } else {
1286 end_offset = s->data_offset;
1289 set_elf_sym(symtab_section,
1290 0, 0,
1291 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1292 s->sh_num, sym_start);
1293 set_elf_sym(symtab_section,
1294 end_offset, 0,
1295 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1296 s->sh_num, sym_end);
1299 #ifndef TCC_TARGET_PE
1300 static int tcc_add_support(TCCState *s1, const char *filename)
1302 char buf[1024];
1303 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1304 return tcc_add_file(s1, buf);
1306 #endif
1308 static void add_array (const char *section, TCCState *s1, Sym *sym, int sh_type)
1310 Section *s;
1311 unsigned char *ptr;
1313 s = find_section(s1, section);
1314 if (s) {
1315 s->sh_flags |= SHF_WRITE;
1316 #ifndef TCC_TARGET_PE
1317 s->sh_type = sh_type;
1318 #endif
1319 ptr = section_ptr_add(s, PTR_SIZE);
1320 memset (ptr, 0, PTR_SIZE);
1321 put_elf_reloc (s1->symtab, s, ptr - s->data, R_DATA_PTR, sym->c);
1325 ST_FUNC void add_init_array (TCCState *s1, Sym *sym)
1327 add_array (".init_array", s1, sym, SHT_INIT_ARRAY);
1330 ST_FUNC void add_fini_array (TCCState *s1, Sym *sym)
1332 add_array (".fini_array", s1, sym, SHT_FINI_ARRAY);
1335 /* add tcc runtime libraries */
1336 ST_FUNC void tcc_add_runtime(TCCState *s1)
1338 s1->filetype = 0;
1339 #ifdef CONFIG_TCC_BCHECK
1340 tcc_add_bcheck(s1);
1341 #endif
1342 tcc_add_pragma_libs(s1);
1343 #ifndef TCC_TARGET_PE
1344 /* add libc */
1345 if (!s1->nostdlib) {
1346 tcc_add_library_err(s1, "c");
1347 #ifdef TCC_LIBGCC
1348 if (!s1->static_link) {
1349 if (TCC_LIBGCC[0] == '/')
1350 tcc_add_file(s1, TCC_LIBGCC);
1351 else
1352 tcc_add_dll(s1, TCC_LIBGCC, 0);
1354 #endif
1355 #ifdef CONFIG_TCC_BCHECK
1356 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1357 tcc_add_library_err(s1, "pthread");
1358 tcc_add_library_err(s1, "dl");
1359 tcc_add_support(s1, TCC_LIBBCHECK);
1361 #endif
1362 tcc_add_support(s1, TCC_LIBTCC1);
1363 /* add crt end if not memory output */
1364 if (s1->output_type != TCC_OUTPUT_MEMORY)
1365 tcc_add_crt(s1, "crtn.o");
1367 #endif
1370 /* add various standard linker symbols (must be done after the
1371 sections are filled (for example after allocating common
1372 symbols)) */
1373 static void tcc_add_linker_symbols(TCCState *s1)
1375 char buf[1024];
1376 int i;
1377 Section *s;
1379 set_elf_sym(symtab_section,
1380 text_section->data_offset, 0,
1381 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1382 text_section->sh_num, "_etext");
1383 set_elf_sym(symtab_section,
1384 data_section->data_offset, 0,
1385 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1386 data_section->sh_num, "_edata");
1387 set_elf_sym(symtab_section,
1388 bss_section->data_offset, 0,
1389 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1390 bss_section->sh_num, "_end");
1391 #ifdef TCC_TARGET_RISCV64
1392 /* XXX should be .sdata+0x800, not .data+0x800 */
1393 set_elf_sym(symtab_section,
1394 0x800, 0,
1395 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1396 data_section->sh_num, "__global_pointer$");
1397 #endif
1398 /* horrible new standard ldscript defines */
1399 add_init_array_defines(s1, ".preinit_array");
1400 add_init_array_defines(s1, ".init_array");
1401 add_init_array_defines(s1, ".fini_array");
1403 /* add start and stop symbols for sections whose name can be
1404 expressed in C */
1405 for(i = 1; i < s1->nb_sections; i++) {
1406 s = s1->sections[i];
1407 if (s->sh_type == SHT_PROGBITS &&
1408 (s->sh_flags & SHF_ALLOC)) {
1409 const char *p;
1410 int ch;
1412 /* check if section name can be expressed in C */
1413 p = s->name;
1414 for(;;) {
1415 ch = *p;
1416 if (!ch)
1417 break;
1418 if (!isid(ch) && !isnum(ch))
1419 goto next_sec;
1420 p++;
1422 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1423 set_elf_sym(symtab_section,
1424 0, 0,
1425 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1426 s->sh_num, buf);
1427 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1428 set_elf_sym(symtab_section,
1429 s->data_offset, 0,
1430 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1431 s->sh_num, buf);
1433 next_sec: ;
1437 ST_FUNC void resolve_common_syms(TCCState *s1)
1439 ElfW(Sym) *sym;
1441 /* Allocate common symbols in BSS. */
1442 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1443 if (sym->st_shndx == SHN_COMMON) {
1444 /* symbol alignment is in st_value for SHN_COMMONs */
1445 sym->st_value = section_add(bss_section, sym->st_size,
1446 sym->st_value);
1447 sym->st_shndx = bss_section->sh_num;
1451 /* Now assign linker provided symbols their value. */
1452 tcc_add_linker_symbols(s1);
1455 static void tcc_output_binary(TCCState *s1, FILE *f,
1456 const int *sec_order)
1458 Section *s;
1459 int i, offset, size;
1461 offset = 0;
1462 for(i=1;i<s1->nb_sections;i++) {
1463 s = s1->sections[sec_order[i]];
1464 if (s->sh_type != SHT_NOBITS &&
1465 (s->sh_flags & SHF_ALLOC)) {
1466 while (offset < s->sh_offset) {
1467 fputc(0, f);
1468 offset++;
1470 size = s->sh_size;
1471 fwrite(s->data, 1, size, f);
1472 offset += size;
1477 #ifndef ELF_OBJ_ONLY
1478 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1480 int sym_index = ELFW(R_SYM) (rel->r_info);
1481 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1482 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1483 unsigned offset = attr->got_offset;
1485 if (0 == offset)
1486 return;
1487 section_reserve(s1->got, offset + PTR_SIZE);
1488 #ifdef TCC_TARGET_X86_64
1489 write64le(s1->got->data + offset, sym->st_value);
1490 #else
1491 write32le(s1->got->data + offset, sym->st_value);
1492 #endif
1495 /* Perform relocation to GOT or PLT entries */
1496 ST_FUNC void fill_got(TCCState *s1)
1498 Section *s;
1499 ElfW_Rel *rel;
1500 int i;
1502 for(i = 1; i < s1->nb_sections; i++) {
1503 s = s1->sections[i];
1504 if (s->sh_type != SHT_RELX)
1505 continue;
1506 /* no need to handle got relocations */
1507 if (s->link != symtab_section)
1508 continue;
1509 for_each_elem(s, 0, rel, ElfW_Rel) {
1510 switch (ELFW(R_TYPE) (rel->r_info)) {
1511 case R_X86_64_GOT32:
1512 case R_X86_64_GOTPCREL:
1513 case R_X86_64_GOTPCRELX:
1514 case R_X86_64_REX_GOTPCRELX:
1515 case R_X86_64_PLT32:
1516 fill_got_entry(s1, rel);
1517 break;
1523 /* See put_got_entry for a description. This is the second stage
1524 where GOT references to local defined symbols are rewritten. */
1525 static void fill_local_got_entries(TCCState *s1)
1527 ElfW_Rel *rel;
1528 if (!s1->got->reloc)
1529 return;
1530 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1531 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1532 int sym_index = ELFW(R_SYM) (rel->r_info);
1533 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1534 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1535 unsigned offset = attr->got_offset;
1536 if (offset != rel->r_offset - s1->got->sh_addr)
1537 tcc_error_noabort("huh");
1538 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1539 #if SHT_RELX == SHT_RELA
1540 rel->r_addend = sym->st_value;
1541 #else
1542 /* All our REL architectures also happen to be 32bit LE. */
1543 write32le(s1->got->data + offset, sym->st_value);
1544 #endif
1549 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1550 in shared libraries and export non local defined symbols to shared libraries
1551 if -rdynamic switch was given on command line */
1552 static void bind_exe_dynsyms(TCCState *s1)
1554 const char *name;
1555 int sym_index, index;
1556 ElfW(Sym) *sym, *esym;
1557 int type;
1559 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1560 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1561 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1562 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1563 if (sym->st_shndx == SHN_UNDEF) {
1564 name = (char *) symtab_section->link->data + sym->st_name;
1565 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1566 if (sym_index) {
1567 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1568 type = ELFW(ST_TYPE)(esym->st_info);
1569 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1570 /* Indirect functions shall have STT_FUNC type in executable
1571 * dynsym section. Indeed, a dlsym call following a lazy
1572 * resolution would pick the symbol value from the
1573 * executable dynsym entry which would contain the address
1574 * of the function wanted by the caller of dlsym instead of
1575 * the address of the function that would return that
1576 * address */
1577 int dynindex
1578 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1579 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1580 name);
1581 int index = sym - (ElfW(Sym) *) symtab_section->data;
1582 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1583 } else if (type == STT_OBJECT) {
1584 unsigned long offset;
1585 ElfW(Sym) *dynsym;
1586 offset = bss_section->data_offset;
1587 /* XXX: which alignment ? */
1588 offset = (offset + 16 - 1) & -16;
1589 set_elf_sym (s1->symtab, offset, esym->st_size,
1590 esym->st_info, 0, bss_section->sh_num, name);
1591 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1592 esym->st_info, 0, bss_section->sh_num,
1593 name);
1595 /* Ensure R_COPY works for weak symbol aliases */
1596 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1597 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1598 if ((dynsym->st_value == esym->st_value)
1599 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1600 char *dynname = (char *) s1->dynsymtab_section->link->data
1601 + dynsym->st_name;
1602 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1603 dynsym->st_info, 0,
1604 bss_section->sh_num, dynname);
1605 break;
1610 put_elf_reloc(s1->dynsym, bss_section,
1611 offset, R_COPY, index);
1612 offset += esym->st_size;
1613 bss_section->data_offset = offset;
1615 } else {
1616 /* STB_WEAK undefined symbols are accepted */
1617 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1618 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1619 !strcmp(name, "_fp_hw")) {
1620 } else {
1621 tcc_error_noabort("undefined symbol '%s'", name);
1624 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1625 /* if -rdynamic option, then export all non local symbols */
1626 name = (char *) symtab_section->link->data + sym->st_name;
1627 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1628 0, sym->st_shndx, name);
1633 /* Bind symbols of libraries: export all non local symbols of executable that
1634 are referenced by shared libraries. The reason is that the dynamic loader
1635 search symbol first in executable and then in libraries. Therefore a
1636 reference to a symbol already defined by a library can still be resolved by
1637 a symbol in the executable. */
1638 static void bind_libs_dynsyms(TCCState *s1)
1640 const char *name;
1641 int sym_index;
1642 ElfW(Sym) *sym, *esym;
1644 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1645 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1646 sym_index = find_elf_sym(symtab_section, name);
1647 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1648 if (sym_index && sym->st_shndx != SHN_UNDEF
1649 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1650 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1651 sym->st_info, 0, sym->st_shndx, name);
1652 } else if (esym->st_shndx == SHN_UNDEF) {
1653 /* weak symbols can stay undefined */
1654 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1655 tcc_warning("undefined dynamic symbol '%s'", name);
1660 /* Export all non local symbols. This is used by shared libraries so that the
1661 non local symbols they define can resolve a reference in another shared
1662 library or in the executable. Correspondingly, it allows undefined local
1663 symbols to be resolved by other shared libraries or by the executable. */
1664 static void export_global_syms(TCCState *s1)
1666 int dynindex, index;
1667 const char *name;
1668 ElfW(Sym) *sym;
1670 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1671 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1672 name = (char *) symtab_section->link->data + sym->st_name;
1673 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1674 sym->st_info, 0, sym->st_shndx, name);
1675 index = sym - (ElfW(Sym) *) symtab_section->data;
1676 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1680 #endif
1682 /* Allocate strings for section names and decide if an unallocated section
1683 should be output.
1684 NOTE: the strsec section comes last, so its size is also correct ! */
1685 static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1687 int i;
1688 Section *s;
1689 int textrel = 0;
1691 /* Allocate strings for section names */
1692 for(i = 1; i < s1->nb_sections; i++) {
1693 s = s1->sections[i];
1694 /* when generating a DLL, we include relocations but we may
1695 patch them */
1696 #ifndef ELF_OBJ_ONLY
1697 if (file_type == TCC_OUTPUT_DLL &&
1698 s->sh_type == SHT_RELX &&
1699 !(s->sh_flags & SHF_ALLOC) &&
1700 (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
1701 prepare_dynamic_rel(s1, s)) {
1702 if (s1->sections[s->sh_info]->sh_flags & SHF_EXECINSTR)
1703 textrel = 1;
1704 } else
1705 #endif
1706 if ((s1->do_debug && s->sh_type != SHT_RELX) ||
1707 file_type == TCC_OUTPUT_OBJ ||
1708 (s->sh_flags & SHF_ALLOC) ||
1709 i == (s1->nb_sections - 1)) {
1710 /* we output all sections if debug or object file */
1711 s->sh_size = s->data_offset;
1713 if (s->sh_size || (s->sh_flags & SHF_ALLOC))
1714 s->sh_name = put_elf_str(strsec, s->name);
1716 strsec->sh_size = strsec->data_offset;
1717 return textrel;
1720 /* Info to be copied in dynamic section */
1721 struct dyn_inf {
1722 Section *dynamic;
1723 Section *dynstr;
1724 unsigned long data_offset;
1725 addr_t rel_addr;
1726 addr_t rel_size;
1727 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1728 addr_t bss_addr;
1729 addr_t bss_size;
1730 #endif
1733 /* Assign sections to segments and decide how are sections laid out when loaded
1734 in memory. This function also fills corresponding program headers. */
1735 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1736 Section *interp, Section* strsec,
1737 struct dyn_inf *dyninf, int *sec_order)
1739 int i, j, k, file_type, sh_order_index, file_offset;
1740 unsigned long s_align;
1741 long long tmp;
1742 addr_t addr;
1743 ElfW(Phdr) *ph;
1744 Section *s;
1746 file_type = s1->output_type;
1747 sh_order_index = 1;
1748 file_offset = 0;
1749 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1750 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1751 s_align = ELF_PAGE_SIZE;
1752 if (s1->section_align)
1753 s_align = s1->section_align;
1755 if (phnum > 0) {
1756 if (s1->has_text_addr) {
1757 int a_offset, p_offset;
1758 addr = s1->text_addr;
1759 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1760 ELF_PAGE_SIZE */
1761 a_offset = (int) (addr & (s_align - 1));
1762 p_offset = file_offset & (s_align - 1);
1763 if (a_offset < p_offset)
1764 a_offset += s_align;
1765 file_offset += (a_offset - p_offset);
1766 } else {
1767 if (file_type == TCC_OUTPUT_DLL)
1768 addr = 0;
1769 else
1770 addr = ELF_START_ADDR;
1771 /* compute address after headers */
1772 addr += (file_offset & (s_align - 1));
1775 ph = &phdr[0];
1776 /* Leave one program headers for the program interpreter and one for
1777 the program header table itself if needed. These are done later as
1778 they require section layout to be done first. */
1779 if (interp)
1780 ph += 2;
1782 /* dynamic relocation table information, for .dynamic section */
1783 dyninf->rel_addr = dyninf->rel_size = 0;
1784 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1785 dyninf->bss_addr = dyninf->bss_size = 0;
1786 #endif
1788 for(j = 0; j < 2; j++) {
1789 ph->p_type = PT_LOAD;
1790 if (j == 0)
1791 ph->p_flags = PF_R | PF_X;
1792 else
1793 ph->p_flags = PF_R | PF_W;
1794 ph->p_align = s_align;
1796 /* Decide the layout of sections loaded in memory. This must
1797 be done before program headers are filled since they contain
1798 info about the layout. We do the following ordering: interp,
1799 symbol tables, relocations, progbits, nobits */
1800 /* XXX: do faster and simpler sorting */
1801 for(k = 0; k < 5; k++) {
1802 for(i = 1; i < s1->nb_sections; i++) {
1803 s = s1->sections[i];
1804 /* compute if section should be included */
1805 if (j == 0) {
1806 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1807 SHF_ALLOC)
1808 continue;
1809 } else {
1810 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1811 (SHF_ALLOC | SHF_WRITE))
1812 continue;
1814 if (s == interp) {
1815 if (k != 0)
1816 continue;
1817 } else if (s->sh_type == SHT_DYNSYM ||
1818 s->sh_type == SHT_STRTAB ||
1819 s->sh_type == SHT_HASH) {
1820 if (k != 1)
1821 continue;
1822 } else if (s->sh_type == SHT_RELX) {
1823 if (k != 2)
1824 continue;
1825 } else if (s->sh_type == SHT_NOBITS) {
1826 if (k != 4)
1827 continue;
1828 } else {
1829 if (k != 3)
1830 continue;
1832 sec_order[sh_order_index++] = i;
1834 /* section matches: we align it and add its size */
1835 tmp = addr;
1836 addr = (addr + s->sh_addralign - 1) &
1837 ~(s->sh_addralign - 1);
1838 file_offset += (int) ( addr - tmp );
1839 s->sh_offset = file_offset;
1840 s->sh_addr = addr;
1842 /* update program header infos */
1843 if (ph->p_offset == 0) {
1844 ph->p_offset = file_offset;
1845 ph->p_vaddr = addr;
1846 ph->p_paddr = ph->p_vaddr;
1848 /* update dynamic relocation infos */
1849 if (s->sh_type == SHT_RELX) {
1850 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1851 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1852 dyninf->rel_addr = addr;
1853 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1855 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1856 dyninf->bss_addr = addr;
1857 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1859 #else
1860 if (dyninf->rel_size == 0)
1861 dyninf->rel_addr = addr;
1862 dyninf->rel_size += s->sh_size;
1863 #endif
1865 addr += s->sh_size;
1866 if (s->sh_type != SHT_NOBITS)
1867 file_offset += s->sh_size;
1870 if (j == 0) {
1871 /* Make the first PT_LOAD segment include the program
1872 headers itself (and the ELF header as well), it'll
1873 come out with same memory use but will make various
1874 tools like binutils strip work better. */
1875 ph->p_offset &= ~(ph->p_align - 1);
1876 ph->p_vaddr &= ~(ph->p_align - 1);
1877 ph->p_paddr &= ~(ph->p_align - 1);
1879 ph->p_filesz = file_offset - ph->p_offset;
1880 ph->p_memsz = addr - ph->p_vaddr;
1881 ph++;
1882 if (j == 0) {
1883 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1884 /* if in the middle of a page, we duplicate the page in
1885 memory so that one copy is RX and the other is RW */
1886 if ((addr & (s_align - 1)) != 0)
1887 addr += s_align;
1888 } else {
1889 addr = (addr + s_align - 1) & ~(s_align - 1);
1890 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1896 /* all other sections come after */
1897 for(i = 1; i < s1->nb_sections; i++) {
1898 s = s1->sections[i];
1899 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1900 continue;
1901 sec_order[sh_order_index++] = i;
1903 file_offset = (file_offset + s->sh_addralign - 1) &
1904 ~(s->sh_addralign - 1);
1905 s->sh_offset = file_offset;
1906 if (s->sh_type != SHT_NOBITS)
1907 file_offset += s->sh_size;
1910 return file_offset;
1913 #ifndef ELF_OBJ_ONLY
1914 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1915 Section *dynamic)
1917 ElfW(Phdr) *ph;
1919 /* if interpreter, then add corresponding program header */
1920 if (interp) {
1921 ph = &phdr[0];
1923 ph->p_type = PT_PHDR;
1924 ph->p_offset = sizeof(ElfW(Ehdr));
1925 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
1926 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
1927 ph->p_paddr = ph->p_vaddr;
1928 ph->p_flags = PF_R | PF_X;
1929 ph->p_align = 4; /* interp->sh_addralign; */
1930 ph++;
1932 ph->p_type = PT_INTERP;
1933 ph->p_offset = interp->sh_offset;
1934 ph->p_vaddr = interp->sh_addr;
1935 ph->p_paddr = ph->p_vaddr;
1936 ph->p_filesz = interp->sh_size;
1937 ph->p_memsz = interp->sh_size;
1938 ph->p_flags = PF_R;
1939 ph->p_align = interp->sh_addralign;
1942 /* if dynamic section, then add corresponding program header */
1943 if (dynamic) {
1944 ph = &phdr[phnum - 1];
1946 ph->p_type = PT_DYNAMIC;
1947 ph->p_offset = dynamic->sh_offset;
1948 ph->p_vaddr = dynamic->sh_addr;
1949 ph->p_paddr = ph->p_vaddr;
1950 ph->p_filesz = dynamic->sh_size;
1951 ph->p_memsz = dynamic->sh_size;
1952 ph->p_flags = PF_R | PF_W;
1953 ph->p_align = dynamic->sh_addralign;
1957 /* Fill the dynamic section with tags describing the address and size of
1958 sections */
1959 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
1961 Section *dynamic = dyninf->dynamic;
1962 Section *s;
1964 /* put dynamic section entries */
1965 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1966 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
1967 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1968 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
1969 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1970 #if PTR_SIZE == 8
1971 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
1972 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
1973 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
1974 #else
1975 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1976 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
1977 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
1978 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
1979 put_dt(dynamic, DT_PLTREL, DT_REL);
1980 put_dt(dynamic, DT_REL, dyninf->bss_addr);
1981 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
1982 #else
1983 put_dt(dynamic, DT_REL, dyninf->rel_addr);
1984 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
1985 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1986 #endif
1987 #endif
1988 if (versym_section) {
1989 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
1990 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
1991 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
1993 s = find_section_create (s1, ".preinit_array", 0);
1994 if (s && s->data_offset) {
1995 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
1996 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
1998 s = find_section_create (s1, ".init_array", 0);
1999 if (s && s->data_offset) {
2000 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2001 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2003 s = find_section_create (s1, ".fini_array", 0);
2004 if (s && s->data_offset) {
2005 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2006 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2008 s = find_section_create (s1, ".init", 0);
2009 if (s && s->data_offset) {
2010 put_dt(dynamic, DT_INIT, s->sh_addr);
2012 s = find_section_create (s1, ".fini", 0);
2013 if (s && s->data_offset) {
2014 put_dt(dynamic, DT_FINI, s->sh_addr);
2016 if (s1->do_debug)
2017 put_dt(dynamic, DT_DEBUG, 0);
2018 put_dt(dynamic, DT_NULL, 0);
2021 /* Relocate remaining sections and symbols (that is those not related to
2022 dynamic linking) */
2023 static int final_sections_reloc(TCCState *s1)
2025 int i;
2026 Section *s;
2028 relocate_syms(s1, s1->symtab, 0);
2030 if (s1->nb_errors != 0)
2031 return -1;
2033 /* relocate sections */
2034 /* XXX: ignore sections with allocated relocations ? */
2035 for(i = 1; i < s1->nb_sections; i++) {
2036 s = s1->sections[i];
2037 if (s->reloc && (s != s1->got || s1->static_link))
2038 relocate_section(s1, s);
2041 /* relocate relocation entries if the relocation tables are
2042 allocated in the executable */
2043 for(i = 1; i < s1->nb_sections; i++) {
2044 s = s1->sections[i];
2045 if ((s->sh_flags & SHF_ALLOC) &&
2046 s->sh_type == SHT_RELX) {
2047 relocate_rel(s1, s);
2050 return 0;
2052 #endif
2054 /* Create an ELF file on disk.
2055 This function handle ELF specific layout requirements */
2056 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2057 int file_offset, int *sec_order)
2059 int i, shnum, offset, size, file_type;
2060 Section *s;
2061 ElfW(Ehdr) ehdr;
2062 ElfW(Shdr) shdr, *sh;
2063 ElfW(Sym) *sym;
2065 file_type = s1->output_type;
2066 shnum = s1->nb_sections;
2068 memset(&ehdr, 0, sizeof(ehdr));
2070 if (phnum > 0) {
2071 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2072 ehdr.e_phnum = phnum;
2073 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2076 /* align to 4 */
2077 file_offset = (file_offset + 3) & -4;
2079 /* fill header */
2080 ehdr.e_ident[0] = ELFMAG0;
2081 ehdr.e_ident[1] = ELFMAG1;
2082 ehdr.e_ident[2] = ELFMAG2;
2083 ehdr.e_ident[3] = ELFMAG3;
2084 ehdr.e_ident[4] = ELFCLASSW;
2085 ehdr.e_ident[5] = ELFDATA2LSB;
2086 ehdr.e_ident[6] = EV_CURRENT;
2087 #if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
2088 /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
2089 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2090 #endif
2091 #ifdef TCC_TARGET_ARM
2092 #ifdef TCC_ARM_EABI
2093 ehdr.e_ident[EI_OSABI] = 0;
2094 ehdr.e_flags = EF_ARM_EABI_VER4;
2095 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2096 ehdr.e_flags |= EF_ARM_HASENTRY;
2097 if (s1->float_abi == ARM_HARD_FLOAT)
2098 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2099 else
2100 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2101 #else
2102 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2103 #endif
2104 #elif defined TCC_TARGET_RISCV64
2105 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2106 #endif
2107 switch(file_type) {
2108 default:
2109 case TCC_OUTPUT_EXE:
2110 ehdr.e_type = ET_EXEC;
2111 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
2112 break;
2113 case TCC_OUTPUT_DLL:
2114 ehdr.e_type = ET_DYN;
2115 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2116 break;
2117 case TCC_OUTPUT_OBJ:
2118 ehdr.e_type = ET_REL;
2119 break;
2121 ehdr.e_machine = EM_TCC_TARGET;
2122 ehdr.e_version = EV_CURRENT;
2123 ehdr.e_shoff = file_offset;
2124 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2125 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2126 ehdr.e_shnum = shnum;
2127 ehdr.e_shstrndx = shnum - 1;
2129 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2130 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2131 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2133 sort_syms(s1, symtab_section);
2134 if (s1->dynsym)
2135 for_each_elem(s1->dynsym, 0, sym, ElfW(Sym))
2136 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
2137 s1->dynsym->sh_info++;
2138 for(i = 1; i < s1->nb_sections; i++) {
2139 s = s1->sections[sec_order[i]];
2140 if (s->sh_type != SHT_NOBITS) {
2141 while (offset < s->sh_offset) {
2142 fputc(0, f);
2143 offset++;
2145 size = s->sh_size;
2146 if (size)
2147 fwrite(s->data, 1, size, f);
2148 offset += size;
2152 /* output section headers */
2153 while (offset < ehdr.e_shoff) {
2154 fputc(0, f);
2155 offset++;
2158 for(i = 0; i < s1->nb_sections; i++) {
2159 sh = &shdr;
2160 memset(sh, 0, sizeof(ElfW(Shdr)));
2161 s = s1->sections[i];
2162 if (s) {
2163 sh->sh_name = s->sh_name;
2164 sh->sh_type = s->sh_type;
2165 sh->sh_flags = s->sh_flags;
2166 sh->sh_entsize = s->sh_entsize;
2167 sh->sh_info = s->sh_info;
2168 if (s->link)
2169 sh->sh_link = s->link->sh_num;
2170 sh->sh_addralign = s->sh_addralign;
2171 sh->sh_addr = s->sh_addr;
2172 sh->sh_offset = s->sh_offset;
2173 sh->sh_size = s->sh_size;
2175 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2179 /* Write an elf, coff or "binary" file */
2180 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2181 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2183 int fd, mode, file_type;
2184 FILE *f;
2186 file_type = s1->output_type;
2187 if (file_type == TCC_OUTPUT_OBJ)
2188 mode = 0666;
2189 else
2190 mode = 0777;
2191 unlink(filename);
2192 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2193 if (fd < 0) {
2194 tcc_error_noabort("could not write '%s'", filename);
2195 return -1;
2197 f = fdopen(fd, "wb");
2198 if (s1->verbose)
2199 printf("<- %s\n", filename);
2201 #ifdef TCC_TARGET_COFF
2202 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2203 tcc_output_coff(s1, f);
2204 else
2205 #endif
2206 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2207 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2208 else
2209 tcc_output_binary(s1, f, sec_order);
2210 fclose(f);
2212 return 0;
2215 #ifndef ELF_OBJ_ONLY
2216 /* Sort section headers by assigned sh_addr, remove sections
2217 that we aren't going to output. */
2218 static void tidy_section_headers(TCCState *s1, int *sec_order)
2220 int i, nnew, l, *backmap;
2221 Section **snew, *s;
2222 ElfW(Sym) *sym;
2224 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2225 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2226 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2227 s = s1->sections[sec_order[i]];
2228 if (!i || s->sh_name) {
2229 backmap[sec_order[i]] = nnew;
2230 snew[nnew] = s;
2231 ++nnew;
2232 } else {
2233 backmap[sec_order[i]] = 0;
2234 snew[--l] = s;
2237 for (i = 0; i < nnew; i++) {
2238 s = snew[i];
2239 if (s) {
2240 s->sh_num = i;
2241 if (s->sh_type == SHT_RELX)
2242 s->sh_info = backmap[s->sh_info];
2246 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2247 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2248 sym->st_shndx = backmap[sym->st_shndx];
2249 if( !s1->static_link ) {
2250 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2251 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2252 sym->st_shndx = backmap[sym->st_shndx];
2254 for (i = 0; i < s1->nb_sections; i++)
2255 sec_order[i] = i;
2256 tcc_free(s1->sections);
2257 s1->sections = snew;
2258 s1->nb_sections = nnew;
2259 tcc_free(backmap);
2261 #endif
2263 /* Output an elf, coff or binary file */
2264 /* XXX: suppress unneeded sections */
2265 static int elf_output_file(TCCState *s1, const char *filename)
2267 int ret, phnum, shnum, file_type, file_offset, *sec_order;
2268 struct dyn_inf dyninf = {0};
2269 ElfW(Phdr) *phdr;
2270 Section *strsec, *interp, *dynamic, *dynstr;
2272 file_type = s1->output_type;
2273 s1->nb_errors = 0;
2274 ret = -1;
2275 phdr = NULL;
2276 sec_order = NULL;
2277 interp = dynamic = dynstr = NULL; /* avoid warning */
2279 #ifndef ELF_OBJ_ONLY
2280 if (file_type != TCC_OUTPUT_OBJ) {
2281 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2282 tcc_add_runtime(s1);
2283 resolve_common_syms(s1);
2285 if (!s1->static_link) {
2286 if (file_type == TCC_OUTPUT_EXE) {
2287 char *ptr;
2288 /* allow override the dynamic loader */
2289 const char *elfint = getenv("LD_SO");
2290 if (elfint == NULL)
2291 elfint = DEFAULT_ELFINTERP(s1);
2292 /* add interpreter section only if executable */
2293 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2294 interp->sh_addralign = 1;
2295 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2296 strcpy(ptr, elfint);
2299 /* add dynamic symbol table */
2300 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2301 ".dynstr",
2302 ".hash", SHF_ALLOC);
2303 dynstr = s1->dynsym->link;
2304 /* add dynamic section */
2305 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2306 SHF_ALLOC | SHF_WRITE);
2307 dynamic->link = dynstr;
2308 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2310 build_got(s1);
2312 if (file_type == TCC_OUTPUT_EXE) {
2313 bind_exe_dynsyms(s1);
2314 if (s1->nb_errors)
2315 goto the_end;
2316 bind_libs_dynsyms(s1);
2317 } else {
2318 /* shared library case: simply export all global symbols */
2319 export_global_syms(s1);
2322 build_got_entries(s1);
2323 version_add (s1);
2325 #endif
2327 /* we add a section for symbols */
2328 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2329 put_elf_str(strsec, "");
2331 /* Allocate strings for section names */
2332 ret = alloc_sec_names(s1, file_type, strsec);
2334 #ifndef ELF_OBJ_ONLY
2335 if (dynamic) {
2336 int i;
2337 /* add a list of needed dlls */
2338 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2339 DLLReference *dllref = s1->loaded_dlls[i];
2340 if (dllref->level == 0)
2341 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2344 if (s1->rpath)
2345 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2346 put_elf_str(dynstr, s1->rpath));
2348 if (file_type == TCC_OUTPUT_DLL) {
2349 if (s1->soname)
2350 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2351 /* XXX: currently, since we do not handle PIC code, we
2352 must relocate the readonly segments */
2353 if (ret)
2354 put_dt(dynamic, DT_TEXTREL, 0);
2357 if (s1->symbolic)
2358 put_dt(dynamic, DT_SYMBOLIC, 0);
2360 dyninf.dynamic = dynamic;
2361 dyninf.dynstr = dynstr;
2362 /* remember offset and reserve space for 2nd call below */
2363 dyninf.data_offset = dynamic->data_offset;
2364 fill_dynamic(s1, &dyninf);
2365 dynamic->sh_size = dynamic->data_offset;
2366 dynstr->sh_size = dynstr->data_offset;
2368 #endif
2370 /* compute number of program headers */
2371 if (file_type == TCC_OUTPUT_OBJ)
2372 phnum = 0;
2373 else if (file_type == TCC_OUTPUT_DLL)
2374 phnum = 3;
2375 else if (s1->static_link)
2376 phnum = 2;
2377 else
2378 phnum = 5;
2380 /* allocate program segment headers */
2381 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2383 /* compute number of sections */
2384 shnum = s1->nb_sections;
2386 /* this array is used to reorder sections in the output file */
2387 sec_order = tcc_malloc(sizeof(int) * shnum);
2388 sec_order[0] = 0;
2390 /* compute section to program header mapping */
2391 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2392 sec_order);
2394 #ifndef ELF_OBJ_ONLY
2395 /* Fill remaining program header and finalize relocation related to dynamic
2396 linking. */
2397 if (file_type != TCC_OUTPUT_OBJ) {
2398 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2399 if (dynamic) {
2400 ElfW(Sym) *sym;
2401 dynamic->data_offset = dyninf.data_offset;
2402 fill_dynamic(s1, &dyninf);
2404 /* put in GOT the dynamic section address and relocate PLT */
2405 write32le(s1->got->data, dynamic->sh_addr);
2406 if (file_type == TCC_OUTPUT_EXE
2407 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2408 relocate_plt(s1);
2410 /* relocate symbols in .dynsym now that final addresses are known */
2411 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2412 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2413 /* do symbol relocation */
2414 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2419 /* if building executable or DLL, then relocate each section
2420 except the GOT which is already relocated */
2421 ret = final_sections_reloc(s1);
2422 if (ret)
2423 goto the_end;
2424 tidy_section_headers(s1, sec_order);
2426 /* Perform relocation to GOT or PLT entries */
2427 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2428 fill_got(s1);
2429 else if (s1->got)
2430 fill_local_got_entries(s1);
2432 #endif
2434 /* Create the ELF file with name 'filename' */
2435 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2436 s1->nb_sections = shnum;
2437 goto the_end;
2438 the_end:
2439 tcc_free(sec_order);
2440 tcc_free(phdr);
2441 return ret;
2444 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2446 int ret;
2447 #ifdef TCC_TARGET_PE
2448 if (s->output_type != TCC_OUTPUT_OBJ) {
2449 ret = pe_output_file(s, filename);
2450 } else
2451 #endif
2452 ret = elf_output_file(s, filename);
2453 return ret;
2456 ssize_t full_read(int fd, void *buf, size_t count) {
2457 char *cbuf = buf;
2458 size_t rnum = 0;
2459 while (1) {
2460 ssize_t num = read(fd, cbuf, count-rnum);
2461 if (num < 0) return num;
2462 if (num == 0) return rnum;
2463 rnum += num;
2464 cbuf += num;
2468 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2470 void *data;
2472 data = tcc_malloc(size);
2473 lseek(fd, file_offset, SEEK_SET);
2474 full_read(fd, data, size);
2475 return data;
2478 typedef struct SectionMergeInfo {
2479 Section *s; /* corresponding existing section */
2480 unsigned long offset; /* offset of the new section in the existing section */
2481 uint8_t new_section; /* true if section 's' was added */
2482 uint8_t link_once; /* true if link once section */
2483 } SectionMergeInfo;
2485 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2487 int size = full_read(fd, h, sizeof *h);
2488 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2489 if (h->e_type == ET_REL)
2490 return AFF_BINTYPE_REL;
2491 if (h->e_type == ET_DYN)
2492 return AFF_BINTYPE_DYN;
2493 } else if (size >= 8) {
2494 if (0 == memcmp(h, ARMAG, 8))
2495 return AFF_BINTYPE_AR;
2496 #ifdef TCC_TARGET_COFF
2497 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2498 return AFF_BINTYPE_C67;
2499 #endif
2501 return 0;
2504 /* load an object file and merge it with current files */
2505 /* XXX: handle correctly stab (debug) info */
2506 ST_FUNC int tcc_load_object_file(TCCState *s1,
2507 int fd, unsigned long file_offset)
2509 ElfW(Ehdr) ehdr;
2510 ElfW(Shdr) *shdr, *sh;
2511 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2512 char *strsec, *strtab;
2513 int stab_index, stabstr_index;
2514 int *old_to_new_syms;
2515 char *sh_name, *name;
2516 SectionMergeInfo *sm_table, *sm;
2517 ElfW(Sym) *sym, *symtab;
2518 ElfW_Rel *rel;
2519 Section *s;
2521 lseek(fd, file_offset, SEEK_SET);
2522 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2523 goto fail1;
2524 /* test CPU specific stuff */
2525 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2526 ehdr.e_machine != EM_TCC_TARGET) {
2527 fail1:
2528 tcc_error_noabort("invalid object file");
2529 return -1;
2531 /* read sections */
2532 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2533 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2534 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2536 /* load section names */
2537 sh = &shdr[ehdr.e_shstrndx];
2538 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2540 /* load symtab and strtab */
2541 old_to_new_syms = NULL;
2542 symtab = NULL;
2543 strtab = NULL;
2544 nb_syms = 0;
2545 seencompressed = 0;
2546 stab_index = stabstr_index = 0;
2548 for(i = 1; i < ehdr.e_shnum; i++) {
2549 sh = &shdr[i];
2550 if (sh->sh_type == SHT_SYMTAB) {
2551 if (symtab) {
2552 tcc_error_noabort("object must contain only one symtab");
2553 fail:
2554 ret = -1;
2555 goto the_end;
2557 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2558 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2559 sm_table[i].s = symtab_section;
2561 /* now load strtab */
2562 sh = &shdr[sh->sh_link];
2563 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2565 if (sh->sh_flags & SHF_COMPRESSED)
2566 seencompressed = 1;
2569 /* now examine each section and try to merge its content with the
2570 ones in memory */
2571 for(i = 1; i < ehdr.e_shnum; i++) {
2572 /* no need to examine section name strtab */
2573 if (i == ehdr.e_shstrndx)
2574 continue;
2575 sh = &shdr[i];
2576 if (sh->sh_type == SHT_RELX)
2577 sh = &shdr[sh->sh_info];
2578 /* ignore sections types we do not handle (plus relocs to those) */
2579 if (sh->sh_type != SHT_PROGBITS &&
2580 #ifdef TCC_ARM_EABI
2581 sh->sh_type != SHT_ARM_EXIDX &&
2582 #endif
2583 sh->sh_type != SHT_NOBITS &&
2584 sh->sh_type != SHT_PREINIT_ARRAY &&
2585 sh->sh_type != SHT_INIT_ARRAY &&
2586 sh->sh_type != SHT_FINI_ARRAY &&
2587 strcmp(strsec + sh->sh_name, ".stabstr")
2589 continue;
2590 if (seencompressed
2591 && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
2592 continue;
2594 sh = &shdr[i];
2595 sh_name = strsec + sh->sh_name;
2596 if (sh->sh_addralign < 1)
2597 sh->sh_addralign = 1;
2598 /* find corresponding section, if any */
2599 for(j = 1; j < s1->nb_sections;j++) {
2600 s = s1->sections[j];
2601 if (!strcmp(s->name, sh_name)) {
2602 if (!strncmp(sh_name, ".gnu.linkonce",
2603 sizeof(".gnu.linkonce") - 1)) {
2604 /* if a 'linkonce' section is already present, we
2605 do not add it again. It is a little tricky as
2606 symbols can still be defined in
2607 it. */
2608 sm_table[i].link_once = 1;
2609 goto next;
2611 if (stab_section) {
2612 if (s == stab_section)
2613 stab_index = i;
2614 if (s == stab_section->link)
2615 stabstr_index = i;
2617 goto found;
2620 /* not found: create new section */
2621 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2622 /* take as much info as possible from the section. sh_link and
2623 sh_info will be updated later */
2624 s->sh_addralign = sh->sh_addralign;
2625 s->sh_entsize = sh->sh_entsize;
2626 sm_table[i].new_section = 1;
2627 found:
2628 if (sh->sh_type != s->sh_type) {
2629 tcc_error_noabort("invalid section type");
2630 goto fail;
2632 /* align start of section */
2633 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
2634 if (sh->sh_addralign > s->sh_addralign)
2635 s->sh_addralign = sh->sh_addralign;
2636 sm_table[i].offset = s->data_offset;
2637 sm_table[i].s = s;
2638 /* concatenate sections */
2639 size = sh->sh_size;
2640 if (sh->sh_type != SHT_NOBITS) {
2641 unsigned char *ptr;
2642 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2643 ptr = section_ptr_add(s, size);
2644 full_read(fd, ptr, size);
2645 } else {
2646 s->data_offset += size;
2648 next: ;
2651 /* gr relocate stab strings */
2652 if (stab_index && stabstr_index) {
2653 Stab_Sym *a, *b;
2654 unsigned o;
2655 s = sm_table[stab_index].s;
2656 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2657 b = (Stab_Sym *)(s->data + s->data_offset);
2658 o = sm_table[stabstr_index].offset;
2659 while (a < b) {
2660 if (a->n_strx)
2661 a->n_strx += o;
2662 a++;
2666 /* second short pass to update sh_link and sh_info fields of new
2667 sections */
2668 for(i = 1; i < ehdr.e_shnum; i++) {
2669 s = sm_table[i].s;
2670 if (!s || !sm_table[i].new_section)
2671 continue;
2672 sh = &shdr[i];
2673 if (sh->sh_link > 0)
2674 s->link = sm_table[sh->sh_link].s;
2675 if (sh->sh_type == SHT_RELX) {
2676 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2677 /* update backward link */
2678 s1->sections[s->sh_info]->reloc = s;
2682 /* resolve symbols */
2683 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2685 sym = symtab + 1;
2686 for(i = 1; i < nb_syms; i++, sym++) {
2687 if (sym->st_shndx != SHN_UNDEF &&
2688 sym->st_shndx < SHN_LORESERVE) {
2689 sm = &sm_table[sym->st_shndx];
2690 if (sm->link_once) {
2691 /* if a symbol is in a link once section, we use the
2692 already defined symbol. It is very important to get
2693 correct relocations */
2694 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2695 name = strtab + sym->st_name;
2696 sym_index = find_elf_sym(symtab_section, name);
2697 if (sym_index)
2698 old_to_new_syms[i] = sym_index;
2700 continue;
2702 /* if no corresponding section added, no need to add symbol */
2703 if (!sm->s)
2704 continue;
2705 /* convert section number */
2706 sym->st_shndx = sm->s->sh_num;
2707 /* offset value */
2708 sym->st_value += sm->offset;
2710 /* add symbol */
2711 name = strtab + sym->st_name;
2712 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2713 sym->st_info, sym->st_other,
2714 sym->st_shndx, name);
2715 old_to_new_syms[i] = sym_index;
2718 /* third pass to patch relocation entries */
2719 for(i = 1; i < ehdr.e_shnum; i++) {
2720 s = sm_table[i].s;
2721 if (!s)
2722 continue;
2723 sh = &shdr[i];
2724 offset = sm_table[i].offset;
2725 switch(s->sh_type) {
2726 case SHT_RELX:
2727 /* take relocation offset information */
2728 offseti = sm_table[sh->sh_info].offset;
2729 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2730 int type;
2731 unsigned sym_index;
2732 /* convert symbol index */
2733 type = ELFW(R_TYPE)(rel->r_info);
2734 sym_index = ELFW(R_SYM)(rel->r_info);
2735 /* NOTE: only one symtab assumed */
2736 if (sym_index >= nb_syms)
2737 goto invalid_reloc;
2738 sym_index = old_to_new_syms[sym_index];
2739 /* ignore link_once in rel section. */
2740 if (!sym_index && !sm_table[sh->sh_info].link_once
2741 #ifdef TCC_TARGET_ARM
2742 && type != R_ARM_V4BX
2743 #elif defined TCC_TARGET_RISCV64
2744 && type != R_RISCV_ALIGN
2745 && type != R_RISCV_RELAX
2746 #endif
2748 invalid_reloc:
2749 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2750 i, strsec + sh->sh_name, rel->r_offset);
2751 goto fail;
2753 rel->r_info = ELFW(R_INFO)(sym_index, type);
2754 /* offset the relocation offset */
2755 rel->r_offset += offseti;
2756 #ifdef TCC_TARGET_ARM
2757 /* Jumps and branches from a Thumb code to a PLT entry need
2758 special handling since PLT entries are ARM code.
2759 Unconditional bl instructions referencing PLT entries are
2760 handled by converting these instructions into blx
2761 instructions. Other case of instructions referencing a PLT
2762 entry require to add a Thumb stub before the PLT entry to
2763 switch to ARM mode. We set bit plt_thumb_stub of the
2764 attribute of a symbol to indicate such a case. */
2765 if (type == R_ARM_THM_JUMP24)
2766 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2767 #endif
2769 break;
2770 default:
2771 break;
2775 ret = 0;
2776 the_end:
2777 tcc_free(symtab);
2778 tcc_free(strtab);
2779 tcc_free(old_to_new_syms);
2780 tcc_free(sm_table);
2781 tcc_free(strsec);
2782 tcc_free(shdr);
2783 return ret;
2786 typedef struct ArchiveHeader {
2787 char ar_name[16]; /* name of this member */
2788 char ar_date[12]; /* file mtime */
2789 char ar_uid[6]; /* owner uid; printed as decimal */
2790 char ar_gid[6]; /* owner gid; printed as decimal */
2791 char ar_mode[8]; /* file mode, printed as octal */
2792 char ar_size[10]; /* file size, printed as decimal */
2793 char ar_fmag[2]; /* should contain ARFMAG */
2794 } ArchiveHeader;
2796 #define ARFMAG "`\n"
2798 static unsigned long long get_be(const uint8_t *b, int n)
2800 unsigned long long ret = 0;
2801 while (n)
2802 ret = (ret << 8) | *b++, --n;
2803 return ret;
2806 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
2808 char *p, *e;
2809 int len;
2810 lseek(fd, offset, SEEK_SET);
2811 len = full_read(fd, hdr, sizeof(ArchiveHeader));
2812 if (len != sizeof(ArchiveHeader))
2813 return len ? -1 : 0;
2814 p = hdr->ar_name;
2815 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
2816 --e;
2817 *e = '\0';
2818 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
2819 return len;
2822 /* load only the objects which resolve undefined symbols */
2823 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2825 int i, bound, nsyms, sym_index, len, ret = -1;
2826 unsigned long long off;
2827 uint8_t *data;
2828 const char *ar_names, *p;
2829 const uint8_t *ar_index;
2830 ElfW(Sym) *sym;
2831 ArchiveHeader hdr;
2833 data = tcc_malloc(size);
2834 if (full_read(fd, data, size) != size)
2835 goto the_end;
2836 nsyms = get_be(data, entrysize);
2837 ar_index = data + entrysize;
2838 ar_names = (char *) ar_index + nsyms * entrysize;
2840 do {
2841 bound = 0;
2842 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2843 Section *s = symtab_section;
2844 sym_index = find_elf_sym(s, p);
2845 #ifdef TCC_TARGET_PE /* windows DLL's don't have UNDEF syms */
2846 if (sym_index == 0) {
2847 s = s1->dynsymtab_section;
2848 sym_index = find_elf_sym(s, p);
2850 #endif
2851 if (!sym_index)
2852 continue;
2853 sym = &((ElfW(Sym) *)s->data)[sym_index];
2854 if(sym->st_shndx != SHN_UNDEF)
2855 continue;
2856 off = get_be(ar_index + i * entrysize, entrysize);
2857 len = read_ar_header(fd, off, &hdr);
2858 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
2859 tcc_error_noabort("invalid archive");
2860 goto the_end;
2862 off += len;
2863 if (s1->verbose == 2)
2864 printf(" -> %s\n", hdr.ar_name);
2865 if (tcc_load_object_file(s1, fd, off) < 0)
2866 goto the_end;
2867 ++bound;
2869 } while(bound);
2870 ret = 0;
2871 the_end:
2872 tcc_free(data);
2873 return ret;
2876 /* load a '.a' file */
2877 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
2879 ArchiveHeader hdr;
2880 /* char magic[8]; */
2881 int size, len;
2882 unsigned long file_offset;
2883 ElfW(Ehdr) ehdr;
2885 /* skip magic which was already checked */
2886 /* full_read(fd, magic, sizeof(magic)); */
2887 file_offset = sizeof ARMAG - 1;
2889 for(;;) {
2890 len = read_ar_header(fd, file_offset, &hdr);
2891 if (len == 0)
2892 return 0;
2893 if (len < 0) {
2894 tcc_error_noabort("invalid archive");
2895 return -1;
2897 file_offset += len;
2898 size = strtol(hdr.ar_size, NULL, 0);
2899 /* align to even */
2900 size = (size + 1) & ~1;
2901 if (alacarte) {
2902 /* coff symbol table : we handle it */
2903 if (!strcmp(hdr.ar_name, "/"))
2904 return tcc_load_alacarte(s1, fd, size, 4);
2905 if (!strcmp(hdr.ar_name, "/SYM64/"))
2906 return tcc_load_alacarte(s1, fd, size, 8);
2907 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2908 if (s1->verbose == 2)
2909 printf(" -> %s\n", hdr.ar_name);
2910 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2911 return -1;
2913 file_offset += size;
2917 #ifndef ELF_OBJ_ONLY
2918 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
2919 LV, maybe create a new entry for (LIB,VERSION). */
2920 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
2922 while (i >= *n) {
2923 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
2924 (*lv)[(*n)++] = -1;
2926 if ((*lv)[i] == -1) {
2927 int v, prev_same_lib = -1;
2928 for (v = 0; v < nb_sym_versions; v++) {
2929 if (strcmp(sym_versions[v].lib, lib))
2930 continue;
2931 prev_same_lib = v;
2932 if (!strcmp(sym_versions[v].version, version))
2933 break;
2935 if (v == nb_sym_versions) {
2936 sym_versions = tcc_realloc (sym_versions,
2937 (v + 1) * sizeof(*sym_versions));
2938 sym_versions[v].lib = tcc_strdup(lib);
2939 sym_versions[v].version = tcc_strdup(version);
2940 sym_versions[v].out_index = 0;
2941 sym_versions[v].prev_same_lib = prev_same_lib;
2942 nb_sym_versions++;
2944 (*lv)[i] = v;
2948 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
2949 VERNDX. */
2950 static void
2951 set_sym_version(TCCState *s1, int sym_index, int verndx)
2953 if (sym_index >= nb_sym_to_version) {
2954 int newelems = sym_index ? sym_index * 2 : 1;
2955 sym_to_version = tcc_realloc(sym_to_version,
2956 newelems * sizeof(*sym_to_version));
2957 memset(sym_to_version + nb_sym_to_version, -1,
2958 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
2959 nb_sym_to_version = newelems;
2961 if (sym_to_version[sym_index] < 0)
2962 sym_to_version[sym_index] = verndx;
2965 struct versym_info {
2966 int nb_versyms;
2967 ElfW(Verdef) *verdef;
2968 ElfW(Verneed) *verneed;
2969 ElfW(Half) *versym;
2970 int nb_local_ver, *local_ver;
2974 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
2976 char *lib, *version;
2977 uint32_t next;
2978 int i;
2980 #define DEBUG_VERSION 0
2982 if (v->versym && v->verdef) {
2983 ElfW(Verdef) *vdef = v->verdef;
2984 lib = NULL;
2985 do {
2986 ElfW(Verdaux) *verdaux =
2987 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
2989 #if DEBUG_VERSION
2990 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
2991 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
2992 vdef->vd_hash);
2993 #endif
2994 if (vdef->vd_cnt) {
2995 version = dynstr + verdaux->vda_name;
2997 if (lib == NULL)
2998 lib = version;
2999 else
3000 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3001 lib, version);
3002 #if DEBUG_VERSION
3003 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3004 #endif
3006 next = vdef->vd_next;
3007 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3008 } while (next);
3010 if (v->versym && v->verneed) {
3011 ElfW(Verneed) *vneed = v->verneed;
3012 do {
3013 ElfW(Vernaux) *vernaux =
3014 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3016 lib = dynstr + vneed->vn_file;
3017 #if DEBUG_VERSION
3018 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3019 #endif
3020 for (i = 0; i < vneed->vn_cnt; i++) {
3021 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3022 version = dynstr + vernaux->vna_name;
3023 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3024 lib, version);
3025 #if DEBUG_VERSION
3026 printf (" vernaux(%u): %u %u %s\n",
3027 vernaux->vna_other, vernaux->vna_hash,
3028 vernaux->vna_flags, version);
3029 #endif
3031 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3033 next = vneed->vn_next;
3034 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3035 } while (next);
3038 #if DEBUG_VERSION
3039 for (i = 0; i < v->nb_local_ver; i++) {
3040 if (v->local_ver[i] > 0) {
3041 printf ("%d: lib: %s, version %s\n",
3042 i, sym_versions[v->local_ver[i]].lib,
3043 sym_versions[v->local_ver[i]].version);
3046 #endif
3049 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3050 is referenced by the user (so it should be added as DT_NEEDED in
3051 the generated ELF file) */
3052 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3054 ElfW(Ehdr) ehdr;
3055 ElfW(Shdr) *shdr, *sh, *sh1;
3056 int i, j, nb_syms, nb_dts, sym_bind, ret;
3057 ElfW(Sym) *sym, *dynsym;
3058 ElfW(Dyn) *dt, *dynamic;
3060 char *dynstr;
3061 int sym_index;
3062 const char *name, *soname;
3063 DLLReference *dllref;
3064 struct versym_info v;
3066 full_read(fd, &ehdr, sizeof(ehdr));
3068 /* test CPU specific stuff */
3069 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3070 ehdr.e_machine != EM_TCC_TARGET) {
3071 tcc_error_noabort("bad architecture");
3072 return -1;
3075 /* read sections */
3076 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3078 /* load dynamic section and dynamic symbols */
3079 nb_syms = 0;
3080 nb_dts = 0;
3081 dynamic = NULL;
3082 dynsym = NULL; /* avoid warning */
3083 dynstr = NULL; /* avoid warning */
3084 memset(&v, 0, sizeof v);
3086 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3087 switch(sh->sh_type) {
3088 case SHT_DYNAMIC:
3089 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3090 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3091 break;
3092 case SHT_DYNSYM:
3093 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3094 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3095 sh1 = &shdr[sh->sh_link];
3096 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3097 break;
3098 case SHT_GNU_verdef:
3099 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3100 break;
3101 case SHT_GNU_verneed:
3102 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3103 break;
3104 case SHT_GNU_versym:
3105 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3106 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3107 break;
3108 default:
3109 break;
3113 /* compute the real library name */
3114 soname = tcc_basename(filename);
3116 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3117 if (dt->d_tag == DT_SONAME) {
3118 soname = dynstr + dt->d_un.d_val;
3122 /* if the dll is already loaded, do not load it */
3123 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3124 dllref = s1->loaded_dlls[i];
3125 if (!strcmp(soname, dllref->name)) {
3126 /* but update level if needed */
3127 if (level < dllref->level)
3128 dllref->level = level;
3129 ret = 0;
3130 goto the_end;
3134 if (v.nb_versyms != nb_syms)
3135 tcc_free (v.versym), v.versym = NULL;
3136 else
3137 store_version(s1, &v, dynstr);
3139 /* add the dll and its level */
3140 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
3141 dllref->level = level;
3142 strcpy(dllref->name, soname);
3143 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
3145 /* add dynamic symbols in dynsym_section */
3146 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3147 sym_bind = ELFW(ST_BIND)(sym->st_info);
3148 if (sym_bind == STB_LOCAL)
3149 continue;
3150 name = dynstr + sym->st_name;
3151 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3152 sym->st_info, sym->st_other, sym->st_shndx, name);
3153 if (v.versym) {
3154 ElfW(Half) vsym = v.versym[i];
3155 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3156 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3160 /* load all referenced DLLs */
3161 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3162 switch(dt->d_tag) {
3163 case DT_NEEDED:
3164 name = dynstr + dt->d_un.d_val;
3165 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3166 dllref = s1->loaded_dlls[j];
3167 if (!strcmp(name, dllref->name))
3168 goto already_loaded;
3170 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3171 tcc_error_noabort("referenced dll '%s' not found", name);
3172 ret = -1;
3173 goto the_end;
3175 already_loaded:
3176 break;
3179 ret = 0;
3180 the_end:
3181 tcc_free(dynstr);
3182 tcc_free(dynsym);
3183 tcc_free(dynamic);
3184 tcc_free(shdr);
3185 tcc_free(v.local_ver);
3186 tcc_free(v.verdef);
3187 tcc_free(v.verneed);
3188 tcc_free(v.versym);
3189 return ret;
3192 #define LD_TOK_NAME 256
3193 #define LD_TOK_EOF (-1)
3195 static int ld_inp(TCCState *s1)
3197 char b;
3198 if (s1->cc != -1) {
3199 int c = s1->cc;
3200 s1->cc = -1;
3201 return c;
3203 if (1 == read(s1->fd, &b, 1))
3204 return b;
3205 return CH_EOF;
3208 /* return next ld script token */
3209 static int ld_next(TCCState *s1, char *name, int name_size)
3211 int c, d, ch;
3212 char *q;
3214 redo:
3215 ch = ld_inp(s1);
3216 switch(ch) {
3217 case ' ':
3218 case '\t':
3219 case '\f':
3220 case '\v':
3221 case '\r':
3222 case '\n':
3223 goto redo;
3224 case '/':
3225 ch = ld_inp(s1);
3226 if (ch == '*') { /* comment */
3227 for (d = 0;; d = ch) {
3228 ch = ld_inp(s1);
3229 if (ch == CH_EOF || (ch == '/' && d == '*'))
3230 break;
3232 goto redo;
3233 } else {
3234 q = name;
3235 *q++ = '/';
3236 goto parse_name;
3238 break;
3239 case '\\':
3240 /* case 'a' ... 'z': */
3241 case 'a':
3242 case 'b':
3243 case 'c':
3244 case 'd':
3245 case 'e':
3246 case 'f':
3247 case 'g':
3248 case 'h':
3249 case 'i':
3250 case 'j':
3251 case 'k':
3252 case 'l':
3253 case 'm':
3254 case 'n':
3255 case 'o':
3256 case 'p':
3257 case 'q':
3258 case 'r':
3259 case 's':
3260 case 't':
3261 case 'u':
3262 case 'v':
3263 case 'w':
3264 case 'x':
3265 case 'y':
3266 case 'z':
3267 /* case 'A' ... 'z': */
3268 case 'A':
3269 case 'B':
3270 case 'C':
3271 case 'D':
3272 case 'E':
3273 case 'F':
3274 case 'G':
3275 case 'H':
3276 case 'I':
3277 case 'J':
3278 case 'K':
3279 case 'L':
3280 case 'M':
3281 case 'N':
3282 case 'O':
3283 case 'P':
3284 case 'Q':
3285 case 'R':
3286 case 'S':
3287 case 'T':
3288 case 'U':
3289 case 'V':
3290 case 'W':
3291 case 'X':
3292 case 'Y':
3293 case 'Z':
3294 case '_':
3295 case '.':
3296 case '$':
3297 case '~':
3298 q = name;
3299 parse_name:
3300 for(;;) {
3301 if (!((ch >= 'a' && ch <= 'z') ||
3302 (ch >= 'A' && ch <= 'Z') ||
3303 (ch >= '0' && ch <= '9') ||
3304 strchr("/.-_+=$:\\,~", ch)))
3305 break;
3306 if ((q - name) < name_size - 1) {
3307 *q++ = ch;
3309 ch = ld_inp(s1);
3311 s1->cc = ch;
3312 *q = '\0';
3313 c = LD_TOK_NAME;
3314 break;
3315 case CH_EOF:
3316 c = LD_TOK_EOF;
3317 break;
3318 default:
3319 c = ch;
3320 break;
3322 return c;
3325 static int ld_add_file(TCCState *s1, const char filename[])
3327 if (filename[0] == '/') {
3328 if (CONFIG_SYSROOT[0] == '\0'
3329 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3330 return 0;
3331 filename = tcc_basename(filename);
3333 return tcc_add_dll(s1, filename, 0);
3336 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3338 char filename[1024], libname[1024];
3339 int t, group, nblibs = 0, ret = 0;
3340 char **libs = NULL;
3342 group = !strcmp(cmd, "GROUP");
3343 if (!as_needed)
3344 s1->new_undef_sym = 0;
3345 t = ld_next(s1, filename, sizeof(filename));
3346 if (t != '(') {
3347 tcc_error_noabort("( expected");
3348 ret = -1;
3349 goto lib_parse_error;
3351 t = ld_next(s1, filename, sizeof(filename));
3352 for(;;) {
3353 libname[0] = '\0';
3354 if (t == LD_TOK_EOF) {
3355 tcc_error_noabort("unexpected end of file");
3356 ret = -1;
3357 goto lib_parse_error;
3358 } else if (t == ')') {
3359 break;
3360 } else if (t == '-') {
3361 t = ld_next(s1, filename, sizeof(filename));
3362 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3363 tcc_error_noabort("library name expected");
3364 ret = -1;
3365 goto lib_parse_error;
3367 pstrcpy(libname, sizeof libname, &filename[1]);
3368 if (s1->static_link) {
3369 snprintf(filename, sizeof filename, "lib%s.a", libname);
3370 } else {
3371 snprintf(filename, sizeof filename, "lib%s.so", libname);
3373 } else if (t != LD_TOK_NAME) {
3374 tcc_error_noabort("filename expected");
3375 ret = -1;
3376 goto lib_parse_error;
3378 if (!strcmp(filename, "AS_NEEDED")) {
3379 ret = ld_add_file_list(s1, cmd, 1);
3380 if (ret)
3381 goto lib_parse_error;
3382 } else {
3383 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3384 if (!as_needed) {
3385 ret = ld_add_file(s1, filename);
3386 if (ret)
3387 goto lib_parse_error;
3388 if (group) {
3389 /* Add the filename *and* the libname to avoid future conversions */
3390 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3391 if (libname[0] != '\0')
3392 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3396 t = ld_next(s1, filename, sizeof(filename));
3397 if (t == ',') {
3398 t = ld_next(s1, filename, sizeof(filename));
3401 if (group && !as_needed) {
3402 while (s1->new_undef_sym) {
3403 int i;
3404 s1->new_undef_sym = 0;
3405 for (i = 0; i < nblibs; i ++)
3406 ld_add_file(s1, libs[i]);
3409 lib_parse_error:
3410 dynarray_reset(&libs, &nblibs);
3411 return ret;
3414 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3415 files */
3416 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3418 char cmd[64];
3419 char filename[1024];
3420 int t, ret;
3422 s1->fd = fd;
3423 s1->cc = -1;
3424 for(;;) {
3425 t = ld_next(s1, cmd, sizeof(cmd));
3426 if (t == LD_TOK_EOF)
3427 return 0;
3428 else if (t != LD_TOK_NAME)
3429 return -1;
3430 if (!strcmp(cmd, "INPUT") ||
3431 !strcmp(cmd, "GROUP")) {
3432 ret = ld_add_file_list(s1, cmd, 0);
3433 if (ret)
3434 return ret;
3435 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3436 !strcmp(cmd, "TARGET")) {
3437 /* ignore some commands */
3438 t = ld_next(s1, cmd, sizeof(cmd));
3439 if (t != '(') {
3440 tcc_error_noabort("( expected");
3441 return -1;
3443 for(;;) {
3444 t = ld_next(s1, filename, sizeof(filename));
3445 if (t == LD_TOK_EOF) {
3446 tcc_error_noabort("unexpected end of file");
3447 return -1;
3448 } else if (t == ')') {
3449 break;
3452 } else {
3453 return -1;
3456 return 0;
3458 #endif /* !ELF_OBJ_ONLY */