Make 112_backtrace/bcheck_123 more robust
[tinycc.git] / tccelf.c
blob6c919d975168fea003a9b8bde658d0210d143e14
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 */
485 ST_FUNC addr_t get_elf_sym_addr(TCCState *s1, const char *name, int err)
487 int sym_index;
488 ElfW(Sym) *sym;
490 sym_index = find_elf_sym(s1->symtab, name);
491 sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
492 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
493 if (err)
494 tcc_error("%s not defined", name);
495 return 0;
497 return sym->st_value;
500 /* list elf symbol names and values */
501 ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
502 void (*symbol_cb)(void *ctx, const char *name, const void *val))
504 ElfW(Sym) *sym;
505 Section *symtab;
506 int sym_index, end_sym;
507 const char *name;
508 unsigned char sym_vis, sym_bind;
510 symtab = s->symtab;
511 end_sym = symtab->data_offset / sizeof (ElfSym);
512 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
513 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
514 if (sym->st_value) {
515 name = (char *) symtab->link->data + sym->st_name;
516 sym_bind = ELFW(ST_BIND)(sym->st_info);
517 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
518 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
519 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
524 /* return elf symbol value */
525 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
527 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0);
530 /* list elf symbol names and values */
531 LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
532 void (*symbol_cb)(void *ctx, const char *name, const void *val))
534 list_elf_symbols(s, ctx, symbol_cb);
537 #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
538 /* return elf symbol value or error */
539 ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
541 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1);
543 #endif
545 #ifndef ELF_OBJ_ONLY
546 static void
547 version_add (TCCState *s1)
549 int i;
550 ElfW(Sym) *sym;
551 ElfW(Verneed) *vn = NULL;
552 Section *symtab;
553 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
554 ElfW(Half) *versym;
555 const char *name;
557 if (0 == nb_sym_versions)
558 return;
559 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
560 versym_section->sh_entsize = sizeof(ElfW(Half));
561 verneed_section = new_section(s1, ".gnu.version_r", SHT_GNU_verneed, SHF_ALLOC);
562 versym_section->link = s1->dynsym;
563 verneed_section->link = s1->dynsym->link;
565 /* add needed symbols */
566 symtab = s1->dynsym;
567 end_sym = symtab->data_offset / sizeof (ElfSym);
568 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
569 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
570 int dllindex, verndx;
571 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
572 name = (char *) symtab->link->data + sym->st_name;
573 dllindex = find_elf_sym(s1->dynsymtab_section, name);
574 verndx = (dllindex && dllindex < nb_sym_to_version)
575 ? sym_to_version[dllindex] : -1;
576 if (verndx >= 0) {
577 if (!sym_versions[verndx].out_index)
578 sym_versions[verndx].out_index = nb_versions++;
579 versym[sym_index] = sym_versions[verndx].out_index;
580 } else
581 versym[sym_index] = 0;
583 /* generate verneed section */
584 for (i = nb_sym_versions; i-- > 0;) {
585 struct sym_version *sv = &sym_versions[i];
586 int n_same_libs = 0, prev;
587 size_t vnofs;
588 ElfW(Vernaux) *vna = 0;
589 if (sv->out_index < 1)
590 continue;
591 vnofs = section_add(verneed_section, sizeof(*vn), 1);
592 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
593 vn->vn_version = 1;
594 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
595 vn->vn_aux = sizeof (*vn);
596 do {
597 prev = sv->prev_same_lib;
598 if (sv->out_index > 0) {
599 vna = section_ptr_add(verneed_section, sizeof(*vna));
600 vna->vna_hash = elf_hash ((const unsigned char *)sv->version);
601 vna->vna_flags = 0;
602 vna->vna_other = sv->out_index;
603 sv->out_index = -2;
604 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
605 vna->vna_next = sizeof (*vna);
606 n_same_libs++;
608 if (prev >= 0)
609 sv = &sym_versions[prev];
610 } while(prev >= 0);
611 vna->vna_next = 0;
612 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
613 vn->vn_cnt = n_same_libs;
614 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
615 nb_entries++;
617 if (vn)
618 vn->vn_next = 0;
619 verneed_section->sh_info = nb_entries;
620 dt_verneednum = nb_entries;
622 #endif
624 /* add an elf symbol : check if it is already defined and patch
625 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
626 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
627 int info, int other, int shndx, const char *name)
629 TCCState *s1 = s->s1;
630 ElfW(Sym) *esym;
631 int sym_bind, sym_index, sym_type, esym_bind;
632 unsigned char sym_vis, esym_vis, new_vis;
634 sym_bind = ELFW(ST_BIND)(info);
635 sym_type = ELFW(ST_TYPE)(info);
636 sym_vis = ELFW(ST_VISIBILITY)(other);
638 if (sym_bind != STB_LOCAL) {
639 /* we search global or weak symbols */
640 sym_index = find_elf_sym(s, name);
641 if (!sym_index)
642 goto do_def;
643 esym = &((ElfW(Sym) *)s->data)[sym_index];
644 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
645 && esym->st_other == other && esym->st_shndx == shndx)
646 return sym_index;
647 if (esym->st_shndx != SHN_UNDEF) {
648 esym_bind = ELFW(ST_BIND)(esym->st_info);
649 /* propagate the most constraining visibility */
650 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
651 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
652 if (esym_vis == STV_DEFAULT) {
653 new_vis = sym_vis;
654 } else if (sym_vis == STV_DEFAULT) {
655 new_vis = esym_vis;
656 } else {
657 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
659 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
660 | new_vis;
661 other = esym->st_other; /* in case we have to patch esym */
662 if (shndx == SHN_UNDEF) {
663 /* ignore adding of undefined symbol if the
664 corresponding symbol is already defined */
665 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
666 /* global overrides weak, so patch */
667 goto do_patch;
668 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
669 /* weak is ignored if already global */
670 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
671 /* keep first-found weak definition, ignore subsequents */
672 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
673 /* ignore hidden symbols after */
674 } else if ((esym->st_shndx == SHN_COMMON
675 || esym->st_shndx == bss_section->sh_num)
676 && (shndx < SHN_LORESERVE
677 && shndx != bss_section->sh_num)) {
678 /* data symbol gets precedence over common/bss */
679 goto do_patch;
680 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
681 /* data symbol keeps precedence over common/bss */
682 } else if (s->sh_flags & SHF_DYNSYM) {
683 /* we accept that two DLL define the same symbol */
684 } else if (esym->st_other & ST_ASM_SET) {
685 /* If the existing symbol came from an asm .set
686 we can override. */
687 goto do_patch;
688 } else {
689 #if 0
690 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
691 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
692 #endif
693 tcc_error_noabort("'%s' defined twice", name);
695 } else {
696 do_patch:
697 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
698 esym->st_shndx = shndx;
699 s1->new_undef_sym = 1;
700 esym->st_value = value;
701 esym->st_size = size;
702 esym->st_other = other;
704 } else {
705 do_def:
706 sym_index = put_elf_sym(s, value, size,
707 ELFW(ST_INFO)(sym_bind, sym_type), other,
708 shndx, name);
710 return sym_index;
713 /* put relocation */
714 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
715 int type, int symbol, addr_t addend)
717 TCCState *s1 = s->s1;
718 char buf[256];
719 Section *sr;
720 ElfW_Rel *rel;
722 sr = s->reloc;
723 if (!sr) {
724 /* if no relocation section, create it */
725 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
726 /* if the symtab is allocated, then we consider the relocation
727 are also */
728 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
729 sr->sh_entsize = sizeof(ElfW_Rel);
730 sr->link = symtab;
731 sr->sh_info = s->sh_num;
732 s->reloc = sr;
734 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
735 rel->r_offset = offset;
736 rel->r_info = ELFW(R_INFO)(symbol, type);
737 #if SHT_RELX == SHT_RELA
738 rel->r_addend = addend;
739 #endif
740 if (SHT_RELX != SHT_RELA && addend)
741 tcc_error("non-zero addend on REL architecture");
744 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
745 int type, int symbol)
747 put_elf_reloca(symtab, s, offset, type, symbol, 0);
750 /* Remove relocations for section S->reloc starting at oldrelocoffset
751 that are to the same place, retaining the last of them. As side effect
752 the relocations are sorted. Possibly reduces the number of relocs. */
753 ST_FUNC void squeeze_multi_relocs(Section *s, size_t oldrelocoffset)
755 Section *sr = s->reloc;
756 ElfW_Rel *r, *dest;
757 ssize_t a;
758 ElfW(Addr) addr;
760 if (oldrelocoffset + sizeof(*r) >= sr->data_offset)
761 return;
762 /* The relocs we're dealing with are the result of initializer parsing.
763 So they will be mostly in order and there aren't many of them.
764 Secondly we need a stable sort (which qsort isn't). We use
765 a simple insertion sort. */
766 for (a = oldrelocoffset + sizeof(*r); a < sr->data_offset; a += sizeof(*r)) {
767 ssize_t i = a - sizeof(*r);
768 addr = ((ElfW_Rel*)(sr->data + a))->r_offset;
769 for (; i >= (ssize_t)oldrelocoffset &&
770 ((ElfW_Rel*)(sr->data + i))->r_offset > addr; i -= sizeof(*r)) {
771 ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a);
772 *(ElfW_Rel*)(sr->data + a) = *(ElfW_Rel*)(sr->data + i);
773 *(ElfW_Rel*)(sr->data + i) = tmp;
777 r = (ElfW_Rel*)(sr->data + oldrelocoffset);
778 dest = r;
779 for (; r < (ElfW_Rel*)(sr->data + sr->data_offset); r++) {
780 if (dest->r_offset != r->r_offset)
781 dest++;
782 *dest = *r;
784 sr->data_offset = (unsigned char*)dest - sr->data + sizeof(*r);
787 /* put stab debug information */
789 ST_FUNC void put_stabs(TCCState *s1, const char *str, int type, int other, int desc,
790 unsigned long value)
792 Stab_Sym *sym;
794 unsigned offset;
795 if (type == N_SLINE
796 && (offset = stab_section->data_offset)
797 && (sym = (Stab_Sym*)(stab_section->data + offset) - 1)
798 && sym->n_type == type
799 && sym->n_value == value) {
800 /* just update line_number in previous entry */
801 sym->n_desc = desc;
802 return;
805 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
806 if (str) {
807 sym->n_strx = put_elf_str(stab_section->link, str);
808 } else {
809 sym->n_strx = 0;
811 sym->n_type = type;
812 sym->n_other = other;
813 sym->n_desc = desc;
814 sym->n_value = value;
817 ST_FUNC void put_stabs_r(TCCState *s1, const char *str, int type, int other, int desc,
818 unsigned long value, Section *sec, int sym_index)
820 put_elf_reloc(symtab_section, stab_section,
821 stab_section->data_offset + 8,
822 sizeof ((Stab_Sym*)0)->n_value == PTR_SIZE ? R_DATA_PTR : R_DATA_32,
823 sym_index);
824 put_stabs(s1, str, type, other, desc, value);
827 ST_FUNC void put_stabn(TCCState *s1, int type, int other, int desc, int value)
829 put_stabs(s1, NULL, type, other, desc, value);
832 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
834 int n;
835 struct sym_attr *tab;
837 if (index >= s1->nb_sym_attrs) {
838 if (!alloc)
839 return s1->sym_attrs;
840 /* find immediately bigger power of 2 and reallocate array */
841 n = 1;
842 while (index >= n)
843 n *= 2;
844 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
845 s1->sym_attrs = tab;
846 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
847 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
848 s1->nb_sym_attrs = n;
850 return &s1->sym_attrs[index];
853 /* Browse each elem of type <type> in section <sec> starting at elem <startoff>
854 using variable <elem> */
855 #define for_each_elem(sec, startoff, elem, type) \
856 for (elem = (type *) sec->data + startoff; \
857 elem < (type *) (sec->data + sec->data_offset); elem++)
859 /* In an ELF file symbol table, the local symbols must appear below
860 the global and weak ones. Since TCC cannot sort it while generating
861 the code, we must do it after. All the relocation tables are also
862 modified to take into account the symbol table sorting */
863 static void sort_syms(TCCState *s1, Section *s)
865 int *old_to_new_syms;
866 ElfW(Sym) *new_syms;
867 int nb_syms, i;
868 ElfW(Sym) *p, *q;
869 ElfW_Rel *rel;
870 Section *sr;
871 int type, sym_index;
873 nb_syms = s->data_offset / sizeof(ElfW(Sym));
874 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
875 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
877 /* first pass for local symbols */
878 p = (ElfW(Sym) *)s->data;
879 q = new_syms;
880 for(i = 0; i < nb_syms; i++) {
881 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
882 old_to_new_syms[i] = q - new_syms;
883 *q++ = *p;
885 p++;
887 /* save the number of local symbols in section header */
888 if( s->sh_size ) /* this 'if' makes IDA happy */
889 s->sh_info = q - new_syms;
891 /* then second pass for non local symbols */
892 p = (ElfW(Sym) *)s->data;
893 for(i = 0; i < nb_syms; i++) {
894 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
895 old_to_new_syms[i] = q - new_syms;
896 *q++ = *p;
898 p++;
901 /* we copy the new symbols to the old */
902 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
903 tcc_free(new_syms);
905 /* now we modify all the relocations */
906 for(i = 1; i < s1->nb_sections; i++) {
907 sr = s1->sections[i];
908 if (sr->sh_type == SHT_RELX && sr->link == s) {
909 for_each_elem(sr, 0, rel, ElfW_Rel) {
910 sym_index = ELFW(R_SYM)(rel->r_info);
911 type = ELFW(R_TYPE)(rel->r_info);
912 sym_index = old_to_new_syms[sym_index];
913 rel->r_info = ELFW(R_INFO)(sym_index, type);
918 tcc_free(old_to_new_syms);
921 /* relocate symbol table, resolve undefined symbols if do_resolve is
922 true and output error if undefined symbol. */
923 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
925 ElfW(Sym) *sym;
926 int sym_bind, sh_num;
927 const char *name;
929 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
930 sh_num = sym->st_shndx;
931 if (sh_num == SHN_UNDEF) {
932 name = (char *) s1->symtab->link->data + sym->st_name;
933 /* Use ld.so to resolve symbol for us (for tcc -run) */
934 if (do_resolve) {
935 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
936 void *addr = dlsym(RTLD_DEFAULT, name);
937 if (addr) {
938 sym->st_value = (addr_t) addr;
939 #ifdef DEBUG_RELOC
940 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
941 #endif
942 goto found;
944 #endif
945 /* if dynamic symbol exist, it will be used in relocate_section */
946 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
947 goto found;
948 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
949 it */
950 if (!strcmp(name, "_fp_hw"))
951 goto found;
952 /* only weak symbols are accepted to be undefined. Their
953 value is zero */
954 sym_bind = ELFW(ST_BIND)(sym->st_info);
955 if (sym_bind == STB_WEAK)
956 sym->st_value = 0;
957 else
958 tcc_error_noabort("undefined symbol '%s'", name);
959 } else if (sh_num < SHN_LORESERVE) {
960 /* add section base */
961 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
963 found: ;
967 /* relocate a given section (CPU dependent) by applying the relocations
968 in the associated relocation section */
969 ST_FUNC void relocate_section(TCCState *s1, Section *s)
971 Section *sr = s->reloc;
972 ElfW_Rel *rel;
973 ElfW(Sym) *sym;
974 int type, sym_index;
975 unsigned char *ptr;
976 addr_t tgt, addr;
978 qrel = (ElfW_Rel *)sr->data;
980 for_each_elem(sr, 0, rel, ElfW_Rel) {
981 ptr = s->data + rel->r_offset;
982 sym_index = ELFW(R_SYM)(rel->r_info);
983 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
984 type = ELFW(R_TYPE)(rel->r_info);
985 tgt = sym->st_value;
986 #if SHT_RELX == SHT_RELA
987 tgt += rel->r_addend;
988 #endif
989 addr = s->sh_addr + rel->r_offset;
990 relocate(s1, rel, type, ptr, addr, tgt);
992 /* if the relocation is allocated, we change its symbol table */
993 if (sr->sh_flags & SHF_ALLOC) {
994 sr->link = s1->dynsym;
995 if (s1->output_type == TCC_OUTPUT_DLL) {
996 size_t r = (uint8_t*)qrel - sr->data;
997 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
998 && 0 == strcmp(s->name, ".stab"))
999 r = 0; /* cannot apply 64bit relocation to 32bit value */
1000 sr->data_offset = sr->sh_size = r;
1005 #ifndef ELF_OBJ_ONLY
1006 /* relocate relocation table in 'sr' */
1007 static void relocate_rel(TCCState *s1, Section *sr)
1009 Section *s;
1010 ElfW_Rel *rel;
1012 s = s1->sections[sr->sh_info];
1013 for_each_elem(sr, 0, rel, ElfW_Rel)
1014 rel->r_offset += s->sh_addr;
1017 /* count the number of dynamic relocations so that we can reserve
1018 their space */
1019 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
1021 int count = 0;
1022 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1023 ElfW_Rel *rel;
1024 for_each_elem(sr, 0, rel, ElfW_Rel) {
1025 int sym_index = ELFW(R_SYM)(rel->r_info);
1026 int type = ELFW(R_TYPE)(rel->r_info);
1027 switch(type) {
1028 #if defined(TCC_TARGET_I386)
1029 case R_386_32:
1030 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
1031 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
1032 /* don't fixup unresolved (weak) symbols */
1033 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
1034 break;
1036 #elif defined(TCC_TARGET_X86_64)
1037 case R_X86_64_32:
1038 case R_X86_64_32S:
1039 case R_X86_64_64:
1040 #endif
1041 count++;
1042 break;
1043 #if defined(TCC_TARGET_I386)
1044 case R_386_PC32:
1045 #elif defined(TCC_TARGET_X86_64)
1046 case R_X86_64_PC32:
1047 #endif
1048 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1049 count++;
1050 break;
1051 default:
1052 break;
1055 if (count) {
1056 /* allocate the section */
1057 sr->sh_flags |= SHF_ALLOC;
1058 sr->sh_size = count * sizeof(ElfW_Rel);
1060 #endif
1061 return count;
1064 static void build_got(TCCState *s1)
1066 /* if no got, then create it */
1067 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1068 s1->got->sh_entsize = 4;
1069 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1070 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1071 /* keep space for _DYNAMIC pointer and two dummy got entries */
1072 section_ptr_add(s1->got, 3 * PTR_SIZE);
1075 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1076 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1077 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1078 Returns the offset of the GOT or (if any) PLT entry. */
1079 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1080 int sym_index)
1082 int need_plt_entry;
1083 const char *name;
1084 ElfW(Sym) *sym;
1085 struct sym_attr *attr;
1086 unsigned got_offset;
1087 char plt_name[100];
1088 int len;
1090 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1091 attr = get_sym_attr(s1, sym_index, 1);
1093 /* In case a function is both called and its address taken 2 GOT entries
1094 are created, one for taking the address (GOT) and the other for the PLT
1095 entry (PLTGOT). */
1096 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1097 return attr;
1099 /* create the GOT entry */
1100 got_offset = s1->got->data_offset;
1101 section_ptr_add(s1->got, PTR_SIZE);
1103 /* Create the GOT relocation that will insert the address of the object or
1104 function of interest in the GOT entry. This is a static relocation for
1105 memory output (dlsym will give us the address of symbols) and dynamic
1106 relocation otherwise (executable and DLLs). The relocation should be
1107 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1108 associated to a PLT entry) but is currently done at load time for an
1109 unknown reason. */
1111 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1112 name = (char *) symtab_section->link->data + sym->st_name;
1114 if (s1->dynsym) {
1115 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1116 /* Hack alarm. We don't want to emit dynamic symbols
1117 and symbol based relocs for STB_LOCAL symbols, but rather
1118 want to resolve them directly. At this point the symbol
1119 values aren't final yet, so we must defer this. We will later
1120 have to create a RELATIVE reloc anyway, so we misuse the
1121 relocation slot to smuggle the symbol reference until
1122 fill_local_got_entries. Not that the sym_index is
1123 relative to symtab_section, not s1->dynsym! Nevertheless
1124 we use s1->dyn_sym so that if this is the first call
1125 that got->reloc is correctly created. Also note that
1126 RELATIVE relocs are not normally created for the .got,
1127 so the types serves as a marker for later (and is retained
1128 also for the final output, which is okay because then the
1129 got is just normal data). */
1130 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1131 sym_index);
1132 } else {
1133 if (0 == attr->dyn_index)
1134 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1135 sym->st_size, sym->st_info, 0,
1136 sym->st_shndx, name);
1137 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
1138 attr->dyn_index);
1140 } else {
1141 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1142 sym_index);
1145 if (need_plt_entry) {
1146 if (!s1->plt) {
1147 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1148 SHF_ALLOC | SHF_EXECINSTR);
1149 s1->plt->sh_entsize = 4;
1152 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1154 /* create a symbol 'sym@plt' for the PLT jump vector */
1155 len = strlen(name);
1156 if (len > sizeof plt_name - 5)
1157 len = sizeof plt_name - 5;
1158 memcpy(plt_name, name, len);
1159 strcpy(plt_name + len, "@plt");
1160 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
1161 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1163 } else {
1164 attr->got_offset = got_offset;
1167 return attr;
1170 /* build GOT and PLT entries */
1171 ST_FUNC void build_got_entries(TCCState *s1)
1173 Section *s;
1174 ElfW_Rel *rel;
1175 ElfW(Sym) *sym;
1176 int i, type, gotplt_entry, reloc_type, sym_index;
1177 struct sym_attr *attr;
1179 for(i = 1; i < s1->nb_sections; i++) {
1180 s = s1->sections[i];
1181 if (s->sh_type != SHT_RELX)
1182 continue;
1183 /* no need to handle got relocations */
1184 if (s->link != symtab_section)
1185 continue;
1186 for_each_elem(s, 0, rel, ElfW_Rel) {
1187 type = ELFW(R_TYPE)(rel->r_info);
1188 gotplt_entry = gotplt_entry_type(type);
1189 if (gotplt_entry == -1)
1190 tcc_error ("Unknown relocation type for got: %d", type);
1191 sym_index = ELFW(R_SYM)(rel->r_info);
1192 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1194 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1195 continue;
1198 /* Automatically create PLT/GOT [entry] if it is an undefined
1199 reference (resolved at runtime), or the symbol is absolute,
1200 probably created by tcc_add_symbol, and thus on 64-bit
1201 targets might be too far from application code. */
1202 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1203 if (sym->st_shndx == SHN_UNDEF) {
1204 ElfW(Sym) *esym;
1205 int dynindex;
1206 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1207 continue;
1208 /* Relocations for UNDEF symbols would normally need
1209 to be transferred into the executable or shared object.
1210 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1211 But TCC doesn't do that (at least for exes), so we
1212 need to resolve all such relocs locally. And that
1213 means PLT slots for functions in DLLs and COPY relocs for
1214 data symbols. COPY relocs were generated in
1215 bind_exe_dynsyms (and the symbol adjusted to be defined),
1216 and for functions we were generated a dynamic symbol
1217 of function type. */
1218 if (s1->dynsym) {
1219 /* dynsym isn't set for -run :-/ */
1220 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1221 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1222 if (dynindex
1223 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1224 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1225 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1226 goto jmp_slot;
1228 } else if (!(sym->st_shndx == SHN_ABS
1229 #ifndef TCC_TARGET_ARM
1230 && PTR_SIZE == 8
1231 #endif
1233 continue;
1236 #ifdef TCC_TARGET_X86_64
1237 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1238 sym->st_shndx != SHN_UNDEF &&
1239 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1240 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1241 s1->output_type == TCC_OUTPUT_EXE)) {
1242 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1243 continue;
1245 #endif
1246 reloc_type = code_reloc(type);
1247 if (reloc_type == -1)
1248 tcc_error ("Unknown relocation type: %d", type);
1249 else if (reloc_type != 0) {
1250 jmp_slot:
1251 reloc_type = R_JMP_SLOT;
1252 } else
1253 reloc_type = R_GLOB_DAT;
1255 if (!s1->got)
1256 build_got(s1);
1258 if (gotplt_entry == BUILD_GOT_ONLY)
1259 continue;
1261 attr = put_got_entry(s1, reloc_type, sym_index);
1263 if (reloc_type == R_JMP_SLOT)
1264 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1269 /* put dynamic tag */
1270 static void put_dt(Section *dynamic, int dt, addr_t val)
1272 ElfW(Dyn) *dyn;
1273 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1274 dyn->d_tag = dt;
1275 dyn->d_un.d_val = val;
1277 #endif
1279 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, long offs)
1281 int shn = sec ? sec->sh_num : offs ? SHN_ABS : SHN_UNDEF;
1282 if (sec && offs == -1)
1283 offs = sec->data_offset;
1284 return set_elf_sym(symtab_section, offs, 0,
1285 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1288 static void add_init_array_defines(TCCState *s1, const char *section_name)
1290 Section *s;
1291 long end_offset;
1292 char buf[1024];
1293 s = find_section(s1, section_name);
1294 if (!s) {
1295 end_offset = 0;
1296 s = data_section;
1297 } else {
1298 end_offset = s->data_offset;
1300 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1301 set_global_sym(s1, buf, s, 0);
1302 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1303 set_global_sym(s1, buf, s, end_offset);
1306 #ifndef TCC_TARGET_PE
1307 static int tcc_add_support(TCCState *s1, const char *filename)
1309 char buf[1024];
1310 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1311 return tcc_add_file(s1, buf);
1313 #endif
1315 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1317 Section *s;
1318 s = find_section(s1, sec);
1319 s->sh_flags |= SHF_WRITE;
1320 #ifndef TCC_TARGET_PE
1321 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1322 #endif
1323 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1324 section_ptr_add(s, PTR_SIZE);
1327 #ifdef CONFIG_TCC_BCHECK
1328 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1330 if (0 == s1->do_bounds_check)
1331 return;
1332 section_ptr_add(bounds_section, sizeof(addr_t));
1334 #endif
1336 #ifdef CONFIG_TCC_BACKTRACE
1337 static void put_ptr(TCCState *s1, Section *s, int offs)
1339 int c;
1340 c = set_global_sym(s1, NULL, s, offs);
1341 s = data_section;
1342 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1343 section_ptr_add(s, PTR_SIZE);
1346 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1347 a dynamic symbol to allow so's to have one each with a different value. */
1348 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1350 int c = find_elf_sym(s1->symtab, name);
1351 if (c) {
1352 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1353 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1354 esym->st_value = offset;
1355 esym->st_shndx = s->sh_num;
1359 ST_FUNC void tcc_add_btstub(TCCState *s1)
1361 Section *s;
1362 int n, o;
1363 CString cstr;
1365 s = data_section;
1366 o = s->data_offset;
1367 /* create (part of) a struct rt_context (see tccrun.c) */
1368 put_ptr(s1, stab_section, 0);
1369 put_ptr(s1, stab_section, -1);
1370 put_ptr(s1, stab_section->link, 0);
1371 section_ptr_add(s, 3 * PTR_SIZE);
1372 /* prog_base */
1373 put_elf_reloc(s1->symtab, s, s->data_offset, R_DATA_PTR, 0);
1374 section_ptr_add(s, PTR_SIZE);
1375 n = 2 * PTR_SIZE;
1376 #ifdef CONFIG_TCC_BCHECK
1377 if (s1->do_bounds_check) {
1378 put_ptr(s1, bounds_section, 0);
1379 n -= PTR_SIZE;
1381 #endif
1382 section_ptr_add(s, n);
1384 cstr_new(&cstr);
1385 cstr_printf(&cstr,
1386 " extern void __bt_init(),*__rt_info[],__bt_init_dll();"
1387 "__attribute__((constructor)) static void __bt_init_rt(){");
1388 #ifdef TCC_TARGET_PE
1389 if (s1->output_type == TCC_OUTPUT_DLL)
1390 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1391 #endif
1392 cstr_printf(&cstr, "__bt_init(__rt_info,%d);}",
1393 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1394 tcc_compile_string(s1, cstr.data);
1395 cstr_free(&cstr);
1396 set_local_sym(s1, "__rt_info", s, o);
1398 #endif
1400 #ifndef TCC_TARGET_PE
1401 /* add tcc runtime libraries */
1402 ST_FUNC void tcc_add_runtime(TCCState *s1)
1404 s1->filetype = 0;
1405 #ifdef CONFIG_TCC_BCHECK
1406 tcc_add_bcheck(s1);
1407 #endif
1408 tcc_add_pragma_libs(s1);
1409 /* add libc */
1410 if (!s1->nostdlib) {
1411 tcc_add_library_err(s1, "c");
1412 #ifdef TCC_LIBGCC
1413 if (!s1->static_link) {
1414 if (TCC_LIBGCC[0] == '/')
1415 tcc_add_file(s1, TCC_LIBGCC);
1416 else
1417 tcc_add_dll(s1, TCC_LIBGCC, 0);
1419 #endif
1420 #ifdef CONFIG_TCC_BCHECK
1421 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1422 tcc_add_library_err(s1, "pthread");
1423 tcc_add_library_err(s1, "dl");
1424 tcc_add_support(s1, "bcheck.o");
1426 #endif
1427 #ifdef CONFIG_TCC_BACKTRACE
1428 if (s1->do_backtrace) {
1429 if (s1->output_type == TCC_OUTPUT_EXE)
1430 tcc_add_support(s1, "bt-exe.o");
1431 if (s1->output_type != TCC_OUTPUT_DLL)
1432 tcc_add_support(s1, "bt-log.o");
1433 if (s1->output_type != TCC_OUTPUT_MEMORY)
1434 tcc_add_btstub(s1);
1436 #endif
1437 tcc_add_support(s1, TCC_LIBTCC1);
1438 /* add crt end if not memory output */
1439 if (s1->output_type != TCC_OUTPUT_MEMORY)
1440 tcc_add_crt(s1, "crtn.o");
1443 #endif
1445 /* add various standard linker symbols (must be done after the
1446 sections are filled (for example after allocating common
1447 symbols)) */
1448 static void tcc_add_linker_symbols(TCCState *s1)
1450 char buf[1024];
1451 int i;
1452 Section *s;
1454 set_global_sym(s1, "_etext", text_section, -1);
1455 set_global_sym(s1, "_edata", data_section, -1);
1456 set_global_sym(s1, "_end", bss_section, -1);
1457 #ifdef TCC_TARGET_RISCV64
1458 /* XXX should be .sdata+0x800, not .data+0x800 */
1459 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1460 #endif
1461 /* horrible new standard ldscript defines */
1462 add_init_array_defines(s1, ".preinit_array");
1463 add_init_array_defines(s1, ".init_array");
1464 add_init_array_defines(s1, ".fini_array");
1465 /* add start and stop symbols for sections whose name can be
1466 expressed in C */
1467 for(i = 1; i < s1->nb_sections; i++) {
1468 s = s1->sections[i];
1469 if ((s->sh_flags & SHF_ALLOC)
1470 && (s->sh_type == SHT_PROGBITS
1471 || s->sh_type == SHT_STRTAB)) {
1472 const char *p;
1473 /* check if section name can be expressed in C */
1474 p = s->name;
1475 for(;;) {
1476 int c = *p;
1477 if (!c)
1478 break;
1479 if (!isid(c) && !isnum(c))
1480 goto next_sec;
1481 p++;
1483 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1484 set_global_sym(s1, buf, s, 0);
1485 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1486 set_global_sym(s1, buf, s, -1);
1488 next_sec: ;
1492 ST_FUNC void resolve_common_syms(TCCState *s1)
1494 ElfW(Sym) *sym;
1496 /* Allocate common symbols in BSS. */
1497 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1498 if (sym->st_shndx == SHN_COMMON) {
1499 /* symbol alignment is in st_value for SHN_COMMONs */
1500 sym->st_value = section_add(bss_section, sym->st_size,
1501 sym->st_value);
1502 sym->st_shndx = bss_section->sh_num;
1506 /* Now assign linker provided symbols their value. */
1507 tcc_add_linker_symbols(s1);
1510 static void tcc_output_binary(TCCState *s1, FILE *f,
1511 const int *sec_order)
1513 Section *s;
1514 int i, offset, size;
1516 offset = 0;
1517 for(i=1;i<s1->nb_sections;i++) {
1518 s = s1->sections[sec_order[i]];
1519 if (s->sh_type != SHT_NOBITS &&
1520 (s->sh_flags & SHF_ALLOC)) {
1521 while (offset < s->sh_offset) {
1522 fputc(0, f);
1523 offset++;
1525 size = s->sh_size;
1526 fwrite(s->data, 1, size, f);
1527 offset += size;
1532 #ifndef ELF_OBJ_ONLY
1533 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1535 int sym_index = ELFW(R_SYM) (rel->r_info);
1536 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1537 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1538 unsigned offset = attr->got_offset;
1540 if (0 == offset)
1541 return;
1542 section_reserve(s1->got, offset + PTR_SIZE);
1543 #ifdef TCC_TARGET_X86_64
1544 write64le(s1->got->data + offset, sym->st_value);
1545 #else
1546 write32le(s1->got->data + offset, sym->st_value);
1547 #endif
1550 /* Perform relocation to GOT or PLT entries */
1551 ST_FUNC void fill_got(TCCState *s1)
1553 Section *s;
1554 ElfW_Rel *rel;
1555 int i;
1557 for(i = 1; i < s1->nb_sections; i++) {
1558 s = s1->sections[i];
1559 if (s->sh_type != SHT_RELX)
1560 continue;
1561 /* no need to handle got relocations */
1562 if (s->link != symtab_section)
1563 continue;
1564 for_each_elem(s, 0, rel, ElfW_Rel) {
1565 switch (ELFW(R_TYPE) (rel->r_info)) {
1566 case R_X86_64_GOT32:
1567 case R_X86_64_GOTPCREL:
1568 case R_X86_64_GOTPCRELX:
1569 case R_X86_64_REX_GOTPCRELX:
1570 case R_X86_64_PLT32:
1571 fill_got_entry(s1, rel);
1572 break;
1578 /* See put_got_entry for a description. This is the second stage
1579 where GOT references to local defined symbols are rewritten. */
1580 static void fill_local_got_entries(TCCState *s1)
1582 ElfW_Rel *rel;
1583 if (!s1->got->reloc)
1584 return;
1585 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1586 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1587 int sym_index = ELFW(R_SYM) (rel->r_info);
1588 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1589 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1590 unsigned offset = attr->got_offset;
1591 if (offset != rel->r_offset - s1->got->sh_addr)
1592 tcc_error_noabort("huh");
1593 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1594 #if SHT_RELX == SHT_RELA
1595 rel->r_addend = sym->st_value;
1596 #else
1597 /* All our REL architectures also happen to be 32bit LE. */
1598 write32le(s1->got->data + offset, sym->st_value);
1599 #endif
1604 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1605 in shared libraries and export non local defined symbols to shared libraries
1606 if -rdynamic switch was given on command line */
1607 static void bind_exe_dynsyms(TCCState *s1)
1609 const char *name;
1610 int sym_index, index;
1611 ElfW(Sym) *sym, *esym;
1612 int type;
1614 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1615 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1616 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1617 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1618 if (sym->st_shndx == SHN_UNDEF) {
1619 name = (char *) symtab_section->link->data + sym->st_name;
1620 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1621 if (sym_index) {
1622 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1623 type = ELFW(ST_TYPE)(esym->st_info);
1624 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1625 /* Indirect functions shall have STT_FUNC type in executable
1626 * dynsym section. Indeed, a dlsym call following a lazy
1627 * resolution would pick the symbol value from the
1628 * executable dynsym entry which would contain the address
1629 * of the function wanted by the caller of dlsym instead of
1630 * the address of the function that would return that
1631 * address */
1632 int dynindex
1633 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1634 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1635 name);
1636 int index = sym - (ElfW(Sym) *) symtab_section->data;
1637 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1638 } else if (type == STT_OBJECT) {
1639 unsigned long offset;
1640 ElfW(Sym) *dynsym;
1641 offset = bss_section->data_offset;
1642 /* XXX: which alignment ? */
1643 offset = (offset + 16 - 1) & -16;
1644 set_elf_sym (s1->symtab, offset, esym->st_size,
1645 esym->st_info, 0, bss_section->sh_num, name);
1646 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1647 esym->st_info, 0, bss_section->sh_num,
1648 name);
1650 /* Ensure R_COPY works for weak symbol aliases */
1651 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1652 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1653 if ((dynsym->st_value == esym->st_value)
1654 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1655 char *dynname = (char *) s1->dynsymtab_section->link->data
1656 + dynsym->st_name;
1657 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1658 dynsym->st_info, 0,
1659 bss_section->sh_num, dynname);
1660 break;
1665 put_elf_reloc(s1->dynsym, bss_section,
1666 offset, R_COPY, index);
1667 offset += esym->st_size;
1668 bss_section->data_offset = offset;
1670 } else {
1671 /* STB_WEAK undefined symbols are accepted */
1672 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1673 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1674 !strcmp(name, "_fp_hw")) {
1675 } else {
1676 tcc_error_noabort("undefined symbol '%s'", name);
1679 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1680 /* if -rdynamic option, then export all non local symbols */
1681 name = (char *) symtab_section->link->data + sym->st_name;
1682 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1683 0, sym->st_shndx, name);
1688 /* Bind symbols of libraries: export all non local symbols of executable that
1689 are referenced by shared libraries. The reason is that the dynamic loader
1690 search symbol first in executable and then in libraries. Therefore a
1691 reference to a symbol already defined by a library can still be resolved by
1692 a symbol in the executable. */
1693 static void bind_libs_dynsyms(TCCState *s1)
1695 const char *name;
1696 int sym_index;
1697 ElfW(Sym) *sym, *esym;
1699 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1700 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1701 sym_index = find_elf_sym(symtab_section, name);
1702 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1703 if (sym_index && sym->st_shndx != SHN_UNDEF
1704 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1705 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1706 sym->st_info, 0, sym->st_shndx, name);
1707 } else if (esym->st_shndx == SHN_UNDEF) {
1708 /* weak symbols can stay undefined */
1709 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1710 tcc_warning("undefined dynamic symbol '%s'", name);
1715 /* Export all non local symbols. This is used by shared libraries so that the
1716 non local symbols they define can resolve a reference in another shared
1717 library or in the executable. Correspondingly, it allows undefined local
1718 symbols to be resolved by other shared libraries or by the executable. */
1719 static void export_global_syms(TCCState *s1)
1721 int dynindex, index;
1722 const char *name;
1723 ElfW(Sym) *sym;
1725 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1726 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1727 name = (char *) symtab_section->link->data + sym->st_name;
1728 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1729 sym->st_info, 0, sym->st_shndx, name);
1730 index = sym - (ElfW(Sym) *) symtab_section->data;
1731 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1735 #endif
1737 /* Allocate strings for section names and decide if an unallocated section
1738 should be output.
1739 NOTE: the strsec section comes last, so its size is also correct ! */
1740 static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1742 int i;
1743 Section *s;
1744 int textrel = 0;
1746 /* Allocate strings for section names */
1747 for(i = 1; i < s1->nb_sections; i++) {
1748 s = s1->sections[i];
1749 /* when generating a DLL, we include relocations but we may
1750 patch them */
1751 #ifndef ELF_OBJ_ONLY
1752 if (file_type == TCC_OUTPUT_DLL &&
1753 s->sh_type == SHT_RELX &&
1754 !(s->sh_flags & SHF_ALLOC) &&
1755 (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
1756 prepare_dynamic_rel(s1, s)) {
1757 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1758 textrel = 1;
1759 } else
1760 #endif
1761 if ((s1->do_debug && s->sh_type != SHT_RELX) ||
1762 file_type == TCC_OUTPUT_OBJ ||
1763 (s->sh_flags & SHF_ALLOC) ||
1764 i == (s1->nb_sections - 1)) {
1765 /* we output all sections if debug or object file */
1766 s->sh_size = s->data_offset;
1768 if (s->sh_size || (s->sh_flags & SHF_ALLOC))
1769 s->sh_name = put_elf_str(strsec, s->name);
1771 strsec->sh_size = strsec->data_offset;
1772 return textrel;
1775 /* Info to be copied in dynamic section */
1776 struct dyn_inf {
1777 Section *dynamic;
1778 Section *dynstr;
1779 unsigned long data_offset;
1780 addr_t rel_addr;
1781 addr_t rel_size;
1782 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1783 addr_t bss_addr;
1784 addr_t bss_size;
1785 #endif
1788 /* Assign sections to segments and decide how are sections laid out when loaded
1789 in memory. This function also fills corresponding program headers. */
1790 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1791 Section *interp, Section* strsec,
1792 struct dyn_inf *dyninf, int *sec_order)
1794 int i, j, k, file_type, sh_order_index, file_offset;
1795 unsigned long s_align;
1796 long long tmp;
1797 addr_t addr;
1798 ElfW(Phdr) *ph;
1799 Section *s;
1801 file_type = s1->output_type;
1802 sh_order_index = 1;
1803 file_offset = 0;
1804 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1805 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1806 s_align = ELF_PAGE_SIZE;
1807 if (s1->section_align)
1808 s_align = s1->section_align;
1810 if (phnum > 0) {
1811 if (s1->has_text_addr) {
1812 int a_offset, p_offset;
1813 addr = s1->text_addr;
1814 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1815 ELF_PAGE_SIZE */
1816 a_offset = (int) (addr & (s_align - 1));
1817 p_offset = file_offset & (s_align - 1);
1818 if (a_offset < p_offset)
1819 a_offset += s_align;
1820 file_offset += (a_offset - p_offset);
1821 } else {
1822 if (file_type == TCC_OUTPUT_DLL)
1823 addr = 0;
1824 else
1825 addr = ELF_START_ADDR;
1826 /* compute address after headers */
1827 addr += (file_offset & (s_align - 1));
1830 ph = &phdr[0];
1831 /* Leave one program headers for the program interpreter and one for
1832 the program header table itself if needed. These are done later as
1833 they require section layout to be done first. */
1834 if (interp)
1835 ph += 2;
1837 /* dynamic relocation table information, for .dynamic section */
1838 dyninf->rel_addr = dyninf->rel_size = 0;
1839 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1840 dyninf->bss_addr = dyninf->bss_size = 0;
1841 #endif
1843 for(j = 0; j < 2; j++) {
1844 ph->p_type = PT_LOAD;
1845 if (j == 0)
1846 ph->p_flags = PF_R | PF_X;
1847 else
1848 ph->p_flags = PF_R | PF_W;
1849 ph->p_align = s_align;
1851 /* Decide the layout of sections loaded in memory. This must
1852 be done before program headers are filled since they contain
1853 info about the layout. We do the following ordering: interp,
1854 symbol tables, relocations, progbits, nobits */
1855 /* XXX: do faster and simpler sorting */
1856 for(k = 0; k < 5; k++) {
1857 for(i = 1; i < s1->nb_sections; i++) {
1858 s = s1->sections[i];
1859 /* compute if section should be included */
1860 if (j == 0) {
1861 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1862 SHF_ALLOC)
1863 continue;
1864 } else {
1865 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1866 (SHF_ALLOC | SHF_WRITE))
1867 continue;
1869 if (s == interp) {
1870 if (k != 0)
1871 continue;
1872 } else if ((s->sh_type == SHT_DYNSYM ||
1873 s->sh_type == SHT_STRTAB ||
1874 s->sh_type == SHT_HASH)
1875 && !strstr(s->name, ".stab")) {
1876 if (k != 1)
1877 continue;
1878 } else if (s->sh_type == SHT_RELX) {
1879 if (k != 2)
1880 continue;
1881 } else if (s->sh_type == SHT_NOBITS) {
1882 if (k != 4)
1883 continue;
1884 } else {
1885 if (k != 3)
1886 continue;
1888 sec_order[sh_order_index++] = i;
1890 /* section matches: we align it and add its size */
1891 tmp = addr;
1892 addr = (addr + s->sh_addralign - 1) &
1893 ~(s->sh_addralign - 1);
1894 file_offset += (int) ( addr - tmp );
1895 s->sh_offset = file_offset;
1896 s->sh_addr = addr;
1898 /* update program header infos */
1899 if (ph->p_offset == 0) {
1900 ph->p_offset = file_offset;
1901 ph->p_vaddr = addr;
1902 ph->p_paddr = ph->p_vaddr;
1904 /* update dynamic relocation infos */
1905 if (s->sh_type == SHT_RELX) {
1906 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1907 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1908 dyninf->rel_addr = addr;
1909 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1911 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1912 dyninf->bss_addr = addr;
1913 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1915 #else
1916 if (dyninf->rel_size == 0)
1917 dyninf->rel_addr = addr;
1918 dyninf->rel_size += s->sh_size;
1919 #endif
1921 addr += s->sh_size;
1922 if (s->sh_type != SHT_NOBITS)
1923 file_offset += s->sh_size;
1926 if (j == 0) {
1927 /* Make the first PT_LOAD segment include the program
1928 headers itself (and the ELF header as well), it'll
1929 come out with same memory use but will make various
1930 tools like binutils strip work better. */
1931 ph->p_offset &= ~(ph->p_align - 1);
1932 ph->p_vaddr &= ~(ph->p_align - 1);
1933 ph->p_paddr &= ~(ph->p_align - 1);
1935 ph->p_filesz = file_offset - ph->p_offset;
1936 ph->p_memsz = addr - ph->p_vaddr;
1937 ph++;
1938 if (j == 0) {
1939 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1940 /* if in the middle of a page, we duplicate the page in
1941 memory so that one copy is RX and the other is RW */
1942 if ((addr & (s_align - 1)) != 0)
1943 addr += s_align;
1944 } else {
1945 addr = (addr + s_align - 1) & ~(s_align - 1);
1946 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1952 /* all other sections come after */
1953 for(i = 1; i < s1->nb_sections; i++) {
1954 s = s1->sections[i];
1955 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1956 continue;
1957 sec_order[sh_order_index++] = i;
1959 file_offset = (file_offset + s->sh_addralign - 1) &
1960 ~(s->sh_addralign - 1);
1961 s->sh_offset = file_offset;
1962 if (s->sh_type != SHT_NOBITS)
1963 file_offset += s->sh_size;
1966 return file_offset;
1969 #ifndef ELF_OBJ_ONLY
1970 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1971 Section *dynamic)
1973 ElfW(Phdr) *ph;
1975 /* if interpreter, then add corresponding program header */
1976 if (interp) {
1977 ph = &phdr[0];
1979 ph->p_type = PT_PHDR;
1980 ph->p_offset = sizeof(ElfW(Ehdr));
1981 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
1982 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
1983 ph->p_paddr = ph->p_vaddr;
1984 ph->p_flags = PF_R | PF_X;
1985 ph->p_align = 4; /* interp->sh_addralign; */
1986 ph++;
1988 ph->p_type = PT_INTERP;
1989 ph->p_offset = interp->sh_offset;
1990 ph->p_vaddr = interp->sh_addr;
1991 ph->p_paddr = ph->p_vaddr;
1992 ph->p_filesz = interp->sh_size;
1993 ph->p_memsz = interp->sh_size;
1994 ph->p_flags = PF_R;
1995 ph->p_align = interp->sh_addralign;
1998 /* if dynamic section, then add corresponding program header */
1999 if (dynamic) {
2000 ph = &phdr[phnum - 1];
2002 ph->p_type = PT_DYNAMIC;
2003 ph->p_offset = dynamic->sh_offset;
2004 ph->p_vaddr = dynamic->sh_addr;
2005 ph->p_paddr = ph->p_vaddr;
2006 ph->p_filesz = dynamic->sh_size;
2007 ph->p_memsz = dynamic->sh_size;
2008 ph->p_flags = PF_R | PF_W;
2009 ph->p_align = dynamic->sh_addralign;
2013 /* Fill the dynamic section with tags describing the address and size of
2014 sections */
2015 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2017 Section *dynamic = dyninf->dynamic;
2018 Section *s;
2020 /* put dynamic section entries */
2021 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2022 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2023 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2024 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2025 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2026 #if PTR_SIZE == 8
2027 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2028 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2029 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2030 #else
2031 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2032 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2033 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
2034 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2035 put_dt(dynamic, DT_PLTREL, DT_REL);
2036 put_dt(dynamic, DT_REL, dyninf->bss_addr);
2037 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
2038 #else
2039 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2040 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2041 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2042 #endif
2043 #endif
2044 if (versym_section) {
2045 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2046 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2047 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2049 s = find_section_create (s1, ".preinit_array", 0);
2050 if (s && s->data_offset) {
2051 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2052 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2054 s = find_section_create (s1, ".init_array", 0);
2055 if (s && s->data_offset) {
2056 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2057 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2059 s = find_section_create (s1, ".fini_array", 0);
2060 if (s && s->data_offset) {
2061 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2062 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2064 s = find_section_create (s1, ".init", 0);
2065 if (s && s->data_offset) {
2066 put_dt(dynamic, DT_INIT, s->sh_addr);
2068 s = find_section_create (s1, ".fini", 0);
2069 if (s && s->data_offset) {
2070 put_dt(dynamic, DT_FINI, s->sh_addr);
2072 if (s1->do_debug)
2073 put_dt(dynamic, DT_DEBUG, 0);
2074 put_dt(dynamic, DT_NULL, 0);
2077 /* Relocate remaining sections and symbols (that is those not related to
2078 dynamic linking) */
2079 static int final_sections_reloc(TCCState *s1)
2081 int i;
2082 Section *s;
2084 relocate_syms(s1, s1->symtab, 0);
2086 if (s1->nb_errors != 0)
2087 return -1;
2089 /* relocate sections */
2090 /* XXX: ignore sections with allocated relocations ? */
2091 for(i = 1; i < s1->nb_sections; i++) {
2092 s = s1->sections[i];
2093 if (s->reloc && (s != s1->got || s1->static_link))
2094 relocate_section(s1, s);
2097 /* relocate relocation entries if the relocation tables are
2098 allocated in the executable */
2099 for(i = 1; i < s1->nb_sections; i++) {
2100 s = s1->sections[i];
2101 if ((s->sh_flags & SHF_ALLOC) &&
2102 s->sh_type == SHT_RELX) {
2103 relocate_rel(s1, s);
2106 return 0;
2108 #endif
2110 /* Create an ELF file on disk.
2111 This function handle ELF specific layout requirements */
2112 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2113 int file_offset, int *sec_order)
2115 int i, shnum, offset, size, file_type;
2116 Section *s;
2117 ElfW(Ehdr) ehdr;
2118 ElfW(Shdr) shdr, *sh;
2120 file_type = s1->output_type;
2121 shnum = s1->nb_sections;
2123 memset(&ehdr, 0, sizeof(ehdr));
2125 if (phnum > 0) {
2126 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2127 ehdr.e_phnum = phnum;
2128 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2131 /* align to 4 */
2132 file_offset = (file_offset + 3) & -4;
2134 /* fill header */
2135 ehdr.e_ident[0] = ELFMAG0;
2136 ehdr.e_ident[1] = ELFMAG1;
2137 ehdr.e_ident[2] = ELFMAG2;
2138 ehdr.e_ident[3] = ELFMAG3;
2139 ehdr.e_ident[4] = ELFCLASSW;
2140 ehdr.e_ident[5] = ELFDATA2LSB;
2141 ehdr.e_ident[6] = EV_CURRENT;
2142 #if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
2143 /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
2144 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2145 #endif
2146 #ifdef TCC_TARGET_ARM
2147 #ifdef TCC_ARM_EABI
2148 ehdr.e_ident[EI_OSABI] = 0;
2149 ehdr.e_flags = EF_ARM_EABI_VER4;
2150 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2151 ehdr.e_flags |= EF_ARM_HASENTRY;
2152 if (s1->float_abi == ARM_HARD_FLOAT)
2153 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2154 else
2155 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2156 #else
2157 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2158 #endif
2159 #elif defined TCC_TARGET_RISCV64
2160 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2161 #endif
2162 switch(file_type) {
2163 default:
2164 case TCC_OUTPUT_EXE:
2165 ehdr.e_type = ET_EXEC;
2166 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
2167 break;
2168 case TCC_OUTPUT_DLL:
2169 ehdr.e_type = ET_DYN;
2170 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2171 break;
2172 case TCC_OUTPUT_OBJ:
2173 ehdr.e_type = ET_REL;
2174 break;
2176 ehdr.e_machine = EM_TCC_TARGET;
2177 ehdr.e_version = EV_CURRENT;
2178 ehdr.e_shoff = file_offset;
2179 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2180 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2181 ehdr.e_shnum = shnum;
2182 ehdr.e_shstrndx = shnum - 1;
2184 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2185 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2186 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2188 sort_syms(s1, symtab_section);
2189 for(i = 1; i < s1->nb_sections; i++) {
2190 s = s1->sections[sec_order[i]];
2191 if (s->sh_type != SHT_NOBITS) {
2192 while (offset < s->sh_offset) {
2193 fputc(0, f);
2194 offset++;
2196 size = s->sh_size;
2197 if (size)
2198 fwrite(s->data, 1, size, f);
2199 offset += size;
2203 /* output section headers */
2204 while (offset < ehdr.e_shoff) {
2205 fputc(0, f);
2206 offset++;
2209 for(i = 0; i < s1->nb_sections; i++) {
2210 sh = &shdr;
2211 memset(sh, 0, sizeof(ElfW(Shdr)));
2212 s = s1->sections[i];
2213 if (s) {
2214 sh->sh_name = s->sh_name;
2215 sh->sh_type = s->sh_type;
2216 sh->sh_flags = s->sh_flags;
2217 sh->sh_entsize = s->sh_entsize;
2218 sh->sh_info = s->sh_info;
2219 if (s->link)
2220 sh->sh_link = s->link->sh_num;
2221 sh->sh_addralign = s->sh_addralign;
2222 sh->sh_addr = s->sh_addr;
2223 sh->sh_offset = s->sh_offset;
2224 sh->sh_size = s->sh_size;
2226 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2230 /* Write an elf, coff or "binary" file */
2231 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2232 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2234 int fd, mode, file_type;
2235 FILE *f;
2237 file_type = s1->output_type;
2238 if (file_type == TCC_OUTPUT_OBJ)
2239 mode = 0666;
2240 else
2241 mode = 0777;
2242 unlink(filename);
2243 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2244 if (fd < 0) {
2245 tcc_error_noabort("could not write '%s'", filename);
2246 return -1;
2248 f = fdopen(fd, "wb");
2249 if (s1->verbose)
2250 printf("<- %s\n", filename);
2252 #ifdef TCC_TARGET_COFF
2253 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2254 tcc_output_coff(s1, f);
2255 else
2256 #endif
2257 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2258 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2259 else
2260 tcc_output_binary(s1, f, sec_order);
2261 fclose(f);
2263 return 0;
2266 #ifndef ELF_OBJ_ONLY
2267 /* Sort section headers by assigned sh_addr, remove sections
2268 that we aren't going to output. */
2269 static void tidy_section_headers(TCCState *s1, int *sec_order)
2271 int i, nnew, l, *backmap;
2272 Section **snew, *s;
2273 ElfW(Sym) *sym;
2275 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2276 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2277 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2278 s = s1->sections[sec_order[i]];
2279 if (!i || s->sh_name) {
2280 backmap[sec_order[i]] = nnew;
2281 snew[nnew] = s;
2282 ++nnew;
2283 } else {
2284 backmap[sec_order[i]] = 0;
2285 snew[--l] = s;
2288 for (i = 0; i < nnew; i++) {
2289 s = snew[i];
2290 if (s) {
2291 s->sh_num = i;
2292 if (s->sh_type == SHT_RELX)
2293 s->sh_info = backmap[s->sh_info];
2297 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2298 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2299 sym->st_shndx = backmap[sym->st_shndx];
2300 if( !s1->static_link ) {
2301 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2302 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2303 sym->st_shndx = backmap[sym->st_shndx];
2305 for (i = 0; i < s1->nb_sections; i++)
2306 sec_order[i] = i;
2307 tcc_free(s1->sections);
2308 s1->sections = snew;
2309 s1->nb_sections = nnew;
2310 tcc_free(backmap);
2312 #endif
2314 /* Output an elf, coff or binary file */
2315 /* XXX: suppress unneeded sections */
2316 static int elf_output_file(TCCState *s1, const char *filename)
2318 int ret, phnum, shnum, file_type, file_offset, *sec_order;
2319 struct dyn_inf dyninf = {0};
2320 ElfW(Phdr) *phdr;
2321 Section *strsec, *interp, *dynamic, *dynstr;
2323 file_type = s1->output_type;
2324 s1->nb_errors = 0;
2325 ret = -1;
2326 phdr = NULL;
2327 sec_order = NULL;
2328 interp = dynamic = dynstr = NULL; /* avoid warning */
2330 #ifndef ELF_OBJ_ONLY
2331 if (file_type != TCC_OUTPUT_OBJ) {
2332 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2333 tcc_add_runtime(s1);
2334 resolve_common_syms(s1);
2336 if (!s1->static_link) {
2337 if (file_type == TCC_OUTPUT_EXE) {
2338 char *ptr;
2339 /* allow override the dynamic loader */
2340 const char *elfint = getenv("LD_SO");
2341 if (elfint == NULL)
2342 elfint = DEFAULT_ELFINTERP(s1);
2343 /* add interpreter section only if executable */
2344 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2345 interp->sh_addralign = 1;
2346 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2347 strcpy(ptr, elfint);
2350 /* add dynamic symbol table */
2351 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2352 ".dynstr",
2353 ".hash", SHF_ALLOC);
2354 dynstr = s1->dynsym->link;
2355 /* add dynamic section */
2356 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2357 SHF_ALLOC | SHF_WRITE);
2358 dynamic->link = dynstr;
2359 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2361 build_got(s1);
2363 if (file_type == TCC_OUTPUT_EXE) {
2364 bind_exe_dynsyms(s1);
2365 if (s1->nb_errors)
2366 goto the_end;
2367 bind_libs_dynsyms(s1);
2368 } else {
2369 /* shared library case: simply export all global symbols */
2370 export_global_syms(s1);
2373 build_got_entries(s1);
2374 version_add (s1);
2376 #endif
2378 /* we add a section for symbols */
2379 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2380 put_elf_str(strsec, "");
2382 /* Allocate strings for section names */
2383 ret = alloc_sec_names(s1, file_type, strsec);
2385 #ifndef ELF_OBJ_ONLY
2386 if (dynamic) {
2387 int i;
2388 /* add a list of needed dlls */
2389 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2390 DLLReference *dllref = s1->loaded_dlls[i];
2391 if (dllref->level == 0)
2392 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2395 if (s1->rpath)
2396 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2397 put_elf_str(dynstr, s1->rpath));
2399 if (file_type == TCC_OUTPUT_DLL) {
2400 if (s1->soname)
2401 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2402 /* XXX: currently, since we do not handle PIC code, we
2403 must relocate the readonly segments */
2404 if (ret)
2405 put_dt(dynamic, DT_TEXTREL, 0);
2408 if (s1->symbolic)
2409 put_dt(dynamic, DT_SYMBOLIC, 0);
2411 dyninf.dynamic = dynamic;
2412 dyninf.dynstr = dynstr;
2413 /* remember offset and reserve space for 2nd call below */
2414 dyninf.data_offset = dynamic->data_offset;
2415 fill_dynamic(s1, &dyninf);
2416 dynamic->sh_size = dynamic->data_offset;
2417 dynstr->sh_size = dynstr->data_offset;
2419 #endif
2421 /* compute number of program headers */
2422 if (file_type == TCC_OUTPUT_OBJ)
2423 phnum = 0;
2424 else if (file_type == TCC_OUTPUT_DLL)
2425 phnum = 3;
2426 else if (s1->static_link)
2427 phnum = 2;
2428 else
2429 phnum = 5;
2431 /* allocate program segment headers */
2432 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2434 /* compute number of sections */
2435 shnum = s1->nb_sections;
2437 /* this array is used to reorder sections in the output file */
2438 sec_order = tcc_malloc(sizeof(int) * shnum);
2439 sec_order[0] = 0;
2441 /* compute section to program header mapping */
2442 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2443 sec_order);
2445 #ifndef ELF_OBJ_ONLY
2446 /* Fill remaining program header and finalize relocation related to dynamic
2447 linking. */
2448 if (file_type != TCC_OUTPUT_OBJ) {
2449 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2450 if (dynamic) {
2451 ElfW(Sym) *sym;
2452 dynamic->data_offset = dyninf.data_offset;
2453 fill_dynamic(s1, &dyninf);
2455 /* put in GOT the dynamic section address and relocate PLT */
2456 write32le(s1->got->data, dynamic->sh_addr);
2457 if (file_type == TCC_OUTPUT_EXE
2458 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2459 relocate_plt(s1);
2461 /* relocate symbols in .dynsym now that final addresses are known */
2462 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2463 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2464 /* do symbol relocation */
2465 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2470 /* if building executable or DLL, then relocate each section
2471 except the GOT which is already relocated */
2472 ret = final_sections_reloc(s1);
2473 if (ret)
2474 goto the_end;
2475 tidy_section_headers(s1, sec_order);
2477 /* Perform relocation to GOT or PLT entries */
2478 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2479 fill_got(s1);
2480 else if (s1->got)
2481 fill_local_got_entries(s1);
2483 #endif
2485 /* Create the ELF file with name 'filename' */
2486 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2487 s1->nb_sections = shnum;
2488 goto the_end;
2489 the_end:
2490 tcc_free(sec_order);
2491 tcc_free(phdr);
2492 return ret;
2495 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2497 int ret;
2498 #ifdef TCC_TARGET_PE
2499 if (s->output_type != TCC_OUTPUT_OBJ) {
2500 ret = pe_output_file(s, filename);
2501 } else
2502 #endif
2503 ret = elf_output_file(s, filename);
2504 return ret;
2507 ssize_t full_read(int fd, void *buf, size_t count) {
2508 char *cbuf = buf;
2509 size_t rnum = 0;
2510 while (1) {
2511 ssize_t num = read(fd, cbuf, count-rnum);
2512 if (num < 0) return num;
2513 if (num == 0) return rnum;
2514 rnum += num;
2515 cbuf += num;
2519 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2521 void *data;
2523 data = tcc_malloc(size);
2524 lseek(fd, file_offset, SEEK_SET);
2525 full_read(fd, data, size);
2526 return data;
2529 typedef struct SectionMergeInfo {
2530 Section *s; /* corresponding existing section */
2531 unsigned long offset; /* offset of the new section in the existing section */
2532 uint8_t new_section; /* true if section 's' was added */
2533 uint8_t link_once; /* true if link once section */
2534 } SectionMergeInfo;
2536 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2538 int size = full_read(fd, h, sizeof *h);
2539 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2540 if (h->e_type == ET_REL)
2541 return AFF_BINTYPE_REL;
2542 if (h->e_type == ET_DYN)
2543 return AFF_BINTYPE_DYN;
2544 } else if (size >= 8) {
2545 if (0 == memcmp(h, ARMAG, 8))
2546 return AFF_BINTYPE_AR;
2547 #ifdef TCC_TARGET_COFF
2548 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2549 return AFF_BINTYPE_C67;
2550 #endif
2552 return 0;
2555 /* load an object file and merge it with current files */
2556 /* XXX: handle correctly stab (debug) info */
2557 ST_FUNC int tcc_load_object_file(TCCState *s1,
2558 int fd, unsigned long file_offset)
2560 ElfW(Ehdr) ehdr;
2561 ElfW(Shdr) *shdr, *sh;
2562 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2563 char *strsec, *strtab;
2564 int stab_index, stabstr_index;
2565 int *old_to_new_syms;
2566 char *sh_name, *name;
2567 SectionMergeInfo *sm_table, *sm;
2568 ElfW(Sym) *sym, *symtab;
2569 ElfW_Rel *rel;
2570 Section *s;
2572 lseek(fd, file_offset, SEEK_SET);
2573 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2574 goto fail1;
2575 /* test CPU specific stuff */
2576 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2577 ehdr.e_machine != EM_TCC_TARGET) {
2578 fail1:
2579 tcc_error_noabort("invalid object file");
2580 return -1;
2582 /* read sections */
2583 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2584 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2585 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2587 /* load section names */
2588 sh = &shdr[ehdr.e_shstrndx];
2589 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2591 /* load symtab and strtab */
2592 old_to_new_syms = NULL;
2593 symtab = NULL;
2594 strtab = NULL;
2595 nb_syms = 0;
2596 seencompressed = 0;
2597 stab_index = stabstr_index = 0;
2599 for(i = 1; i < ehdr.e_shnum; i++) {
2600 sh = &shdr[i];
2601 if (sh->sh_type == SHT_SYMTAB) {
2602 if (symtab) {
2603 tcc_error_noabort("object must contain only one symtab");
2604 fail:
2605 ret = -1;
2606 goto the_end;
2608 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2609 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2610 sm_table[i].s = symtab_section;
2612 /* now load strtab */
2613 sh = &shdr[sh->sh_link];
2614 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2616 if (sh->sh_flags & SHF_COMPRESSED)
2617 seencompressed = 1;
2620 /* now examine each section and try to merge its content with the
2621 ones in memory */
2622 for(i = 1; i < ehdr.e_shnum; i++) {
2623 /* no need to examine section name strtab */
2624 if (i == ehdr.e_shstrndx)
2625 continue;
2626 sh = &shdr[i];
2627 if (sh->sh_type == SHT_RELX)
2628 sh = &shdr[sh->sh_info];
2629 /* ignore sections types we do not handle (plus relocs to those) */
2630 if (sh->sh_type != SHT_PROGBITS &&
2631 #ifdef TCC_ARM_EABI
2632 sh->sh_type != SHT_ARM_EXIDX &&
2633 #endif
2634 sh->sh_type != SHT_NOBITS &&
2635 sh->sh_type != SHT_PREINIT_ARRAY &&
2636 sh->sh_type != SHT_INIT_ARRAY &&
2637 sh->sh_type != SHT_FINI_ARRAY &&
2638 strcmp(strsec + sh->sh_name, ".stabstr")
2640 continue;
2641 if (seencompressed
2642 && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
2643 continue;
2645 sh = &shdr[i];
2646 sh_name = strsec + sh->sh_name;
2647 if (sh->sh_addralign < 1)
2648 sh->sh_addralign = 1;
2649 /* find corresponding section, if any */
2650 for(j = 1; j < s1->nb_sections;j++) {
2651 s = s1->sections[j];
2652 if (!strcmp(s->name, sh_name)) {
2653 if (!strncmp(sh_name, ".gnu.linkonce",
2654 sizeof(".gnu.linkonce") - 1)) {
2655 /* if a 'linkonce' section is already present, we
2656 do not add it again. It is a little tricky as
2657 symbols can still be defined in
2658 it. */
2659 sm_table[i].link_once = 1;
2660 goto next;
2662 if (stab_section) {
2663 if (s == stab_section)
2664 stab_index = i;
2665 if (s == stab_section->link)
2666 stabstr_index = i;
2668 goto found;
2671 /* not found: create new section */
2672 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2673 /* take as much info as possible from the section. sh_link and
2674 sh_info will be updated later */
2675 s->sh_addralign = sh->sh_addralign;
2676 s->sh_entsize = sh->sh_entsize;
2677 sm_table[i].new_section = 1;
2678 found:
2679 if (sh->sh_type != s->sh_type) {
2680 tcc_error_noabort("invalid section type");
2681 goto fail;
2683 /* align start of section */
2684 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
2685 if (sh->sh_addralign > s->sh_addralign)
2686 s->sh_addralign = sh->sh_addralign;
2687 sm_table[i].offset = s->data_offset;
2688 sm_table[i].s = s;
2689 /* concatenate sections */
2690 size = sh->sh_size;
2691 if (sh->sh_type != SHT_NOBITS) {
2692 unsigned char *ptr;
2693 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2694 ptr = section_ptr_add(s, size);
2695 full_read(fd, ptr, size);
2696 } else {
2697 s->data_offset += size;
2699 next: ;
2702 /* gr relocate stab strings */
2703 if (stab_index && stabstr_index) {
2704 Stab_Sym *a, *b;
2705 unsigned o;
2706 s = sm_table[stab_index].s;
2707 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2708 b = (Stab_Sym *)(s->data + s->data_offset);
2709 o = sm_table[stabstr_index].offset;
2710 while (a < b) {
2711 if (a->n_strx)
2712 a->n_strx += o;
2713 a++;
2717 /* second short pass to update sh_link and sh_info fields of new
2718 sections */
2719 for(i = 1; i < ehdr.e_shnum; i++) {
2720 s = sm_table[i].s;
2721 if (!s || !sm_table[i].new_section)
2722 continue;
2723 sh = &shdr[i];
2724 if (sh->sh_link > 0)
2725 s->link = sm_table[sh->sh_link].s;
2726 if (sh->sh_type == SHT_RELX) {
2727 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2728 /* update backward link */
2729 s1->sections[s->sh_info]->reloc = s;
2733 /* resolve symbols */
2734 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2736 sym = symtab + 1;
2737 for(i = 1; i < nb_syms; i++, sym++) {
2738 if (sym->st_shndx != SHN_UNDEF &&
2739 sym->st_shndx < SHN_LORESERVE) {
2740 sm = &sm_table[sym->st_shndx];
2741 if (sm->link_once) {
2742 /* if a symbol is in a link once section, we use the
2743 already defined symbol. It is very important to get
2744 correct relocations */
2745 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2746 name = strtab + sym->st_name;
2747 sym_index = find_elf_sym(symtab_section, name);
2748 if (sym_index)
2749 old_to_new_syms[i] = sym_index;
2751 continue;
2753 /* if no corresponding section added, no need to add symbol */
2754 if (!sm->s)
2755 continue;
2756 /* convert section number */
2757 sym->st_shndx = sm->s->sh_num;
2758 /* offset value */
2759 sym->st_value += sm->offset;
2761 /* add symbol */
2762 name = strtab + sym->st_name;
2763 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2764 sym->st_info, sym->st_other,
2765 sym->st_shndx, name);
2766 old_to_new_syms[i] = sym_index;
2769 /* third pass to patch relocation entries */
2770 for(i = 1; i < ehdr.e_shnum; i++) {
2771 s = sm_table[i].s;
2772 if (!s)
2773 continue;
2774 sh = &shdr[i];
2775 offset = sm_table[i].offset;
2776 switch(s->sh_type) {
2777 case SHT_RELX:
2778 /* take relocation offset information */
2779 offseti = sm_table[sh->sh_info].offset;
2780 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2781 int type;
2782 unsigned sym_index;
2783 /* convert symbol index */
2784 type = ELFW(R_TYPE)(rel->r_info);
2785 sym_index = ELFW(R_SYM)(rel->r_info);
2786 /* NOTE: only one symtab assumed */
2787 if (sym_index >= nb_syms)
2788 goto invalid_reloc;
2789 sym_index = old_to_new_syms[sym_index];
2790 /* ignore link_once in rel section. */
2791 if (!sym_index && !sm_table[sh->sh_info].link_once
2792 #ifdef TCC_TARGET_ARM
2793 && type != R_ARM_V4BX
2794 #elif defined TCC_TARGET_RISCV64
2795 && type != R_RISCV_ALIGN
2796 && type != R_RISCV_RELAX
2797 #endif
2799 invalid_reloc:
2800 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2801 i, strsec + sh->sh_name, rel->r_offset);
2802 goto fail;
2804 rel->r_info = ELFW(R_INFO)(sym_index, type);
2805 /* offset the relocation offset */
2806 rel->r_offset += offseti;
2807 #ifdef TCC_TARGET_ARM
2808 /* Jumps and branches from a Thumb code to a PLT entry need
2809 special handling since PLT entries are ARM code.
2810 Unconditional bl instructions referencing PLT entries are
2811 handled by converting these instructions into blx
2812 instructions. Other case of instructions referencing a PLT
2813 entry require to add a Thumb stub before the PLT entry to
2814 switch to ARM mode. We set bit plt_thumb_stub of the
2815 attribute of a symbol to indicate such a case. */
2816 if (type == R_ARM_THM_JUMP24)
2817 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2818 #endif
2820 break;
2821 default:
2822 break;
2826 ret = 0;
2827 the_end:
2828 tcc_free(symtab);
2829 tcc_free(strtab);
2830 tcc_free(old_to_new_syms);
2831 tcc_free(sm_table);
2832 tcc_free(strsec);
2833 tcc_free(shdr);
2834 return ret;
2837 typedef struct ArchiveHeader {
2838 char ar_name[16]; /* name of this member */
2839 char ar_date[12]; /* file mtime */
2840 char ar_uid[6]; /* owner uid; printed as decimal */
2841 char ar_gid[6]; /* owner gid; printed as decimal */
2842 char ar_mode[8]; /* file mode, printed as octal */
2843 char ar_size[10]; /* file size, printed as decimal */
2844 char ar_fmag[2]; /* should contain ARFMAG */
2845 } ArchiveHeader;
2847 #define ARFMAG "`\n"
2849 static unsigned long long get_be(const uint8_t *b, int n)
2851 unsigned long long ret = 0;
2852 while (n)
2853 ret = (ret << 8) | *b++, --n;
2854 return ret;
2857 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
2859 char *p, *e;
2860 int len;
2861 lseek(fd, offset, SEEK_SET);
2862 len = full_read(fd, hdr, sizeof(ArchiveHeader));
2863 if (len != sizeof(ArchiveHeader))
2864 return len ? -1 : 0;
2865 p = hdr->ar_name;
2866 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
2867 --e;
2868 *e = '\0';
2869 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
2870 return len;
2873 /* load only the objects which resolve undefined symbols */
2874 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2876 int i, bound, nsyms, sym_index, len, ret = -1;
2877 unsigned long long off;
2878 uint8_t *data;
2879 const char *ar_names, *p;
2880 const uint8_t *ar_index;
2881 ElfW(Sym) *sym;
2882 ArchiveHeader hdr;
2884 data = tcc_malloc(size);
2885 if (full_read(fd, data, size) != size)
2886 goto the_end;
2887 nsyms = get_be(data, entrysize);
2888 ar_index = data + entrysize;
2889 ar_names = (char *) ar_index + nsyms * entrysize;
2891 do {
2892 bound = 0;
2893 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2894 Section *s = symtab_section;
2895 sym_index = find_elf_sym(s, p);
2896 if (!sym_index)
2897 continue;
2898 sym = &((ElfW(Sym) *)s->data)[sym_index];
2899 if(sym->st_shndx != SHN_UNDEF)
2900 continue;
2901 off = get_be(ar_index + i * entrysize, entrysize);
2902 len = read_ar_header(fd, off, &hdr);
2903 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
2904 tcc_error_noabort("invalid archive");
2905 goto the_end;
2907 off += len;
2908 if (s1->verbose == 2)
2909 printf(" -> %s\n", hdr.ar_name);
2910 if (tcc_load_object_file(s1, fd, off) < 0)
2911 goto the_end;
2912 ++bound;
2914 } while(bound);
2915 ret = 0;
2916 the_end:
2917 tcc_free(data);
2918 return ret;
2921 /* load a '.a' file */
2922 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
2924 ArchiveHeader hdr;
2925 /* char magic[8]; */
2926 int size, len;
2927 unsigned long file_offset;
2928 ElfW(Ehdr) ehdr;
2930 /* skip magic which was already checked */
2931 /* full_read(fd, magic, sizeof(magic)); */
2932 file_offset = sizeof ARMAG - 1;
2934 for(;;) {
2935 len = read_ar_header(fd, file_offset, &hdr);
2936 if (len == 0)
2937 return 0;
2938 if (len < 0) {
2939 tcc_error_noabort("invalid archive");
2940 return -1;
2942 file_offset += len;
2943 size = strtol(hdr.ar_size, NULL, 0);
2944 /* align to even */
2945 size = (size + 1) & ~1;
2946 if (alacarte) {
2947 /* coff symbol table : we handle it */
2948 if (!strcmp(hdr.ar_name, "/"))
2949 return tcc_load_alacarte(s1, fd, size, 4);
2950 if (!strcmp(hdr.ar_name, "/SYM64/"))
2951 return tcc_load_alacarte(s1, fd, size, 8);
2952 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2953 if (s1->verbose == 2)
2954 printf(" -> %s\n", hdr.ar_name);
2955 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2956 return -1;
2958 file_offset += size;
2962 #ifndef ELF_OBJ_ONLY
2963 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
2964 LV, maybe create a new entry for (LIB,VERSION). */
2965 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
2967 while (i >= *n) {
2968 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
2969 (*lv)[(*n)++] = -1;
2971 if ((*lv)[i] == -1) {
2972 int v, prev_same_lib = -1;
2973 for (v = 0; v < nb_sym_versions; v++) {
2974 if (strcmp(sym_versions[v].lib, lib))
2975 continue;
2976 prev_same_lib = v;
2977 if (!strcmp(sym_versions[v].version, version))
2978 break;
2980 if (v == nb_sym_versions) {
2981 sym_versions = tcc_realloc (sym_versions,
2982 (v + 1) * sizeof(*sym_versions));
2983 sym_versions[v].lib = tcc_strdup(lib);
2984 sym_versions[v].version = tcc_strdup(version);
2985 sym_versions[v].out_index = 0;
2986 sym_versions[v].prev_same_lib = prev_same_lib;
2987 nb_sym_versions++;
2989 (*lv)[i] = v;
2993 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
2994 VERNDX. */
2995 static void
2996 set_sym_version(TCCState *s1, int sym_index, int verndx)
2998 if (sym_index >= nb_sym_to_version) {
2999 int newelems = sym_index ? sym_index * 2 : 1;
3000 sym_to_version = tcc_realloc(sym_to_version,
3001 newelems * sizeof(*sym_to_version));
3002 memset(sym_to_version + nb_sym_to_version, -1,
3003 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3004 nb_sym_to_version = newelems;
3006 if (sym_to_version[sym_index] < 0)
3007 sym_to_version[sym_index] = verndx;
3010 struct versym_info {
3011 int nb_versyms;
3012 ElfW(Verdef) *verdef;
3013 ElfW(Verneed) *verneed;
3014 ElfW(Half) *versym;
3015 int nb_local_ver, *local_ver;
3019 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3021 char *lib, *version;
3022 uint32_t next;
3023 int i;
3025 #define DEBUG_VERSION 0
3027 if (v->versym && v->verdef) {
3028 ElfW(Verdef) *vdef = v->verdef;
3029 lib = NULL;
3030 do {
3031 ElfW(Verdaux) *verdaux =
3032 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3034 #if DEBUG_VERSION
3035 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3036 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3037 vdef->vd_hash);
3038 #endif
3039 if (vdef->vd_cnt) {
3040 version = dynstr + verdaux->vda_name;
3042 if (lib == NULL)
3043 lib = version;
3044 else
3045 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3046 lib, version);
3047 #if DEBUG_VERSION
3048 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3049 #endif
3051 next = vdef->vd_next;
3052 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3053 } while (next);
3055 if (v->versym && v->verneed) {
3056 ElfW(Verneed) *vneed = v->verneed;
3057 do {
3058 ElfW(Vernaux) *vernaux =
3059 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3061 lib = dynstr + vneed->vn_file;
3062 #if DEBUG_VERSION
3063 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3064 #endif
3065 for (i = 0; i < vneed->vn_cnt; i++) {
3066 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3067 version = dynstr + vernaux->vna_name;
3068 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3069 lib, version);
3070 #if DEBUG_VERSION
3071 printf (" vernaux(%u): %u %u %s\n",
3072 vernaux->vna_other, vernaux->vna_hash,
3073 vernaux->vna_flags, version);
3074 #endif
3076 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3078 next = vneed->vn_next;
3079 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3080 } while (next);
3083 #if DEBUG_VERSION
3084 for (i = 0; i < v->nb_local_ver; i++) {
3085 if (v->local_ver[i] > 0) {
3086 printf ("%d: lib: %s, version %s\n",
3087 i, sym_versions[v->local_ver[i]].lib,
3088 sym_versions[v->local_ver[i]].version);
3091 #endif
3094 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3095 is referenced by the user (so it should be added as DT_NEEDED in
3096 the generated ELF file) */
3097 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3099 ElfW(Ehdr) ehdr;
3100 ElfW(Shdr) *shdr, *sh, *sh1;
3101 int i, j, nb_syms, nb_dts, sym_bind, ret;
3102 ElfW(Sym) *sym, *dynsym;
3103 ElfW(Dyn) *dt, *dynamic;
3105 char *dynstr;
3106 int sym_index;
3107 const char *name, *soname;
3108 DLLReference *dllref;
3109 struct versym_info v;
3111 full_read(fd, &ehdr, sizeof(ehdr));
3113 /* test CPU specific stuff */
3114 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3115 ehdr.e_machine != EM_TCC_TARGET) {
3116 tcc_error_noabort("bad architecture");
3117 return -1;
3120 /* read sections */
3121 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3123 /* load dynamic section and dynamic symbols */
3124 nb_syms = 0;
3125 nb_dts = 0;
3126 dynamic = NULL;
3127 dynsym = NULL; /* avoid warning */
3128 dynstr = NULL; /* avoid warning */
3129 memset(&v, 0, sizeof v);
3131 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3132 switch(sh->sh_type) {
3133 case SHT_DYNAMIC:
3134 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3135 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3136 break;
3137 case SHT_DYNSYM:
3138 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3139 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3140 sh1 = &shdr[sh->sh_link];
3141 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3142 break;
3143 case SHT_GNU_verdef:
3144 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3145 break;
3146 case SHT_GNU_verneed:
3147 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3148 break;
3149 case SHT_GNU_versym:
3150 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3151 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3152 break;
3153 default:
3154 break;
3158 /* compute the real library name */
3159 soname = tcc_basename(filename);
3161 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3162 if (dt->d_tag == DT_SONAME) {
3163 soname = dynstr + dt->d_un.d_val;
3167 /* if the dll is already loaded, do not load it */
3168 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3169 dllref = s1->loaded_dlls[i];
3170 if (!strcmp(soname, dllref->name)) {
3171 /* but update level if needed */
3172 if (level < dllref->level)
3173 dllref->level = level;
3174 ret = 0;
3175 goto the_end;
3179 if (v.nb_versyms != nb_syms)
3180 tcc_free (v.versym), v.versym = NULL;
3181 else
3182 store_version(s1, &v, dynstr);
3184 /* add the dll and its level */
3185 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
3186 dllref->level = level;
3187 strcpy(dllref->name, soname);
3188 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
3190 /* add dynamic symbols in dynsym_section */
3191 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3192 sym_bind = ELFW(ST_BIND)(sym->st_info);
3193 if (sym_bind == STB_LOCAL)
3194 continue;
3195 name = dynstr + sym->st_name;
3196 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3197 sym->st_info, sym->st_other, sym->st_shndx, name);
3198 if (v.versym) {
3199 ElfW(Half) vsym = v.versym[i];
3200 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3201 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3205 /* load all referenced DLLs */
3206 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3207 switch(dt->d_tag) {
3208 case DT_NEEDED:
3209 name = dynstr + dt->d_un.d_val;
3210 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3211 dllref = s1->loaded_dlls[j];
3212 if (!strcmp(name, dllref->name))
3213 goto already_loaded;
3215 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3216 tcc_error_noabort("referenced dll '%s' not found", name);
3217 ret = -1;
3218 goto the_end;
3220 already_loaded:
3221 break;
3224 ret = 0;
3225 the_end:
3226 tcc_free(dynstr);
3227 tcc_free(dynsym);
3228 tcc_free(dynamic);
3229 tcc_free(shdr);
3230 tcc_free(v.local_ver);
3231 tcc_free(v.verdef);
3232 tcc_free(v.verneed);
3233 tcc_free(v.versym);
3234 return ret;
3237 #define LD_TOK_NAME 256
3238 #define LD_TOK_EOF (-1)
3240 static int ld_inp(TCCState *s1)
3242 char b;
3243 if (s1->cc != -1) {
3244 int c = s1->cc;
3245 s1->cc = -1;
3246 return c;
3248 if (1 == read(s1->fd, &b, 1))
3249 return b;
3250 return CH_EOF;
3253 /* return next ld script token */
3254 static int ld_next(TCCState *s1, char *name, int name_size)
3256 int c, d, ch;
3257 char *q;
3259 redo:
3260 ch = ld_inp(s1);
3261 switch(ch) {
3262 case ' ':
3263 case '\t':
3264 case '\f':
3265 case '\v':
3266 case '\r':
3267 case '\n':
3268 goto redo;
3269 case '/':
3270 ch = ld_inp(s1);
3271 if (ch == '*') { /* comment */
3272 for (d = 0;; d = ch) {
3273 ch = ld_inp(s1);
3274 if (ch == CH_EOF || (ch == '/' && d == '*'))
3275 break;
3277 goto redo;
3278 } else {
3279 q = name;
3280 *q++ = '/';
3281 goto parse_name;
3283 break;
3284 case '\\':
3285 /* case 'a' ... 'z': */
3286 case 'a':
3287 case 'b':
3288 case 'c':
3289 case 'd':
3290 case 'e':
3291 case 'f':
3292 case 'g':
3293 case 'h':
3294 case 'i':
3295 case 'j':
3296 case 'k':
3297 case 'l':
3298 case 'm':
3299 case 'n':
3300 case 'o':
3301 case 'p':
3302 case 'q':
3303 case 'r':
3304 case 's':
3305 case 't':
3306 case 'u':
3307 case 'v':
3308 case 'w':
3309 case 'x':
3310 case 'y':
3311 case 'z':
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 '_':
3340 case '.':
3341 case '$':
3342 case '~':
3343 q = name;
3344 parse_name:
3345 for(;;) {
3346 if (!((ch >= 'a' && ch <= 'z') ||
3347 (ch >= 'A' && ch <= 'Z') ||
3348 (ch >= '0' && ch <= '9') ||
3349 strchr("/.-_+=$:\\,~", ch)))
3350 break;
3351 if ((q - name) < name_size - 1) {
3352 *q++ = ch;
3354 ch = ld_inp(s1);
3356 s1->cc = ch;
3357 *q = '\0';
3358 c = LD_TOK_NAME;
3359 break;
3360 case CH_EOF:
3361 c = LD_TOK_EOF;
3362 break;
3363 default:
3364 c = ch;
3365 break;
3367 return c;
3370 static int ld_add_file(TCCState *s1, const char filename[])
3372 if (filename[0] == '/') {
3373 if (CONFIG_SYSROOT[0] == '\0'
3374 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3375 return 0;
3376 filename = tcc_basename(filename);
3378 return tcc_add_dll(s1, filename, 0);
3381 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3383 char filename[1024], libname[1024];
3384 int t, group, nblibs = 0, ret = 0;
3385 char **libs = NULL;
3387 group = !strcmp(cmd, "GROUP");
3388 if (!as_needed)
3389 s1->new_undef_sym = 0;
3390 t = ld_next(s1, filename, sizeof(filename));
3391 if (t != '(') {
3392 tcc_error_noabort("( expected");
3393 ret = -1;
3394 goto lib_parse_error;
3396 t = ld_next(s1, filename, sizeof(filename));
3397 for(;;) {
3398 libname[0] = '\0';
3399 if (t == LD_TOK_EOF) {
3400 tcc_error_noabort("unexpected end of file");
3401 ret = -1;
3402 goto lib_parse_error;
3403 } else if (t == ')') {
3404 break;
3405 } else if (t == '-') {
3406 t = ld_next(s1, filename, sizeof(filename));
3407 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3408 tcc_error_noabort("library name expected");
3409 ret = -1;
3410 goto lib_parse_error;
3412 pstrcpy(libname, sizeof libname, &filename[1]);
3413 if (s1->static_link) {
3414 snprintf(filename, sizeof filename, "lib%s.a", libname);
3415 } else {
3416 snprintf(filename, sizeof filename, "lib%s.so", libname);
3418 } else if (t != LD_TOK_NAME) {
3419 tcc_error_noabort("filename expected");
3420 ret = -1;
3421 goto lib_parse_error;
3423 if (!strcmp(filename, "AS_NEEDED")) {
3424 ret = ld_add_file_list(s1, cmd, 1);
3425 if (ret)
3426 goto lib_parse_error;
3427 } else {
3428 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3429 if (!as_needed) {
3430 ret = ld_add_file(s1, filename);
3431 if (ret)
3432 goto lib_parse_error;
3433 if (group) {
3434 /* Add the filename *and* the libname to avoid future conversions */
3435 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3436 if (libname[0] != '\0')
3437 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3441 t = ld_next(s1, filename, sizeof(filename));
3442 if (t == ',') {
3443 t = ld_next(s1, filename, sizeof(filename));
3446 if (group && !as_needed) {
3447 while (s1->new_undef_sym) {
3448 int i;
3449 s1->new_undef_sym = 0;
3450 for (i = 0; i < nblibs; i ++)
3451 ld_add_file(s1, libs[i]);
3454 lib_parse_error:
3455 dynarray_reset(&libs, &nblibs);
3456 return ret;
3459 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3460 files */
3461 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3463 char cmd[64];
3464 char filename[1024];
3465 int t, ret;
3467 s1->fd = fd;
3468 s1->cc = -1;
3469 for(;;) {
3470 t = ld_next(s1, cmd, sizeof(cmd));
3471 if (t == LD_TOK_EOF)
3472 return 0;
3473 else if (t != LD_TOK_NAME)
3474 return -1;
3475 if (!strcmp(cmd, "INPUT") ||
3476 !strcmp(cmd, "GROUP")) {
3477 ret = ld_add_file_list(s1, cmd, 0);
3478 if (ret)
3479 return ret;
3480 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3481 !strcmp(cmd, "TARGET")) {
3482 /* ignore some commands */
3483 t = ld_next(s1, cmd, sizeof(cmd));
3484 if (t != '(') {
3485 tcc_error_noabort("( expected");
3486 return -1;
3488 for(;;) {
3489 t = ld_next(s1, filename, sizeof(filename));
3490 if (t == LD_TOK_EOF) {
3491 tcc_error_noabort("unexpected end of file");
3492 return -1;
3493 } else if (t == ')') {
3494 break;
3497 } else {
3498 return -1;
3501 return 0;
3503 #endif /* !ELF_OBJ_ONLY */