macos: workaround to build tcc using tcc until .o object files generated by tcc are...
[tinycc.git] / tccelf.c
blob8d3f965394a163888b6a36f0d114f830a8c4b082
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 ST_FUNC int find_c_sym(TCCState *s1, const char *name)
486 int ret;
487 CString cstr;
488 if (s1->leading_underscore) {
489 cstr_new(&cstr);
490 cstr_ccat(&cstr, '_');
491 cstr_cat(&cstr, name, 0);
492 name = cstr.data;
494 ret = find_elf_sym(s1->symtab, name);
495 if (s1->leading_underscore)
496 cstr_free(&cstr);
497 return ret;
500 /* return elf symbol value, signal error if 'err' is nonzero, decorate
501 name if FORC */
502 ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
504 int sym_index;
505 ElfW(Sym) *sym;
507 if (forc)
508 sym_index = find_c_sym(s1, name);
509 else
510 sym_index = find_elf_sym(s1->symtab, name);
511 sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
512 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
513 if (err)
514 tcc_error("%s not defined", name);
515 return 0;
517 return sym->st_value;
520 /* list elf symbol names and values */
521 ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
522 void (*symbol_cb)(void *ctx, const char *name, const void *val))
524 ElfW(Sym) *sym;
525 Section *symtab;
526 int sym_index, end_sym;
527 const char *name;
528 unsigned char sym_vis, sym_bind;
530 symtab = s->symtab;
531 end_sym = symtab->data_offset / sizeof (ElfSym);
532 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
533 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
534 if (sym->st_value) {
535 name = (char *) symtab->link->data + sym->st_name;
536 sym_bind = ELFW(ST_BIND)(sym->st_info);
537 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
538 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
539 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
544 /* return elf symbol value */
545 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
547 return (void*)(uintptr_t)get_sym_addr(s, name, 0, 1);
550 /* list elf symbol names and values */
551 LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
552 void (*symbol_cb)(void *ctx, const char *name, const void *val))
554 list_elf_symbols(s, ctx, symbol_cb);
557 #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
558 /* return elf symbol value or error */
559 ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
561 return (void*)(uintptr_t)get_sym_addr(s, name, 1, 1);
563 #endif
565 #ifndef ELF_OBJ_ONLY
566 static void
567 version_add (TCCState *s1)
569 int i;
570 ElfW(Sym) *sym;
571 ElfW(Verneed) *vn = NULL;
572 Section *symtab;
573 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
574 ElfW(Half) *versym;
575 const char *name;
577 if (0 == nb_sym_versions)
578 return;
579 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
580 versym_section->sh_entsize = sizeof(ElfW(Half));
581 versym_section->link = s1->dynsym;
583 /* add needed symbols */
584 symtab = s1->dynsym;
585 end_sym = symtab->data_offset / sizeof (ElfSym);
586 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
587 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
588 int dllindex, verndx;
589 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
590 name = (char *) symtab->link->data + sym->st_name;
591 dllindex = find_elf_sym(s1->dynsymtab_section, name);
592 verndx = (dllindex && dllindex < nb_sym_to_version)
593 ? sym_to_version[dllindex] : -1;
594 if (verndx >= 0) {
595 if (!sym_versions[verndx].out_index)
596 sym_versions[verndx].out_index = nb_versions++;
597 versym[sym_index] = sym_versions[verndx].out_index;
598 } else
599 versym[sym_index] = 0;
601 /* generate verneed section, but not when it will be empty. Some
602 dynamic linkers look at their contents even when DTVERNEEDNUM and
603 section size is zero. */
604 if (nb_versions > 2) {
605 verneed_section = new_section(s1, ".gnu.version_r",
606 SHT_GNU_verneed, SHF_ALLOC);
607 verneed_section->link = s1->dynsym->link;
608 for (i = nb_sym_versions; i-- > 0;) {
609 struct sym_version *sv = &sym_versions[i];
610 int n_same_libs = 0, prev;
611 size_t vnofs;
612 ElfW(Vernaux) *vna = 0;
613 if (sv->out_index < 1)
614 continue;
615 vnofs = section_add(verneed_section, sizeof(*vn), 1);
616 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
617 vn->vn_version = 1;
618 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
619 vn->vn_aux = sizeof (*vn);
620 do {
621 prev = sv->prev_same_lib;
622 if (sv->out_index > 0) {
623 vna = section_ptr_add(verneed_section, sizeof(*vna));
624 vna->vna_hash = elf_hash ((const unsigned char *)sv->version);
625 vna->vna_flags = 0;
626 vna->vna_other = sv->out_index;
627 sv->out_index = -2;
628 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
629 vna->vna_next = sizeof (*vna);
630 n_same_libs++;
632 if (prev >= 0)
633 sv = &sym_versions[prev];
634 } while(prev >= 0);
635 vna->vna_next = 0;
636 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
637 vn->vn_cnt = n_same_libs;
638 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
639 nb_entries++;
641 if (vn)
642 vn->vn_next = 0;
643 verneed_section->sh_info = nb_entries;
645 dt_verneednum = nb_entries;
647 #endif
649 /* add an elf symbol : check if it is already defined and patch
650 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
651 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
652 int info, int other, int shndx, const char *name)
654 TCCState *s1 = s->s1;
655 ElfW(Sym) *esym;
656 int sym_bind, sym_index, sym_type, esym_bind;
657 unsigned char sym_vis, esym_vis, new_vis;
659 sym_bind = ELFW(ST_BIND)(info);
660 sym_type = ELFW(ST_TYPE)(info);
661 sym_vis = ELFW(ST_VISIBILITY)(other);
663 if (sym_bind != STB_LOCAL) {
664 /* we search global or weak symbols */
665 sym_index = find_elf_sym(s, name);
666 if (!sym_index)
667 goto do_def;
668 esym = &((ElfW(Sym) *)s->data)[sym_index];
669 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
670 && esym->st_other == other && esym->st_shndx == shndx)
671 return sym_index;
672 if (esym->st_shndx != SHN_UNDEF) {
673 esym_bind = ELFW(ST_BIND)(esym->st_info);
674 /* propagate the most constraining visibility */
675 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
676 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
677 if (esym_vis == STV_DEFAULT) {
678 new_vis = sym_vis;
679 } else if (sym_vis == STV_DEFAULT) {
680 new_vis = esym_vis;
681 } else {
682 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
684 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
685 | new_vis;
686 other = esym->st_other; /* in case we have to patch esym */
687 if (shndx == SHN_UNDEF) {
688 /* ignore adding of undefined symbol if the
689 corresponding symbol is already defined */
690 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
691 /* global overrides weak, so patch */
692 goto do_patch;
693 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
694 /* weak is ignored if already global */
695 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
696 /* keep first-found weak definition, ignore subsequents */
697 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
698 /* ignore hidden symbols after */
699 } else if ((esym->st_shndx == SHN_COMMON
700 || esym->st_shndx == bss_section->sh_num)
701 && (shndx < SHN_LORESERVE
702 && shndx != bss_section->sh_num)) {
703 /* data symbol gets precedence over common/bss */
704 goto do_patch;
705 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
706 /* data symbol keeps precedence over common/bss */
707 } else if (s->sh_flags & SHF_DYNSYM) {
708 /* we accept that two DLL define the same symbol */
709 } else if (esym->st_other & ST_ASM_SET) {
710 /* If the existing symbol came from an asm .set
711 we can override. */
712 goto do_patch;
713 } else {
714 #if 0
715 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
716 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
717 #endif
718 tcc_error_noabort("'%s' defined twice", name);
720 } else {
721 do_patch:
722 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
723 esym->st_shndx = shndx;
724 s1->new_undef_sym = 1;
725 esym->st_value = value;
726 esym->st_size = size;
727 esym->st_other = other;
729 } else {
730 do_def:
731 sym_index = put_elf_sym(s, value, size,
732 ELFW(ST_INFO)(sym_bind, sym_type), other,
733 shndx, name);
735 return sym_index;
738 /* put relocation */
739 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
740 int type, int symbol, addr_t addend)
742 TCCState *s1 = s->s1;
743 char buf[256];
744 Section *sr;
745 ElfW_Rel *rel;
747 sr = s->reloc;
748 if (!sr) {
749 /* if no relocation section, create it */
750 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
751 /* if the symtab is allocated, then we consider the relocation
752 are also */
753 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
754 sr->sh_entsize = sizeof(ElfW_Rel);
755 sr->link = symtab;
756 sr->sh_info = s->sh_num;
757 s->reloc = sr;
759 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
760 rel->r_offset = offset;
761 rel->r_info = ELFW(R_INFO)(symbol, type);
762 #if SHT_RELX == SHT_RELA
763 rel->r_addend = addend;
764 #endif
765 if (SHT_RELX != SHT_RELA && addend)
766 tcc_error("non-zero addend on REL architecture");
769 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
770 int type, int symbol)
772 put_elf_reloca(symtab, s, offset, type, symbol, 0);
775 /* Remove relocations for section S->reloc starting at oldrelocoffset
776 that are to the same place, retaining the last of them. As side effect
777 the relocations are sorted. Possibly reduces the number of relocs. */
778 ST_FUNC void squeeze_multi_relocs(Section *s, size_t oldrelocoffset)
780 Section *sr = s->reloc;
781 ElfW_Rel *r, *dest;
782 ssize_t a;
783 ElfW(Addr) addr;
785 if (oldrelocoffset + sizeof(*r) >= sr->data_offset)
786 return;
787 /* The relocs we're dealing with are the result of initializer parsing.
788 So they will be mostly in order and there aren't many of them.
789 Secondly we need a stable sort (which qsort isn't). We use
790 a simple insertion sort. */
791 for (a = oldrelocoffset + sizeof(*r); a < sr->data_offset; a += sizeof(*r)) {
792 ssize_t i = a - sizeof(*r);
793 addr = ((ElfW_Rel*)(sr->data + a))->r_offset;
794 for (; i >= (ssize_t)oldrelocoffset &&
795 ((ElfW_Rel*)(sr->data + i))->r_offset > addr; i -= sizeof(*r)) {
796 ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a);
797 *(ElfW_Rel*)(sr->data + a) = *(ElfW_Rel*)(sr->data + i);
798 *(ElfW_Rel*)(sr->data + i) = tmp;
802 r = (ElfW_Rel*)(sr->data + oldrelocoffset);
803 dest = r;
804 for (; r < (ElfW_Rel*)(sr->data + sr->data_offset); r++) {
805 if (dest->r_offset != r->r_offset)
806 dest++;
807 *dest = *r;
809 sr->data_offset = (unsigned char*)dest - sr->data + sizeof(*r);
812 /* put stab debug information */
814 ST_FUNC void put_stabs(TCCState *s1, const char *str, int type, int other, int desc,
815 unsigned long value)
817 Stab_Sym *sym;
819 unsigned offset;
820 if (type == N_SLINE
821 && (offset = stab_section->data_offset)
822 && (sym = (Stab_Sym*)(stab_section->data + offset) - 1)
823 && sym->n_type == type
824 && sym->n_value == value) {
825 /* just update line_number in previous entry */
826 sym->n_desc = desc;
827 return;
830 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
831 if (str) {
832 sym->n_strx = put_elf_str(stab_section->link, str);
833 } else {
834 sym->n_strx = 0;
836 sym->n_type = type;
837 sym->n_other = other;
838 sym->n_desc = desc;
839 sym->n_value = value;
842 ST_FUNC void put_stabs_r(TCCState *s1, const char *str, int type, int other, int desc,
843 unsigned long value, Section *sec, int sym_index)
845 put_elf_reloc(symtab_section, stab_section,
846 stab_section->data_offset + 8,
847 sizeof ((Stab_Sym*)0)->n_value == PTR_SIZE ? R_DATA_PTR : R_DATA_32,
848 sym_index);
849 put_stabs(s1, str, type, other, desc, value);
852 ST_FUNC void put_stabn(TCCState *s1, int type, int other, int desc, int value)
854 put_stabs(s1, NULL, type, other, desc, value);
857 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
859 int n;
860 struct sym_attr *tab;
862 if (index >= s1->nb_sym_attrs) {
863 if (!alloc)
864 return s1->sym_attrs;
865 /* find immediately bigger power of 2 and reallocate array */
866 n = 1;
867 while (index >= n)
868 n *= 2;
869 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
870 s1->sym_attrs = tab;
871 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
872 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
873 s1->nb_sym_attrs = n;
875 return &s1->sym_attrs[index];
878 /* In an ELF file symbol table, the local symbols must appear below
879 the global and weak ones. Since TCC cannot sort it while generating
880 the code, we must do it after. All the relocation tables are also
881 modified to take into account the symbol table sorting */
882 static void sort_syms(TCCState *s1, Section *s)
884 int *old_to_new_syms;
885 ElfW(Sym) *new_syms;
886 int nb_syms, i;
887 ElfW(Sym) *p, *q;
888 ElfW_Rel *rel;
889 Section *sr;
890 int type, sym_index;
892 nb_syms = s->data_offset / sizeof(ElfW(Sym));
893 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
894 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
896 /* first pass for local symbols */
897 p = (ElfW(Sym) *)s->data;
898 q = new_syms;
899 for(i = 0; i < nb_syms; i++) {
900 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
901 old_to_new_syms[i] = q - new_syms;
902 *q++ = *p;
904 p++;
906 /* save the number of local symbols in section header */
907 if( s->sh_size ) /* this 'if' makes IDA happy */
908 s->sh_info = q - new_syms;
910 /* then second pass for non local symbols */
911 p = (ElfW(Sym) *)s->data;
912 for(i = 0; i < nb_syms; i++) {
913 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
914 old_to_new_syms[i] = q - new_syms;
915 *q++ = *p;
917 p++;
920 /* we copy the new symbols to the old */
921 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
922 tcc_free(new_syms);
924 /* now we modify all the relocations */
925 for(i = 1; i < s1->nb_sections; i++) {
926 sr = s1->sections[i];
927 if (sr->sh_type == SHT_RELX && sr->link == s) {
928 for_each_elem(sr, 0, rel, ElfW_Rel) {
929 sym_index = ELFW(R_SYM)(rel->r_info);
930 type = ELFW(R_TYPE)(rel->r_info);
931 sym_index = old_to_new_syms[sym_index];
932 rel->r_info = ELFW(R_INFO)(sym_index, type);
937 tcc_free(old_to_new_syms);
940 /* relocate symbol table, resolve undefined symbols if do_resolve is
941 true and output error if undefined symbol. */
942 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
944 ElfW(Sym) *sym;
945 int sym_bind, sh_num;
946 const char *name;
948 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
949 sh_num = sym->st_shndx;
950 if (sh_num == SHN_UNDEF) {
951 name = (char *) s1->symtab->link->data + sym->st_name;
952 /* Use ld.so to resolve symbol for us (for tcc -run) */
953 if (do_resolve) {
954 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
955 #ifdef TCC_TARGET_MACHO
956 /* The symbols in the symtables have a prepended '_'
957 but dlsym() needs the undecorated name. */
958 void *addr = dlsym(RTLD_DEFAULT, name + 1);
959 #else
960 void *addr = dlsym(RTLD_DEFAULT, name);
961 #endif
962 if (addr) {
963 sym->st_value = (addr_t) addr;
964 #ifdef DEBUG_RELOC
965 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
966 #endif
967 goto found;
969 #endif
970 /* if dynamic symbol exist, it will be used in relocate_section */
971 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
972 goto found;
973 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
974 it */
975 if (!strcmp(name, "_fp_hw"))
976 goto found;
977 /* only weak symbols are accepted to be undefined. Their
978 value is zero */
979 sym_bind = ELFW(ST_BIND)(sym->st_info);
980 if (sym_bind == STB_WEAK)
981 sym->st_value = 0;
982 else
983 tcc_error_noabort("undefined symbol '%s'", name);
984 } else if (sh_num < SHN_LORESERVE) {
985 /* add section base */
986 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
988 found: ;
992 /* relocate a given section (CPU dependent) by applying the relocations
993 in the associated relocation section */
994 ST_FUNC void relocate_section(TCCState *s1, Section *s)
996 Section *sr = s->reloc;
997 ElfW_Rel *rel;
998 ElfW(Sym) *sym;
999 int type, sym_index;
1000 unsigned char *ptr;
1001 addr_t tgt, addr;
1003 qrel = (ElfW_Rel *)sr->data;
1005 for_each_elem(sr, 0, rel, ElfW_Rel) {
1006 ptr = s->data + rel->r_offset;
1007 sym_index = ELFW(R_SYM)(rel->r_info);
1008 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1009 type = ELFW(R_TYPE)(rel->r_info);
1010 tgt = sym->st_value;
1011 #if SHT_RELX == SHT_RELA
1012 tgt += rel->r_addend;
1013 #endif
1014 addr = s->sh_addr + rel->r_offset;
1015 relocate(s1, rel, type, ptr, addr, tgt);
1017 /* if the relocation is allocated, we change its symbol table */
1018 if (sr->sh_flags & SHF_ALLOC) {
1019 sr->link = s1->dynsym;
1020 if (s1->output_type == TCC_OUTPUT_DLL) {
1021 size_t r = (uint8_t*)qrel - sr->data;
1022 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
1023 && 0 == strcmp(s->name, ".stab"))
1024 r = 0; /* cannot apply 64bit relocation to 32bit value */
1025 sr->data_offset = sr->sh_size = r;
1030 #ifndef ELF_OBJ_ONLY
1031 /* relocate relocation table in 'sr' */
1032 static void relocate_rel(TCCState *s1, Section *sr)
1034 Section *s;
1035 ElfW_Rel *rel;
1037 s = s1->sections[sr->sh_info];
1038 for_each_elem(sr, 0, rel, ElfW_Rel)
1039 rel->r_offset += s->sh_addr;
1042 /* count the number of dynamic relocations so that we can reserve
1043 their space */
1044 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
1046 int count = 0;
1047 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1048 ElfW_Rel *rel;
1049 for_each_elem(sr, 0, rel, ElfW_Rel) {
1050 int sym_index = ELFW(R_SYM)(rel->r_info);
1051 int type = ELFW(R_TYPE)(rel->r_info);
1052 switch(type) {
1053 #if defined(TCC_TARGET_I386)
1054 case R_386_32:
1055 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
1056 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
1057 /* don't fixup unresolved (weak) symbols */
1058 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
1059 break;
1061 #elif defined(TCC_TARGET_X86_64)
1062 case R_X86_64_32:
1063 case R_X86_64_32S:
1064 case R_X86_64_64:
1065 #endif
1066 count++;
1067 break;
1068 #if defined(TCC_TARGET_I386)
1069 case R_386_PC32:
1070 #elif defined(TCC_TARGET_X86_64)
1071 case R_X86_64_PC32:
1072 #endif
1073 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1074 count++;
1075 break;
1076 default:
1077 break;
1080 if (count) {
1081 /* allocate the section */
1082 sr->sh_flags |= SHF_ALLOC;
1083 sr->sh_size = count * sizeof(ElfW_Rel);
1085 #endif
1086 return count;
1088 #endif
1090 #if !defined(ELF_OBJ_ONLY) || defined(TCC_TARGET_MACHO)
1091 static void build_got(TCCState *s1)
1093 /* if no got, then create it */
1094 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1095 s1->got->sh_entsize = 4;
1096 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1097 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1098 /* keep space for _DYNAMIC pointer and two dummy got entries */
1099 section_ptr_add(s1->got, 3 * PTR_SIZE);
1102 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1103 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1104 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1105 Returns the offset of the GOT or (if any) PLT entry. */
1106 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1107 int sym_index)
1109 int need_plt_entry;
1110 const char *name;
1111 ElfW(Sym) *sym;
1112 struct sym_attr *attr;
1113 unsigned got_offset;
1114 char plt_name[100];
1115 int len;
1117 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1118 attr = get_sym_attr(s1, sym_index, 1);
1120 /* In case a function is both called and its address taken 2 GOT entries
1121 are created, one for taking the address (GOT) and the other for the PLT
1122 entry (PLTGOT). */
1123 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1124 return attr;
1126 /* create the GOT entry */
1127 got_offset = s1->got->data_offset;
1128 section_ptr_add(s1->got, PTR_SIZE);
1130 /* Create the GOT relocation that will insert the address of the object or
1131 function of interest in the GOT entry. This is a static relocation for
1132 memory output (dlsym will give us the address of symbols) and dynamic
1133 relocation otherwise (executable and DLLs). The relocation should be
1134 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1135 associated to a PLT entry) but is currently done at load time for an
1136 unknown reason. */
1138 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1139 name = (char *) symtab_section->link->data + sym->st_name;
1141 if (s1->dynsym) {
1142 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1143 /* Hack alarm. We don't want to emit dynamic symbols
1144 and symbol based relocs for STB_LOCAL symbols, but rather
1145 want to resolve them directly. At this point the symbol
1146 values aren't final yet, so we must defer this. We will later
1147 have to create a RELATIVE reloc anyway, so we misuse the
1148 relocation slot to smuggle the symbol reference until
1149 fill_local_got_entries. Not that the sym_index is
1150 relative to symtab_section, not s1->dynsym! Nevertheless
1151 we use s1->dyn_sym so that if this is the first call
1152 that got->reloc is correctly created. Also note that
1153 RELATIVE relocs are not normally created for the .got,
1154 so the types serves as a marker for later (and is retained
1155 also for the final output, which is okay because then the
1156 got is just normal data). */
1157 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1158 sym_index);
1159 } else {
1160 if (0 == attr->dyn_index)
1161 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1162 sym->st_size, sym->st_info, 0,
1163 sym->st_shndx, name);
1164 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
1165 attr->dyn_index);
1167 } else {
1168 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1169 sym_index);
1172 if (need_plt_entry) {
1173 if (!s1->plt) {
1174 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1175 SHF_ALLOC | SHF_EXECINSTR);
1176 s1->plt->sh_entsize = 4;
1179 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1181 /* create a symbol 'sym@plt' for the PLT jump vector */
1182 len = strlen(name);
1183 if (len > sizeof plt_name - 5)
1184 len = sizeof plt_name - 5;
1185 memcpy(plt_name, name, len);
1186 strcpy(plt_name + len, "@plt");
1187 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
1188 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1190 } else {
1191 attr->got_offset = got_offset;
1194 return attr;
1197 /* build GOT and PLT entries */
1198 ST_FUNC void build_got_entries(TCCState *s1)
1200 Section *s;
1201 ElfW_Rel *rel;
1202 ElfW(Sym) *sym;
1203 int i, type, gotplt_entry, reloc_type, sym_index;
1204 struct sym_attr *attr;
1206 for(i = 1; i < s1->nb_sections; i++) {
1207 s = s1->sections[i];
1208 if (s->sh_type != SHT_RELX)
1209 continue;
1210 /* no need to handle got relocations */
1211 if (s->link != symtab_section)
1212 continue;
1213 for_each_elem(s, 0, rel, ElfW_Rel) {
1214 type = ELFW(R_TYPE)(rel->r_info);
1215 gotplt_entry = gotplt_entry_type(type);
1216 if (gotplt_entry == -1)
1217 tcc_error ("Unknown relocation type for got: %d", type);
1218 sym_index = ELFW(R_SYM)(rel->r_info);
1219 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1221 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1222 continue;
1225 /* Automatically create PLT/GOT [entry] if it is an undefined
1226 reference (resolved at runtime), or the symbol is absolute,
1227 probably created by tcc_add_symbol, and thus on 64-bit
1228 targets might be too far from application code. */
1229 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1230 if (sym->st_shndx == SHN_UNDEF) {
1231 ElfW(Sym) *esym;
1232 int dynindex;
1233 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1234 continue;
1235 /* Relocations for UNDEF symbols would normally need
1236 to be transferred into the executable or shared object.
1237 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1238 But TCC doesn't do that (at least for exes), so we
1239 need to resolve all such relocs locally. And that
1240 means PLT slots for functions in DLLs and COPY relocs for
1241 data symbols. COPY relocs were generated in
1242 bind_exe_dynsyms (and the symbol adjusted to be defined),
1243 and for functions we were generated a dynamic symbol
1244 of function type. */
1245 if (s1->dynsym) {
1246 /* dynsym isn't set for -run :-/ */
1247 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1248 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1249 if (dynindex
1250 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1251 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1252 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1253 goto jmp_slot;
1255 } else if (!(sym->st_shndx == SHN_ABS
1256 #ifndef TCC_TARGET_ARM
1257 && PTR_SIZE == 8
1258 #endif
1260 continue;
1263 #ifdef TCC_TARGET_X86_64
1264 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1265 sym->st_shndx != SHN_UNDEF &&
1266 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1267 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1268 s1->output_type == TCC_OUTPUT_EXE)) {
1269 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1270 continue;
1272 #endif
1273 reloc_type = code_reloc(type);
1274 if (reloc_type == -1)
1275 tcc_error ("Unknown relocation type: %d", type);
1276 else if (reloc_type != 0) {
1277 jmp_slot:
1278 reloc_type = R_JMP_SLOT;
1279 } else
1280 reloc_type = R_GLOB_DAT;
1282 if (!s1->got)
1283 build_got(s1);
1285 if (gotplt_entry == BUILD_GOT_ONLY)
1286 continue;
1288 attr = put_got_entry(s1, reloc_type, sym_index);
1290 if (reloc_type == R_JMP_SLOT)
1291 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1295 #endif
1297 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, long offs)
1299 int shn = sec ? sec->sh_num : offs ? SHN_ABS : SHN_UNDEF;
1300 if (sec && offs == -1)
1301 offs = sec->data_offset;
1302 return set_elf_sym(symtab_section, offs, 0,
1303 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1306 static void add_init_array_defines(TCCState *s1, const char *section_name)
1308 Section *s;
1309 long end_offset;
1310 char buf[1024];
1311 s = find_section(s1, section_name);
1312 if (!s) {
1313 end_offset = 0;
1314 s = data_section;
1315 } else {
1316 end_offset = s->data_offset;
1318 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1319 set_global_sym(s1, buf, s, 0);
1320 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1321 set_global_sym(s1, buf, s, end_offset);
1324 #ifndef TCC_TARGET_PE
1325 static int tcc_add_support(TCCState *s1, const char *filename)
1327 char buf[1024];
1328 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1329 return tcc_add_file(s1, buf);
1331 #endif
1333 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1335 Section *s;
1336 s = find_section(s1, sec);
1337 s->sh_flags |= SHF_WRITE;
1338 #ifndef TCC_TARGET_PE
1339 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1340 #endif
1341 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1342 section_ptr_add(s, PTR_SIZE);
1345 #ifdef CONFIG_TCC_BCHECK
1346 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1348 if (0 == s1->do_bounds_check)
1349 return;
1350 section_ptr_add(bounds_section, sizeof(addr_t));
1352 #endif
1354 #ifdef CONFIG_TCC_BACKTRACE
1355 static void put_ptr(TCCState *s1, Section *s, int offs)
1357 int c;
1358 c = set_global_sym(s1, NULL, s, offs);
1359 s = data_section;
1360 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1361 section_ptr_add(s, PTR_SIZE);
1364 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1365 a dynamic symbol to allow so's to have one each with a different value. */
1366 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1368 int c = find_elf_sym(s1->symtab, name);
1369 if (c) {
1370 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1371 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1372 esym->st_value = offset;
1373 esym->st_shndx = s->sh_num;
1377 ST_FUNC void tcc_add_btstub(TCCState *s1)
1379 Section *s;
1380 int n, o;
1381 CString cstr;
1383 s = data_section;
1384 o = s->data_offset;
1385 /* create (part of) a struct rt_context (see tccrun.c) */
1386 put_ptr(s1, stab_section, 0);
1387 put_ptr(s1, stab_section, -1);
1388 put_ptr(s1, stab_section->link, 0);
1389 section_ptr_add(s, 3 * PTR_SIZE);
1390 /* prog_base */
1391 #ifndef TCC_TARGET_MACHO
1392 /* XXX this relocation is wrong, it uses sym-index 0 (local,undef) */
1393 put_elf_reloc(s1->symtab, s, s->data_offset, R_DATA_PTR, 0);
1394 #endif
1395 section_ptr_add(s, PTR_SIZE);
1396 n = 2 * PTR_SIZE;
1397 #ifdef CONFIG_TCC_BCHECK
1398 if (s1->do_bounds_check) {
1399 put_ptr(s1, bounds_section, 0);
1400 n -= PTR_SIZE;
1402 #endif
1403 section_ptr_add(s, n);
1405 cstr_new(&cstr);
1406 cstr_printf(&cstr,
1407 " extern void __bt_init(),*__rt_info[],__bt_init_dll();"
1408 "__attribute__((constructor)) static void __bt_init_rt(){");
1409 #ifdef TCC_TARGET_PE
1410 if (s1->output_type == TCC_OUTPUT_DLL)
1411 #ifdef CONFIG_TCC_BCHECK
1412 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1413 #else
1414 cstr_printf(&cstr, "__bt_init_dll(0);");
1415 #endif
1416 #endif
1417 cstr_printf(&cstr, "__bt_init(__rt_info,%d, 0);}",
1418 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1419 tcc_compile_string(s1, cstr.data);
1420 cstr_free(&cstr);
1421 set_local_sym(s1, "___rt_info" + !s1->leading_underscore, s, o);
1423 #endif
1425 #ifndef TCC_TARGET_PE
1426 /* add tcc runtime libraries */
1427 ST_FUNC void tcc_add_runtime(TCCState *s1)
1429 s1->filetype = 0;
1430 #ifdef CONFIG_TCC_BCHECK
1431 tcc_add_bcheck(s1);
1432 #endif
1433 tcc_add_pragma_libs(s1);
1434 /* add libc */
1435 if (!s1->nostdlib) {
1436 if (s1->option_pthread)
1437 tcc_add_library_err(s1, "pthread");
1438 tcc_add_library_err(s1, "c");
1439 #ifdef TCC_LIBGCC
1440 if (!s1->static_link) {
1441 if (TCC_LIBGCC[0] == '/')
1442 tcc_add_file(s1, TCC_LIBGCC);
1443 else
1444 tcc_add_dll(s1, TCC_LIBGCC, 0);
1446 #endif
1447 #ifdef CONFIG_TCC_BCHECK
1448 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1449 tcc_add_library_err(s1, "pthread");
1450 tcc_add_library_err(s1, "dl");
1451 tcc_add_support(s1, "bcheck.o");
1453 #endif
1454 #ifdef CONFIG_TCC_BACKTRACE
1455 if (s1->do_backtrace) {
1456 if (s1->output_type == TCC_OUTPUT_EXE)
1457 tcc_add_support(s1, "bt-exe.o");
1458 if (s1->output_type != TCC_OUTPUT_DLL)
1459 tcc_add_support(s1, "bt-log.o");
1460 if (s1->output_type != TCC_OUTPUT_MEMORY)
1461 tcc_add_btstub(s1);
1463 #endif
1464 tcc_add_support(s1, TCC_LIBTCC1);
1465 #ifndef TCC_TARGET_MACHO
1466 /* add crt end if not memory output */
1467 if (s1->output_type != TCC_OUTPUT_MEMORY)
1468 tcc_add_crt(s1, "crtn.o");
1469 #endif
1472 #endif
1474 /* add various standard linker symbols (must be done after the
1475 sections are filled (for example after allocating common
1476 symbols)) */
1477 static void tcc_add_linker_symbols(TCCState *s1)
1479 char buf[1024];
1480 int i;
1481 Section *s;
1483 set_global_sym(s1, "_etext", text_section, -1);
1484 set_global_sym(s1, "_edata", data_section, -1);
1485 set_global_sym(s1, "_end", bss_section, -1);
1486 #ifdef TCC_TARGET_RISCV64
1487 /* XXX should be .sdata+0x800, not .data+0x800 */
1488 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1489 #endif
1490 /* horrible new standard ldscript defines */
1491 add_init_array_defines(s1, ".preinit_array");
1492 add_init_array_defines(s1, ".init_array");
1493 add_init_array_defines(s1, ".fini_array");
1494 /* add start and stop symbols for sections whose name can be
1495 expressed in C */
1496 for(i = 1; i < s1->nb_sections; i++) {
1497 s = s1->sections[i];
1498 if ((s->sh_flags & SHF_ALLOC)
1499 && (s->sh_type == SHT_PROGBITS
1500 || s->sh_type == SHT_STRTAB)) {
1501 const char *p;
1502 /* check if section name can be expressed in C */
1503 p = s->name;
1504 for(;;) {
1505 int c = *p;
1506 if (!c)
1507 break;
1508 if (!isid(c) && !isnum(c))
1509 goto next_sec;
1510 p++;
1512 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1513 set_global_sym(s1, buf, s, 0);
1514 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1515 set_global_sym(s1, buf, s, -1);
1517 next_sec: ;
1521 ST_FUNC void resolve_common_syms(TCCState *s1)
1523 ElfW(Sym) *sym;
1525 /* Allocate common symbols in BSS. */
1526 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1527 if (sym->st_shndx == SHN_COMMON) {
1528 /* symbol alignment is in st_value for SHN_COMMONs */
1529 sym->st_value = section_add(bss_section, sym->st_size,
1530 sym->st_value);
1531 sym->st_shndx = bss_section->sh_num;
1535 /* Now assign linker provided symbols their value. */
1536 tcc_add_linker_symbols(s1);
1539 static void tcc_output_binary(TCCState *s1, FILE *f,
1540 const int *sec_order)
1542 Section *s;
1543 int i, offset, size;
1545 offset = 0;
1546 for(i=1;i<s1->nb_sections;i++) {
1547 s = s1->sections[sec_order[i]];
1548 if (s->sh_type != SHT_NOBITS &&
1549 (s->sh_flags & SHF_ALLOC)) {
1550 while (offset < s->sh_offset) {
1551 fputc(0, f);
1552 offset++;
1554 size = s->sh_size;
1555 fwrite(s->data, 1, size, f);
1556 offset += size;
1561 #ifndef ELF_OBJ_ONLY
1562 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1564 int sym_index = ELFW(R_SYM) (rel->r_info);
1565 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1566 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1567 unsigned offset = attr->got_offset;
1569 if (0 == offset)
1570 return;
1571 section_reserve(s1->got, offset + PTR_SIZE);
1572 #ifdef TCC_TARGET_X86_64
1573 write64le(s1->got->data + offset, sym->st_value);
1574 #else
1575 write32le(s1->got->data + offset, sym->st_value);
1576 #endif
1579 /* Perform relocation to GOT or PLT entries */
1580 ST_FUNC void fill_got(TCCState *s1)
1582 Section *s;
1583 ElfW_Rel *rel;
1584 int i;
1586 for(i = 1; i < s1->nb_sections; i++) {
1587 s = s1->sections[i];
1588 if (s->sh_type != SHT_RELX)
1589 continue;
1590 /* no need to handle got relocations */
1591 if (s->link != symtab_section)
1592 continue;
1593 for_each_elem(s, 0, rel, ElfW_Rel) {
1594 switch (ELFW(R_TYPE) (rel->r_info)) {
1595 case R_X86_64_GOT32:
1596 case R_X86_64_GOTPCREL:
1597 case R_X86_64_GOTPCRELX:
1598 case R_X86_64_REX_GOTPCRELX:
1599 case R_X86_64_PLT32:
1600 fill_got_entry(s1, rel);
1601 break;
1607 /* See put_got_entry for a description. This is the second stage
1608 where GOT references to local defined symbols are rewritten. */
1609 static void fill_local_got_entries(TCCState *s1)
1611 ElfW_Rel *rel;
1612 if (!s1->got->reloc)
1613 return;
1614 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1615 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1616 int sym_index = ELFW(R_SYM) (rel->r_info);
1617 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1618 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1619 unsigned offset = attr->got_offset;
1620 if (offset != rel->r_offset - s1->got->sh_addr)
1621 tcc_error_noabort("huh");
1622 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1623 #if SHT_RELX == SHT_RELA
1624 rel->r_addend = sym->st_value;
1625 #else
1626 /* All our REL architectures also happen to be 32bit LE. */
1627 write32le(s1->got->data + offset, sym->st_value);
1628 #endif
1633 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1634 in shared libraries and export non local defined symbols to shared libraries
1635 if -rdynamic switch was given on command line */
1636 static void bind_exe_dynsyms(TCCState *s1)
1638 const char *name;
1639 int sym_index, index;
1640 ElfW(Sym) *sym, *esym;
1641 int type;
1643 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1644 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1645 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1646 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1647 if (sym->st_shndx == SHN_UNDEF) {
1648 name = (char *) symtab_section->link->data + sym->st_name;
1649 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1650 if (sym_index) {
1651 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1652 type = ELFW(ST_TYPE)(esym->st_info);
1653 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1654 /* Indirect functions shall have STT_FUNC type in executable
1655 * dynsym section. Indeed, a dlsym call following a lazy
1656 * resolution would pick the symbol value from the
1657 * executable dynsym entry which would contain the address
1658 * of the function wanted by the caller of dlsym instead of
1659 * the address of the function that would return that
1660 * address */
1661 int dynindex
1662 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1663 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1664 name);
1665 int index = sym - (ElfW(Sym) *) symtab_section->data;
1666 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1667 } else if (type == STT_OBJECT) {
1668 unsigned long offset;
1669 ElfW(Sym) *dynsym;
1670 offset = bss_section->data_offset;
1671 /* XXX: which alignment ? */
1672 offset = (offset + 16 - 1) & -16;
1673 set_elf_sym (s1->symtab, offset, esym->st_size,
1674 esym->st_info, 0, bss_section->sh_num, name);
1675 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1676 esym->st_info, 0, bss_section->sh_num,
1677 name);
1679 /* Ensure R_COPY works for weak symbol aliases */
1680 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1681 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1682 if ((dynsym->st_value == esym->st_value)
1683 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1684 char *dynname = (char *) s1->dynsymtab_section->link->data
1685 + dynsym->st_name;
1686 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1687 dynsym->st_info, 0,
1688 bss_section->sh_num, dynname);
1689 break;
1694 put_elf_reloc(s1->dynsym, bss_section,
1695 offset, R_COPY, index);
1696 offset += esym->st_size;
1697 bss_section->data_offset = offset;
1699 } else {
1700 /* STB_WEAK undefined symbols are accepted */
1701 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1702 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1703 !strcmp(name, "_fp_hw")) {
1704 } else {
1705 tcc_error_noabort("undefined symbol '%s'", name);
1708 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1709 /* if -rdynamic option, then export all non local symbols */
1710 name = (char *) symtab_section->link->data + sym->st_name;
1711 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1712 0, sym->st_shndx, name);
1717 /* Bind symbols of libraries: export all non local symbols of executable that
1718 are referenced by shared libraries. The reason is that the dynamic loader
1719 search symbol first in executable and then in libraries. Therefore a
1720 reference to a symbol already defined by a library can still be resolved by
1721 a symbol in the executable. */
1722 static void bind_libs_dynsyms(TCCState *s1)
1724 const char *name;
1725 int sym_index;
1726 ElfW(Sym) *sym, *esym;
1728 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1729 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1730 sym_index = find_elf_sym(symtab_section, name);
1731 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1732 if (sym_index && sym->st_shndx != SHN_UNDEF
1733 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1734 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1735 sym->st_info, 0, sym->st_shndx, name);
1736 } else if (esym->st_shndx == SHN_UNDEF) {
1737 /* weak symbols can stay undefined */
1738 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1739 tcc_warning("undefined dynamic symbol '%s'", name);
1744 /* Export all non local symbols. This is used by shared libraries so that the
1745 non local symbols they define can resolve a reference in another shared
1746 library or in the executable. Correspondingly, it allows undefined local
1747 symbols to be resolved by other shared libraries or by the executable. */
1748 static void export_global_syms(TCCState *s1)
1750 int dynindex, index;
1751 const char *name;
1752 ElfW(Sym) *sym;
1754 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1755 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1756 name = (char *) symtab_section->link->data + sym->st_name;
1757 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1758 sym->st_info, 0, sym->st_shndx, name);
1759 index = sym - (ElfW(Sym) *) symtab_section->data;
1760 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1764 #endif
1766 /* Allocate strings for section names and decide if an unallocated section
1767 should be output.
1768 NOTE: the strsec section comes last, so its size is also correct ! */
1769 static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1771 int i;
1772 Section *s;
1773 int textrel = 0;
1775 /* Allocate strings for section names */
1776 for(i = 1; i < s1->nb_sections; i++) {
1777 s = s1->sections[i];
1778 /* when generating a DLL, we include relocations but we may
1779 patch them */
1780 #ifndef ELF_OBJ_ONLY
1781 if (file_type == TCC_OUTPUT_DLL &&
1782 s->sh_type == SHT_RELX &&
1783 !(s->sh_flags & SHF_ALLOC) &&
1784 (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
1785 prepare_dynamic_rel(s1, s)) {
1786 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
1787 textrel = 1;
1788 } else
1789 #endif
1790 if ((s1->do_debug && s->sh_type != SHT_RELX) ||
1791 file_type == TCC_OUTPUT_OBJ ||
1792 (s->sh_flags & SHF_ALLOC) ||
1793 i == (s1->nb_sections - 1)) {
1794 /* we output all sections if debug or object file */
1795 s->sh_size = s->data_offset;
1797 if (s->sh_size || (s->sh_flags & SHF_ALLOC))
1798 s->sh_name = put_elf_str(strsec, s->name);
1800 strsec->sh_size = strsec->data_offset;
1801 return textrel;
1804 /* Info to be copied in dynamic section */
1805 struct dyn_inf {
1806 Section *dynamic;
1807 Section *dynstr;
1808 unsigned long data_offset;
1809 addr_t rel_addr;
1810 addr_t rel_size;
1811 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1812 addr_t bss_addr;
1813 addr_t bss_size;
1814 #endif
1817 /* Assign sections to segments and decide how are sections laid out when loaded
1818 in memory. This function also fills corresponding program headers. */
1819 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1820 Section *interp, Section* strsec,
1821 struct dyn_inf *dyninf, int *sec_order)
1823 int i, j, k, file_type, sh_order_index, file_offset;
1824 unsigned long s_align;
1825 long long tmp;
1826 addr_t addr;
1827 ElfW(Phdr) *ph;
1828 Section *s;
1830 file_type = s1->output_type;
1831 sh_order_index = 1;
1832 file_offset = 0;
1833 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1834 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1835 s_align = ELF_PAGE_SIZE;
1836 if (s1->section_align)
1837 s_align = s1->section_align;
1839 if (phnum > 0) {
1840 if (s1->has_text_addr) {
1841 int a_offset, p_offset;
1842 addr = s1->text_addr;
1843 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1844 ELF_PAGE_SIZE */
1845 a_offset = (int) (addr & (s_align - 1));
1846 p_offset = file_offset & (s_align - 1);
1847 if (a_offset < p_offset)
1848 a_offset += s_align;
1849 file_offset += (a_offset - p_offset);
1850 } else {
1851 if (file_type == TCC_OUTPUT_DLL)
1852 addr = 0;
1853 else
1854 addr = ELF_START_ADDR;
1855 /* compute address after headers */
1856 addr += (file_offset & (s_align - 1));
1859 ph = &phdr[0];
1860 /* Leave one program headers for the program interpreter and one for
1861 the program header table itself if needed. These are done later as
1862 they require section layout to be done first. */
1863 if (interp)
1864 ph += 2;
1866 /* dynamic relocation table information, for .dynamic section */
1867 dyninf->rel_addr = dyninf->rel_size = 0;
1868 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1869 dyninf->bss_addr = dyninf->bss_size = 0;
1870 #endif
1872 for(j = 0; j < 2; j++) {
1873 ph->p_type = PT_LOAD;
1874 if (j == 0)
1875 ph->p_flags = PF_R | PF_X;
1876 else
1877 ph->p_flags = PF_R | PF_W;
1878 ph->p_align = s_align;
1880 /* Decide the layout of sections loaded in memory. This must
1881 be done before program headers are filled since they contain
1882 info about the layout. We do the following ordering: interp,
1883 symbol tables, relocations, progbits, nobits */
1884 /* XXX: do faster and simpler sorting */
1885 for(k = 0; k < 5; k++) {
1886 for(i = 1; i < s1->nb_sections; i++) {
1887 s = s1->sections[i];
1888 /* compute if section should be included */
1889 if (j == 0) {
1890 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1891 SHF_ALLOC)
1892 continue;
1893 } else {
1894 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1895 (SHF_ALLOC | SHF_WRITE))
1896 continue;
1898 if (s == interp) {
1899 if (k != 0)
1900 continue;
1901 } else if ((s->sh_type == SHT_DYNSYM ||
1902 s->sh_type == SHT_STRTAB ||
1903 s->sh_type == SHT_HASH)
1904 && !strstr(s->name, ".stab")) {
1905 if (k != 1)
1906 continue;
1907 } else if (s->sh_type == SHT_RELX) {
1908 if (k != 2)
1909 continue;
1910 } else if (s->sh_type == SHT_NOBITS) {
1911 if (k != 4)
1912 continue;
1913 } else {
1914 if (k != 3)
1915 continue;
1917 sec_order[sh_order_index++] = i;
1919 /* section matches: we align it and add its size */
1920 tmp = addr;
1921 addr = (addr + s->sh_addralign - 1) &
1922 ~(s->sh_addralign - 1);
1923 file_offset += (int) ( addr - tmp );
1924 s->sh_offset = file_offset;
1925 s->sh_addr = addr;
1927 /* update program header infos */
1928 if (ph->p_offset == 0) {
1929 ph->p_offset = file_offset;
1930 ph->p_vaddr = addr;
1931 ph->p_paddr = ph->p_vaddr;
1933 /* update dynamic relocation infos */
1934 if (s->sh_type == SHT_RELX) {
1935 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1936 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1937 dyninf->rel_addr = addr;
1938 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1940 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1941 dyninf->bss_addr = addr;
1942 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1944 #else
1945 if (dyninf->rel_size == 0)
1946 dyninf->rel_addr = addr;
1947 dyninf->rel_size += s->sh_size;
1948 #endif
1950 addr += s->sh_size;
1951 if (s->sh_type != SHT_NOBITS)
1952 file_offset += s->sh_size;
1955 if (j == 0) {
1956 /* Make the first PT_LOAD segment include the program
1957 headers itself (and the ELF header as well), it'll
1958 come out with same memory use but will make various
1959 tools like binutils strip work better. */
1960 ph->p_offset &= ~(ph->p_align - 1);
1961 ph->p_vaddr &= ~(ph->p_align - 1);
1962 ph->p_paddr &= ~(ph->p_align - 1);
1964 ph->p_filesz = file_offset - ph->p_offset;
1965 ph->p_memsz = addr - ph->p_vaddr;
1966 ph++;
1967 if (j == 0) {
1968 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1969 /* if in the middle of a page, we duplicate the page in
1970 memory so that one copy is RX and the other is RW */
1971 if ((addr & (s_align - 1)) != 0)
1972 addr += s_align;
1973 } else {
1974 addr = (addr + s_align - 1) & ~(s_align - 1);
1975 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1981 /* all other sections come after */
1982 for(i = 1; i < s1->nb_sections; i++) {
1983 s = s1->sections[i];
1984 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1985 continue;
1986 sec_order[sh_order_index++] = i;
1988 file_offset = (file_offset + s->sh_addralign - 1) &
1989 ~(s->sh_addralign - 1);
1990 s->sh_offset = file_offset;
1991 if (s->sh_type != SHT_NOBITS)
1992 file_offset += s->sh_size;
1995 return file_offset;
1998 #ifndef ELF_OBJ_ONLY
1999 /* put dynamic tag */
2000 static void put_dt(Section *dynamic, int dt, addr_t val)
2002 ElfW(Dyn) *dyn;
2003 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
2004 dyn->d_tag = dt;
2005 dyn->d_un.d_val = val;
2008 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
2009 Section *dynamic)
2011 ElfW(Phdr) *ph;
2013 /* if interpreter, then add corresponding program header */
2014 if (interp) {
2015 ph = &phdr[0];
2017 ph->p_type = PT_PHDR;
2018 ph->p_offset = sizeof(ElfW(Ehdr));
2019 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
2020 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
2021 ph->p_paddr = ph->p_vaddr;
2022 ph->p_flags = PF_R | PF_X;
2023 ph->p_align = 4; /* interp->sh_addralign; */
2024 ph++;
2026 ph->p_type = PT_INTERP;
2027 ph->p_offset = interp->sh_offset;
2028 ph->p_vaddr = interp->sh_addr;
2029 ph->p_paddr = ph->p_vaddr;
2030 ph->p_filesz = interp->sh_size;
2031 ph->p_memsz = interp->sh_size;
2032 ph->p_flags = PF_R;
2033 ph->p_align = interp->sh_addralign;
2036 /* if dynamic section, then add corresponding program header */
2037 if (dynamic) {
2038 ph = &phdr[phnum - 1];
2040 ph->p_type = PT_DYNAMIC;
2041 ph->p_offset = dynamic->sh_offset;
2042 ph->p_vaddr = dynamic->sh_addr;
2043 ph->p_paddr = ph->p_vaddr;
2044 ph->p_filesz = dynamic->sh_size;
2045 ph->p_memsz = dynamic->sh_size;
2046 ph->p_flags = PF_R | PF_W;
2047 ph->p_align = dynamic->sh_addralign;
2051 /* Fill the dynamic section with tags describing the address and size of
2052 sections */
2053 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2055 Section *dynamic = dyninf->dynamic;
2056 Section *s;
2058 /* put dynamic section entries */
2059 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2060 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2061 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2062 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2063 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2064 #if PTR_SIZE == 8
2065 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2066 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2067 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2068 #else
2069 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2070 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2071 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
2072 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2073 put_dt(dynamic, DT_PLTREL, DT_REL);
2074 put_dt(dynamic, DT_REL, dyninf->bss_addr);
2075 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
2076 #else
2077 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2078 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2079 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2080 #endif
2081 #endif
2082 if (versym_section)
2083 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2084 if (verneed_section) {
2085 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2086 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2088 s = find_section_create (s1, ".preinit_array", 0);
2089 if (s && s->data_offset) {
2090 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2091 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2093 s = find_section_create (s1, ".init_array", 0);
2094 if (s && s->data_offset) {
2095 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2096 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2098 s = find_section_create (s1, ".fini_array", 0);
2099 if (s && s->data_offset) {
2100 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2101 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2103 s = find_section_create (s1, ".init", 0);
2104 if (s && s->data_offset) {
2105 put_dt(dynamic, DT_INIT, s->sh_addr);
2107 s = find_section_create (s1, ".fini", 0);
2108 if (s && s->data_offset) {
2109 put_dt(dynamic, DT_FINI, s->sh_addr);
2111 if (s1->do_debug)
2112 put_dt(dynamic, DT_DEBUG, 0);
2113 put_dt(dynamic, DT_NULL, 0);
2116 /* Relocate remaining sections and symbols (that is those not related to
2117 dynamic linking) */
2118 static int final_sections_reloc(TCCState *s1)
2120 int i;
2121 Section *s;
2123 relocate_syms(s1, s1->symtab, 0);
2125 if (s1->nb_errors != 0)
2126 return -1;
2128 /* relocate sections */
2129 /* XXX: ignore sections with allocated relocations ? */
2130 for(i = 1; i < s1->nb_sections; i++) {
2131 s = s1->sections[i];
2132 if (s->reloc && (s != s1->got || s1->static_link))
2133 relocate_section(s1, s);
2136 /* relocate relocation entries if the relocation tables are
2137 allocated in the executable */
2138 for(i = 1; i < s1->nb_sections; i++) {
2139 s = s1->sections[i];
2140 if ((s->sh_flags & SHF_ALLOC) &&
2141 s->sh_type == SHT_RELX) {
2142 relocate_rel(s1, s);
2145 return 0;
2147 #endif
2149 /* Create an ELF file on disk.
2150 This function handle ELF specific layout requirements */
2151 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2152 int file_offset, int *sec_order)
2154 int i, shnum, offset, size, file_type;
2155 Section *s;
2156 ElfW(Ehdr) ehdr;
2157 ElfW(Shdr) shdr, *sh;
2159 file_type = s1->output_type;
2160 shnum = s1->nb_sections;
2162 memset(&ehdr, 0, sizeof(ehdr));
2164 if (phnum > 0) {
2165 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2166 ehdr.e_phnum = phnum;
2167 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2170 /* align to 4 */
2171 file_offset = (file_offset + 3) & -4;
2173 /* fill header */
2174 ehdr.e_ident[0] = ELFMAG0;
2175 ehdr.e_ident[1] = ELFMAG1;
2176 ehdr.e_ident[2] = ELFMAG2;
2177 ehdr.e_ident[3] = ELFMAG3;
2178 ehdr.e_ident[4] = ELFCLASSW;
2179 ehdr.e_ident[5] = ELFDATA2LSB;
2180 ehdr.e_ident[6] = EV_CURRENT;
2181 #if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
2182 /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
2183 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2184 #endif
2185 #ifdef TCC_TARGET_ARM
2186 #ifdef TCC_ARM_EABI
2187 ehdr.e_ident[EI_OSABI] = 0;
2188 ehdr.e_flags = EF_ARM_EABI_VER4;
2189 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2190 ehdr.e_flags |= EF_ARM_HASENTRY;
2191 if (s1->float_abi == ARM_HARD_FLOAT)
2192 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2193 else
2194 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2195 #else
2196 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2197 #endif
2198 #elif defined TCC_TARGET_RISCV64
2199 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2200 #endif
2201 switch(file_type) {
2202 default:
2203 case TCC_OUTPUT_EXE:
2204 ehdr.e_type = ET_EXEC;
2205 ehdr.e_entry = get_sym_addr(s1, "_start", 1, 0);
2206 break;
2207 case TCC_OUTPUT_DLL:
2208 ehdr.e_type = ET_DYN;
2209 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2210 break;
2211 case TCC_OUTPUT_OBJ:
2212 ehdr.e_type = ET_REL;
2213 break;
2215 ehdr.e_machine = EM_TCC_TARGET;
2216 ehdr.e_version = EV_CURRENT;
2217 ehdr.e_shoff = file_offset;
2218 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2219 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2220 ehdr.e_shnum = shnum;
2221 ehdr.e_shstrndx = shnum - 1;
2223 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2224 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2225 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2227 sort_syms(s1, symtab_section);
2228 for(i = 1; i < s1->nb_sections; i++) {
2229 s = s1->sections[sec_order[i]];
2230 if (s->sh_type != SHT_NOBITS) {
2231 while (offset < s->sh_offset) {
2232 fputc(0, f);
2233 offset++;
2235 size = s->sh_size;
2236 if (size)
2237 fwrite(s->data, 1, size, f);
2238 offset += size;
2242 /* output section headers */
2243 while (offset < ehdr.e_shoff) {
2244 fputc(0, f);
2245 offset++;
2248 for(i = 0; i < s1->nb_sections; i++) {
2249 sh = &shdr;
2250 memset(sh, 0, sizeof(ElfW(Shdr)));
2251 s = s1->sections[i];
2252 if (s) {
2253 sh->sh_name = s->sh_name;
2254 sh->sh_type = s->sh_type;
2255 sh->sh_flags = s->sh_flags;
2256 sh->sh_entsize = s->sh_entsize;
2257 sh->sh_info = s->sh_info;
2258 if (s->link)
2259 sh->sh_link = s->link->sh_num;
2260 sh->sh_addralign = s->sh_addralign;
2261 sh->sh_addr = s->sh_addr;
2262 sh->sh_offset = s->sh_offset;
2263 sh->sh_size = s->sh_size;
2265 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2269 /* Write an elf, coff or "binary" file */
2270 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2271 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2273 int fd, mode, file_type;
2274 FILE *f;
2276 file_type = s1->output_type;
2277 if (file_type == TCC_OUTPUT_OBJ)
2278 mode = 0666;
2279 else
2280 mode = 0777;
2281 unlink(filename);
2282 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2283 if (fd < 0) {
2284 tcc_error_noabort("could not write '%s'", filename);
2285 return -1;
2287 f = fdopen(fd, "wb");
2288 if (s1->verbose)
2289 printf("<- %s\n", filename);
2291 #ifdef TCC_TARGET_COFF
2292 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2293 tcc_output_coff(s1, f);
2294 else
2295 #endif
2296 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2297 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2298 else
2299 tcc_output_binary(s1, f, sec_order);
2300 fclose(f);
2302 return 0;
2305 #ifndef ELF_OBJ_ONLY
2306 /* Sort section headers by assigned sh_addr, remove sections
2307 that we aren't going to output. */
2308 static void tidy_section_headers(TCCState *s1, int *sec_order)
2310 int i, nnew, l, *backmap;
2311 Section **snew, *s;
2312 ElfW(Sym) *sym;
2314 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2315 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2316 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2317 s = s1->sections[sec_order[i]];
2318 if (!i || s->sh_name) {
2319 backmap[sec_order[i]] = nnew;
2320 snew[nnew] = s;
2321 ++nnew;
2322 } else {
2323 backmap[sec_order[i]] = 0;
2324 snew[--l] = s;
2327 for (i = 0; i < nnew; i++) {
2328 s = snew[i];
2329 if (s) {
2330 s->sh_num = i;
2331 if (s->sh_type == SHT_RELX)
2332 s->sh_info = backmap[s->sh_info];
2336 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2337 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2338 sym->st_shndx = backmap[sym->st_shndx];
2339 if( !s1->static_link ) {
2340 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2341 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2342 sym->st_shndx = backmap[sym->st_shndx];
2344 for (i = 0; i < s1->nb_sections; i++)
2345 sec_order[i] = i;
2346 tcc_free(s1->sections);
2347 s1->sections = snew;
2348 s1->nb_sections = nnew;
2349 tcc_free(backmap);
2351 #endif
2353 /* Output an elf, coff or binary file */
2354 /* XXX: suppress unneeded sections */
2355 static int elf_output_file(TCCState *s1, const char *filename)
2357 int ret, phnum, shnum, file_type, file_offset, *sec_order;
2358 struct dyn_inf dyninf = {0};
2359 ElfW(Phdr) *phdr;
2360 Section *strsec, *interp, *dynamic, *dynstr;
2362 file_type = s1->output_type;
2363 s1->nb_errors = 0;
2364 ret = -1;
2365 phdr = NULL;
2366 sec_order = NULL;
2367 interp = dynamic = dynstr = NULL; /* avoid warning */
2369 #ifndef ELF_OBJ_ONLY
2370 if (file_type != TCC_OUTPUT_OBJ) {
2371 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2372 tcc_add_runtime(s1);
2373 resolve_common_syms(s1);
2375 if (!s1->static_link) {
2376 if (file_type == TCC_OUTPUT_EXE) {
2377 char *ptr;
2378 /* allow override the dynamic loader */
2379 const char *elfint = getenv("LD_SO");
2380 if (elfint == NULL)
2381 elfint = DEFAULT_ELFINTERP(s1);
2382 /* add interpreter section only if executable */
2383 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2384 interp->sh_addralign = 1;
2385 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2386 strcpy(ptr, elfint);
2389 /* add dynamic symbol table */
2390 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2391 ".dynstr",
2392 ".hash", SHF_ALLOC);
2393 dynstr = s1->dynsym->link;
2394 /* add dynamic section */
2395 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2396 SHF_ALLOC | SHF_WRITE);
2397 dynamic->link = dynstr;
2398 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2400 build_got(s1);
2402 if (file_type == TCC_OUTPUT_EXE) {
2403 bind_exe_dynsyms(s1);
2404 if (s1->nb_errors)
2405 goto the_end;
2406 bind_libs_dynsyms(s1);
2407 } else {
2408 /* shared library case: simply export all global symbols */
2409 export_global_syms(s1);
2412 build_got_entries(s1);
2413 version_add (s1);
2415 #endif
2417 /* we add a section for symbols */
2418 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2419 put_elf_str(strsec, "");
2421 /* Allocate strings for section names */
2422 ret = alloc_sec_names(s1, file_type, strsec);
2424 #ifndef ELF_OBJ_ONLY
2425 if (dynamic) {
2426 int i;
2427 /* add a list of needed dlls */
2428 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2429 DLLReference *dllref = s1->loaded_dlls[i];
2430 if (dllref->level == 0)
2431 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2434 if (s1->rpath)
2435 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2436 put_elf_str(dynstr, s1->rpath));
2438 if (file_type == TCC_OUTPUT_DLL) {
2439 if (s1->soname)
2440 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2441 /* XXX: currently, since we do not handle PIC code, we
2442 must relocate the readonly segments */
2443 if (ret)
2444 put_dt(dynamic, DT_TEXTREL, 0);
2447 if (s1->symbolic)
2448 put_dt(dynamic, DT_SYMBOLIC, 0);
2450 dyninf.dynamic = dynamic;
2451 dyninf.dynstr = dynstr;
2452 /* remember offset and reserve space for 2nd call below */
2453 dyninf.data_offset = dynamic->data_offset;
2454 fill_dynamic(s1, &dyninf);
2455 dynamic->sh_size = dynamic->data_offset;
2456 dynstr->sh_size = dynstr->data_offset;
2458 #endif
2460 /* compute number of program headers */
2461 if (file_type == TCC_OUTPUT_OBJ)
2462 phnum = 0;
2463 else if (file_type == TCC_OUTPUT_DLL)
2464 phnum = 3;
2465 else if (s1->static_link)
2466 phnum = 2;
2467 else
2468 phnum = 5;
2470 /* allocate program segment headers */
2471 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2473 /* compute number of sections */
2474 shnum = s1->nb_sections;
2476 /* this array is used to reorder sections in the output file */
2477 sec_order = tcc_malloc(sizeof(int) * shnum);
2478 sec_order[0] = 0;
2480 /* compute section to program header mapping */
2481 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2482 sec_order);
2484 #ifndef ELF_OBJ_ONLY
2485 /* Fill remaining program header and finalize relocation related to dynamic
2486 linking. */
2487 if (file_type != TCC_OUTPUT_OBJ) {
2488 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2489 if (dynamic) {
2490 ElfW(Sym) *sym;
2491 dynamic->data_offset = dyninf.data_offset;
2492 fill_dynamic(s1, &dyninf);
2494 /* put in GOT the dynamic section address and relocate PLT */
2495 write32le(s1->got->data, dynamic->sh_addr);
2496 if (file_type == TCC_OUTPUT_EXE
2497 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2498 relocate_plt(s1);
2500 /* relocate symbols in .dynsym now that final addresses are known */
2501 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2502 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2503 /* do symbol relocation */
2504 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2509 /* if building executable or DLL, then relocate each section
2510 except the GOT which is already relocated */
2511 ret = final_sections_reloc(s1);
2512 if (ret)
2513 goto the_end;
2514 tidy_section_headers(s1, sec_order);
2516 /* Perform relocation to GOT or PLT entries */
2517 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2518 fill_got(s1);
2519 else if (s1->got)
2520 fill_local_got_entries(s1);
2522 #endif
2524 /* Create the ELF file with name 'filename' */
2525 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2526 s1->nb_sections = shnum;
2527 goto the_end;
2528 the_end:
2529 tcc_free(sec_order);
2530 tcc_free(phdr);
2531 return ret;
2534 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2536 int ret;
2537 #ifdef TCC_TARGET_PE
2538 if (s->output_type != TCC_OUTPUT_OBJ) {
2539 ret = pe_output_file(s, filename);
2540 } else
2541 #elif TCC_TARGET_MACHO
2542 if (s->output_type != TCC_OUTPUT_OBJ) {
2543 ret = macho_output_file(s, filename);
2544 } else
2545 #endif
2546 ret = elf_output_file(s, filename);
2547 return ret;
2550 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
2551 char *cbuf = buf;
2552 size_t rnum = 0;
2553 while (1) {
2554 ssize_t num = read(fd, cbuf, count-rnum);
2555 if (num < 0) return num;
2556 if (num == 0) return rnum;
2557 rnum += num;
2558 cbuf += num;
2562 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
2564 void *data;
2566 data = tcc_malloc(size);
2567 lseek(fd, file_offset, SEEK_SET);
2568 full_read(fd, data, size);
2569 return data;
2572 typedef struct SectionMergeInfo {
2573 Section *s; /* corresponding existing section */
2574 unsigned long offset; /* offset of the new section in the existing section */
2575 uint8_t new_section; /* true if section 's' was added */
2576 uint8_t link_once; /* true if link once section */
2577 } SectionMergeInfo;
2579 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2581 int size = full_read(fd, h, sizeof *h);
2582 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2583 if (h->e_type == ET_REL)
2584 return AFF_BINTYPE_REL;
2585 if (h->e_type == ET_DYN)
2586 return AFF_BINTYPE_DYN;
2587 } else if (size >= 8) {
2588 if (0 == memcmp(h, ARMAG, 8))
2589 return AFF_BINTYPE_AR;
2590 #ifdef TCC_TARGET_COFF
2591 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2592 return AFF_BINTYPE_C67;
2593 #endif
2595 return 0;
2598 /* load an object file and merge it with current files */
2599 /* XXX: handle correctly stab (debug) info */
2600 ST_FUNC int tcc_load_object_file(TCCState *s1,
2601 int fd, unsigned long file_offset)
2603 ElfW(Ehdr) ehdr;
2604 ElfW(Shdr) *shdr, *sh;
2605 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2606 char *strsec, *strtab;
2607 int stab_index, stabstr_index;
2608 int *old_to_new_syms;
2609 char *sh_name, *name;
2610 SectionMergeInfo *sm_table, *sm;
2611 ElfW(Sym) *sym, *symtab;
2612 ElfW_Rel *rel;
2613 Section *s;
2615 lseek(fd, file_offset, SEEK_SET);
2616 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2617 goto fail1;
2618 /* test CPU specific stuff */
2619 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2620 ehdr.e_machine != EM_TCC_TARGET) {
2621 fail1:
2622 tcc_error_noabort("invalid object file");
2623 return -1;
2625 /* read sections */
2626 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2627 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2628 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2630 /* load section names */
2631 sh = &shdr[ehdr.e_shstrndx];
2632 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2634 /* load symtab and strtab */
2635 old_to_new_syms = NULL;
2636 symtab = NULL;
2637 strtab = NULL;
2638 nb_syms = 0;
2639 seencompressed = 0;
2640 stab_index = stabstr_index = 0;
2642 for(i = 1; i < ehdr.e_shnum; i++) {
2643 sh = &shdr[i];
2644 if (sh->sh_type == SHT_SYMTAB) {
2645 if (symtab) {
2646 tcc_error_noabort("object must contain only one symtab");
2647 fail:
2648 ret = -1;
2649 goto the_end;
2651 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2652 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2653 sm_table[i].s = symtab_section;
2655 /* now load strtab */
2656 sh = &shdr[sh->sh_link];
2657 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2659 if (sh->sh_flags & SHF_COMPRESSED)
2660 seencompressed = 1;
2663 /* now examine each section and try to merge its content with the
2664 ones in memory */
2665 for(i = 1; i < ehdr.e_shnum; i++) {
2666 /* no need to examine section name strtab */
2667 if (i == ehdr.e_shstrndx)
2668 continue;
2669 sh = &shdr[i];
2670 if (sh->sh_type == SHT_RELX)
2671 sh = &shdr[sh->sh_info];
2672 /* ignore sections types we do not handle (plus relocs to those) */
2673 if (sh->sh_type != SHT_PROGBITS &&
2674 #ifdef TCC_ARM_EABI
2675 sh->sh_type != SHT_ARM_EXIDX &&
2676 #endif
2677 sh->sh_type != SHT_NOBITS &&
2678 sh->sh_type != SHT_PREINIT_ARRAY &&
2679 sh->sh_type != SHT_INIT_ARRAY &&
2680 sh->sh_type != SHT_FINI_ARRAY &&
2681 strcmp(strsec + sh->sh_name, ".stabstr")
2683 continue;
2684 if (seencompressed
2685 && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
2686 continue;
2688 sh = &shdr[i];
2689 sh_name = strsec + sh->sh_name;
2690 if (sh->sh_addralign < 1)
2691 sh->sh_addralign = 1;
2692 /* find corresponding section, if any */
2693 for(j = 1; j < s1->nb_sections;j++) {
2694 s = s1->sections[j];
2695 if (!strcmp(s->name, sh_name)) {
2696 if (!strncmp(sh_name, ".gnu.linkonce",
2697 sizeof(".gnu.linkonce") - 1)) {
2698 /* if a 'linkonce' section is already present, we
2699 do not add it again. It is a little tricky as
2700 symbols can still be defined in
2701 it. */
2702 sm_table[i].link_once = 1;
2703 goto next;
2705 if (stab_section) {
2706 if (s == stab_section)
2707 stab_index = i;
2708 if (s == stab_section->link)
2709 stabstr_index = i;
2711 goto found;
2714 /* not found: create new section */
2715 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2716 /* take as much info as possible from the section. sh_link and
2717 sh_info will be updated later */
2718 s->sh_addralign = sh->sh_addralign;
2719 s->sh_entsize = sh->sh_entsize;
2720 sm_table[i].new_section = 1;
2721 found:
2722 if (sh->sh_type != s->sh_type) {
2723 tcc_error_noabort("invalid section type");
2724 goto fail;
2726 /* align start of section */
2727 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
2728 if (sh->sh_addralign > s->sh_addralign)
2729 s->sh_addralign = sh->sh_addralign;
2730 sm_table[i].offset = s->data_offset;
2731 sm_table[i].s = s;
2732 /* concatenate sections */
2733 size = sh->sh_size;
2734 if (sh->sh_type != SHT_NOBITS) {
2735 unsigned char *ptr;
2736 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2737 ptr = section_ptr_add(s, size);
2738 full_read(fd, ptr, size);
2739 } else {
2740 s->data_offset += size;
2742 next: ;
2745 /* gr relocate stab strings */
2746 if (stab_index && stabstr_index) {
2747 Stab_Sym *a, *b;
2748 unsigned o;
2749 s = sm_table[stab_index].s;
2750 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2751 b = (Stab_Sym *)(s->data + s->data_offset);
2752 o = sm_table[stabstr_index].offset;
2753 while (a < b) {
2754 if (a->n_strx)
2755 a->n_strx += o;
2756 a++;
2760 /* second short pass to update sh_link and sh_info fields of new
2761 sections */
2762 for(i = 1; i < ehdr.e_shnum; i++) {
2763 s = sm_table[i].s;
2764 if (!s || !sm_table[i].new_section)
2765 continue;
2766 sh = &shdr[i];
2767 if (sh->sh_link > 0)
2768 s->link = sm_table[sh->sh_link].s;
2769 if (sh->sh_type == SHT_RELX) {
2770 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2771 /* update backward link */
2772 s1->sections[s->sh_info]->reloc = s;
2776 /* resolve symbols */
2777 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2779 sym = symtab + 1;
2780 for(i = 1; i < nb_syms; i++, sym++) {
2781 if (sym->st_shndx != SHN_UNDEF &&
2782 sym->st_shndx < SHN_LORESERVE) {
2783 sm = &sm_table[sym->st_shndx];
2784 if (sm->link_once) {
2785 /* if a symbol is in a link once section, we use the
2786 already defined symbol. It is very important to get
2787 correct relocations */
2788 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2789 name = strtab + sym->st_name;
2790 sym_index = find_elf_sym(symtab_section, name);
2791 if (sym_index)
2792 old_to_new_syms[i] = sym_index;
2794 continue;
2796 /* if no corresponding section added, no need to add symbol */
2797 if (!sm->s)
2798 continue;
2799 /* convert section number */
2800 sym->st_shndx = sm->s->sh_num;
2801 /* offset value */
2802 sym->st_value += sm->offset;
2804 /* add symbol */
2805 name = strtab + sym->st_name;
2806 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2807 sym->st_info, sym->st_other,
2808 sym->st_shndx, name);
2809 old_to_new_syms[i] = sym_index;
2812 /* third pass to patch relocation entries */
2813 for(i = 1; i < ehdr.e_shnum; i++) {
2814 s = sm_table[i].s;
2815 if (!s)
2816 continue;
2817 sh = &shdr[i];
2818 offset = sm_table[i].offset;
2819 switch(s->sh_type) {
2820 case SHT_RELX:
2821 /* take relocation offset information */
2822 offseti = sm_table[sh->sh_info].offset;
2823 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2824 int type;
2825 unsigned sym_index;
2826 /* convert symbol index */
2827 type = ELFW(R_TYPE)(rel->r_info);
2828 sym_index = ELFW(R_SYM)(rel->r_info);
2829 /* NOTE: only one symtab assumed */
2830 if (sym_index >= nb_syms)
2831 goto invalid_reloc;
2832 sym_index = old_to_new_syms[sym_index];
2833 /* ignore link_once in rel section. */
2834 if (!sym_index && !sm_table[sh->sh_info].link_once
2835 #ifdef TCC_TARGET_ARM
2836 && type != R_ARM_V4BX
2837 #elif defined TCC_TARGET_RISCV64
2838 && type != R_RISCV_ALIGN
2839 && type != R_RISCV_RELAX
2840 #endif
2842 invalid_reloc:
2843 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2844 i, strsec + sh->sh_name, (int)rel->r_offset);
2845 goto fail;
2847 rel->r_info = ELFW(R_INFO)(sym_index, type);
2848 /* offset the relocation offset */
2849 rel->r_offset += offseti;
2850 #ifdef TCC_TARGET_ARM
2851 /* Jumps and branches from a Thumb code to a PLT entry need
2852 special handling since PLT entries are ARM code.
2853 Unconditional bl instructions referencing PLT entries are
2854 handled by converting these instructions into blx
2855 instructions. Other case of instructions referencing a PLT
2856 entry require to add a Thumb stub before the PLT entry to
2857 switch to ARM mode. We set bit plt_thumb_stub of the
2858 attribute of a symbol to indicate such a case. */
2859 if (type == R_ARM_THM_JUMP24)
2860 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2861 #endif
2863 break;
2864 default:
2865 break;
2869 ret = 0;
2870 the_end:
2871 tcc_free(symtab);
2872 tcc_free(strtab);
2873 tcc_free(old_to_new_syms);
2874 tcc_free(sm_table);
2875 tcc_free(strsec);
2876 tcc_free(shdr);
2877 return ret;
2880 typedef struct ArchiveHeader {
2881 char ar_name[16]; /* name of this member */
2882 char ar_date[12]; /* file mtime */
2883 char ar_uid[6]; /* owner uid; printed as decimal */
2884 char ar_gid[6]; /* owner gid; printed as decimal */
2885 char ar_mode[8]; /* file mode, printed as octal */
2886 char ar_size[10]; /* file size, printed as decimal */
2887 char ar_fmag[2]; /* should contain ARFMAG */
2888 } ArchiveHeader;
2890 #define ARFMAG "`\n"
2892 static unsigned long long get_be(const uint8_t *b, int n)
2894 unsigned long long ret = 0;
2895 while (n)
2896 ret = (ret << 8) | *b++, --n;
2897 return ret;
2900 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
2902 char *p, *e;
2903 int len;
2904 lseek(fd, offset, SEEK_SET);
2905 len = full_read(fd, hdr, sizeof(ArchiveHeader));
2906 if (len != sizeof(ArchiveHeader))
2907 return len ? -1 : 0;
2908 p = hdr->ar_name;
2909 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
2910 --e;
2911 *e = '\0';
2912 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
2913 return len;
2916 /* load only the objects which resolve undefined symbols */
2917 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2919 int i, bound, nsyms, sym_index, len, ret = -1;
2920 unsigned long long off;
2921 uint8_t *data;
2922 const char *ar_names, *p;
2923 const uint8_t *ar_index;
2924 ElfW(Sym) *sym;
2925 ArchiveHeader hdr;
2927 data = tcc_malloc(size);
2928 if (full_read(fd, data, size) != size)
2929 goto the_end;
2930 nsyms = get_be(data, entrysize);
2931 ar_index = data + entrysize;
2932 ar_names = (char *) ar_index + nsyms * entrysize;
2934 do {
2935 bound = 0;
2936 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2937 Section *s = symtab_section;
2938 sym_index = find_elf_sym(s, p);
2939 if (!sym_index)
2940 continue;
2941 sym = &((ElfW(Sym) *)s->data)[sym_index];
2942 if(sym->st_shndx != SHN_UNDEF)
2943 continue;
2944 off = get_be(ar_index + i * entrysize, entrysize);
2945 len = read_ar_header(fd, off, &hdr);
2946 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
2947 tcc_error_noabort("invalid archive");
2948 goto the_end;
2950 off += len;
2951 if (s1->verbose == 2)
2952 printf(" -> %s\n", hdr.ar_name);
2953 if (tcc_load_object_file(s1, fd, off) < 0)
2954 goto the_end;
2955 ++bound;
2957 } while(bound);
2958 ret = 0;
2959 the_end:
2960 tcc_free(data);
2961 return ret;
2964 /* load a '.a' file */
2965 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
2967 ArchiveHeader hdr;
2968 /* char magic[8]; */
2969 int size, len;
2970 unsigned long file_offset;
2971 ElfW(Ehdr) ehdr;
2973 /* skip magic which was already checked */
2974 /* full_read(fd, magic, sizeof(magic)); */
2975 file_offset = sizeof ARMAG - 1;
2977 for(;;) {
2978 len = read_ar_header(fd, file_offset, &hdr);
2979 if (len == 0)
2980 return 0;
2981 if (len < 0) {
2982 tcc_error_noabort("invalid archive");
2983 return -1;
2985 file_offset += len;
2986 size = strtol(hdr.ar_size, NULL, 0);
2987 /* align to even */
2988 size = (size + 1) & ~1;
2989 if (alacarte) {
2990 /* coff symbol table : we handle it */
2991 if (!strcmp(hdr.ar_name, "/"))
2992 return tcc_load_alacarte(s1, fd, size, 4);
2993 if (!strcmp(hdr.ar_name, "/SYM64/"))
2994 return tcc_load_alacarte(s1, fd, size, 8);
2995 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2996 if (s1->verbose == 2)
2997 printf(" -> %s\n", hdr.ar_name);
2998 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2999 return -1;
3001 file_offset += size;
3005 #ifndef ELF_OBJ_ONLY
3006 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3007 LV, maybe create a new entry for (LIB,VERSION). */
3008 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3010 while (i >= *n) {
3011 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3012 (*lv)[(*n)++] = -1;
3014 if ((*lv)[i] == -1) {
3015 int v, prev_same_lib = -1;
3016 for (v = 0; v < nb_sym_versions; v++) {
3017 if (strcmp(sym_versions[v].lib, lib))
3018 continue;
3019 prev_same_lib = v;
3020 if (!strcmp(sym_versions[v].version, version))
3021 break;
3023 if (v == nb_sym_versions) {
3024 sym_versions = tcc_realloc (sym_versions,
3025 (v + 1) * sizeof(*sym_versions));
3026 sym_versions[v].lib = tcc_strdup(lib);
3027 sym_versions[v].version = tcc_strdup(version);
3028 sym_versions[v].out_index = 0;
3029 sym_versions[v].prev_same_lib = prev_same_lib;
3030 nb_sym_versions++;
3032 (*lv)[i] = v;
3036 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3037 VERNDX. */
3038 static void
3039 set_sym_version(TCCState *s1, int sym_index, int verndx)
3041 if (sym_index >= nb_sym_to_version) {
3042 int newelems = sym_index ? sym_index * 2 : 1;
3043 sym_to_version = tcc_realloc(sym_to_version,
3044 newelems * sizeof(*sym_to_version));
3045 memset(sym_to_version + nb_sym_to_version, -1,
3046 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3047 nb_sym_to_version = newelems;
3049 if (sym_to_version[sym_index] < 0)
3050 sym_to_version[sym_index] = verndx;
3053 struct versym_info {
3054 int nb_versyms;
3055 ElfW(Verdef) *verdef;
3056 ElfW(Verneed) *verneed;
3057 ElfW(Half) *versym;
3058 int nb_local_ver, *local_ver;
3062 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3064 char *lib, *version;
3065 uint32_t next;
3066 int i;
3068 #define DEBUG_VERSION 0
3070 if (v->versym && v->verdef) {
3071 ElfW(Verdef) *vdef = v->verdef;
3072 lib = NULL;
3073 do {
3074 ElfW(Verdaux) *verdaux =
3075 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3077 #if DEBUG_VERSION
3078 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3079 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3080 vdef->vd_hash);
3081 #endif
3082 if (vdef->vd_cnt) {
3083 version = dynstr + verdaux->vda_name;
3085 if (lib == NULL)
3086 lib = version;
3087 else
3088 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3089 lib, version);
3090 #if DEBUG_VERSION
3091 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3092 #endif
3094 next = vdef->vd_next;
3095 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3096 } while (next);
3098 if (v->versym && v->verneed) {
3099 ElfW(Verneed) *vneed = v->verneed;
3100 do {
3101 ElfW(Vernaux) *vernaux =
3102 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3104 lib = dynstr + vneed->vn_file;
3105 #if DEBUG_VERSION
3106 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3107 #endif
3108 for (i = 0; i < vneed->vn_cnt; i++) {
3109 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3110 version = dynstr + vernaux->vna_name;
3111 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3112 lib, version);
3113 #if DEBUG_VERSION
3114 printf (" vernaux(%u): %u %u %s\n",
3115 vernaux->vna_other, vernaux->vna_hash,
3116 vernaux->vna_flags, version);
3117 #endif
3119 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3121 next = vneed->vn_next;
3122 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3123 } while (next);
3126 #if DEBUG_VERSION
3127 for (i = 0; i < v->nb_local_ver; i++) {
3128 if (v->local_ver[i] > 0) {
3129 printf ("%d: lib: %s, version %s\n",
3130 i, sym_versions[v->local_ver[i]].lib,
3131 sym_versions[v->local_ver[i]].version);
3134 #endif
3137 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3138 is referenced by the user (so it should be added as DT_NEEDED in
3139 the generated ELF file) */
3140 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3142 ElfW(Ehdr) ehdr;
3143 ElfW(Shdr) *shdr, *sh, *sh1;
3144 int i, j, nb_syms, nb_dts, sym_bind, ret;
3145 ElfW(Sym) *sym, *dynsym;
3146 ElfW(Dyn) *dt, *dynamic;
3148 char *dynstr;
3149 int sym_index;
3150 const char *name, *soname;
3151 DLLReference *dllref;
3152 struct versym_info v;
3154 full_read(fd, &ehdr, sizeof(ehdr));
3156 /* test CPU specific stuff */
3157 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3158 ehdr.e_machine != EM_TCC_TARGET) {
3159 tcc_error_noabort("bad architecture");
3160 return -1;
3163 /* read sections */
3164 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3166 /* load dynamic section and dynamic symbols */
3167 nb_syms = 0;
3168 nb_dts = 0;
3169 dynamic = NULL;
3170 dynsym = NULL; /* avoid warning */
3171 dynstr = NULL; /* avoid warning */
3172 memset(&v, 0, sizeof v);
3174 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3175 switch(sh->sh_type) {
3176 case SHT_DYNAMIC:
3177 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3178 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3179 break;
3180 case SHT_DYNSYM:
3181 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3182 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3183 sh1 = &shdr[sh->sh_link];
3184 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3185 break;
3186 case SHT_GNU_verdef:
3187 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3188 break;
3189 case SHT_GNU_verneed:
3190 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3191 break;
3192 case SHT_GNU_versym:
3193 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3194 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3195 break;
3196 default:
3197 break;
3201 /* compute the real library name */
3202 soname = tcc_basename(filename);
3204 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3205 if (dt->d_tag == DT_SONAME) {
3206 soname = dynstr + dt->d_un.d_val;
3210 /* if the dll is already loaded, do not load it */
3211 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3212 dllref = s1->loaded_dlls[i];
3213 if (!strcmp(soname, dllref->name)) {
3214 /* but update level if needed */
3215 if (level < dllref->level)
3216 dllref->level = level;
3217 ret = 0;
3218 goto the_end;
3222 if (v.nb_versyms != nb_syms)
3223 tcc_free (v.versym), v.versym = NULL;
3224 else
3225 store_version(s1, &v, dynstr);
3227 /* add the dll and its level */
3228 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
3229 dllref->level = level;
3230 strcpy(dllref->name, soname);
3231 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
3233 /* add dynamic symbols in dynsym_section */
3234 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3235 sym_bind = ELFW(ST_BIND)(sym->st_info);
3236 if (sym_bind == STB_LOCAL)
3237 continue;
3238 name = dynstr + sym->st_name;
3239 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3240 sym->st_info, sym->st_other, sym->st_shndx, name);
3241 if (v.versym) {
3242 ElfW(Half) vsym = v.versym[i];
3243 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3244 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3248 /* load all referenced DLLs */
3249 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3250 switch(dt->d_tag) {
3251 case DT_NEEDED:
3252 name = dynstr + dt->d_un.d_val;
3253 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3254 dllref = s1->loaded_dlls[j];
3255 if (!strcmp(name, dllref->name))
3256 goto already_loaded;
3258 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3259 tcc_error_noabort("referenced dll '%s' not found", name);
3260 ret = -1;
3261 goto the_end;
3263 already_loaded:
3264 break;
3267 ret = 0;
3268 the_end:
3269 tcc_free(dynstr);
3270 tcc_free(dynsym);
3271 tcc_free(dynamic);
3272 tcc_free(shdr);
3273 tcc_free(v.local_ver);
3274 tcc_free(v.verdef);
3275 tcc_free(v.verneed);
3276 tcc_free(v.versym);
3277 return ret;
3280 #define LD_TOK_NAME 256
3281 #define LD_TOK_EOF (-1)
3283 static int ld_inp(TCCState *s1)
3285 char b;
3286 if (s1->cc != -1) {
3287 int c = s1->cc;
3288 s1->cc = -1;
3289 return c;
3291 if (1 == read(s1->fd, &b, 1))
3292 return b;
3293 return CH_EOF;
3296 /* return next ld script token */
3297 static int ld_next(TCCState *s1, char *name, int name_size)
3299 int c, d, ch;
3300 char *q;
3302 redo:
3303 ch = ld_inp(s1);
3304 switch(ch) {
3305 case ' ':
3306 case '\t':
3307 case '\f':
3308 case '\v':
3309 case '\r':
3310 case '\n':
3311 goto redo;
3312 case '/':
3313 ch = ld_inp(s1);
3314 if (ch == '*') { /* comment */
3315 for (d = 0;; d = ch) {
3316 ch = ld_inp(s1);
3317 if (ch == CH_EOF || (ch == '/' && d == '*'))
3318 break;
3320 goto redo;
3321 } else {
3322 q = name;
3323 *q++ = '/';
3324 goto parse_name;
3326 break;
3327 case '\\':
3328 /* case 'a' ... 'z': */
3329 case 'a':
3330 case 'b':
3331 case 'c':
3332 case 'd':
3333 case 'e':
3334 case 'f':
3335 case 'g':
3336 case 'h':
3337 case 'i':
3338 case 'j':
3339 case 'k':
3340 case 'l':
3341 case 'm':
3342 case 'n':
3343 case 'o':
3344 case 'p':
3345 case 'q':
3346 case 'r':
3347 case 's':
3348 case 't':
3349 case 'u':
3350 case 'v':
3351 case 'w':
3352 case 'x':
3353 case 'y':
3354 case 'z':
3355 /* case 'A' ... 'z': */
3356 case 'A':
3357 case 'B':
3358 case 'C':
3359 case 'D':
3360 case 'E':
3361 case 'F':
3362 case 'G':
3363 case 'H':
3364 case 'I':
3365 case 'J':
3366 case 'K':
3367 case 'L':
3368 case 'M':
3369 case 'N':
3370 case 'O':
3371 case 'P':
3372 case 'Q':
3373 case 'R':
3374 case 'S':
3375 case 'T':
3376 case 'U':
3377 case 'V':
3378 case 'W':
3379 case 'X':
3380 case 'Y':
3381 case 'Z':
3382 case '_':
3383 case '.':
3384 case '$':
3385 case '~':
3386 q = name;
3387 parse_name:
3388 for(;;) {
3389 if (!((ch >= 'a' && ch <= 'z') ||
3390 (ch >= 'A' && ch <= 'Z') ||
3391 (ch >= '0' && ch <= '9') ||
3392 strchr("/.-_+=$:\\,~", ch)))
3393 break;
3394 if ((q - name) < name_size - 1) {
3395 *q++ = ch;
3397 ch = ld_inp(s1);
3399 s1->cc = ch;
3400 *q = '\0';
3401 c = LD_TOK_NAME;
3402 break;
3403 case CH_EOF:
3404 c = LD_TOK_EOF;
3405 break;
3406 default:
3407 c = ch;
3408 break;
3410 return c;
3413 static int ld_add_file(TCCState *s1, const char filename[])
3415 if (filename[0] == '/') {
3416 if (CONFIG_SYSROOT[0] == '\0'
3417 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3418 return 0;
3419 filename = tcc_basename(filename);
3421 return tcc_add_dll(s1, filename, 0);
3424 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3426 char filename[1024], libname[1024];
3427 int t, group, nblibs = 0, ret = 0;
3428 char **libs = NULL;
3430 group = !strcmp(cmd, "GROUP");
3431 if (!as_needed)
3432 s1->new_undef_sym = 0;
3433 t = ld_next(s1, filename, sizeof(filename));
3434 if (t != '(') {
3435 tcc_error_noabort("( expected");
3436 ret = -1;
3437 goto lib_parse_error;
3439 t = ld_next(s1, filename, sizeof(filename));
3440 for(;;) {
3441 libname[0] = '\0';
3442 if (t == LD_TOK_EOF) {
3443 tcc_error_noabort("unexpected end of file");
3444 ret = -1;
3445 goto lib_parse_error;
3446 } else if (t == ')') {
3447 break;
3448 } else if (t == '-') {
3449 t = ld_next(s1, filename, sizeof(filename));
3450 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3451 tcc_error_noabort("library name expected");
3452 ret = -1;
3453 goto lib_parse_error;
3455 pstrcpy(libname, sizeof libname, &filename[1]);
3456 if (s1->static_link) {
3457 snprintf(filename, sizeof filename, "lib%s.a", libname);
3458 } else {
3459 snprintf(filename, sizeof filename, "lib%s.so", libname);
3461 } else if (t != LD_TOK_NAME) {
3462 tcc_error_noabort("filename expected");
3463 ret = -1;
3464 goto lib_parse_error;
3466 if (!strcmp(filename, "AS_NEEDED")) {
3467 ret = ld_add_file_list(s1, cmd, 1);
3468 if (ret)
3469 goto lib_parse_error;
3470 } else {
3471 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3472 if (!as_needed) {
3473 ret = ld_add_file(s1, filename);
3474 if (ret)
3475 goto lib_parse_error;
3476 if (group) {
3477 /* Add the filename *and* the libname to avoid future conversions */
3478 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3479 if (libname[0] != '\0')
3480 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3484 t = ld_next(s1, filename, sizeof(filename));
3485 if (t == ',') {
3486 t = ld_next(s1, filename, sizeof(filename));
3489 if (group && !as_needed) {
3490 while (s1->new_undef_sym) {
3491 int i;
3492 s1->new_undef_sym = 0;
3493 for (i = 0; i < nblibs; i ++)
3494 ld_add_file(s1, libs[i]);
3497 lib_parse_error:
3498 dynarray_reset(&libs, &nblibs);
3499 return ret;
3502 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3503 files */
3504 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3506 char cmd[64];
3507 char filename[1024];
3508 int t, ret;
3510 s1->fd = fd;
3511 s1->cc = -1;
3512 for(;;) {
3513 t = ld_next(s1, cmd, sizeof(cmd));
3514 if (t == LD_TOK_EOF)
3515 return 0;
3516 else if (t != LD_TOK_NAME)
3517 return -1;
3518 if (!strcmp(cmd, "INPUT") ||
3519 !strcmp(cmd, "GROUP")) {
3520 ret = ld_add_file_list(s1, cmd, 0);
3521 if (ret)
3522 return ret;
3523 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3524 !strcmp(cmd, "TARGET")) {
3525 /* ignore some commands */
3526 t = ld_next(s1, cmd, sizeof(cmd));
3527 if (t != '(') {
3528 tcc_error_noabort("( expected");
3529 return -1;
3531 for(;;) {
3532 t = ld_next(s1, filename, sizeof(filename));
3533 if (t == LD_TOK_EOF) {
3534 tcc_error_noabort("unexpected end of file");
3535 return -1;
3536 } else if (t == ')') {
3537 break;
3540 } else {
3541 return -1;
3544 return 0;
3546 #endif /* !ELF_OBJ_ONLY */