Relicensing TinyCC
[tinycc.git] / tccelf.c
blob0110152d1bcadf94aafcc41850c69a15207d9df9
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 #ifdef TCC_TARGET_PE
51 static const int shf_RELRO = SHF_ALLOC;
52 static const char rdata[] = ".rdata";
53 #else
54 static const int shf_RELRO = SHF_ALLOC | SHF_WRITE;
55 static const char rdata[] = ".data.ro";
56 #endif
58 /* ------------------------------------------------------------------------- */
60 ST_FUNC void tccelf_new(TCCState *s)
62 TCCState *s1 = s;
63 /* no section zero */
64 dynarray_add(&s->sections, &s->nb_sections, NULL);
66 /* create standard sections */
67 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
68 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
69 /* create ro data section (make ro after relocation done with GNU_RELRO) */
70 rodata_section = new_section(s, rdata, SHT_PROGBITS, shf_RELRO);
71 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
72 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
73 common_section->sh_num = SHN_COMMON;
75 /* symbols are always generated for linking stage */
76 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
77 ".strtab",
78 ".hashtab", SHF_PRIVATE);
79 s->symtab = symtab_section;
81 /* private symbol table for dynamic symbols */
82 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
83 ".dynstrtab",
84 ".dynhashtab", SHF_PRIVATE);
85 get_sym_attr(s, 0, 1);
88 #ifdef CONFIG_TCC_BCHECK
89 ST_FUNC void tccelf_bounds_new(TCCState *s)
91 TCCState *s1 = s;
92 /* create bounds sections (make ro after relocation done with GNU_RELRO) */
93 bounds_section = new_section(s, ".bounds", SHT_PROGBITS, shf_RELRO);
94 lbounds_section = new_section(s, ".lbounds", SHT_PROGBITS, shf_RELRO);
96 #endif
98 static void free_section(Section *s)
100 tcc_free(s->data);
103 ST_FUNC void tccelf_delete(TCCState *s1)
105 int i;
107 #ifndef ELF_OBJ_ONLY
108 /* free symbol versions */
109 for (i = 0; i < nb_sym_versions; i++) {
110 tcc_free(sym_versions[i].version);
111 tcc_free(sym_versions[i].lib);
113 tcc_free(sym_versions);
114 tcc_free(sym_to_version);
115 #endif
117 /* free all sections */
118 for(i = 1; i < s1->nb_sections; i++)
119 free_section(s1->sections[i]);
120 dynarray_reset(&s1->sections, &s1->nb_sections);
122 for(i = 0; i < s1->nb_priv_sections; i++)
123 free_section(s1->priv_sections[i]);
124 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
126 /* free any loaded DLLs */
127 #ifdef TCC_IS_NATIVE
128 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
129 DLLReference *ref = s1->loaded_dlls[i];
130 if ( ref->handle )
131 # ifdef _WIN32
132 FreeLibrary((HMODULE)ref->handle);
133 # else
134 dlclose(ref->handle);
135 # endif
137 #endif
138 /* free loaded dlls array */
139 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
140 tcc_free(s1->sym_attrs);
142 symtab_section = NULL; /* for tccrun.c:rt_printline() */
145 /* save section data state */
146 ST_FUNC void tccelf_begin_file(TCCState *s1)
148 Section *s; int i;
149 for (i = 1; i < s1->nb_sections; i++) {
150 s = s1->sections[i];
151 s->sh_offset = s->data_offset;
153 /* disable symbol hashing during compilation */
154 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
155 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
156 s1->uw_sym = 0;
157 #endif
160 /* At the end of compilation, convert any UNDEF syms to global, and merge
161 with previously existing symbols */
162 ST_FUNC void tccelf_end_file(TCCState *s1)
164 Section *s = s1->symtab;
165 int first_sym, nb_syms, *tr, i;
167 first_sym = s->sh_offset / sizeof (ElfSym);
168 nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
169 s->data_offset = s->sh_offset;
170 s->link->data_offset = s->link->sh_offset;
171 s->hash = s->reloc, s->reloc = NULL;
172 tr = tcc_mallocz(nb_syms * sizeof *tr);
174 for (i = 0; i < nb_syms; ++i) {
175 ElfSym *sym = (ElfSym*)s->data + first_sym + i;
176 if (sym->st_shndx == SHN_UNDEF
177 && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
178 sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
179 /* An ELF relocatable file should have the types of its undefined global symbol set
180 to STT_NOTYPE or it will confuse binutils bfd */
181 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF && s1->output_type == TCC_OUTPUT_OBJ)
182 if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_GLOBAL)
183 sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(STT_NOTYPE));
184 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
185 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
187 /* now update relocations */
188 for (i = 1; i < s1->nb_sections; i++) {
189 Section *sr = s1->sections[i];
190 if (sr->sh_type == SHT_RELX && sr->link == s) {
191 ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
192 ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
193 for (; rel < rel_end; ++rel) {
194 int n = ELFW(R_SYM)(rel->r_info) - first_sym;
195 if (n < 0) /* zero sym_index in reloc (can happen with asm) */
196 continue;
197 rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
201 tcc_free(tr);
203 /* record text/data/bss output for -bench info */
204 for (i = 0; i < 4; ++i) {
205 s = s1->sections[i + 1];
206 s1->total_output[i] += s->data_offset - s->sh_offset;
210 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
212 Section *sec;
214 sec = tcc_mallocz(sizeof(Section) + strlen(name));
215 sec->s1 = s1;
216 strcpy(sec->name, name);
217 sec->sh_type = sh_type;
218 sec->sh_flags = sh_flags;
219 switch(sh_type) {
220 case SHT_GNU_versym:
221 sec->sh_addralign = 2;
222 break;
223 case SHT_HASH:
224 case SHT_GNU_HASH:
225 case SHT_REL:
226 case SHT_RELA:
227 case SHT_DYNSYM:
228 case SHT_SYMTAB:
229 case SHT_DYNAMIC:
230 case SHT_GNU_verneed:
231 case SHT_GNU_verdef:
232 sec->sh_addralign = PTR_SIZE;
233 break;
234 case SHT_STRTAB:
235 sec->sh_addralign = 1;
236 break;
237 default:
238 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */
239 break;
242 if (sh_flags & SHF_PRIVATE) {
243 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
244 } else {
245 sec->sh_num = s1->nb_sections;
246 dynarray_add(&s1->sections, &s1->nb_sections, sec);
249 return sec;
252 ST_FUNC Section *new_symtab(TCCState *s1,
253 const char *symtab_name, int sh_type, int sh_flags,
254 const char *strtab_name,
255 const char *hash_name, int hash_sh_flags)
257 Section *symtab, *strtab, *hash;
258 int *ptr, nb_buckets;
260 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
261 symtab->sh_entsize = sizeof(ElfW(Sym));
262 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
263 put_elf_str(strtab, "");
264 symtab->link = strtab;
265 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
267 nb_buckets = 1;
269 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
270 hash->sh_entsize = sizeof(int);
271 symtab->hash = hash;
272 hash->link = symtab;
274 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
275 ptr[0] = nb_buckets;
276 ptr[1] = 1;
277 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
278 return symtab;
281 /* realloc section and set its content to zero */
282 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
284 unsigned long size;
285 unsigned char *data;
287 size = sec->data_allocated;
288 if (size == 0)
289 size = 1;
290 while (size < new_size)
291 size = size * 2;
292 data = tcc_realloc(sec->data, size);
293 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
294 sec->data = data;
295 sec->data_allocated = size;
298 /* reserve at least 'size' bytes aligned per 'align' in section
299 'sec' from current offset, and return the aligned offset */
300 ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
302 size_t offset, offset1;
304 offset = (sec->data_offset + align - 1) & -align;
305 offset1 = offset + size;
306 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
307 section_realloc(sec, offset1);
308 sec->data_offset = offset1;
309 if (align > sec->sh_addralign)
310 sec->sh_addralign = align;
311 return offset;
314 /* reserve at least 'size' bytes in section 'sec' from
315 sec->data_offset. */
316 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
318 size_t offset = section_add(sec, size, 1);
319 return sec->data + offset;
322 #ifndef ELF_OBJ_ONLY
323 /* reserve at least 'size' bytes from section start */
324 static void section_reserve(Section *sec, unsigned long size)
326 if (size > sec->data_allocated)
327 section_realloc(sec, size);
328 if (size > sec->data_offset)
329 sec->data_offset = size;
331 #endif
333 static Section *have_section(TCCState *s1, const char *name)
335 Section *sec;
336 int i;
337 for(i = 1; i < s1->nb_sections; i++) {
338 sec = s1->sections[i];
339 if (!strcmp(name, sec->name))
340 return sec;
342 return NULL;
345 /* return a reference to a section, and create it if it does not
346 exists */
347 ST_FUNC Section *find_section(TCCState *s1, const char *name)
349 Section *sec = have_section(s1, name);
350 if (sec)
351 return sec;
352 /* sections are created as PROGBITS */
353 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
356 /* ------------------------------------------------------------------------- */
358 ST_FUNC int put_elf_str(Section *s, const char *sym)
360 int offset, len;
361 char *ptr;
363 len = strlen(sym) + 1;
364 offset = s->data_offset;
365 ptr = section_ptr_add(s, len);
366 memmove(ptr, sym, len);
367 return offset;
370 /* elf symbol hashing function */
371 static ElfW(Word) elf_hash(const unsigned char *name)
373 ElfW(Word) h = 0, g;
375 while (*name) {
376 h = (h << 4) + *name++;
377 g = h & 0xf0000000;
378 if (g)
379 h ^= g >> 24;
380 h &= ~g;
382 return h;
385 /* rebuild hash table of section s */
386 /* NOTE: we do factorize the hash table code to go faster */
387 static void rebuild_hash(Section *s, unsigned int nb_buckets)
389 ElfW(Sym) *sym;
390 int *ptr, *hash, nb_syms, sym_index, h;
391 unsigned char *strtab;
393 strtab = s->link->data;
394 nb_syms = s->data_offset / sizeof(ElfW(Sym));
396 if (!nb_buckets)
397 nb_buckets = ((int*)s->hash->data)[0];
399 s->hash->data_offset = 0;
400 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
401 ptr[0] = nb_buckets;
402 ptr[1] = nb_syms;
403 ptr += 2;
404 hash = ptr;
405 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
406 ptr += nb_buckets + 1;
408 sym = (ElfW(Sym) *)s->data + 1;
409 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
410 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
411 h = elf_hash(strtab + sym->st_name) % nb_buckets;
412 *ptr = hash[h];
413 hash[h] = sym_index;
414 } else {
415 *ptr = 0;
417 ptr++;
418 sym++;
422 /* return the symbol number */
423 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
424 int info, int other, int shndx, const char *name)
426 int name_offset, sym_index;
427 int nbuckets, h;
428 ElfW(Sym) *sym;
429 Section *hs;
431 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
432 if (name && name[0])
433 name_offset = put_elf_str(s->link, name);
434 else
435 name_offset = 0;
436 /* XXX: endianness */
437 sym->st_name = name_offset;
438 sym->st_value = value;
439 sym->st_size = size;
440 sym->st_info = info;
441 sym->st_other = other;
442 sym->st_shndx = shndx;
443 sym_index = sym - (ElfW(Sym) *)s->data;
444 hs = s->hash;
445 if (hs) {
446 int *ptr, *base;
447 ptr = section_ptr_add(hs, sizeof(int));
448 base = (int *)hs->data;
449 /* only add global or weak symbols. */
450 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
451 /* add another hashing entry */
452 nbuckets = base[0];
453 h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
454 *ptr = base[2 + h];
455 base[2 + h] = sym_index;
456 base[1]++;
457 /* we resize the hash table */
458 hs->nb_hashed_syms++;
459 if (hs->nb_hashed_syms > 2 * nbuckets) {
460 rebuild_hash(s, 2 * nbuckets);
462 } else {
463 *ptr = 0;
464 base[1]++;
467 return sym_index;
470 ST_FUNC int find_elf_sym(Section *s, const char *name)
472 ElfW(Sym) *sym;
473 Section *hs;
474 int nbuckets, sym_index, h;
475 const char *name1;
477 hs = s->hash;
478 if (!hs)
479 return 0;
480 nbuckets = ((int *)hs->data)[0];
481 h = elf_hash((unsigned char *) name) % nbuckets;
482 sym_index = ((int *)hs->data)[2 + h];
483 while (sym_index != 0) {
484 sym = &((ElfW(Sym) *)s->data)[sym_index];
485 name1 = (char *) s->link->data + sym->st_name;
486 if (!strcmp(name, name1))
487 return sym_index;
488 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
490 return 0;
493 /* return elf symbol value, signal error if 'err' is nonzero, decorate
494 name if FORC */
495 ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
497 int sym_index;
498 ElfW(Sym) *sym;
499 char buf[256];
500 if (forc && s1->leading_underscore
501 #ifdef TCC_TARGET_PE
502 /* win32-32bit stdcall symbols always have _ already */
503 && !strchr(name, '@')
504 #endif
506 buf[0] = '_';
507 pstrcpy(buf + 1, sizeof(buf) - 1, name);
508 name = buf;
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_noabort("%s not defined", name);
515 return (addr_t)-1;
517 return sym->st_value;
520 /* return elf symbol value */
521 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
523 addr_t addr = get_sym_addr(s, name, 0, 1);
524 return addr == -1 ? NULL : (void*)(uintptr_t)addr;
527 /* list elf symbol names and values */
528 ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
529 void (*symbol_cb)(void *ctx, const char *name, const void *val))
531 ElfW(Sym) *sym;
532 Section *symtab;
533 int sym_index, end_sym;
534 const char *name;
535 unsigned char sym_vis, sym_bind;
537 symtab = s->symtab;
538 end_sym = symtab->data_offset / sizeof (ElfSym);
539 for (sym_index = 0; sym_index < end_sym; ++sym_index) {
540 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
541 if (sym->st_value) {
542 name = (char *) symtab->link->data + sym->st_name;
543 sym_bind = ELFW(ST_BIND)(sym->st_info);
544 sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
545 if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
546 symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
551 /* list elf symbol names and values */
552 LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
553 void (*symbol_cb)(void *ctx, const char *name, const void *val))
555 list_elf_symbols(s, ctx, symbol_cb);
558 #ifndef ELF_OBJ_ONLY
559 static void
560 version_add (TCCState *s1)
562 int i;
563 ElfW(Sym) *sym;
564 ElfW(Verneed) *vn = NULL;
565 Section *symtab;
566 int sym_index, end_sym, nb_versions = 2, nb_entries = 0;
567 ElfW(Half) *versym;
568 const char *name;
570 if (0 == nb_sym_versions)
571 return;
572 versym_section = new_section(s1, ".gnu.version", SHT_GNU_versym, SHF_ALLOC);
573 versym_section->sh_entsize = sizeof(ElfW(Half));
574 versym_section->link = s1->dynsym;
576 /* add needed symbols */
577 symtab = s1->dynsym;
578 end_sym = symtab->data_offset / sizeof (ElfSym);
579 versym = section_ptr_add(versym_section, end_sym * sizeof(ElfW(Half)));
580 for (sym_index = 1; sym_index < end_sym; ++sym_index) {
581 int dllindex, verndx;
582 sym = &((ElfW(Sym) *)symtab->data)[sym_index];
583 if (sym->st_shndx != SHN_UNDEF)
584 continue; /* defined symbol doesn't need library version */
585 name = (char *) symtab->link->data + sym->st_name;
586 dllindex = find_elf_sym(s1->dynsymtab_section, name);
587 verndx = (dllindex && dllindex < nb_sym_to_version)
588 ? sym_to_version[dllindex] : -1;
589 if (verndx >= 0) {
590 if (!sym_versions[verndx].out_index)
591 sym_versions[verndx].out_index = nb_versions++;
592 versym[sym_index] = sym_versions[verndx].out_index;
595 /* generate verneed section, but not when it will be empty. Some
596 dynamic linkers look at their contents even when DTVERNEEDNUM and
597 section size is zero. */
598 if (nb_versions > 2) {
599 verneed_section = new_section(s1, ".gnu.version_r",
600 SHT_GNU_verneed, SHF_ALLOC);
601 verneed_section->link = s1->dynsym->link;
602 for (i = nb_sym_versions; i-- > 0;) {
603 struct sym_version *sv = &sym_versions[i];
604 int n_same_libs = 0, prev;
605 size_t vnofs;
606 ElfW(Vernaux) *vna = 0;
607 if (sv->out_index < 1)
608 continue;
610 /* make sure that a DT_NEEDED tag is put */
611 /* abitest-tcc fails on older i386-linux with "ld-linux.so.2" DT_NEEDED
612 ret_int_test... Inconsistency detected by ld.so: dl-minimal.c: 148:
613 realloc: Assertion `ptr == alloc_last_block' failed! */
614 if (strcmp(sv->lib, "ld-linux.so.2"))
615 tcc_add_dllref(s1, sv->lib, 0);
617 vnofs = section_add(verneed_section, sizeof(*vn), 1);
618 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
619 vn->vn_version = 1;
620 vn->vn_file = put_elf_str(verneed_section->link, sv->lib);
621 vn->vn_aux = sizeof (*vn);
622 do {
623 prev = sv->prev_same_lib;
624 if (sv->out_index > 0) {
625 vna = section_ptr_add(verneed_section, sizeof(*vna));
626 vna->vna_hash = elf_hash ((const unsigned char *)sv->version);
627 vna->vna_flags = 0;
628 vna->vna_other = sv->out_index;
629 sv->out_index = -2;
630 vna->vna_name = put_elf_str(verneed_section->link, sv->version);
631 vna->vna_next = sizeof (*vna);
632 n_same_libs++;
634 if (prev >= 0)
635 sv = &sym_versions[prev];
636 } while(prev >= 0);
637 vna->vna_next = 0;
638 vn = (ElfW(Verneed)*)(verneed_section->data + vnofs);
639 vn->vn_cnt = n_same_libs;
640 vn->vn_next = sizeof(*vn) + n_same_libs * sizeof(*vna);
641 nb_entries++;
643 if (vn)
644 vn->vn_next = 0;
645 verneed_section->sh_info = nb_entries;
647 dt_verneednum = nb_entries;
649 #endif /* ndef ELF_OBJ_ONLY */
651 /* add an elf symbol : check if it is already defined and patch
652 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
653 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
654 int info, int other, int shndx, const char *name)
656 TCCState *s1 = s->s1;
657 ElfW(Sym) *esym;
658 int sym_bind, sym_index, sym_type, esym_bind;
659 unsigned char sym_vis, esym_vis, new_vis;
661 sym_bind = ELFW(ST_BIND)(info);
662 sym_type = ELFW(ST_TYPE)(info);
663 sym_vis = ELFW(ST_VISIBILITY)(other);
665 if (sym_bind != STB_LOCAL) {
666 /* we search global or weak symbols */
667 sym_index = find_elf_sym(s, name);
668 if (!sym_index)
669 goto do_def;
670 esym = &((ElfW(Sym) *)s->data)[sym_index];
671 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
672 && esym->st_other == other && esym->st_shndx == shndx)
673 return sym_index;
674 if (esym->st_shndx != SHN_UNDEF) {
675 esym_bind = ELFW(ST_BIND)(esym->st_info);
676 /* propagate the most constraining visibility */
677 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
678 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
679 if (esym_vis == STV_DEFAULT) {
680 new_vis = sym_vis;
681 } else if (sym_vis == STV_DEFAULT) {
682 new_vis = esym_vis;
683 } else {
684 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
686 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
687 | new_vis;
688 if (shndx == SHN_UNDEF) {
689 /* ignore adding of undefined symbol if the
690 corresponding symbol is already defined */
691 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
692 /* global overrides weak, so patch */
693 goto do_patch;
694 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
695 /* weak is ignored if already global */
696 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
697 /* keep first-found weak definition, ignore subsequents */
698 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
699 /* ignore hidden symbols after */
700 } else if ((esym->st_shndx == SHN_COMMON
701 || esym->st_shndx == bss_section->sh_num)
702 && (shndx < SHN_LORESERVE
703 && shndx != bss_section->sh_num)) {
704 /* data symbol gets precedence over common/bss */
705 goto do_patch;
706 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
707 /* data symbol keeps precedence over common/bss */
708 } else if (s->sh_flags & SHF_DYNSYM) {
709 /* we accept that two DLL define the same symbol */
710 } else if (esym->st_other & ST_ASM_SET) {
711 /* If the existing symbol came from an asm .set
712 we can override. */
713 goto do_patch;
714 } else {
715 #if 0
716 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
717 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
718 #endif
719 tcc_error_noabort("'%s' defined twice", name);
721 } else {
722 esym->st_other = other;
723 do_patch:
724 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
725 esym->st_shndx = shndx;
726 s1->new_undef_sym = 1;
727 esym->st_value = value;
728 esym->st_size = size;
730 } else {
731 do_def:
732 sym_index = put_elf_sym(s, value, size,
733 ELFW(ST_INFO)(sym_bind, sym_type), other,
734 shndx, name);
736 return sym_index;
739 /* put relocation */
740 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
741 int type, int symbol, addr_t addend)
743 TCCState *s1 = s->s1;
744 char buf[256];
745 Section *sr;
746 ElfW_Rel *rel;
748 sr = s->reloc;
749 if (!sr) {
750 /* if no relocation section, create it */
751 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
752 /* if the symtab is allocated, then we consider the relocation
753 are also */
754 sr = new_section(s->s1, buf, SHT_RELX, symtab->sh_flags);
755 sr->sh_entsize = sizeof(ElfW_Rel);
756 sr->link = symtab;
757 sr->sh_info = s->sh_num;
758 s->reloc = sr;
760 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
761 rel->r_offset = offset;
762 rel->r_info = ELFW(R_INFO)(symbol, type);
763 #if SHT_RELX == SHT_RELA
764 rel->r_addend = addend;
765 #endif
766 if (SHT_RELX != SHT_RELA && addend)
767 tcc_error_noabort("non-zero addend on REL architecture");
770 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
771 int type, int symbol)
773 put_elf_reloca(symtab, s, offset, type, symbol, 0);
776 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
778 int n;
779 struct sym_attr *tab;
781 if (index >= s1->nb_sym_attrs) {
782 if (!alloc)
783 return s1->sym_attrs;
784 /* find immediately bigger power of 2 and reallocate array */
785 n = 1;
786 while (index >= n)
787 n *= 2;
788 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
789 s1->sym_attrs = tab;
790 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
791 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
792 s1->nb_sym_attrs = n;
794 return &s1->sym_attrs[index];
797 static void modify_reloctions_old_to_new(TCCState *s1, Section *s, int *old_to_new_syms)
799 int i, type, sym_index;
800 Section *sr;
801 ElfW_Rel *rel;
803 for(i = 1; i < s1->nb_sections; i++) {
804 sr = s1->sections[i];
805 if (sr->sh_type == SHT_RELX && sr->link == s) {
806 for_each_elem(sr, 0, rel, ElfW_Rel) {
807 sym_index = ELFW(R_SYM)(rel->r_info);
808 type = ELFW(R_TYPE)(rel->r_info);
809 sym_index = old_to_new_syms[sym_index];
810 rel->r_info = ELFW(R_INFO)(sym_index, type);
816 /* In an ELF file symbol table, the local symbols must appear below
817 the global and weak ones. Since TCC cannot sort it while generating
818 the code, we must do it after. All the relocation tables are also
819 modified to take into account the symbol table sorting */
820 static void sort_syms(TCCState *s1, Section *s)
822 int *old_to_new_syms;
823 ElfW(Sym) *new_syms;
824 int nb_syms, i;
825 ElfW(Sym) *p, *q;
827 nb_syms = s->data_offset / sizeof(ElfW(Sym));
828 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
829 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
831 /* first pass for local symbols */
832 p = (ElfW(Sym) *)s->data;
833 q = new_syms;
834 for(i = 0; i < nb_syms; i++) {
835 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
836 old_to_new_syms[i] = q - new_syms;
837 *q++ = *p;
839 p++;
841 /* save the number of local symbols in section header */
842 if( s->sh_size ) /* this 'if' makes IDA happy */
843 s->sh_info = q - new_syms;
845 /* then second pass for non local symbols */
846 p = (ElfW(Sym) *)s->data;
847 for(i = 0; i < nb_syms; i++) {
848 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
849 old_to_new_syms[i] = q - new_syms;
850 *q++ = *p;
852 p++;
855 /* we copy the new symbols to the old */
856 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
857 tcc_free(new_syms);
859 modify_reloctions_old_to_new(s1, s, old_to_new_syms);
861 tcc_free(old_to_new_syms);
864 #ifndef ELF_OBJ_ONLY
865 /* See: https://flapenguin.me/elf-dt-gnu-hash */
866 #define ELFCLASS_BITS (PTR_SIZE * 8)
868 static Section *create_gnu_hash(TCCState *s1)
870 int nb_syms, i, ndef, nbuckets, symoffset, bloom_size, bloom_shift;
871 ElfW(Sym) *p;
872 Section *gnu_hash;
873 Section *dynsym = s1->dynsym;
874 Elf32_Word *ptr;
876 gnu_hash = new_section(s1, ".gnu.hash", SHT_GNU_HASH, SHF_ALLOC);
877 gnu_hash->link = dynsym->hash->link;
879 nb_syms = dynsym->data_offset / sizeof(ElfW(Sym));
881 /* count def symbols */
882 ndef = 0;
883 p = (ElfW(Sym) *)dynsym->data;
884 for(i = 0; i < nb_syms; i++, p++)
885 ndef += p->st_shndx != SHN_UNDEF;
887 /* calculate gnu hash sizes and fill header */
888 nbuckets = ndef / 4 + 1;
889 symoffset = nb_syms - ndef;
890 bloom_shift = PTR_SIZE == 8 ? 6 : 5;
891 bloom_size = 1; /* must be power of two */
892 while (ndef >= bloom_size * (1 << (bloom_shift - 3)))
893 bloom_size *= 2;
894 ptr = section_ptr_add(gnu_hash, 4 * 4 +
895 PTR_SIZE * bloom_size +
896 nbuckets * 4 +
897 ndef * 4);
898 ptr[0] = nbuckets;
899 ptr[1] = symoffset;
900 ptr[2] = bloom_size;
901 ptr[3] = bloom_shift;
902 return gnu_hash;
905 static Elf32_Word elf_gnu_hash (const unsigned char *name)
907 Elf32_Word h = 5381;
908 unsigned char c;
910 while ((c = *name++))
911 h = h * 33 + c;
912 return h;
915 static void update_gnu_hash(TCCState *s1, Section *gnu_hash)
917 int *old_to_new_syms;
918 ElfW(Sym) *new_syms;
919 int nb_syms, i, nbuckets, bloom_size, bloom_shift;
920 ElfW(Sym) *p, *q;
921 Section *vs;
922 Section *dynsym = s1->dynsym;
923 Elf32_Word *ptr, *buckets, *chain, *hash;
924 unsigned int *nextbuck;
925 addr_t *bloom;
926 unsigned char *strtab;
927 struct { int first, last; } *buck;
929 strtab = dynsym->link->data;
930 nb_syms = dynsym->data_offset / sizeof(ElfW(Sym));
931 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
932 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
933 hash = tcc_malloc(nb_syms * sizeof(Elf32_Word));
934 nextbuck = tcc_malloc(nb_syms * sizeof(int));
936 /* calculate hashes and copy undefs */
937 p = (ElfW(Sym) *)dynsym->data;
938 q = new_syms;
939 for(i = 0; i < nb_syms; i++, p++) {
940 if (p->st_shndx == SHN_UNDEF) {
941 old_to_new_syms[i] = q - new_syms;
942 *q++ = *p;
944 else
945 hash[i] = elf_gnu_hash(strtab + p->st_name);
948 ptr = (Elf32_Word *) gnu_hash->data;
949 nbuckets = ptr[0];
950 bloom_size = ptr[2];
951 bloom_shift = ptr[3];
952 bloom = (addr_t *) (void *) &ptr[4];
953 buckets = (Elf32_Word*) (void *) &bloom[bloom_size];
954 chain = &buckets[nbuckets];
955 buck = tcc_malloc(nbuckets * sizeof(*buck));
957 if (gnu_hash->data_offset != 4 * 4 +
958 PTR_SIZE * bloom_size +
959 nbuckets * 4 +
960 (nb_syms - (q - new_syms)) * 4)
961 tcc_error_noabort ("gnu_hash size incorrect");
963 /* find buckets */
964 for(i = 0; i < nbuckets; i++)
965 buck[i].first = -1;
967 p = (ElfW(Sym) *)dynsym->data;
968 for(i = 0; i < nb_syms; i++, p++)
969 if (p->st_shndx != SHN_UNDEF) {
970 int bucket = hash[i] % nbuckets;
972 if (buck[bucket].first == -1)
973 buck[bucket].first = buck[bucket].last = i;
974 else {
975 nextbuck[buck[bucket].last] = i;
976 buck[bucket].last = i;
980 /* fill buckets/chains/bloom and sort symbols */
981 p = (ElfW(Sym) *)dynsym->data;
982 for(i = 0; i < nbuckets; i++) {
983 int cur = buck[i].first;
985 if (cur != -1) {
986 buckets[i] = q - new_syms;
987 for (;;) {
988 old_to_new_syms[cur] = q - new_syms;
989 *q++ = p[cur];
990 *chain++ = hash[cur] & ~1;
991 bloom[(hash[cur] / ELFCLASS_BITS) % bloom_size] |=
992 (addr_t)1 << (hash[cur] % ELFCLASS_BITS) |
993 (addr_t)1 << ((hash[cur] >> bloom_shift) % ELFCLASS_BITS);
994 if (cur == buck[i].last)
995 break;
996 cur = nextbuck[cur];
998 chain[-1] |= 1;
1002 memcpy(dynsym->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
1003 tcc_free(new_syms);
1004 tcc_free(hash);
1005 tcc_free(buck);
1006 tcc_free(nextbuck);
1008 modify_reloctions_old_to_new(s1, dynsym, old_to_new_syms);
1010 /* modify the versions */
1011 vs = versym_section;
1012 if (vs) {
1013 ElfW(Half) *newver, *versym = (ElfW(Half) *)vs->data;
1015 if (1/*versym*/) {
1016 newver = tcc_malloc(nb_syms * sizeof(*newver));
1017 for (i = 0; i < nb_syms; i++)
1018 newver[old_to_new_syms[i]] = versym[i];
1019 memcpy(vs->data, newver, nb_syms * sizeof(*newver));
1020 tcc_free(newver);
1024 tcc_free(old_to_new_syms);
1026 /* rebuild hash */
1027 ptr = (Elf32_Word *) dynsym->hash->data;
1028 rebuild_hash(dynsym, ptr[0]);
1030 #endif /* ELF_OBJ_ONLY */
1032 /* relocate symbol table, resolve undefined symbols if do_resolve is
1033 true and output error if undefined symbol. */
1034 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
1036 ElfW(Sym) *sym;
1037 int sym_bind, sh_num;
1038 const char *name;
1040 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
1041 sh_num = sym->st_shndx;
1042 if (sh_num == SHN_UNDEF) {
1043 if (do_resolve == 2) /* relocating dynsym */
1044 continue;
1045 name = (char *) s1->symtab->link->data + sym->st_name;
1046 /* Use ld.so to resolve symbol for us (for tcc -run) */
1047 if (do_resolve) {
1048 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
1049 /* dlsym() needs the undecorated name. */
1050 void *addr = dlsym(RTLD_DEFAULT, &name[s1->leading_underscore]);
1051 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD || TARGETOS_ANDROID
1052 if (addr == NULL) {
1053 int i;
1054 for (i = 0; i < s1->nb_loaded_dlls; i++)
1055 if ((addr = dlsym(s1->loaded_dlls[i]->handle, name)))
1056 break;
1058 #endif
1059 if (addr) {
1060 sym->st_value = (addr_t) addr;
1061 #ifdef DEBUG_RELOC
1062 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
1063 #endif
1064 goto found;
1066 #endif
1067 /* if dynamic symbol exist, it will be used in relocate_section */
1068 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
1069 goto found;
1070 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1071 it */
1072 if (!strcmp(name, "_fp_hw"))
1073 goto found;
1074 /* only weak symbols are accepted to be undefined. Their
1075 value is zero */
1076 sym_bind = ELFW(ST_BIND)(sym->st_info);
1077 if (sym_bind == STB_WEAK)
1078 sym->st_value = 0;
1079 else
1080 tcc_error_noabort("undefined symbol '%s'", name);
1082 } else if (sh_num < SHN_LORESERVE) {
1083 /* add section base */
1084 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1086 found: ;
1090 /* relocate a given section (CPU dependent) by applying the relocations
1091 in the associated relocation section */
1092 static void relocate_section(TCCState *s1, Section *s, Section *sr)
1094 ElfW_Rel *rel;
1095 ElfW(Sym) *sym;
1096 int type, sym_index;
1097 unsigned char *ptr;
1098 addr_t tgt, addr;
1099 int is_dwarf = s->sh_num >= s1->dwlo && s->sh_num < s1->dwhi;
1101 qrel = (ElfW_Rel *)sr->data;
1102 for_each_elem(sr, 0, rel, ElfW_Rel) {
1103 ptr = s->data + rel->r_offset;
1104 sym_index = ELFW(R_SYM)(rel->r_info);
1105 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1106 type = ELFW(R_TYPE)(rel->r_info);
1107 tgt = sym->st_value;
1108 #if SHT_RELX == SHT_RELA
1109 tgt += rel->r_addend;
1110 #endif
1111 if (is_dwarf && type == R_DATA_32DW
1112 && sym->st_shndx >= s1->dwlo && sym->st_shndx < s1->dwhi) {
1113 /* dwarf section relocation to each other */
1114 add32le(ptr, tgt - s1->sections[sym->st_shndx]->sh_addr);
1115 continue;
1117 addr = s->sh_addr + rel->r_offset;
1118 relocate(s1, rel, type, ptr, addr, tgt);
1120 #ifndef ELF_OBJ_ONLY
1121 /* if the relocation is allocated, we change its symbol table */
1122 if (sr->sh_flags & SHF_ALLOC) {
1123 sr->link = s1->dynsym;
1124 if (s1->output_type & TCC_OUTPUT_DYN) {
1125 size_t r = (uint8_t*)qrel - sr->data;
1126 if (sizeof ((Stab_Sym*)0)->n_value < PTR_SIZE
1127 && 0 == strcmp(s->name, ".stab"))
1128 r = 0; /* cannot apply 64bit relocation to 32bit value */
1129 sr->data_offset = sr->sh_size = r;
1130 #ifdef CONFIG_TCC_PIE
1131 if (r && 0 == (s->sh_flags & SHF_WRITE))
1132 tcc_warning("%d relocations to ro-section %s", (unsigned)(r / sizeof *qrel), s->name);
1133 #endif
1136 #endif
1139 /* relocate all sections */
1140 ST_FUNC void relocate_sections(TCCState *s1)
1142 int i;
1143 Section *s, *sr;
1145 for (i = 1; i < s1->nb_sections; ++i) {
1146 sr = s1->sections[i];
1147 if (sr->sh_type != SHT_RELX)
1148 continue;
1149 s = s1->sections[sr->sh_info];
1150 #ifndef TCC_TARGET_MACHO
1151 if (s != s1->got
1152 || s1->static_link
1153 || s1->output_type == TCC_OUTPUT_MEMORY)
1154 #endif
1156 relocate_section(s1, s, sr);
1158 #ifndef ELF_OBJ_ONLY
1159 if (sr->sh_flags & SHF_ALLOC) {
1160 ElfW_Rel *rel;
1161 /* relocate relocation table in 'sr' */
1162 for_each_elem(sr, 0, rel, ElfW_Rel)
1163 rel->r_offset += s->sh_addr;
1165 #endif
1169 #ifndef ELF_OBJ_ONLY
1170 /* count the number of dynamic relocations so that we can reserve
1171 their space */
1172 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
1174 int count = 0;
1175 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1176 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1177 defined(TCC_TARGET_RISCV64)
1178 ElfW_Rel *rel;
1179 for_each_elem(sr, 0, rel, ElfW_Rel) {
1180 int sym_index = ELFW(R_SYM)(rel->r_info);
1181 int type = ELFW(R_TYPE)(rel->r_info);
1182 switch(type) {
1183 #if defined(TCC_TARGET_I386)
1184 case R_386_32:
1185 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
1186 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
1187 /* don't fixup unresolved (weak) symbols */
1188 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
1189 break;
1191 #elif defined(TCC_TARGET_X86_64)
1192 case R_X86_64_32:
1193 case R_X86_64_32S:
1194 case R_X86_64_64:
1195 #elif defined(TCC_TARGET_ARM)
1196 case R_ARM_ABS32:
1197 case R_ARM_TARGET1:
1198 #elif defined(TCC_TARGET_ARM64)
1199 case R_AARCH64_ABS32:
1200 case R_AARCH64_ABS64:
1201 #elif defined(TCC_TARGET_RISCV64)
1202 case R_RISCV_32:
1203 case R_RISCV_64:
1204 #endif
1205 count++;
1206 break;
1207 #if defined(TCC_TARGET_I386)
1208 case R_386_PC32:
1209 #elif defined(TCC_TARGET_X86_64)
1210 case R_X86_64_PC32:
1212 ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1213 /* Hidden defined symbols can and must be resolved locally.
1214 We're misusing a PLT32 reloc for this, as that's always
1215 resolved to its address even in shared libs. */
1216 if (sym->st_shndx != SHN_UNDEF &&
1217 ELFW(ST_VISIBILITY)(sym->st_other) == STV_HIDDEN) {
1218 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PLT32);
1219 break;
1222 #elif defined(TCC_TARGET_ARM64)
1223 case R_AARCH64_PREL32:
1224 #endif
1225 if (s1->output_type != TCC_OUTPUT_DLL)
1226 break;
1227 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
1228 count++;
1229 break;
1230 default:
1231 break;
1234 #endif
1235 return count;
1237 #endif
1239 #ifdef NEED_BUILD_GOT
1240 static int build_got(TCCState *s1)
1242 /* if no got, then create it */
1243 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1244 s1->got->sh_entsize = 4;
1245 /* keep space for _DYNAMIC pointer and two dummy got entries */
1246 section_ptr_add(s1->got, 3 * PTR_SIZE);
1247 return set_elf_sym(symtab_section, 0, 0, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1248 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1251 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1252 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1253 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1254 Returns the offset of the GOT or (if any) PLT entry. */
1255 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
1256 int sym_index)
1258 int need_plt_entry;
1259 const char *name;
1260 ElfW(Sym) *sym;
1261 struct sym_attr *attr;
1262 unsigned got_offset;
1263 char plt_name[200];
1264 int len;
1265 Section *s_rel;
1267 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
1268 attr = get_sym_attr(s1, sym_index, 1);
1270 /* In case a function is both called and its address taken 2 GOT entries
1271 are created, one for taking the address (GOT) and the other for the PLT
1272 entry (PLTGOT). */
1273 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
1274 return attr;
1276 s_rel = s1->got;
1277 if (need_plt_entry) {
1278 if (!s1->plt) {
1279 s1->plt = new_section(s1, ".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
1280 s1->plt->sh_entsize = 4;
1282 s_rel = s1->plt;
1285 /* create the GOT entry */
1286 got_offset = s1->got->data_offset;
1287 section_ptr_add(s1->got, PTR_SIZE);
1289 /* Create the GOT relocation that will insert the address of the object or
1290 function of interest in the GOT entry. This is a static relocation for
1291 memory output (dlsym will give us the address of symbols) and dynamic
1292 relocation otherwise (executable and DLLs). The relocation should be
1293 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1294 associated to a PLT entry) but is currently done at load time for an
1295 unknown reason. */
1297 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1298 name = (char *) symtab_section->link->data + sym->st_name;
1299 //printf("sym %d %s\n", need_plt_entry, name);
1301 if (s1->dynsym) {
1302 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
1303 /* Hack alarm. We don't want to emit dynamic symbols
1304 and symbol based relocs for STB_LOCAL symbols, but rather
1305 want to resolve them directly. At this point the symbol
1306 values aren't final yet, so we must defer this. We will later
1307 have to create a RELATIVE reloc anyway, so we misuse the
1308 relocation slot to smuggle the symbol reference until
1309 fill_local_got_entries. Not that the sym_index is
1310 relative to symtab_section, not s1->dynsym! Nevertheless
1311 we use s1->dyn_sym so that if this is the first call
1312 that got->reloc is correctly created. Also note that
1313 RELATIVE relocs are not normally created for the .got,
1314 so the types serves as a marker for later (and is retained
1315 also for the final output, which is okay because then the
1316 got is just normal data). */
1317 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
1318 sym_index);
1319 } else {
1320 if (0 == attr->dyn_index)
1321 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
1322 sym->st_size, sym->st_info, 0,
1323 sym->st_shndx, name);
1324 put_elf_reloc(s1->dynsym, s_rel, got_offset, dyn_reloc_type,
1325 attr->dyn_index);
1327 } else {
1328 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1329 sym_index);
1332 if (need_plt_entry) {
1333 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1335 /* create a symbol 'sym@plt' for the PLT jump vector */
1336 len = strlen(name);
1337 if (len > sizeof plt_name - 5)
1338 len = sizeof plt_name - 5;
1339 memcpy(plt_name, name, len);
1340 strcpy(plt_name + len, "@plt");
1341 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, 0,
1342 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1343 } else {
1344 attr->got_offset = got_offset;
1347 return attr;
1350 /* build GOT and PLT entries */
1351 /* Two passes because R_JMP_SLOT should become first. Some targets
1352 (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1353 ST_FUNC void build_got_entries(TCCState *s1, int got_sym)
1355 Section *s;
1356 ElfW_Rel *rel;
1357 ElfW(Sym) *sym;
1358 int i, type, gotplt_entry, reloc_type, sym_index;
1359 struct sym_attr *attr;
1360 int pass = 0;
1361 redo:
1362 for(i = 1; i < s1->nb_sections; i++) {
1363 s = s1->sections[i];
1364 if (s->sh_type != SHT_RELX)
1365 continue;
1366 /* no need to handle got relocations */
1367 if (s->link != symtab_section)
1368 continue;
1369 for_each_elem(s, 0, rel, ElfW_Rel) {
1370 type = ELFW(R_TYPE)(rel->r_info);
1371 gotplt_entry = gotplt_entry_type(type);
1372 if (gotplt_entry == -1) {
1373 tcc_error_noabort ("Unknown relocation type for got: %d", type);
1374 continue;
1376 sym_index = ELFW(R_SYM)(rel->r_info);
1377 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1379 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1380 continue;
1383 /* Automatically create PLT/GOT [entry] if it is an undefined
1384 reference (resolved at runtime), or the symbol is absolute,
1385 probably created by tcc_add_symbol, and thus on 64-bit
1386 targets might be too far from application code. */
1387 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1388 if (sym->st_shndx == SHN_UNDEF) {
1389 ElfW(Sym) *esym;
1390 int dynindex;
1391 if (!PCRELATIVE_DLLPLT
1392 && (s1->output_type & TCC_OUTPUT_DYN))
1393 continue;
1394 /* Relocations for UNDEF symbols would normally need
1395 to be transferred into the executable or shared object.
1396 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1397 But TCC doesn't do that (at least for exes), so we
1398 need to resolve all such relocs locally. And that
1399 means PLT slots for functions in DLLs and COPY relocs for
1400 data symbols. COPY relocs were generated in
1401 bind_exe_dynsyms (and the symbol adjusted to be defined),
1402 and for functions we were generated a dynamic symbol
1403 of function type. */
1404 if (s1->dynsym) {
1405 /* dynsym isn't set for -run :-/ */
1406 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1407 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1408 if (dynindex
1409 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1410 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1411 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1412 goto jmp_slot;
1414 } else if (sym->st_shndx == SHN_ABS) {
1415 if (sym->st_value == 0) /* from tcc_add_btstub() */
1416 continue;
1417 #ifndef TCC_TARGET_ARM
1418 if (PTR_SIZE != 8)
1419 continue;
1420 #endif
1421 /* from tcc_add_symbol(): on 64 bit platforms these
1422 need to go through .got */
1423 } else
1424 continue;
1427 #ifdef TCC_TARGET_X86_64
1428 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1429 sym->st_shndx != SHN_UNDEF &&
1430 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1431 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1432 s1->output_type & TCC_OUTPUT_EXE)) {
1433 if (pass != 0)
1434 continue;
1435 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1436 continue;
1438 #endif
1439 reloc_type = code_reloc(type);
1440 if (reloc_type == -1) {
1441 tcc_error_noabort ("Unknown relocation type: %d", type);
1442 continue;
1445 if (reloc_type != 0) {
1446 jmp_slot:
1447 if (pass != 0)
1448 continue;
1449 reloc_type = R_JMP_SLOT;
1450 } else {
1451 if (pass != 1)
1452 continue;
1453 reloc_type = R_GLOB_DAT;
1456 if (!s1->got)
1457 got_sym = build_got(s1);
1459 if (gotplt_entry == BUILD_GOT_ONLY)
1460 continue;
1462 attr = put_got_entry(s1, reloc_type, sym_index);
1464 if (reloc_type == R_JMP_SLOT)
1465 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1468 if (++pass < 2)
1469 goto redo;
1470 /* .rel.plt refers to .got actually */
1471 if (s1->plt && s1->plt->reloc)
1472 s1->plt->reloc->sh_info = s1->got->sh_num;
1473 if (got_sym) /* set size */
1474 ((ElfW(Sym)*)symtab_section->data)[got_sym].st_size = s1->got->data_offset;
1476 #endif /* def NEED_BUILD_GOT */
1478 ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs)
1480 int shn = sec ? sec->sh_num : offs || !name ? SHN_ABS : SHN_UNDEF;
1481 if (sec && offs == -1)
1482 offs = sec->data_offset;
1483 return set_elf_sym(symtab_section, offs, 0,
1484 ELFW(ST_INFO)(name ? STB_GLOBAL : STB_LOCAL, STT_NOTYPE), 0, shn, name);
1487 static void add_init_array_defines(TCCState *s1, const char *section_name)
1489 Section *s;
1490 addr_t end_offset;
1491 char buf[1024];
1492 s = have_section(s1, section_name);
1493 if (!s || !(s->sh_flags & SHF_ALLOC)) {
1494 end_offset = 0;
1495 s = data_section;
1496 } else {
1497 end_offset = s->data_offset;
1499 snprintf(buf, sizeof(buf), "__%s_start", section_name + 1);
1500 set_global_sym(s1, buf, s, 0);
1501 snprintf(buf, sizeof(buf), "__%s_end", section_name + 1);
1502 set_global_sym(s1, buf, s, end_offset);
1505 ST_FUNC void add_array (TCCState *s1, const char *sec, int c)
1507 Section *s;
1508 s = find_section(s1, sec);
1509 s->sh_flags = shf_RELRO;
1510 s->sh_type = sec[1] == 'i' ? SHT_INIT_ARRAY : SHT_FINI_ARRAY;
1511 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1512 section_ptr_add(s, PTR_SIZE);
1515 #ifdef CONFIG_TCC_BCHECK
1516 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1518 if (0 == s1->do_bounds_check)
1519 return;
1520 section_ptr_add(bounds_section, sizeof(addr_t));
1522 #endif
1524 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1525 a dynamic symbol to allow so's to have one each with a different value. */
1526 static void set_local_sym(TCCState *s1, const char *name, Section *s, int offset)
1528 int c = find_elf_sym(s1->symtab, name);
1529 if (c) {
1530 ElfW(Sym) *esym = (ElfW(Sym)*)s1->symtab->data + c;
1531 esym->st_info = ELFW(ST_INFO)(STB_LOCAL, STT_NOTYPE);
1532 esym->st_value = offset;
1533 esym->st_shndx = s->sh_num;
1537 /* avoid generating debug/test_coverage code for stub functions */
1538 static void tcc_compile_string_no_debug(TCCState *s, const char *str)
1540 int save_do_debug = s->do_debug;
1541 int save_test_coverage = s->test_coverage;
1543 s->do_debug = 0;
1544 s->test_coverage = 0;
1545 tcc_compile_string(s, str);
1546 s->do_debug = save_do_debug;
1547 s->test_coverage = save_test_coverage;
1550 #ifdef CONFIG_TCC_BACKTRACE
1551 static void put_ptr(TCCState *s1, Section *s, int offs)
1553 int c;
1554 c = set_global_sym(s1, NULL, s, offs);
1555 s = data_section;
1556 put_elf_reloc (s1->symtab, s, s->data_offset, R_DATA_PTR, c);
1557 section_ptr_add(s, PTR_SIZE);
1560 ST_FUNC void tcc_add_btstub(TCCState *s1)
1562 Section *s;
1563 int n, o;
1564 CString cstr;
1566 s = data_section;
1567 /* Align to PTR_SIZE */
1568 section_ptr_add(s, -s->data_offset & (PTR_SIZE - 1));
1569 o = s->data_offset;
1570 /* create (part of) a struct rt_context (see tccrun.c) */
1571 if (s1->dwarf) {
1572 put_ptr(s1, dwarf_line_section, 0);
1573 put_ptr(s1, dwarf_line_section, -1);
1574 if (s1->dwarf >= 5)
1575 put_ptr(s1, dwarf_line_str_section, 0);
1576 else
1577 put_ptr(s1, dwarf_str_section, 0);
1579 else
1581 put_ptr(s1, stab_section, 0);
1582 put_ptr(s1, stab_section, -1);
1583 put_ptr(s1, stab_section->link, 0);
1585 *(addr_t *)section_ptr_add(s, PTR_SIZE) = s1->dwarf;
1586 /* skip esym_start/esym_end/elf_str (not loaded) */
1587 section_ptr_add(s, 3 * PTR_SIZE);
1588 /* prog_base : local nameless symbol with offset 0 at SHN_ABS */
1589 put_ptr(s1, NULL, 0);
1590 #if defined TCC_TARGET_MACHO
1591 /* adjust for __PAGEZERO */
1592 if (s1->dwarf == 0 && s1->output_type == TCC_OUTPUT_EXE)
1593 write64le(data_section->data + data_section->data_offset - PTR_SIZE,
1594 (uint64_t)1 << 32);
1595 #endif
1596 n = 2 * PTR_SIZE;
1597 #ifdef CONFIG_TCC_BCHECK
1598 if (s1->do_bounds_check) {
1599 put_ptr(s1, bounds_section, 0);
1600 n -= PTR_SIZE;
1602 #endif
1603 section_ptr_add(s, n);
1604 cstr_new(&cstr);
1605 cstr_printf(&cstr,
1606 "extern void __bt_init(),__bt_exit(),__bt_init_dll();"
1607 "static void *__rt_info[];"
1608 "__attribute__((constructor)) static void __bt_init_rt(){");
1609 #ifdef TCC_TARGET_PE
1610 if (s1->output_type == TCC_OUTPUT_DLL)
1611 #ifdef CONFIG_TCC_BCHECK
1612 cstr_printf(&cstr, "__bt_init_dll(%d);", s1->do_bounds_check);
1613 #else
1614 cstr_printf(&cstr, "__bt_init_dll(0);");
1615 #endif
1616 #endif
1617 cstr_printf(&cstr, "__bt_init(__rt_info,%d);}",
1618 s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1);
1619 /* In case dlcose is called by application */
1620 cstr_printf(&cstr,
1621 "__attribute__((destructor)) static void __bt_exit_rt(){"
1622 "__bt_exit(__rt_info);}");
1623 tcc_compile_string_no_debug(s1, cstr.data);
1624 cstr_free(&cstr);
1625 set_local_sym(s1, &"___rt_info"[!s1->leading_underscore], s, o);
1627 #endif /* def CONFIG_TCC_BACKTRACE */
1629 static void tcc_tcov_add_file(TCCState *s1, const char *filename)
1631 CString cstr;
1632 void *ptr;
1633 char wd[1024];
1635 if (tcov_section == NULL)
1636 return;
1637 section_ptr_add(tcov_section, 1);
1638 write32le (tcov_section->data, tcov_section->data_offset);
1640 cstr_new (&cstr);
1641 if (filename[0] == '/')
1642 cstr_printf (&cstr, "%s.tcov", filename);
1643 else {
1644 getcwd (wd, sizeof(wd));
1645 cstr_printf (&cstr, "%s/%s.tcov", wd, filename);
1647 ptr = section_ptr_add(tcov_section, cstr.size + 1);
1648 strcpy((char *)ptr, cstr.data);
1649 unlink((char *)ptr);
1650 #ifdef _WIN32
1651 normalize_slashes((char *)ptr);
1652 #endif
1653 cstr_free (&cstr);
1655 cstr_new(&cstr);
1656 cstr_printf(&cstr,
1657 "extern char *__tcov_data[];"
1658 "extern void __store_test_coverage ();"
1659 "__attribute__((destructor)) static void __tcov_exit() {"
1660 "__store_test_coverage(__tcov_data);"
1661 "}");
1662 tcc_compile_string_no_debug(s1, cstr.data);
1663 cstr_free(&cstr);
1664 set_local_sym(s1, &"___tcov_data"[!s1->leading_underscore], tcov_section, 0);
1667 #ifndef TCC_TARGET_PE
1668 /* add tcc runtime libraries */
1669 ST_FUNC void tcc_add_runtime(TCCState *s1)
1671 s1->filetype = 0;
1673 #ifdef CONFIG_TCC_BCHECK
1674 tcc_add_bcheck(s1);
1675 #endif
1676 tcc_add_pragma_libs(s1);
1678 /* add libc */
1679 if (!s1->nostdlib) {
1680 int lpthread = s1->option_pthread;
1682 #ifdef CONFIG_TCC_BCHECK
1683 if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) {
1684 tcc_add_support(s1, "bcheck.o");
1685 # if !(TARGETOS_OpenBSD || TARGETOS_NetBSD)
1686 tcc_add_library_err(s1, "dl");
1687 # endif
1688 lpthread = 1;
1690 #endif
1691 #ifdef CONFIG_TCC_BACKTRACE
1692 if (s1->do_backtrace) {
1693 if (s1->output_type & TCC_OUTPUT_EXE)
1694 tcc_add_support(s1, "bt-exe.o");
1695 if (s1->output_type != TCC_OUTPUT_DLL)
1696 tcc_add_support(s1, "bt-log.o");
1697 if (s1->output_type != TCC_OUTPUT_MEMORY)
1698 tcc_add_btstub(s1);
1700 #endif
1701 if (lpthread)
1702 tcc_add_library_err(s1, "pthread");
1703 tcc_add_library_err(s1, "c");
1704 #ifdef TCC_LIBGCC
1705 if (!s1->static_link) {
1706 if (TCC_LIBGCC[0] == '/')
1707 tcc_add_file(s1, TCC_LIBGCC);
1708 else
1709 tcc_add_dll(s1, TCC_LIBGCC, 0);
1711 #endif
1712 #if defined TCC_TARGET_ARM && TARGETOS_FreeBSD
1713 tcc_add_library_err(s1, "gcc_s"); // unwind code
1714 #endif
1715 if (TCC_LIBTCC1[0])
1716 tcc_add_support(s1, TCC_LIBTCC1);
1718 /* add crt end if not memory output */
1719 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1720 #if defined TCC_TARGET_MACHO
1721 /* nothing to do */
1722 #elif TARGETOS_FreeBSD || TARGETOS_NetBSD
1723 if (s1->output_type & TCC_OUTPUT_DYN)
1724 tcc_add_crt(s1, "crtendS.o");
1725 else
1726 tcc_add_crt(s1, "crtend.o");
1727 tcc_add_crt(s1, "crtn.o");
1728 #elif TARGETOS_OpenBSD
1729 if (s1->output_type == TCC_OUTPUT_DLL)
1730 tcc_add_crt(s1, "crtendS.o");
1731 else
1732 tcc_add_crt(s1, "crtend.o");
1733 #elif TARGETOS_ANDROID
1734 if (s1->output_type == TCC_OUTPUT_DLL)
1735 tcc_add_crt(s1, "crtend_so.o");
1736 else
1737 tcc_add_crt(s1, "crtend_android.o");
1738 #else
1739 tcc_add_crt(s1, "crtn.o");
1740 #endif
1744 #endif /* ndef TCC_TARGET_PE */
1746 /* add various standard linker symbols (must be done after the
1747 sections are filled (for example after allocating common
1748 symbols)) */
1749 static void tcc_add_linker_symbols(TCCState *s1)
1751 char buf[1024];
1752 int i;
1753 Section *s;
1755 set_global_sym(s1, "_etext", text_section, -1);
1756 set_global_sym(s1, "_edata", data_section, -1);
1757 set_global_sym(s1, "_end", bss_section, -1);
1758 #if TARGETOS_OpenBSD
1759 set_global_sym(s1, "__executable_start", NULL, ELF_START_ADDR);
1760 #endif
1761 #ifdef TCC_TARGET_RISCV64
1762 /* XXX should be .sdata+0x800, not .data+0x800 */
1763 set_global_sym(s1, "__global_pointer$", data_section, 0x800);
1764 #endif
1765 /* horrible new standard ldscript defines */
1766 add_init_array_defines(s1, ".preinit_array");
1767 add_init_array_defines(s1, ".init_array");
1768 add_init_array_defines(s1, ".fini_array");
1769 /* add start and stop symbols for sections whose name can be
1770 expressed in C */
1771 for(i = 1; i < s1->nb_sections; i++) {
1772 s = s1->sections[i];
1773 if ((s->sh_flags & SHF_ALLOC)
1774 && (s->sh_type == SHT_PROGBITS
1775 || s->sh_type == SHT_STRTAB)) {
1776 const char *p;
1777 /* check if section name can be expressed in C */
1778 p = s->name;
1779 for(;;) {
1780 int c = *p;
1781 if (!c)
1782 break;
1783 if (!isid(c) && !isnum(c))
1784 goto next_sec;
1785 p++;
1787 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1788 set_global_sym(s1, buf, s, 0);
1789 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1790 set_global_sym(s1, buf, s, -1);
1792 next_sec: ;
1796 ST_FUNC void resolve_common_syms(TCCState *s1)
1798 ElfW(Sym) *sym;
1800 /* Allocate common symbols in BSS. */
1801 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1802 if (sym->st_shndx == SHN_COMMON) {
1803 /* symbol alignment is in st_value for SHN_COMMONs */
1804 sym->st_value = section_add(bss_section, sym->st_size,
1805 sym->st_value);
1806 sym->st_shndx = bss_section->sh_num;
1810 /* Now assign linker provided symbols their value. */
1811 tcc_add_linker_symbols(s1);
1814 #ifndef ELF_OBJ_ONLY
1815 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1817 int sym_index = ELFW(R_SYM) (rel->r_info);
1818 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1819 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1820 unsigned offset = attr->got_offset;
1822 if (0 == offset)
1823 return;
1824 section_reserve(s1->got, offset + PTR_SIZE);
1825 #if PTR_SIZE == 8
1826 write64le(s1->got->data + offset, sym->st_value);
1827 #else
1828 write32le(s1->got->data + offset, sym->st_value);
1829 #endif
1832 /* Perform relocation to GOT or PLT entries */
1833 ST_FUNC void fill_got(TCCState *s1)
1835 Section *s;
1836 ElfW_Rel *rel;
1837 int i;
1839 for(i = 1; i < s1->nb_sections; i++) {
1840 s = s1->sections[i];
1841 if (s->sh_type != SHT_RELX)
1842 continue;
1843 /* no need to handle got relocations */
1844 if (s->link != symtab_section)
1845 continue;
1846 for_each_elem(s, 0, rel, ElfW_Rel) {
1847 switch (ELFW(R_TYPE) (rel->r_info)) {
1848 case R_X86_64_GOT32:
1849 case R_X86_64_GOTPCREL:
1850 case R_X86_64_GOTPCRELX:
1851 case R_X86_64_REX_GOTPCRELX:
1852 case R_X86_64_PLT32:
1853 fill_got_entry(s1, rel);
1854 break;
1860 /* See put_got_entry for a description. This is the second stage
1861 where GOT references to local defined symbols are rewritten. */
1862 static void fill_local_got_entries(TCCState *s1)
1864 ElfW_Rel *rel;
1865 if (!s1->got->reloc)
1866 return;
1867 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1868 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1869 int sym_index = ELFW(R_SYM) (rel->r_info);
1870 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1871 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1872 unsigned offset = attr->got_offset;
1873 if (offset != rel->r_offset - s1->got->sh_addr)
1874 tcc_error_noabort("fill_local_got_entries: huh?");
1875 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1876 #if SHT_RELX == SHT_RELA
1877 rel->r_addend = sym->st_value;
1878 #else
1879 /* All our REL architectures also happen to be 32bit LE. */
1880 write32le(s1->got->data + offset, sym->st_value);
1881 #endif
1886 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1887 in shared libraries */
1888 static void bind_exe_dynsyms(TCCState *s1, int is_PIE)
1890 const char *name;
1891 int sym_index, index;
1892 ElfW(Sym) *sym, *esym;
1893 int type;
1895 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1896 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1897 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1898 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1899 if (sym->st_shndx == SHN_UNDEF) {
1900 name = (char *) symtab_section->link->data + sym->st_name;
1901 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1902 if (sym_index) {
1903 if (is_PIE)
1904 continue;
1905 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1906 type = ELFW(ST_TYPE)(esym->st_info);
1907 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1908 /* Indirect functions shall have STT_FUNC type in executable
1909 * dynsym section. Indeed, a dlsym call following a lazy
1910 * resolution would pick the symbol value from the
1911 * executable dynsym entry which would contain the address
1912 * of the function wanted by the caller of dlsym instead of
1913 * the address of the function that would return that
1914 * address */
1915 int dynindex
1916 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1917 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1918 name);
1919 int index = sym - (ElfW(Sym) *) symtab_section->data;
1920 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1921 } else if (type == STT_OBJECT) {
1922 unsigned long offset;
1923 ElfW(Sym) *dynsym;
1924 offset = bss_section->data_offset;
1925 /* XXX: which alignment ? */
1926 offset = (offset + 16 - 1) & -16;
1927 set_elf_sym (s1->symtab, offset, esym->st_size,
1928 esym->st_info, 0, bss_section->sh_num, name);
1929 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1930 esym->st_info, 0, bss_section->sh_num,
1931 name);
1933 /* Ensure R_COPY works for weak symbol aliases */
1934 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1935 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1936 if ((dynsym->st_value == esym->st_value)
1937 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1938 char *dynname = (char *) s1->dynsymtab_section->link->data
1939 + dynsym->st_name;
1940 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1941 dynsym->st_info, 0,
1942 bss_section->sh_num, dynname);
1943 break;
1948 put_elf_reloc(s1->dynsym, bss_section,
1949 offset, R_COPY, index);
1950 offset += esym->st_size;
1951 bss_section->data_offset = offset;
1953 } else {
1954 /* STB_WEAK undefined symbols are accepted */
1955 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1956 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1957 !strcmp(name, "_fp_hw")) {
1958 } else {
1959 tcc_error_noabort("undefined symbol '%s'", name);
1966 /* Bind symbols of libraries: export all non local symbols of executable that
1967 are referenced by shared libraries. The reason is that the dynamic loader
1968 search symbol first in executable and then in libraries. Therefore a
1969 reference to a symbol already defined by a library can still be resolved by
1970 a symbol in the executable. With -rdynamic, export all defined symbols */
1971 static void bind_libs_dynsyms(TCCState *s1)
1973 const char *name;
1974 int dynsym_index;
1975 ElfW(Sym) *sym, *esym;
1977 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1978 name = (char *)symtab_section->link->data + sym->st_name;
1979 dynsym_index = find_elf_sym(s1->dynsymtab_section, name);
1980 if (sym->st_shndx != SHN_UNDEF) {
1981 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL
1982 && (dynsym_index || s1->rdynamic))
1983 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1984 sym->st_info, 0, sym->st_shndx, name);
1985 } else if (dynsym_index) {
1986 esym = (ElfW(Sym) *)s1->dynsymtab_section->data + dynsym_index;
1987 if (esym->st_shndx == SHN_UNDEF) {
1988 /* weak symbols can stay undefined */
1989 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1990 tcc_warning("undefined dynamic symbol '%s'", name);
1996 /* Export all non local symbols. This is used by shared libraries so that the
1997 non local symbols they define can resolve a reference in another shared
1998 library or in the executable. Correspondingly, it allows undefined local
1999 symbols to be resolved by other shared libraries or by the executable. */
2000 static void export_global_syms(TCCState *s1)
2002 int dynindex, index;
2003 const char *name;
2004 ElfW(Sym) *sym;
2005 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
2006 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2007 name = (char *) symtab_section->link->data + sym->st_name;
2008 dynindex = set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
2009 sym->st_info, 0, sym->st_shndx, name);
2010 index = sym - (ElfW(Sym) *) symtab_section->data;
2011 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
2016 /* decide if an unallocated section should be output. */
2017 static int set_sec_sizes(TCCState *s1)
2019 int i;
2020 Section *s;
2021 int textrel = 0;
2022 int file_type = s1->output_type;
2024 /* Allocate strings for section names */
2025 for(i = 1; i < s1->nb_sections; i++) {
2026 s = s1->sections[i];
2027 if (s->sh_type == SHT_RELX && !(s->sh_flags & SHF_ALLOC)) {
2028 /* when generating a DLL, we include relocations but
2029 we may patch them */
2030 if ((file_type & TCC_OUTPUT_DYN)
2031 && (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)) {
2032 int count = prepare_dynamic_rel(s1, s);
2033 if (count) {
2034 /* allocate the section */
2035 s->sh_flags |= SHF_ALLOC;
2036 s->sh_size = count * sizeof(ElfW_Rel);
2037 if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE))
2038 textrel += count;
2041 } else if ((s->sh_flags & SHF_ALLOC)
2042 #ifdef TCC_TARGET_ARM
2043 || s->sh_type == SHT_ARM_ATTRIBUTES
2044 #endif
2045 || s1->do_debug) {
2046 s->sh_size = s->data_offset;
2049 #ifdef TCC_TARGET_ARM
2050 /* XXX: Suppress stack unwinding section. */
2051 if (s->sh_type == SHT_ARM_EXIDX) {
2052 s->sh_flags = 0;
2053 s->sh_size = 0;
2055 #endif
2058 return textrel;
2061 /* various data used under elf_output_file() */
2062 struct dyn_inf {
2063 Section *dynamic;
2064 Section *dynstr;
2065 struct {
2066 /* Info to be copied in dynamic section */
2067 unsigned long data_offset;
2068 addr_t rel_addr;
2069 addr_t rel_size;
2072 ElfW(Phdr) *phdr;
2073 int phnum;
2074 Section *interp;
2075 Section *note;
2076 Section *gnu_hash;
2078 /* read only segment mapping for GNU_RELRO */
2079 Section _roinf, *roinf;
2082 /* Decide the layout of sections loaded in memory. This must be done before
2083 program headers are filled since they contain info about the layout.
2084 We do the following ordering: interp, symbol tables, relocations, progbits,
2085 nobits */
2086 static int sort_sections(TCCState *s1, int *sec_order, Section *interp)
2088 Section *s;
2089 int i, j, k, f, f0, n;
2090 int nb_sections = s1->nb_sections;
2091 int *sec_cls = sec_order + nb_sections;
2093 for (i = 1; i < nb_sections; i++) {
2094 s = s1->sections[i];
2095 if (s->sh_flags & SHF_ALLOC) {
2096 j = 0x100;
2097 if (s->sh_flags & SHF_WRITE)
2098 j = 0x200;
2099 if (s->sh_flags & SHF_TLS)
2100 j += 0x200;
2101 } else if (s->sh_name) {
2102 j = 0x700;
2103 } else {
2104 j = 0x900; /* no sh_name: won't go to file */
2106 if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_DYNSYM) {
2107 k = 0x10;
2108 } else if (s->sh_type == SHT_STRTAB && strcmp(s->name, ".stabstr")) {
2109 k = 0x11;
2110 if (i == nb_sections - 1) /* ".shstrtab" assumed to remain last */
2111 k = 0xff;
2112 } else if (s->sh_type == SHT_HASH || s->sh_type == SHT_GNU_HASH) {
2113 k = 0x12;
2114 } else if (s->sh_type == SHT_RELX) {
2115 k = 0x20;
2116 if (s1->plt && s == s1->plt->reloc)
2117 k = 0x21;
2118 } else if (s->sh_type == SHT_PREINIT_ARRAY) {
2119 k = 0x41;
2120 } else if (s->sh_type == SHT_INIT_ARRAY) {
2121 k = 0x42;
2122 } else if (s->sh_type == SHT_FINI_ARRAY) {
2123 k = 0x43;
2124 #ifdef CONFIG_TCC_BCHECK
2125 } else if (s == bounds_section || s == lbounds_section) {
2126 k = 0x44;
2127 #endif
2128 } else if (s == rodata_section || 0 == strcmp(s->name, ".data.rel.ro")) {
2129 k = 0x45;
2130 } else if (s->sh_type == SHT_DYNAMIC) {
2131 k = 0x46;
2132 } else if (s == s1->got) {
2133 k = 0x47; /* .got as RELRO needs BIND_NOW in DT_FLAGS */
2134 } else {
2135 k = 0x50;
2136 if (s->sh_type == SHT_NOTE)
2137 k = 0x60;
2138 if (s->sh_flags & SHF_EXECINSTR)
2139 k = 0x70;
2140 if (s->sh_type == SHT_NOBITS)
2141 k = 0x80;
2142 if (s == interp)
2143 k = 0x00;
2145 k += j;
2147 for (n = i; n > 1 && k < (f = sec_cls[n - 1]); --n)
2148 sec_cls[n] = f, sec_order[n] = sec_order[n - 1];
2149 sec_cls[n] = k, sec_order[n] = i;
2151 sec_order[0] = 0;
2153 /* count PT_LOAD headers needed */
2154 n = f0 = 0;
2155 for (i = 1; i < nb_sections; i++) {
2156 s = s1->sections[sec_order[i]];
2157 k = sec_cls[i];
2158 f = 0;
2159 if (k < 0x700) {
2160 f = s->sh_flags & (SHF_ALLOC|SHF_WRITE|SHF_EXECINSTR|SHF_TLS);
2161 #if TARGETOS_NetBSD
2162 /* NetBSD only supports 2 PT_LOAD sections.
2163 See: https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */
2164 if ((f & SHF_WRITE) == 0) f |= SHF_EXECINSTR;
2165 #else
2166 if ((k & 0xfff0) == 0x240) /* RELRO sections */
2167 f |= 1<<4;
2168 #endif
2169 if (f != f0) /* start new header when flags changed or relro */
2170 f0 = f, ++n, f |= 1<<8;
2172 sec_cls[i] = f;
2173 //printf("ph %d sec %02d : %3X %3X %8.2X %04X %s\n", !!f * n, i, f, k, s->sh_type, s->sh_size, s->name);
2175 return n;
2178 static ElfW(Phdr) *fill_phdr(ElfW(Phdr) *ph, int type, Section *s)
2180 if (s) {
2181 ph->p_offset = s->sh_offset;
2182 ph->p_vaddr = s->sh_addr;
2183 ph->p_filesz = s->sh_size;
2184 ph->p_align = s->sh_addralign;
2186 ph->p_type = type;
2187 ph->p_flags = PF_R;
2188 ph->p_paddr = ph->p_vaddr;
2189 ph->p_memsz = ph->p_filesz;
2190 return ph;
2193 /* Assign sections to segments and decide how are sections laid out when loaded
2194 in memory. This function also fills corresponding program headers. */
2195 static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
2197 Section *s;
2198 addr_t addr, tmp, align, s_align, base;
2199 ElfW(Phdr) *ph = NULL;
2200 int i, f, n, phnum, phfill;
2201 int file_offset;
2203 /* compute number of program headers */
2204 phnum = sort_sections(s1, sec_order, d->interp);
2205 phfill = 0; /* set to 1 to have dll's with a PT_PHDR */
2206 if (d->interp)
2207 phfill = 2;
2208 phnum += phfill;
2209 if (d->note)
2210 ++phnum;
2211 if (d->dynamic)
2212 ++phnum;
2213 if (d->roinf)
2214 ++phnum;
2215 d->phnum = phnum;
2216 d->phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2218 file_offset = 0;
2219 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2220 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2222 s_align = ELF_PAGE_SIZE;
2223 if (s1->section_align)
2224 s_align = s1->section_align;
2226 addr = ELF_START_ADDR;
2227 if (s1->output_type & TCC_OUTPUT_DYN)
2228 addr = 0;
2230 if (s1->has_text_addr) {
2231 addr = s1->text_addr;
2232 if (0) {
2233 int a_offset, p_offset;
2234 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
2235 ELF_PAGE_SIZE */
2236 a_offset = (int) (addr & (s_align - 1));
2237 p_offset = file_offset & (s_align - 1);
2238 if (a_offset < p_offset)
2239 a_offset += s_align;
2240 file_offset += (a_offset - p_offset);
2243 base = addr;
2244 /* compute address after headers */
2245 addr = addr + (file_offset & (s_align - 1));
2247 n = 0;
2248 for(i = 1; i < s1->nb_sections; i++) {
2249 s = s1->sections[sec_order[i]];
2250 f = sec_order[i + s1->nb_sections];
2251 align = s->sh_addralign - 1;
2253 if (f == 0) { /* no alloc */
2254 file_offset = (file_offset + align) & ~align;
2255 s->sh_offset = file_offset;
2256 if (s->sh_type != SHT_NOBITS)
2257 file_offset += s->sh_size;
2258 continue;
2261 if ((f & 1<<8) && n) {
2262 /* different rwx section flags */
2263 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
2264 /* if in the middle of a page, w e duplicate the page in
2265 memory so that one copy is RX and the other is RW */
2266 if ((addr & (s_align - 1)) != 0)
2267 addr += s_align;
2268 } else {
2269 align = s_align - 1;
2273 tmp = addr;
2274 addr = (addr + align) & ~align;
2275 file_offset += (int)(addr - tmp);
2276 s->sh_offset = file_offset;
2277 s->sh_addr = addr;
2279 if (f & 1<<8) {
2280 /* set new program header */
2281 ph = &d->phdr[phfill + n];
2282 ph->p_type = PT_LOAD;
2283 ph->p_align = s_align;
2284 ph->p_flags = PF_R;
2285 if (f & SHF_WRITE)
2286 ph->p_flags |= PF_W;
2287 if (f & SHF_EXECINSTR)
2288 ph->p_flags |= PF_X;
2289 if (f & SHF_TLS) {
2290 ph->p_type = PT_TLS;
2291 ph->p_align = align + 1;
2294 ph->p_offset = file_offset;
2295 ph->p_vaddr = addr;
2296 if (n == 0) {
2297 /* Make the first PT_LOAD segment include the program
2298 headers itself (and the ELF header as well), it'll
2299 come out with same memory use but will make various
2300 tools like binutils strip work better. */
2301 ph->p_offset = 0;
2302 ph->p_vaddr = base;
2304 ph->p_paddr = ph->p_vaddr;
2305 ++n;
2308 if (f & 1<<4) {
2309 Section *roinf = &d->_roinf;
2310 if (roinf->sh_size == 0) {
2311 roinf->sh_offset = s->sh_offset;
2312 roinf->sh_addr = s->sh_addr;
2313 roinf->sh_addralign = 1;
2315 roinf->sh_size = (addr - roinf->sh_addr) + s->sh_size;
2318 addr += s->sh_size;
2319 if (s->sh_type != SHT_NOBITS)
2320 file_offset += s->sh_size;
2322 ph->p_filesz = file_offset - ph->p_offset;
2323 ph->p_memsz = addr - ph->p_vaddr;
2326 /* Fill other headers */
2327 if (d->note)
2328 fill_phdr(++ph, PT_NOTE, d->note);
2329 if (d->dynamic)
2330 fill_phdr(++ph, PT_DYNAMIC, d->dynamic)->p_flags |= PF_W;
2331 if (d->roinf)
2332 fill_phdr(++ph, PT_GNU_RELRO, d->roinf)->p_flags |= PF_W;
2333 if (d->interp)
2334 fill_phdr(&d->phdr[1], PT_INTERP, d->interp);
2335 if (phfill) {
2336 ph = &d->phdr[0];
2337 ph->p_offset = sizeof(ElfW(Ehdr));
2338 ph->p_vaddr = base + ph->p_offset;
2339 ph->p_filesz = phnum * sizeof(ElfW(Phdr));
2340 ph->p_align = 4;
2341 fill_phdr(ph, PT_PHDR, NULL);
2343 return file_offset;
2346 /* put dynamic tag */
2347 static void put_dt(Section *dynamic, int dt, addr_t val)
2349 ElfW(Dyn) *dyn;
2350 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
2351 dyn->d_tag = dt;
2352 dyn->d_un.d_val = val;
2355 /* Fill the dynamic section with tags describing the address and size of
2356 sections */
2357 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2359 Section *dynamic = dyninf->dynamic;
2360 Section *s;
2362 /* put dynamic section entries */
2363 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2364 put_dt(dynamic, DT_GNU_HASH, dyninf->gnu_hash->sh_addr);
2365 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2366 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2367 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2368 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2369 #if PTR_SIZE == 8
2370 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2371 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2372 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2373 if (s1->plt && s1->plt->reloc) {
2374 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2375 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2376 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2377 put_dt(dynamic, DT_PLTREL, DT_RELA);
2379 put_dt(dynamic, DT_RELACOUNT, 0);
2380 #else
2381 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2382 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2383 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2384 if (s1->plt && s1->plt->reloc) {
2385 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2386 put_dt(dynamic, DT_PLTRELSZ, s1->plt->reloc->data_offset);
2387 put_dt(dynamic, DT_JMPREL, s1->plt->reloc->sh_addr);
2388 put_dt(dynamic, DT_PLTREL, DT_REL);
2390 put_dt(dynamic, DT_RELCOUNT, 0);
2391 #endif
2392 if (versym_section && verneed_section) {
2393 /* The dynamic linker can not handle VERSYM without VERNEED */
2394 put_dt(dynamic, DT_VERSYM, versym_section->sh_addr);
2395 put_dt(dynamic, DT_VERNEED, verneed_section->sh_addr);
2396 put_dt(dynamic, DT_VERNEEDNUM, dt_verneednum);
2398 s = have_section(s1, ".preinit_array");
2399 if (s && s->data_offset) {
2400 put_dt(dynamic, DT_PREINIT_ARRAY, s->sh_addr);
2401 put_dt(dynamic, DT_PREINIT_ARRAYSZ, s->data_offset);
2403 s = have_section(s1, ".init_array");
2404 if (s && s->data_offset) {
2405 put_dt(dynamic, DT_INIT_ARRAY, s->sh_addr);
2406 put_dt(dynamic, DT_INIT_ARRAYSZ, s->data_offset);
2408 s = have_section(s1, ".fini_array");
2409 if (s && s->data_offset) {
2410 put_dt(dynamic, DT_FINI_ARRAY, s->sh_addr);
2411 put_dt(dynamic, DT_FINI_ARRAYSZ, s->data_offset);
2413 s = have_section(s1, ".init");
2414 if (s && s->data_offset) {
2415 put_dt(dynamic, DT_INIT, s->sh_addr);
2417 s = have_section(s1, ".fini");
2418 if (s && s->data_offset) {
2419 put_dt(dynamic, DT_FINI, s->sh_addr);
2421 if (s1->do_debug)
2422 put_dt(dynamic, DT_DEBUG, 0);
2423 put_dt(dynamic, DT_NULL, 0);
2426 /* Remove gaps between RELX sections.
2427 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2428 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2429 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2430 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2431 static void update_reloc_sections(TCCState *s1, struct dyn_inf *dyninf)
2433 int i;
2434 unsigned long file_offset = 0;
2435 Section *s;
2436 Section *relocplt = s1->plt ? s1->plt->reloc : NULL;
2438 /* dynamic relocation table information, for .dynamic section */
2439 dyninf->rel_addr = dyninf->rel_size = 0;
2441 for(i = 1; i < s1->nb_sections; i++) {
2442 s = s1->sections[i];
2443 if (s->sh_type == SHT_RELX && s != relocplt) {
2444 if (dyninf->rel_size == 0) {
2445 dyninf->rel_addr = s->sh_addr;
2446 file_offset = s->sh_offset;
2448 else {
2449 s->sh_addr = dyninf->rel_addr + dyninf->rel_size;
2450 s->sh_offset = file_offset + dyninf->rel_size;
2452 dyninf->rel_size += s->sh_size;
2457 static int tidy_section_headers(TCCState *s1, int *sec_order);
2458 #endif /* ndef ELF_OBJ_ONLY */
2460 /* Create an ELF file on disk.
2461 This function handle ELF specific layout requirements */
2462 static int tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2463 int file_offset, int *sec_order)
2465 int i, shnum, offset, size, file_type;
2466 Section *s;
2467 ElfW(Ehdr) ehdr;
2468 ElfW(Shdr) shdr, *sh;
2470 file_type = s1->output_type;
2471 shnum = s1->nb_sections;
2473 memset(&ehdr, 0, sizeof(ehdr));
2475 if (phnum > 0) {
2476 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2477 ehdr.e_phnum = phnum;
2478 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2479 #ifndef ELF_OBJ_ONLY
2480 shnum = tidy_section_headers(s1, sec_order);
2481 #endif
2484 /* align to 4 */
2485 file_offset = (file_offset + 3) & -4;
2487 /* fill header */
2488 ehdr.e_ident[0] = ELFMAG0;
2489 ehdr.e_ident[1] = ELFMAG1;
2490 ehdr.e_ident[2] = ELFMAG2;
2491 ehdr.e_ident[3] = ELFMAG3;
2492 ehdr.e_ident[4] = ELFCLASSW;
2493 ehdr.e_ident[5] = ELFDATA2LSB;
2494 ehdr.e_ident[6] = EV_CURRENT;
2496 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2497 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2498 #elif defined TCC_TARGET_ARM && defined TCC_ARM_EABI
2499 ehdr.e_flags = EF_ARM_EABI_VER5;
2500 ehdr.e_flags |= s1->float_abi == ARM_HARD_FLOAT
2501 ? EF_ARM_VFP_FLOAT : EF_ARM_SOFT_FLOAT;
2502 #elif defined TCC_TARGET_ARM
2503 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2504 #elif defined TCC_TARGET_RISCV64
2505 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
2506 #endif
2508 if (file_type == TCC_OUTPUT_OBJ) {
2509 ehdr.e_type = ET_REL;
2510 } else {
2511 if (file_type & TCC_OUTPUT_DYN)
2512 ehdr.e_type = ET_DYN;
2513 else
2514 ehdr.e_type = ET_EXEC;
2515 if (s1->elf_entryname)
2516 ehdr.e_entry = get_sym_addr(s1, s1->elf_entryname, 1, 0);
2517 else
2518 ehdr.e_entry = get_sym_addr(s1, "_start", !!(file_type & TCC_OUTPUT_EXE), 0);
2519 if (ehdr.e_entry == (addr_t)-1)
2520 ehdr.e_entry = text_section->sh_addr;
2521 if (s1->nb_errors)
2522 return -1;
2525 ehdr.e_machine = EM_TCC_TARGET;
2526 ehdr.e_version = EV_CURRENT;
2527 ehdr.e_shoff = file_offset;
2528 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2529 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2530 ehdr.e_shnum = shnum;
2531 ehdr.e_shstrndx = shnum - 1;
2533 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2534 if (phdr)
2535 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2536 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2538 sort_syms(s1, symtab_section);
2540 for(i = 1; i < shnum; i++) {
2541 s = s1->sections[sec_order ? sec_order[i] : i];
2542 if (s->sh_type != SHT_NOBITS) {
2543 while (offset < s->sh_offset) {
2544 fputc(0, f);
2545 offset++;
2547 size = s->sh_size;
2548 if (size)
2549 fwrite(s->data, 1, size, f);
2550 offset += size;
2554 /* output section headers */
2555 while (offset < ehdr.e_shoff) {
2556 fputc(0, f);
2557 offset++;
2560 for(i = 0; i < shnum; i++) {
2561 sh = &shdr;
2562 memset(sh, 0, sizeof(ElfW(Shdr)));
2563 s = s1->sections[i];
2564 if (s) {
2565 sh->sh_name = s->sh_name;
2566 sh->sh_type = s->sh_type;
2567 sh->sh_flags = s->sh_flags;
2568 sh->sh_entsize = s->sh_entsize;
2569 sh->sh_info = s->sh_info;
2570 if (s->link)
2571 sh->sh_link = s->link->sh_num;
2572 sh->sh_addralign = s->sh_addralign;
2573 sh->sh_addr = s->sh_addr;
2574 sh->sh_offset = s->sh_offset;
2575 sh->sh_size = s->sh_size;
2577 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2579 return 0;
2582 static int tcc_output_binary(TCCState *s1, FILE *f,
2583 const int *sec_order)
2585 Section *s;
2586 int i, offset, size;
2588 offset = 0;
2589 for(i=1;i<s1->nb_sections;i++) {
2590 s = s1->sections[sec_order[i]];
2591 if (s->sh_type != SHT_NOBITS &&
2592 (s->sh_flags & SHF_ALLOC)) {
2593 while (offset < s->sh_offset) {
2594 fputc(0, f);
2595 offset++;
2597 size = s->sh_size;
2598 fwrite(s->data, 1, size, f);
2599 offset += size;
2602 return 0;
2605 /* Write an elf, coff or "binary" file */
2606 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2607 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2609 int fd, mode, file_type, ret;
2610 FILE *f;
2612 file_type = s1->output_type;
2613 if (file_type == TCC_OUTPUT_OBJ)
2614 mode = 0666;
2615 else
2616 mode = 0777;
2617 unlink(filename);
2618 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2619 if (fd < 0 || (f = fdopen(fd, "wb")) == NULL)
2620 return tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno));
2621 if (s1->verbose)
2622 printf("<- %s\n", filename);
2623 #ifdef TCC_TARGET_COFF
2624 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2625 tcc_output_coff(s1, f);
2626 else
2627 #endif
2628 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2629 ret = tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2630 else
2631 ret = tcc_output_binary(s1, f, sec_order);
2632 fclose(f);
2634 return ret;
2637 #ifndef ELF_OBJ_ONLY
2638 /* Sort section headers by assigned sh_addr, remove sections
2639 that we aren't going to output. */
2640 static int tidy_section_headers(TCCState *s1, int *sec_order)
2642 int i, nnew, l, *backmap;
2643 Section **snew, *s;
2644 ElfW(Sym) *sym;
2646 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2647 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2648 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2649 s = s1->sections[sec_order[i]];
2650 if (!i || s->sh_name) {
2651 backmap[sec_order[i]] = nnew;
2652 snew[nnew] = s;
2653 ++nnew;
2654 } else {
2655 backmap[sec_order[i]] = 0;
2656 snew[--l] = s;
2659 for (i = 0; i < nnew; i++) {
2660 s = snew[i];
2661 if (s) {
2662 s->sh_num = i;
2663 if (s->sh_type == SHT_RELX)
2664 s->sh_info = backmap[s->sh_info];
2668 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2669 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2670 sym->st_shndx = backmap[sym->st_shndx];
2671 if ( !s1->static_link ) {
2672 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2673 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2674 sym->st_shndx = backmap[sym->st_shndx];
2676 for (i = 0; i < s1->nb_sections; i++)
2677 sec_order[i] = i;
2678 tcc_free(s1->sections);
2679 s1->sections = snew;
2680 tcc_free(backmap);
2681 return nnew;
2684 #ifdef TCC_TARGET_ARM
2685 static void create_arm_attribute_section(TCCState *s1)
2687 // Needed for DLL support.
2688 static const unsigned char arm_attr[] = {
2689 0x41, // 'A'
2690 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2691 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2692 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2693 0x05, 0x36, 0x00, // 'CPU_name', "6"
2694 0x06, 0x06, // 'CPU_arch', 'v6'
2695 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2696 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2697 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2698 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2699 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2700 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2701 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2702 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2703 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2704 0x1a, 0x02, // 'ABI_enum_size', 'int'
2705 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2706 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2708 Section *attr = new_section(s1, ".ARM.attributes", SHT_ARM_ATTRIBUTES, 0);
2709 unsigned char *ptr = section_ptr_add(attr, sizeof(arm_attr));
2710 attr->sh_addralign = 1;
2711 memcpy(ptr, arm_attr, sizeof(arm_attr));
2712 if (s1->float_abi != ARM_HARD_FLOAT) {
2713 ptr[26] = 0x00; // 'FP_arch', 'No'
2714 ptr[41] = 0x1e; // 'ABI_optimization_goals'
2715 ptr[42] = 0x06; // 'Aggressive Debug'
2718 #endif
2720 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2721 static Section *create_bsd_note_section(TCCState *s1,
2722 const char *name,
2723 const char *value)
2725 Section *s = find_section (s1, name);
2727 if (s->data_offset == 0) {
2728 char *ptr = section_ptr_add(s, sizeof(ElfW(Nhdr)) + 8 + 4);
2729 ElfW(Nhdr) *note = (ElfW(Nhdr) *) ptr;
2731 s->sh_type = SHT_NOTE;
2732 note->n_namesz = 8;
2733 note->n_descsz = 4;
2734 note->n_type = ELF_NOTE_OS_GNU;
2735 strcpy (ptr + sizeof(ElfW(Nhdr)), value);
2737 return s;
2739 #endif
2741 static void alloc_sec_names(TCCState *s1, int is_obj);
2743 /* Output an elf, coff or binary file */
2744 /* XXX: suppress unneeded sections */
2745 static int elf_output_file(TCCState *s1, const char *filename)
2747 int i, ret, file_type, file_offset, *sec_order;
2748 struct dyn_inf dyninf = {0};
2749 Section *interp, *dynstr, *dynamic;
2750 int textrel, got_sym, dt_flags_1;
2752 file_type = s1->output_type;
2753 s1->nb_errors = 0;
2754 ret = -1;
2755 interp = dynstr = dynamic = NULL;
2756 sec_order = NULL;
2757 dyninf.roinf = &dyninf._roinf;
2759 #ifdef TCC_TARGET_ARM
2760 create_arm_attribute_section (s1);
2761 #endif
2763 #if TARGETOS_OpenBSD
2764 dyninf.note = create_bsd_note_section (s1, ".note.openbsd.ident", "OpenBSD");
2765 #endif
2767 #if TARGETOS_NetBSD
2768 dyninf.note = create_bsd_note_section (s1, ".note.netbsd.ident", "NetBSD");
2769 #endif
2771 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
2772 dyninf.roinf = NULL;
2773 #endif
2774 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2775 tcc_add_runtime(s1);
2776 resolve_common_syms(s1);
2778 if (!s1->static_link) {
2779 if (file_type & TCC_OUTPUT_EXE) {
2780 char *ptr;
2781 /* allow override the dynamic loader */
2782 const char *elfint = getenv("LD_SO");
2783 if (elfint == NULL)
2784 elfint = DEFAULT_ELFINTERP(s1);
2785 /* add interpreter section only if executable */
2786 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2787 interp->sh_addralign = 1;
2788 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2789 strcpy(ptr, elfint);
2790 dyninf.interp = interp;
2793 /* add dynamic symbol table */
2794 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2795 ".dynstr",
2796 ".hash", SHF_ALLOC);
2797 /* Number of local symbols (readelf complains if not set) */
2798 s1->dynsym->sh_info = 1;
2799 dynstr = s1->dynsym->link;
2800 /* add dynamic section */
2801 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2802 SHF_ALLOC | SHF_WRITE);
2803 dynamic->link = dynstr;
2804 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2806 got_sym = build_got(s1);
2807 if (file_type & TCC_OUTPUT_EXE) {
2808 bind_exe_dynsyms(s1, file_type & TCC_OUTPUT_DYN);
2809 if (s1->nb_errors)
2810 goto the_end;
2812 build_got_entries(s1, got_sym);
2813 if (file_type & TCC_OUTPUT_EXE) {
2814 bind_libs_dynsyms(s1);
2815 } else {
2816 /* shared library case: simply export all global symbols */
2817 export_global_syms(s1);
2819 dyninf.gnu_hash = create_gnu_hash(s1);
2820 } else {
2821 build_got_entries(s1, 0);
2823 version_add (s1);
2825 textrel = set_sec_sizes(s1);
2826 alloc_sec_names(s1, 0);
2828 if (!s1->static_link) {
2829 /* add a list of needed dlls */
2830 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2831 DLLReference *dllref = s1->loaded_dlls[i];
2832 if (dllref->level == 0)
2833 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2836 if (s1->rpath)
2837 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2838 put_elf_str(dynstr, s1->rpath));
2840 dt_flags_1 = DF_1_NOW;
2841 if (file_type & TCC_OUTPUT_DYN) {
2842 if (s1->soname)
2843 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2844 /* XXX: currently, since we do not handle PIC code, we
2845 must relocate the readonly segments */
2846 if (textrel)
2847 put_dt(dynamic, DT_TEXTREL, 0);
2848 if (file_type & TCC_OUTPUT_EXE)
2849 dt_flags_1 = DF_1_NOW | DF_1_PIE;
2851 put_dt(dynamic, DT_FLAGS, DF_BIND_NOW);
2852 put_dt(dynamic, DT_FLAGS_1, dt_flags_1);
2853 if (s1->symbolic)
2854 put_dt(dynamic, DT_SYMBOLIC, 0);
2856 dyninf.dynamic = dynamic;
2857 dyninf.dynstr = dynstr;
2858 /* remember offset and reserve space for 2nd call below */
2859 dyninf.data_offset = dynamic->data_offset;
2860 fill_dynamic(s1, &dyninf);
2861 dynamic->sh_size = dynamic->data_offset;
2862 dynstr->sh_size = dynstr->data_offset;
2865 /* this array is used to reorder sections in the output file */
2866 sec_order = tcc_malloc(sizeof(int) * 2 * s1->nb_sections);
2867 /* compute section to program header mapping */
2868 file_offset = layout_sections(s1, sec_order, &dyninf);
2870 if (dynamic) {
2871 /* put in GOT the dynamic section address and relocate PLT */
2872 write32le(s1->got->data, dynamic->sh_addr);
2873 if (file_type == TCC_OUTPUT_EXE
2874 || (RELOCATE_DLLPLT && (file_type & TCC_OUTPUT_DYN)))
2875 relocate_plt(s1);
2876 /* relocate symbols in .dynsym now that final addresses are known */
2877 relocate_syms(s1, s1->dynsym, 2);
2880 /* if building executable or DLL, then relocate each section
2881 except the GOT which is already relocated */
2882 relocate_syms(s1, s1->symtab, 0);
2883 if (s1->nb_errors != 0)
2884 goto the_end;
2885 relocate_sections(s1);
2886 if (dynamic) {
2887 update_reloc_sections (s1, &dyninf);
2888 dynamic->data_offset = dyninf.data_offset;
2889 fill_dynamic(s1, &dyninf);
2891 /* Perform relocation to GOT or PLT entries */
2892 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2893 fill_got(s1);
2894 else if (s1->got)
2895 fill_local_got_entries(s1);
2897 if (dyninf.gnu_hash)
2898 update_gnu_hash(s1, dyninf.gnu_hash);
2900 /* Create the ELF file with name 'filename' */
2901 ret = tcc_write_elf_file(s1, filename, dyninf.phnum, dyninf.phdr, file_offset, sec_order);
2902 the_end:
2903 tcc_free(sec_order);
2904 tcc_free(dyninf.phdr);
2905 return ret;
2907 #endif /* ndef ELF_OBJ_ONLY */
2909 /* Allocate strings for section names */
2910 static void alloc_sec_names(TCCState *s1, int is_obj)
2912 int i;
2913 Section *s, *strsec;
2915 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2916 put_elf_str(strsec, "");
2917 for(i = 1; i < s1->nb_sections; i++) {
2918 s = s1->sections[i];
2919 if (is_obj)
2920 s->sh_size = s->data_offset;
2921 if (s == strsec || s->sh_size || (s->sh_flags & SHF_ALLOC))
2922 s->sh_name = put_elf_str(strsec, s->name);
2924 strsec->sh_size = strsec->data_offset;
2927 /* Output an elf .o file */
2928 static int elf_output_obj(TCCState *s1, const char *filename)
2930 Section *s;
2931 int i, ret, file_offset;
2932 s1->nb_errors = 0;
2933 /* Allocate strings for section names */
2934 alloc_sec_names(s1, 1);
2935 file_offset = sizeof (ElfW(Ehdr));
2936 for(i = 1; i < s1->nb_sections; i++) {
2937 s = s1->sections[i];
2938 file_offset = (file_offset + 15) & -16;
2939 s->sh_offset = file_offset;
2940 if (s->sh_type != SHT_NOBITS)
2941 file_offset += s->sh_size;
2943 /* Create the ELF file with name 'filename' */
2944 ret = tcc_write_elf_file(s1, filename, 0, NULL, file_offset, NULL);
2945 return ret;
2948 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2950 if (s->test_coverage)
2951 tcc_tcov_add_file(s, filename);
2952 if (s->output_type == TCC_OUTPUT_OBJ)
2953 return elf_output_obj(s, filename);
2954 #ifdef TCC_TARGET_PE
2955 return pe_output_file(s, filename);
2956 #elif TCC_TARGET_MACHO
2957 return macho_output_file(s, filename);
2958 #else
2959 return elf_output_file(s, filename);
2960 #endif
2963 ST_FUNC ssize_t full_read(int fd, void *buf, size_t count) {
2964 char *cbuf = buf;
2965 size_t rnum = 0;
2966 while (1) {
2967 ssize_t num = read(fd, cbuf, count-rnum);
2968 if (num < 0) return num;
2969 if (num == 0) return rnum;
2970 rnum += num;
2971 cbuf += num;
2975 ST_FUNC void *load_data(int fd, unsigned long file_offset, unsigned long size)
2977 void *data;
2979 data = tcc_malloc(size);
2980 lseek(fd, file_offset, SEEK_SET);
2981 full_read(fd, data, size);
2982 return data;
2985 typedef struct SectionMergeInfo {
2986 Section *s; /* corresponding existing section */
2987 unsigned long offset; /* offset of the new section in the existing section */
2988 uint8_t new_section; /* true if section 's' was added */
2989 uint8_t link_once; /* true if link once section */
2990 } SectionMergeInfo;
2992 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2994 int size = full_read(fd, h, sizeof *h);
2995 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2996 if (h->e_type == ET_REL)
2997 return AFF_BINTYPE_REL;
2998 if (h->e_type == ET_DYN)
2999 return AFF_BINTYPE_DYN;
3000 } else if (size >= 8) {
3001 if (0 == memcmp(h, ARMAG, 8))
3002 return AFF_BINTYPE_AR;
3003 #ifdef TCC_TARGET_COFF
3004 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
3005 return AFF_BINTYPE_C67;
3006 #endif
3008 return 0;
3011 /* load an object file and merge it with current files */
3012 /* XXX: handle correctly stab (debug) info */
3013 ST_FUNC int tcc_load_object_file(TCCState *s1,
3014 int fd, unsigned long file_offset)
3016 ElfW(Ehdr) ehdr;
3017 ElfW(Shdr) *shdr, *sh;
3018 unsigned long size, offset, offseti;
3019 int i, j, nb_syms, sym_index, ret, seencompressed;
3020 char *strsec, *strtab;
3021 int stab_index, stabstr_index;
3022 int *old_to_new_syms;
3023 char *sh_name, *name;
3024 SectionMergeInfo *sm_table, *sm;
3025 ElfW(Sym) *sym, *symtab;
3026 ElfW_Rel *rel;
3027 Section *s;
3029 lseek(fd, file_offset, SEEK_SET);
3030 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
3031 goto invalid;
3032 /* test CPU specific stuff */
3033 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3034 ehdr.e_machine != EM_TCC_TARGET) {
3035 invalid:
3036 return tcc_error_noabort("invalid object file");
3038 /* read sections */
3039 shdr = load_data(fd, file_offset + ehdr.e_shoff,
3040 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3041 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
3043 /* load section names */
3044 sh = &shdr[ehdr.e_shstrndx];
3045 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3047 /* load symtab and strtab */
3048 old_to_new_syms = NULL;
3049 symtab = NULL;
3050 strtab = NULL;
3051 nb_syms = 0;
3052 seencompressed = 0;
3053 stab_index = stabstr_index = 0;
3054 ret = -1;
3056 for(i = 1; i < ehdr.e_shnum; i++) {
3057 sh = &shdr[i];
3058 if (sh->sh_type == SHT_SYMTAB) {
3059 if (symtab) {
3060 tcc_error_noabort("object must contain only one symtab");
3061 goto the_end;
3063 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3064 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3065 sm_table[i].s = symtab_section;
3067 /* now load strtab */
3068 sh = &shdr[sh->sh_link];
3069 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3071 if (sh->sh_flags & SHF_COMPRESSED)
3072 seencompressed = 1;
3075 /* now examine each section and try to merge its content with the
3076 ones in memory */
3077 for(i = 1; i < ehdr.e_shnum; i++) {
3078 /* no need to examine section name strtab */
3079 if (i == ehdr.e_shstrndx)
3080 continue;
3081 sh = &shdr[i];
3082 if (sh->sh_type == SHT_RELX)
3083 sh = &shdr[sh->sh_info];
3084 /* ignore sections types we do not handle (plus relocs to those) */
3085 if (sh->sh_type != SHT_PROGBITS &&
3086 #ifdef TCC_ARM_EABI
3087 sh->sh_type != SHT_ARM_EXIDX &&
3088 #endif
3089 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3090 sh->sh_type != SHT_X86_64_UNWIND &&
3091 #endif
3092 sh->sh_type != SHT_NOTE &&
3093 sh->sh_type != SHT_NOBITS &&
3094 sh->sh_type != SHT_PREINIT_ARRAY &&
3095 sh->sh_type != SHT_INIT_ARRAY &&
3096 sh->sh_type != SHT_FINI_ARRAY &&
3097 strcmp(strsec + sh->sh_name, ".stabstr")
3099 continue;
3100 if (seencompressed && 0 == strncmp(strsec + sh->sh_name, ".debug_", 7))
3101 continue;
3103 sh = &shdr[i];
3104 sh_name = strsec + sh->sh_name;
3105 if (sh->sh_addralign < 1)
3106 sh->sh_addralign = 1;
3107 /* find corresponding section, if any */
3108 for(j = 1; j < s1->nb_sections;j++) {
3109 s = s1->sections[j];
3110 if (!strcmp(s->name, sh_name)) {
3111 if (!strncmp(sh_name, ".gnu.linkonce",
3112 sizeof(".gnu.linkonce") - 1)) {
3113 /* if a 'linkonce' section is already present, we
3114 do not add it again. It is a little tricky as
3115 symbols can still be defined in
3116 it. */
3117 sm_table[i].link_once = 1;
3118 goto next;
3120 if (stab_section) {
3121 if (s == stab_section)
3122 stab_index = i;
3123 if (s == stab_section->link)
3124 stabstr_index = i;
3126 goto found;
3129 /* not found: create new section */
3130 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
3131 /* take as much info as possible from the section. sh_link and
3132 sh_info will be updated later */
3133 s->sh_addralign = sh->sh_addralign;
3134 s->sh_entsize = sh->sh_entsize;
3135 sm_table[i].new_section = 1;
3136 found:
3137 if (sh->sh_type != s->sh_type
3138 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3139 && strcmp (s->name, ".eh_frame")
3140 #endif
3142 tcc_error_noabort("invalid section type");
3143 goto the_end;
3145 /* align start of section */
3146 s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
3147 if (sh->sh_addralign > s->sh_addralign)
3148 s->sh_addralign = sh->sh_addralign;
3149 sm_table[i].offset = s->data_offset;
3150 sm_table[i].s = s;
3151 /* concatenate sections */
3152 size = sh->sh_size;
3153 if (sh->sh_type != SHT_NOBITS) {
3154 unsigned char *ptr;
3155 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
3156 ptr = section_ptr_add(s, size);
3157 full_read(fd, ptr, size);
3158 } else {
3159 s->data_offset += size;
3161 next: ;
3164 /* gr relocate stab strings */
3165 if (stab_index && stabstr_index) {
3166 Stab_Sym *a, *b;
3167 unsigned o;
3168 s = sm_table[stab_index].s;
3169 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
3170 b = (Stab_Sym *)(s->data + s->data_offset);
3171 o = sm_table[stabstr_index].offset;
3172 while (a < b) {
3173 if (a->n_strx)
3174 a->n_strx += o;
3175 a++;
3179 /* second short pass to update sh_link and sh_info fields of new
3180 sections */
3181 for(i = 1; i < ehdr.e_shnum; i++) {
3182 s = sm_table[i].s;
3183 if (!s || !sm_table[i].new_section)
3184 continue;
3185 sh = &shdr[i];
3186 if (sh->sh_link > 0)
3187 s->link = sm_table[sh->sh_link].s;
3188 if (sh->sh_type == SHT_RELX) {
3189 s->sh_info = sm_table[sh->sh_info].s->sh_num;
3190 /* update backward link */
3191 s1->sections[s->sh_info]->reloc = s;
3195 /* resolve symbols */
3196 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
3198 sym = symtab + 1;
3199 for(i = 1; i < nb_syms; i++, sym++) {
3200 if (sym->st_shndx != SHN_UNDEF &&
3201 sym->st_shndx < SHN_LORESERVE) {
3202 sm = &sm_table[sym->st_shndx];
3203 if (sm->link_once) {
3204 /* if a symbol is in a link once section, we use the
3205 already defined symbol. It is very important to get
3206 correct relocations */
3207 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
3208 name = strtab + sym->st_name;
3209 sym_index = find_elf_sym(symtab_section, name);
3210 if (sym_index)
3211 old_to_new_syms[i] = sym_index;
3213 continue;
3215 /* if no corresponding section added, no need to add symbol */
3216 if (!sm->s)
3217 continue;
3218 /* convert section number */
3219 sym->st_shndx = sm->s->sh_num;
3220 /* offset value */
3221 sym->st_value += sm->offset;
3223 /* add symbol */
3224 name = strtab + sym->st_name;
3225 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
3226 sym->st_info, sym->st_other,
3227 sym->st_shndx, name);
3228 old_to_new_syms[i] = sym_index;
3231 /* third pass to patch relocation entries */
3232 for(i = 1; i < ehdr.e_shnum; i++) {
3233 s = sm_table[i].s;
3234 if (!s)
3235 continue;
3236 sh = &shdr[i];
3237 offset = sm_table[i].offset;
3238 size = sh->sh_size;
3239 switch(s->sh_type) {
3240 case SHT_RELX:
3241 /* take relocation offset information */
3242 offseti = sm_table[sh->sh_info].offset;
3243 for (rel = (ElfW_Rel *) s->data + (offset / sizeof(*rel));
3244 rel < (ElfW_Rel *) s->data + ((offset + size) / sizeof(*rel));
3245 rel++) {
3246 int type;
3247 unsigned sym_index;
3248 /* convert symbol index */
3249 type = ELFW(R_TYPE)(rel->r_info);
3250 sym_index = ELFW(R_SYM)(rel->r_info);
3251 /* NOTE: only one symtab assumed */
3252 if (sym_index >= nb_syms)
3253 goto invalid_reloc;
3254 sym_index = old_to_new_syms[sym_index];
3255 /* ignore link_once in rel section. */
3256 if (!sym_index && !sm_table[sh->sh_info].link_once
3257 #ifdef TCC_TARGET_ARM
3258 && type != R_ARM_V4BX
3259 #elif defined TCC_TARGET_RISCV64
3260 && type != R_RISCV_ALIGN
3261 && type != R_RISCV_RELAX
3262 #endif
3264 invalid_reloc:
3265 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3266 i, strsec + sh->sh_name, (int)rel->r_offset);
3267 goto the_end;
3269 rel->r_info = ELFW(R_INFO)(sym_index, type);
3270 /* offset the relocation offset */
3271 rel->r_offset += offseti;
3272 #ifdef TCC_TARGET_ARM
3273 /* Jumps and branches from a Thumb code to a PLT entry need
3274 special handling since PLT entries are ARM code.
3275 Unconditional bl instructions referencing PLT entries are
3276 handled by converting these instructions into blx
3277 instructions. Other case of instructions referencing a PLT
3278 entry require to add a Thumb stub before the PLT entry to
3279 switch to ARM mode. We set bit plt_thumb_stub of the
3280 attribute of a symbol to indicate such a case. */
3281 if (type == R_ARM_THM_JUMP24)
3282 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
3283 #endif
3285 break;
3286 default:
3287 break;
3291 ret = 0;
3292 the_end:
3293 tcc_free(symtab);
3294 tcc_free(strtab);
3295 tcc_free(old_to_new_syms);
3296 tcc_free(sm_table);
3297 tcc_free(strsec);
3298 tcc_free(shdr);
3299 return ret;
3302 typedef struct ArchiveHeader {
3303 char ar_name[16]; /* name of this member */
3304 char ar_date[12]; /* file mtime */
3305 char ar_uid[6]; /* owner uid; printed as decimal */
3306 char ar_gid[6]; /* owner gid; printed as decimal */
3307 char ar_mode[8]; /* file mode, printed as octal */
3308 char ar_size[10]; /* file size, printed as decimal */
3309 char ar_fmag[2]; /* should contain ARFMAG */
3310 } ArchiveHeader;
3312 #define ARFMAG "`\n"
3314 static unsigned long long get_be(const uint8_t *b, int n)
3316 unsigned long long ret = 0;
3317 while (n)
3318 ret = (ret << 8) | *b++, --n;
3319 return ret;
3322 static int read_ar_header(int fd, int offset, ArchiveHeader *hdr)
3324 char *p, *e;
3325 int len;
3326 lseek(fd, offset, SEEK_SET);
3327 len = full_read(fd, hdr, sizeof(ArchiveHeader));
3328 if (len != sizeof(ArchiveHeader))
3329 return len ? -1 : 0;
3330 p = hdr->ar_name;
3331 for (e = p + sizeof hdr->ar_name; e > p && e[-1] == ' ';)
3332 --e;
3333 *e = '\0';
3334 hdr->ar_size[sizeof hdr->ar_size-1] = 0;
3335 return len;
3338 /* load only the objects which resolve undefined symbols */
3339 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
3341 int i, bound, nsyms, sym_index, len, ret = -1;
3342 unsigned long long off;
3343 uint8_t *data;
3344 const char *ar_names, *p;
3345 const uint8_t *ar_index;
3346 ElfW(Sym) *sym;
3347 ArchiveHeader hdr;
3349 data = tcc_malloc(size);
3350 if (full_read(fd, data, size) != size)
3351 goto the_end;
3352 nsyms = get_be(data, entrysize);
3353 ar_index = data + entrysize;
3354 ar_names = (char *) ar_index + nsyms * entrysize;
3356 do {
3357 bound = 0;
3358 for (p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
3359 Section *s = symtab_section;
3360 sym_index = find_elf_sym(s, p);
3361 if (!sym_index)
3362 continue;
3363 sym = &((ElfW(Sym) *)s->data)[sym_index];
3364 if(sym->st_shndx != SHN_UNDEF)
3365 continue;
3366 off = get_be(ar_index + i * entrysize, entrysize);
3367 len = read_ar_header(fd, off, &hdr);
3368 if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) {
3369 tcc_error_noabort("invalid archive");
3370 goto the_end;
3372 off += len;
3373 if (s1->verbose == 2)
3374 printf(" -> %s\n", hdr.ar_name);
3375 if (tcc_load_object_file(s1, fd, off) < 0)
3376 goto the_end;
3377 ++bound;
3379 } while(bound);
3380 ret = 0;
3381 the_end:
3382 tcc_free(data);
3383 return ret;
3386 /* load a '.a' file */
3387 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
3389 ArchiveHeader hdr;
3390 /* char magic[8]; */
3391 int size, len;
3392 unsigned long file_offset;
3393 ElfW(Ehdr) ehdr;
3395 /* skip magic which was already checked */
3396 /* full_read(fd, magic, sizeof(magic)); */
3397 file_offset = sizeof ARMAG - 1;
3399 for(;;) {
3400 len = read_ar_header(fd, file_offset, &hdr);
3401 if (len == 0)
3402 return 0;
3403 if (len < 0)
3404 return tcc_error_noabort("invalid archive");
3405 file_offset += len;
3406 size = strtol(hdr.ar_size, NULL, 0);
3407 /* align to even */
3408 size = (size + 1) & ~1;
3409 if (alacarte) {
3410 /* coff symbol table : we handle it */
3411 if (!strcmp(hdr.ar_name, "/"))
3412 return tcc_load_alacarte(s1, fd, size, 4);
3413 if (!strcmp(hdr.ar_name, "/SYM64/"))
3414 return tcc_load_alacarte(s1, fd, size, 8);
3415 } else if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3416 if (s1->verbose == 2)
3417 printf(" -> %s\n", hdr.ar_name);
3418 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3419 return -1;
3421 file_offset += size;
3425 #ifndef ELF_OBJ_ONLY
3426 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3427 LV, maybe create a new entry for (LIB,VERSION). */
3428 static void set_ver_to_ver(TCCState *s1, int *n, int **lv, int i, char *lib, char *version)
3430 while (i >= *n) {
3431 *lv = tcc_realloc(*lv, (*n + 1) * sizeof(**lv));
3432 (*lv)[(*n)++] = -1;
3434 if ((*lv)[i] == -1) {
3435 int v, prev_same_lib = -1;
3436 for (v = 0; v < nb_sym_versions; v++) {
3437 if (strcmp(sym_versions[v].lib, lib))
3438 continue;
3439 prev_same_lib = v;
3440 if (!strcmp(sym_versions[v].version, version))
3441 break;
3443 if (v == nb_sym_versions) {
3444 sym_versions = tcc_realloc (sym_versions,
3445 (v + 1) * sizeof(*sym_versions));
3446 sym_versions[v].lib = tcc_strdup(lib);
3447 sym_versions[v].version = tcc_strdup(version);
3448 sym_versions[v].out_index = 0;
3449 sym_versions[v].prev_same_lib = prev_same_lib;
3450 nb_sym_versions++;
3452 (*lv)[i] = v;
3456 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3457 VERNDX. */
3458 static void
3459 set_sym_version(TCCState *s1, int sym_index, int verndx)
3461 if (sym_index >= nb_sym_to_version) {
3462 int newelems = sym_index ? sym_index * 2 : 1;
3463 sym_to_version = tcc_realloc(sym_to_version,
3464 newelems * sizeof(*sym_to_version));
3465 memset(sym_to_version + nb_sym_to_version, -1,
3466 (newelems - nb_sym_to_version) * sizeof(*sym_to_version));
3467 nb_sym_to_version = newelems;
3469 if (sym_to_version[sym_index] < 0)
3470 sym_to_version[sym_index] = verndx;
3473 struct versym_info {
3474 int nb_versyms;
3475 ElfW(Verdef) *verdef;
3476 ElfW(Verneed) *verneed;
3477 ElfW(Half) *versym;
3478 int nb_local_ver, *local_ver;
3482 static void store_version(TCCState *s1, struct versym_info *v, char *dynstr)
3484 char *lib, *version;
3485 uint32_t next;
3486 int i;
3488 #define DEBUG_VERSION 0
3490 if (v->versym && v->verdef) {
3491 ElfW(Verdef) *vdef = v->verdef;
3492 lib = NULL;
3493 do {
3494 ElfW(Verdaux) *verdaux =
3495 (ElfW(Verdaux) *) (((char *) vdef) + vdef->vd_aux);
3497 #if DEBUG_VERSION
3498 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3499 vdef->vd_version, vdef->vd_flags, vdef->vd_ndx,
3500 vdef->vd_hash);
3501 #endif
3502 if (vdef->vd_cnt) {
3503 version = dynstr + verdaux->vda_name;
3505 if (lib == NULL)
3506 lib = version;
3507 else
3508 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vdef->vd_ndx,
3509 lib, version);
3510 #if DEBUG_VERSION
3511 printf (" verdaux(%u): %s\n", vdef->vd_ndx, version);
3512 #endif
3514 next = vdef->vd_next;
3515 vdef = (ElfW(Verdef) *) (((char *) vdef) + next);
3516 } while (next);
3518 if (v->versym && v->verneed) {
3519 ElfW(Verneed) *vneed = v->verneed;
3520 do {
3521 ElfW(Vernaux) *vernaux =
3522 (ElfW(Vernaux) *) (((char *) vneed) + vneed->vn_aux);
3524 lib = dynstr + vneed->vn_file;
3525 #if DEBUG_VERSION
3526 printf ("verneed: %u %s\n", vneed->vn_version, lib);
3527 #endif
3528 for (i = 0; i < vneed->vn_cnt; i++) {
3529 if ((vernaux->vna_other & 0x8000) == 0) { /* hidden */
3530 version = dynstr + vernaux->vna_name;
3531 set_ver_to_ver(s1, &v->nb_local_ver, &v->local_ver, vernaux->vna_other,
3532 lib, version);
3533 #if DEBUG_VERSION
3534 printf (" vernaux(%u): %u %u %s\n",
3535 vernaux->vna_other, vernaux->vna_hash,
3536 vernaux->vna_flags, version);
3537 #endif
3539 vernaux = (ElfW(Vernaux) *) (((char *) vernaux) + vernaux->vna_next);
3541 next = vneed->vn_next;
3542 vneed = (ElfW(Verneed) *) (((char *) vneed) + next);
3543 } while (next);
3546 #if DEBUG_VERSION
3547 for (i = 0; i < v->nb_local_ver; i++) {
3548 if (v->local_ver[i] > 0) {
3549 printf ("%d: lib: %s, version %s\n",
3550 i, sym_versions[v->local_ver[i]].lib,
3551 sym_versions[v->local_ver[i]].version);
3554 #endif
3557 /* load a library / DLL
3558 'level = 0' means that the DLL is referenced by the user
3559 (so it should be added as DT_NEEDED in the generated ELF file) */
3560 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3562 ElfW(Ehdr) ehdr;
3563 ElfW(Shdr) *shdr, *sh, *sh1;
3564 int i, nb_syms, nb_dts, sym_bind, ret = -1;
3565 ElfW(Sym) *sym, *dynsym;
3566 ElfW(Dyn) *dt, *dynamic;
3568 char *dynstr;
3569 int sym_index;
3570 const char *name, *soname;
3571 struct versym_info v;
3573 full_read(fd, &ehdr, sizeof(ehdr));
3575 /* test CPU specific stuff */
3576 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3577 ehdr.e_machine != EM_TCC_TARGET) {
3578 return tcc_error_noabort("bad architecture");
3581 /* read sections */
3582 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3584 /* load dynamic section and dynamic symbols */
3585 nb_syms = 0;
3586 nb_dts = 0;
3587 dynamic = NULL;
3588 dynsym = NULL; /* avoid warning */
3589 dynstr = NULL; /* avoid warning */
3590 memset(&v, 0, sizeof v);
3592 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3593 switch(sh->sh_type) {
3594 case SHT_DYNAMIC:
3595 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3596 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3597 break;
3598 case SHT_DYNSYM:
3599 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3600 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3601 sh1 = &shdr[sh->sh_link];
3602 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3603 break;
3604 case SHT_GNU_verdef:
3605 v.verdef = load_data(fd, sh->sh_offset, sh->sh_size);
3606 break;
3607 case SHT_GNU_verneed:
3608 v.verneed = load_data(fd, sh->sh_offset, sh->sh_size);
3609 break;
3610 case SHT_GNU_versym:
3611 v.nb_versyms = sh->sh_size / sizeof(ElfW(Half));
3612 v.versym = load_data(fd, sh->sh_offset, sh->sh_size);
3613 break;
3614 default:
3615 break;
3619 if (!dynamic)
3620 goto the_end;
3622 /* compute the real library name */
3623 soname = tcc_basename(filename);
3624 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
3625 if (dt->d_tag == DT_SONAME)
3626 soname = dynstr + dt->d_un.d_val;
3628 /* if the dll is already loaded, do not load it */
3629 if (tcc_add_dllref(s1, soname, level)->found)
3630 goto ret_success;
3632 if (v.nb_versyms != nb_syms)
3633 tcc_free (v.versym), v.versym = NULL;
3634 else
3635 store_version(s1, &v, dynstr);
3637 /* add dynamic symbols in dynsym_section */
3638 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3639 sym_bind = ELFW(ST_BIND)(sym->st_info);
3640 if (sym_bind == STB_LOCAL)
3641 continue;
3642 name = dynstr + sym->st_name;
3643 sym_index = set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3644 sym->st_info, sym->st_other, sym->st_shndx, name);
3645 if (v.versym) {
3646 ElfW(Half) vsym = v.versym[i];
3647 if ((vsym & 0x8000) == 0 && vsym > 0 && vsym < v.nb_local_ver)
3648 set_sym_version(s1, sym_index, v.local_ver[vsym]);
3652 /* do not load all referenced libraries
3653 (recursive loading can break linking of libraries) */
3654 /* following DT_NEEDED is needed for the dynamic loader (libdl.so),
3655 but it is no longer needed, when linking a library or a program.
3656 When tcc output mode is OUTPUT_MEM,
3657 tcc calls dlopen, which handles DT_NEEDED for us */
3659 #if 0
3660 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++)
3661 if (dt->d_tag == DT_RPATH)
3662 tcc_add_library_path(s1, dynstr + dt->d_un.d_val);
3664 /* load all referenced DLLs */
3665 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3666 switch(dt->d_tag) {
3667 case DT_NEEDED:
3668 name = dynstr + dt->d_un.d_val;
3669 if (tcc_add_dllref(s1, name, -1))
3670 continue;
3671 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3672 ret = tcc_error_noabort("referenced dll '%s' not found", name);
3673 goto the_end;
3677 #endif
3679 ret_success:
3680 ret = 0;
3681 the_end:
3682 tcc_free(dynstr);
3683 tcc_free(dynsym);
3684 tcc_free(dynamic);
3685 tcc_free(shdr);
3686 tcc_free(v.local_ver);
3687 tcc_free(v.verdef);
3688 tcc_free(v.verneed);
3689 tcc_free(v.versym);
3690 return ret;
3693 #define LD_TOK_NAME 256
3694 #define LD_TOK_EOF (-1)
3696 static int ld_inp(TCCState *s1)
3698 char b;
3699 if (s1->cc != -1) {
3700 int c = s1->cc;
3701 s1->cc = -1;
3702 return c;
3704 if (1 == read(s1->fd, &b, 1))
3705 return b;
3706 return CH_EOF;
3709 /* return next ld script token */
3710 static int ld_next(TCCState *s1, char *name, int name_size)
3712 int c, d, ch;
3713 char *q;
3715 redo:
3716 ch = ld_inp(s1);
3717 switch(ch) {
3718 case ' ':
3719 case '\t':
3720 case '\f':
3721 case '\v':
3722 case '\r':
3723 case '\n':
3724 goto redo;
3725 case '/':
3726 ch = ld_inp(s1);
3727 if (ch == '*') { /* comment */
3728 for (d = 0;; d = ch) {
3729 ch = ld_inp(s1);
3730 if (ch == CH_EOF || (ch == '/' && d == '*'))
3731 break;
3733 goto redo;
3734 } else {
3735 q = name;
3736 *q++ = '/';
3737 goto parse_name;
3739 break;
3740 case '\\':
3741 /* case 'a' ... 'z': */
3742 case 'a':
3743 case 'b':
3744 case 'c':
3745 case 'd':
3746 case 'e':
3747 case 'f':
3748 case 'g':
3749 case 'h':
3750 case 'i':
3751 case 'j':
3752 case 'k':
3753 case 'l':
3754 case 'm':
3755 case 'n':
3756 case 'o':
3757 case 'p':
3758 case 'q':
3759 case 'r':
3760 case 's':
3761 case 't':
3762 case 'u':
3763 case 'v':
3764 case 'w':
3765 case 'x':
3766 case 'y':
3767 case 'z':
3768 /* case 'A' ... 'z': */
3769 case 'A':
3770 case 'B':
3771 case 'C':
3772 case 'D':
3773 case 'E':
3774 case 'F':
3775 case 'G':
3776 case 'H':
3777 case 'I':
3778 case 'J':
3779 case 'K':
3780 case 'L':
3781 case 'M':
3782 case 'N':
3783 case 'O':
3784 case 'P':
3785 case 'Q':
3786 case 'R':
3787 case 'S':
3788 case 'T':
3789 case 'U':
3790 case 'V':
3791 case 'W':
3792 case 'X':
3793 case 'Y':
3794 case 'Z':
3795 case '_':
3796 case '.':
3797 case '$':
3798 case '~':
3799 q = name;
3800 parse_name:
3801 for(;;) {
3802 if (!((ch >= 'a' && ch <= 'z') ||
3803 (ch >= 'A' && ch <= 'Z') ||
3804 (ch >= '0' && ch <= '9') ||
3805 strchr("/.-_+=$:\\,~", ch)))
3806 break;
3807 if ((q - name) < name_size - 1) {
3808 *q++ = ch;
3810 ch = ld_inp(s1);
3812 s1->cc = ch;
3813 *q = '\0';
3814 c = LD_TOK_NAME;
3815 break;
3816 case CH_EOF:
3817 c = LD_TOK_EOF;
3818 break;
3819 default:
3820 c = ch;
3821 break;
3823 return c;
3826 static int ld_add_file(TCCState *s1, const char filename[])
3828 if (filename[0] == '/') {
3829 if (CONFIG_SYSROOT[0] == '\0'
3830 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
3831 return 0;
3832 filename = tcc_basename(filename);
3834 return tcc_add_dll(s1, filename, 0);
3837 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3839 char filename[1024], libname[1024];
3840 int t, group, nblibs = 0, ret = 0;
3841 char **libs = NULL;
3843 group = !strcmp(cmd, "GROUP");
3844 if (!as_needed)
3845 s1->new_undef_sym = 0;
3846 t = ld_next(s1, filename, sizeof(filename));
3847 if (t != '(') {
3848 ret = tcc_error_noabort("( expected");
3849 goto lib_parse_error;
3851 t = ld_next(s1, filename, sizeof(filename));
3852 for(;;) {
3853 libname[0] = '\0';
3854 if (t == LD_TOK_EOF) {
3855 ret = tcc_error_noabort("unexpected end of file");
3856 goto lib_parse_error;
3857 } else if (t == ')') {
3858 break;
3859 } else if (t == '-') {
3860 t = ld_next(s1, filename, sizeof(filename));
3861 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3862 ret = tcc_error_noabort("library name expected");
3863 goto lib_parse_error;
3865 pstrcpy(libname, sizeof libname, &filename[1]);
3866 if (s1->static_link) {
3867 snprintf(filename, sizeof filename, "lib%s.a", libname);
3868 } else {
3869 snprintf(filename, sizeof filename, "lib%s.so", libname);
3871 } else if (t != LD_TOK_NAME) {
3872 ret = tcc_error_noabort("filename expected");
3873 goto lib_parse_error;
3875 if (!strcmp(filename, "AS_NEEDED")) {
3876 ret = ld_add_file_list(s1, cmd, 1);
3877 if (ret)
3878 goto lib_parse_error;
3879 } else {
3880 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3881 if (!as_needed) {
3882 ret = ld_add_file(s1, filename);
3883 if (ret)
3884 goto lib_parse_error;
3885 if (group) {
3886 /* Add the filename *and* the libname to avoid future conversions */
3887 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3888 if (libname[0] != '\0')
3889 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3893 t = ld_next(s1, filename, sizeof(filename));
3894 if (t == ',') {
3895 t = ld_next(s1, filename, sizeof(filename));
3898 if (group && !as_needed) {
3899 while (s1->new_undef_sym) {
3900 int i;
3901 s1->new_undef_sym = 0;
3902 for (i = 0; i < nblibs; i ++)
3903 ld_add_file(s1, libs[i]);
3906 lib_parse_error:
3907 dynarray_reset(&libs, &nblibs);
3908 return ret;
3911 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3912 files */
3913 ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
3915 char cmd[64];
3916 char filename[1024];
3917 int t, ret;
3919 s1->fd = fd;
3920 s1->cc = -1;
3921 for(;;) {
3922 t = ld_next(s1, cmd, sizeof(cmd));
3923 if (t == LD_TOK_EOF)
3924 return 0;
3925 else if (t != LD_TOK_NAME)
3926 return -1;
3927 if (!strcmp(cmd, "INPUT") ||
3928 !strcmp(cmd, "GROUP")) {
3929 ret = ld_add_file_list(s1, cmd, 0);
3930 if (ret)
3931 return ret;
3932 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3933 !strcmp(cmd, "TARGET")) {
3934 /* ignore some commands */
3935 t = ld_next(s1, cmd, sizeof(cmd));
3936 if (t != '(')
3937 return tcc_error_noabort("( expected");
3938 for(;;) {
3939 t = ld_next(s1, filename, sizeof(filename));
3940 if (t == LD_TOK_EOF) {
3941 return tcc_error_noabort("unexpected end of file");
3942 } else if (t == ')') {
3943 break;
3946 } else {
3947 return -1;
3950 return 0;
3952 #endif /* !ELF_OBJ_ONLY */