riscv: Fix 73_arm.c
[tinycc.git] / tccelf.c
blob5b6737e74ddb3ec6a8582364745526abdbb5b410
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 ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
30 ST_DATA Section *common_section;
31 ST_DATA Section *cur_text_section; /* current section where function code is generated */
32 #ifdef CONFIG_TCC_ASM
33 ST_DATA Section *last_text_section; /* to handle .previous asm directive */
34 #endif
35 #ifdef CONFIG_TCC_BCHECK
36 /* bound check related sections */
37 ST_DATA Section *bounds_section; /* contains global data bound description */
38 ST_DATA Section *lbounds_section; /* contains local data bound description */
39 #endif
40 /* symbol sections */
41 ST_DATA Section *symtab_section;
42 /* debug sections */
43 ST_DATA Section *stab_section, *stabstr_section;
45 /* XXX: avoid static variable */
46 static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */
48 /* special flag to indicate that the section should not be linked to the other ones */
49 #define SHF_PRIVATE 0x80000000
50 /* section is dynsymtab_section */
51 #define SHF_DYNSYM 0x40000000
53 /* ------------------------------------------------------------------------- */
55 ST_FUNC void tccelf_new(TCCState *s)
57 /* no section zero */
58 dynarray_add(&s->sections, &s->nb_sections, NULL);
60 /* create standard sections */
61 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
62 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
63 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
64 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
65 common_section->sh_num = SHN_COMMON;
67 /* symbols are always generated for linking stage */
68 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
69 ".strtab",
70 ".hashtab", SHF_PRIVATE);
71 s->symtab = symtab_section;
73 /* private symbol table for dynamic symbols */
74 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
75 ".dynstrtab",
76 ".dynhashtab", SHF_PRIVATE);
77 get_sym_attr(s, 0, 1);
80 #ifdef CONFIG_TCC_BCHECK
81 ST_FUNC void tccelf_bounds_new(TCCState *s)
83 /* create bounds sections */
84 bounds_section = new_section(s, ".bounds",
85 SHT_PROGBITS, SHF_ALLOC);
86 lbounds_section = new_section(s, ".lbounds",
87 SHT_PROGBITS, SHF_ALLOC);
89 #endif
91 ST_FUNC void tccelf_stab_new(TCCState *s)
93 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
94 stab_section->sh_entsize = sizeof(Stab_Sym);
95 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
96 put_elf_str(stabstr_section, "");
97 stab_section->link = stabstr_section;
98 /* put first entry */
99 put_stabs("", 0, 0, 0, 0);
102 static void free_section(Section *s)
104 tcc_free(s->data);
107 ST_FUNC void tccelf_delete(TCCState *s1)
109 int i;
111 /* free all sections */
112 for(i = 1; i < s1->nb_sections; i++)
113 free_section(s1->sections[i]);
114 dynarray_reset(&s1->sections, &s1->nb_sections);
116 for(i = 0; i < s1->nb_priv_sections; i++)
117 free_section(s1->priv_sections[i]);
118 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
120 /* free any loaded DLLs */
121 #ifdef TCC_IS_NATIVE
122 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
123 DLLReference *ref = s1->loaded_dlls[i];
124 if ( ref->handle )
125 # ifdef _WIN32
126 FreeLibrary((HMODULE)ref->handle);
127 # else
128 dlclose(ref->handle);
129 # endif
131 #endif
132 /* free loaded dlls array */
133 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
134 tcc_free(s1->sym_attrs);
136 symtab_section = NULL; /* for tccrun.c:rt_printline() */
139 /* save section data state */
140 ST_FUNC void tccelf_begin_file(TCCState *s1)
142 Section *s; int i;
143 for (i = 1; i < s1->nb_sections; i++) {
144 s = s1->sections[i];
145 s->sh_offset = s->data_offset;
147 /* disable symbol hashing during compilation */
148 s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
149 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
150 s1->uw_sym = 0;
151 #endif
154 /* At the end of compilation, convert any UNDEF syms to global, and merge
155 with previously existing symbols */
156 ST_FUNC void tccelf_end_file(TCCState *s1)
158 Section *s = s1->symtab;
159 int first_sym, nb_syms, *tr, i;
161 first_sym = s->sh_offset / sizeof (ElfSym);
162 nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
163 s->data_offset = s->sh_offset;
164 s->link->data_offset = s->link->sh_offset;
165 s->hash = s->reloc, s->reloc = NULL;
166 tr = tcc_mallocz(nb_syms * sizeof *tr);
168 for (i = 0; i < nb_syms; ++i) {
169 ElfSym *sym = (ElfSym*)s->data + first_sym + i;
170 if (sym->st_shndx == SHN_UNDEF
171 && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
172 sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
173 tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
174 sym->st_other, sym->st_shndx, (char*)s->link->data + sym->st_name);
176 /* now update relocations */
177 for (i = 1; i < s1->nb_sections; i++) {
178 Section *sr = s1->sections[i];
179 if (sr->sh_type == SHT_RELX && sr->link == s) {
180 ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
181 ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
182 for (; rel < rel_end; ++rel) {
183 int n = ELFW(R_SYM)(rel->r_info) - first_sym;
184 //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
185 rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
189 tcc_free(tr);
192 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
194 Section *sec;
196 sec = tcc_mallocz(sizeof(Section) + strlen(name));
197 strcpy(sec->name, name);
198 sec->sh_type = sh_type;
199 sec->sh_flags = sh_flags;
200 switch(sh_type) {
201 case SHT_HASH:
202 case SHT_REL:
203 case SHT_RELA:
204 case SHT_DYNSYM:
205 case SHT_SYMTAB:
206 case SHT_DYNAMIC:
207 sec->sh_addralign = 4;
208 break;
209 case SHT_STRTAB:
210 sec->sh_addralign = 1;
211 break;
212 default:
213 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default alignment */
214 break;
217 if (sh_flags & SHF_PRIVATE) {
218 dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
219 } else {
220 sec->sh_num = s1->nb_sections;
221 dynarray_add(&s1->sections, &s1->nb_sections, sec);
224 return sec;
227 ST_FUNC Section *new_symtab(TCCState *s1,
228 const char *symtab_name, int sh_type, int sh_flags,
229 const char *strtab_name,
230 const char *hash_name, int hash_sh_flags)
232 Section *symtab, *strtab, *hash;
233 int *ptr, nb_buckets;
235 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
236 symtab->sh_entsize = sizeof(ElfW(Sym));
237 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
238 put_elf_str(strtab, "");
239 symtab->link = strtab;
240 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
242 nb_buckets = 1;
244 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
245 hash->sh_entsize = sizeof(int);
246 symtab->hash = hash;
247 hash->link = symtab;
249 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
250 ptr[0] = nb_buckets;
251 ptr[1] = 1;
252 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
253 return symtab;
256 /* realloc section and set its content to zero */
257 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
259 unsigned long size;
260 unsigned char *data;
262 size = sec->data_allocated;
263 if (size == 0)
264 size = 1;
265 while (size < new_size)
266 size = size * 2;
267 data = tcc_realloc(sec->data, size);
268 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
269 sec->data = data;
270 sec->data_allocated = size;
273 /* reserve at least 'size' bytes aligned per 'align' in section
274 'sec' from current offset, and return the aligned offset */
275 ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
277 size_t offset, offset1;
279 offset = (sec->data_offset + align - 1) & -align;
280 offset1 = offset + size;
281 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
282 section_realloc(sec, offset1);
283 sec->data_offset = offset1;
284 if (align > sec->sh_addralign)
285 sec->sh_addralign = align;
286 return offset;
289 /* reserve at least 'size' bytes in section 'sec' from
290 sec->data_offset. */
291 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
293 size_t offset = section_add(sec, size, 1);
294 return sec->data + offset;
297 /* reserve at least 'size' bytes from section start */
298 ST_FUNC void section_reserve(Section *sec, unsigned long size)
300 if (size > sec->data_allocated)
301 section_realloc(sec, size);
302 if (size > sec->data_offset)
303 sec->data_offset = size;
306 /* return a reference to a section, and create it if it does not
307 exists */
308 ST_FUNC Section *find_section(TCCState *s1, const char *name)
310 Section *sec;
311 int i;
312 for(i = 1; i < s1->nb_sections; i++) {
313 sec = s1->sections[i];
314 if (!strcmp(name, sec->name))
315 return sec;
317 /* sections are created as PROGBITS */
318 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
321 /* ------------------------------------------------------------------------- */
323 ST_FUNC int put_elf_str(Section *s, const char *sym)
325 int offset, len;
326 char *ptr;
328 len = strlen(sym) + 1;
329 offset = s->data_offset;
330 ptr = section_ptr_add(s, len);
331 memmove(ptr, sym, len);
332 return offset;
335 /* elf symbol hashing function */
336 static unsigned long elf_hash(const unsigned char *name)
338 unsigned long h = 0, g;
340 while (*name) {
341 h = (h << 4) + *name++;
342 g = h & 0xf0000000;
343 if (g)
344 h ^= g >> 24;
345 h &= ~g;
347 return h;
350 /* rebuild hash table of section s */
351 /* NOTE: we do factorize the hash table code to go faster */
352 static void rebuild_hash(Section *s, unsigned int nb_buckets)
354 ElfW(Sym) *sym;
355 int *ptr, *hash, nb_syms, sym_index, h;
356 unsigned char *strtab;
358 strtab = s->link->data;
359 nb_syms = s->data_offset / sizeof(ElfW(Sym));
361 if (!nb_buckets)
362 nb_buckets = ((int*)s->hash->data)[0];
364 s->hash->data_offset = 0;
365 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
366 ptr[0] = nb_buckets;
367 ptr[1] = nb_syms;
368 ptr += 2;
369 hash = ptr;
370 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
371 ptr += nb_buckets + 1;
373 sym = (ElfW(Sym) *)s->data + 1;
374 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
375 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
376 h = elf_hash(strtab + sym->st_name) % nb_buckets;
377 *ptr = hash[h];
378 hash[h] = sym_index;
379 } else {
380 *ptr = 0;
382 ptr++;
383 sym++;
387 /* return the symbol number */
388 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
389 int info, int other, int shndx, const char *name)
391 int name_offset, sym_index;
392 int nbuckets, h;
393 ElfW(Sym) *sym;
394 Section *hs;
396 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
397 if (name && name[0])
398 name_offset = put_elf_str(s->link, name);
399 else
400 name_offset = 0;
401 /* XXX: endianness */
402 sym->st_name = name_offset;
403 sym->st_value = value;
404 sym->st_size = size;
405 sym->st_info = info;
406 sym->st_other = other;
407 sym->st_shndx = shndx;
408 sym_index = sym - (ElfW(Sym) *)s->data;
409 hs = s->hash;
410 if (hs) {
411 int *ptr, *base;
412 ptr = section_ptr_add(hs, sizeof(int));
413 base = (int *)hs->data;
414 /* only add global or weak symbols. */
415 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
416 /* add another hashing entry */
417 nbuckets = base[0];
418 h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
419 *ptr = base[2 + h];
420 base[2 + h] = sym_index;
421 base[1]++;
422 /* we resize the hash table */
423 hs->nb_hashed_syms++;
424 if (hs->nb_hashed_syms > 2 * nbuckets) {
425 rebuild_hash(s, 2 * nbuckets);
427 } else {
428 *ptr = 0;
429 base[1]++;
432 return sym_index;
435 ST_FUNC int find_elf_sym(Section *s, const char *name)
437 ElfW(Sym) *sym;
438 Section *hs;
439 int nbuckets, sym_index, h;
440 const char *name1;
442 hs = s->hash;
443 if (!hs)
444 return 0;
445 nbuckets = ((int *)hs->data)[0];
446 h = elf_hash((unsigned char *) name) % nbuckets;
447 sym_index = ((int *)hs->data)[2 + h];
448 while (sym_index != 0) {
449 sym = &((ElfW(Sym) *)s->data)[sym_index];
450 name1 = (char *) s->link->data + sym->st_name;
451 if (!strcmp(name, name1))
452 return sym_index;
453 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
455 return 0;
458 /* return elf symbol value, signal error if 'err' is nonzero */
459 ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err)
461 int sym_index;
462 ElfW(Sym) *sym;
464 sym_index = find_elf_sym(s->symtab, name);
465 sym = &((ElfW(Sym) *)s->symtab->data)[sym_index];
466 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
467 if (err)
468 tcc_error("%s not defined", name);
469 return 0;
471 return sym->st_value;
474 /* return elf symbol value */
475 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
477 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0);
480 #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
481 /* return elf symbol value or error */
482 ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
484 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1);
486 #endif
488 /* add an elf symbol : check if it is already defined and patch
489 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
490 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
491 int info, int other, int shndx, const char *name)
493 ElfW(Sym) *esym;
494 int sym_bind, sym_index, sym_type, esym_bind;
495 unsigned char sym_vis, esym_vis, new_vis;
497 sym_bind = ELFW(ST_BIND)(info);
498 sym_type = ELFW(ST_TYPE)(info);
499 sym_vis = ELFW(ST_VISIBILITY)(other);
501 if (sym_bind != STB_LOCAL) {
502 /* we search global or weak symbols */
503 sym_index = find_elf_sym(s, name);
504 if (!sym_index)
505 goto do_def;
506 esym = &((ElfW(Sym) *)s->data)[sym_index];
507 if (esym->st_value == value && esym->st_size == size && esym->st_info == info
508 && esym->st_other == other && esym->st_shndx == shndx)
509 return sym_index;
510 if (esym->st_shndx != SHN_UNDEF) {
511 esym_bind = ELFW(ST_BIND)(esym->st_info);
512 /* propagate the most constraining visibility */
513 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
514 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
515 if (esym_vis == STV_DEFAULT) {
516 new_vis = sym_vis;
517 } else if (sym_vis == STV_DEFAULT) {
518 new_vis = esym_vis;
519 } else {
520 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
522 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
523 | new_vis;
524 other = esym->st_other; /* in case we have to patch esym */
525 if (shndx == SHN_UNDEF) {
526 /* ignore adding of undefined symbol if the
527 corresponding symbol is already defined */
528 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
529 /* global overrides weak, so patch */
530 goto do_patch;
531 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
532 /* weak is ignored if already global */
533 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
534 /* keep first-found weak definition, ignore subsequents */
535 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
536 /* ignore hidden symbols after */
537 } else if ((esym->st_shndx == SHN_COMMON
538 || esym->st_shndx == bss_section->sh_num)
539 && (shndx < SHN_LORESERVE
540 && shndx != bss_section->sh_num)) {
541 /* data symbol gets precedence over common/bss */
542 goto do_patch;
543 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
544 /* data symbol keeps precedence over common/bss */
545 } else if (s->sh_flags & SHF_DYNSYM) {
546 /* we accept that two DLL define the same symbol */
547 } else if (esym->st_other & ST_ASM_SET) {
548 /* If the existing symbol came from an asm .set
549 we can override. */
550 goto do_patch;
551 } else {
552 #if 0
553 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
554 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
555 #endif
556 tcc_error_noabort("'%s' defined twice", name);
558 } else {
559 do_patch:
560 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
561 esym->st_shndx = shndx;
562 new_undef_sym = 1;
563 esym->st_value = value;
564 esym->st_size = size;
565 esym->st_other = other;
567 } else {
568 do_def:
569 sym_index = put_elf_sym(s, value, size,
570 ELFW(ST_INFO)(sym_bind, sym_type), other,
571 shndx, name);
573 return sym_index;
576 /* put relocation */
577 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
578 int type, int symbol, addr_t addend)
580 char buf[256];
581 Section *sr;
582 ElfW_Rel *rel;
584 sr = s->reloc;
585 if (!sr) {
586 /* if no relocation section, create it */
587 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
588 /* if the symtab is allocated, then we consider the relocation
589 are also */
590 sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
591 sr->sh_entsize = sizeof(ElfW_Rel);
592 sr->link = symtab;
593 sr->sh_info = s->sh_num;
594 s->reloc = sr;
596 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
597 rel->r_offset = offset;
598 rel->r_info = ELFW(R_INFO)(symbol, type);
599 #if SHT_RELX == SHT_RELA
600 rel->r_addend = addend;
601 #else
602 if (addend)
603 tcc_error("non-zero addend on REL architecture");
604 #endif
607 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
608 int type, int symbol)
610 put_elf_reloca(symtab, s, offset, type, symbol, 0);
613 /* Remove relocations for section S->reloc starting at oldrelocoffset
614 that are to the same place, retaining the last of them. As side effect
615 the relocations are sorted. Possibly reduces the number of relocs. */
616 ST_FUNC void squeeze_multi_relocs(Section *s, size_t oldrelocoffset)
618 Section *sr = s->reloc;
619 ElfW_Rel *r, *dest;
620 ssize_t a;
621 ElfW(Addr) addr;
623 if (oldrelocoffset + sizeof(*r) >= sr->data_offset)
624 return;
625 /* The relocs we're dealing with are the result of initializer parsing.
626 So they will be mostly in order and there aren't many of them.
627 Secondly we need a stable sort (which qsort isn't). We use
628 a simple insertion sort. */
629 for (a = oldrelocoffset + sizeof(*r); a < sr->data_offset; a += sizeof(*r)) {
630 ssize_t i = a - sizeof(*r);
631 addr = ((ElfW_Rel*)(sr->data + a))->r_offset;
632 for (; i >= (ssize_t)oldrelocoffset &&
633 ((ElfW_Rel*)(sr->data + i))->r_offset > addr; i -= sizeof(*r)) {
634 ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a);
635 *(ElfW_Rel*)(sr->data + a) = *(ElfW_Rel*)(sr->data + i);
636 *(ElfW_Rel*)(sr->data + i) = tmp;
640 r = (ElfW_Rel*)(sr->data + oldrelocoffset);
641 dest = r;
642 for (; r < (ElfW_Rel*)(sr->data + sr->data_offset); r++) {
643 if (dest->r_offset != r->r_offset)
644 dest++;
645 *dest = *r;
647 sr->data_offset = (unsigned char*)dest - sr->data + sizeof(*r);
650 /* put stab debug information */
652 ST_FUNC void put_stabs(const char *str, int type, int other, int desc,
653 unsigned long value)
655 Stab_Sym *sym;
657 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
658 if (str) {
659 sym->n_strx = put_elf_str(stabstr_section, str);
660 } else {
661 sym->n_strx = 0;
663 sym->n_type = type;
664 sym->n_other = other;
665 sym->n_desc = desc;
666 sym->n_value = value;
669 ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc,
670 unsigned long value, Section *sec, int sym_index)
672 put_stabs(str, type, other, desc, value);
673 put_elf_reloc(symtab_section, stab_section,
674 stab_section->data_offset - sizeof(unsigned int),
675 R_DATA_32, sym_index);
678 ST_FUNC void put_stabn(int type, int other, int desc, int value)
680 put_stabs(NULL, type, other, desc, value);
683 ST_FUNC void put_stabd(int type, int other, int desc)
685 put_stabs(NULL, type, other, desc, 0);
688 ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
690 int n;
691 struct sym_attr *tab;
693 if (index >= s1->nb_sym_attrs) {
694 if (!alloc)
695 return s1->sym_attrs;
696 /* find immediately bigger power of 2 and reallocate array */
697 n = 1;
698 while (index >= n)
699 n *= 2;
700 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
701 s1->sym_attrs = tab;
702 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
703 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
704 s1->nb_sym_attrs = n;
706 return &s1->sym_attrs[index];
709 /* Browse each elem of type <type> in section <sec> starting at elem <startoff>
710 using variable <elem> */
711 #define for_each_elem(sec, startoff, elem, type) \
712 for (elem = (type *) sec->data + startoff; \
713 elem < (type *) (sec->data + sec->data_offset); elem++)
715 /* In an ELF file symbol table, the local symbols must appear below
716 the global and weak ones. Since TCC cannot sort it while generating
717 the code, we must do it after. All the relocation tables are also
718 modified to take into account the symbol table sorting */
719 static void sort_syms(TCCState *s1, Section *s)
721 int *old_to_new_syms;
722 ElfW(Sym) *new_syms;
723 int nb_syms, i;
724 ElfW(Sym) *p, *q;
725 ElfW_Rel *rel;
726 Section *sr;
727 int type, sym_index;
729 nb_syms = s->data_offset / sizeof(ElfW(Sym));
730 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
731 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
733 /* first pass for local symbols */
734 p = (ElfW(Sym) *)s->data;
735 q = new_syms;
736 for(i = 0; i < nb_syms; i++) {
737 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
738 old_to_new_syms[i] = q - new_syms;
739 *q++ = *p;
741 p++;
743 /* save the number of local symbols in section header */
744 if( s->sh_size ) /* this 'if' makes IDA happy */
745 s->sh_info = q - new_syms;
747 /* then second pass for non local symbols */
748 p = (ElfW(Sym) *)s->data;
749 for(i = 0; i < nb_syms; i++) {
750 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
751 old_to_new_syms[i] = q - new_syms;
752 *q++ = *p;
754 p++;
757 /* we copy the new symbols to the old */
758 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
759 tcc_free(new_syms);
761 /* now we modify all the relocations */
762 for(i = 1; i < s1->nb_sections; i++) {
763 sr = s1->sections[i];
764 if (sr->sh_type == SHT_RELX && sr->link == s) {
765 for_each_elem(sr, 0, rel, ElfW_Rel) {
766 sym_index = ELFW(R_SYM)(rel->r_info);
767 type = ELFW(R_TYPE)(rel->r_info);
768 sym_index = old_to_new_syms[sym_index];
769 rel->r_info = ELFW(R_INFO)(sym_index, type);
774 tcc_free(old_to_new_syms);
777 /* relocate symbol table, resolve undefined symbols if do_resolve is
778 true and output error if undefined symbol. */
779 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
781 ElfW(Sym) *sym;
782 int sym_bind, sh_num;
783 const char *name;
785 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
786 sh_num = sym->st_shndx;
787 if (sh_num == SHN_UNDEF) {
788 name = (char *) s1->symtab->link->data + sym->st_name;
789 /* Use ld.so to resolve symbol for us (for tcc -run) */
790 if (do_resolve) {
791 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
792 void *addr = dlsym(RTLD_DEFAULT, name);
793 if (addr) {
794 sym->st_value = (addr_t) addr;
795 #ifdef DEBUG_RELOC
796 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
797 #endif
798 goto found;
800 #endif
801 /* if dynamic symbol exist, it will be used in relocate_section */
802 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
803 goto found;
804 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
805 it */
806 if (!strcmp(name, "_fp_hw"))
807 goto found;
808 /* only weak symbols are accepted to be undefined. Their
809 value is zero */
810 sym_bind = ELFW(ST_BIND)(sym->st_info);
811 if (sym_bind == STB_WEAK)
812 sym->st_value = 0;
813 else
814 tcc_error_noabort("undefined symbol '%s'", name);
815 } else if (sh_num < SHN_LORESERVE) {
816 /* add section base */
817 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
819 found: ;
823 /* relocate a given section (CPU dependent) by applying the relocations
824 in the associated relocation section */
825 ST_FUNC void relocate_section(TCCState *s1, Section *s)
827 Section *sr = s->reloc;
828 ElfW_Rel *rel;
829 ElfW(Sym) *sym;
830 int type, sym_index;
831 unsigned char *ptr;
832 addr_t tgt, addr;
834 relocate_init(sr);
836 for_each_elem(sr, 0, rel, ElfW_Rel) {
837 ptr = s->data + rel->r_offset;
838 sym_index = ELFW(R_SYM)(rel->r_info);
839 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
840 type = ELFW(R_TYPE)(rel->r_info);
841 tgt = sym->st_value;
842 #if SHT_RELX == SHT_RELA
843 tgt += rel->r_addend;
844 #endif
845 addr = s->sh_addr + rel->r_offset;
846 relocate(s1, rel, type, ptr, addr, tgt);
848 /* if the relocation is allocated, we change its symbol table */
849 if (sr->sh_flags & SHF_ALLOC)
850 sr->link = s1->dynsym;
853 /* relocate relocation table in 'sr' */
854 static void relocate_rel(TCCState *s1, Section *sr)
856 Section *s;
857 ElfW_Rel *rel;
859 s = s1->sections[sr->sh_info];
860 for_each_elem(sr, 0, rel, ElfW_Rel)
861 rel->r_offset += s->sh_addr;
864 /* count the number of dynamic relocations so that we can reserve
865 their space */
866 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
868 int count = 0;
869 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
870 ElfW_Rel *rel;
871 for_each_elem(sr, 0, rel, ElfW_Rel) {
872 int sym_index = ELFW(R_SYM)(rel->r_info);
873 int type = ELFW(R_TYPE)(rel->r_info);
874 switch(type) {
875 #if defined(TCC_TARGET_I386)
876 case R_386_32:
877 if (!get_sym_attr(s1, sym_index, 0)->dyn_index
878 && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
879 /* don't fixup unresolved (weak) symbols */
880 rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
881 break;
883 #elif defined(TCC_TARGET_X86_64)
884 case R_X86_64_32:
885 case R_X86_64_32S:
886 case R_X86_64_64:
887 #endif
888 count++;
889 break;
890 #if defined(TCC_TARGET_I386)
891 case R_386_PC32:
892 #elif defined(TCC_TARGET_X86_64)
893 case R_X86_64_PC32:
894 #endif
895 if (get_sym_attr(s1, sym_index, 0)->dyn_index)
896 count++;
897 break;
898 default:
899 break;
902 if (count) {
903 /* allocate the section */
904 sr->sh_flags |= SHF_ALLOC;
905 sr->sh_size = count * sizeof(ElfW_Rel);
907 #endif
908 return count;
911 static void build_got(TCCState *s1)
913 /* if no got, then create it */
914 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
915 s1->got->sh_entsize = 4;
916 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
917 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
918 /* keep space for _DYNAMIC pointer and two dummy got entries */
919 section_ptr_add(s1->got, 3 * PTR_SIZE);
922 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
923 in s1->symtab. When creating the dynamic symbol table entry for the GOT
924 relocation, use 'size' and 'info' for the corresponding symbol metadata.
925 Returns the offset of the GOT or (if any) PLT entry. */
926 static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
927 int sym_index)
929 int need_plt_entry;
930 const char *name;
931 ElfW(Sym) *sym;
932 struct sym_attr *attr;
933 unsigned got_offset;
934 char plt_name[100];
935 int len;
937 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
938 attr = get_sym_attr(s1, sym_index, 1);
940 /* In case a function is both called and its address taken 2 GOT entries
941 are created, one for taking the address (GOT) and the other for the PLT
942 entry (PLTGOT). */
943 if (need_plt_entry ? attr->plt_offset : attr->got_offset)
944 return attr;
946 /* create the GOT entry */
947 got_offset = s1->got->data_offset;
948 section_ptr_add(s1->got, PTR_SIZE);
950 /* Create the GOT relocation that will insert the address of the object or
951 function of interest in the GOT entry. This is a static relocation for
952 memory output (dlsym will give us the address of symbols) and dynamic
953 relocation otherwise (executable and DLLs). The relocation should be
954 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
955 associated to a PLT entry) but is currently done at load time for an
956 unknown reason. */
958 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
959 name = (char *) symtab_section->link->data + sym->st_name;
961 if (s1->dynsym) {
962 if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
963 /* Hack alarm. We don't want to emit dynamic symbols
964 and symbol based relocs for STB_LOCAL symbols, but rather
965 want to resolve them directly. At this point the symbol
966 values aren't final yet, so we must defer this. We will later
967 have to create a RELATIVE reloc anyway, so we misuse the
968 relocation slot to smuggle the symbol reference until
969 fill_local_got_entries. Not that the sym_index is
970 relative to symtab_section, not s1->dynsym! Nevertheless
971 we use s1->dyn_sym so that if this is the first call
972 that got->reloc is correctly created. Also note that
973 RELATIVE relocs are not normally created for the .got,
974 so the types serves as a marker for later (and is retained
975 also for the final output, which is okay because then the
976 got is just normal data). */
977 put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
978 sym_index);
979 } else {
980 if (0 == attr->dyn_index)
981 attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value,
982 sym->st_size, sym->st_info, 0,
983 sym->st_shndx, name);
984 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
985 attr->dyn_index);
987 } else {
988 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
989 sym_index);
992 if (need_plt_entry) {
993 if (!s1->plt) {
994 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
995 SHF_ALLOC | SHF_EXECINSTR);
996 s1->plt->sh_entsize = 4;
999 attr->plt_offset = create_plt_entry(s1, got_offset, attr);
1001 /* create a symbol 'sym@plt' for the PLT jump vector */
1002 len = strlen(name);
1003 if (len > sizeof plt_name - 5)
1004 len = sizeof plt_name - 5;
1005 memcpy(plt_name, name, len);
1006 strcpy(plt_name + len, "@plt");
1007 attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
1008 ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
1010 } else {
1011 attr->got_offset = got_offset;
1014 return attr;
1017 /* build GOT and PLT entries */
1018 ST_FUNC void build_got_entries(TCCState *s1)
1020 Section *s;
1021 ElfW_Rel *rel;
1022 ElfW(Sym) *sym;
1023 int i, type, gotplt_entry, reloc_type, sym_index;
1024 struct sym_attr *attr;
1026 for(i = 1; i < s1->nb_sections; i++) {
1027 s = s1->sections[i];
1028 if (s->sh_type != SHT_RELX)
1029 continue;
1030 /* no need to handle got relocations */
1031 if (s->link != symtab_section)
1032 continue;
1033 for_each_elem(s, 0, rel, ElfW_Rel) {
1034 type = ELFW(R_TYPE)(rel->r_info);
1035 gotplt_entry = gotplt_entry_type(type);
1036 sym_index = ELFW(R_SYM)(rel->r_info);
1037 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1039 if (gotplt_entry == NO_GOTPLT_ENTRY) {
1040 continue;
1043 /* Automatically create PLT/GOT [entry] if it is an undefined
1044 reference (resolved at runtime), or the symbol is absolute,
1045 probably created by tcc_add_symbol, and thus on 64-bit
1046 targets might be too far from application code. */
1047 if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
1048 if (sym->st_shndx == SHN_UNDEF) {
1049 ElfW(Sym) *esym;
1050 int dynindex;
1051 if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
1052 continue;
1053 /* Relocations for UNDEF symbols would normally need
1054 to be transferred into the executable or shared object.
1055 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1056 But TCC doesn't do that (at least for exes), so we
1057 need to resolve all such relocs locally. And that
1058 means PLT slots for functions in DLLs and COPY relocs for
1059 data symbols. COPY relocs were generated in
1060 bind_exe_dynsyms (and the symbol adjusted to be defined),
1061 and for functions we were generated a dynamic symbol
1062 of function type. */
1063 if (s1->dynsym) {
1064 /* dynsym isn't set for -run :-/ */
1065 dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
1066 esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
1067 if (dynindex
1068 && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
1069 || (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
1070 && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
1071 goto jmp_slot;
1073 } else if (!(sym->st_shndx == SHN_ABS
1074 #ifndef TCC_TARGET_ARM
1075 && PTR_SIZE == 8
1076 #endif
1078 continue;
1081 #ifdef TCC_TARGET_X86_64
1082 if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
1083 sym->st_shndx != SHN_UNDEF &&
1084 (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
1085 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL ||
1086 s1->output_type == TCC_OUTPUT_EXE)) {
1087 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1088 continue;
1090 #endif
1091 if (code_reloc(type)) {
1092 jmp_slot:
1093 reloc_type = R_JMP_SLOT;
1094 } else
1095 reloc_type = R_GLOB_DAT;
1097 if (!s1->got)
1098 build_got(s1);
1100 if (gotplt_entry == BUILD_GOT_ONLY)
1101 continue;
1103 attr = put_got_entry(s1, reloc_type, sym_index);
1105 if (reloc_type == R_JMP_SLOT)
1106 rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
1111 /* put dynamic tag */
1112 static void put_dt(Section *dynamic, int dt, addr_t val)
1114 ElfW(Dyn) *dyn;
1115 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1116 dyn->d_tag = dt;
1117 dyn->d_un.d_val = val;
1120 #ifndef TCC_TARGET_PE
1121 static void add_init_array_defines(TCCState *s1, const char *section_name)
1123 Section *s;
1124 long end_offset;
1125 char sym_start[1024];
1126 char sym_end[1024];
1128 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1129 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1131 s = find_section(s1, section_name);
1132 if (!s) {
1133 end_offset = 0;
1134 s = data_section;
1135 } else {
1136 end_offset = s->data_offset;
1139 set_elf_sym(symtab_section,
1140 0, 0,
1141 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1142 s->sh_num, sym_start);
1143 set_elf_sym(symtab_section,
1144 end_offset, 0,
1145 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1146 s->sh_num, sym_end);
1149 static int tcc_add_support(TCCState *s1, const char *filename)
1151 char buf[1024];
1152 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1153 return tcc_add_file(s1, buf);
1155 #endif
1157 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1159 #ifdef CONFIG_TCC_BCHECK
1160 addr_t *ptr;
1161 int sym_index;
1163 if (0 == s1->do_bounds_check)
1164 return;
1165 /* XXX: add an object file to do that */
1166 ptr = section_ptr_add(bounds_section, sizeof(*ptr));
1167 *ptr = 0;
1168 set_elf_sym(symtab_section, 0, 0,
1169 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1170 bounds_section->sh_num, "__bounds_start");
1171 /* pull bcheck.o from libtcc1.a */
1172 sym_index = set_elf_sym(symtab_section, 0, 0,
1173 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1174 SHN_UNDEF, "__bound_init");
1175 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1176 /* add 'call __bound_init()' in .init section */
1177 Section *init_section = find_section(s1, ".init");
1178 unsigned char *pinit = section_ptr_add(init_section, 5);
1179 pinit[0] = 0xe8;
1180 write32le(pinit + 1, -4);
1181 put_elf_reloc(symtab_section, init_section,
1182 init_section->data_offset - 4, R_386_PC32, sym_index);
1183 /* R_386_PC32 = R_X86_64_PC32 = 2 */
1185 #endif
1188 /* add tcc runtime libraries */
1189 ST_FUNC void tcc_add_runtime(TCCState *s1)
1191 s1->filetype = 0;
1192 tcc_add_bcheck(s1);
1193 tcc_add_pragma_libs(s1);
1194 #ifndef TCC_TARGET_PE
1195 /* add libc */
1196 if (!s1->nostdlib) {
1197 tcc_add_library_err(s1, "c");
1198 #ifdef TCC_LIBGCC
1199 if (!s1->static_link) {
1200 if (TCC_LIBGCC[0] == '/')
1201 tcc_add_file(s1, TCC_LIBGCC);
1202 else
1203 tcc_add_dll(s1, TCC_LIBGCC, 0);
1205 #endif
1206 tcc_add_support(s1, TCC_LIBTCC1);
1207 /* add crt end if not memory output */
1208 if (s1->output_type != TCC_OUTPUT_MEMORY)
1209 tcc_add_crt(s1, "crtn.o");
1211 #endif
1214 /* add various standard linker symbols (must be done after the
1215 sections are filled (for example after allocating common
1216 symbols)) */
1217 static void tcc_add_linker_symbols(TCCState *s1)
1219 char buf[1024];
1220 int i;
1221 Section *s;
1223 set_elf_sym(symtab_section,
1224 text_section->data_offset, 0,
1225 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1226 text_section->sh_num, "_etext");
1227 set_elf_sym(symtab_section,
1228 data_section->data_offset, 0,
1229 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1230 data_section->sh_num, "_edata");
1231 set_elf_sym(symtab_section,
1232 bss_section->data_offset, 0,
1233 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1234 bss_section->sh_num, "_end");
1235 #ifdef TCC_TARGET_RISCV64
1236 /* XXX should be .sdata+0x800, not .data+0x800 */
1237 set_elf_sym(symtab_section,
1238 0x800, 0,
1239 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1240 data_section->sh_num, "__global_pointer$");
1241 #endif
1242 #ifndef TCC_TARGET_PE
1243 /* horrible new standard ldscript defines */
1244 add_init_array_defines(s1, ".preinit_array");
1245 add_init_array_defines(s1, ".init_array");
1246 add_init_array_defines(s1, ".fini_array");
1247 #endif
1249 /* add start and stop symbols for sections whose name can be
1250 expressed in C */
1251 for(i = 1; i < s1->nb_sections; i++) {
1252 s = s1->sections[i];
1253 if (s->sh_type == SHT_PROGBITS &&
1254 (s->sh_flags & SHF_ALLOC)) {
1255 const char *p;
1256 int ch;
1258 /* check if section name can be expressed in C */
1259 p = s->name;
1260 for(;;) {
1261 ch = *p;
1262 if (!ch)
1263 break;
1264 if (!isid(ch) && !isnum(ch))
1265 goto next_sec;
1266 p++;
1268 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1269 set_elf_sym(symtab_section,
1270 0, 0,
1271 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1272 s->sh_num, buf);
1273 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1274 set_elf_sym(symtab_section,
1275 s->data_offset, 0,
1276 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1277 s->sh_num, buf);
1279 next_sec: ;
1283 ST_FUNC void resolve_common_syms(TCCState *s1)
1285 ElfW(Sym) *sym;
1287 /* Allocate common symbols in BSS. */
1288 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1289 if (sym->st_shndx == SHN_COMMON) {
1290 /* symbol alignment is in st_value for SHN_COMMONs */
1291 sym->st_value = section_add(bss_section, sym->st_size,
1292 sym->st_value);
1293 sym->st_shndx = bss_section->sh_num;
1297 /* Now assign linker provided symbols their value. */
1298 tcc_add_linker_symbols(s1);
1301 static void tcc_output_binary(TCCState *s1, FILE *f,
1302 const int *sec_order)
1304 Section *s;
1305 int i, offset, size;
1307 offset = 0;
1308 for(i=1;i<s1->nb_sections;i++) {
1309 s = s1->sections[sec_order[i]];
1310 if (s->sh_type != SHT_NOBITS &&
1311 (s->sh_flags & SHF_ALLOC)) {
1312 while (offset < s->sh_offset) {
1313 fputc(0, f);
1314 offset++;
1316 size = s->sh_size;
1317 fwrite(s->data, 1, size, f);
1318 offset += size;
1323 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1325 int sym_index = ELFW(R_SYM) (rel->r_info);
1326 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1327 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1328 unsigned offset = attr->got_offset;
1330 if (0 == offset)
1331 return;
1332 section_reserve(s1->got, offset + PTR_SIZE);
1333 #ifdef TCC_TARGET_X86_64
1334 write64le(s1->got->data + offset, sym->st_value);
1335 #else
1336 write32le(s1->got->data + offset, sym->st_value);
1337 #endif
1340 /* Perform relocation to GOT or PLT entries */
1341 ST_FUNC void fill_got(TCCState *s1)
1343 Section *s;
1344 ElfW_Rel *rel;
1345 int i;
1347 for(i = 1; i < s1->nb_sections; i++) {
1348 s = s1->sections[i];
1349 if (s->sh_type != SHT_RELX)
1350 continue;
1351 /* no need to handle got relocations */
1352 if (s->link != symtab_section)
1353 continue;
1354 for_each_elem(s, 0, rel, ElfW_Rel) {
1355 switch (ELFW(R_TYPE) (rel->r_info)) {
1356 case R_X86_64_GOT32:
1357 case R_X86_64_GOTPCREL:
1358 case R_X86_64_GOTPCRELX:
1359 case R_X86_64_REX_GOTPCRELX:
1360 case R_X86_64_PLT32:
1361 fill_got_entry(s1, rel);
1362 break;
1368 /* See put_got_entry for a description. This is the second stage
1369 where GOT references to local defined symbols are rewritten. */
1370 static void fill_local_got_entries(TCCState *s1)
1372 ElfW_Rel *rel;
1373 if (!s1->got->reloc)
1374 return;
1375 for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
1376 if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
1377 int sym_index = ELFW(R_SYM) (rel->r_info);
1378 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1379 struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
1380 unsigned offset = attr->got_offset;
1381 if (offset != rel->r_offset - s1->got->sh_addr)
1382 tcc_error_noabort("huh");
1383 rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
1384 #if SHT_RELX == SHT_RELA
1385 rel->r_addend = sym->st_value;
1386 #else
1387 /* All our REL architectures also happen to be 32bit LE. */
1388 write32le(s1->got->data + offset, sym->st_value);
1389 #endif
1394 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1395 in shared libraries and export non local defined symbols to shared libraries
1396 if -rdynamic switch was given on command line */
1397 static void bind_exe_dynsyms(TCCState *s1)
1399 const char *name;
1400 int sym_index, index;
1401 ElfW(Sym) *sym, *esym;
1402 int type;
1404 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1405 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1406 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1407 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1408 if (sym->st_shndx == SHN_UNDEF) {
1409 name = (char *) symtab_section->link->data + sym->st_name;
1410 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1411 if (sym_index) {
1412 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1413 type = ELFW(ST_TYPE)(esym->st_info);
1414 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1415 /* Indirect functions shall have STT_FUNC type in executable
1416 * dynsym section. Indeed, a dlsym call following a lazy
1417 * resolution would pick the symbol value from the
1418 * executable dynsym entry which would contain the address
1419 * of the function wanted by the caller of dlsym instead of
1420 * the address of the function that would return that
1421 * address */
1422 int dynindex
1423 = put_elf_sym(s1->dynsym, 0, esym->st_size,
1424 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1425 name);
1426 int index = sym - (ElfW(Sym) *) symtab_section->data;
1427 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1428 } else if (type == STT_OBJECT) {
1429 unsigned long offset;
1430 ElfW(Sym) *dynsym;
1431 offset = bss_section->data_offset;
1432 /* XXX: which alignment ? */
1433 offset = (offset + 16 - 1) & -16;
1434 set_elf_sym (s1->symtab, offset, esym->st_size,
1435 esym->st_info, 0, bss_section->sh_num, name);
1436 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1437 esym->st_info, 0, bss_section->sh_num,
1438 name);
1440 /* Ensure R_COPY works for weak symbol aliases */
1441 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1442 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1443 if ((dynsym->st_value == esym->st_value)
1444 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1445 char *dynname = (char *) s1->dynsymtab_section->link->data
1446 + dynsym->st_name;
1447 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1448 dynsym->st_info, 0,
1449 bss_section->sh_num, dynname);
1450 break;
1455 put_elf_reloc(s1->dynsym, bss_section,
1456 offset, R_COPY, index);
1457 offset += esym->st_size;
1458 bss_section->data_offset = offset;
1460 } else {
1461 /* STB_WEAK undefined symbols are accepted */
1462 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1463 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1464 !strcmp(name, "_fp_hw")) {
1465 } else {
1466 tcc_error_noabort("undefined symbol '%s'", name);
1469 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1470 /* if -rdynamic option, then export all non local symbols */
1471 name = (char *) symtab_section->link->data + sym->st_name;
1472 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1473 0, sym->st_shndx, name);
1478 /* Bind symbols of libraries: export all non local symbols of executable that
1479 are referenced by shared libraries. The reason is that the dynamic loader
1480 search symbol first in executable and then in libraries. Therefore a
1481 reference to a symbol already defined by a library can still be resolved by
1482 a symbol in the executable. */
1483 static void bind_libs_dynsyms(TCCState *s1)
1485 const char *name;
1486 int sym_index;
1487 ElfW(Sym) *sym, *esym;
1489 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1490 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1491 sym_index = find_elf_sym(symtab_section, name);
1492 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1493 if (sym_index && sym->st_shndx != SHN_UNDEF
1494 && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1495 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1496 sym->st_info, 0, sym->st_shndx, name);
1497 } else if (esym->st_shndx == SHN_UNDEF) {
1498 /* weak symbols can stay undefined */
1499 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1500 tcc_warning("undefined dynamic symbol '%s'", name);
1505 /* Export all non local symbols. This is used by shared libraries so that the
1506 non local symbols they define can resolve a reference in another shared
1507 library or in the executable. Correspondingly, it allows undefined local
1508 symbols to be resolved by other shared libraries or by the executable. */
1509 static void export_global_syms(TCCState *s1)
1511 int dynindex, index;
1512 const char *name;
1513 ElfW(Sym) *sym;
1515 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1516 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1517 name = (char *) symtab_section->link->data + sym->st_name;
1518 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1519 sym->st_info, 0, sym->st_shndx, name);
1520 index = sym - (ElfW(Sym) *) symtab_section->data;
1521 get_sym_attr(s1, index, 1)->dyn_index = dynindex;
1526 /* Allocate strings for section names and decide if an unallocated section
1527 should be output.
1528 NOTE: the strsec section comes last, so its size is also correct ! */
1529 static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1531 int i;
1532 Section *s;
1533 int textrel = 0;
1535 /* Allocate strings for section names */
1536 for(i = 1; i < s1->nb_sections; i++) {
1537 s = s1->sections[i];
1538 /* when generating a DLL, we include relocations but we may
1539 patch them */
1540 if (file_type == TCC_OUTPUT_DLL &&
1541 s->sh_type == SHT_RELX &&
1542 !(s->sh_flags & SHF_ALLOC) &&
1543 (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
1544 prepare_dynamic_rel(s1, s)) {
1545 if (s1->sections[s->sh_info]->sh_flags & SHF_EXECINSTR)
1546 textrel = 1;
1547 } else if ((s1->do_debug && s->sh_type != SHT_RELX) ||
1548 file_type == TCC_OUTPUT_OBJ ||
1549 (s->sh_flags & SHF_ALLOC) ||
1550 i == (s1->nb_sections - 1)) {
1551 /* we output all sections if debug or object file */
1552 s->sh_size = s->data_offset;
1554 if (s->sh_size || (s->sh_flags & SHF_ALLOC))
1555 s->sh_name = put_elf_str(strsec, s->name);
1557 strsec->sh_size = strsec->data_offset;
1558 return textrel;
1561 /* Info to be copied in dynamic section */
1562 struct dyn_inf {
1563 Section *dynamic;
1564 Section *dynstr;
1565 unsigned long data_offset;
1566 addr_t rel_addr;
1567 addr_t rel_size;
1568 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1569 addr_t bss_addr;
1570 addr_t bss_size;
1571 #endif
1574 /* Assign sections to segments and decide how are sections laid out when loaded
1575 in memory. This function also fills corresponding program headers. */
1576 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1577 Section *interp, Section* strsec,
1578 struct dyn_inf *dyninf, int *sec_order)
1580 int i, j, k, file_type, sh_order_index, file_offset;
1581 unsigned long s_align;
1582 long long tmp;
1583 addr_t addr;
1584 ElfW(Phdr) *ph;
1585 Section *s;
1587 file_type = s1->output_type;
1588 sh_order_index = 1;
1589 file_offset = 0;
1590 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1591 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1592 s_align = ELF_PAGE_SIZE;
1593 if (s1->section_align)
1594 s_align = s1->section_align;
1596 if (phnum > 0) {
1597 if (s1->has_text_addr) {
1598 int a_offset, p_offset;
1599 addr = s1->text_addr;
1600 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1601 ELF_PAGE_SIZE */
1602 a_offset = (int) (addr & (s_align - 1));
1603 p_offset = file_offset & (s_align - 1);
1604 if (a_offset < p_offset)
1605 a_offset += s_align;
1606 file_offset += (a_offset - p_offset);
1607 } else {
1608 if (file_type == TCC_OUTPUT_DLL)
1609 addr = 0;
1610 else
1611 addr = ELF_START_ADDR;
1612 /* compute address after headers */
1613 addr += (file_offset & (s_align - 1));
1616 ph = &phdr[0];
1617 /* Leave one program headers for the program interpreter and one for
1618 the program header table itself if needed. These are done later as
1619 they require section layout to be done first. */
1620 if (interp)
1621 ph += 2;
1623 /* dynamic relocation table information, for .dynamic section */
1624 dyninf->rel_addr = dyninf->rel_size = 0;
1625 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1626 dyninf->bss_addr = dyninf->bss_size = 0;
1627 #endif
1629 for(j = 0; j < 2; j++) {
1630 ph->p_type = PT_LOAD;
1631 if (j == 0)
1632 ph->p_flags = PF_R | PF_X;
1633 else
1634 ph->p_flags = PF_R | PF_W;
1635 ph->p_align = s_align;
1637 /* Decide the layout of sections loaded in memory. This must
1638 be done before program headers are filled since they contain
1639 info about the layout. We do the following ordering: interp,
1640 symbol tables, relocations, progbits, nobits */
1641 /* XXX: do faster and simpler sorting */
1642 for(k = 0; k < 5; k++) {
1643 for(i = 1; i < s1->nb_sections; i++) {
1644 s = s1->sections[i];
1645 /* compute if section should be included */
1646 if (j == 0) {
1647 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1648 SHF_ALLOC)
1649 continue;
1650 } else {
1651 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1652 (SHF_ALLOC | SHF_WRITE))
1653 continue;
1655 if (s == interp) {
1656 if (k != 0)
1657 continue;
1658 } else if (s->sh_type == SHT_DYNSYM ||
1659 s->sh_type == SHT_STRTAB ||
1660 s->sh_type == SHT_HASH) {
1661 if (k != 1)
1662 continue;
1663 } else if (s->sh_type == SHT_RELX) {
1664 if (k != 2)
1665 continue;
1666 } else if (s->sh_type == SHT_NOBITS) {
1667 if (k != 4)
1668 continue;
1669 } else {
1670 if (k != 3)
1671 continue;
1673 sec_order[sh_order_index++] = i;
1675 /* section matches: we align it and add its size */
1676 tmp = addr;
1677 addr = (addr + s->sh_addralign - 1) &
1678 ~(s->sh_addralign - 1);
1679 file_offset += (int) ( addr - tmp );
1680 s->sh_offset = file_offset;
1681 s->sh_addr = addr;
1683 /* update program header infos */
1684 if (ph->p_offset == 0) {
1685 ph->p_offset = file_offset;
1686 ph->p_vaddr = addr;
1687 ph->p_paddr = ph->p_vaddr;
1689 /* update dynamic relocation infos */
1690 if (s->sh_type == SHT_RELX) {
1691 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1692 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1693 dyninf->rel_addr = addr;
1694 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1696 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1697 dyninf->bss_addr = addr;
1698 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1700 #else
1701 if (dyninf->rel_size == 0)
1702 dyninf->rel_addr = addr;
1703 dyninf->rel_size += s->sh_size;
1704 #endif
1706 addr += s->sh_size;
1707 if (s->sh_type != SHT_NOBITS)
1708 file_offset += s->sh_size;
1711 if (j == 0) {
1712 /* Make the first PT_LOAD segment include the program
1713 headers itself (and the ELF header as well), it'll
1714 come out with same memory use but will make various
1715 tools like binutils strip work better. */
1716 ph->p_offset &= ~(ph->p_align - 1);
1717 ph->p_vaddr &= ~(ph->p_align - 1);
1718 ph->p_paddr &= ~(ph->p_align - 1);
1720 ph->p_filesz = file_offset - ph->p_offset;
1721 ph->p_memsz = addr - ph->p_vaddr;
1722 ph++;
1723 if (j == 0) {
1724 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1725 /* if in the middle of a page, we duplicate the page in
1726 memory so that one copy is RX and the other is RW */
1727 if ((addr & (s_align - 1)) != 0)
1728 addr += s_align;
1729 } else {
1730 addr = (addr + s_align - 1) & ~(s_align - 1);
1731 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1737 /* all other sections come after */
1738 for(i = 1; i < s1->nb_sections; i++) {
1739 s = s1->sections[i];
1740 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1741 continue;
1742 sec_order[sh_order_index++] = i;
1744 file_offset = (file_offset + s->sh_addralign - 1) &
1745 ~(s->sh_addralign - 1);
1746 s->sh_offset = file_offset;
1747 if (s->sh_type != SHT_NOBITS)
1748 file_offset += s->sh_size;
1751 return file_offset;
1754 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1755 Section *dynamic)
1757 ElfW(Phdr) *ph;
1759 /* if interpreter, then add corresponding program header */
1760 if (interp) {
1761 ph = &phdr[0];
1763 ph->p_type = PT_PHDR;
1764 ph->p_offset = sizeof(ElfW(Ehdr));
1765 ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
1766 ph->p_vaddr = interp->sh_addr - ph->p_filesz;
1767 ph->p_paddr = ph->p_vaddr;
1768 ph->p_flags = PF_R | PF_X;
1769 ph->p_align = 4; /* interp->sh_addralign; */
1770 ph++;
1772 ph->p_type = PT_INTERP;
1773 ph->p_offset = interp->sh_offset;
1774 ph->p_vaddr = interp->sh_addr;
1775 ph->p_paddr = ph->p_vaddr;
1776 ph->p_filesz = interp->sh_size;
1777 ph->p_memsz = interp->sh_size;
1778 ph->p_flags = PF_R;
1779 ph->p_align = interp->sh_addralign;
1782 /* if dynamic section, then add corresponding program header */
1783 if (dynamic) {
1784 ph = &phdr[phnum - 1];
1786 ph->p_type = PT_DYNAMIC;
1787 ph->p_offset = dynamic->sh_offset;
1788 ph->p_vaddr = dynamic->sh_addr;
1789 ph->p_paddr = ph->p_vaddr;
1790 ph->p_filesz = dynamic->sh_size;
1791 ph->p_memsz = dynamic->sh_size;
1792 ph->p_flags = PF_R | PF_W;
1793 ph->p_align = dynamic->sh_addralign;
1797 /* Fill the dynamic section with tags describing the address and size of
1798 sections */
1799 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
1801 Section *dynamic = dyninf->dynamic;
1803 /* put dynamic section entries */
1804 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1805 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
1806 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1807 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
1808 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1809 #if PTR_SIZE == 8
1810 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
1811 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
1812 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
1813 #else
1814 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1815 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
1816 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
1817 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
1818 put_dt(dynamic, DT_PLTREL, DT_REL);
1819 put_dt(dynamic, DT_REL, dyninf->bss_addr);
1820 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
1821 #else
1822 put_dt(dynamic, DT_REL, dyninf->rel_addr);
1823 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
1824 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1825 #endif
1826 #endif
1827 if (s1->do_debug)
1828 put_dt(dynamic, DT_DEBUG, 0);
1829 put_dt(dynamic, DT_NULL, 0);
1832 /* Relocate remaining sections and symbols (that is those not related to
1833 dynamic linking) */
1834 static int final_sections_reloc(TCCState *s1)
1836 int i;
1837 Section *s;
1839 relocate_syms(s1, s1->symtab, 0);
1841 if (s1->nb_errors != 0)
1842 return -1;
1844 /* relocate sections */
1845 /* XXX: ignore sections with allocated relocations ? */
1846 for(i = 1; i < s1->nb_sections; i++) {
1847 s = s1->sections[i];
1848 if (s->reloc && (s != s1->got || s1->static_link))
1849 relocate_section(s1, s);
1852 /* relocate relocation entries if the relocation tables are
1853 allocated in the executable */
1854 for(i = 1; i < s1->nb_sections; i++) {
1855 s = s1->sections[i];
1856 if ((s->sh_flags & SHF_ALLOC) &&
1857 s->sh_type == SHT_RELX) {
1858 relocate_rel(s1, s);
1861 return 0;
1864 /* Create an ELF file on disk.
1865 This function handle ELF specific layout requirements */
1866 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
1867 int file_offset, int *sec_order)
1869 int i, shnum, offset, size, file_type;
1870 Section *s;
1871 ElfW(Ehdr) ehdr;
1872 ElfW(Shdr) shdr, *sh;
1874 file_type = s1->output_type;
1875 shnum = s1->nb_sections;
1877 memset(&ehdr, 0, sizeof(ehdr));
1879 if (phnum > 0) {
1880 ehdr.e_phentsize = sizeof(ElfW(Phdr));
1881 ehdr.e_phnum = phnum;
1882 ehdr.e_phoff = sizeof(ElfW(Ehdr));
1885 /* align to 4 */
1886 file_offset = (file_offset + 3) & -4;
1888 /* fill header */
1889 ehdr.e_ident[0] = ELFMAG0;
1890 ehdr.e_ident[1] = ELFMAG1;
1891 ehdr.e_ident[2] = ELFMAG2;
1892 ehdr.e_ident[3] = ELFMAG3;
1893 ehdr.e_ident[4] = ELFCLASSW;
1894 ehdr.e_ident[5] = ELFDATA2LSB;
1895 ehdr.e_ident[6] = EV_CURRENT;
1896 #if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
1897 /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
1898 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1899 #endif
1900 #ifdef TCC_TARGET_ARM
1901 #ifdef TCC_ARM_EABI
1902 ehdr.e_ident[EI_OSABI] = 0;
1903 ehdr.e_flags = EF_ARM_EABI_VER4;
1904 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
1905 ehdr.e_flags |= EF_ARM_HASENTRY;
1906 if (s1->float_abi == ARM_HARD_FLOAT)
1907 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
1908 else
1909 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
1910 #else
1911 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1912 #endif
1913 #elif defined TCC_TARGET_RISCV64
1914 ehdr.e_flags = EF_RISCV_FLOAT_ABI_DOUBLE;
1915 #endif
1916 switch(file_type) {
1917 default:
1918 case TCC_OUTPUT_EXE:
1919 ehdr.e_type = ET_EXEC;
1920 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
1921 break;
1922 case TCC_OUTPUT_DLL:
1923 ehdr.e_type = ET_DYN;
1924 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1925 break;
1926 case TCC_OUTPUT_OBJ:
1927 ehdr.e_type = ET_REL;
1928 break;
1930 ehdr.e_machine = EM_TCC_TARGET;
1931 ehdr.e_version = EV_CURRENT;
1932 ehdr.e_shoff = file_offset;
1933 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
1934 ehdr.e_shentsize = sizeof(ElfW(Shdr));
1935 ehdr.e_shnum = shnum;
1936 ehdr.e_shstrndx = shnum - 1;
1938 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
1939 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
1940 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1942 sort_syms(s1, symtab_section);
1943 for(i = 1; i < s1->nb_sections; i++) {
1944 s = s1->sections[sec_order[i]];
1945 if (s->sh_type != SHT_NOBITS) {
1946 while (offset < s->sh_offset) {
1947 fputc(0, f);
1948 offset++;
1950 size = s->sh_size;
1951 if (size)
1952 fwrite(s->data, 1, size, f);
1953 offset += size;
1957 /* output section headers */
1958 while (offset < ehdr.e_shoff) {
1959 fputc(0, f);
1960 offset++;
1963 for(i = 0; i < s1->nb_sections; i++) {
1964 sh = &shdr;
1965 memset(sh, 0, sizeof(ElfW(Shdr)));
1966 s = s1->sections[i];
1967 if (s) {
1968 sh->sh_name = s->sh_name;
1969 sh->sh_type = s->sh_type;
1970 sh->sh_flags = s->sh_flags;
1971 sh->sh_entsize = s->sh_entsize;
1972 sh->sh_info = s->sh_info;
1973 if (s->link)
1974 sh->sh_link = s->link->sh_num;
1975 sh->sh_addralign = s->sh_addralign;
1976 sh->sh_addr = s->sh_addr;
1977 sh->sh_offset = s->sh_offset;
1978 sh->sh_size = s->sh_size;
1980 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
1984 /* Write an elf, coff or "binary" file */
1985 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
1986 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
1988 int fd, mode, file_type;
1989 FILE *f;
1991 file_type = s1->output_type;
1992 if (file_type == TCC_OUTPUT_OBJ)
1993 mode = 0666;
1994 else
1995 mode = 0777;
1996 unlink(filename);
1997 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1998 if (fd < 0) {
1999 tcc_error_noabort("could not write '%s'", filename);
2000 return -1;
2002 f = fdopen(fd, "wb");
2003 if (s1->verbose)
2004 printf("<- %s\n", filename);
2006 #ifdef TCC_TARGET_COFF
2007 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2008 tcc_output_coff(s1, f);
2009 else
2010 #endif
2011 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2012 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2013 else
2014 tcc_output_binary(s1, f, sec_order);
2015 fclose(f);
2017 return 0;
2020 /* Sort section headers by assigned sh_addr, remove sections
2021 that we aren't going to output. */
2022 static void tidy_section_headers(TCCState *s1, int *sec_order)
2024 int i, nnew, l, *backmap;
2025 Section **snew, *s;
2026 ElfW(Sym) *sym;
2028 snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
2029 backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
2030 for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
2031 s = s1->sections[sec_order[i]];
2032 if (!i || s->sh_name) {
2033 backmap[sec_order[i]] = nnew;
2034 snew[nnew] = s;
2035 ++nnew;
2036 } else {
2037 backmap[sec_order[i]] = 0;
2038 snew[--l] = s;
2041 for (i = 0; i < nnew; i++) {
2042 s = snew[i];
2043 if (s) {
2044 s->sh_num = i;
2045 if (s->sh_type == SHT_RELX)
2046 s->sh_info = backmap[s->sh_info];
2050 for_each_elem(symtab_section, 1, sym, ElfW(Sym))
2051 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2052 sym->st_shndx = backmap[sym->st_shndx];
2053 if( !s1->static_link ) {
2054 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
2055 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
2056 sym->st_shndx = backmap[sym->st_shndx];
2058 for (i = 0; i < s1->nb_sections; i++)
2059 sec_order[i] = i;
2060 tcc_free(s1->sections);
2061 s1->sections = snew;
2062 s1->nb_sections = nnew;
2063 tcc_free(backmap);
2066 /* Output an elf, coff or binary file */
2067 /* XXX: suppress unneeded sections */
2068 static int elf_output_file(TCCState *s1, const char *filename)
2070 int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
2071 struct dyn_inf dyninf = {0};
2072 ElfW(Phdr) *phdr;
2073 ElfW(Sym) *sym;
2074 Section *strsec, *interp, *dynamic, *dynstr;
2075 int textrel;
2077 file_type = s1->output_type;
2078 s1->nb_errors = 0;
2079 ret = -1;
2080 phdr = NULL;
2081 sec_order = NULL;
2082 interp = dynamic = dynstr = NULL; /* avoid warning */
2083 textrel = 0;
2085 if (file_type != TCC_OUTPUT_OBJ) {
2086 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2087 tcc_add_runtime(s1);
2088 resolve_common_syms(s1);
2090 if (!s1->static_link) {
2091 if (file_type == TCC_OUTPUT_EXE) {
2092 char *ptr;
2093 /* allow override the dynamic loader */
2094 const char *elfint = getenv("LD_SO");
2095 if (elfint == NULL)
2096 elfint = DEFAULT_ELFINTERP(s1);
2097 /* add interpreter section only if executable */
2098 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2099 interp->sh_addralign = 1;
2100 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2101 strcpy(ptr, elfint);
2104 /* add dynamic symbol table */
2105 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2106 ".dynstr",
2107 ".hash", SHF_ALLOC);
2108 dynstr = s1->dynsym->link;
2110 /* add dynamic section */
2111 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2112 SHF_ALLOC | SHF_WRITE);
2113 dynamic->link = dynstr;
2114 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2116 build_got(s1);
2118 if (file_type == TCC_OUTPUT_EXE) {
2119 bind_exe_dynsyms(s1);
2120 if (s1->nb_errors)
2121 goto the_end;
2122 bind_libs_dynsyms(s1);
2123 } else {
2124 /* shared library case: simply export all global symbols */
2125 export_global_syms(s1);
2128 build_got_entries(s1);
2131 /* we add a section for symbols */
2132 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2133 put_elf_str(strsec, "");
2135 /* Allocate strings for section names */
2136 textrel = alloc_sec_names(s1, file_type, strsec);
2138 if (dynamic) {
2139 /* add a list of needed dlls */
2140 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2141 DLLReference *dllref = s1->loaded_dlls[i];
2142 if (dllref->level == 0)
2143 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2146 if (s1->rpath)
2147 put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
2148 put_elf_str(dynstr, s1->rpath));
2150 if (file_type == TCC_OUTPUT_DLL) {
2151 if (s1->soname)
2152 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2153 /* XXX: currently, since we do not handle PIC code, we
2154 must relocate the readonly segments */
2155 if (textrel)
2156 put_dt(dynamic, DT_TEXTREL, 0);
2159 if (s1->symbolic)
2160 put_dt(dynamic, DT_SYMBOLIC, 0);
2162 dyninf.dynamic = dynamic;
2163 dyninf.dynstr = dynstr;
2164 /* remember offset and reserve space for 2nd call below */
2165 dyninf.data_offset = dynamic->data_offset;
2166 fill_dynamic(s1, &dyninf);
2167 dynamic->sh_size = dynamic->data_offset;
2168 dynstr->sh_size = dynstr->data_offset;
2171 /* compute number of program headers */
2172 if (file_type == TCC_OUTPUT_OBJ)
2173 phnum = 0;
2174 else if (file_type == TCC_OUTPUT_DLL)
2175 phnum = 3;
2176 else if (s1->static_link)
2177 phnum = 2;
2178 else
2179 phnum = 5;
2181 /* allocate program segment headers */
2182 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2184 /* compute number of sections */
2185 shnum = s1->nb_sections;
2187 /* this array is used to reorder sections in the output file */
2188 sec_order = tcc_malloc(sizeof(int) * shnum);
2189 sec_order[0] = 0;
2191 /* compute section to program header mapping */
2192 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2193 sec_order);
2195 /* Fill remaining program header and finalize relocation related to dynamic
2196 linking. */
2197 if (file_type != TCC_OUTPUT_OBJ) {
2198 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2199 if (dynamic) {
2200 dynamic->data_offset = dyninf.data_offset;
2201 fill_dynamic(s1, &dyninf);
2203 /* put in GOT the dynamic section address and relocate PLT */
2204 write32le(s1->got->data, dynamic->sh_addr);
2205 if (file_type == TCC_OUTPUT_EXE
2206 || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
2207 relocate_plt(s1);
2209 /* relocate symbols in .dynsym now that final addresses are known */
2210 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2211 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
2212 /* do symbol relocation */
2213 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2218 /* if building executable or DLL, then relocate each section
2219 except the GOT which is already relocated */
2220 ret = final_sections_reloc(s1);
2221 if (ret)
2222 goto the_end;
2223 tidy_section_headers(s1, sec_order);
2225 /* Perform relocation to GOT or PLT entries */
2226 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2227 fill_got(s1);
2228 else if (s1->got)
2229 fill_local_got_entries(s1);
2232 /* Create the ELF file with name 'filename' */
2233 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2234 s1->nb_sections = shnum;
2235 the_end:
2236 tcc_free(sec_order);
2237 tcc_free(phdr);
2238 return ret;
2241 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2243 int ret;
2244 #ifdef TCC_TARGET_PE
2245 if (s->output_type != TCC_OUTPUT_OBJ) {
2246 ret = pe_output_file(s, filename);
2247 } else
2248 #endif
2249 ret = elf_output_file(s, filename);
2250 return ret;
2253 ssize_t full_read(int fd, void *buf, size_t count) {
2254 char *cbuf = buf;
2255 size_t rnum = 0;
2256 while (1) {
2257 ssize_t num = read(fd, cbuf, count-rnum);
2258 if (num < 0) return num;
2259 if (num == 0) return rnum;
2260 rnum += num;
2261 cbuf += num;
2265 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2267 void *data;
2269 data = tcc_malloc(size);
2270 lseek(fd, file_offset, SEEK_SET);
2271 full_read(fd, data, size);
2272 return data;
2275 typedef struct SectionMergeInfo {
2276 Section *s; /* corresponding existing section */
2277 unsigned long offset; /* offset of the new section in the existing section */
2278 uint8_t new_section; /* true if section 's' was added */
2279 uint8_t link_once; /* true if link once section */
2280 } SectionMergeInfo;
2282 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2284 int size = full_read(fd, h, sizeof *h);
2285 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2286 if (h->e_type == ET_REL)
2287 return AFF_BINTYPE_REL;
2288 if (h->e_type == ET_DYN)
2289 return AFF_BINTYPE_DYN;
2290 } else if (size >= 8) {
2291 if (0 == memcmp(h, ARMAG, 8))
2292 return AFF_BINTYPE_AR;
2293 #ifdef TCC_TARGET_COFF
2294 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2295 return AFF_BINTYPE_C67;
2296 #endif
2298 return 0;
2301 /* load an object file and merge it with current files */
2302 /* XXX: handle correctly stab (debug) info */
2303 ST_FUNC int tcc_load_object_file(TCCState *s1,
2304 int fd, unsigned long file_offset)
2306 ElfW(Ehdr) ehdr;
2307 ElfW(Shdr) *shdr, *sh;
2308 int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
2309 char *strsec, *strtab;
2310 int *old_to_new_syms;
2311 char *sh_name, *name;
2312 SectionMergeInfo *sm_table, *sm;
2313 ElfW(Sym) *sym, *symtab;
2314 ElfW_Rel *rel;
2315 Section *s;
2317 int stab_index;
2318 int stabstr_index;
2320 stab_index = stabstr_index = 0;
2322 lseek(fd, file_offset, SEEK_SET);
2323 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2324 goto fail1;
2325 /* test CPU specific stuff */
2326 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2327 ehdr.e_machine != EM_TCC_TARGET) {
2328 fail1:
2329 tcc_error_noabort("invalid object file");
2330 return -1;
2332 /* read sections */
2333 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2334 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2335 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2337 /* load section names */
2338 sh = &shdr[ehdr.e_shstrndx];
2339 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2341 /* load symtab and strtab */
2342 old_to_new_syms = NULL;
2343 symtab = NULL;
2344 strtab = NULL;
2345 nb_syms = 0;
2346 seencompressed = 0;
2347 for(i = 1; i < ehdr.e_shnum; i++) {
2348 sh = &shdr[i];
2349 if (sh->sh_type == SHT_SYMTAB) {
2350 if (symtab) {
2351 tcc_error_noabort("object must contain only one symtab");
2352 fail:
2353 ret = -1;
2354 goto the_end;
2356 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2357 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2358 sm_table[i].s = symtab_section;
2360 /* now load strtab */
2361 sh = &shdr[sh->sh_link];
2362 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2364 if (sh->sh_flags & SHF_COMPRESSED)
2365 seencompressed = 1;
2368 /* now examine each section and try to merge its content with the
2369 ones in memory */
2370 for(i = 1; i < ehdr.e_shnum; i++) {
2371 /* no need to examine section name strtab */
2372 if (i == ehdr.e_shstrndx)
2373 continue;
2374 sh = &shdr[i];
2375 if (sh->sh_type == SHT_RELX)
2376 sh = &shdr[sh->sh_info];
2377 /* ignore sections types we do not handle (plus relocs to those) */
2378 if (sh->sh_type != SHT_PROGBITS &&
2379 #ifdef TCC_ARM_EABI
2380 sh->sh_type != SHT_ARM_EXIDX &&
2381 #endif
2382 sh->sh_type != SHT_NOBITS &&
2383 sh->sh_type != SHT_PREINIT_ARRAY &&
2384 sh->sh_type != SHT_INIT_ARRAY &&
2385 sh->sh_type != SHT_FINI_ARRAY &&
2386 strcmp(strsec + sh->sh_name, ".stabstr")
2388 continue;
2389 if (seencompressed
2390 && !strncmp(strsec + sh->sh_name, ".debug_", sizeof(".debug_")-1))
2391 continue;
2393 sh = &shdr[i];
2394 sh_name = strsec + sh->sh_name;
2395 if (sh->sh_addralign < 1)
2396 sh->sh_addralign = 1;
2397 /* find corresponding section, if any */
2398 for(j = 1; j < s1->nb_sections;j++) {
2399 s = s1->sections[j];
2400 if (!strcmp(s->name, sh_name)) {
2401 if (!strncmp(sh_name, ".gnu.linkonce",
2402 sizeof(".gnu.linkonce") - 1)) {
2403 /* if a 'linkonce' section is already present, we
2404 do not add it again. It is a little tricky as
2405 symbols can still be defined in
2406 it. */
2407 sm_table[i].link_once = 1;
2408 goto next;
2409 } else {
2410 goto found;
2414 /* not found: create new section */
2415 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2416 /* take as much info as possible from the section. sh_link and
2417 sh_info will be updated later */
2418 s->sh_addralign = sh->sh_addralign;
2419 s->sh_entsize = sh->sh_entsize;
2420 sm_table[i].new_section = 1;
2421 found:
2422 if (sh->sh_type != s->sh_type) {
2423 tcc_error_noabort("invalid section type");
2424 goto fail;
2427 /* align start of section */
2428 offset = s->data_offset;
2430 if (0 == strcmp(sh_name, ".stab")) {
2431 stab_index = i;
2432 goto no_align;
2434 if (0 == strcmp(sh_name, ".stabstr")) {
2435 stabstr_index = i;
2436 goto no_align;
2439 size = sh->sh_addralign - 1;
2440 offset = (offset + size) & ~size;
2441 if (sh->sh_addralign > s->sh_addralign)
2442 s->sh_addralign = sh->sh_addralign;
2443 s->data_offset = offset;
2444 no_align:
2445 sm_table[i].offset = offset;
2446 sm_table[i].s = s;
2447 /* concatenate sections */
2448 size = sh->sh_size;
2449 if (sh->sh_type != SHT_NOBITS) {
2450 unsigned char *ptr;
2451 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2452 ptr = section_ptr_add(s, size);
2453 full_read(fd, ptr, size);
2454 } else {
2455 s->data_offset += size;
2457 next: ;
2460 /* gr relocate stab strings */
2461 if (stab_index && stabstr_index) {
2462 Stab_Sym *a, *b;
2463 unsigned o;
2464 s = sm_table[stab_index].s;
2465 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2466 b = (Stab_Sym *)(s->data + s->data_offset);
2467 o = sm_table[stabstr_index].offset;
2468 while (a < b) {
2469 if (a->n_strx)
2470 a->n_strx += o;
2471 a++;
2475 /* second short pass to update sh_link and sh_info fields of new
2476 sections */
2477 for(i = 1; i < ehdr.e_shnum; i++) {
2478 s = sm_table[i].s;
2479 if (!s || !sm_table[i].new_section)
2480 continue;
2481 sh = &shdr[i];
2482 if (sh->sh_link > 0)
2483 s->link = sm_table[sh->sh_link].s;
2484 if (sh->sh_type == SHT_RELX) {
2485 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2486 /* update backward link */
2487 s1->sections[s->sh_info]->reloc = s;
2490 sm = sm_table;
2492 /* resolve symbols */
2493 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2495 sym = symtab + 1;
2496 for(i = 1; i < nb_syms; i++, sym++) {
2497 if (sym->st_shndx != SHN_UNDEF &&
2498 sym->st_shndx < SHN_LORESERVE) {
2499 sm = &sm_table[sym->st_shndx];
2500 if (sm->link_once) {
2501 /* if a symbol is in a link once section, we use the
2502 already defined symbol. It is very important to get
2503 correct relocations */
2504 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2505 name = strtab + sym->st_name;
2506 sym_index = find_elf_sym(symtab_section, name);
2507 if (sym_index)
2508 old_to_new_syms[i] = sym_index;
2510 continue;
2512 /* if no corresponding section added, no need to add symbol */
2513 if (!sm->s)
2514 continue;
2515 /* convert section number */
2516 sym->st_shndx = sm->s->sh_num;
2517 /* offset value */
2518 sym->st_value += sm->offset;
2520 /* add symbol */
2521 name = strtab + sym->st_name;
2522 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2523 sym->st_info, sym->st_other,
2524 sym->st_shndx, name);
2525 old_to_new_syms[i] = sym_index;
2528 /* third pass to patch relocation entries */
2529 for(i = 1; i < ehdr.e_shnum; i++) {
2530 s = sm_table[i].s;
2531 if (!s)
2532 continue;
2533 sh = &shdr[i];
2534 offset = sm_table[i].offset;
2535 switch(s->sh_type) {
2536 case SHT_RELX:
2537 /* take relocation offset information */
2538 offseti = sm_table[sh->sh_info].offset;
2539 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2540 int type;
2541 unsigned sym_index;
2542 /* convert symbol index */
2543 type = ELFW(R_TYPE)(rel->r_info);
2544 sym_index = ELFW(R_SYM)(rel->r_info);
2545 /* NOTE: only one symtab assumed */
2546 if (sym_index >= nb_syms)
2547 goto invalid_reloc;
2548 sym_index = old_to_new_syms[sym_index];
2549 /* ignore link_once in rel section. */
2550 if (!sym_index && !sm->link_once
2551 #ifdef TCC_TARGET_ARM
2552 && type != R_ARM_V4BX
2553 #elif defined TCC_TARGET_RISCV64
2554 && type != R_RISCV_ALIGN
2555 && type != R_RISCV_RELAX
2556 #endif
2558 invalid_reloc:
2559 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2560 i, strsec + sh->sh_name, rel->r_offset);
2561 goto fail;
2563 rel->r_info = ELFW(R_INFO)(sym_index, type);
2564 /* offset the relocation offset */
2565 rel->r_offset += offseti;
2566 #ifdef TCC_TARGET_ARM
2567 /* Jumps and branches from a Thumb code to a PLT entry need
2568 special handling since PLT entries are ARM code.
2569 Unconditional bl instructions referencing PLT entries are
2570 handled by converting these instructions into blx
2571 instructions. Other case of instructions referencing a PLT
2572 entry require to add a Thumb stub before the PLT entry to
2573 switch to ARM mode. We set bit plt_thumb_stub of the
2574 attribute of a symbol to indicate such a case. */
2575 if (type == R_ARM_THM_JUMP24)
2576 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2577 #endif
2579 break;
2580 default:
2581 break;
2585 ret = 0;
2586 the_end:
2587 tcc_free(symtab);
2588 tcc_free(strtab);
2589 tcc_free(old_to_new_syms);
2590 tcc_free(sm_table);
2591 tcc_free(strsec);
2592 tcc_free(shdr);
2593 return ret;
2596 typedef struct ArchiveHeader {
2597 char ar_name[16]; /* name of this member */
2598 char ar_date[12]; /* file mtime */
2599 char ar_uid[6]; /* owner uid; printed as decimal */
2600 char ar_gid[6]; /* owner gid; printed as decimal */
2601 char ar_mode[8]; /* file mode, printed as octal */
2602 char ar_size[10]; /* file size, printed as decimal */
2603 char ar_fmag[2]; /* should contain ARFMAG */
2604 } ArchiveHeader;
2606 static int get_be32(const uint8_t *b)
2608 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2611 static long get_be64(const uint8_t *b)
2613 long long ret = get_be32(b);
2614 ret = (ret << 32) | (unsigned)get_be32(b+4);
2615 return (long)ret;
2618 /* load only the objects which resolve undefined symbols */
2619 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2621 long i, bound, nsyms, sym_index, off, ret;
2622 uint8_t *data;
2623 const char *ar_names, *p;
2624 const uint8_t *ar_index;
2625 ElfW(Sym) *sym;
2627 data = tcc_malloc(size);
2628 if (full_read(fd, data, size) != size)
2629 goto fail;
2630 nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
2631 ar_index = data + entrysize;
2632 ar_names = (char *) ar_index + nsyms * entrysize;
2634 do {
2635 bound = 0;
2636 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2637 sym_index = find_elf_sym(symtab_section, p);
2638 if(sym_index) {
2639 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2640 if(sym->st_shndx == SHN_UNDEF) {
2641 off = (entrysize == 4
2642 ? get_be32(ar_index + i * 4)
2643 : get_be64(ar_index + i * 8))
2644 + sizeof(ArchiveHeader);
2645 ++bound;
2646 if(tcc_load_object_file(s1, fd, off) < 0) {
2647 fail:
2648 ret = -1;
2649 goto the_end;
2654 } while(bound);
2655 ret = 0;
2656 the_end:
2657 tcc_free(data);
2658 return ret;
2661 /* load a '.a' file */
2662 ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte)
2664 ArchiveHeader hdr;
2665 char ar_size[11];
2666 char ar_name[17];
2667 char magic[8];
2668 int size, len, i;
2669 unsigned long file_offset;
2671 /* skip magic which was already checked */
2672 full_read(fd, magic, sizeof(magic));
2674 for(;;) {
2675 len = full_read(fd, &hdr, sizeof(hdr));
2676 if (len == 0)
2677 break;
2678 if (len != sizeof(hdr)) {
2679 tcc_error_noabort("invalid archive");
2680 return -1;
2682 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2683 ar_size[sizeof(hdr.ar_size)] = '\0';
2684 size = strtol(ar_size, NULL, 0);
2685 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2686 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2687 if (ar_name[i] != ' ')
2688 break;
2690 ar_name[i + 1] = '\0';
2691 file_offset = lseek(fd, 0, SEEK_CUR);
2692 /* align to even */
2693 size = (size + 1) & ~1;
2694 if (!strcmp(ar_name, "/")) {
2695 /* coff symbol table : we handle it */
2696 if (alacarte)
2697 return tcc_load_alacarte(s1, fd, size, 4);
2698 } else if (!strcmp(ar_name, "/SYM64/")) {
2699 if (alacarte)
2700 return tcc_load_alacarte(s1, fd, size, 8);
2701 } else {
2702 ElfW(Ehdr) ehdr;
2703 if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2704 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2705 return -1;
2708 lseek(fd, file_offset + size, SEEK_SET);
2710 return 0;
2713 #ifndef TCC_TARGET_PE
2714 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2715 is referenced by the user (so it should be added as DT_NEEDED in
2716 the generated ELF file) */
2717 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2719 ElfW(Ehdr) ehdr;
2720 ElfW(Shdr) *shdr, *sh, *sh1;
2721 int i, j, nb_syms, nb_dts, sym_bind, ret;
2722 ElfW(Sym) *sym, *dynsym;
2723 ElfW(Dyn) *dt, *dynamic;
2724 unsigned char *dynstr;
2725 const char *name, *soname;
2726 DLLReference *dllref;
2728 full_read(fd, &ehdr, sizeof(ehdr));
2730 /* test CPU specific stuff */
2731 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2732 ehdr.e_machine != EM_TCC_TARGET) {
2733 tcc_error_noabort("bad architecture");
2734 return -1;
2737 /* read sections */
2738 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2740 /* load dynamic section and dynamic symbols */
2741 nb_syms = 0;
2742 nb_dts = 0;
2743 dynamic = NULL;
2744 dynsym = NULL; /* avoid warning */
2745 dynstr = NULL; /* avoid warning */
2746 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2747 switch(sh->sh_type) {
2748 case SHT_DYNAMIC:
2749 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2750 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2751 break;
2752 case SHT_DYNSYM:
2753 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2754 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2755 sh1 = &shdr[sh->sh_link];
2756 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2757 break;
2758 default:
2759 break;
2763 /* compute the real library name */
2764 soname = tcc_basename(filename);
2766 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2767 if (dt->d_tag == DT_SONAME) {
2768 soname = (char *) dynstr + dt->d_un.d_val;
2772 /* if the dll is already loaded, do not load it */
2773 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2774 dllref = s1->loaded_dlls[i];
2775 if (!strcmp(soname, dllref->name)) {
2776 /* but update level if needed */
2777 if (level < dllref->level)
2778 dllref->level = level;
2779 ret = 0;
2780 goto the_end;
2784 /* add the dll and its level */
2785 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2786 dllref->level = level;
2787 strcpy(dllref->name, soname);
2788 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2790 /* add dynamic symbols in dynsym_section */
2791 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2792 sym_bind = ELFW(ST_BIND)(sym->st_info);
2793 if (sym_bind == STB_LOCAL)
2794 continue;
2795 name = (char *) dynstr + sym->st_name;
2796 set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2797 sym->st_info, sym->st_other, sym->st_shndx, name);
2800 /* load all referenced DLLs */
2801 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2802 switch(dt->d_tag) {
2803 case DT_NEEDED:
2804 name = (char *) dynstr + dt->d_un.d_val;
2805 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2806 dllref = s1->loaded_dlls[j];
2807 if (!strcmp(name, dllref->name))
2808 goto already_loaded;
2810 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2811 tcc_error_noabort("referenced dll '%s' not found", name);
2812 ret = -1;
2813 goto the_end;
2815 already_loaded:
2816 break;
2819 ret = 0;
2820 the_end:
2821 tcc_free(dynstr);
2822 tcc_free(dynsym);
2823 tcc_free(dynamic);
2824 tcc_free(shdr);
2825 return ret;
2828 #define LD_TOK_NAME 256
2829 #define LD_TOK_EOF (-1)
2831 /* return next ld script token */
2832 static int ld_next(TCCState *s1, char *name, int name_size)
2834 int c;
2835 char *q;
2837 redo:
2838 switch(ch) {
2839 case ' ':
2840 case '\t':
2841 case '\f':
2842 case '\v':
2843 case '\r':
2844 case '\n':
2845 inp();
2846 goto redo;
2847 case '/':
2848 minp();
2849 if (ch == '*') {
2850 file->buf_ptr = parse_comment(file->buf_ptr);
2851 ch = file->buf_ptr[0];
2852 goto redo;
2853 } else {
2854 q = name;
2855 *q++ = '/';
2856 goto parse_name;
2858 break;
2859 case '\\':
2860 ch = handle_eob();
2861 if (ch != '\\')
2862 goto redo;
2863 /* fall through */
2864 /* case 'a' ... 'z': */
2865 case 'a':
2866 case 'b':
2867 case 'c':
2868 case 'd':
2869 case 'e':
2870 case 'f':
2871 case 'g':
2872 case 'h':
2873 case 'i':
2874 case 'j':
2875 case 'k':
2876 case 'l':
2877 case 'm':
2878 case 'n':
2879 case 'o':
2880 case 'p':
2881 case 'q':
2882 case 'r':
2883 case 's':
2884 case 't':
2885 case 'u':
2886 case 'v':
2887 case 'w':
2888 case 'x':
2889 case 'y':
2890 case 'z':
2891 /* case 'A' ... 'z': */
2892 case 'A':
2893 case 'B':
2894 case 'C':
2895 case 'D':
2896 case 'E':
2897 case 'F':
2898 case 'G':
2899 case 'H':
2900 case 'I':
2901 case 'J':
2902 case 'K':
2903 case 'L':
2904 case 'M':
2905 case 'N':
2906 case 'O':
2907 case 'P':
2908 case 'Q':
2909 case 'R':
2910 case 'S':
2911 case 'T':
2912 case 'U':
2913 case 'V':
2914 case 'W':
2915 case 'X':
2916 case 'Y':
2917 case 'Z':
2918 case '_':
2919 case '.':
2920 case '$':
2921 case '~':
2922 q = name;
2923 parse_name:
2924 for(;;) {
2925 if (!((ch >= 'a' && ch <= 'z') ||
2926 (ch >= 'A' && ch <= 'Z') ||
2927 (ch >= '0' && ch <= '9') ||
2928 strchr("/.-_+=$:\\,~", ch)))
2929 break;
2930 if ((q - name) < name_size - 1) {
2931 *q++ = ch;
2933 minp();
2935 *q = '\0';
2936 c = LD_TOK_NAME;
2937 break;
2938 case CH_EOF:
2939 c = LD_TOK_EOF;
2940 break;
2941 default:
2942 c = ch;
2943 inp();
2944 break;
2946 return c;
2949 static int ld_add_file(TCCState *s1, const char filename[])
2951 if (filename[0] == '/') {
2952 if (CONFIG_SYSROOT[0] == '\0'
2953 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
2954 return 0;
2955 filename = tcc_basename(filename);
2957 return tcc_add_dll(s1, filename, 0);
2960 static inline int new_undef_syms(void)
2962 int ret = 0;
2963 ret = new_undef_sym;
2964 new_undef_sym = 0;
2965 return ret;
2968 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
2970 char filename[1024], libname[1024];
2971 int t, group, nblibs = 0, ret = 0;
2972 char **libs = NULL;
2974 group = !strcmp(cmd, "GROUP");
2975 if (!as_needed)
2976 new_undef_syms();
2977 t = ld_next(s1, filename, sizeof(filename));
2978 if (t != '(')
2979 expect("(");
2980 t = ld_next(s1, filename, sizeof(filename));
2981 for(;;) {
2982 libname[0] = '\0';
2983 if (t == LD_TOK_EOF) {
2984 tcc_error_noabort("unexpected end of file");
2985 ret = -1;
2986 goto lib_parse_error;
2987 } else if (t == ')') {
2988 break;
2989 } else if (t == '-') {
2990 t = ld_next(s1, filename, sizeof(filename));
2991 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
2992 tcc_error_noabort("library name expected");
2993 ret = -1;
2994 goto lib_parse_error;
2996 pstrcpy(libname, sizeof libname, &filename[1]);
2997 if (s1->static_link) {
2998 snprintf(filename, sizeof filename, "lib%s.a", libname);
2999 } else {
3000 snprintf(filename, sizeof filename, "lib%s.so", libname);
3002 } else if (t != LD_TOK_NAME) {
3003 tcc_error_noabort("filename expected");
3004 ret = -1;
3005 goto lib_parse_error;
3007 if (!strcmp(filename, "AS_NEEDED")) {
3008 ret = ld_add_file_list(s1, cmd, 1);
3009 if (ret)
3010 goto lib_parse_error;
3011 } else {
3012 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3013 if (!as_needed) {
3014 ret = ld_add_file(s1, filename);
3015 if (ret)
3016 goto lib_parse_error;
3017 if (group) {
3018 /* Add the filename *and* the libname to avoid future conversions */
3019 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3020 if (libname[0] != '\0')
3021 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3025 t = ld_next(s1, filename, sizeof(filename));
3026 if (t == ',') {
3027 t = ld_next(s1, filename, sizeof(filename));
3030 if (group && !as_needed) {
3031 while (new_undef_syms()) {
3032 int i;
3034 for (i = 0; i < nblibs; i ++)
3035 ld_add_file(s1, libs[i]);
3038 lib_parse_error:
3039 dynarray_reset(&libs, &nblibs);
3040 return ret;
3043 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3044 files */
3045 ST_FUNC int tcc_load_ldscript(TCCState *s1)
3047 char cmd[64];
3048 char filename[1024];
3049 int t, ret;
3051 ch = handle_eob();
3052 for(;;) {
3053 t = ld_next(s1, cmd, sizeof(cmd));
3054 if (t == LD_TOK_EOF)
3055 return 0;
3056 else if (t != LD_TOK_NAME)
3057 return -1;
3058 if (!strcmp(cmd, "INPUT") ||
3059 !strcmp(cmd, "GROUP")) {
3060 ret = ld_add_file_list(s1, cmd, 0);
3061 if (ret)
3062 return ret;
3063 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3064 !strcmp(cmd, "TARGET")) {
3065 /* ignore some commands */
3066 t = ld_next(s1, cmd, sizeof(cmd));
3067 if (t != '(')
3068 expect("(");
3069 for(;;) {
3070 t = ld_next(s1, filename, sizeof(filename));
3071 if (t == LD_TOK_EOF) {
3072 tcc_error_noabort("unexpected end of file");
3073 return -1;
3074 } else if (t == ')') {
3075 break;
3078 } else {
3079 return -1;
3082 return 0;
3084 #endif /* !TCC_TARGET_PE */