win32/tccpe: use full dll-path with -run
[tinycc.git] / tccelf.c
blobff83eb4525a612afce92a6818266888099780383
1 /*
2 * ELF file handling for TCC
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "tcc.h"
23 /* Define this to get some debug output during relocation processing. */
24 #undef DEBUG_RELOC
26 /********************************************************/
27 /* global variables */
29 /* elf version information */
30 struct sym_version {
31 char *lib;
32 char *version;
33 int out_index;
34 int prev_same_lib;
37 #define nb_sym_versions s1->nb_sym_versions
38 #define sym_versions s1->sym_versions
39 #define nb_sym_to_version s1->nb_sym_to_version
40 #define sym_to_version s1->sym_to_version
41 #define dt_verneednum s1->dt_verneednum
42 #define versym_section s1->versym_section
43 #define verneed_section s1->verneed_section
45 /* special flag to indicate that the section should not be linked to the other ones */
46 #define SHF_PRIVATE 0x80000000
47 /* section is dynsymtab_section */
48 #define SHF_DYNSYM 0x40000000
50 /* ------------------------------------------------------------------------- */
52 ST_FUNC void tccelf_new(TCCState *s)
54 TCCState *s1 = s;
55 /* no section zero */
56 dynarray_add(&s->sections, &s->nb_sections, NULL);
58 /* create standard sections */
59 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
60 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
61 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
62 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
63 common_section->sh_num = SHN_COMMON;
65 /* symbols are always generated for linking stage */
66 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
67 ".strtab",
68 ".hashtab", SHF_PRIVATE);
69 s->symtab = symtab_section;
71 /* private symbol table for dynamic symbols */
72 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
73 ".dynstrtab",
74 ".dynhashtab", SHF_PRIVATE);
75 get_sym_attr(s, 0, 1);
78 #ifdef CONFIG_TCC_BCHECK
79 ST_FUNC void tccelf_bounds_new(TCCState *s)
81 TCCState *s1 = s;
82 /* create bounds sections */
83 bounds_section = new_section(s, ".bounds",
84 SHT_PROGBITS, SHF_ALLOC);
85 lbounds_section = new_section(s, ".lbounds",
86 SHT_PROGBITS, SHF_ALLOC);
88 #endif
90 ST_FUNC void tccelf_stab_new(TCCState *s)
92 TCCState *s1 = s;
93 int shf = 0;
94 #ifdef CONFIG_TCC_BACKTRACE
95 /* include stab info with standalone backtrace support */
96 if (s->do_backtrace && s->output_type != TCC_OUTPUT_MEMORY)
97 shf = SHF_ALLOC;
98 #endif
99 stab_section = new_section(s, ".stab", SHT_PROGBITS, shf);
100 stab_section->sh_entsize = sizeof(Stab_Sym);
101 stab_section->sh_addralign = sizeof ((Stab_Sym*)0)->n_value;
102 stab_section->link = new_section(s, ".stabstr", SHT_STRTAB, shf);
103 /* put first entry */
104 put_stabs(s, "", 0, 0, 0, 0);
107 static void free_section(Section *s)
109 tcc_free(s->data);
112 ST_FUNC void tccelf_delete(TCCState *s1)
114 int i;
116 #ifndef ELF_OBJ_ONLY
117 /* free symbol versions */
118 for (i = 0; i < nb_sym_versions; i++) {
119 tcc_free(sym_versions[i].version);
120 tcc_free(sym_versions[i].lib);
122 tcc_free(sym_versions);
123 tcc_free(sym_to_version);
124 #endif
126 /* free all sections */
127 for(i = 1; i < s1->nb_sections; i++)
128 free_section(s1->sections[i]);
129 dynarray_reset(&s1->sections, &s1->nb_sections);
131 for(i = 0; i < s1->nb_priv_sections; i++)
132 free_section(s1->priv_sections[i]);
133 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
135 /* free any loaded DLLs */
136 #ifdef TCC_IS_NATIVE
137 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
138 DLLReference *ref = s1->loaded_dlls[i];
139 if ( ref->handle )
140 # ifdef _WIN32
141 FreeLibrary((HMODULE)ref->handle);
142 # else
143 dlclose(ref->handle);
144 # endif
146 #endif
147 /* free loaded dlls array */
148 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
149 tcc_free(s1->sym_attrs);
151 symtab_section = NULL; /* for tccrun.c:rt_printline() */
154 /* save section data state */
155 ST_FUNC void tccelf_begin_file(TCCState *s1)
157 Section *s; int i;
158 for (i = 1; i < s1->nb_sections; i++) {
159 s = s1->sections[i];
160 s->sh_offset = s->data_offset;
162 /* disable symbol hashing during compilation */
163 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
164 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
165 s1->uw_sym = 0;
166 #endif
169 /* At the end of compilation, convert any UNDEF syms to global, and merge
170 with previously existing symbols */
171 ST_FUNC void tccelf_end_file(TCCState *s1)
173 Section *s = s1->symtab;
174 int first_sym, nb_syms, *tr, i;
176 first_sym = s->sh_offset / sizeof (ElfSym);
177 nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
178 s->data_offset = s->sh_offset;
179 s->link->data_offset = s->link->sh_offset;
180 s->hash = s->reloc, s->reloc = NULL;
181 tr = tcc_mallocz(nb_syms * sizeof *tr);
183 for (i = 0; i < nb_syms; ++i) {
184 ElfSym *sym = (ElfSym*)s->data + first_sym + i;
185 if (sym->st_shndx == SHN_UNDEF
186 && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
187 sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
188 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
189 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
191 /* now update relocations */
192 for (i = 1; i < s1->nb_sections; i++) {
193 Section *sr = s1->sections[i];
194 if (sr->sh_type == SHT_RELX && sr->link == s) {
195 ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
196 ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
197 for (; rel < rel_end; ++rel) {
198 int n = ELFW(R_SYM)(rel->r_info) - first_sym;
199 //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
200 rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
204 tcc_free(tr);
207 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
209 Section *sec;
211 sec = tcc_mallocz(sizeof(Section) + strlen(name));
212 sec->s1 = s1;
213 strcpy(sec->name, name);
214 sec->sh_type = sh_type;
215 sec->sh_flags = sh_flags;
216 switch(sh_type) {
217 case SHT_GNU_versym:
218 sec->sh_addralign = 2;
219 break;
220 case SHT_HASH:
221 case SHT_REL:
222 case SHT_RELA:
223 case SHT_DYNSYM:
224 case SHT_SYMTAB:
225 case SHT_DYNAMIC:
226 case SHT_GNU_verneed:
227 case SHT_GNU_verdef:
228 sec->sh_addralign = PTR_SIZE;
229 break;
230 case SHT_STRTAB:
231 sec->sh_addralign = 1;
232 break;
233 default:
234 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */
235 break;
238 if (sh_flags & SHF_PRIVATE) {
239 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
240 } else {
241 sec->sh_num = s1->nb_sections;
242 dynarray_add(&s1->sections, &s1->nb_sections, sec);
245 return sec;
248 ST_FUNC Section *new_symtab(TCCState *s1,
249 const char *symtab_name, int sh_type, int sh_flags,
250 const char *strtab_name,
251 const char *hash_name, int hash_sh_flags)
253 Section *symtab, *strtab, *hash;
254 int *ptr, nb_buckets;
256 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
257 symtab->sh_entsize = sizeof(ElfW(Sym));
258 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
259 put_elf_str(strtab, "");
260 symtab->link = strtab;
261 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
263 nb_buckets = 1;
265 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
266 hash->sh_entsize = sizeof(int);
267 symtab->hash = hash;
268 hash->link = symtab;
270 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
271 ptr[0] = nb_buckets;
272 ptr[1] = 1;
273 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
274 return symtab;
277 /* realloc section and set its content to zero */
278 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
280 unsigned long size;
281 unsigned char *data;
283 size = sec->data_allocated;
284 if (size == 0)
285 size = 1;
286 while (size < new_size)
287 size = size * 2;
288 data = tcc_realloc(sec->data, size);
289 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
290 sec->data = data;
291 sec->data_allocated = size;
294 /* reserve at least 'size' bytes aligned per 'align' in section
295 'sec' from current offset, and return the aligned offset */
296 ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
298 size_t offset, offset1;
300 offset = (sec->data_offset + align - 1) & -align;
301 offset1 = offset + size;
302 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
303 section_realloc(sec, offset1);
304 sec->data_offset = offset1;
305 if (align > sec->sh_addralign)
306 sec->sh_addralign = align;
307 return offset;
310 /* reserve at least 'size' bytes in section 'sec' from
311 sec->data_offset. */
312 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
314 size_t offset = section_add(sec, size, 1);
315 return sec->data + offset;
318 /* reserve at least 'size' bytes from section start */
319 ST_FUNC void section_reserve(Section *sec, unsigned long size)
321 if (size > sec->data_allocated)
322 section_realloc(sec, size);
323 if (size > sec->data_offset)
324 sec->data_offset = size;
327 static Section *find_section_create (TCCState *s1, const char *name, int create)
329 Section *sec;
330 int i;
331 for(i = 1; i < s1->nb_sections; i++) {
332 sec = s1->sections[i];
333 if (!strcmp(name, sec->name))
334 return sec;
336 /* sections are created as PROGBITS */
337 return create ? new_section(s1, name, SHT_PROGBITS, SHF_ALLOC) : NULL;
340 /* return a reference to a section, and create it if it does not
341 exists */
342 ST_FUNC Section *find_section(TCCState *s1, const char *name)
344 return find_section_create (s1, name, 1);
347 /* ------------------------------------------------------------------------- */
349 ST_FUNC int put_elf_str(Section *s, const char *sym)
351 int offset, len;
352 char *ptr;
354 len = strlen(sym) + 1;
355 offset = s->data_offset;
356 ptr = section_ptr_add(s, len);
357 memmove(ptr, sym, len);
358 return offset;
361 /* elf symbol hashing function */
362 static unsigned long elf_hash(const unsigned char *name)
364 unsigned long h = 0, g;
366 while (*name) {
367 h = (h << 4) + *name++;
368 g = h & 0xf0000000;
369 if (g)
370 h ^= g >> 24;
371 h &= ~g;
373 return h;
376 /* rebuild hash table of section s */
377 /* NOTE: we do factorize the hash table code to go faster */
378 static void rebuild_hash(Section *s, unsigned int nb_buckets)
380 ElfW(Sym) *sym;
381 int *ptr, *hash, nb_syms, sym_index, h;
382 unsigned char *strtab;
384 strtab = s->link->data;
385 nb_syms = s->data_offset / sizeof(ElfW(Sym));
387 if (!nb_buckets)
388 nb_buckets = ((int*)s->hash->data)[0];
390 s->hash->data_offset = 0;
391 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
392 ptr[0] = nb_buckets;
393 ptr[1] = nb_syms;
394 ptr += 2;
395 hash = ptr;
396 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
397 ptr += nb_buckets + 1;
399 sym = (ElfW(Sym) *)s->data + 1;
400 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
401 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
402 h = elf_hash(strtab + sym->st_name) % nb_buckets;
403 *ptr = hash[h];
404 hash[h] = sym_index;
405 } else {
406 *ptr = 0;
408 ptr++;
409 sym++;
413 /* return the symbol number */
414 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
415 int info, int other, int shndx, const char *name)
417 int name_offset, sym_index;
418 int nbuckets, h;
419 ElfW(Sym) *sym;
420 Section *hs;
422 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
423 if (name && name[0])
424 name_offset = put_elf_str(s->link, name);
425 else
426 name_offset = 0;
427 /* XXX: endianness */
428 sym->st_name = name_offset;
429 sym->st_value = value;
430 sym->st_size = size;
431 sym->st_info = info;
432 sym->st_other = other;
433 sym->st_shndx = shndx;
434 sym_index = sym - (ElfW(Sym) *)s->data;
435 hs = s->hash;
436 if (hs) {
437 int *ptr, *base;
438 ptr = section_ptr_add(hs, sizeof(int));
439 base = (int *)hs->data;
440 /* only add global or weak symbols. */
441 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
442 /* add another hashing entry */
443 nbuckets = base[0];
444 h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
445 *ptr = base[2 + h];
446 base[2 + h] = sym_index;
447 base[1]++;
448 /* we resize the hash table */
449 hs->nb_hashed_syms++;
450 if (hs->nb_hashed_syms > 2 * nbuckets) {
451 rebuild_hash(s, 2 * nbuckets);
453 } else {
454 *ptr = 0;
455 base[1]++;
458 return sym_index;
461 ST_FUNC int find_elf_sym(Section *s, const char *name)
463 ElfW(Sym) *sym;
464 Section *hs;
465 int nbuckets, sym_index, h;
466 const char *name1;
468 hs = s->hash;
469 if (!hs)
470 return 0;
471 nbuckets = ((int *)hs->data)[0];
472 h = elf_hash((unsigned char *) name) % nbuckets;
473 sym_index = ((int *)hs->data)[2 + h];
474 while (sym_index != 0) {
475 sym = &((ElfW(Sym) *)s->data)[sym_index];
476 name1 = (char *) s->link->data + sym->st_name;
477 if (!strcmp(name, name1))
478 return sym_index;
479 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
481 return 0;
484 /* return elf symbol value, signal error if 'err' is nonzero, decorate
485 name if FORC */
486 ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
488 int sym_index;
489 ElfW(Sym) *sym;
490 char buf[256];
491 if (forc && s1->leading_underscore
492 #ifdef TCC_TARGET_PE
493 /* win32-32bit stdcall symbols always have _ already */
494 && !strchr(name, '@')
495 #endif
497 buf[0] = '_';
498 pstrcpy(buf + 1, sizeof(buf) - 1, name);
499 name = buf;
501 sym_index = find_elf_sym(s1->symtab, name);
502 sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
503 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
504 if (err)
505 tcc_error("%s not defined", name);
506 return (addr_t)-1;
508 return sym->st_value;
511 /* return elf symbol value */
512 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
514 addr_t addr = get_sym_addr(s, name, 0, 1);
515 return addr == -1 ? NULL : (void*)(uintptr_t)addr;
518 /* list elf symbol names and values */
519 ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
520 void (*symbol_cb)(void *ctx, const char *name, const void *val))
522 ElfW(Sym) *sym;
523 Section *symtab;
524 int sym_index, end_sym;
525 const char *name;
526 unsigned char sym_vis, sym_bind;
528 symtab = s->symtab;
529 end_sym = symtab->data_offset / sizeof (ElfSym);
530 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
531 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
532 if (sym->st_value) {
533 name = (char *) symtab->link->data + sym->st_name;
534 sym_bind = ELFW(ST_BIND)(sym->st_info);
535 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
536 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
537 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
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 #ifndef ELF_OBJ_ONLY
550 static void
551 version_add (TCCState *s1)
553 int i;
554 ElfW(Sym) *sym;
555 ElfW(Verneed) *vn = NULL;
556 Section *symtab;
557 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
558 ElfW(Half) *versym;
559 const char *name;
561 if (0 == nb_sym_versions)
562 return;
563 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
564 versym_section->sh_entsize = sizeof(ElfW(Half));
565 versym_section->link = s1->dynsym;
567 /* add needed symbols */
568 symtab = s1->dynsym;
569 end_sym = symtab->data_offset / sizeof (ElfSym);
570 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
571 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
572 int dllindex, verndx;
573 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
574 name = (char *) symtab->link->data + sym->st_name;
575 dllindex = find_elf_sym(s1->dynsymtab_section, name);
576 verndx = (dllindex && dllindex < nb_sym_to_version)
577 ? sym_to_version[dllindex] : -1;
578 if (verndx >= 0) {
579 if (!sym_versions[verndx].out_index)
580 sym_versions[verndx].out_index = nb_versions++;
581 versym[sym_index] = sym_versions[verndx].out_index;
582 } else
583 versym[sym_index] = 0;
585 /* generate verneed section, but not when it will be empty. Some
586 dynamic linkers look at their contents even when DTVERNEEDNUM and
587 section size is zero. */
588 if (nb_versions > 2) {
589 verneed_section = new_section(s1, ".gnu.version_r",
590 SHT_GNU_verneed, SHF_ALLOC);
591 verneed_section->link = s1->dynsym->link;
592 for (i = nb_sym_versions; i-- > 0;) {
593 struct sym_version *sv = &sym_versions[i];
594 int n_same_libs = 0, prev;
595 size_t vnofs;
596 ElfW(Vernaux) *vna = 0;
597 if (sv->out_index < 1)
598 continue;
599 vnofs = section_add(verneed_section, sizeof(*vn), 1);
600 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
601 vn->vn_version = 1;
602 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
603 vn->vn_aux = sizeof (*vn);
604 do {
605 prev = sv->prev_same_lib;
606 if (sv->out_index > 0) {
607 vna = section_ptr_add(verneed_section, sizeof(*vna));
608 vna->vna_hash = elf_hash ((const unsigned char *)sv->version);
609 vna->vna_flags = 0;
610 vna->vna_other = sv->out_index;
611 sv->out_index = -2;
612 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
613 vna->vna_next = sizeof (*vna);
614 n_same_libs++;
616 if (prev >= 0)
617 sv = &sym_versions[prev];
618 } while(prev >= 0);
619 vna->vna_next = 0;
620 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
621 vn->vn_cnt = n_same_libs;
622 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
623 nb_entries++;
625 if (vn)
626 vn->vn_next = 0;
627 verneed_section->sh_info = nb_entries;
629 dt_verneednum = nb_entries;
631 #endif
633 /* add an elf symbol : check if it is already defined and patch
634 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
635 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
636 int info, int other, int shndx, const char *name)
638 TCCState *s1 = s->s1;
639 ElfW(Sym) *esym;
640 int sym_bind, sym_index, sym_type, esym_bind;
641 unsigned char sym_vis, esym_vis, new_vis;
643 sym_bind = ELFW(ST_BIND)(info);
644 sym_type = ELFW(ST_TYPE)(info);
645 sym_vis = ELFW(ST_VISIBILITY)(other);
647 if (sym_bind != STB_LOCAL) {
648 /* we search global or weak symbols */
649 sym_index = find_elf_sym(s, name);
650 if (!sym_index)
651 goto do_def;
652 esym = &((ElfW(Sym) *)s->data)[sym_index];
653 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
654 && esym->st_other == other && esym->st_shndx == shndx)
655 return sym_index;
656 if (esym->st_shndx != SHN_UNDEF) {
657 esym_bind = ELFW(ST_BIND)(esym->st_info);
658 /* propagate the most constraining visibility */
659 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
660 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
661 if (esym_vis == STV_DEFAULT) {
662 new_vis = sym_vis;
663 } else if (sym_vis == STV_DEFAULT) {
664 new_vis = esym_vis;
665 } else {
666 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
668 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
669 | new_vis;
670 other = esym->st_other; /* in case we have to patch esym */
671 if (shndx == SHN_UNDEF) {
672 /* ignore adding of undefined symbol if the
673 corresponding symbol is already defined */
674 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
675 /* global overrides weak, so patch */
676 goto do_patch;
677 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
678 /* weak is ignored if already global */
679 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
680 /* keep first-found weak definition, ignore subsequents */
681 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
682 /* ignore hidden symbols after */
683 } else if ((esym->st_shndx == SHN_COMMON
684 || esym->st_shndx == bss_section->sh_num)
685 && (shndx < SHN_LORESERVE
686 && shndx != bss_section->sh_num)) {
687 /* data symbol gets precedence over common/bss */
688 goto do_patch;
689 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
690 /* data symbol keeps precedence over common/bss */
691 } else if (s->sh_flags & SHF_DYNSYM) {
692 /* we accept that two DLL define the same symbol */
693 } else if (esym->st_other & ST_ASM_SET) {
694 /* If the existing symbol came from an asm .set
695 we can override. */
696 goto do_patch;
697 } else {
698 #if 0
699 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
700 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
701 #endif
702 tcc_error_noabort("'%s' defined twice", name);
704 } else {
705 do_patch:
706 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
707 esym->st_shndx = shndx;
708 s1->new_undef_sym = 1;
709 esym->st_value = value;
710 esym->st_size = size;
711 esym->st_other = other;
713 } else {
714 do_def:
715 sym_index = put_elf_sym(s, value, size,
716 ELFW(ST_INFO)(sym_bind, sym_type), other,
717 shndx, name);
719 return sym_index;
722 /* put relocation */
723 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
724 int type, int symbol, addr_t addend)
726 TCCState *s1 = s->s1;
727 char buf[256];
728 Section *sr;
729 ElfW_Rel *rel;
731 sr = s->reloc;
732 if (!sr) {
733 /* if no relocation section, create it */
734 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
735 /* if the symtab is allocated, then we consider the relocation
736 are also */
737 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
738 sr->sh_entsize = sizeof(ElfW_Rel);
739 sr->link = symtab;
740 sr->sh_info = s->sh_num;
741 s->reloc = sr;
743 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
744 rel->r_offset = offset;
745 rel->r_info = ELFW(R_INFO)(symbol, type);
746 #if SHT_RELX == SHT_RELA
747 rel->r_addend = addend;
748 #endif
749 if (SHT_RELX != SHT_RELA && addend)
750 tcc_error("non-zero addend on REL architecture");
753 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
754 int type, int symbol)
756 put_elf_reloca(symtab, s, offset, type, symbol, 0);
759 /* Remove relocations for section S->reloc starting at oldrelocoffset
760 that are to the same place, retaining the last of them. As side effect
761 the relocations are sorted. Possibly reduces the number of relocs. */
762 ST_FUNC void squeeze_multi_relocs(Section *s, size_t oldrelocoffset)
764 Section *sr = s->reloc;
765 ElfW_Rel *r, *dest;
766 ssize_t a;
767 ElfW(Addr) addr;
769 if (oldrelocoffset + sizeof(*r) >= sr->data_offset)
770 return;
771 /* The relocs we're dealing with are the result of initializer parsing.
772 So they will be mostly in order and there aren't many of them.
773 Secondly we need a stable sort (which qsort isn't). We use
774 a simple insertion sort. */
775 for (a = oldrelocoffset + sizeof(*r); a < sr->data_offset; a += sizeof(*r)) {
776 ssize_t i = a - sizeof(*r);
777 addr = ((ElfW_Rel*)(sr->data + a))->r_offset;
778 for (; i >= (ssize_t)oldrelocoffset &&
779 ((ElfW_Rel*)(sr->data + i))->r_offset > addr; i -= sizeof(*r)) {
780 ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a);
781 *(ElfW_Rel*)(sr->data + a) = *(ElfW_Rel*)(sr->data + i);
782 *(ElfW_Rel*)(sr->data + i) = tmp;
786 r = (ElfW_Rel*)(sr->data + oldrelocoffset);
787 dest = r;
788 for (; r < (ElfW_Rel*)(sr->data + sr->data_offset); r++) {
789 if (dest->r_offset != r->r_offset)
790 dest++;
791 *dest = *r;
793 sr->data_offset = (unsigned char*)dest - sr->data + sizeof(*r);
796 /* put stab debug information */
798 ST_FUNC void put_stabs(TCCState *s1, const char *str, int type, int other, int desc,
799 unsigned long value)
801 Stab_Sym *sym;
803 unsigned offset;
804 if (type == N_SLINE
805 && (offset = stab_section->data_offset)
806 && (sym = (Stab_Sym*)(stab_section->data + offset) - 1)
807 && sym->n_type == type
808 && sym->n_value == value) {
809 /* just update line_number in previous entry */
810 sym->n_desc = desc;
811 return;
814 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
815 if (str) {
816 sym->n_strx = put_elf_str(stab_section->link, str);
817 } else {
818 sym->n_strx = 0;
820 sym->n_type = type;
821 sym->n_other = other;
822 sym->n_desc = desc;
823 sym->n_value = value;
826 ST_FUNC void put_stabs_r(TCCState *s1, const char *str, int type, int other, int desc,
827 unsigned long value, Section *sec, int sym_index)
829 put_elf_reloc(symtab_section, stab_section,
830 stab_section->data_offset + 8,
831 sizeof ((Stab_Sym*)0)->n_value == PTR_SIZE ? R_DATA_PTR : R_DATA_32,
832 sym_index);
833 put_stabs(s1, str, type, other, desc, value);
836 ST_FUNC void put_stabn(TCCState *s1, int type, int other, int desc, int value)
838 put_stabs(s1, NULL, type, other, desc, value);
841 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
843 int n;
844 struct sym_attr *tab;
846 if (index >= s1->nb_sym_attrs) {
847 if (!alloc)
848 return s1->sym_attrs;
849 /* find immediately bigger power of 2 and reallocate array */
850 n = 1;
851 while (index >= n)
852 n *= 2;
853 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
854 s1->sym_attrs = tab;
855 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
856 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
857 s1->nb_sym_attrs = n;
859 return &s1->sym_attrs[index];
862 /* In an ELF file symbol table, the local symbols must appear below
863 the global and weak ones. Since TCC cannot sort it while generating
864 the code, we must do it after. All the relocation tables are also
865 modified to take into account the symbol table sorting */
866 static void sort_syms(TCCState *s1, Section *s)
868 int *old_to_new_syms;
869 ElfW(Sym) *new_syms;
870 int nb_syms, i;
871 ElfW(Sym) *p, *q;
872 ElfW_Rel *rel;
873 Section *sr;
874 int type, sym_index;
876 nb_syms = s->data_offset / sizeof(ElfW(Sym));
877 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
878 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
880 /* first pass for local symbols */
881 p = (ElfW(Sym) *)s->data;
882 q = new_syms;
883 for(i = 0; i < nb_syms; i++) {
884 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
885 old_to_new_syms[i] = q - new_syms;
886 *q++ = *p;
888 p++;
890 /* save the number of local symbols in section header */
891 if( s->sh_size ) /* this 'if' makes IDA happy */
892 s->sh_info = q - new_syms;
894 /* then second pass for non local symbols */
895 p = (ElfW(Sym) *)s->data;
896 for(i = 0; i < nb_syms; i++) {
897 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
898 old_to_new_syms[i] = q - new_syms;
899 *q++ = *p;
901 p++;
904 /* we copy the new symbols to the old */
905 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
906 tcc_free(new_syms);
908 /* now we modify all the relocations */
909 for(i = 1; i < s1->nb_sections; i++) {
910 sr = s1->sections[i];
911 if (sr->sh_type == SHT_RELX && sr->link == s) {
912 for_each_elem(sr, 0, rel, ElfW_Rel) {
913 sym_index = ELFW(R_SYM)(rel->r_info);
914 type = ELFW(R_TYPE)(rel->r_info);
915 sym_index = old_to_new_syms[sym_index];
916 rel->r_info = ELFW(R_INFO)(sym_index, type);
921 tcc_free(old_to_new_syms);
924 /* relocate symbol table, resolve undefined symbols if do_resolve is
925 true and output error if undefined symbol. */
926 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
928 ElfW(Sym) *sym;
929 int sym_bind, sh_num;
930 const char *name;
932 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
933 sh_num = sym->st_shndx;
934 if (sh_num == SHN_UNDEF) {
935 name = (char *) s1->symtab->link->data + sym->st_name;
936 /* Use ld.so to resolve symbol for us (for tcc -run) */
937 if (do_resolve) {
938 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
939 #ifdef TCC_TARGET_MACHO
940 /* The symbols in the symtables have a prepended '_'
941 but dlsym() needs the undecorated name. */
942 void *addr = dlsym(RTLD_DEFAULT, name + 1);
943 #else
944 void *addr = dlsym(RTLD_DEFAULT, name);
945 #endif
946 if (addr) {
947 sym->st_value = (addr_t) addr;
948 #ifdef DEBUG_RELOC
949 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
950 #endif
951 goto found;
953 #endif
954 /* if dynamic symbol exist, it will be used in relocate_section */
955 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
956 goto found;
957 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
958 it */
959 if (!strcmp(name, "_fp_hw"))
960 goto found;
961 /* only weak symbols are accepted to be undefined. Their
962 value is zero */
963 sym_bind = ELFW(ST_BIND)(sym->st_info);
964 if (sym_bind == STB_WEAK)
965 sym->st_value = 0;
966 else
967 tcc_error_noabort("undefined symbol '%s'", name);
968 } else if (sh_num < SHN_LORESERVE) {
969 /* add section base */
970 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
972 found: ;
976 /* relocate a given section (CPU dependent) by applying the relocations
977 in the associated relocation section */
978 ST_FUNC void relocate_section(TCCState *s1, Section *s)
980 Section *sr = s->reloc;
981 ElfW_Rel *rel;
982 ElfW(Sym) *sym;
983 int type, sym_index;
984 unsigned char *ptr;
985 addr_t tgt, addr;
987 qrel = (ElfW_Rel *)sr->data;
989 for_each_elem(sr, 0, rel, ElfW_Rel) {
990 ptr = s->data + rel->r_offset;
991 sym_index = ELFW(R_SYM)(rel->r_info);
992 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
993 type = ELFW(R_TYPE)(rel->r_info);
994 tgt = sym->st_value;
995 #if SHT_RELX == SHT_RELA
996 tgt += rel->r_addend;
997 #endif
998 addr = s->sh_addr + rel->r_offset;
999 relocate(s1, rel, type, ptr, addr, tgt);
1001 /* if the relocation is allocated, we change its symbol table */
1002 if (sr->sh_flags & SHF_ALLOC) {
1003 sr->link = s1->dynsym;
1004 if (s1->output_type == TCC_OUTPUT_DLL) {
1005 size_t r = (uint8_t*)qrel - sr->data;
1006 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
1007 && 0 == strcmp(s->name, ".stab"))
1008 r = 0; /* cannot apply 64bit relocation to 32bit value */
1009 sr->data_offset = sr->sh_size = r;
1014 #ifndef ELF_OBJ_ONLY
1015 /* relocate relocation table in 'sr' */
1016 static void relocate_rel(TCCState *s1, Section *sr)
1018 Section *s;
1019 ElfW_Rel *rel;
1021 s = s1->sections[sr->sh_info];
1022 for_each_elem(sr, 0, rel, ElfW_Rel)
1023 rel->r_offset += s->sh_addr;
1026 /* count the number of dynamic relocations so that we can reserve
1027 their space */
1028 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
1030 int count = 0;
1031 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1032 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1033 defined(TCC_TARGET_RISCV64)
1034 ElfW_Rel *rel;
1035 for_each_elem(sr, 0, rel, ElfW_Rel) {
1036 int sym_index = ELFW(R_SYM)(rel->r_info);
1037 int type = ELFW(R_TYPE)(rel->r_info);
1038 switch(type) {
1039 #if defined(TCC_TARGET_I386)
1040 case R_386_32:
1041 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
1042 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
1043 /* don't fixup unresolved (weak) symbols */
1044 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
1045 break;
1047 #elif defined(TCC_TARGET_X86_64)
1048 case R_X86_64_32:
1049 case R_X86_64_32S:
1050 case R_X86_64_64:
1051 #elif defined(TCC_TARGET_ARM)
1052 case R_ARM_ABS32:
1053 #elif defined(TCC_TARGET_ARM64)
1054 case R_AARCH64_ABS32:
1055 case R_AARCH64_ABS64:
1056 #elif defined(TCC_TARGET_RISCV64)
1057 case R_RISCV_32:
1058 case R_RISCV_64:
1059 #endif
1060 count++;
1061 break;
1062 #if defined(TCC_TARGET_I386)
1063 case R_386_PC32:
1064 #elif defined(TCC_TARGET_X86_64)
1065 case R_X86_64_PC32:
1066 #elif defined(TCC_TARGET_ARM64)
1067 case R_AARCH64_PREL32:
1068 #endif
1069 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1070 count++;
1071 break;
1072 default:
1073 break;
1076 if (count) {
1077 /* allocate the section */
1078 sr->sh_flags |= SHF_ALLOC;
1079 sr->sh_size = count * sizeof(ElfW_Rel);
1081 #endif
1082 return count;
1084 #endif
1086 #if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE)
1087 static void build_got(TCCState *s1)
1089 /* if no got, then create it */
1090 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1091 s1->got->sh_entsize = 4;
1092 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1093 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1094 /* keep space for _DYNAMIC pointer and two dummy got entries */
1095 section_ptr_add(s1->got, 3 * PTR_SIZE);
1098 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1099 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1100 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1101 Returns the offset of the GOT or (if any) PLT entry. */
1102 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1103 int sym_index)
1105 int need_plt_entry;
1106 const char *name;
1107 ElfW(Sym) *sym;
1108 struct sym_attr *attr;
1109 unsigned got_offset;
1110 char plt_name[100];
1111 int len;
1113 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1114 attr = get_sym_attr(s1, sym_index, 1);
1116 /* In case a function is both called and its address taken 2 GOT entries
1117 are created, one for taking the address (GOT) and the other for the PLT
1118 entry (PLTGOT). */
1119 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1120 return attr;
1122 /* create the GOT entry */
1123 got_offset = s1->got->data_offset;
1124 section_ptr_add(s1->got, PTR_SIZE);
1126 /* Create the GOT relocation that will insert the address of the object or
1127 function of interest in the GOT entry. This is a static relocation for
1128 memory output (dlsym will give us the address of symbols) and dynamic
1129 relocation otherwise (executable and DLLs). The relocation should be
1130 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1131 associated to a PLT entry) but is currently done at load time for an
1132 unknown reason. */
1134 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1135 name = (char *) symtab_section->link->data + sym->st_name;
1137 if (s1->dynsym) {
1138 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1139 /* Hack alarm. We don't want to emit dynamic symbols
1140 and symbol based relocs for STB_LOCAL symbols, but rather
1141 want to resolve them directly. At this point the symbol
1142 values aren't final yet, so we must defer this. We will later
1143 have to create a RELATIVE reloc anyway, so we misuse the
1144 relocation slot to smuggle the symbol reference until
1145 fill_local_got_entries. Not that the sym_index is
1146 relative to symtab_section, not s1->dynsym! Nevertheless
1147 we use s1->dyn_sym so that if this is the first call
1148 that got->reloc is correctly created. Also note that
1149 RELATIVE relocs are not normally created for the .got,
1150 so the types serves as a marker for later (and is retained
1151 also for the final output, which is okay because then the
1152 got is just normal data). */
1153 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1154 sym_index);
1155 } else {
1156 if (0 == attr->dyn_index)
1157 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1158 sym->st_size, sym->st_info, 0,
1159 sym->st_shndx, name);
1160 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
1161 attr->dyn_index);
1163 } else {
1164 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1165 sym_index);
1168 if (need_plt_entry) {
1169 if (!s1->plt) {
1170 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1171 SHF_ALLOC | SHF_EXECINSTR);
1172 s1->plt->sh_entsize = 4;
1175 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1177 /* create a symbol 'sym@plt' for the PLT jump vector */
1178 len = strlen(name);
1179 if (len > sizeof plt_name - 5)
1180 len = sizeof plt_name - 5;
1181 memcpy(plt_name, name, len);
1182 strcpy(plt_name + len, "@plt");
1183 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
1184 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1186 } else {
1187 attr->got_offset = got_offset;
1190 return attr;
1193 /* build GOT and PLT entries */
1194 ST_FUNC void build_got_entries(TCCState *s1)
1196 Section *s;
1197 ElfW_Rel *rel;
1198 ElfW(Sym) *sym;
1199 int i, type, gotplt_entry, reloc_type, sym_index;
1200 struct sym_attr *attr;
1202 for(i = 1; i < s1->nb_sections; i++) {
1203 s = s1->sections[i];
1204 if (s->sh_type != SHT_RELX)
1205 continue;
1206 /* no need to handle got relocations */
1207 if (s->link != symtab_section)
1208 continue;
1209 for_each_elem(s, 0, rel, ElfW_Rel) {
1210 type = ELFW(R_TYPE)(rel->r_info);
1211 gotplt_entry = gotplt_entry_type(type);
1212 if (gotplt_entry == -1)
1213 tcc_error ("Unknown relocation type for got: %d", type);
1214 sym_index = ELFW(R_SYM)(rel->r_info);
1215 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1217 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1218 continue;
1221 /* Automatically create PLT/GOT [entry] if it is an undefined
1222 reference (resolved at runtime), or the symbol is absolute,
1223 probably created by tcc_add_symbol, and thus on 64-bit
1224 targets might be too far from application code. */
1225 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1226 if (sym->st_shndx == SHN_UNDEF) {
1227 ElfW(Sym) *esym;
1228 int dynindex;
1229 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1230 continue;
1231 /* Relocations for UNDEF symbols would normally need
1232 to be transferred into the executable or shared object.
1233 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1234 But TCC doesn't do that (at least for exes), so we
1235 need to resolve all such relocs locally. And that
1236 means PLT slots for functions in DLLs and COPY relocs for
1237 data symbols. COPY relocs were generated in
1238 bind_exe_dynsyms (and the symbol adjusted to be defined),
1239 and for functions we were generated a dynamic symbol
1240 of function type. */
1241 if (s1->dynsym) {
1242 /* dynsym isn't set for -run :-/ */
1243 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1244 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1245 if (dynindex
1246 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1247 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1248 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1249 goto jmp_slot;
1251 } else if (!(sym->st_shndx == SHN_ABS
1252 #ifndef TCC_TARGET_ARM
1253 && PTR_SIZE == 8
1254 #endif
1256 continue;
1259 #ifdef TCC_TARGET_X86_64
1260 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1261 sym->st_shndx != SHN_UNDEF &&
1262 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1263 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1264 s1->output_type == TCC_OUTPUT_EXE)) {
1265 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1266 continue;
1268 #endif
1269 reloc_type = code_reloc(type);
1270 if (reloc_type == -1)
1271 tcc_error ("Unknown relocation type: %d", type);
1272 else if (reloc_type != 0) {
1273 jmp_slot:
1274 reloc_type = R_JMP_SLOT;
1275 } else
1276 reloc_type = R_GLOB_DAT;
1278 if (!s1->got)
1279 build_got(s1);
1281 if (gotplt_entry == BUILD_GOT_ONLY)
1282 continue;
1284 attr = put_got_entry(s1, reloc_type, sym_index);
1286 if (reloc_type == R_JMP_SLOT)
1287 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1291 #endif
1293 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
1295 int shn = sec ? sec->sh_num : offs ? SHN_ABS : SHN_UNDEF;
1296 if (sec && offs == -1)
1297 offs = sec->data_offset;
1298 return set_elf_sym(symtab_section, offs, 0,
1299 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1302 static void add_init_array_defines(TCCState *s1, const char *section_name)
1304 Section *s;
1305 addr_t end_offset;
1306 char buf[1024];
1307 s = find_section(s1, section_name);
1308 if (!s) {
1309 end_offset = 0;
1310 s = data_section;
1311 } else {
1312 end_offset = s->data_offset;
1314 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1315 set_global_sym(s1, buf, s, 0);
1316 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1317 set_global_sym(s1, buf, s, end_offset);
1320 #ifndef TCC_TARGET_PE
1321 static int tcc_add_support(TCCState *s1, const char *filename)
1323 char buf[1024];
1324 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1325 return tcc_add_file(s1, buf);
1327 #endif
1329 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1331 Section *s;
1332 s = find_section(s1, sec);
1333 s->sh_flags |= SHF_WRITE;
1334 #ifndef TCC_TARGET_PE
1335 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1336 #endif
1337 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1338 section_ptr_add(s, PTR_SIZE);
1341 #ifdef CONFIG_TCC_BCHECK
1342 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1344 if (0 == s1->do_bounds_check)
1345 return;
1346 section_ptr_add(bounds_section, sizeof(addr_t));
1348 #endif
1350 #ifdef CONFIG_TCC_BACKTRACE
1351 static void put_ptr(TCCState *s1, Section *s, int offs)
1353 int c;
1354 c = set_global_sym(s1, NULL, s, offs);
1355 s = data_section;
1356 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1357 section_ptr_add(s, PTR_SIZE);
1360 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1361 a dynamic symbol to allow so's to have one each with a different value. */
1362 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1364 int c = find_elf_sym(s1->symtab, name);
1365 if (c) {
1366 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1367 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1368 esym->st_value = offset;
1369 esym->st_shndx = s->sh_num;
1373 ST_FUNC void tcc_add_btstub(TCCState *s1)
1375 Section *s;
1376 int n, o;
1377 CString cstr;
1379 s = data_section;
1380 o = s->data_offset;
1381 /* create (part of) a struct rt_context (see tccrun.c) */
1382 put_ptr(s1, stab_section, 0);
1383 put_ptr(s1, stab_section, -1);
1384 put_ptr(s1, stab_section->link, 0);
1385 section_ptr_add(s, 3 * PTR_SIZE);
1386 /* prog_base */
1387 #ifndef TCC_TARGET_MACHO
1388 /* XXX this relocation is wrong, it uses sym-index 0 (local,undef) */
1389 put_elf_reloc(s1->symtab, s, s->data_offset, R_DATA_PTR, 0);
1390 #endif
1391 section_ptr_add(s, PTR_SIZE);
1392 n = 2 * PTR_SIZE;
1393 #ifdef CONFIG_TCC_BCHECK
1394 if (s1->do_bounds_check) {
1395 put_ptr(s1, bounds_section, 0);
1396 n -= PTR_SIZE;
1398 #endif
1399 section_ptr_add(s, n);
1401 cstr_new(&cstr);
1402 cstr_printf(&cstr,
1403 " extern void __bt_init(),*__rt_info[],__bt_init_dll();"
1404 "__attribute__((constructor)) static void __bt_init_rt(){");
1405 #ifdef TCC_TARGET_PE
1406 if (s1->output_type == TCC_OUTPUT_DLL)
1407 #ifdef CONFIG_TCC_BCHECK
1408 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1409 #else
1410 cstr_printf(&cstr, "__bt_init_dll(0);");
1411 #endif
1412 #endif
1413 cstr_printf(&cstr, "__bt_init(__rt_info,%d, 0);}",
1414 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1415 tcc_compile_string(s1, cstr.data);
1416 cstr_free(&cstr);
1417 set_local_sym(s1, &"___rt_info"[!s1->leading_underscore], s, o);
1419 #endif
1421 #ifndef TCC_TARGET_PE
1422 /* add tcc runtime libraries */
1423 ST_FUNC void tcc_add_runtime(TCCState *s1)
1425 s1->filetype = 0;
1426 #ifdef CONFIG_TCC_BCHECK
1427 tcc_add_bcheck(s1);
1428 #endif
1429 tcc_add_pragma_libs(s1);
1430 /* add libc */
1431 if (!s1->nostdlib) {
1432 if (s1->option_pthread)
1433 tcc_add_library_err(s1, "pthread");
1434 tcc_add_library_err(s1, "c");
1435 #ifdef TCC_LIBGCC
1436 if (!s1->static_link) {
1437 if (TCC_LIBGCC[0] == '/')
1438 tcc_add_file(s1, TCC_LIBGCC);
1439 else
1440 tcc_add_dll(s1, TCC_LIBGCC, 0);
1442 #endif
1443 #ifdef CONFIG_TCC_BCHECK
1444 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1445 tcc_add_library_err(s1, "pthread");
1446 tcc_add_library_err(s1, "dl");
1447 tcc_add_support(s1, "bcheck.o");
1449 #endif
1450 #ifdef CONFIG_TCC_BACKTRACE
1451 if (s1->do_backtrace) {
1452 if (s1->output_type == TCC_OUTPUT_EXE)
1453 tcc_add_support(s1, "bt-exe.o");
1454 if (s1->output_type != TCC_OUTPUT_DLL)
1455 tcc_add_support(s1, "bt-log.o");
1456 if (s1->output_type != TCC_OUTPUT_MEMORY)
1457 tcc_add_btstub(s1);
1459 #endif
1460 tcc_add_support(s1, TCC_LIBTCC1);
1461 #ifndef TCC_TARGET_MACHO
1462 /* add crt end if not memory output */
1463 if (s1->output_type != TCC_OUTPUT_MEMORY)
1464 tcc_add_crt(s1, "crtn.o");
1465 #endif
1468 #endif
1470 /* add various standard linker symbols (must be done after the
1471 sections are filled (for example after allocating common
1472 symbols)) */
1473 static void tcc_add_linker_symbols(TCCState *s1)
1475 char buf[1024];
1476 int i;
1477 Section *s;
1479 set_global_sym(s1, "_etext", text_section, -1);
1480 set_global_sym(s1, "_edata", data_section, -1);
1481 set_global_sym(s1, "_end", bss_section, -1);
1482 #ifdef TCC_TARGET_RISCV64
1483 /* XXX should be .sdata+0x800, not .data+0x800 */
1484 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1485 #endif
1486 /* horrible new standard ldscript defines */
1487 add_init_array_defines(s1, ".preinit_array");
1488 add_init_array_defines(s1, ".init_array");
1489 add_init_array_defines(s1, ".fini_array");
1490 /* add start and stop symbols for sections whose name can be
1491 expressed in C */
1492 for(i = 1; i < s1->nb_sections; i++) {
1493 s = s1->sections[i];
1494 if ((s->sh_flags & SHF_ALLOC)
1495 && (s->sh_type == SHT_PROGBITS
1496 || s->sh_type == SHT_STRTAB)) {
1497 const char *p;
1498 /* check if section name can be expressed in C */
1499 p = s->name;
1500 for(;;) {
1501 int c = *p;
1502 if (!c)
1503 break;
1504 if (!isid(c) && !isnum(c))
1505 goto next_sec;
1506 p++;
1508 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1509 set_global_sym(s1, buf, s, 0);
1510 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1511 set_global_sym(s1, buf, s, -1);
1513 next_sec: ;
1517 ST_FUNC void resolve_common_syms(TCCState *s1)
1519 ElfW(Sym) *sym;
1521 /* Allocate common symbols in BSS. */
1522 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1523 if (sym->st_shndx == SHN_COMMON) {
1524 /* symbol alignment is in st_value for SHN_COMMONs */
1525 sym->st_value = section_add(bss_section, sym->st_size,
1526 sym->st_value);
1527 sym->st_shndx = bss_section->sh_num;
1531 /* Now assign linker provided symbols their value. */
1532 tcc_add_linker_symbols(s1);
1535 static void tcc_output_binary(TCCState *s1, FILE *f,
1536 const int *sec_order)
1538 Section *s;
1539 int i, offset, size;
1541 offset = 0;
1542 for(i=1;i<s1->nb_sections;i++) {
1543 s = s1->sections[sec_order[i]];
1544 if (s->sh_type != SHT_NOBITS &&
1545 (s->sh_flags & SHF_ALLOC)) {
1546 while (offset < s->sh_offset) {
1547 fputc(0, f);
1548 offset++;
1550 size = s->sh_size;
1551 fwrite(s->data, 1, size, f);
1552 offset += size;
1557 #ifndef ELF_OBJ_ONLY
1558 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1560 int sym_index = ELFW(R_SYM) (rel->r_info);
1561 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1562 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1563 unsigned offset = attr->got_offset;
1565 if (0 == offset)
1566 return;
1567 section_reserve(s1->got, offset + PTR_SIZE);
1568 #if PTR_SIZE == 8
1569 write64le(s1->got->data + offset, sym->st_value);
1570 #else
1571 write32le(s1->got->data + offset, sym->st_value);
1572 #endif
1575 /* Perform relocation to GOT or PLT entries */
1576 ST_FUNC void fill_got(TCCState *s1)
1578 Section *s;
1579 ElfW_Rel *rel;
1580 int i;
1582 for(i = 1; i < s1->nb_sections; i++) {
1583 s = s1->sections[i];
1584 if (s->sh_type != SHT_RELX)
1585 continue;
1586 /* no need to handle got relocations */
1587 if (s->link != symtab_section)
1588 continue;
1589 for_each_elem(s, 0, rel, ElfW_Rel) {
1590 switch (ELFW(R_TYPE) (rel->r_info)) {
1591 case R_X86_64_GOT32:
1592 case R_X86_64_GOTPCREL:
1593 case R_X86_64_GOTPCRELX:
1594 case R_X86_64_REX_GOTPCRELX:
1595 case R_X86_64_PLT32:
1596 fill_got_entry(s1, rel);
1597 break;
1603 /* See put_got_entry for a description. This is the second stage
1604 where GOT references to local defined symbols are rewritten. */
1605 static void fill_local_got_entries(TCCState *s1)
1607 ElfW_Rel *rel;
1608 if (!s1->got->reloc)
1609 return;
1610 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1611 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1612 int sym_index = ELFW(R_SYM) (rel->r_info);
1613 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1614 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1615 unsigned offset = attr->got_offset;
1616 if (offset != rel->r_offset - s1->got->sh_addr)
1617 tcc_error_noabort("huh");
1618 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1619 #if SHT_RELX == SHT_RELA
1620 rel->r_addend = sym->st_value;
1621 #else
1622 /* All our REL architectures also happen to be 32bit LE. */
1623 write32le(s1->got->data + offset, sym->st_value);
1624 #endif
1629 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1630 in shared libraries and export non local defined symbols to shared libraries
1631 if -rdynamic switch was given on command line */
1632 static void bind_exe_dynsyms(TCCState *s1)
1634 const char *name;
1635 int sym_index, index;
1636 ElfW(Sym) *sym, *esym;
1637 int type;
1639 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1640 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1641 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1642 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1643 if (sym->st_shndx == SHN_UNDEF) {
1644 name = (char *) symtab_section->link->data + sym->st_name;
1645 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1646 if (sym_index) {
1647 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1648 type = ELFW(ST_TYPE)(esym->st_info);
1649 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1650 /* Indirect functions shall have STT_FUNC type in executable
1651 * dynsym section. Indeed, a dlsym call following a lazy
1652 * resolution would pick the symbol value from the
1653 * executable dynsym entry which would contain the address
1654 * of the function wanted by the caller of dlsym instead of
1655 * the address of the function that would return that
1656 * address */
1657 int dynindex
1658 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1659 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1660 name);
1661 int index = sym - (ElfW(Sym) *) symtab_section->data;
1662 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1663 } else if (type == STT_OBJECT) {
1664 unsigned long offset;
1665 ElfW(Sym) *dynsym;
1666 offset = bss_section->data_offset;
1667 /* XXX: which alignment ? */
1668 offset = (offset + 16 - 1) & -16;
1669 set_elf_sym (s1->symtab, offset, esym->st_size,
1670 esym->st_info, 0, bss_section->sh_num, name);
1671 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1672 esym->st_info, 0, bss_section->sh_num,
1673 name);
1675 /* Ensure R_COPY works for weak symbol aliases */
1676 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1677 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1678 if ((dynsym->st_value == esym->st_value)
1679 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1680 char *dynname = (char *) s1->dynsymtab_section->link->data
1681 + dynsym->st_name;
1682 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1683 dynsym->st_info, 0,
1684 bss_section->sh_num, dynname);
1685 break;
1690 put_elf_reloc(s1->dynsym, bss_section,
1691 offset, R_COPY, index);
1692 offset += esym->st_size;
1693 bss_section->data_offset = offset;
1695 } else {
1696 /* STB_WEAK undefined symbols are accepted */
1697 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1698 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1699 !strcmp(name, "_fp_hw")) {
1700 } else {
1701 tcc_error_noabort("undefined symbol '%s'", name);
1704 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1705 /* if -rdynamic option, then export all non local symbols */
1706 name = (char *) symtab_section->link->data + sym->st_name;
1707 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1708 0, sym->st_shndx, name);
1713 /* Bind symbols of libraries: export all non local symbols of executable that
1714 are referenced by shared libraries. The reason is that the dynamic loader
1715 search symbol first in executable and then in libraries. Therefore a
1716 reference to a symbol already defined by a library can still be resolved by
1717 a symbol in the executable. */
1718 static void bind_libs_dynsyms(TCCState *s1)
1720 const char *name;
1721 int sym_index;
1722 ElfW(Sym) *sym, *esym;
1724 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1725 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1726 sym_index = find_elf_sym(symtab_section, name);
1727 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1728 if (sym_index && sym->st_shndx != SHN_UNDEF
1729 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1730 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1731 sym->st_info, 0, sym->st_shndx, name);
1732 } else if (esym->st_shndx == SHN_UNDEF) {
1733 /* weak symbols can stay undefined */
1734 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1735 tcc_warning("undefined dynamic symbol '%s'", name);
1740 /* Export all non local symbols. This is used by shared libraries so that the
1741 non local symbols they define can resolve a reference in another shared
1742 library or in the executable. Correspondingly, it allows undefined local
1743 symbols to be resolved by other shared libraries or by the executable. */
1744 static void export_global_syms(TCCState *s1)
1746 int dynindex, index;
1747 const char *name;
1748 ElfW(Sym) *sym;
1750 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1751 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1752 name = (char *) symtab_section->link->data + sym->st_name;
1753 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1754 sym->st_info, 0, sym->st_shndx, name);
1755 index = sym - (ElfW(Sym) *) symtab_section->data;
1756 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1760 #endif
1762 /* Allocate strings for section names and decide if an unallocated section
1763 should be output.
1764 NOTE: the strsec section comes last, so its size is also correct ! */
1765 static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1767 int i;
1768 Section *s;
1769 int textrel = 0;
1771 /* Allocate strings for section names */
1772 for(i = 1; i < s1->nb_sections; i++) {
1773 s = s1->sections[i];
1774 /* when generating a DLL, we include relocations but we may
1775 patch them */
1776 #ifndef ELF_OBJ_ONLY
1777 if (file_type == TCC_OUTPUT_DLL &&
1778 s->sh_type == SHT_RELX &&
1779 !(s->sh_flags & SHF_ALLOC) &&
1780 (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
1781 prepare_dynamic_rel(s1, s)) {
1782 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1783 textrel = 1;
1784 } else
1785 #endif
1786 if ((s1->do_debug && s->sh_type != SHT_RELX) ||
1787 file_type == TCC_OUTPUT_OBJ ||
1788 (s->sh_flags & SHF_ALLOC) ||
1789 i == (s1->nb_sections - 1)
1790 #ifdef TCC_TARGET_ARM
1791 || s->sh_type == SHT_ARM_ATTRIBUTES
1792 #endif
1794 /* we output all sections if debug or object file */
1795 s->sh_size = s->data_offset;
1797 #ifdef TCC_TARGET_ARM
1798 /* XXX: Suppress stack unwinding section. */
1799 if (s->sh_type == SHT_ARM_EXIDX) {
1800 s->sh_flags = 0;
1801 s->sh_size = 0;
1803 #endif
1804 if (s->sh_size || (s->sh_flags & SHF_ALLOC))
1805 s->sh_name = put_elf_str(strsec, s->name);
1807 strsec->sh_size = strsec->data_offset;
1808 return textrel;
1811 /* Info to be copied in dynamic section */
1812 struct dyn_inf {
1813 Section *dynamic;
1814 Section *dynstr;
1815 unsigned long data_offset;
1816 addr_t rel_addr;
1817 addr_t rel_size;
1818 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1819 addr_t bss_addr;
1820 addr_t bss_size;
1821 #endif
1824 /* Assign sections to segments and decide how are sections laid out when loaded
1825 in memory. This function also fills corresponding program headers. */
1826 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1827 Section *interp, Section* strsec,
1828 struct dyn_inf *dyninf, int *sec_order)
1830 int i, j, k, file_type, sh_order_index, file_offset;
1831 unsigned long s_align;
1832 long long tmp;
1833 addr_t addr;
1834 ElfW(Phdr) *ph;
1835 Section *s;
1837 file_type = s1->output_type;
1838 sh_order_index = 1;
1839 file_offset = 0;
1840 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1841 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1842 s_align = ELF_PAGE_SIZE;
1843 if (s1->section_align)
1844 s_align = s1->section_align;
1846 if (phnum > 0) {
1847 if (s1->has_text_addr) {
1848 int a_offset, p_offset;
1849 addr = s1->text_addr;
1850 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1851 ELF_PAGE_SIZE */
1852 a_offset = (int) (addr & (s_align - 1));
1853 p_offset = file_offset & (s_align - 1);
1854 if (a_offset < p_offset)
1855 a_offset += s_align;
1856 file_offset += (a_offset - p_offset);
1857 } else {
1858 if (file_type == TCC_OUTPUT_DLL)
1859 addr = 0;
1860 else
1861 addr = ELF_START_ADDR;
1862 /* compute address after headers */
1863 addr += (file_offset & (s_align - 1));
1866 ph = &phdr[0];
1867 /* Leave one program headers for the program interpreter and one for
1868 the program header table itself if needed. These are done later as
1869 they require section layout to be done first. */
1870 if (interp)
1871 ph += 2;
1873 /* dynamic relocation table information, for .dynamic section */
1874 dyninf->rel_addr = dyninf->rel_size = 0;
1875 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1876 dyninf->bss_addr = dyninf->bss_size = 0;
1877 #endif
1879 for(j = 0; j < 2; j++) {
1880 ph->p_type = PT_LOAD;
1881 if (j == 0)
1882 ph->p_flags = PF_R | PF_X;
1883 else
1884 ph->p_flags = PF_R | PF_W;
1885 ph->p_align = s_align;
1887 /* Decide the layout of sections loaded in memory. This must
1888 be done before program headers are filled since they contain
1889 info about the layout. We do the following ordering: interp,
1890 symbol tables, relocations, progbits, nobits */
1891 /* XXX: do faster and simpler sorting */
1892 for(k = 0; k < 5; k++) {
1893 for(i = 1; i < s1->nb_sections; i++) {
1894 s = s1->sections[i];
1895 /* compute if section should be included */
1896 if (j == 0) {
1897 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1898 SHF_ALLOC)
1899 continue;
1900 } else {
1901 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1902 (SHF_ALLOC | SHF_WRITE))
1903 continue;
1905 if (s == interp) {
1906 if (k != 0)
1907 continue;
1908 } else if ((s->sh_type == SHT_DYNSYM ||
1909 s->sh_type == SHT_STRTAB ||
1910 s->sh_type == SHT_HASH)
1911 && !strstr(s->name, ".stab")) {
1912 if (k != 1)
1913 continue;
1914 } else if (s->sh_type == SHT_RELX) {
1915 if (k != 2)
1916 continue;
1917 } else if (s->sh_type == SHT_NOBITS) {
1918 if (k != 4)
1919 continue;
1920 } else {
1921 if (k != 3)
1922 continue;
1924 sec_order[sh_order_index++] = i;
1926 /* section matches: we align it and add its size */
1927 tmp = addr;
1928 addr = (addr + s->sh_addralign - 1) &
1929 ~(s->sh_addralign - 1);
1930 file_offset += (int) ( addr - tmp );
1931 s->sh_offset = file_offset;
1932 s->sh_addr = addr;
1934 /* update program header infos */
1935 if (ph->p_offset == 0) {
1936 ph->p_offset = file_offset;
1937 ph->p_vaddr = addr;
1938 ph->p_paddr = ph->p_vaddr;
1940 /* update dynamic relocation infos */
1941 if (s->sh_type == SHT_RELX) {
1942 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1943 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1944 dyninf->rel_addr = addr;
1945 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1947 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1948 dyninf->bss_addr = addr;
1949 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1951 #else
1952 if (dyninf->rel_size == 0)
1953 dyninf->rel_addr = addr;
1954 dyninf->rel_size += s->sh_size;
1955 #endif
1957 addr += s->sh_size;
1958 if (s->sh_type != SHT_NOBITS)
1959 file_offset += s->sh_size;
1962 if (j == 0) {
1963 /* Make the first PT_LOAD segment include the program
1964 headers itself (and the ELF header as well), it'll
1965 come out with same memory use but will make various
1966 tools like binutils strip work better. */
1967 ph->p_offset &= ~(ph->p_align - 1);
1968 ph->p_vaddr &= ~(ph->p_align - 1);
1969 ph->p_paddr &= ~(ph->p_align - 1);
1971 ph->p_filesz = file_offset - ph->p_offset;
1972 ph->p_memsz = addr - ph->p_vaddr;
1973 ph++;
1974 if (j == 0) {
1975 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1976 /* if in the middle of a page, we duplicate the page in
1977 memory so that one copy is RX and the other is RW */
1978 if ((addr & (s_align - 1)) != 0)
1979 addr += s_align;
1980 } else {
1981 addr = (addr + s_align - 1) & ~(s_align - 1);
1982 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1988 /* all other sections come after */
1989 for(i = 1; i < s1->nb_sections; i++) {
1990 s = s1->sections[i];
1991 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1992 continue;
1993 sec_order[sh_order_index++] = i;
1995 file_offset = (file_offset + s->sh_addralign - 1) &
1996 ~(s->sh_addralign - 1);
1997 s->sh_offset = file_offset;
1998 if (s->sh_type != SHT_NOBITS)
1999 file_offset += s->sh_size;
2002 return file_offset;
2005 #ifndef ELF_OBJ_ONLY
2006 /* put dynamic tag */
2007 static void put_dt(Section *dynamic, int dt, addr_t val)
2009 ElfW(Dyn) *dyn;
2010 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
2011 dyn->d_tag = dt;
2012 dyn->d_un.d_val = val;
2015 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
2016 Section *dynamic)
2018 ElfW(Phdr) *ph;
2020 /* if interpreter, then add corresponding program header */
2021 if (interp) {
2022 ph = &phdr[0];
2024 ph->p_type = PT_PHDR;
2025 ph->p_offset = sizeof(ElfW(Ehdr));
2026 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
2027 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
2028 ph->p_paddr = ph->p_vaddr;
2029 ph->p_flags = PF_R | PF_X;
2030 ph->p_align = 4; /* interp->sh_addralign; */
2031 ph++;
2033 ph->p_type = PT_INTERP;
2034 ph->p_offset = interp->sh_offset;
2035 ph->p_vaddr = interp->sh_addr;
2036 ph->p_paddr = ph->p_vaddr;
2037 ph->p_filesz = interp->sh_size;
2038 ph->p_memsz = interp->sh_size;
2039 ph->p_flags = PF_R;
2040 ph->p_align = interp->sh_addralign;
2043 /* if dynamic section, then add corresponding program header */
2044 if (dynamic) {
2045 ph = &phdr[phnum - 1];
2047 ph->p_type = PT_DYNAMIC;
2048 ph->p_offset = dynamic->sh_offset;
2049 ph->p_vaddr = dynamic->sh_addr;
2050 ph->p_paddr = ph->p_vaddr;
2051 ph->p_filesz = dynamic->sh_size;
2052 ph->p_memsz = dynamic->sh_size;
2053 ph->p_flags = PF_R | PF_W;
2054 ph->p_align = dynamic->sh_addralign;
2058 /* Fill the dynamic section with tags describing the address and size of
2059 sections */
2060 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2062 Section *dynamic = dyninf->dynamic;
2063 Section *s;
2065 /* put dynamic section entries */
2066 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2067 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2068 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2069 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2070 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2071 #if PTR_SIZE == 8
2072 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2073 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2074 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2075 #else
2076 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2077 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2078 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
2079 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2080 put_dt(dynamic, DT_PLTREL, DT_REL);
2081 put_dt(dynamic, DT_REL, dyninf->bss_addr);
2082 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
2083 #else
2084 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2085 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2086 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2087 #endif
2088 #endif
2089 if (versym_section)
2090 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2091 if (verneed_section) {
2092 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2093 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2095 s = find_section_create (s1, ".preinit_array", 0);
2096 if (s && s->data_offset) {
2097 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2098 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2100 s = find_section_create (s1, ".init_array", 0);
2101 if (s && s->data_offset) {
2102 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2103 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2105 s = find_section_create (s1, ".fini_array", 0);
2106 if (s && s->data_offset) {
2107 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2108 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2110 s = find_section_create (s1, ".init", 0);
2111 if (s && s->data_offset) {
2112 put_dt(dynamic, DT_INIT, s->sh_addr);
2114 s = find_section_create (s1, ".fini", 0);
2115 if (s && s->data_offset) {
2116 put_dt(dynamic, DT_FINI, s->sh_addr);
2118 if (s1->do_debug)
2119 put_dt(dynamic, DT_DEBUG, 0);
2120 put_dt(dynamic, DT_NULL, 0);
2123 /* Relocate remaining sections and symbols (that is those not related to
2124 dynamic linking) */
2125 static int final_sections_reloc(TCCState *s1)
2127 int i;
2128 Section *s;
2130 relocate_syms(s1, s1->symtab, 0);
2132 if (s1->nb_errors != 0)
2133 return -1;
2135 /* relocate sections */
2136 /* XXX: ignore sections with allocated relocations ? */
2137 for(i = 1; i < s1->nb_sections; i++) {
2138 s = s1->sections[i];
2139 if (s->reloc && (s != s1->got || s1->static_link))
2140 relocate_section(s1, s);
2143 /* relocate relocation entries if the relocation tables are
2144 allocated in the executable */
2145 for(i = 1; i < s1->nb_sections; i++) {
2146 s = s1->sections[i];
2147 if ((s->sh_flags & SHF_ALLOC) &&
2148 s->sh_type == SHT_RELX) {
2149 relocate_rel(s1, s);
2152 return 0;
2154 #endif
2156 /* Create an ELF file on disk.
2157 This function handle ELF specific layout requirements */
2158 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2159 int file_offset, int *sec_order)
2161 int i, shnum, offset, size, file_type;
2162 Section *s;
2163 ElfW(Ehdr) ehdr;
2164 ElfW(Shdr) shdr, *sh;
2166 file_type = s1->output_type;
2167 shnum = s1->nb_sections;
2169 memset(&ehdr, 0, sizeof(ehdr));
2171 if (phnum > 0) {
2172 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2173 ehdr.e_phnum = phnum;
2174 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2177 /* align to 4 */
2178 file_offset = (file_offset + 3) & -4;
2180 /* fill header */
2181 ehdr.e_ident[0] = ELFMAG0;
2182 ehdr.e_ident[1] = ELFMAG1;
2183 ehdr.e_ident[2] = ELFMAG2;
2184 ehdr.e_ident[3] = ELFMAG3;
2185 ehdr.e_ident[4] = ELFCLASSW;
2186 ehdr.e_ident[5] = ELFDATA2LSB;
2187 ehdr.e_ident[6] = EV_CURRENT;
2188 #if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
2189 /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
2190 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2191 #endif
2192 #ifdef TCC_TARGET_ARM
2193 #ifdef TCC_ARM_EABI
2194 ehdr.e_ident[EI_OSABI] = 0;
2195 ehdr.e_flags = EF_ARM_EABI_VER4;
2196 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2197 ehdr.e_flags |= EF_ARM_HASENTRY;
2198 if (s1->float_abi == ARM_HARD_FLOAT)
2199 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2200 else
2201 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2202 #else
2203 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2204 #endif
2205 #elif defined TCC_TARGET_RISCV64
2206 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2207 #endif
2208 switch(file_type) {
2209 default:
2210 case TCC_OUTPUT_EXE:
2211 ehdr.e_type = ET_EXEC;
2212 ehdr.e_entry = get_sym_addr(s1, "_start", 1, 0);
2213 break;
2214 case TCC_OUTPUT_DLL:
2215 ehdr.e_type = ET_DYN;
2216 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2217 break;
2218 case TCC_OUTPUT_OBJ:
2219 ehdr.e_type = ET_REL;
2220 break;
2222 ehdr.e_machine = EM_TCC_TARGET;
2223 ehdr.e_version = EV_CURRENT;
2224 ehdr.e_shoff = file_offset;
2225 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2226 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2227 ehdr.e_shnum = shnum;
2228 ehdr.e_shstrndx = shnum - 1;
2230 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2231 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2232 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2234 sort_syms(s1, symtab_section);
2235 for(i = 1; i < s1->nb_sections; i++) {
2236 s = s1->sections[sec_order[i]];
2237 if (s->sh_type != SHT_NOBITS) {
2238 while (offset < s->sh_offset) {
2239 fputc(0, f);
2240 offset++;
2242 size = s->sh_size;
2243 if (size)
2244 fwrite(s->data, 1, size, f);
2245 offset += size;
2249 /* output section headers */
2250 while (offset < ehdr.e_shoff) {
2251 fputc(0, f);
2252 offset++;
2255 for(i = 0; i < s1->nb_sections; i++) {
2256 sh = &shdr;
2257 memset(sh, 0, sizeof(ElfW(Shdr)));
2258 s = s1->sections[i];
2259 if (s) {
2260 sh->sh_name = s->sh_name;
2261 sh->sh_type = s->sh_type;
2262 sh->sh_flags = s->sh_flags;
2263 sh->sh_entsize = s->sh_entsize;
2264 sh->sh_info = s->sh_info;
2265 if (s->link)
2266 sh->sh_link = s->link->sh_num;
2267 sh->sh_addralign = s->sh_addralign;
2268 sh->sh_addr = s->sh_addr;
2269 sh->sh_offset = s->sh_offset;
2270 sh->sh_size = s->sh_size;
2272 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2276 /* Write an elf, coff or "binary" file */
2277 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2278 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2280 int fd, mode, file_type;
2281 FILE *f;
2283 file_type = s1->output_type;
2284 if (file_type == TCC_OUTPUT_OBJ)
2285 mode = 0666;
2286 else
2287 mode = 0777;
2288 unlink(filename);
2289 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2290 if (fd < 0) {
2291 tcc_error_noabort("could not write '%s'", filename);
2292 return -1;
2294 f = fdopen(fd, "wb");
2295 if (s1->verbose)
2296 printf("<- %s\n", filename);
2298 #ifdef TCC_TARGET_COFF
2299 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2300 tcc_output_coff(s1, f);
2301 else
2302 #endif
2303 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2304 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2305 else
2306 tcc_output_binary(s1, f, sec_order);
2307 fclose(f);
2309 return 0;
2312 #ifndef ELF_OBJ_ONLY
2313 /* Sort section headers by assigned sh_addr, remove sections
2314 that we aren't going to output. */
2315 static void tidy_section_headers(TCCState *s1, int *sec_order)
2317 int i, nnew, l, *backmap;
2318 Section **snew, *s;
2319 ElfW(Sym) *sym;
2321 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2322 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2323 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2324 s = s1->sections[sec_order[i]];
2325 if (!i || s->sh_name) {
2326 backmap[sec_order[i]] = nnew;
2327 snew[nnew] = s;
2328 ++nnew;
2329 } else {
2330 backmap[sec_order[i]] = 0;
2331 snew[--l] = s;
2334 for (i = 0; i < nnew; i++) {
2335 s = snew[i];
2336 if (s) {
2337 s->sh_num = i;
2338 if (s->sh_type == SHT_RELX)
2339 s->sh_info = backmap[s->sh_info];
2343 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2344 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2345 sym->st_shndx = backmap[sym->st_shndx];
2346 if( !s1->static_link ) {
2347 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2348 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2349 sym->st_shndx = backmap[sym->st_shndx];
2351 for (i = 0; i < s1->nb_sections; i++)
2352 sec_order[i] = i;
2353 tcc_free(s1->sections);
2354 s1->sections = snew;
2355 s1->nb_sections = nnew;
2356 tcc_free(backmap);
2358 #endif
2360 #ifdef TCC_TARGET_ARM
2361 static void create_arm_attribute_section(TCCState *s1)
2363 // Needed for DLL support.
2364 static const unsigned char arm_attr[] = {
2365 0x41, // 'A'
2366 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2367 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2368 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2369 0x05, 0x36, 0x00, // 'CPU_name', "6"
2370 0x06, 0x06, // 'CPU_arch', 'v6'
2371 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2372 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2373 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2374 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2375 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2376 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2377 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2378 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2379 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2380 0x1a, 0x02, // 'ABI_enum_size', 'int'
2381 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2382 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2384 Section *attr = new_section(s1, ".ARM.attributes", SHT_ARM_ATTRIBUTES, 0);
2385 unsigned char *ptr = section_ptr_add(attr, sizeof(arm_attr));
2386 attr->sh_addralign = 1;
2387 memcpy(ptr, arm_attr, sizeof(arm_attr));
2388 if (s1->float_abi != ARM_HARD_FLOAT) {
2389 ptr[26] = 0x00; // 'FP_arch', 'No'
2390 ptr[41] = 0x1e; // 'ABI_optimization_goals'
2391 ptr[42] = 0x06; // 'Aggressive Debug'
2394 #endif
2396 /* Output an elf, coff or binary file */
2397 /* XXX: suppress unneeded sections */
2398 static int elf_output_file(TCCState *s1, const char *filename)
2400 int ret, phnum, shnum, file_type, file_offset, *sec_order;
2401 struct dyn_inf dyninf = {0};
2402 ElfW(Phdr) *phdr;
2403 Section *strsec, *interp, *dynamic, *dynstr;
2405 #ifdef TCC_TARGET_ARM
2406 create_arm_attribute_section (s1);
2407 #endif
2409 file_type = s1->output_type;
2410 s1->nb_errors = 0;
2411 ret = -1;
2412 phdr = NULL;
2413 sec_order = NULL;
2414 interp = dynamic = dynstr = NULL; /* avoid warning */
2416 #ifndef ELF_OBJ_ONLY
2417 if (file_type != TCC_OUTPUT_OBJ) {
2418 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2419 tcc_add_runtime(s1);
2420 resolve_common_syms(s1);
2422 if (!s1->static_link) {
2423 if (file_type == TCC_OUTPUT_EXE) {
2424 char *ptr;
2425 /* allow override the dynamic loader */
2426 const char *elfint = getenv("LD_SO");
2427 if (elfint == NULL)
2428 elfint = DEFAULT_ELFINTERP(s1);
2429 /* add interpreter section only if executable */
2430 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2431 interp->sh_addralign = 1;
2432 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2433 strcpy(ptr, elfint);
2436 /* add dynamic symbol table */
2437 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2438 ".dynstr",
2439 ".hash", SHF_ALLOC);
2440 dynstr = s1->dynsym->link;
2441 /* add dynamic section */
2442 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2443 SHF_ALLOC | SHF_WRITE);
2444 dynamic->link = dynstr;
2445 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2447 build_got(s1);
2449 if (file_type == TCC_OUTPUT_EXE) {
2450 bind_exe_dynsyms(s1);
2451 if (s1->nb_errors)
2452 goto the_end;
2453 bind_libs_dynsyms(s1);
2454 } else {
2455 /* shared library case: simply export all global symbols */
2456 export_global_syms(s1);
2459 build_got_entries(s1);
2460 version_add (s1);
2462 #endif
2464 /* we add a section for symbols */
2465 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2466 put_elf_str(strsec, "");
2468 /* Allocate strings for section names */
2469 ret = alloc_sec_names(s1, file_type, strsec);
2471 #ifndef ELF_OBJ_ONLY
2472 if (dynamic) {
2473 int i;
2474 /* add a list of needed dlls */
2475 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2476 DLLReference *dllref = s1->loaded_dlls[i];
2477 if (dllref->level == 0)
2478 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2481 if (s1->rpath)
2482 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2483 put_elf_str(dynstr, s1->rpath));
2485 if (file_type == TCC_OUTPUT_DLL) {
2486 if (s1->soname)
2487 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2488 /* XXX: currently, since we do not handle PIC code, we
2489 must relocate the readonly segments */
2490 if (ret)
2491 put_dt(dynamic, DT_TEXTREL, 0);
2494 if (s1->symbolic)
2495 put_dt(dynamic, DT_SYMBOLIC, 0);
2497 dyninf.dynamic = dynamic;
2498 dyninf.dynstr = dynstr;
2499 /* remember offset and reserve space for 2nd call below */
2500 dyninf.data_offset = dynamic->data_offset;
2501 fill_dynamic(s1, &dyninf);
2502 dynamic->sh_size = dynamic->data_offset;
2503 dynstr->sh_size = dynstr->data_offset;
2505 #endif
2507 /* compute number of program headers */
2508 if (file_type == TCC_OUTPUT_OBJ)
2509 phnum = 0;
2510 else if (file_type == TCC_OUTPUT_DLL)
2511 phnum = 3;
2512 else if (s1->static_link)
2513 phnum = 2;
2514 else
2515 phnum = 5;
2517 /* allocate program segment headers */
2518 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2520 /* compute number of sections */
2521 shnum = s1->nb_sections;
2523 /* this array is used to reorder sections in the output file */
2524 sec_order = tcc_malloc(sizeof(int) * shnum);
2525 sec_order[0] = 0;
2527 /* compute section to program header mapping */
2528 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2529 sec_order);
2531 #ifndef ELF_OBJ_ONLY
2532 /* Fill remaining program header and finalize relocation related to dynamic
2533 linking. */
2534 if (file_type != TCC_OUTPUT_OBJ) {
2535 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2536 if (dynamic) {
2537 ElfW(Sym) *sym;
2538 dynamic->data_offset = dyninf.data_offset;
2539 fill_dynamic(s1, &dyninf);
2541 /* put in GOT the dynamic section address and relocate PLT */
2542 write32le(s1->got->data, dynamic->sh_addr);
2543 if (file_type == TCC_OUTPUT_EXE
2544 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2545 relocate_plt(s1);
2547 /* relocate symbols in .dynsym now that final addresses are known */
2548 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2549 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2550 /* do symbol relocation */
2551 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2556 /* if building executable or DLL, then relocate each section
2557 except the GOT which is already relocated */
2558 ret = final_sections_reloc(s1);
2559 if (ret)
2560 goto the_end;
2561 tidy_section_headers(s1, sec_order);
2563 /* Perform relocation to GOT or PLT entries */
2564 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2565 fill_got(s1);
2566 else if (s1->got)
2567 fill_local_got_entries(s1);
2569 #endif
2571 /* Create the ELF file with name 'filename' */
2572 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2573 s1->nb_sections = shnum;
2574 goto the_end;
2575 the_end:
2576 tcc_free(sec_order);
2577 tcc_free(phdr);
2578 return ret;
2581 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2583 int ret;
2584 #ifdef TCC_TARGET_PE
2585 if (s->output_type != TCC_OUTPUT_OBJ) {
2586 ret = pe_output_file(s, filename);
2587 } else
2588 #elif TCC_TARGET_MACHO
2589 if (s->output_type != TCC_OUTPUT_OBJ) {
2590 ret = macho_output_file(s, filename);
2591 } else
2592 #endif
2593 ret = elf_output_file(s, filename);
2594 return ret;
2597 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
2598 char *cbuf = buf;
2599 size_t rnum = 0;
2600 while (1) {
2601 ssize_t num = read(fd, cbuf, count-rnum);
2602 if (num < 0) return num;
2603 if (num == 0) return rnum;
2604 rnum += num;
2605 cbuf += num;
2609 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
2611 void *data;
2613 data = tcc_malloc(size);
2614 lseek(fd, file_offset, SEEK_SET);
2615 full_read(fd, data, size);
2616 return data;
2619 typedef struct SectionMergeInfo {
2620 Section *s; /* corresponding existing section */
2621 unsigned long offset; /* offset of the new section in the existing section */
2622 uint8_t new_section; /* true if section 's' was added */
2623 uint8_t link_once; /* true if link once section */
2624 } SectionMergeInfo;
2626 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2628 int size = full_read(fd, h, sizeof *h);
2629 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2630 if (h->e_type == ET_REL)
2631 return AFF_BINTYPE_REL;
2632 if (h->e_type == ET_DYN)
2633 return AFF_BINTYPE_DYN;
2634 } else if (size >= 8) {
2635 if (0 == memcmp(h, ARMAG, 8))
2636 return AFF_BINTYPE_AR;
2637 #ifdef TCC_TARGET_COFF
2638 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2639 return AFF_BINTYPE_C67;
2640 #endif
2642 return 0;
2645 /* load an object file and merge it with current files */
2646 /* XXX: handle correctly stab (debug) info */
2647 ST_FUNC int tcc_load_object_file(TCCState *s1,
2648 int fd, unsigned long file_offset)
2650 ElfW(Ehdr) ehdr;
2651 ElfW(Shdr) *shdr, *sh;
2652 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2653 char *strsec, *strtab;
2654 int stab_index, stabstr_index;
2655 int *old_to_new_syms;
2656 char *sh_name, *name;
2657 SectionMergeInfo *sm_table, *sm;
2658 ElfW(Sym) *sym, *symtab;
2659 ElfW_Rel *rel;
2660 Section *s;
2662 lseek(fd, file_offset, SEEK_SET);
2663 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2664 goto fail1;
2665 /* test CPU specific stuff */
2666 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2667 ehdr.e_machine != EM_TCC_TARGET) {
2668 fail1:
2669 tcc_error_noabort("invalid object file");
2670 return -1;
2672 /* read sections */
2673 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2674 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2675 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2677 /* load section names */
2678 sh = &shdr[ehdr.e_shstrndx];
2679 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2681 /* load symtab and strtab */
2682 old_to_new_syms = NULL;
2683 symtab = NULL;
2684 strtab = NULL;
2685 nb_syms = 0;
2686 seencompressed = 0;
2687 stab_index = stabstr_index = 0;
2689 for(i = 1; i < ehdr.e_shnum; i++) {
2690 sh = &shdr[i];
2691 if (sh->sh_type == SHT_SYMTAB) {
2692 if (symtab) {
2693 tcc_error_noabort("object must contain only one symtab");
2694 fail:
2695 ret = -1;
2696 goto the_end;
2698 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2699 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2700 sm_table[i].s = symtab_section;
2702 /* now load strtab */
2703 sh = &shdr[sh->sh_link];
2704 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2706 if (sh->sh_flags & SHF_COMPRESSED)
2707 seencompressed = 1;
2710 /* now examine each section and try to merge its content with the
2711 ones in memory */
2712 for(i = 1; i < ehdr.e_shnum; i++) {
2713 /* no need to examine section name strtab */
2714 if (i == ehdr.e_shstrndx)
2715 continue;
2716 sh = &shdr[i];
2717 if (sh->sh_type == SHT_RELX)
2718 sh = &shdr[sh->sh_info];
2719 /* ignore sections types we do not handle (plus relocs to those) */
2720 if (sh->sh_type != SHT_PROGBITS &&
2721 #ifdef TCC_ARM_EABI
2722 sh->sh_type != SHT_ARM_EXIDX &&
2723 #endif
2724 sh->sh_type != SHT_NOBITS &&
2725 sh->sh_type != SHT_PREINIT_ARRAY &&
2726 sh->sh_type != SHT_INIT_ARRAY &&
2727 sh->sh_type != SHT_FINI_ARRAY &&
2728 strcmp(strsec + sh->sh_name, ".stabstr")
2730 continue;
2731 if (seencompressed
2732 && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
2733 continue;
2735 sh = &shdr[i];
2736 sh_name = strsec + sh->sh_name;
2737 if (sh->sh_addralign < 1)
2738 sh->sh_addralign = 1;
2739 /* find corresponding section, if any */
2740 for(j = 1; j < s1->nb_sections;j++) {
2741 s = s1->sections[j];
2742 if (!strcmp(s->name, sh_name)) {
2743 if (!strncmp(sh_name, ".gnu.linkonce",
2744 sizeof(".gnu.linkonce") - 1)) {
2745 /* if a 'linkonce' section is already present, we
2746 do not add it again. It is a little tricky as
2747 symbols can still be defined in
2748 it. */
2749 sm_table[i].link_once = 1;
2750 goto next;
2752 if (stab_section) {
2753 if (s == stab_section)
2754 stab_index = i;
2755 if (s == stab_section->link)
2756 stabstr_index = i;
2758 goto found;
2761 /* not found: create new section */
2762 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2763 /* take as much info as possible from the section. sh_link and
2764 sh_info will be updated later */
2765 s->sh_addralign = sh->sh_addralign;
2766 s->sh_entsize = sh->sh_entsize;
2767 sm_table[i].new_section = 1;
2768 found:
2769 if (sh->sh_type != s->sh_type) {
2770 tcc_error_noabort("invalid section type");
2771 goto fail;
2773 /* align start of section */
2774 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
2775 if (sh->sh_addralign > s->sh_addralign)
2776 s->sh_addralign = sh->sh_addralign;
2777 sm_table[i].offset = s->data_offset;
2778 sm_table[i].s = s;
2779 /* concatenate sections */
2780 size = sh->sh_size;
2781 if (sh->sh_type != SHT_NOBITS) {
2782 unsigned char *ptr;
2783 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2784 ptr = section_ptr_add(s, size);
2785 full_read(fd, ptr, size);
2786 } else {
2787 s->data_offset += size;
2789 next: ;
2792 /* gr relocate stab strings */
2793 if (stab_index && stabstr_index) {
2794 Stab_Sym *a, *b;
2795 unsigned o;
2796 s = sm_table[stab_index].s;
2797 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2798 b = (Stab_Sym *)(s->data + s->data_offset);
2799 o = sm_table[stabstr_index].offset;
2800 while (a < b) {
2801 if (a->n_strx)
2802 a->n_strx += o;
2803 a++;
2807 /* second short pass to update sh_link and sh_info fields of new
2808 sections */
2809 for(i = 1; i < ehdr.e_shnum; i++) {
2810 s = sm_table[i].s;
2811 if (!s || !sm_table[i].new_section)
2812 continue;
2813 sh = &shdr[i];
2814 if (sh->sh_link > 0)
2815 s->link = sm_table[sh->sh_link].s;
2816 if (sh->sh_type == SHT_RELX) {
2817 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2818 /* update backward link */
2819 s1->sections[s->sh_info]->reloc = s;
2823 /* resolve symbols */
2824 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2826 sym = symtab + 1;
2827 for(i = 1; i < nb_syms; i++, sym++) {
2828 if (sym->st_shndx != SHN_UNDEF &&
2829 sym->st_shndx < SHN_LORESERVE) {
2830 sm = &sm_table[sym->st_shndx];
2831 if (sm->link_once) {
2832 /* if a symbol is in a link once section, we use the
2833 already defined symbol. It is very important to get
2834 correct relocations */
2835 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2836 name = strtab + sym->st_name;
2837 sym_index = find_elf_sym(symtab_section, name);
2838 if (sym_index)
2839 old_to_new_syms[i] = sym_index;
2841 continue;
2843 /* if no corresponding section added, no need to add symbol */
2844 if (!sm->s)
2845 continue;
2846 /* convert section number */
2847 sym->st_shndx = sm->s->sh_num;
2848 /* offset value */
2849 sym->st_value += sm->offset;
2851 /* add symbol */
2852 name = strtab + sym->st_name;
2853 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2854 sym->st_info, sym->st_other,
2855 sym->st_shndx, name);
2856 old_to_new_syms[i] = sym_index;
2859 /* third pass to patch relocation entries */
2860 for(i = 1; i < ehdr.e_shnum; i++) {
2861 s = sm_table[i].s;
2862 if (!s)
2863 continue;
2864 sh = &shdr[i];
2865 offset = sm_table[i].offset;
2866 switch(s->sh_type) {
2867 case SHT_RELX:
2868 /* take relocation offset information */
2869 offseti = sm_table[sh->sh_info].offset;
2870 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2871 int type;
2872 unsigned sym_index;
2873 /* convert symbol index */
2874 type = ELFW(R_TYPE)(rel->r_info);
2875 sym_index = ELFW(R_SYM)(rel->r_info);
2876 /* NOTE: only one symtab assumed */
2877 if (sym_index >= nb_syms)
2878 goto invalid_reloc;
2879 sym_index = old_to_new_syms[sym_index];
2880 /* ignore link_once in rel section. */
2881 if (!sym_index && !sm_table[sh->sh_info].link_once
2882 #ifdef TCC_TARGET_ARM
2883 && type != R_ARM_V4BX
2884 #elif defined TCC_TARGET_RISCV64
2885 && type != R_RISCV_ALIGN
2886 && type != R_RISCV_RELAX
2887 #endif
2889 invalid_reloc:
2890 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2891 i, strsec + sh->sh_name, (int)rel->r_offset);
2892 goto fail;
2894 rel->r_info = ELFW(R_INFO)(sym_index, type);
2895 /* offset the relocation offset */
2896 rel->r_offset += offseti;
2897 #ifdef TCC_TARGET_ARM
2898 /* Jumps and branches from a Thumb code to a PLT entry need
2899 special handling since PLT entries are ARM code.
2900 Unconditional bl instructions referencing PLT entries are
2901 handled by converting these instructions into blx
2902 instructions. Other case of instructions referencing a PLT
2903 entry require to add a Thumb stub before the PLT entry to
2904 switch to ARM mode. We set bit plt_thumb_stub of the
2905 attribute of a symbol to indicate such a case. */
2906 if (type == R_ARM_THM_JUMP24)
2907 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2908 #endif
2910 break;
2911 default:
2912 break;
2916 ret = 0;
2917 the_end:
2918 tcc_free(symtab);
2919 tcc_free(strtab);
2920 tcc_free(old_to_new_syms);
2921 tcc_free(sm_table);
2922 tcc_free(strsec);
2923 tcc_free(shdr);
2924 return ret;
2927 typedef struct ArchiveHeader {
2928 char ar_name[16]; /* name of this member */
2929 char ar_date[12]; /* file mtime */
2930 char ar_uid[6]; /* owner uid; printed as decimal */
2931 char ar_gid[6]; /* owner gid; printed as decimal */
2932 char ar_mode[8]; /* file mode, printed as octal */
2933 char ar_size[10]; /* file size, printed as decimal */
2934 char ar_fmag[2]; /* should contain ARFMAG */
2935 } ArchiveHeader;
2937 #define ARFMAG "`\n"
2939 static unsigned long long get_be(const uint8_t *b, int n)
2941 unsigned long long ret = 0;
2942 while (n)
2943 ret = (ret << 8) | *b++, --n;
2944 return ret;
2947 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
2949 char *p, *e;
2950 int len;
2951 lseek(fd, offset, SEEK_SET);
2952 len = full_read(fd, hdr, sizeof(ArchiveHeader));
2953 if (len != sizeof(ArchiveHeader))
2954 return len ? -1 : 0;
2955 p = hdr->ar_name;
2956 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
2957 --e;
2958 *e = '\0';
2959 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
2960 return len;
2963 /* load only the objects which resolve undefined symbols */
2964 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2966 int i, bound, nsyms, sym_index, len, ret = -1;
2967 unsigned long long off;
2968 uint8_t *data;
2969 const char *ar_names, *p;
2970 const uint8_t *ar_index;
2971 ElfW(Sym) *sym;
2972 ArchiveHeader hdr;
2974 data = tcc_malloc(size);
2975 if (full_read(fd, data, size) != size)
2976 goto the_end;
2977 nsyms = get_be(data, entrysize);
2978 ar_index = data + entrysize;
2979 ar_names = (char *) ar_index + nsyms * entrysize;
2981 do {
2982 bound = 0;
2983 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2984 Section *s = symtab_section;
2985 sym_index = find_elf_sym(s, p);
2986 if (!sym_index)
2987 continue;
2988 sym = &((ElfW(Sym) *)s->data)[sym_index];
2989 if(sym->st_shndx != SHN_UNDEF)
2990 continue;
2991 off = get_be(ar_index + i * entrysize, entrysize);
2992 len = read_ar_header(fd, off, &hdr);
2993 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
2994 tcc_error_noabort("invalid archive");
2995 goto the_end;
2997 off += len;
2998 if (s1->verbose == 2)
2999 printf(" -> %s\n", hdr.ar_name);
3000 if (tcc_load_object_file(s1, fd, off) < 0)
3001 goto the_end;
3002 ++bound;
3004 } while(bound);
3005 ret = 0;
3006 the_end:
3007 tcc_free(data);
3008 return ret;
3011 /* load a '.a' file */
3012 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
3014 ArchiveHeader hdr;
3015 /* char magic[8]; */
3016 int size, len;
3017 unsigned long file_offset;
3018 ElfW(Ehdr) ehdr;
3020 /* skip magic which was already checked */
3021 /* full_read(fd, magic, sizeof(magic)); */
3022 file_offset = sizeof ARMAG - 1;
3024 for(;;) {
3025 len = read_ar_header(fd, file_offset, &hdr);
3026 if (len == 0)
3027 return 0;
3028 if (len < 0) {
3029 tcc_error_noabort("invalid archive");
3030 return -1;
3032 file_offset += len;
3033 size = strtol(hdr.ar_size, NULL, 0);
3034 /* align to even */
3035 size = (size + 1) & ~1;
3036 if (alacarte) {
3037 /* coff symbol table : we handle it */
3038 if (!strcmp(hdr.ar_name, "/"))
3039 return tcc_load_alacarte(s1, fd, size, 4);
3040 if (!strcmp(hdr.ar_name, "/SYM64/"))
3041 return tcc_load_alacarte(s1, fd, size, 8);
3042 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3043 if (s1->verbose == 2)
3044 printf(" -> %s\n", hdr.ar_name);
3045 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3046 return -1;
3048 file_offset += size;
3052 #ifndef ELF_OBJ_ONLY
3053 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3054 LV, maybe create a new entry for (LIB,VERSION). */
3055 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3057 while (i >= *n) {
3058 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3059 (*lv)[(*n)++] = -1;
3061 if ((*lv)[i] == -1) {
3062 int v, prev_same_lib = -1;
3063 for (v = 0; v < nb_sym_versions; v++) {
3064 if (strcmp(sym_versions[v].lib, lib))
3065 continue;
3066 prev_same_lib = v;
3067 if (!strcmp(sym_versions[v].version, version))
3068 break;
3070 if (v == nb_sym_versions) {
3071 sym_versions = tcc_realloc (sym_versions,
3072 (v + 1) * sizeof(*sym_versions));
3073 sym_versions[v].lib = tcc_strdup(lib);
3074 sym_versions[v].version = tcc_strdup(version);
3075 sym_versions[v].out_index = 0;
3076 sym_versions[v].prev_same_lib = prev_same_lib;
3077 nb_sym_versions++;
3079 (*lv)[i] = v;
3083 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3084 VERNDX. */
3085 static void
3086 set_sym_version(TCCState *s1, int sym_index, int verndx)
3088 if (sym_index >= nb_sym_to_version) {
3089 int newelems = sym_index ? sym_index * 2 : 1;
3090 sym_to_version = tcc_realloc(sym_to_version,
3091 newelems * sizeof(*sym_to_version));
3092 memset(sym_to_version + nb_sym_to_version, -1,
3093 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3094 nb_sym_to_version = newelems;
3096 if (sym_to_version[sym_index] < 0)
3097 sym_to_version[sym_index] = verndx;
3100 struct versym_info {
3101 int nb_versyms;
3102 ElfW(Verdef) *verdef;
3103 ElfW(Verneed) *verneed;
3104 ElfW(Half) *versym;
3105 int nb_local_ver, *local_ver;
3109 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3111 char *lib, *version;
3112 uint32_t next;
3113 int i;
3115 #define DEBUG_VERSION 0
3117 if (v->versym && v->verdef) {
3118 ElfW(Verdef) *vdef = v->verdef;
3119 lib = NULL;
3120 do {
3121 ElfW(Verdaux) *verdaux =
3122 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3124 #if DEBUG_VERSION
3125 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3126 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3127 vdef->vd_hash);
3128 #endif
3129 if (vdef->vd_cnt) {
3130 version = dynstr + verdaux->vda_name;
3132 if (lib == NULL)
3133 lib = version;
3134 else
3135 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3136 lib, version);
3137 #if DEBUG_VERSION
3138 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3139 #endif
3141 next = vdef->vd_next;
3142 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3143 } while (next);
3145 if (v->versym && v->verneed) {
3146 ElfW(Verneed) *vneed = v->verneed;
3147 do {
3148 ElfW(Vernaux) *vernaux =
3149 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3151 lib = dynstr + vneed->vn_file;
3152 #if DEBUG_VERSION
3153 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3154 #endif
3155 for (i = 0; i < vneed->vn_cnt; i++) {
3156 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3157 version = dynstr + vernaux->vna_name;
3158 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3159 lib, version);
3160 #if DEBUG_VERSION
3161 printf (" vernaux(%u): %u %u %s\n",
3162 vernaux->vna_other, vernaux->vna_hash,
3163 vernaux->vna_flags, version);
3164 #endif
3166 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3168 next = vneed->vn_next;
3169 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3170 } while (next);
3173 #if DEBUG_VERSION
3174 for (i = 0; i < v->nb_local_ver; i++) {
3175 if (v->local_ver[i] > 0) {
3176 printf ("%d: lib: %s, version %s\n",
3177 i, sym_versions[v->local_ver[i]].lib,
3178 sym_versions[v->local_ver[i]].version);
3181 #endif
3184 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3185 is referenced by the user (so it should be added as DT_NEEDED in
3186 the generated ELF file) */
3187 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3189 ElfW(Ehdr) ehdr;
3190 ElfW(Shdr) *shdr, *sh, *sh1;
3191 int i, j, nb_syms, nb_dts, sym_bind, ret;
3192 ElfW(Sym) *sym, *dynsym;
3193 ElfW(Dyn) *dt, *dynamic;
3195 char *dynstr;
3196 int sym_index;
3197 const char *name, *soname;
3198 DLLReference *dllref;
3199 struct versym_info v;
3201 full_read(fd, &ehdr, sizeof(ehdr));
3203 /* test CPU specific stuff */
3204 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3205 ehdr.e_machine != EM_TCC_TARGET) {
3206 tcc_error_noabort("bad architecture");
3207 return -1;
3210 /* read sections */
3211 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3213 /* load dynamic section and dynamic symbols */
3214 nb_syms = 0;
3215 nb_dts = 0;
3216 dynamic = NULL;
3217 dynsym = NULL; /* avoid warning */
3218 dynstr = NULL; /* avoid warning */
3219 memset(&v, 0, sizeof v);
3221 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3222 switch(sh->sh_type) {
3223 case SHT_DYNAMIC:
3224 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3225 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3226 break;
3227 case SHT_DYNSYM:
3228 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3229 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3230 sh1 = &shdr[sh->sh_link];
3231 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3232 break;
3233 case SHT_GNU_verdef:
3234 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3235 break;
3236 case SHT_GNU_verneed:
3237 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3238 break;
3239 case SHT_GNU_versym:
3240 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3241 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3242 break;
3243 default:
3244 break;
3248 /* compute the real library name */
3249 soname = tcc_basename(filename);
3251 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3252 if (dt->d_tag == DT_SONAME) {
3253 soname = dynstr + dt->d_un.d_val;
3257 /* if the dll is already loaded, do not load it */
3258 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3259 dllref = s1->loaded_dlls[i];
3260 if (!strcmp(soname, dllref->name)) {
3261 /* but update level if needed */
3262 if (level < dllref->level)
3263 dllref->level = level;
3264 ret = 0;
3265 goto the_end;
3269 if (v.nb_versyms != nb_syms)
3270 tcc_free (v.versym), v.versym = NULL;
3271 else
3272 store_version(s1, &v, dynstr);
3274 /* add the dll and its level */
3275 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
3276 dllref->level = level;
3277 strcpy(dllref->name, soname);
3278 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
3280 /* add dynamic symbols in dynsym_section */
3281 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3282 sym_bind = ELFW(ST_BIND)(sym->st_info);
3283 if (sym_bind == STB_LOCAL)
3284 continue;
3285 name = dynstr + sym->st_name;
3286 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3287 sym->st_info, sym->st_other, sym->st_shndx, name);
3288 if (v.versym) {
3289 ElfW(Half) vsym = v.versym[i];
3290 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3291 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3295 /* load all referenced DLLs */
3296 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3297 switch(dt->d_tag) {
3298 case DT_NEEDED:
3299 name = dynstr + dt->d_un.d_val;
3300 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3301 dllref = s1->loaded_dlls[j];
3302 if (!strcmp(name, dllref->name))
3303 goto already_loaded;
3305 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3306 tcc_error_noabort("referenced dll '%s' not found", name);
3307 ret = -1;
3308 goto the_end;
3310 already_loaded:
3311 break;
3314 ret = 0;
3315 the_end:
3316 tcc_free(dynstr);
3317 tcc_free(dynsym);
3318 tcc_free(dynamic);
3319 tcc_free(shdr);
3320 tcc_free(v.local_ver);
3321 tcc_free(v.verdef);
3322 tcc_free(v.verneed);
3323 tcc_free(v.versym);
3324 return ret;
3327 #define LD_TOK_NAME 256
3328 #define LD_TOK_EOF (-1)
3330 static int ld_inp(TCCState *s1)
3332 char b;
3333 if (s1->cc != -1) {
3334 int c = s1->cc;
3335 s1->cc = -1;
3336 return c;
3338 if (1 == read(s1->fd, &b, 1))
3339 return b;
3340 return CH_EOF;
3343 /* return next ld script token */
3344 static int ld_next(TCCState *s1, char *name, int name_size)
3346 int c, d, ch;
3347 char *q;
3349 redo:
3350 ch = ld_inp(s1);
3351 switch(ch) {
3352 case ' ':
3353 case '\t':
3354 case '\f':
3355 case '\v':
3356 case '\r':
3357 case '\n':
3358 goto redo;
3359 case '/':
3360 ch = ld_inp(s1);
3361 if (ch == '*') { /* comment */
3362 for (d = 0;; d = ch) {
3363 ch = ld_inp(s1);
3364 if (ch == CH_EOF || (ch == '/' && d == '*'))
3365 break;
3367 goto redo;
3368 } else {
3369 q = name;
3370 *q++ = '/';
3371 goto parse_name;
3373 break;
3374 case '\\':
3375 /* case 'a' ... 'z': */
3376 case 'a':
3377 case 'b':
3378 case 'c':
3379 case 'd':
3380 case 'e':
3381 case 'f':
3382 case 'g':
3383 case 'h':
3384 case 'i':
3385 case 'j':
3386 case 'k':
3387 case 'l':
3388 case 'm':
3389 case 'n':
3390 case 'o':
3391 case 'p':
3392 case 'q':
3393 case 'r':
3394 case 's':
3395 case 't':
3396 case 'u':
3397 case 'v':
3398 case 'w':
3399 case 'x':
3400 case 'y':
3401 case 'z':
3402 /* case 'A' ... 'z': */
3403 case 'A':
3404 case 'B':
3405 case 'C':
3406 case 'D':
3407 case 'E':
3408 case 'F':
3409 case 'G':
3410 case 'H':
3411 case 'I':
3412 case 'J':
3413 case 'K':
3414 case 'L':
3415 case 'M':
3416 case 'N':
3417 case 'O':
3418 case 'P':
3419 case 'Q':
3420 case 'R':
3421 case 'S':
3422 case 'T':
3423 case 'U':
3424 case 'V':
3425 case 'W':
3426 case 'X':
3427 case 'Y':
3428 case 'Z':
3429 case '_':
3430 case '.':
3431 case '$':
3432 case '~':
3433 q = name;
3434 parse_name:
3435 for(;;) {
3436 if (!((ch >= 'a' && ch <= 'z') ||
3437 (ch >= 'A' && ch <= 'Z') ||
3438 (ch >= '0' && ch <= '9') ||
3439 strchr("/.-_+=$:\\,~", ch)))
3440 break;
3441 if ((q - name) < name_size - 1) {
3442 *q++ = ch;
3444 ch = ld_inp(s1);
3446 s1->cc = ch;
3447 *q = '\0';
3448 c = LD_TOK_NAME;
3449 break;
3450 case CH_EOF:
3451 c = LD_TOK_EOF;
3452 break;
3453 default:
3454 c = ch;
3455 break;
3457 return c;
3460 static int ld_add_file(TCCState *s1, const char filename[])
3462 if (filename[0] == '/') {
3463 if (CONFIG_SYSROOT[0] == '\0'
3464 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3465 return 0;
3466 filename = tcc_basename(filename);
3468 return tcc_add_dll(s1, filename, 0);
3471 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3473 char filename[1024], libname[1024];
3474 int t, group, nblibs = 0, ret = 0;
3475 char **libs = NULL;
3477 group = !strcmp(cmd, "GROUP");
3478 if (!as_needed)
3479 s1->new_undef_sym = 0;
3480 t = ld_next(s1, filename, sizeof(filename));
3481 if (t != '(') {
3482 tcc_error_noabort("( expected");
3483 ret = -1;
3484 goto lib_parse_error;
3486 t = ld_next(s1, filename, sizeof(filename));
3487 for(;;) {
3488 libname[0] = '\0';
3489 if (t == LD_TOK_EOF) {
3490 tcc_error_noabort("unexpected end of file");
3491 ret = -1;
3492 goto lib_parse_error;
3493 } else if (t == ')') {
3494 break;
3495 } else if (t == '-') {
3496 t = ld_next(s1, filename, sizeof(filename));
3497 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3498 tcc_error_noabort("library name expected");
3499 ret = -1;
3500 goto lib_parse_error;
3502 pstrcpy(libname, sizeof libname, &filename[1]);
3503 if (s1->static_link) {
3504 snprintf(filename, sizeof filename, "lib%s.a", libname);
3505 } else {
3506 snprintf(filename, sizeof filename, "lib%s.so", libname);
3508 } else if (t != LD_TOK_NAME) {
3509 tcc_error_noabort("filename expected");
3510 ret = -1;
3511 goto lib_parse_error;
3513 if (!strcmp(filename, "AS_NEEDED")) {
3514 ret = ld_add_file_list(s1, cmd, 1);
3515 if (ret)
3516 goto lib_parse_error;
3517 } else {
3518 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3519 if (!as_needed) {
3520 ret = ld_add_file(s1, filename);
3521 if (ret)
3522 goto lib_parse_error;
3523 if (group) {
3524 /* Add the filename *and* the libname to avoid future conversions */
3525 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3526 if (libname[0] != '\0')
3527 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3531 t = ld_next(s1, filename, sizeof(filename));
3532 if (t == ',') {
3533 t = ld_next(s1, filename, sizeof(filename));
3536 if (group && !as_needed) {
3537 while (s1->new_undef_sym) {
3538 int i;
3539 s1->new_undef_sym = 0;
3540 for (i = 0; i < nblibs; i ++)
3541 ld_add_file(s1, libs[i]);
3544 lib_parse_error:
3545 dynarray_reset(&libs, &nblibs);
3546 return ret;
3549 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3550 files */
3551 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3553 char cmd[64];
3554 char filename[1024];
3555 int t, ret;
3557 s1->fd = fd;
3558 s1->cc = -1;
3559 for(;;) {
3560 t = ld_next(s1, cmd, sizeof(cmd));
3561 if (t == LD_TOK_EOF)
3562 return 0;
3563 else if (t != LD_TOK_NAME)
3564 return -1;
3565 if (!strcmp(cmd, "INPUT") ||
3566 !strcmp(cmd, "GROUP")) {
3567 ret = ld_add_file_list(s1, cmd, 0);
3568 if (ret)
3569 return ret;
3570 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3571 !strcmp(cmd, "TARGET")) {
3572 /* ignore some commands */
3573 t = ld_next(s1, cmd, sizeof(cmd));
3574 if (t != '(') {
3575 tcc_error_noabort("( expected");
3576 return -1;
3578 for(;;) {
3579 t = ld_next(s1, filename, sizeof(filename));
3580 if (t == LD_TOK_EOF) {
3581 tcc_error_noabort("unexpected end of file");
3582 return -1;
3583 } else if (t == ')') {
3584 break;
3587 } else {
3588 return -1;
3591 return 0;
3593 #endif /* !ELF_OBJ_ONLY */