macos: add path relative ../lib
[tinycc.git] / tccelf.c
blobebbd15f230dbd7d4a85ac837fd99a497e80fb6a8
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 ElfW_Rel *rel;
1033 for_each_elem(sr, 0, rel, ElfW_Rel) {
1034 int sym_index = ELFW(R_SYM)(rel->r_info);
1035 int type = ELFW(R_TYPE)(rel->r_info);
1036 switch(type) {
1037 #if defined(TCC_TARGET_I386)
1038 case R_386_32:
1039 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
1040 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
1041 /* don't fixup unresolved (weak) symbols */
1042 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
1043 break;
1045 #elif defined(TCC_TARGET_X86_64)
1046 case R_X86_64_32:
1047 case R_X86_64_32S:
1048 case R_X86_64_64:
1049 #endif
1050 count++;
1051 break;
1052 #if defined(TCC_TARGET_I386)
1053 case R_386_PC32:
1054 #elif defined(TCC_TARGET_X86_64)
1055 case R_X86_64_PC32:
1056 #endif
1057 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1058 count++;
1059 break;
1060 default:
1061 break;
1064 if (count) {
1065 /* allocate the section */
1066 sr->sh_flags |= SHF_ALLOC;
1067 sr->sh_size = count * sizeof(ElfW_Rel);
1069 #endif
1070 return count;
1072 #endif
1074 #if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE)
1075 static void build_got(TCCState *s1)
1077 /* if no got, then create it */
1078 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1079 s1->got->sh_entsize = 4;
1080 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1081 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1082 /* keep space for _DYNAMIC pointer and two dummy got entries */
1083 section_ptr_add(s1->got, 3 * PTR_SIZE);
1086 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1087 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1088 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1089 Returns the offset of the GOT or (if any) PLT entry. */
1090 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1091 int sym_index)
1093 int need_plt_entry;
1094 const char *name;
1095 ElfW(Sym) *sym;
1096 struct sym_attr *attr;
1097 unsigned got_offset;
1098 char plt_name[100];
1099 int len;
1101 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1102 attr = get_sym_attr(s1, sym_index, 1);
1104 /* In case a function is both called and its address taken 2 GOT entries
1105 are created, one for taking the address (GOT) and the other for the PLT
1106 entry (PLTGOT). */
1107 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1108 return attr;
1110 /* create the GOT entry */
1111 got_offset = s1->got->data_offset;
1112 section_ptr_add(s1->got, PTR_SIZE);
1114 /* Create the GOT relocation that will insert the address of the object or
1115 function of interest in the GOT entry. This is a static relocation for
1116 memory output (dlsym will give us the address of symbols) and dynamic
1117 relocation otherwise (executable and DLLs). The relocation should be
1118 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1119 associated to a PLT entry) but is currently done at load time for an
1120 unknown reason. */
1122 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1123 name = (char *) symtab_section->link->data + sym->st_name;
1125 if (s1->dynsym) {
1126 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1127 /* Hack alarm. We don't want to emit dynamic symbols
1128 and symbol based relocs for STB_LOCAL symbols, but rather
1129 want to resolve them directly. At this point the symbol
1130 values aren't final yet, so we must defer this. We will later
1131 have to create a RELATIVE reloc anyway, so we misuse the
1132 relocation slot to smuggle the symbol reference until
1133 fill_local_got_entries. Not that the sym_index is
1134 relative to symtab_section, not s1->dynsym! Nevertheless
1135 we use s1->dyn_sym so that if this is the first call
1136 that got->reloc is correctly created. Also note that
1137 RELATIVE relocs are not normally created for the .got,
1138 so the types serves as a marker for later (and is retained
1139 also for the final output, which is okay because then the
1140 got is just normal data). */
1141 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1142 sym_index);
1143 } else {
1144 if (0 == attr->dyn_index)
1145 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1146 sym->st_size, sym->st_info, 0,
1147 sym->st_shndx, name);
1148 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
1149 attr->dyn_index);
1151 } else {
1152 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1153 sym_index);
1156 if (need_plt_entry) {
1157 if (!s1->plt) {
1158 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1159 SHF_ALLOC | SHF_EXECINSTR);
1160 s1->plt->sh_entsize = 4;
1163 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1165 /* create a symbol 'sym@plt' for the PLT jump vector */
1166 len = strlen(name);
1167 if (len > sizeof plt_name - 5)
1168 len = sizeof plt_name - 5;
1169 memcpy(plt_name, name, len);
1170 strcpy(plt_name + len, "@plt");
1171 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
1172 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1174 } else {
1175 attr->got_offset = got_offset;
1178 return attr;
1181 /* build GOT and PLT entries */
1182 ST_FUNC void build_got_entries(TCCState *s1)
1184 Section *s;
1185 ElfW_Rel *rel;
1186 ElfW(Sym) *sym;
1187 int i, type, gotplt_entry, reloc_type, sym_index;
1188 struct sym_attr *attr;
1190 for(i = 1; i < s1->nb_sections; i++) {
1191 s = s1->sections[i];
1192 if (s->sh_type != SHT_RELX)
1193 continue;
1194 /* no need to handle got relocations */
1195 if (s->link != symtab_section)
1196 continue;
1197 for_each_elem(s, 0, rel, ElfW_Rel) {
1198 type = ELFW(R_TYPE)(rel->r_info);
1199 gotplt_entry = gotplt_entry_type(type);
1200 if (gotplt_entry == -1)
1201 tcc_error ("Unknown relocation type for got: %d", type);
1202 sym_index = ELFW(R_SYM)(rel->r_info);
1203 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1205 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1206 continue;
1209 /* Automatically create PLT/GOT [entry] if it is an undefined
1210 reference (resolved at runtime), or the symbol is absolute,
1211 probably created by tcc_add_symbol, and thus on 64-bit
1212 targets might be too far from application code. */
1213 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1214 if (sym->st_shndx == SHN_UNDEF) {
1215 ElfW(Sym) *esym;
1216 int dynindex;
1217 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1218 continue;
1219 /* Relocations for UNDEF symbols would normally need
1220 to be transferred into the executable or shared object.
1221 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1222 But TCC doesn't do that (at least for exes), so we
1223 need to resolve all such relocs locally. And that
1224 means PLT slots for functions in DLLs and COPY relocs for
1225 data symbols. COPY relocs were generated in
1226 bind_exe_dynsyms (and the symbol adjusted to be defined),
1227 and for functions we were generated a dynamic symbol
1228 of function type. */
1229 if (s1->dynsym) {
1230 /* dynsym isn't set for -run :-/ */
1231 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1232 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1233 if (dynindex
1234 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1235 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1236 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1237 goto jmp_slot;
1239 } else if (!(sym->st_shndx == SHN_ABS
1240 #ifndef TCC_TARGET_ARM
1241 && PTR_SIZE == 8
1242 #endif
1244 continue;
1247 #ifdef TCC_TARGET_X86_64
1248 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1249 sym->st_shndx != SHN_UNDEF &&
1250 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1251 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1252 s1->output_type == TCC_OUTPUT_EXE)) {
1253 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1254 continue;
1256 #endif
1257 reloc_type = code_reloc(type);
1258 if (reloc_type == -1)
1259 tcc_error ("Unknown relocation type: %d", type);
1260 else if (reloc_type != 0) {
1261 jmp_slot:
1262 reloc_type = R_JMP_SLOT;
1263 } else
1264 reloc_type = R_GLOB_DAT;
1266 if (!s1->got)
1267 build_got(s1);
1269 if (gotplt_entry == BUILD_GOT_ONLY)
1270 continue;
1272 attr = put_got_entry(s1, reloc_type, sym_index);
1274 if (reloc_type == R_JMP_SLOT)
1275 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1279 #endif
1281 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
1283 int shn = sec ? sec->sh_num : offs ? SHN_ABS : SHN_UNDEF;
1284 if (sec && offs == -1)
1285 offs = sec->data_offset;
1286 return set_elf_sym(symtab_section, offs, 0,
1287 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1290 static void add_init_array_defines(TCCState *s1, const char *section_name)
1292 Section *s;
1293 addr_t end_offset;
1294 char buf[1024];
1295 s = find_section(s1, section_name);
1296 if (!s) {
1297 end_offset = 0;
1298 s = data_section;
1299 } else {
1300 end_offset = s->data_offset;
1302 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1303 set_global_sym(s1, buf, s, 0);
1304 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1305 set_global_sym(s1, buf, s, end_offset);
1308 #ifndef TCC_TARGET_PE
1309 static int tcc_add_support(TCCState *s1, const char *filename)
1311 char buf[1024];
1312 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1313 return tcc_add_file(s1, buf);
1315 #endif
1317 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1319 Section *s;
1320 s = find_section(s1, sec);
1321 s->sh_flags |= SHF_WRITE;
1322 #ifndef TCC_TARGET_PE
1323 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1324 #endif
1325 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1326 section_ptr_add(s, PTR_SIZE);
1329 #ifdef CONFIG_TCC_BCHECK
1330 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1332 if (0 == s1->do_bounds_check)
1333 return;
1334 section_ptr_add(bounds_section, sizeof(addr_t));
1336 #endif
1338 #ifdef CONFIG_TCC_BACKTRACE
1339 static void put_ptr(TCCState *s1, Section *s, int offs)
1341 int c;
1342 c = set_global_sym(s1, NULL, s, offs);
1343 s = data_section;
1344 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1345 section_ptr_add(s, PTR_SIZE);
1348 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1349 a dynamic symbol to allow so's to have one each with a different value. */
1350 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1352 int c = find_elf_sym(s1->symtab, name);
1353 if (c) {
1354 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1355 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1356 esym->st_value = offset;
1357 esym->st_shndx = s->sh_num;
1361 ST_FUNC void tcc_add_btstub(TCCState *s1)
1363 Section *s;
1364 int n, o;
1365 CString cstr;
1367 s = data_section;
1368 o = s->data_offset;
1369 /* create (part of) a struct rt_context (see tccrun.c) */
1370 put_ptr(s1, stab_section, 0);
1371 put_ptr(s1, stab_section, -1);
1372 put_ptr(s1, stab_section->link, 0);
1373 section_ptr_add(s, 3 * PTR_SIZE);
1374 /* prog_base */
1375 #ifndef TCC_TARGET_MACHO
1376 /* XXX this relocation is wrong, it uses sym-index 0 (local,undef) */
1377 put_elf_reloc(s1->symtab, s, s->data_offset, R_DATA_PTR, 0);
1378 #endif
1379 section_ptr_add(s, PTR_SIZE);
1380 n = 2 * PTR_SIZE;
1381 #ifdef CONFIG_TCC_BCHECK
1382 if (s1->do_bounds_check) {
1383 put_ptr(s1, bounds_section, 0);
1384 n -= PTR_SIZE;
1386 #endif
1387 section_ptr_add(s, n);
1389 cstr_new(&cstr);
1390 cstr_printf(&cstr,
1391 " extern void __bt_init(),*__rt_info[],__bt_init_dll();"
1392 "__attribute__((constructor)) static void __bt_init_rt(){");
1393 #ifdef TCC_TARGET_PE
1394 if (s1->output_type == TCC_OUTPUT_DLL)
1395 #ifdef CONFIG_TCC_BCHECK
1396 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1397 #else
1398 cstr_printf(&cstr, "__bt_init_dll(0);");
1399 #endif
1400 #endif
1401 cstr_printf(&cstr, "__bt_init(__rt_info,%d, 0);}",
1402 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1403 tcc_compile_string(s1, cstr.data);
1404 cstr_free(&cstr);
1405 set_local_sym(s1, &"___rt_info"[!s1->leading_underscore], s, o);
1407 #endif
1409 #ifndef TCC_TARGET_PE
1410 /* add tcc runtime libraries */
1411 ST_FUNC void tcc_add_runtime(TCCState *s1)
1413 s1->filetype = 0;
1414 #ifdef CONFIG_TCC_BCHECK
1415 tcc_add_bcheck(s1);
1416 #endif
1417 tcc_add_pragma_libs(s1);
1418 /* add libc */
1419 if (!s1->nostdlib) {
1420 if (s1->option_pthread)
1421 tcc_add_library_err(s1, "pthread");
1422 tcc_add_library_err(s1, "c");
1423 #ifdef TCC_LIBGCC
1424 if (!s1->static_link) {
1425 if (TCC_LIBGCC[0] == '/')
1426 tcc_add_file(s1, TCC_LIBGCC);
1427 else
1428 tcc_add_dll(s1, TCC_LIBGCC, 0);
1430 #endif
1431 #ifdef CONFIG_TCC_BCHECK
1432 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1433 tcc_add_library_err(s1, "pthread");
1434 tcc_add_library_err(s1, "dl");
1435 tcc_add_support(s1, "bcheck.o");
1437 #endif
1438 #ifdef CONFIG_TCC_BACKTRACE
1439 if (s1->do_backtrace) {
1440 if (s1->output_type == TCC_OUTPUT_EXE)
1441 tcc_add_support(s1, "bt-exe.o");
1442 if (s1->output_type != TCC_OUTPUT_DLL)
1443 tcc_add_support(s1, "bt-log.o");
1444 if (s1->output_type != TCC_OUTPUT_MEMORY)
1445 tcc_add_btstub(s1);
1447 #endif
1448 tcc_add_support(s1, TCC_LIBTCC1);
1449 #ifndef TCC_TARGET_MACHO
1450 /* add crt end if not memory output */
1451 if (s1->output_type != TCC_OUTPUT_MEMORY)
1452 tcc_add_crt(s1, "crtn.o");
1453 #endif
1456 #endif
1458 /* add various standard linker symbols (must be done after the
1459 sections are filled (for example after allocating common
1460 symbols)) */
1461 static void tcc_add_linker_symbols(TCCState *s1)
1463 char buf[1024];
1464 int i;
1465 Section *s;
1467 set_global_sym(s1, "_etext", text_section, -1);
1468 set_global_sym(s1, "_edata", data_section, -1);
1469 set_global_sym(s1, "_end", bss_section, -1);
1470 #ifdef TCC_TARGET_RISCV64
1471 /* XXX should be .sdata+0x800, not .data+0x800 */
1472 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1473 #endif
1474 /* horrible new standard ldscript defines */
1475 add_init_array_defines(s1, ".preinit_array");
1476 add_init_array_defines(s1, ".init_array");
1477 add_init_array_defines(s1, ".fini_array");
1478 /* add start and stop symbols for sections whose name can be
1479 expressed in C */
1480 for(i = 1; i < s1->nb_sections; i++) {
1481 s = s1->sections[i];
1482 if ((s->sh_flags & SHF_ALLOC)
1483 && (s->sh_type == SHT_PROGBITS
1484 || s->sh_type == SHT_STRTAB)) {
1485 const char *p;
1486 /* check if section name can be expressed in C */
1487 p = s->name;
1488 for(;;) {
1489 int c = *p;
1490 if (!c)
1491 break;
1492 if (!isid(c) && !isnum(c))
1493 goto next_sec;
1494 p++;
1496 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1497 set_global_sym(s1, buf, s, 0);
1498 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1499 set_global_sym(s1, buf, s, -1);
1501 next_sec: ;
1505 ST_FUNC void resolve_common_syms(TCCState *s1)
1507 ElfW(Sym) *sym;
1509 /* Allocate common symbols in BSS. */
1510 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1511 if (sym->st_shndx == SHN_COMMON) {
1512 /* symbol alignment is in st_value for SHN_COMMONs */
1513 sym->st_value = section_add(bss_section, sym->st_size,
1514 sym->st_value);
1515 sym->st_shndx = bss_section->sh_num;
1519 /* Now assign linker provided symbols their value. */
1520 tcc_add_linker_symbols(s1);
1523 static void tcc_output_binary(TCCState *s1, FILE *f,
1524 const int *sec_order)
1526 Section *s;
1527 int i, offset, size;
1529 offset = 0;
1530 for(i=1;i<s1->nb_sections;i++) {
1531 s = s1->sections[sec_order[i]];
1532 if (s->sh_type != SHT_NOBITS &&
1533 (s->sh_flags & SHF_ALLOC)) {
1534 while (offset < s->sh_offset) {
1535 fputc(0, f);
1536 offset++;
1538 size = s->sh_size;
1539 fwrite(s->data, 1, size, f);
1540 offset += size;
1545 #ifndef ELF_OBJ_ONLY
1546 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1548 int sym_index = ELFW(R_SYM) (rel->r_info);
1549 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1550 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1551 unsigned offset = attr->got_offset;
1553 if (0 == offset)
1554 return;
1555 section_reserve(s1->got, offset + PTR_SIZE);
1556 #ifdef TCC_TARGET_X86_64
1557 write64le(s1->got->data + offset, sym->st_value);
1558 #else
1559 write32le(s1->got->data + offset, sym->st_value);
1560 #endif
1563 /* Perform relocation to GOT or PLT entries */
1564 ST_FUNC void fill_got(TCCState *s1)
1566 Section *s;
1567 ElfW_Rel *rel;
1568 int i;
1570 for(i = 1; i < s1->nb_sections; i++) {
1571 s = s1->sections[i];
1572 if (s->sh_type != SHT_RELX)
1573 continue;
1574 /* no need to handle got relocations */
1575 if (s->link != symtab_section)
1576 continue;
1577 for_each_elem(s, 0, rel, ElfW_Rel) {
1578 switch (ELFW(R_TYPE) (rel->r_info)) {
1579 case R_X86_64_GOT32:
1580 case R_X86_64_GOTPCREL:
1581 case R_X86_64_GOTPCRELX:
1582 case R_X86_64_REX_GOTPCRELX:
1583 case R_X86_64_PLT32:
1584 fill_got_entry(s1, rel);
1585 break;
1591 /* See put_got_entry for a description. This is the second stage
1592 where GOT references to local defined symbols are rewritten. */
1593 static void fill_local_got_entries(TCCState *s1)
1595 ElfW_Rel *rel;
1596 if (!s1->got->reloc)
1597 return;
1598 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1599 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1600 int sym_index = ELFW(R_SYM) (rel->r_info);
1601 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1602 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1603 unsigned offset = attr->got_offset;
1604 if (offset != rel->r_offset - s1->got->sh_addr)
1605 tcc_error_noabort("huh");
1606 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1607 #if SHT_RELX == SHT_RELA
1608 rel->r_addend = sym->st_value;
1609 #else
1610 /* All our REL architectures also happen to be 32bit LE. */
1611 write32le(s1->got->data + offset, sym->st_value);
1612 #endif
1617 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1618 in shared libraries and export non local defined symbols to shared libraries
1619 if -rdynamic switch was given on command line */
1620 static void bind_exe_dynsyms(TCCState *s1)
1622 const char *name;
1623 int sym_index, index;
1624 ElfW(Sym) *sym, *esym;
1625 int type;
1627 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1628 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1629 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1630 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1631 if (sym->st_shndx == SHN_UNDEF) {
1632 name = (char *) symtab_section->link->data + sym->st_name;
1633 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1634 if (sym_index) {
1635 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1636 type = ELFW(ST_TYPE)(esym->st_info);
1637 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1638 /* Indirect functions shall have STT_FUNC type in executable
1639 * dynsym section. Indeed, a dlsym call following a lazy
1640 * resolution would pick the symbol value from the
1641 * executable dynsym entry which would contain the address
1642 * of the function wanted by the caller of dlsym instead of
1643 * the address of the function that would return that
1644 * address */
1645 int dynindex
1646 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1647 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1648 name);
1649 int index = sym - (ElfW(Sym) *) symtab_section->data;
1650 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1651 } else if (type == STT_OBJECT) {
1652 unsigned long offset;
1653 ElfW(Sym) *dynsym;
1654 offset = bss_section->data_offset;
1655 /* XXX: which alignment ? */
1656 offset = (offset + 16 - 1) & -16;
1657 set_elf_sym (s1->symtab, offset, esym->st_size,
1658 esym->st_info, 0, bss_section->sh_num, name);
1659 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1660 esym->st_info, 0, bss_section->sh_num,
1661 name);
1663 /* Ensure R_COPY works for weak symbol aliases */
1664 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1665 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1666 if ((dynsym->st_value == esym->st_value)
1667 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1668 char *dynname = (char *) s1->dynsymtab_section->link->data
1669 + dynsym->st_name;
1670 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1671 dynsym->st_info, 0,
1672 bss_section->sh_num, dynname);
1673 break;
1678 put_elf_reloc(s1->dynsym, bss_section,
1679 offset, R_COPY, index);
1680 offset += esym->st_size;
1681 bss_section->data_offset = offset;
1683 } else {
1684 /* STB_WEAK undefined symbols are accepted */
1685 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1686 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1687 !strcmp(name, "_fp_hw")) {
1688 } else {
1689 tcc_error_noabort("undefined symbol '%s'", name);
1692 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1693 /* if -rdynamic option, then export all non local symbols */
1694 name = (char *) symtab_section->link->data + sym->st_name;
1695 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1696 0, sym->st_shndx, name);
1701 /* Bind symbols of libraries: export all non local symbols of executable that
1702 are referenced by shared libraries. The reason is that the dynamic loader
1703 search symbol first in executable and then in libraries. Therefore a
1704 reference to a symbol already defined by a library can still be resolved by
1705 a symbol in the executable. */
1706 static void bind_libs_dynsyms(TCCState *s1)
1708 const char *name;
1709 int sym_index;
1710 ElfW(Sym) *sym, *esym;
1712 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1713 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1714 sym_index = find_elf_sym(symtab_section, name);
1715 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1716 if (sym_index && sym->st_shndx != SHN_UNDEF
1717 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1718 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1719 sym->st_info, 0, sym->st_shndx, name);
1720 } else if (esym->st_shndx == SHN_UNDEF) {
1721 /* weak symbols can stay undefined */
1722 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1723 tcc_warning("undefined dynamic symbol '%s'", name);
1728 /* Export all non local symbols. This is used by shared libraries so that the
1729 non local symbols they define can resolve a reference in another shared
1730 library or in the executable. Correspondingly, it allows undefined local
1731 symbols to be resolved by other shared libraries or by the executable. */
1732 static void export_global_syms(TCCState *s1)
1734 int dynindex, index;
1735 const char *name;
1736 ElfW(Sym) *sym;
1738 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1739 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1740 name = (char *) symtab_section->link->data + sym->st_name;
1741 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1742 sym->st_info, 0, sym->st_shndx, name);
1743 index = sym - (ElfW(Sym) *) symtab_section->data;
1744 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1748 #endif
1750 /* Allocate strings for section names and decide if an unallocated section
1751 should be output.
1752 NOTE: the strsec section comes last, so its size is also correct ! */
1753 static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1755 int i;
1756 Section *s;
1757 int textrel = 0;
1759 /* Allocate strings for section names */
1760 for(i = 1; i < s1->nb_sections; i++) {
1761 s = s1->sections[i];
1762 /* when generating a DLL, we include relocations but we may
1763 patch them */
1764 #ifndef ELF_OBJ_ONLY
1765 if (file_type == TCC_OUTPUT_DLL &&
1766 s->sh_type == SHT_RELX &&
1767 !(s->sh_flags & SHF_ALLOC) &&
1768 (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
1769 prepare_dynamic_rel(s1, s)) {
1770 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1771 textrel = 1;
1772 } else
1773 #endif
1774 if ((s1->do_debug && s->sh_type != SHT_RELX) ||
1775 file_type == TCC_OUTPUT_OBJ ||
1776 (s->sh_flags & SHF_ALLOC) ||
1777 i == (s1->nb_sections - 1)) {
1778 /* we output all sections if debug or object file */
1779 s->sh_size = s->data_offset;
1781 if (s->sh_size || (s->sh_flags & SHF_ALLOC))
1782 s->sh_name = put_elf_str(strsec, s->name);
1784 strsec->sh_size = strsec->data_offset;
1785 return textrel;
1788 /* Info to be copied in dynamic section */
1789 struct dyn_inf {
1790 Section *dynamic;
1791 Section *dynstr;
1792 unsigned long data_offset;
1793 addr_t rel_addr;
1794 addr_t rel_size;
1795 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1796 addr_t bss_addr;
1797 addr_t bss_size;
1798 #endif
1801 /* Assign sections to segments and decide how are sections laid out when loaded
1802 in memory. This function also fills corresponding program headers. */
1803 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1804 Section *interp, Section* strsec,
1805 struct dyn_inf *dyninf, int *sec_order)
1807 int i, j, k, file_type, sh_order_index, file_offset;
1808 unsigned long s_align;
1809 long long tmp;
1810 addr_t addr;
1811 ElfW(Phdr) *ph;
1812 Section *s;
1814 file_type = s1->output_type;
1815 sh_order_index = 1;
1816 file_offset = 0;
1817 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1818 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1819 s_align = ELF_PAGE_SIZE;
1820 if (s1->section_align)
1821 s_align = s1->section_align;
1823 if (phnum > 0) {
1824 if (s1->has_text_addr) {
1825 int a_offset, p_offset;
1826 addr = s1->text_addr;
1827 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1828 ELF_PAGE_SIZE */
1829 a_offset = (int) (addr & (s_align - 1));
1830 p_offset = file_offset & (s_align - 1);
1831 if (a_offset < p_offset)
1832 a_offset += s_align;
1833 file_offset += (a_offset - p_offset);
1834 } else {
1835 if (file_type == TCC_OUTPUT_DLL)
1836 addr = 0;
1837 else
1838 addr = ELF_START_ADDR;
1839 /* compute address after headers */
1840 addr += (file_offset & (s_align - 1));
1843 ph = &phdr[0];
1844 /* Leave one program headers for the program interpreter and one for
1845 the program header table itself if needed. These are done later as
1846 they require section layout to be done first. */
1847 if (interp)
1848 ph += 2;
1850 /* dynamic relocation table information, for .dynamic section */
1851 dyninf->rel_addr = dyninf->rel_size = 0;
1852 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1853 dyninf->bss_addr = dyninf->bss_size = 0;
1854 #endif
1856 for(j = 0; j < 2; j++) {
1857 ph->p_type = PT_LOAD;
1858 if (j == 0)
1859 ph->p_flags = PF_R | PF_X;
1860 else
1861 ph->p_flags = PF_R | PF_W;
1862 ph->p_align = s_align;
1864 /* Decide the layout of sections loaded in memory. This must
1865 be done before program headers are filled since they contain
1866 info about the layout. We do the following ordering: interp,
1867 symbol tables, relocations, progbits, nobits */
1868 /* XXX: do faster and simpler sorting */
1869 for(k = 0; k < 5; k++) {
1870 for(i = 1; i < s1->nb_sections; i++) {
1871 s = s1->sections[i];
1872 /* compute if section should be included */
1873 if (j == 0) {
1874 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1875 SHF_ALLOC)
1876 continue;
1877 } else {
1878 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1879 (SHF_ALLOC | SHF_WRITE))
1880 continue;
1882 if (s == interp) {
1883 if (k != 0)
1884 continue;
1885 } else if ((s->sh_type == SHT_DYNSYM ||
1886 s->sh_type == SHT_STRTAB ||
1887 s->sh_type == SHT_HASH)
1888 && !strstr(s->name, ".stab")) {
1889 if (k != 1)
1890 continue;
1891 } else if (s->sh_type == SHT_RELX) {
1892 if (k != 2)
1893 continue;
1894 } else if (s->sh_type == SHT_NOBITS) {
1895 if (k != 4)
1896 continue;
1897 } else {
1898 if (k != 3)
1899 continue;
1901 sec_order[sh_order_index++] = i;
1903 /* section matches: we align it and add its size */
1904 tmp = addr;
1905 addr = (addr + s->sh_addralign - 1) &
1906 ~(s->sh_addralign - 1);
1907 file_offset += (int) ( addr - tmp );
1908 s->sh_offset = file_offset;
1909 s->sh_addr = addr;
1911 /* update program header infos */
1912 if (ph->p_offset == 0) {
1913 ph->p_offset = file_offset;
1914 ph->p_vaddr = addr;
1915 ph->p_paddr = ph->p_vaddr;
1917 /* update dynamic relocation infos */
1918 if (s->sh_type == SHT_RELX) {
1919 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1920 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1921 dyninf->rel_addr = addr;
1922 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1924 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1925 dyninf->bss_addr = addr;
1926 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1928 #else
1929 if (dyninf->rel_size == 0)
1930 dyninf->rel_addr = addr;
1931 dyninf->rel_size += s->sh_size;
1932 #endif
1934 addr += s->sh_size;
1935 if (s->sh_type != SHT_NOBITS)
1936 file_offset += s->sh_size;
1939 if (j == 0) {
1940 /* Make the first PT_LOAD segment include the program
1941 headers itself (and the ELF header as well), it'll
1942 come out with same memory use but will make various
1943 tools like binutils strip work better. */
1944 ph->p_offset &= ~(ph->p_align - 1);
1945 ph->p_vaddr &= ~(ph->p_align - 1);
1946 ph->p_paddr &= ~(ph->p_align - 1);
1948 ph->p_filesz = file_offset - ph->p_offset;
1949 ph->p_memsz = addr - ph->p_vaddr;
1950 ph++;
1951 if (j == 0) {
1952 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1953 /* if in the middle of a page, we duplicate the page in
1954 memory so that one copy is RX and the other is RW */
1955 if ((addr & (s_align - 1)) != 0)
1956 addr += s_align;
1957 } else {
1958 addr = (addr + s_align - 1) & ~(s_align - 1);
1959 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1965 /* all other sections come after */
1966 for(i = 1; i < s1->nb_sections; i++) {
1967 s = s1->sections[i];
1968 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1969 continue;
1970 sec_order[sh_order_index++] = i;
1972 file_offset = (file_offset + s->sh_addralign - 1) &
1973 ~(s->sh_addralign - 1);
1974 s->sh_offset = file_offset;
1975 if (s->sh_type != SHT_NOBITS)
1976 file_offset += s->sh_size;
1979 return file_offset;
1982 #ifndef ELF_OBJ_ONLY
1983 /* put dynamic tag */
1984 static void put_dt(Section *dynamic, int dt, addr_t val)
1986 ElfW(Dyn) *dyn;
1987 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1988 dyn->d_tag = dt;
1989 dyn->d_un.d_val = val;
1992 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1993 Section *dynamic)
1995 ElfW(Phdr) *ph;
1997 /* if interpreter, then add corresponding program header */
1998 if (interp) {
1999 ph = &phdr[0];
2001 ph->p_type = PT_PHDR;
2002 ph->p_offset = sizeof(ElfW(Ehdr));
2003 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
2004 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
2005 ph->p_paddr = ph->p_vaddr;
2006 ph->p_flags = PF_R | PF_X;
2007 ph->p_align = 4; /* interp->sh_addralign; */
2008 ph++;
2010 ph->p_type = PT_INTERP;
2011 ph->p_offset = interp->sh_offset;
2012 ph->p_vaddr = interp->sh_addr;
2013 ph->p_paddr = ph->p_vaddr;
2014 ph->p_filesz = interp->sh_size;
2015 ph->p_memsz = interp->sh_size;
2016 ph->p_flags = PF_R;
2017 ph->p_align = interp->sh_addralign;
2020 /* if dynamic section, then add corresponding program header */
2021 if (dynamic) {
2022 ph = &phdr[phnum - 1];
2024 ph->p_type = PT_DYNAMIC;
2025 ph->p_offset = dynamic->sh_offset;
2026 ph->p_vaddr = dynamic->sh_addr;
2027 ph->p_paddr = ph->p_vaddr;
2028 ph->p_filesz = dynamic->sh_size;
2029 ph->p_memsz = dynamic->sh_size;
2030 ph->p_flags = PF_R | PF_W;
2031 ph->p_align = dynamic->sh_addralign;
2035 /* Fill the dynamic section with tags describing the address and size of
2036 sections */
2037 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2039 Section *dynamic = dyninf->dynamic;
2040 Section *s;
2042 /* put dynamic section entries */
2043 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2044 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2045 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2046 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2047 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2048 #if PTR_SIZE == 8
2049 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2050 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2051 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2052 #else
2053 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2054 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2055 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
2056 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2057 put_dt(dynamic, DT_PLTREL, DT_REL);
2058 put_dt(dynamic, DT_REL, dyninf->bss_addr);
2059 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
2060 #else
2061 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2062 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2063 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2064 #endif
2065 #endif
2066 if (versym_section)
2067 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2068 if (verneed_section) {
2069 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2070 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2072 s = find_section_create (s1, ".preinit_array", 0);
2073 if (s && s->data_offset) {
2074 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2075 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2077 s = find_section_create (s1, ".init_array", 0);
2078 if (s && s->data_offset) {
2079 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2080 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2082 s = find_section_create (s1, ".fini_array", 0);
2083 if (s && s->data_offset) {
2084 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2085 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2087 s = find_section_create (s1, ".init", 0);
2088 if (s && s->data_offset) {
2089 put_dt(dynamic, DT_INIT, s->sh_addr);
2091 s = find_section_create (s1, ".fini", 0);
2092 if (s && s->data_offset) {
2093 put_dt(dynamic, DT_FINI, s->sh_addr);
2095 if (s1->do_debug)
2096 put_dt(dynamic, DT_DEBUG, 0);
2097 put_dt(dynamic, DT_NULL, 0);
2100 /* Relocate remaining sections and symbols (that is those not related to
2101 dynamic linking) */
2102 static int final_sections_reloc(TCCState *s1)
2104 int i;
2105 Section *s;
2107 relocate_syms(s1, s1->symtab, 0);
2109 if (s1->nb_errors != 0)
2110 return -1;
2112 /* relocate sections */
2113 /* XXX: ignore sections with allocated relocations ? */
2114 for(i = 1; i < s1->nb_sections; i++) {
2115 s = s1->sections[i];
2116 if (s->reloc && (s != s1->got || s1->static_link))
2117 relocate_section(s1, s);
2120 /* relocate relocation entries if the relocation tables are
2121 allocated in the executable */
2122 for(i = 1; i < s1->nb_sections; i++) {
2123 s = s1->sections[i];
2124 if ((s->sh_flags & SHF_ALLOC) &&
2125 s->sh_type == SHT_RELX) {
2126 relocate_rel(s1, s);
2129 return 0;
2131 #endif
2133 /* Create an ELF file on disk.
2134 This function handle ELF specific layout requirements */
2135 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2136 int file_offset, int *sec_order)
2138 int i, shnum, offset, size, file_type;
2139 Section *s;
2140 ElfW(Ehdr) ehdr;
2141 ElfW(Shdr) shdr, *sh;
2143 file_type = s1->output_type;
2144 shnum = s1->nb_sections;
2146 memset(&ehdr, 0, sizeof(ehdr));
2148 if (phnum > 0) {
2149 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2150 ehdr.e_phnum = phnum;
2151 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2154 /* align to 4 */
2155 file_offset = (file_offset + 3) & -4;
2157 /* fill header */
2158 ehdr.e_ident[0] = ELFMAG0;
2159 ehdr.e_ident[1] = ELFMAG1;
2160 ehdr.e_ident[2] = ELFMAG2;
2161 ehdr.e_ident[3] = ELFMAG3;
2162 ehdr.e_ident[4] = ELFCLASSW;
2163 ehdr.e_ident[5] = ELFDATA2LSB;
2164 ehdr.e_ident[6] = EV_CURRENT;
2165 #if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
2166 /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
2167 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2168 #endif
2169 #ifdef TCC_TARGET_ARM
2170 #ifdef TCC_ARM_EABI
2171 ehdr.e_ident[EI_OSABI] = 0;
2172 ehdr.e_flags = EF_ARM_EABI_VER4;
2173 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2174 ehdr.e_flags |= EF_ARM_HASENTRY;
2175 if (s1->float_abi == ARM_HARD_FLOAT)
2176 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2177 else
2178 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2179 #else
2180 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2181 #endif
2182 #elif defined TCC_TARGET_RISCV64
2183 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2184 #endif
2185 switch(file_type) {
2186 default:
2187 case TCC_OUTPUT_EXE:
2188 ehdr.e_type = ET_EXEC;
2189 ehdr.e_entry = get_sym_addr(s1, "_start", 1, 0);
2190 break;
2191 case TCC_OUTPUT_DLL:
2192 ehdr.e_type = ET_DYN;
2193 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2194 break;
2195 case TCC_OUTPUT_OBJ:
2196 ehdr.e_type = ET_REL;
2197 break;
2199 ehdr.e_machine = EM_TCC_TARGET;
2200 ehdr.e_version = EV_CURRENT;
2201 ehdr.e_shoff = file_offset;
2202 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2203 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2204 ehdr.e_shnum = shnum;
2205 ehdr.e_shstrndx = shnum - 1;
2207 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2208 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2209 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2211 sort_syms(s1, symtab_section);
2212 for(i = 1; i < s1->nb_sections; i++) {
2213 s = s1->sections[sec_order[i]];
2214 if (s->sh_type != SHT_NOBITS) {
2215 while (offset < s->sh_offset) {
2216 fputc(0, f);
2217 offset++;
2219 size = s->sh_size;
2220 if (size)
2221 fwrite(s->data, 1, size, f);
2222 offset += size;
2226 /* output section headers */
2227 while (offset < ehdr.e_shoff) {
2228 fputc(0, f);
2229 offset++;
2232 for(i = 0; i < s1->nb_sections; i++) {
2233 sh = &shdr;
2234 memset(sh, 0, sizeof(ElfW(Shdr)));
2235 s = s1->sections[i];
2236 if (s) {
2237 sh->sh_name = s->sh_name;
2238 sh->sh_type = s->sh_type;
2239 sh->sh_flags = s->sh_flags;
2240 sh->sh_entsize = s->sh_entsize;
2241 sh->sh_info = s->sh_info;
2242 if (s->link)
2243 sh->sh_link = s->link->sh_num;
2244 sh->sh_addralign = s->sh_addralign;
2245 sh->sh_addr = s->sh_addr;
2246 sh->sh_offset = s->sh_offset;
2247 sh->sh_size = s->sh_size;
2249 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2253 /* Write an elf, coff or "binary" file */
2254 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2255 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2257 int fd, mode, file_type;
2258 FILE *f;
2260 file_type = s1->output_type;
2261 if (file_type == TCC_OUTPUT_OBJ)
2262 mode = 0666;
2263 else
2264 mode = 0777;
2265 unlink(filename);
2266 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2267 if (fd < 0) {
2268 tcc_error_noabort("could not write '%s'", filename);
2269 return -1;
2271 f = fdopen(fd, "wb");
2272 if (s1->verbose)
2273 printf("<- %s\n", filename);
2275 #ifdef TCC_TARGET_COFF
2276 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2277 tcc_output_coff(s1, f);
2278 else
2279 #endif
2280 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2281 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2282 else
2283 tcc_output_binary(s1, f, sec_order);
2284 fclose(f);
2286 return 0;
2289 #ifndef ELF_OBJ_ONLY
2290 /* Sort section headers by assigned sh_addr, remove sections
2291 that we aren't going to output. */
2292 static void tidy_section_headers(TCCState *s1, int *sec_order)
2294 int i, nnew, l, *backmap;
2295 Section **snew, *s;
2296 ElfW(Sym) *sym;
2298 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2299 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2300 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2301 s = s1->sections[sec_order[i]];
2302 if (!i || s->sh_name) {
2303 backmap[sec_order[i]] = nnew;
2304 snew[nnew] = s;
2305 ++nnew;
2306 } else {
2307 backmap[sec_order[i]] = 0;
2308 snew[--l] = s;
2311 for (i = 0; i < nnew; i++) {
2312 s = snew[i];
2313 if (s) {
2314 s->sh_num = i;
2315 if (s->sh_type == SHT_RELX)
2316 s->sh_info = backmap[s->sh_info];
2320 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2321 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2322 sym->st_shndx = backmap[sym->st_shndx];
2323 if( !s1->static_link ) {
2324 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2325 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2326 sym->st_shndx = backmap[sym->st_shndx];
2328 for (i = 0; i < s1->nb_sections; i++)
2329 sec_order[i] = i;
2330 tcc_free(s1->sections);
2331 s1->sections = snew;
2332 s1->nb_sections = nnew;
2333 tcc_free(backmap);
2335 #endif
2337 /* Output an elf, coff or binary file */
2338 /* XXX: suppress unneeded sections */
2339 static int elf_output_file(TCCState *s1, const char *filename)
2341 int ret, phnum, shnum, file_type, file_offset, *sec_order;
2342 struct dyn_inf dyninf = {0};
2343 ElfW(Phdr) *phdr;
2344 Section *strsec, *interp, *dynamic, *dynstr;
2346 file_type = s1->output_type;
2347 s1->nb_errors = 0;
2348 ret = -1;
2349 phdr = NULL;
2350 sec_order = NULL;
2351 interp = dynamic = dynstr = NULL; /* avoid warning */
2353 #ifndef ELF_OBJ_ONLY
2354 if (file_type != TCC_OUTPUT_OBJ) {
2355 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2356 tcc_add_runtime(s1);
2357 resolve_common_syms(s1);
2359 if (!s1->static_link) {
2360 if (file_type == TCC_OUTPUT_EXE) {
2361 char *ptr;
2362 /* allow override the dynamic loader */
2363 const char *elfint = getenv("LD_SO");
2364 if (elfint == NULL)
2365 elfint = DEFAULT_ELFINTERP(s1);
2366 /* add interpreter section only if executable */
2367 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2368 interp->sh_addralign = 1;
2369 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2370 strcpy(ptr, elfint);
2373 /* add dynamic symbol table */
2374 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2375 ".dynstr",
2376 ".hash", SHF_ALLOC);
2377 dynstr = s1->dynsym->link;
2378 /* add dynamic section */
2379 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2380 SHF_ALLOC | SHF_WRITE);
2381 dynamic->link = dynstr;
2382 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2384 build_got(s1);
2386 if (file_type == TCC_OUTPUT_EXE) {
2387 bind_exe_dynsyms(s1);
2388 if (s1->nb_errors)
2389 goto the_end;
2390 bind_libs_dynsyms(s1);
2391 } else {
2392 /* shared library case: simply export all global symbols */
2393 export_global_syms(s1);
2396 build_got_entries(s1);
2397 version_add (s1);
2399 #endif
2401 /* we add a section for symbols */
2402 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2403 put_elf_str(strsec, "");
2405 /* Allocate strings for section names */
2406 ret = alloc_sec_names(s1, file_type, strsec);
2408 #ifndef ELF_OBJ_ONLY
2409 if (dynamic) {
2410 int i;
2411 /* add a list of needed dlls */
2412 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2413 DLLReference *dllref = s1->loaded_dlls[i];
2414 if (dllref->level == 0)
2415 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2418 if (s1->rpath)
2419 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2420 put_elf_str(dynstr, s1->rpath));
2422 if (file_type == TCC_OUTPUT_DLL) {
2423 if (s1->soname)
2424 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2425 /* XXX: currently, since we do not handle PIC code, we
2426 must relocate the readonly segments */
2427 if (ret)
2428 put_dt(dynamic, DT_TEXTREL, 0);
2431 if (s1->symbolic)
2432 put_dt(dynamic, DT_SYMBOLIC, 0);
2434 dyninf.dynamic = dynamic;
2435 dyninf.dynstr = dynstr;
2436 /* remember offset and reserve space for 2nd call below */
2437 dyninf.data_offset = dynamic->data_offset;
2438 fill_dynamic(s1, &dyninf);
2439 dynamic->sh_size = dynamic->data_offset;
2440 dynstr->sh_size = dynstr->data_offset;
2442 #endif
2444 /* compute number of program headers */
2445 if (file_type == TCC_OUTPUT_OBJ)
2446 phnum = 0;
2447 else if (file_type == TCC_OUTPUT_DLL)
2448 phnum = 3;
2449 else if (s1->static_link)
2450 phnum = 2;
2451 else
2452 phnum = 5;
2454 /* allocate program segment headers */
2455 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2457 /* compute number of sections */
2458 shnum = s1->nb_sections;
2460 /* this array is used to reorder sections in the output file */
2461 sec_order = tcc_malloc(sizeof(int) * shnum);
2462 sec_order[0] = 0;
2464 /* compute section to program header mapping */
2465 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2466 sec_order);
2468 #ifndef ELF_OBJ_ONLY
2469 /* Fill remaining program header and finalize relocation related to dynamic
2470 linking. */
2471 if (file_type != TCC_OUTPUT_OBJ) {
2472 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2473 if (dynamic) {
2474 ElfW(Sym) *sym;
2475 dynamic->data_offset = dyninf.data_offset;
2476 fill_dynamic(s1, &dyninf);
2478 /* put in GOT the dynamic section address and relocate PLT */
2479 write32le(s1->got->data, dynamic->sh_addr);
2480 if (file_type == TCC_OUTPUT_EXE
2481 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2482 relocate_plt(s1);
2484 /* relocate symbols in .dynsym now that final addresses are known */
2485 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2486 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2487 /* do symbol relocation */
2488 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2493 /* if building executable or DLL, then relocate each section
2494 except the GOT which is already relocated */
2495 ret = final_sections_reloc(s1);
2496 if (ret)
2497 goto the_end;
2498 tidy_section_headers(s1, sec_order);
2500 /* Perform relocation to GOT or PLT entries */
2501 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2502 fill_got(s1);
2503 else if (s1->got)
2504 fill_local_got_entries(s1);
2506 #endif
2508 /* Create the ELF file with name 'filename' */
2509 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2510 s1->nb_sections = shnum;
2511 goto the_end;
2512 the_end:
2513 tcc_free(sec_order);
2514 tcc_free(phdr);
2515 return ret;
2518 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2520 int ret;
2521 #ifdef TCC_TARGET_PE
2522 if (s->output_type != TCC_OUTPUT_OBJ) {
2523 ret = pe_output_file(s, filename);
2524 } else
2525 #elif TCC_TARGET_MACHO
2526 if (s->output_type != TCC_OUTPUT_OBJ) {
2527 ret = macho_output_file(s, filename);
2528 } else
2529 #endif
2530 ret = elf_output_file(s, filename);
2531 return ret;
2534 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
2535 char *cbuf = buf;
2536 size_t rnum = 0;
2537 while (1) {
2538 ssize_t num = read(fd, cbuf, count-rnum);
2539 if (num < 0) return num;
2540 if (num == 0) return rnum;
2541 rnum += num;
2542 cbuf += num;
2546 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
2548 void *data;
2550 data = tcc_malloc(size);
2551 lseek(fd, file_offset, SEEK_SET);
2552 full_read(fd, data, size);
2553 return data;
2556 typedef struct SectionMergeInfo {
2557 Section *s; /* corresponding existing section */
2558 unsigned long offset; /* offset of the new section in the existing section */
2559 uint8_t new_section; /* true if section 's' was added */
2560 uint8_t link_once; /* true if link once section */
2561 } SectionMergeInfo;
2563 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2565 int size = full_read(fd, h, sizeof *h);
2566 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2567 if (h->e_type == ET_REL)
2568 return AFF_BINTYPE_REL;
2569 if (h->e_type == ET_DYN)
2570 return AFF_BINTYPE_DYN;
2571 } else if (size >= 8) {
2572 if (0 == memcmp(h, ARMAG, 8))
2573 return AFF_BINTYPE_AR;
2574 #ifdef TCC_TARGET_COFF
2575 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2576 return AFF_BINTYPE_C67;
2577 #endif
2579 return 0;
2582 /* load an object file and merge it with current files */
2583 /* XXX: handle correctly stab (debug) info */
2584 ST_FUNC int tcc_load_object_file(TCCState *s1,
2585 int fd, unsigned long file_offset)
2587 ElfW(Ehdr) ehdr;
2588 ElfW(Shdr) *shdr, *sh;
2589 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2590 char *strsec, *strtab;
2591 int stab_index, stabstr_index;
2592 int *old_to_new_syms;
2593 char *sh_name, *name;
2594 SectionMergeInfo *sm_table, *sm;
2595 ElfW(Sym) *sym, *symtab;
2596 ElfW_Rel *rel;
2597 Section *s;
2599 lseek(fd, file_offset, SEEK_SET);
2600 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2601 goto fail1;
2602 /* test CPU specific stuff */
2603 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2604 ehdr.e_machine != EM_TCC_TARGET) {
2605 fail1:
2606 tcc_error_noabort("invalid object file");
2607 return -1;
2609 /* read sections */
2610 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2611 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2612 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2614 /* load section names */
2615 sh = &shdr[ehdr.e_shstrndx];
2616 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2618 /* load symtab and strtab */
2619 old_to_new_syms = NULL;
2620 symtab = NULL;
2621 strtab = NULL;
2622 nb_syms = 0;
2623 seencompressed = 0;
2624 stab_index = stabstr_index = 0;
2626 for(i = 1; i < ehdr.e_shnum; i++) {
2627 sh = &shdr[i];
2628 if (sh->sh_type == SHT_SYMTAB) {
2629 if (symtab) {
2630 tcc_error_noabort("object must contain only one symtab");
2631 fail:
2632 ret = -1;
2633 goto the_end;
2635 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2636 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2637 sm_table[i].s = symtab_section;
2639 /* now load strtab */
2640 sh = &shdr[sh->sh_link];
2641 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2643 if (sh->sh_flags & SHF_COMPRESSED)
2644 seencompressed = 1;
2647 /* now examine each section and try to merge its content with the
2648 ones in memory */
2649 for(i = 1; i < ehdr.e_shnum; i++) {
2650 /* no need to examine section name strtab */
2651 if (i == ehdr.e_shstrndx)
2652 continue;
2653 sh = &shdr[i];
2654 if (sh->sh_type == SHT_RELX)
2655 sh = &shdr[sh->sh_info];
2656 /* ignore sections types we do not handle (plus relocs to those) */
2657 if (sh->sh_type != SHT_PROGBITS &&
2658 #ifdef TCC_ARM_EABI
2659 sh->sh_type != SHT_ARM_EXIDX &&
2660 #endif
2661 sh->sh_type != SHT_NOBITS &&
2662 sh->sh_type != SHT_PREINIT_ARRAY &&
2663 sh->sh_type != SHT_INIT_ARRAY &&
2664 sh->sh_type != SHT_FINI_ARRAY &&
2665 strcmp(strsec + sh->sh_name, ".stabstr")
2667 continue;
2668 if (seencompressed
2669 && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
2670 continue;
2672 sh = &shdr[i];
2673 sh_name = strsec + sh->sh_name;
2674 if (sh->sh_addralign < 1)
2675 sh->sh_addralign = 1;
2676 /* find corresponding section, if any */
2677 for(j = 1; j < s1->nb_sections;j++) {
2678 s = s1->sections[j];
2679 if (!strcmp(s->name, sh_name)) {
2680 if (!strncmp(sh_name, ".gnu.linkonce",
2681 sizeof(".gnu.linkonce") - 1)) {
2682 /* if a 'linkonce' section is already present, we
2683 do not add it again. It is a little tricky as
2684 symbols can still be defined in
2685 it. */
2686 sm_table[i].link_once = 1;
2687 goto next;
2689 if (stab_section) {
2690 if (s == stab_section)
2691 stab_index = i;
2692 if (s == stab_section->link)
2693 stabstr_index = i;
2695 goto found;
2698 /* not found: create new section */
2699 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2700 /* take as much info as possible from the section. sh_link and
2701 sh_info will be updated later */
2702 s->sh_addralign = sh->sh_addralign;
2703 s->sh_entsize = sh->sh_entsize;
2704 sm_table[i].new_section = 1;
2705 found:
2706 if (sh->sh_type != s->sh_type) {
2707 tcc_error_noabort("invalid section type");
2708 goto fail;
2710 /* align start of section */
2711 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
2712 if (sh->sh_addralign > s->sh_addralign)
2713 s->sh_addralign = sh->sh_addralign;
2714 sm_table[i].offset = s->data_offset;
2715 sm_table[i].s = s;
2716 /* concatenate sections */
2717 size = sh->sh_size;
2718 if (sh->sh_type != SHT_NOBITS) {
2719 unsigned char *ptr;
2720 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2721 ptr = section_ptr_add(s, size);
2722 full_read(fd, ptr, size);
2723 } else {
2724 s->data_offset += size;
2726 next: ;
2729 /* gr relocate stab strings */
2730 if (stab_index && stabstr_index) {
2731 Stab_Sym *a, *b;
2732 unsigned o;
2733 s = sm_table[stab_index].s;
2734 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2735 b = (Stab_Sym *)(s->data + s->data_offset);
2736 o = sm_table[stabstr_index].offset;
2737 while (a < b) {
2738 if (a->n_strx)
2739 a->n_strx += o;
2740 a++;
2744 /* second short pass to update sh_link and sh_info fields of new
2745 sections */
2746 for(i = 1; i < ehdr.e_shnum; i++) {
2747 s = sm_table[i].s;
2748 if (!s || !sm_table[i].new_section)
2749 continue;
2750 sh = &shdr[i];
2751 if (sh->sh_link > 0)
2752 s->link = sm_table[sh->sh_link].s;
2753 if (sh->sh_type == SHT_RELX) {
2754 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2755 /* update backward link */
2756 s1->sections[s->sh_info]->reloc = s;
2760 /* resolve symbols */
2761 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2763 sym = symtab + 1;
2764 for(i = 1; i < nb_syms; i++, sym++) {
2765 if (sym->st_shndx != SHN_UNDEF &&
2766 sym->st_shndx < SHN_LORESERVE) {
2767 sm = &sm_table[sym->st_shndx];
2768 if (sm->link_once) {
2769 /* if a symbol is in a link once section, we use the
2770 already defined symbol. It is very important to get
2771 correct relocations */
2772 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2773 name = strtab + sym->st_name;
2774 sym_index = find_elf_sym(symtab_section, name);
2775 if (sym_index)
2776 old_to_new_syms[i] = sym_index;
2778 continue;
2780 /* if no corresponding section added, no need to add symbol */
2781 if (!sm->s)
2782 continue;
2783 /* convert section number */
2784 sym->st_shndx = sm->s->sh_num;
2785 /* offset value */
2786 sym->st_value += sm->offset;
2788 /* add symbol */
2789 name = strtab + sym->st_name;
2790 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2791 sym->st_info, sym->st_other,
2792 sym->st_shndx, name);
2793 old_to_new_syms[i] = sym_index;
2796 /* third pass to patch relocation entries */
2797 for(i = 1; i < ehdr.e_shnum; i++) {
2798 s = sm_table[i].s;
2799 if (!s)
2800 continue;
2801 sh = &shdr[i];
2802 offset = sm_table[i].offset;
2803 switch(s->sh_type) {
2804 case SHT_RELX:
2805 /* take relocation offset information */
2806 offseti = sm_table[sh->sh_info].offset;
2807 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2808 int type;
2809 unsigned sym_index;
2810 /* convert symbol index */
2811 type = ELFW(R_TYPE)(rel->r_info);
2812 sym_index = ELFW(R_SYM)(rel->r_info);
2813 /* NOTE: only one symtab assumed */
2814 if (sym_index >= nb_syms)
2815 goto invalid_reloc;
2816 sym_index = old_to_new_syms[sym_index];
2817 /* ignore link_once in rel section. */
2818 if (!sym_index && !sm_table[sh->sh_info].link_once
2819 #ifdef TCC_TARGET_ARM
2820 && type != R_ARM_V4BX
2821 #elif defined TCC_TARGET_RISCV64
2822 && type != R_RISCV_ALIGN
2823 && type != R_RISCV_RELAX
2824 #endif
2826 invalid_reloc:
2827 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2828 i, strsec + sh->sh_name, (int)rel->r_offset);
2829 goto fail;
2831 rel->r_info = ELFW(R_INFO)(sym_index, type);
2832 /* offset the relocation offset */
2833 rel->r_offset += offseti;
2834 #ifdef TCC_TARGET_ARM
2835 /* Jumps and branches from a Thumb code to a PLT entry need
2836 special handling since PLT entries are ARM code.
2837 Unconditional bl instructions referencing PLT entries are
2838 handled by converting these instructions into blx
2839 instructions. Other case of instructions referencing a PLT
2840 entry require to add a Thumb stub before the PLT entry to
2841 switch to ARM mode. We set bit plt_thumb_stub of the
2842 attribute of a symbol to indicate such a case. */
2843 if (type == R_ARM_THM_JUMP24)
2844 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2845 #endif
2847 break;
2848 default:
2849 break;
2853 ret = 0;
2854 the_end:
2855 tcc_free(symtab);
2856 tcc_free(strtab);
2857 tcc_free(old_to_new_syms);
2858 tcc_free(sm_table);
2859 tcc_free(strsec);
2860 tcc_free(shdr);
2861 return ret;
2864 typedef struct ArchiveHeader {
2865 char ar_name[16]; /* name of this member */
2866 char ar_date[12]; /* file mtime */
2867 char ar_uid[6]; /* owner uid; printed as decimal */
2868 char ar_gid[6]; /* owner gid; printed as decimal */
2869 char ar_mode[8]; /* file mode, printed as octal */
2870 char ar_size[10]; /* file size, printed as decimal */
2871 char ar_fmag[2]; /* should contain ARFMAG */
2872 } ArchiveHeader;
2874 #define ARFMAG "`\n"
2876 static unsigned long long get_be(const uint8_t *b, int n)
2878 unsigned long long ret = 0;
2879 while (n)
2880 ret = (ret << 8) | *b++, --n;
2881 return ret;
2884 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
2886 char *p, *e;
2887 int len;
2888 lseek(fd, offset, SEEK_SET);
2889 len = full_read(fd, hdr, sizeof(ArchiveHeader));
2890 if (len != sizeof(ArchiveHeader))
2891 return len ? -1 : 0;
2892 p = hdr->ar_name;
2893 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
2894 --e;
2895 *e = '\0';
2896 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
2897 return len;
2900 /* load only the objects which resolve undefined symbols */
2901 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2903 int i, bound, nsyms, sym_index, len, ret = -1;
2904 unsigned long long off;
2905 uint8_t *data;
2906 const char *ar_names, *p;
2907 const uint8_t *ar_index;
2908 ElfW(Sym) *sym;
2909 ArchiveHeader hdr;
2911 data = tcc_malloc(size);
2912 if (full_read(fd, data, size) != size)
2913 goto the_end;
2914 nsyms = get_be(data, entrysize);
2915 ar_index = data + entrysize;
2916 ar_names = (char *) ar_index + nsyms * entrysize;
2918 do {
2919 bound = 0;
2920 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2921 Section *s = symtab_section;
2922 sym_index = find_elf_sym(s, p);
2923 if (!sym_index)
2924 continue;
2925 sym = &((ElfW(Sym) *)s->data)[sym_index];
2926 if(sym->st_shndx != SHN_UNDEF)
2927 continue;
2928 off = get_be(ar_index + i * entrysize, entrysize);
2929 len = read_ar_header(fd, off, &hdr);
2930 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
2931 tcc_error_noabort("invalid archive");
2932 goto the_end;
2934 off += len;
2935 if (s1->verbose == 2)
2936 printf(" -> %s\n", hdr.ar_name);
2937 if (tcc_load_object_file(s1, fd, off) < 0)
2938 goto the_end;
2939 ++bound;
2941 } while(bound);
2942 ret = 0;
2943 the_end:
2944 tcc_free(data);
2945 return ret;
2948 /* load a '.a' file */
2949 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
2951 ArchiveHeader hdr;
2952 /* char magic[8]; */
2953 int size, len;
2954 unsigned long file_offset;
2955 ElfW(Ehdr) ehdr;
2957 /* skip magic which was already checked */
2958 /* full_read(fd, magic, sizeof(magic)); */
2959 file_offset = sizeof ARMAG - 1;
2961 for(;;) {
2962 len = read_ar_header(fd, file_offset, &hdr);
2963 if (len == 0)
2964 return 0;
2965 if (len < 0) {
2966 tcc_error_noabort("invalid archive");
2967 return -1;
2969 file_offset += len;
2970 size = strtol(hdr.ar_size, NULL, 0);
2971 /* align to even */
2972 size = (size + 1) & ~1;
2973 if (alacarte) {
2974 /* coff symbol table : we handle it */
2975 if (!strcmp(hdr.ar_name, "/"))
2976 return tcc_load_alacarte(s1, fd, size, 4);
2977 if (!strcmp(hdr.ar_name, "/SYM64/"))
2978 return tcc_load_alacarte(s1, fd, size, 8);
2979 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2980 if (s1->verbose == 2)
2981 printf(" -> %s\n", hdr.ar_name);
2982 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2983 return -1;
2985 file_offset += size;
2989 #ifndef ELF_OBJ_ONLY
2990 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
2991 LV, maybe create a new entry for (LIB,VERSION). */
2992 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
2994 while (i >= *n) {
2995 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
2996 (*lv)[(*n)++] = -1;
2998 if ((*lv)[i] == -1) {
2999 int v, prev_same_lib = -1;
3000 for (v = 0; v < nb_sym_versions; v++) {
3001 if (strcmp(sym_versions[v].lib, lib))
3002 continue;
3003 prev_same_lib = v;
3004 if (!strcmp(sym_versions[v].version, version))
3005 break;
3007 if (v == nb_sym_versions) {
3008 sym_versions = tcc_realloc (sym_versions,
3009 (v + 1) * sizeof(*sym_versions));
3010 sym_versions[v].lib = tcc_strdup(lib);
3011 sym_versions[v].version = tcc_strdup(version);
3012 sym_versions[v].out_index = 0;
3013 sym_versions[v].prev_same_lib = prev_same_lib;
3014 nb_sym_versions++;
3016 (*lv)[i] = v;
3020 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3021 VERNDX. */
3022 static void
3023 set_sym_version(TCCState *s1, int sym_index, int verndx)
3025 if (sym_index >= nb_sym_to_version) {
3026 int newelems = sym_index ? sym_index * 2 : 1;
3027 sym_to_version = tcc_realloc(sym_to_version,
3028 newelems * sizeof(*sym_to_version));
3029 memset(sym_to_version + nb_sym_to_version, -1,
3030 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3031 nb_sym_to_version = newelems;
3033 if (sym_to_version[sym_index] < 0)
3034 sym_to_version[sym_index] = verndx;
3037 struct versym_info {
3038 int nb_versyms;
3039 ElfW(Verdef) *verdef;
3040 ElfW(Verneed) *verneed;
3041 ElfW(Half) *versym;
3042 int nb_local_ver, *local_ver;
3046 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3048 char *lib, *version;
3049 uint32_t next;
3050 int i;
3052 #define DEBUG_VERSION 0
3054 if (v->versym && v->verdef) {
3055 ElfW(Verdef) *vdef = v->verdef;
3056 lib = NULL;
3057 do {
3058 ElfW(Verdaux) *verdaux =
3059 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3061 #if DEBUG_VERSION
3062 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3063 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3064 vdef->vd_hash);
3065 #endif
3066 if (vdef->vd_cnt) {
3067 version = dynstr + verdaux->vda_name;
3069 if (lib == NULL)
3070 lib = version;
3071 else
3072 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3073 lib, version);
3074 #if DEBUG_VERSION
3075 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3076 #endif
3078 next = vdef->vd_next;
3079 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3080 } while (next);
3082 if (v->versym && v->verneed) {
3083 ElfW(Verneed) *vneed = v->verneed;
3084 do {
3085 ElfW(Vernaux) *vernaux =
3086 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3088 lib = dynstr + vneed->vn_file;
3089 #if DEBUG_VERSION
3090 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3091 #endif
3092 for (i = 0; i < vneed->vn_cnt; i++) {
3093 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3094 version = dynstr + vernaux->vna_name;
3095 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3096 lib, version);
3097 #if DEBUG_VERSION
3098 printf (" vernaux(%u): %u %u %s\n",
3099 vernaux->vna_other, vernaux->vna_hash,
3100 vernaux->vna_flags, version);
3101 #endif
3103 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3105 next = vneed->vn_next;
3106 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3107 } while (next);
3110 #if DEBUG_VERSION
3111 for (i = 0; i < v->nb_local_ver; i++) {
3112 if (v->local_ver[i] > 0) {
3113 printf ("%d: lib: %s, version %s\n",
3114 i, sym_versions[v->local_ver[i]].lib,
3115 sym_versions[v->local_ver[i]].version);
3118 #endif
3121 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3122 is referenced by the user (so it should be added as DT_NEEDED in
3123 the generated ELF file) */
3124 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3126 ElfW(Ehdr) ehdr;
3127 ElfW(Shdr) *shdr, *sh, *sh1;
3128 int i, j, nb_syms, nb_dts, sym_bind, ret;
3129 ElfW(Sym) *sym, *dynsym;
3130 ElfW(Dyn) *dt, *dynamic;
3132 char *dynstr;
3133 int sym_index;
3134 const char *name, *soname;
3135 DLLReference *dllref;
3136 struct versym_info v;
3138 full_read(fd, &ehdr, sizeof(ehdr));
3140 /* test CPU specific stuff */
3141 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3142 ehdr.e_machine != EM_TCC_TARGET) {
3143 tcc_error_noabort("bad architecture");
3144 return -1;
3147 /* read sections */
3148 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3150 /* load dynamic section and dynamic symbols */
3151 nb_syms = 0;
3152 nb_dts = 0;
3153 dynamic = NULL;
3154 dynsym = NULL; /* avoid warning */
3155 dynstr = NULL; /* avoid warning */
3156 memset(&v, 0, sizeof v);
3158 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3159 switch(sh->sh_type) {
3160 case SHT_DYNAMIC:
3161 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3162 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3163 break;
3164 case SHT_DYNSYM:
3165 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3166 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3167 sh1 = &shdr[sh->sh_link];
3168 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3169 break;
3170 case SHT_GNU_verdef:
3171 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3172 break;
3173 case SHT_GNU_verneed:
3174 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3175 break;
3176 case SHT_GNU_versym:
3177 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3178 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3179 break;
3180 default:
3181 break;
3185 /* compute the real library name */
3186 soname = tcc_basename(filename);
3188 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3189 if (dt->d_tag == DT_SONAME) {
3190 soname = dynstr + dt->d_un.d_val;
3194 /* if the dll is already loaded, do not load it */
3195 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3196 dllref = s1->loaded_dlls[i];
3197 if (!strcmp(soname, dllref->name)) {
3198 /* but update level if needed */
3199 if (level < dllref->level)
3200 dllref->level = level;
3201 ret = 0;
3202 goto the_end;
3206 if (v.nb_versyms != nb_syms)
3207 tcc_free (v.versym), v.versym = NULL;
3208 else
3209 store_version(s1, &v, dynstr);
3211 /* add the dll and its level */
3212 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
3213 dllref->level = level;
3214 strcpy(dllref->name, soname);
3215 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
3217 /* add dynamic symbols in dynsym_section */
3218 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3219 sym_bind = ELFW(ST_BIND)(sym->st_info);
3220 if (sym_bind == STB_LOCAL)
3221 continue;
3222 name = dynstr + sym->st_name;
3223 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3224 sym->st_info, sym->st_other, sym->st_shndx, name);
3225 if (v.versym) {
3226 ElfW(Half) vsym = v.versym[i];
3227 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3228 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3232 /* load all referenced DLLs */
3233 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3234 switch(dt->d_tag) {
3235 case DT_NEEDED:
3236 name = dynstr + dt->d_un.d_val;
3237 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3238 dllref = s1->loaded_dlls[j];
3239 if (!strcmp(name, dllref->name))
3240 goto already_loaded;
3242 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3243 tcc_error_noabort("referenced dll '%s' not found", name);
3244 ret = -1;
3245 goto the_end;
3247 already_loaded:
3248 break;
3251 ret = 0;
3252 the_end:
3253 tcc_free(dynstr);
3254 tcc_free(dynsym);
3255 tcc_free(dynamic);
3256 tcc_free(shdr);
3257 tcc_free(v.local_ver);
3258 tcc_free(v.verdef);
3259 tcc_free(v.verneed);
3260 tcc_free(v.versym);
3261 return ret;
3264 #define LD_TOK_NAME 256
3265 #define LD_TOK_EOF (-1)
3267 static int ld_inp(TCCState *s1)
3269 char b;
3270 if (s1->cc != -1) {
3271 int c = s1->cc;
3272 s1->cc = -1;
3273 return c;
3275 if (1 == read(s1->fd, &b, 1))
3276 return b;
3277 return CH_EOF;
3280 /* return next ld script token */
3281 static int ld_next(TCCState *s1, char *name, int name_size)
3283 int c, d, ch;
3284 char *q;
3286 redo:
3287 ch = ld_inp(s1);
3288 switch(ch) {
3289 case ' ':
3290 case '\t':
3291 case '\f':
3292 case '\v':
3293 case '\r':
3294 case '\n':
3295 goto redo;
3296 case '/':
3297 ch = ld_inp(s1);
3298 if (ch == '*') { /* comment */
3299 for (d = 0;; d = ch) {
3300 ch = ld_inp(s1);
3301 if (ch == CH_EOF || (ch == '/' && d == '*'))
3302 break;
3304 goto redo;
3305 } else {
3306 q = name;
3307 *q++ = '/';
3308 goto parse_name;
3310 break;
3311 case '\\':
3312 /* case 'a' ... 'z': */
3313 case 'a':
3314 case 'b':
3315 case 'c':
3316 case 'd':
3317 case 'e':
3318 case 'f':
3319 case 'g':
3320 case 'h':
3321 case 'i':
3322 case 'j':
3323 case 'k':
3324 case 'l':
3325 case 'm':
3326 case 'n':
3327 case 'o':
3328 case 'p':
3329 case 'q':
3330 case 'r':
3331 case 's':
3332 case 't':
3333 case 'u':
3334 case 'v':
3335 case 'w':
3336 case 'x':
3337 case 'y':
3338 case 'z':
3339 /* case 'A' ... 'z': */
3340 case 'A':
3341 case 'B':
3342 case 'C':
3343 case 'D':
3344 case 'E':
3345 case 'F':
3346 case 'G':
3347 case 'H':
3348 case 'I':
3349 case 'J':
3350 case 'K':
3351 case 'L':
3352 case 'M':
3353 case 'N':
3354 case 'O':
3355 case 'P':
3356 case 'Q':
3357 case 'R':
3358 case 'S':
3359 case 'T':
3360 case 'U':
3361 case 'V':
3362 case 'W':
3363 case 'X':
3364 case 'Y':
3365 case 'Z':
3366 case '_':
3367 case '.':
3368 case '$':
3369 case '~':
3370 q = name;
3371 parse_name:
3372 for(;;) {
3373 if (!((ch >= 'a' && ch <= 'z') ||
3374 (ch >= 'A' && ch <= 'Z') ||
3375 (ch >= '0' && ch <= '9') ||
3376 strchr("/.-_+=$:\\,~", ch)))
3377 break;
3378 if ((q - name) < name_size - 1) {
3379 *q++ = ch;
3381 ch = ld_inp(s1);
3383 s1->cc = ch;
3384 *q = '\0';
3385 c = LD_TOK_NAME;
3386 break;
3387 case CH_EOF:
3388 c = LD_TOK_EOF;
3389 break;
3390 default:
3391 c = ch;
3392 break;
3394 return c;
3397 static int ld_add_file(TCCState *s1, const char filename[])
3399 if (filename[0] == '/') {
3400 if (CONFIG_SYSROOT[0] == '\0'
3401 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3402 return 0;
3403 filename = tcc_basename(filename);
3405 return tcc_add_dll(s1, filename, 0);
3408 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3410 char filename[1024], libname[1024];
3411 int t, group, nblibs = 0, ret = 0;
3412 char **libs = NULL;
3414 group = !strcmp(cmd, "GROUP");
3415 if (!as_needed)
3416 s1->new_undef_sym = 0;
3417 t = ld_next(s1, filename, sizeof(filename));
3418 if (t != '(') {
3419 tcc_error_noabort("( expected");
3420 ret = -1;
3421 goto lib_parse_error;
3423 t = ld_next(s1, filename, sizeof(filename));
3424 for(;;) {
3425 libname[0] = '\0';
3426 if (t == LD_TOK_EOF) {
3427 tcc_error_noabort("unexpected end of file");
3428 ret = -1;
3429 goto lib_parse_error;
3430 } else if (t == ')') {
3431 break;
3432 } else if (t == '-') {
3433 t = ld_next(s1, filename, sizeof(filename));
3434 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3435 tcc_error_noabort("library name expected");
3436 ret = -1;
3437 goto lib_parse_error;
3439 pstrcpy(libname, sizeof libname, &filename[1]);
3440 if (s1->static_link) {
3441 snprintf(filename, sizeof filename, "lib%s.a", libname);
3442 } else {
3443 snprintf(filename, sizeof filename, "lib%s.so", libname);
3445 } else if (t != LD_TOK_NAME) {
3446 tcc_error_noabort("filename expected");
3447 ret = -1;
3448 goto lib_parse_error;
3450 if (!strcmp(filename, "AS_NEEDED")) {
3451 ret = ld_add_file_list(s1, cmd, 1);
3452 if (ret)
3453 goto lib_parse_error;
3454 } else {
3455 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3456 if (!as_needed) {
3457 ret = ld_add_file(s1, filename);
3458 if (ret)
3459 goto lib_parse_error;
3460 if (group) {
3461 /* Add the filename *and* the libname to avoid future conversions */
3462 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3463 if (libname[0] != '\0')
3464 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3468 t = ld_next(s1, filename, sizeof(filename));
3469 if (t == ',') {
3470 t = ld_next(s1, filename, sizeof(filename));
3473 if (group && !as_needed) {
3474 while (s1->new_undef_sym) {
3475 int i;
3476 s1->new_undef_sym = 0;
3477 for (i = 0; i < nblibs; i ++)
3478 ld_add_file(s1, libs[i]);
3481 lib_parse_error:
3482 dynarray_reset(&libs, &nblibs);
3483 return ret;
3486 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3487 files */
3488 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3490 char cmd[64];
3491 char filename[1024];
3492 int t, ret;
3494 s1->fd = fd;
3495 s1->cc = -1;
3496 for(;;) {
3497 t = ld_next(s1, cmd, sizeof(cmd));
3498 if (t == LD_TOK_EOF)
3499 return 0;
3500 else if (t != LD_TOK_NAME)
3501 return -1;
3502 if (!strcmp(cmd, "INPUT") ||
3503 !strcmp(cmd, "GROUP")) {
3504 ret = ld_add_file_list(s1, cmd, 0);
3505 if (ret)
3506 return ret;
3507 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3508 !strcmp(cmd, "TARGET")) {
3509 /* ignore some commands */
3510 t = ld_next(s1, cmd, sizeof(cmd));
3511 if (t != '(') {
3512 tcc_error_noabort("( expected");
3513 return -1;
3515 for(;;) {
3516 t = ld_next(s1, filename, sizeof(filename));
3517 if (t == LD_TOK_EOF) {
3518 tcc_error_noabort("unexpected end of file");
3519 return -1;
3520 } else if (t == ')') {
3521 break;
3524 } else {
3525 return -1;
3528 return 0;
3530 #endif /* !ELF_OBJ_ONLY */