Fix relocs_info declaration in tcc.h
[tinycc.git] / tccelf.c
blob7d656e5df0c0411a68620f5359044fd39e381a54
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 *cur_text_section; /* current section where function code is generated */
31 #ifdef CONFIG_TCC_ASM
32 ST_DATA Section *last_text_section; /* to handle .previous asm directive */
33 #endif
34 #ifdef CONFIG_TCC_BCHECK
35 /* bound check related sections */
36 ST_DATA Section *bounds_section; /* contains global data bound description */
37 ST_DATA Section *lbounds_section; /* contains local data bound description */
38 #endif
39 /* symbol sections */
40 ST_DATA Section *symtab_section, *strtab_section;
41 /* debug sections */
42 ST_DATA Section *stab_section, *stabstr_section;
44 /* XXX: avoid static variable */
45 static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */
47 /* ------------------------------------------------------------------------- */
49 ST_FUNC void tccelf_new(TCCState *s)
51 /* no section zero */
52 dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
54 /* create standard sections */
55 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
56 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
57 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
59 /* symbols are always generated for linking stage */
60 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
61 ".strtab",
62 ".hashtab", SHF_PRIVATE);
63 strtab_section = symtab_section->link;
64 s->symtab = symtab_section;
66 /* private symbol table for dynamic symbols */
67 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
68 ".dynstrtab",
69 ".dynhashtab", SHF_PRIVATE);
72 #ifdef CONFIG_TCC_BCHECK
73 ST_FUNC void tccelf_bounds_new(TCCState *s)
75 /* create bounds sections */
76 bounds_section = new_section(s, ".bounds",
77 SHT_PROGBITS, SHF_ALLOC);
78 lbounds_section = new_section(s, ".lbounds",
79 SHT_PROGBITS, SHF_ALLOC);
81 #endif
83 ST_FUNC void tccelf_stab_new(TCCState *s)
85 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
86 stab_section->sh_entsize = sizeof(Stab_Sym);
87 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
88 put_elf_str(stabstr_section, "");
89 stab_section->link = stabstr_section;
90 /* put first entry */
91 put_stabs("", 0, 0, 0, 0);
94 static void free_section(Section *s)
96 tcc_free(s->data);
99 ST_FUNC void tccelf_delete(TCCState *s1)
101 int i;
103 /* free all sections */
104 for(i = 1; i < s1->nb_sections; i++)
105 free_section(s1->sections[i]);
106 dynarray_reset(&s1->sections, &s1->nb_sections);
108 for(i = 0; i < s1->nb_priv_sections; i++)
109 free_section(s1->priv_sections[i]);
110 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
112 /* free any loaded DLLs */
113 #ifdef TCC_IS_NATIVE
114 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
115 DLLReference *ref = s1->loaded_dlls[i];
116 if ( ref->handle )
117 # ifdef _WIN32
118 FreeLibrary((HMODULE)ref->handle);
119 # else
120 dlclose(ref->handle);
121 # endif
123 #endif
124 /* free loaded dlls array */
125 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
128 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
130 Section *sec;
132 sec = tcc_mallocz(sizeof(Section) + strlen(name));
133 strcpy(sec->name, name);
134 sec->sh_type = sh_type;
135 sec->sh_flags = sh_flags;
136 switch(sh_type) {
137 case SHT_HASH:
138 case SHT_REL:
139 case SHT_RELA:
140 case SHT_DYNSYM:
141 case SHT_SYMTAB:
142 case SHT_DYNAMIC:
143 sec->sh_addralign = 4;
144 break;
145 case SHT_STRTAB:
146 sec->sh_addralign = 1;
147 break;
148 default:
149 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default aligment */
150 break;
153 if (sh_flags & SHF_PRIVATE) {
154 dynarray_add((void ***)&s1->priv_sections, &s1->nb_priv_sections, sec);
155 } else {
156 sec->sh_num = s1->nb_sections;
157 dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
160 return sec;
163 /* realloc section and set its content to zero */
164 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
166 unsigned long size;
167 unsigned char *data;
169 size = sec->data_allocated;
170 if (size == 0)
171 size = 1;
172 while (size < new_size)
173 size = size * 2;
174 data = tcc_realloc(sec->data, size);
175 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
176 sec->data = data;
177 sec->data_allocated = size;
180 /* reserve at least 'size' bytes in section 'sec' from
181 sec->data_offset. */
182 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
184 size_t offset, offset1;
186 offset = sec->data_offset;
187 offset1 = offset + size;
188 if (offset1 > sec->data_allocated)
189 section_realloc(sec, offset1);
190 sec->data_offset = offset1;
191 return sec->data + offset;
194 /* reserve at least 'size' bytes from section start */
195 ST_FUNC void section_reserve(Section *sec, unsigned long size)
197 if (size > sec->data_allocated)
198 section_realloc(sec, size);
199 if (size > sec->data_offset)
200 sec->data_offset = size;
203 /* return a reference to a section, and create it if it does not
204 exists */
205 ST_FUNC Section *find_section(TCCState *s1, const char *name)
207 Section *sec;
208 int i;
209 for(i = 1; i < s1->nb_sections; i++) {
210 sec = s1->sections[i];
211 if (!strcmp(name, sec->name))
212 return sec;
214 /* sections are created as PROGBITS */
215 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
218 /* ------------------------------------------------------------------------- */
220 ST_FUNC int put_elf_str(Section *s, const char *sym)
222 int offset, len;
223 char *ptr;
225 len = strlen(sym) + 1;
226 offset = s->data_offset;
227 ptr = section_ptr_add(s, len);
228 memcpy(ptr, sym, len);
229 return offset;
232 /* elf symbol hashing function */
233 static unsigned long elf_hash(const unsigned char *name)
235 unsigned long h = 0, g;
237 while (*name) {
238 h = (h << 4) + *name++;
239 g = h & 0xf0000000;
240 if (g)
241 h ^= g >> 24;
242 h &= ~g;
244 return h;
247 /* rebuild hash table of section s */
248 /* NOTE: we do factorize the hash table code to go faster */
249 static void rebuild_hash(Section *s, unsigned int nb_buckets)
251 ElfW(Sym) *sym;
252 int *ptr, *hash, nb_syms, sym_index, h;
253 unsigned char *strtab;
255 strtab = s->link->data;
256 nb_syms = s->data_offset / sizeof(ElfW(Sym));
258 s->hash->data_offset = 0;
259 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
260 ptr[0] = nb_buckets;
261 ptr[1] = nb_syms;
262 ptr += 2;
263 hash = ptr;
264 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
265 ptr += nb_buckets + 1;
267 sym = (ElfW(Sym) *)s->data + 1;
268 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
269 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
270 h = elf_hash(strtab + sym->st_name) % nb_buckets;
271 *ptr = hash[h];
272 hash[h] = sym_index;
273 } else {
274 *ptr = 0;
276 ptr++;
277 sym++;
281 /* return the symbol number */
282 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
283 int info, int other, int shndx, const char *name)
285 int name_offset, sym_index;
286 int nbuckets, h;
287 ElfW(Sym) *sym;
288 Section *hs;
290 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
291 if (name)
292 name_offset = put_elf_str(s->link, name);
293 else
294 name_offset = 0;
295 /* XXX: endianness */
296 sym->st_name = name_offset;
297 sym->st_value = value;
298 sym->st_size = size;
299 sym->st_info = info;
300 sym->st_other = other;
301 sym->st_shndx = shndx;
302 sym_index = sym - (ElfW(Sym) *)s->data;
303 hs = s->hash;
304 if (hs) {
305 int *ptr, *base;
306 ptr = section_ptr_add(hs, sizeof(int));
307 base = (int *)hs->data;
308 /* only add global or weak symbols */
309 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
310 /* add another hashing entry */
311 nbuckets = base[0];
312 h = elf_hash((unsigned char *) name) % nbuckets;
313 *ptr = base[2 + h];
314 base[2 + h] = sym_index;
315 base[1]++;
316 /* we resize the hash table */
317 hs->nb_hashed_syms++;
318 if (hs->nb_hashed_syms > 2 * nbuckets) {
319 rebuild_hash(s, 2 * nbuckets);
321 } else {
322 *ptr = 0;
323 base[1]++;
326 return sym_index;
329 /* find global ELF symbol 'name' and return its index. Return 0 if not
330 found. */
331 ST_FUNC int find_elf_sym(Section *s, const char *name)
333 ElfW(Sym) *sym;
334 Section *hs;
335 int nbuckets, sym_index, h;
336 const char *name1;
338 hs = s->hash;
339 if (!hs)
340 return 0;
341 nbuckets = ((int *)hs->data)[0];
342 h = elf_hash((unsigned char *) name) % nbuckets;
343 sym_index = ((int *)hs->data)[2 + h];
344 while (sym_index != 0) {
345 sym = &((ElfW(Sym) *)s->data)[sym_index];
346 name1 = (char *) s->link->data + sym->st_name;
347 if (!strcmp(name, name1))
348 return sym_index;
349 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
351 return 0;
354 /* return elf symbol value, signal error if 'err' is nonzero */
355 ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err)
357 int sym_index;
358 ElfW(Sym) *sym;
360 sym_index = find_elf_sym(s->symtab, name);
361 sym = &((ElfW(Sym) *)s->symtab->data)[sym_index];
362 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
363 if (err)
364 tcc_error("%s not defined", name);
365 return 0;
367 return sym->st_value;
370 /* return elf symbol value */
371 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
373 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0);
376 #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
377 /* return elf symbol value or error */
378 ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
380 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1);
382 #endif
384 /* add an elf symbol : check if it is already defined and patch
385 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
386 ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
387 int info, int other, int shndx, const char *name)
389 ElfW(Sym) *esym;
390 int sym_bind, sym_index, sym_type, esym_bind;
391 unsigned char sym_vis, esym_vis, new_vis;
393 sym_bind = ELFW(ST_BIND)(info);
394 sym_type = ELFW(ST_TYPE)(info);
395 sym_vis = ELFW(ST_VISIBILITY)(other);
397 sym_index = find_elf_sym(s, name);
398 esym = &((ElfW(Sym) *)s->data)[sym_index];
399 if (sym_index && esym->st_value == value && esym->st_size == size
400 && esym->st_info == info && esym->st_other == other
401 && esym->st_shndx == shndx)
402 return sym_index;
404 if (sym_bind != STB_LOCAL) {
405 /* we search global or weak symbols */
406 if (!sym_index)
407 goto do_def;
408 if (esym->st_shndx != SHN_UNDEF) {
409 esym_bind = ELFW(ST_BIND)(esym->st_info);
410 /* propagate the most constraining visibility */
411 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
412 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
413 if (esym_vis == STV_DEFAULT) {
414 new_vis = sym_vis;
415 } else if (sym_vis == STV_DEFAULT) {
416 new_vis = esym_vis;
417 } else {
418 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
420 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
421 | new_vis;
422 other = esym->st_other; /* in case we have to patch esym */
423 if (shndx == SHN_UNDEF) {
424 /* ignore adding of undefined symbol if the
425 corresponding symbol is already defined */
426 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
427 /* global overrides weak, so patch */
428 goto do_patch;
429 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
430 /* weak is ignored if already global */
431 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
432 /* keep first-found weak definition, ignore subsequents */
433 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
434 /* ignore hidden symbols after */
435 } else if ((esym->st_shndx == SHN_COMMON
436 || esym->st_shndx == bss_section->sh_num)
437 && (shndx < SHN_LORESERVE
438 && shndx != bss_section->sh_num)) {
439 /* data symbol gets precedence over common/bss */
440 goto do_patch;
441 } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
442 /* data symbol keeps precedence over common/bss */
443 } else if (s == tcc_state->dynsymtab_section) {
444 /* we accept that two DLL define the same symbol */
445 } else {
446 #if 0
447 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
448 sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
449 #endif
450 tcc_error_noabort("'%s' defined twice", name);
452 } else {
453 do_patch:
454 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
455 esym->st_shndx = shndx;
456 new_undef_sym = 1;
457 esym->st_value = value;
458 esym->st_size = size;
459 esym->st_other = other;
461 } else {
462 do_def:
463 sym_index = put_elf_sym(s, value, size,
464 ELFW(ST_INFO)(sym_bind, sym_type), other,
465 shndx, name);
467 return sym_index;
470 /* put relocation */
471 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
472 int type, int symbol, addr_t addend)
474 char buf[256];
475 Section *sr;
476 ElfW_Rel *rel;
478 sr = s->reloc;
479 if (!sr) {
480 /* if no relocation section, create it */
481 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
482 /* if the symtab is allocated, then we consider the relocation
483 are also */
484 sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
485 sr->sh_entsize = sizeof(ElfW_Rel);
486 sr->link = symtab;
487 sr->sh_info = s->sh_num;
488 s->reloc = sr;
490 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
491 rel->r_offset = offset;
492 rel->r_info = ELFW(R_INFO)(symbol, type);
493 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
494 rel->r_addend = addend;
495 #else
496 if (addend)
497 tcc_error("non-zero addend on REL architecture");
498 #endif
501 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
502 int type, int symbol)
504 put_elf_reloca(symtab, s, offset, type, symbol, 0);
507 /* put stab debug information */
509 ST_FUNC void put_stabs(const char *str, int type, int other, int desc,
510 unsigned long value)
512 Stab_Sym *sym;
514 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
515 if (str) {
516 sym->n_strx = put_elf_str(stabstr_section, str);
517 } else {
518 sym->n_strx = 0;
520 sym->n_type = type;
521 sym->n_other = other;
522 sym->n_desc = desc;
523 sym->n_value = value;
526 ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc,
527 unsigned long value, Section *sec, int sym_index)
529 put_stabs(str, type, other, desc, value);
530 put_elf_reloc(symtab_section, stab_section,
531 stab_section->data_offset - sizeof(unsigned int),
532 R_DATA_32, sym_index);
535 ST_FUNC void put_stabn(int type, int other, int desc, int value)
537 put_stabs(NULL, type, other, desc, value);
540 ST_FUNC void put_stabd(int type, int other, int desc)
542 put_stabs(NULL, type, other, desc, 0);
545 static struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
547 int n;
548 struct sym_attr *tab;
550 if (index >= s1->nb_sym_attrs) {
551 if (!alloc)
552 return NULL;
553 /* find immediately bigger power of 2 and reallocate array */
554 n = 1;
555 while (index >= n)
556 n *= 2;
557 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
558 s1->sym_attrs = tab;
559 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
560 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
561 s1->nb_sym_attrs = n;
563 return &s1->sym_attrs[index];
566 /* Browse each elem of type <type> in section <sec> starting at elem <startoff>
567 using variable <elem> */
568 #define for_each_elem(sec, startoff, elem, type) \
569 for (elem = (type *) sec->data + startoff; \
570 elem < (type *) (sec->data + sec->data_offset); elem++)
572 /* In an ELF file symbol table, the local symbols must appear below
573 the global and weak ones. Since TCC cannot sort it while generating
574 the code, we must do it after. All the relocation tables are also
575 modified to take into account the symbol table sorting */
576 static void sort_syms(TCCState *s1, Section *s)
578 int *old_to_new_syms;
579 ElfW(Sym) *new_syms;
580 int nb_syms, i;
581 ElfW(Sym) *p, *q;
582 ElfW_Rel *rel;
583 Section *sr;
584 int type, sym_index;
586 nb_syms = s->data_offset / sizeof(ElfW(Sym));
587 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
588 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
590 /* first pass for local symbols */
591 p = (ElfW(Sym) *)s->data;
592 q = new_syms;
593 for(i = 0; i < nb_syms; i++) {
594 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
595 old_to_new_syms[i] = q - new_syms;
596 *q++ = *p;
598 p++;
600 /* save the number of local symbols in section header */
601 s->sh_info = q - new_syms;
603 /* then second pass for non local symbols */
604 p = (ElfW(Sym) *)s->data;
605 for(i = 0; i < nb_syms; i++) {
606 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
607 old_to_new_syms[i] = q - new_syms;
608 *q++ = *p;
610 p++;
613 /* we copy the new symbols to the old */
614 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
615 tcc_free(new_syms);
617 /* now we modify all the relocations */
618 for(i = 1; i < s1->nb_sections; i++) {
619 sr = s1->sections[i];
620 if (sr->sh_type == SHT_RELX && sr->link == s) {
621 for_each_elem(sr, 0, rel, ElfW_Rel) {
622 sym_index = ELFW(R_SYM)(rel->r_info);
623 type = ELFW(R_TYPE)(rel->r_info);
624 sym_index = old_to_new_syms[sym_index];
625 rel->r_info = ELFW(R_INFO)(sym_index, type);
630 tcc_free(old_to_new_syms);
633 /* relocate common symbols in the .bss section */
634 ST_FUNC void relocate_common_syms(void)
636 ElfW(Sym) *sym;
637 unsigned long offset, align;
639 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
640 if (sym->st_shndx == SHN_COMMON) {
641 /* align symbol */
642 align = sym->st_value;
643 offset = bss_section->data_offset;
644 offset = (offset + align - 1) & -align;
645 sym->st_value = offset;
646 sym->st_shndx = bss_section->sh_num;
647 offset += sym->st_size;
648 bss_section->data_offset = offset;
653 /* relocate symbol table, resolve undefined symbols if do_resolve is
654 true and output error if undefined symbol. */
655 ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
657 ElfW(Sym) *sym;
658 int sym_bind, sh_num;
659 const char *name;
661 for_each_elem(symtab, 1, sym, ElfW(Sym)) {
662 sh_num = sym->st_shndx;
663 if (sh_num == SHN_UNDEF) {
664 name = (char *) strtab_section->data + sym->st_name;
665 /* Use ld.so to resolve symbol for us (for tcc -run) */
666 if (do_resolve) {
667 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
668 void *addr = dlsym(RTLD_DEFAULT, name);
669 if (addr) {
670 sym->st_value = (addr_t) addr;
671 #ifdef DEBUG_RELOC
672 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
673 #endif
674 goto found;
676 #endif
677 /* if dynamic symbol exist, it will be used in relocate_section */
678 } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
679 goto found;
680 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
681 it */
682 if (!strcmp(name, "_fp_hw"))
683 goto found;
684 /* only weak symbols are accepted to be undefined. Their
685 value is zero */
686 sym_bind = ELFW(ST_BIND)(sym->st_info);
687 if (sym_bind == STB_WEAK)
688 sym->st_value = 0;
689 else
690 tcc_error_noabort("undefined symbol '%s'", name);
691 } else if (sh_num < SHN_LORESERVE) {
692 /* add section base */
693 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
695 found: ;
699 /* relocate a given section (CPU dependent) by applying the relocations
700 in the associated relocation section */
701 ST_FUNC void relocate_section(TCCState *s1, Section *s)
703 Section *sr = s->reloc;
704 ElfW_Rel *rel;
705 ElfW(Sym) *sym;
706 int type, sym_index;
707 unsigned char *ptr;
708 addr_t tgt, addr;
709 struct sym_attr *symattr;
711 relocate_init(sr);
712 for_each_elem(sr, 0, rel, ElfW_Rel) {
713 ptr = s->data + rel->r_offset;
715 sym_index = ELFW(R_SYM)(rel->r_info);
716 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
717 type = ELFW(R_TYPE)(rel->r_info);
718 symattr = get_sym_attr(s1, sym_index, 0);
719 tgt = sym->st_value;
720 /* If static relocation to a dynamic symbol, relocate to PLT entry.
721 Note 1: in tcc -run mode we go through PLT to avoid range issues
722 Note 2: symbols compiled with libtcc and later added with
723 tcc_add_symbol are not dynamic and thus have symattr NULL */
724 if (relocs_info[type].gotplt_entry != NO_GOTPLT_ENTRY &&
725 relocs_info[type].code_reloc && symattr && symattr->plt_offset)
726 tgt = s1->plt->sh_addr + symattr->plt_offset;
727 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
728 tgt += rel->r_addend;
729 #endif
730 addr = s->sh_addr + rel->r_offset;
732 relocate(s1, rel, type, ptr, addr, tgt);
734 /* if the relocation is allocated, we change its symbol table */
735 if (sr->sh_flags & SHF_ALLOC)
736 sr->link = s1->dynsym;
739 /* relocate relocation table in 'sr' */
740 static void relocate_rel(TCCState *s1, Section *sr)
742 Section *s;
743 ElfW_Rel *rel;
745 s = s1->sections[sr->sh_info];
746 for_each_elem(sr, 0, rel, ElfW_Rel)
747 rel->r_offset += s->sh_addr;
750 /* count the number of dynamic relocations so that we can reserve
751 their space */
752 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
754 ElfW_Rel *rel;
755 int sym_index, esym_index, type, count;
757 count = 0;
758 for_each_elem(sr, 0, rel, ElfW_Rel) {
759 sym_index = ELFW(R_SYM)(rel->r_info);
760 type = ELFW(R_TYPE)(rel->r_info);
761 switch(type) {
762 #if defined(TCC_TARGET_I386)
763 case R_386_32:
764 #elif defined(TCC_TARGET_X86_64)
765 case R_X86_64_32:
766 case R_X86_64_32S:
767 case R_X86_64_64:
768 #endif
769 count++;
770 break;
771 #if defined(TCC_TARGET_I386)
772 case R_386_PC32:
773 #elif defined(TCC_TARGET_X86_64)
774 case R_X86_64_PC32:
775 #endif
776 esym_index = s1->symtab_to_dynsym[sym_index];
777 if (esym_index)
778 count++;
779 break;
780 default:
781 break;
784 if (count) {
785 /* allocate the section */
786 sr->sh_flags |= SHF_ALLOC;
787 sr->sh_size = count * sizeof(ElfW_Rel);
789 return count;
792 static void build_got(TCCState *s1)
794 unsigned char *ptr;
796 /* if no got, then create it */
797 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
798 s1->got->sh_entsize = 4;
799 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
800 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
801 ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
802 #if PTR_SIZE == 4
803 /* keep space for _DYNAMIC pointer, if present */
804 write32le(ptr, 0);
805 /* two dummy got entries */
806 write32le(ptr + 4, 0);
807 write32le(ptr + 8, 0);
808 #else
809 /* keep space for _DYNAMIC pointer, if present */
810 write32le(ptr, 0);
811 write32le(ptr + 4, 0);
812 /* two dummy got entries */
813 write32le(ptr + 8, 0);
814 write32le(ptr + 12, 0);
815 write32le(ptr + 16, 0);
816 write32le(ptr + 20, 0);
817 #endif
820 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
821 in s1->symtab. When creating the dynamic symbol table entry for the GOT
822 relocation, use 'size' and 'info' for the corresponding symbol metadata.
823 Returns the offset of the GOT or (if any) PLT entry. */
824 static unsigned long put_got_entry(TCCState *s1, int dyn_reloc_type,
825 int reloc_type, unsigned long size,
826 int info, int sym_index)
828 int index, need_plt_entry = 0;
829 const char *name;
830 ElfW(Sym) *sym, *esym;
831 unsigned long offset;
832 int *ptr;
833 size_t got_offset;
834 struct sym_attr *symattr;
836 need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
838 if (!s1->got)
839 build_got(s1);
841 /* create PLT if needed */
842 if (need_plt_entry && !s1->plt) {
843 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
844 SHF_ALLOC | SHF_EXECINSTR);
845 s1->plt->sh_entsize = 4;
848 /* already a GOT and/or PLT entry, no need to add one */
849 if (sym_index < s1->nb_sym_attrs) {
850 if (need_plt_entry && s1->sym_attrs[sym_index].plt_offset)
851 return s1->sym_attrs[sym_index].plt_offset;
852 else if (!need_plt_entry && s1->sym_attrs[sym_index].got_offset)
853 return s1->sym_attrs[sym_index].got_offset;
856 symattr = get_sym_attr(s1, sym_index, 1);
858 /* create the GOT entry */
859 ptr = section_ptr_add(s1->got, PTR_SIZE);
860 *ptr = 0;
861 got_offset = OFFSET_FROM_SECTION_START (s1->got, ptr);
863 /* In case a function is both called and its address taken 2 GOT entries
864 are created, one for taking the address (GOT) and the other for the PLT
865 entry (PLTGOT). We don't record the offset of the PLTGOT entry in the
866 got_offset field since it might overwrite the offset of a GOT entry.
867 Besides, for PLT entry the static relocation is against the PLT entry
868 and the dynamic relocation for PLTGOT is created in this function. */
869 if (!need_plt_entry)
870 symattr->got_offset = got_offset;
872 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
873 name = (char *) symtab_section->link->data + sym->st_name;
874 offset = sym->st_value;
876 /* create PLT entry */
877 if (need_plt_entry) {
878 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
879 Section *plt;
880 uint8_t *p;
881 int modrm;
882 unsigned long relofs;
884 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
885 modrm = 0x25;
886 #else
887 /* if we build a DLL, we add a %ebx offset */
888 if (s1->output_type == TCC_OUTPUT_DLL)
889 modrm = 0xa3;
890 else
891 modrm = 0x25;
892 #endif
894 plt = s1->plt;
895 /* empty PLT: create PLT0 entry that pushes the library indentifier
896 (GOT + PTR_SIZE) and jumps to ld.so resolution routine
897 (GOT + 2 * PTR_SIZE) */
898 if (plt->data_offset == 0) {
899 p = section_ptr_add(plt, 16);
900 p[0] = 0xff; /* pushl got + PTR_SIZE */
901 p[1] = modrm + 0x10;
902 write32le(p + 2, PTR_SIZE);
903 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
904 p[7] = modrm;
905 write32le(p + 8, PTR_SIZE * 2);
908 /* The PLT slot refers to the relocation entry it needs via offset.
909 The reloc entry is created below, so its offset is the current
910 data_offset */
911 relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
912 symattr->plt_offset = plt->data_offset;
914 /* Jump to GOT entry where ld.so initially put the address of ip + 4 */
915 p = section_ptr_add(plt, 16);
916 p[0] = 0xff; /* jmp *(got + x) */
917 p[1] = modrm;
918 write32le(p + 2, got_offset);
919 p[6] = 0x68; /* push $xxx */
920 #ifdef TCC_TARGET_X86_64
921 /* On x86-64, the relocation is referred to by _index_ */
922 write32le(p + 7, relofs / sizeof (ElfW_Rel));
923 #else
924 write32le(p + 7, relofs);
925 #endif
926 p[11] = 0xe9; /* jmp plt_start */
927 write32le(p + 12, -(plt->data_offset));
929 /* If this was an UNDEF symbol set the offset in the dynsymtab to the
930 PLT slot, so that PC32 relocs to it can be resolved */
931 if (sym->st_shndx == SHN_UNDEF)
932 offset = plt->data_offset - 16;
933 #elif defined(TCC_TARGET_ARM)
934 Section *plt;
935 uint8_t *p;
937 /* when building a DLL, GOT entry accesses must be done relative to
938 start of GOT (see x86_64 examble above) */
939 if (s1->output_type == TCC_OUTPUT_DLL)
940 tcc_error("DLLs unimplemented!");
942 plt = s1->plt;
943 /* empty PLT: create PLT0 entry that push address of call site and
944 jump to ld.so resolution routine (GOT + 8) */
945 if (plt->data_offset == 0) {
946 p = section_ptr_add(plt, 20);
947 write32le(p, 0xe52de004); /* push {lr} */
948 write32le(p+4, 0xe59fe004); /* ldr lr, [pc, #4] */
949 write32le(p+8, 0xe08fe00e); /* add lr, pc, lr */
950 write32le(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */
951 /* p+16 is set in relocate_plt */
954 symattr->plt_offset = plt->data_offset;
955 if (symattr->plt_thumb_stub) {
956 p = section_ptr_add(plt, 4);
957 write32le(p, 0x4778); /* bx pc */
958 write32le(p+2, 0x46c0); /* nop */
960 p = section_ptr_add(plt, 16);
961 /* Jump to GOT entry where ld.so initially put address of PLT0 */
962 write32le(p, 0xe59fc004); /* ldr ip, [pc, #4] */
963 write32le(p+4, 0xe08fc00c); /* add ip, pc, ip */
964 write32le(p+8, 0xe59cf000); /* ldr pc, [ip] */
965 /* p + 12 contains offset to GOT entry once patched by relocate_plt */
966 write32le(p+12, got_offset);
968 /* the symbol is modified so that it will be relocated to the PLT */
969 if (sym->st_shndx == SHN_UNDEF)
970 offset = plt->data_offset - 16;
971 #elif defined(TCC_TARGET_ARM64)
972 Section *plt;
973 uint8_t *p;
975 if (s1->output_type == TCC_OUTPUT_DLL)
976 tcc_error("DLLs unimplemented!");
978 plt = s1->plt;
979 if (plt->data_offset == 0)
980 section_ptr_add(plt, 32);
981 symattr->plt_offset = plt->data_offset;
982 p = section_ptr_add(plt, 16);
983 write32le(p, got_offset);
984 write32le(p + 4, (uint64_t) got_offset >> 32);
986 if (sym->st_shndx == SHN_UNDEF)
987 offset = plt->data_offset - 16;
988 #elif defined(TCC_TARGET_C67)
989 tcc_error("C67 got not implemented");
990 #else
991 #error unsupported CPU
992 #endif
995 /* Create the GOT relocation that will insert the address of the object or
996 function of interest in the GOT entry. This is a static relocation for
997 memory output (dlsym will give us the address of symbols) and dynamic
998 relocation otherwise (executable and DLLs). The relocation should be
999 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1000 associated to a PLT entry) but is currently done at load time for an
1001 unknown reason. */
1002 if (s1->dynsym) {
1003 /* create the dynamic symbol table entry that the relocation refers to
1004 in its r_info field to identify the symbol */
1005 /* XXX This might generate multiple syms for name. */
1006 index = find_elf_sym (s1->dynsym, name);
1007 if (index) {
1008 esym = (ElfW(Sym) *) s1->dynsym->data + index;
1009 esym->st_value = offset;
1011 } else if (s1->output_type == TCC_OUTPUT_MEMORY ||
1012 relocs_info[reloc_type].gotplt_entry == ALWAYS_GOTPLT_ENTRY)
1013 index = put_elf_sym(s1->dynsym, offset, size, info, 0,
1014 sym->st_shndx, name);
1015 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type, index);
1016 } else
1017 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1018 sym_index);
1020 if (need_plt_entry)
1021 return symattr->plt_offset;
1022 else
1023 return symattr->got_offset;
1026 /* build GOT and PLT entries */
1027 ST_FUNC void build_got_entries(TCCState *s1)
1029 Section *s;
1030 ElfW_Rel *rel;
1031 ElfW(Sym) *sym;
1032 int i, type, reloc_type, sym_index;
1034 for(i = 1; i < s1->nb_sections; i++) {
1035 s = s1->sections[i];
1036 if (s->sh_type != SHT_RELX)
1037 continue;
1038 /* no need to handle got relocations */
1039 if (s->link != symtab_section)
1040 continue;
1041 for_each_elem(s, 0, rel, ElfW_Rel) {
1042 type = ELFW(R_TYPE)(rel->r_info);
1043 sym_index = ELFW(R_SYM)(rel->r_info);
1044 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1045 if (relocs_info[type].gotplt_entry == NO_GOTPLT_ENTRY)
1046 continue;
1048 /* Proceed with PLT/GOT [entry] creation if any of the following
1049 condition is met:
1050 - it is an undefined reference (dynamic relocation needed)
1051 - symbol is absolute (probably created by tcc_add_symbol)
1052 - relocation requires a PLT/GOT (BUILD_GOTPLT_ENTRY or
1053 ALWAYS_GOTPLT_ENTRY). */
1054 if (sym->st_shndx != SHN_UNDEF &&
1055 sym->st_shndx != SHN_ABS &&
1056 relocs_info[type].gotplt_entry == AUTO_GOTPLT_ENTRY)
1057 continue;
1059 #ifdef TCC_TARGET_X86_64
1060 if (type == R_X86_64_PLT32 &&
1061 ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT) {
1062 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1063 continue;
1065 #endif
1067 if (!s1->got)
1068 build_got(s1);
1070 if (relocs_info[type].gotplt_entry == BUILD_GOT_ONLY)
1071 continue;
1073 if (relocs_info[type].code_reloc)
1074 reloc_type = R_JMP_SLOT;
1075 else
1076 reloc_type = R_GLOB_DAT;
1077 put_got_entry(s1, reloc_type, type, sym->st_size, sym->st_info,
1078 sym_index);
1083 ST_FUNC Section *new_symtab(TCCState *s1,
1084 const char *symtab_name, int sh_type, int sh_flags,
1085 const char *strtab_name,
1086 const char *hash_name, int hash_sh_flags)
1088 Section *symtab, *strtab, *hash;
1089 int *ptr, nb_buckets;
1091 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1092 symtab->sh_entsize = sizeof(ElfW(Sym));
1093 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1094 put_elf_str(strtab, "");
1095 symtab->link = strtab;
1096 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1098 nb_buckets = 1;
1100 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1101 hash->sh_entsize = sizeof(int);
1102 symtab->hash = hash;
1103 hash->link = symtab;
1105 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1106 ptr[0] = nb_buckets;
1107 ptr[1] = 1;
1108 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1109 return symtab;
1112 /* put dynamic tag */
1113 static void put_dt(Section *dynamic, int dt, addr_t val)
1115 ElfW(Dyn) *dyn;
1116 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1117 dyn->d_tag = dt;
1118 dyn->d_un.d_val = val;
1121 #ifndef TCC_TARGET_PE
1122 static void add_init_array_defines(TCCState *s1, const char *section_name)
1124 Section *s;
1125 long end_offset;
1126 char sym_start[1024];
1127 char sym_end[1024];
1129 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1130 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1132 s = find_section(s1, section_name);
1133 if (!s) {
1134 end_offset = 0;
1135 s = data_section;
1136 } else {
1137 end_offset = s->data_offset;
1140 set_elf_sym(symtab_section,
1141 0, 0,
1142 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1143 s->sh_num, sym_start);
1144 set_elf_sym(symtab_section,
1145 end_offset, 0,
1146 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1147 s->sh_num, sym_end);
1149 #endif
1151 static int tcc_add_support(TCCState *s1, const char *filename)
1153 char buf[1024];
1154 snprintf(buf, sizeof(buf), "%s/"TCC_ARCH_DIR"%s", s1->tcc_lib_path, filename);
1155 return tcc_add_file(s1, buf);
1158 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1160 #ifdef CONFIG_TCC_BCHECK
1161 addr_t *ptr;
1162 int sym_index;
1164 if (0 == s1->do_bounds_check)
1165 return;
1166 /* XXX: add an object file to do that */
1167 ptr = section_ptr_add(bounds_section, sizeof(*ptr));
1168 *ptr = 0;
1169 set_elf_sym(symtab_section, 0, 0,
1170 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1171 bounds_section->sh_num, "__bounds_start");
1172 /* pull bcheck.o from libtcc1.a */
1173 sym_index = set_elf_sym(symtab_section, 0, 0,
1174 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1175 SHN_UNDEF, "__bound_init");
1176 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1177 /* add 'call __bound_init()' in .init section */
1178 Section *init_section = find_section(s1, ".init");
1179 unsigned char *pinit = section_ptr_add(init_section, 5);
1180 pinit[0] = 0xe8;
1181 write32le(pinit + 1, -4);
1182 put_elf_reloc(symtab_section, init_section,
1183 init_section->data_offset - 4, R_386_PC32, sym_index);
1184 /* R_386_PC32 = R_X86_64_PC32 = 2 */
1186 #endif
1189 /* add tcc runtime libraries */
1190 ST_FUNC void tcc_add_runtime(TCCState *s1)
1192 tcc_add_bcheck(s1);
1193 tcc_add_pragma_libs(s1);
1194 /* add libc */
1195 if (!s1->nostdlib) {
1196 tcc_add_library_err(s1, "c");
1197 #ifdef CONFIG_USE_LIBGCC
1198 if (!s1->static_link) {
1199 tcc_add_file(s1, TCC_LIBGCC);
1201 #endif
1202 tcc_add_support(s1, "libtcc1.a");
1203 /* add crt end if not memory output */
1204 if (s1->output_type != TCC_OUTPUT_MEMORY)
1205 tcc_add_crt(s1, "crtn.o");
1209 /* add various standard linker symbols (must be done after the
1210 sections are filled (for example after allocating common
1211 symbols)) */
1212 ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
1214 char buf[1024];
1215 int i;
1216 Section *s;
1218 set_elf_sym(symtab_section,
1219 text_section->data_offset, 0,
1220 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1221 text_section->sh_num, "_etext");
1222 set_elf_sym(symtab_section,
1223 data_section->data_offset, 0,
1224 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1225 data_section->sh_num, "_edata");
1226 set_elf_sym(symtab_section,
1227 bss_section->data_offset, 0,
1228 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1229 bss_section->sh_num, "_end");
1230 #ifndef TCC_TARGET_PE
1231 /* horrible new standard ldscript defines */
1232 add_init_array_defines(s1, ".preinit_array");
1233 add_init_array_defines(s1, ".init_array");
1234 add_init_array_defines(s1, ".fini_array");
1235 #endif
1237 /* add start and stop symbols for sections whose name can be
1238 expressed in C */
1239 for(i = 1; i < s1->nb_sections; i++) {
1240 s = s1->sections[i];
1241 if (s->sh_type == SHT_PROGBITS &&
1242 (s->sh_flags & SHF_ALLOC)) {
1243 const char *p;
1244 int ch;
1246 /* check if section name can be expressed in C */
1247 p = s->name;
1248 for(;;) {
1249 ch = *p;
1250 if (!ch)
1251 break;
1252 if (!isid(ch) && !isnum(ch))
1253 goto next_sec;
1254 p++;
1256 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1257 set_elf_sym(symtab_section,
1258 0, 0,
1259 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1260 s->sh_num, buf);
1261 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1262 set_elf_sym(symtab_section,
1263 s->data_offset, 0,
1264 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1265 s->sh_num, buf);
1267 next_sec: ;
1271 static void tcc_output_binary(TCCState *s1, FILE *f,
1272 const int *sec_order)
1274 Section *s;
1275 int i, offset, size;
1277 offset = 0;
1278 for(i=1;i<s1->nb_sections;i++) {
1279 s = s1->sections[sec_order[i]];
1280 if (s->sh_type != SHT_NOBITS &&
1281 (s->sh_flags & SHF_ALLOC)) {
1282 while (offset < s->sh_offset) {
1283 fputc(0, f);
1284 offset++;
1286 size = s->sh_size;
1287 fwrite(s->data, 1, size, f);
1288 offset += size;
1293 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1294 #define HAVE_PHDR 1
1295 #define EXTRA_RELITEMS 14
1297 /* move the relocation value from .dynsym to .got */
1298 static void patch_dynsym_undef(TCCState *s1, Section *s)
1300 uint32_t *gotd = (void *)s1->got->data;
1301 ElfW(Sym) *sym;
1303 gotd += 3; /* dummy entries in .got */
1304 /* relocate symbols in .dynsym */
1305 for_each_elem(s, 1, sym, ElfW(Sym)) {
1306 if (sym->st_shndx == SHN_UNDEF) {
1307 *gotd++ = sym->st_value + 6; /* XXX 6 is magic ? */
1308 sym->st_value = 0;
1312 #else
1313 #define HAVE_PHDR 1
1314 #define EXTRA_RELITEMS 9
1316 /* zero plt offsets of weak symbols in .dynsym */
1317 static void patch_dynsym_undef(TCCState *s1, Section *s)
1319 ElfW(Sym) *sym;
1321 for_each_elem(s, 1, sym, ElfW(Sym))
1322 if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
1323 sym->st_value = 0;
1325 #endif
1327 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1329 int sym_index = ELFW(R_SYM) (rel->r_info);
1330 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1331 unsigned long offset;
1333 if (sym_index >= s1->nb_sym_attrs)
1334 return;
1335 offset = s1->sym_attrs[sym_index].got_offset;
1336 section_reserve(s1->got, offset + PTR_SIZE);
1337 #ifdef TCC_TARGET_X86_64
1338 /* only works for x86-64 */
1339 write32le(s1->got->data + offset + 4, sym->st_value >> 32);
1340 #endif
1341 write32le(s1->got->data + offset, sym->st_value & 0xffffffff);
1344 /* Perform relocation to GOT or PLT entries */
1345 ST_FUNC void fill_got(TCCState *s1)
1347 Section *s;
1348 ElfW_Rel *rel;
1349 int i;
1351 for(i = 1; i < s1->nb_sections; i++) {
1352 s = s1->sections[i];
1353 if (s->sh_type != SHT_RELX)
1354 continue;
1355 /* no need to handle got relocations */
1356 if (s->link != symtab_section)
1357 continue;
1358 for_each_elem(s, 0, rel, ElfW_Rel) {
1359 switch (ELFW(R_TYPE) (rel->r_info)) {
1360 case R_X86_64_GOT32:
1361 case R_X86_64_GOTPCREL:
1362 case R_X86_64_GOTPCRELX:
1363 case R_X86_64_REX_GOTPCRELX:
1364 case R_X86_64_PLT32:
1365 fill_got_entry(s1, rel);
1366 break;
1372 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1373 in shared libraries and export non local defined symbols to shared libraries
1374 if -rdynamic switch was given on command line */
1375 static void bind_exe_dynsyms(TCCState *s1)
1377 const char *name;
1378 int sym_index, index;
1379 ElfW(Sym) *sym, *esym;
1380 int type;
1382 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1383 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1384 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1385 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1386 if (sym->st_shndx == SHN_UNDEF) {
1387 name = (char *) symtab_section->link->data + sym->st_name;
1388 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1389 if (sym_index) {
1390 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1391 type = ELFW(ST_TYPE)(esym->st_info);
1392 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1393 /* Indirect functions shall have STT_FUNC type in executable
1394 * dynsym section. Indeed, a dlsym call following a lazy
1395 * resolution would pick the symbol value from the
1396 * executable dynsym entry which would contain the address
1397 * of the function wanted by the caller of dlsym instead of
1398 * the address of the function that would return that
1399 * address */
1400 put_elf_sym(s1->dynsym, 0, esym->st_size,
1401 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1402 name);
1403 } else if (type == STT_OBJECT) {
1404 unsigned long offset;
1405 ElfW(Sym) *dynsym;
1406 offset = bss_section->data_offset;
1407 /* XXX: which alignment ? */
1408 offset = (offset + 16 - 1) & -16;
1409 set_elf_sym (s1->symtab, offset, esym->st_size,
1410 esym->st_info, 0, bss_section->sh_num, name);
1411 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1412 esym->st_info, 0, bss_section->sh_num,
1413 name);
1414 /* Ensure R_COPY works for weak symbol aliases */
1415 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1416 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1417 if ((dynsym->st_value == esym->st_value)
1418 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1419 char *dynname = (char *) s1->dynsymtab_section->link->data
1420 + dynsym->st_name;
1421 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1422 dynsym->st_info, 0,
1423 bss_section->sh_num, dynname);
1424 break;
1428 put_elf_reloc(s1->dynsym, bss_section,
1429 offset, R_COPY, index);
1430 offset += esym->st_size;
1431 bss_section->data_offset = offset;
1433 } else {
1434 /* STB_WEAK undefined symbols are accepted */
1435 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1436 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1437 !strcmp(name, "_fp_hw")) {
1438 } else {
1439 tcc_error_noabort("undefined symbol '%s'", name);
1442 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1443 /* if -rdynamic option, then export all non local symbols */
1444 name = (char *) symtab_section->link->data + sym->st_name;
1445 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1446 0, sym->st_shndx, name);
1451 /* Bind symbols of libraries: export all non local symbols of executable that
1452 are referenced by shared libraries. The reason is that the dynamic loader
1453 search symbol first in executable and then in libraries. Therefore a
1454 reference to a symbol already defined by a library can still be resolved by
1455 a symbol in the executable. */
1456 static void bind_libs_dynsyms(TCCState *s1)
1458 const char *name;
1459 int sym_index;
1460 ElfW(Sym) *sym, *esym;
1462 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1463 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1464 sym_index = find_elf_sym(symtab_section, name);
1465 /* XXX: avoid adding a symbol if already present because of
1466 -rdynamic ? */
1467 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1468 if (sym_index && sym->st_shndx != SHN_UNDEF)
1469 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1470 0, sym->st_shndx, name);
1471 else if (esym->st_shndx == SHN_UNDEF) {
1472 /* weak symbols can stay undefined */
1473 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1474 tcc_warning("undefined dynamic symbol '%s'", name);
1479 /* Export all non local symbols. This is used by shared libraries so that the
1480 non local symbols they define can resolve a reference in another shared
1481 library or in the executable. Correspondingly, it allows undefined local
1482 symbols to be resolved by other shared libraries or by the executable. */
1483 static void export_global_syms(TCCState *s1)
1485 int nb_syms, dynindex, index;
1486 const char *name;
1487 ElfW(Sym) *sym;
1489 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1490 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1491 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1492 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1493 name = (char *) symtab_section->link->data + sym->st_name;
1494 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1495 sym->st_info, 0, sym->st_shndx, name);
1496 index = sym - (ElfW(Sym) *) symtab_section->data;
1497 s1->symtab_to_dynsym[index] = dynindex;
1502 /* relocate the PLT: compute addresses and offsets in the PLT now that final
1503 address for PLT and GOT are known (see fill_program_header) */
1504 ST_FUNC void relocate_plt(TCCState *s1)
1506 uint8_t *p, *p_end;
1508 if (!s1->plt)
1509 return;
1511 p = s1->plt->data;
1512 p_end = p + s1->plt->data_offset;
1513 if (p < p_end) {
1514 #if defined(TCC_TARGET_I386)
1515 add32le(p + 2, s1->got->sh_addr);
1516 add32le(p + 8, s1->got->sh_addr);
1517 p += 16;
1518 while (p < p_end) {
1519 add32le(p + 2, s1->got->sh_addr);
1520 p += 16;
1522 #elif defined(TCC_TARGET_X86_64)
1523 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
1524 add32le(p + 2, x);
1525 add32le(p + 8, x - 6);
1526 p += 16;
1527 while (p < p_end) {
1528 add32le(p + 2, x + s1->plt->data - p);
1529 p += 16;
1531 #elif defined(TCC_TARGET_ARM)
1532 int x = s1->got->sh_addr - s1->plt->sh_addr - 12;
1533 write32le(s1->plt->data + 16, x - 16);
1534 p += 20;
1535 while (p < p_end) {
1536 if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
1537 p += 4;
1538 add32le(p + 12, x + s1->plt->data - p);
1539 p += 16;
1541 #elif defined(TCC_TARGET_ARM64)
1542 uint64_t plt = s1->plt->sh_addr;
1543 uint64_t got = s1->got->sh_addr;
1544 uint64_t off = (got >> 12) - (plt >> 12);
1545 if ((off + ((uint32_t)1 << 20)) >> 21)
1546 tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt);
1547 write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
1548 write32le(p + 4, (0x90000010 | // adrp x16,...
1549 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1550 write32le(p + 8, (0xf9400211 | // ldr x17,[x16,#...]
1551 (got & 0xff8) << 7));
1552 write32le(p + 12, (0x91000210 | // add x16,x16,#...
1553 (got & 0xfff) << 10));
1554 write32le(p + 16, 0xd61f0220); // br x17
1555 write32le(p + 20, 0xd503201f); // nop
1556 write32le(p + 24, 0xd503201f); // nop
1557 write32le(p + 28, 0xd503201f); // nop
1558 p += 32;
1559 while (p < p_end) {
1560 uint64_t pc = plt + (p - s1->plt->data);
1561 uint64_t addr = got + read64le(p);
1562 uint64_t off = (addr >> 12) - (pc >> 12);
1563 if ((off + ((uint32_t)1 << 20)) >> 21)
1564 tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc);
1565 write32le(p, (0x90000010 | // adrp x16,...
1566 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1567 write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
1568 (addr & 0xff8) << 7));
1569 write32le(p + 8, (0x91000210 | // add x16,x16,#...
1570 (addr & 0xfff) << 10));
1571 write32le(p + 12, 0xd61f0220); // br x17
1572 p += 16;
1574 #elif defined(TCC_TARGET_C67)
1575 /* XXX: TODO */
1576 #else
1577 #error unsupported CPU
1578 #endif
1582 /* Allocate strings for section names and decide if an unallocated section
1583 should be output.
1585 NOTE: the strsec section comes last, so its size is also correct ! */
1586 static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1588 int i;
1589 Section *s;
1591 /* Allocate strings for section names */
1592 for(i = 1; i < s1->nb_sections; i++) {
1593 s = s1->sections[i];
1594 s->sh_name = put_elf_str(strsec, s->name);
1595 /* when generating a DLL, we include relocations but we may
1596 patch them */
1597 if (file_type == TCC_OUTPUT_DLL &&
1598 s->sh_type == SHT_RELX &&
1599 !(s->sh_flags & SHF_ALLOC)) {
1600 /* gr: avoid bogus relocs for empty (debug) sections */
1601 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1602 prepare_dynamic_rel(s1, s);
1603 else if (s1->do_debug)
1604 s->sh_size = s->data_offset;
1605 } else if (s1->do_debug ||
1606 file_type == TCC_OUTPUT_OBJ ||
1607 (s->sh_flags & SHF_ALLOC) ||
1608 i == (s1->nb_sections - 1)) {
1609 /* we output all sections if debug or object file */
1610 s->sh_size = s->data_offset;
1615 /* Info to be copied in dynamic section */
1616 struct dyn_inf {
1617 Section *dynamic;
1618 Section *dynstr;
1619 unsigned long dyn_rel_off;
1620 addr_t rel_addr;
1621 addr_t rel_size;
1622 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1623 addr_t bss_addr;
1624 addr_t bss_size;
1625 #endif
1628 /* Assign sections to segments and decide how are sections laid out when loaded
1629 in memory. This function also fills corresponding program headers. */
1630 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1631 Section *interp, Section* strsec,
1632 struct dyn_inf *dyninf, int *sec_order)
1634 int i, j, k, file_type, sh_order_index, file_offset;
1635 unsigned long s_align;
1636 long long tmp;
1637 addr_t addr;
1638 ElfW(Phdr) *ph;
1639 Section *s;
1641 file_type = s1->output_type;
1642 sh_order_index = 1;
1643 file_offset = 0;
1644 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1645 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1646 s_align = ELF_PAGE_SIZE;
1647 if (s1->section_align)
1648 s_align = s1->section_align;
1650 if (phnum > 0) {
1651 if (s1->has_text_addr) {
1652 int a_offset, p_offset;
1653 addr = s1->text_addr;
1654 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1655 ELF_PAGE_SIZE */
1656 a_offset = (int) (addr & (s_align - 1));
1657 p_offset = file_offset & (s_align - 1);
1658 if (a_offset < p_offset)
1659 a_offset += s_align;
1660 file_offset += (a_offset - p_offset);
1661 } else {
1662 if (file_type == TCC_OUTPUT_DLL)
1663 addr = 0;
1664 else
1665 addr = ELF_START_ADDR;
1666 /* compute address after headers */
1667 addr += (file_offset & (s_align - 1));
1670 ph = &phdr[0];
1671 /* Leave one program headers for the program interpreter and one for
1672 the program header table itself if needed. These are done later as
1673 they require section layout to be done first. */
1674 if (interp)
1675 ph += 1 + HAVE_PHDR;
1677 /* dynamic relocation table information, for .dynamic section */
1678 dyninf->rel_addr = dyninf->rel_size = 0;
1679 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1680 dyninf->bss_addr = dyninf->bss_size = 0;
1681 #endif
1683 for(j = 0; j < 2; j++) {
1684 ph->p_type = PT_LOAD;
1685 if (j == 0)
1686 ph->p_flags = PF_R | PF_X;
1687 else
1688 ph->p_flags = PF_R | PF_W;
1689 ph->p_align = s_align;
1691 /* Decide the layout of sections loaded in memory. This must
1692 be done before program headers are filled since they contain
1693 info about the layout. We do the following ordering: interp,
1694 symbol tables, relocations, progbits, nobits */
1695 /* XXX: do faster and simpler sorting */
1696 for(k = 0; k < 5; k++) {
1697 for(i = 1; i < s1->nb_sections; i++) {
1698 s = s1->sections[i];
1699 /* compute if section should be included */
1700 if (j == 0) {
1701 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1702 SHF_ALLOC)
1703 continue;
1704 } else {
1705 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1706 (SHF_ALLOC | SHF_WRITE))
1707 continue;
1709 if (s == interp) {
1710 if (k != 0)
1711 continue;
1712 } else if (s->sh_type == SHT_DYNSYM ||
1713 s->sh_type == SHT_STRTAB ||
1714 s->sh_type == SHT_HASH) {
1715 if (k != 1)
1716 continue;
1717 } else if (s->sh_type == SHT_RELX) {
1718 if (k != 2)
1719 continue;
1720 } else if (s->sh_type == SHT_NOBITS) {
1721 if (k != 4)
1722 continue;
1723 } else {
1724 if (k != 3)
1725 continue;
1727 sec_order[sh_order_index++] = i;
1729 /* section matches: we align it and add its size */
1730 tmp = addr;
1731 addr = (addr + s->sh_addralign - 1) &
1732 ~(s->sh_addralign - 1);
1733 file_offset += (int) ( addr - tmp );
1734 s->sh_offset = file_offset;
1735 s->sh_addr = addr;
1737 /* update program header infos */
1738 if (ph->p_offset == 0) {
1739 ph->p_offset = file_offset;
1740 ph->p_vaddr = addr;
1741 ph->p_paddr = ph->p_vaddr;
1743 /* update dynamic relocation infos */
1744 if (s->sh_type == SHT_RELX) {
1745 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1746 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1747 dyninf->rel_addr = addr;
1748 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1750 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1751 dyninf->bss_addr = addr;
1752 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1754 #else
1755 if (dyninf->rel_size == 0)
1756 dyninf->rel_addr = addr;
1757 dyninf->rel_size += s->sh_size;
1758 #endif
1760 addr += s->sh_size;
1761 if (s->sh_type != SHT_NOBITS)
1762 file_offset += s->sh_size;
1765 if (j == 0) {
1766 /* Make the first PT_LOAD segment include the program
1767 headers itself (and the ELF header as well), it'll
1768 come out with same memory use but will make various
1769 tools like binutils strip work better. */
1770 ph->p_offset &= ~(ph->p_align - 1);
1771 ph->p_vaddr &= ~(ph->p_align - 1);
1772 ph->p_paddr &= ~(ph->p_align - 1);
1774 ph->p_filesz = file_offset - ph->p_offset;
1775 ph->p_memsz = addr - ph->p_vaddr;
1776 ph++;
1777 if (j == 0) {
1778 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1779 /* if in the middle of a page, we duplicate the page in
1780 memory so that one copy is RX and the other is RW */
1781 if ((addr & (s_align - 1)) != 0)
1782 addr += s_align;
1783 } else {
1784 addr = (addr + s_align - 1) & ~(s_align - 1);
1785 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1791 /* all other sections come after */
1792 for(i = 1; i < s1->nb_sections; i++) {
1793 s = s1->sections[i];
1794 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1795 continue;
1796 sec_order[sh_order_index++] = i;
1798 file_offset = (file_offset + s->sh_addralign - 1) &
1799 ~(s->sh_addralign - 1);
1800 s->sh_offset = file_offset;
1801 if (s->sh_type != SHT_NOBITS)
1802 file_offset += s->sh_size;
1805 return file_offset;
1808 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1809 Section *dynamic)
1811 ElfW(Phdr) *ph;
1813 /* if interpreter, then add corresponding program header */
1814 if (interp) {
1815 ph = &phdr[0];
1817 if (HAVE_PHDR)
1819 int len = phnum * sizeof(ElfW(Phdr));
1821 ph->p_type = PT_PHDR;
1822 ph->p_offset = sizeof(ElfW(Ehdr));
1823 ph->p_vaddr = interp->sh_addr - len;
1824 ph->p_paddr = ph->p_vaddr;
1825 ph->p_filesz = ph->p_memsz = len;
1826 ph->p_flags = PF_R | PF_X;
1827 ph->p_align = 4; /* interp->sh_addralign; */
1828 ph++;
1831 ph->p_type = PT_INTERP;
1832 ph->p_offset = interp->sh_offset;
1833 ph->p_vaddr = interp->sh_addr;
1834 ph->p_paddr = ph->p_vaddr;
1835 ph->p_filesz = interp->sh_size;
1836 ph->p_memsz = interp->sh_size;
1837 ph->p_flags = PF_R;
1838 ph->p_align = interp->sh_addralign;
1841 /* if dynamic section, then add corresponding program header */
1842 if (dynamic) {
1843 ph = &phdr[phnum - 1];
1845 ph->p_type = PT_DYNAMIC;
1846 ph->p_offset = dynamic->sh_offset;
1847 ph->p_vaddr = dynamic->sh_addr;
1848 ph->p_paddr = ph->p_vaddr;
1849 ph->p_filesz = dynamic->sh_size;
1850 ph->p_memsz = dynamic->sh_size;
1851 ph->p_flags = PF_R | PF_W;
1852 ph->p_align = dynamic->sh_addralign;
1856 /* Fill the dynamic section with tags describing the address and size of
1857 sections */
1858 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
1860 Section *dynamic;
1862 dynamic = dyninf->dynamic;
1864 /* put dynamic section entries */
1865 dynamic->data_offset = dyninf->dyn_rel_off;
1866 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1867 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
1868 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1869 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
1870 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1871 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1872 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
1873 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
1874 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
1875 #else
1876 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1877 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
1878 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
1879 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
1880 put_dt(dynamic, DT_PLTREL, DT_REL);
1881 put_dt(dynamic, DT_REL, dyninf->bss_addr);
1882 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
1883 #else
1884 put_dt(dynamic, DT_REL, dyninf->rel_addr);
1885 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
1886 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1887 #endif
1888 #endif
1889 if (s1->do_debug)
1890 put_dt(dynamic, DT_DEBUG, 0);
1891 put_dt(dynamic, DT_NULL, 0);
1894 /* Relocate remaining sections and symbols (that is those not related to
1895 dynamic linking) */
1896 static int final_sections_reloc(TCCState *s1)
1898 int i;
1899 Section *s;
1901 relocate_syms(s1, s1->symtab, 0);
1903 if (s1->nb_errors != 0)
1904 return -1;
1906 /* relocate sections */
1907 /* XXX: ignore sections with allocated relocations ? */
1908 for(i = 1; i < s1->nb_sections; i++) {
1909 s = s1->sections[i];
1910 #ifdef TCC_TARGET_I386
1911 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
1912 /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
1913 checking is removed */
1914 #else
1915 if (s->reloc && s != s1->got)
1916 /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
1917 #endif
1918 relocate_section(s1, s);
1921 /* relocate relocation entries if the relocation tables are
1922 allocated in the executable */
1923 for(i = 1; i < s1->nb_sections; i++) {
1924 s = s1->sections[i];
1925 if ((s->sh_flags & SHF_ALLOC) &&
1926 s->sh_type == SHT_RELX) {
1927 relocate_rel(s1, s);
1930 return 0;
1933 /* Create an ELF file on disk.
1934 This function handle ELF specific layout requirements */
1935 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
1936 int file_offset, int *sec_order)
1938 int i, shnum, offset, size, file_type;
1939 Section *s;
1940 ElfW(Ehdr) ehdr;
1941 ElfW(Shdr) shdr, *sh;
1943 file_type = s1->output_type;
1944 shnum = s1->nb_sections;
1946 memset(&ehdr, 0, sizeof(ehdr));
1948 if (phnum > 0) {
1949 ehdr.e_phentsize = sizeof(ElfW(Phdr));
1950 ehdr.e_phnum = phnum;
1951 ehdr.e_phoff = sizeof(ElfW(Ehdr));
1954 /* align to 4 */
1955 file_offset = (file_offset + 3) & -4;
1957 /* fill header */
1958 ehdr.e_ident[0] = ELFMAG0;
1959 ehdr.e_ident[1] = ELFMAG1;
1960 ehdr.e_ident[2] = ELFMAG2;
1961 ehdr.e_ident[3] = ELFMAG3;
1962 ehdr.e_ident[4] = ELFCLASSW;
1963 ehdr.e_ident[5] = ELFDATA2LSB;
1964 ehdr.e_ident[6] = EV_CURRENT;
1965 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1966 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1967 #endif
1968 #ifdef TCC_TARGET_ARM
1969 #ifdef TCC_ARM_EABI
1970 ehdr.e_ident[EI_OSABI] = 0;
1971 ehdr.e_flags = EF_ARM_EABI_VER4;
1972 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
1973 ehdr.e_flags |= EF_ARM_HASENTRY;
1974 if (s1->float_abi == ARM_HARD_FLOAT)
1975 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
1976 else
1977 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
1978 #else
1979 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1980 #endif
1981 #endif
1982 switch(file_type) {
1983 default:
1984 case TCC_OUTPUT_EXE:
1985 ehdr.e_type = ET_EXEC;
1986 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
1987 break;
1988 case TCC_OUTPUT_DLL:
1989 ehdr.e_type = ET_DYN;
1990 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1991 break;
1992 case TCC_OUTPUT_OBJ:
1993 ehdr.e_type = ET_REL;
1994 break;
1996 ehdr.e_machine = EM_TCC_TARGET;
1997 ehdr.e_version = EV_CURRENT;
1998 ehdr.e_shoff = file_offset;
1999 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2000 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2001 ehdr.e_shnum = shnum;
2002 ehdr.e_shstrndx = shnum - 1;
2004 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2005 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2006 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2008 sort_syms(s1, symtab_section);
2009 for(i = 1; i < s1->nb_sections; i++) {
2010 s = s1->sections[sec_order[i]];
2011 if (s->sh_type != SHT_NOBITS) {
2012 if (s->sh_type == SHT_DYNSYM)
2013 patch_dynsym_undef(s1, s);
2014 while (offset < s->sh_offset) {
2015 fputc(0, f);
2016 offset++;
2018 size = s->sh_size;
2019 if (size)
2020 fwrite(s->data, 1, size, f);
2021 offset += size;
2025 /* output section headers */
2026 while (offset < ehdr.e_shoff) {
2027 fputc(0, f);
2028 offset++;
2031 for(i = 0; i < s1->nb_sections; i++) {
2032 sh = &shdr;
2033 memset(sh, 0, sizeof(ElfW(Shdr)));
2034 s = s1->sections[i];
2035 if (s) {
2036 sh->sh_name = s->sh_name;
2037 sh->sh_type = s->sh_type;
2038 sh->sh_flags = s->sh_flags;
2039 sh->sh_entsize = s->sh_entsize;
2040 sh->sh_info = s->sh_info;
2041 if (s->link)
2042 sh->sh_link = s->link->sh_num;
2043 sh->sh_addralign = s->sh_addralign;
2044 sh->sh_addr = s->sh_addr;
2045 sh->sh_offset = s->sh_offset;
2046 sh->sh_size = s->sh_size;
2048 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2052 /* Write an elf, coff or "binary" file */
2053 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2054 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2056 int fd, mode, file_type;
2057 FILE *f;
2059 file_type = s1->output_type;
2060 if (file_type == TCC_OUTPUT_OBJ)
2061 mode = 0666;
2062 else
2063 mode = 0777;
2064 unlink(filename);
2065 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2066 if (fd < 0) {
2067 tcc_error_noabort("could not write '%s'", filename);
2068 return -1;
2070 f = fdopen(fd, "wb");
2071 if (s1->verbose)
2072 printf("<- %s\n", filename);
2074 #ifdef TCC_TARGET_COFF
2075 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2076 tcc_output_coff(s1, f);
2077 else
2078 #endif
2079 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2080 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2081 else
2082 tcc_output_binary(s1, f, sec_order);
2083 fclose(f);
2085 return 0;
2088 /* Output an elf, coff or binary file */
2089 /* XXX: suppress unneeded sections */
2090 static int elf_output_file(TCCState *s1, const char *filename)
2092 int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
2093 struct dyn_inf dyninf;
2094 ElfW(Phdr) *phdr;
2095 ElfW(Sym) *sym;
2096 Section *strsec, *interp, *dynamic, *dynstr;
2098 file_type = s1->output_type;
2099 s1->nb_errors = 0;
2101 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2102 if (file_type != TCC_OUTPUT_OBJ) {
2103 tcc_add_runtime(s1);
2106 phdr = NULL;
2107 sec_order = NULL;
2108 interp = dynamic = dynstr = NULL; /* avoid warning */
2109 dyninf.dyn_rel_off = 0; /* avoid warning */
2111 if (file_type != TCC_OUTPUT_OBJ) {
2112 relocate_common_syms();
2114 tcc_add_linker_symbols(s1);
2116 if (!s1->static_link) {
2117 if (file_type == TCC_OUTPUT_EXE) {
2118 char *ptr;
2119 /* allow override the dynamic loader */
2120 const char *elfint = getenv("LD_SO");
2121 if (elfint == NULL)
2122 elfint = DEFAULT_ELFINTERP(s1);
2123 /* add interpreter section only if executable */
2124 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2125 interp->sh_addralign = 1;
2126 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2127 strcpy(ptr, elfint);
2130 /* add dynamic symbol table */
2131 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2132 ".dynstr",
2133 ".hash", SHF_ALLOC);
2134 dynstr = s1->dynsym->link;
2136 /* add dynamic section */
2137 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2138 SHF_ALLOC | SHF_WRITE);
2139 dynamic->link = dynstr;
2140 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2142 build_got(s1);
2144 if (file_type == TCC_OUTPUT_EXE) {
2145 bind_exe_dynsyms(s1);
2147 if (s1->nb_errors) {
2148 ret = -1;
2149 goto the_end;
2152 bind_libs_dynsyms(s1);
2153 } else /* shared library case: simply export all global symbols */
2154 export_global_syms(s1);
2156 build_got_entries(s1);
2158 /* add a list of needed dlls */
2159 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2160 DLLReference *dllref = s1->loaded_dlls[i];
2161 if (dllref->level == 0)
2162 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2165 if (s1->rpath)
2166 put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath));
2168 /* XXX: currently, since we do not handle PIC code, we
2169 must relocate the readonly segments */
2170 if (file_type == TCC_OUTPUT_DLL) {
2171 if (s1->soname)
2172 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2173 put_dt(dynamic, DT_TEXTREL, 0);
2176 if (s1->symbolic)
2177 put_dt(dynamic, DT_SYMBOLIC, 0);
2179 /* add necessary space for other entries */
2180 dyninf.dyn_rel_off = dynamic->data_offset;
2181 dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
2182 } else {
2183 /* still need to build got entries in case of static link */
2184 build_got_entries(s1);
2188 /* we add a section for symbols */
2189 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2190 put_elf_str(strsec, "");
2192 /* compute number of sections */
2193 shnum = s1->nb_sections;
2195 /* this array is used to reorder sections in the output file */
2196 sec_order = tcc_malloc(sizeof(int) * shnum);
2197 sec_order[0] = 0;
2199 /* compute number of program headers */
2200 switch(file_type) {
2201 default:
2202 case TCC_OUTPUT_OBJ:
2203 phnum = 0;
2204 break;
2205 case TCC_OUTPUT_EXE:
2206 if (!s1->static_link)
2207 phnum = 4 + HAVE_PHDR;
2208 else
2209 phnum = 2;
2210 break;
2211 case TCC_OUTPUT_DLL:
2212 phnum = 3;
2213 break;
2216 /* Allocate strings for section names */
2217 alloc_sec_names(s1, file_type, strsec);
2219 /* allocate program segment headers */
2220 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2222 /* compute section to program header mapping */
2223 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2224 sec_order);
2226 /* Fill remaining program header and finalize relocation related to dynamic
2227 linking. */
2228 if (phnum > 0) {
2229 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2230 if (dynamic) {
2231 dyninf.dynamic = dynamic;
2232 dyninf.dynstr = dynstr;
2234 fill_dynamic(s1, &dyninf);
2236 /* put in GOT the dynamic section address and relocate PLT */
2237 write32le(s1->got->data, dynamic->sh_addr);
2238 if (file_type == TCC_OUTPUT_EXE
2239 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
2240 || file_type == TCC_OUTPUT_DLL
2241 #endif
2243 relocate_plt(s1);
2245 /* relocate symbols in .dynsym now that final addresses are known */
2246 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2247 if (sym->st_shndx == SHN_UNDEF) {
2248 /* relocate to PLT if symbol corresponds to a PLT entry,
2249 but not if it's a weak symbol */
2250 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
2251 sym->st_value = 0;
2252 else if (sym->st_value)
2253 sym->st_value += s1->plt->sh_addr;
2254 } else if (sym->st_shndx < SHN_LORESERVE) {
2255 /* do symbol relocation */
2256 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2262 /* if building executable or DLL, then relocate each section
2263 except the GOT which is already relocated */
2264 if (file_type != TCC_OUTPUT_OBJ) {
2265 ret = final_sections_reloc(s1);
2266 if (ret)
2267 goto the_end;
2270 /* Perform relocation to GOT or PLT entries */
2271 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2272 fill_got(s1);
2274 /* Create the ELF file with name 'filename' */
2275 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2276 the_end:
2277 tcc_free(s1->symtab_to_dynsym);
2278 tcc_free(sec_order);
2279 tcc_free(phdr);
2280 tcc_free(s1->sym_attrs);
2281 s1->sym_attrs = NULL;
2282 return ret;
2285 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2287 int ret;
2288 #ifdef TCC_TARGET_PE
2289 if (s->output_type != TCC_OUTPUT_OBJ) {
2290 ret = pe_output_file(s, filename);
2291 } else
2292 #endif
2293 ret = elf_output_file(s, filename);
2294 return ret;
2297 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2299 void *data;
2301 data = tcc_malloc(size);
2302 lseek(fd, file_offset, SEEK_SET);
2303 read(fd, data, size);
2304 return data;
2307 typedef struct SectionMergeInfo {
2308 Section *s; /* corresponding existing section */
2309 unsigned long offset; /* offset of the new section in the existing section */
2310 uint8_t new_section; /* true if section 's' was added */
2311 uint8_t link_once; /* true if link once section */
2312 } SectionMergeInfo;
2314 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2316 int size = read(fd, h, sizeof *h);
2317 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2318 if (h->e_type == ET_REL)
2319 return AFF_BINTYPE_REL;
2320 if (h->e_type == ET_DYN)
2321 return AFF_BINTYPE_DYN;
2322 } else if (size >= 8) {
2323 if (0 == memcmp(h, ARMAG, 8))
2324 return AFF_BINTYPE_AR;
2325 #ifdef TCC_TARGET_COFF
2326 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2327 return AFF_BINTYPE_C67;
2328 #endif
2330 return 0;
2333 /* load an object file and merge it with current files */
2334 /* XXX: handle correctly stab (debug) info */
2335 ST_FUNC int tcc_load_object_file(TCCState *s1,
2336 int fd, unsigned long file_offset)
2338 ElfW(Ehdr) ehdr;
2339 ElfW(Shdr) *shdr, *sh;
2340 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2341 unsigned char *strsec, *strtab;
2342 int *old_to_new_syms;
2343 char *sh_name, *name;
2344 SectionMergeInfo *sm_table, *sm;
2345 ElfW(Sym) *sym, *symtab;
2346 ElfW_Rel *rel;
2347 Section *s;
2349 int stab_index;
2350 int stabstr_index;
2352 stab_index = stabstr_index = 0;
2354 lseek(fd, file_offset, SEEK_SET);
2355 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2356 goto fail1;
2357 /* test CPU specific stuff */
2358 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2359 ehdr.e_machine != EM_TCC_TARGET) {
2360 fail1:
2361 tcc_error_noabort("invalid object file");
2362 return -1;
2364 /* read sections */
2365 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2366 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2367 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2369 /* load section names */
2370 sh = &shdr[ehdr.e_shstrndx];
2371 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2373 /* load symtab and strtab */
2374 old_to_new_syms = NULL;
2375 symtab = NULL;
2376 strtab = NULL;
2377 nb_syms = 0;
2378 for(i = 1; i < ehdr.e_shnum; i++) {
2379 sh = &shdr[i];
2380 if (sh->sh_type == SHT_SYMTAB) {
2381 if (symtab) {
2382 tcc_error_noabort("object must contain only one symtab");
2383 fail:
2384 ret = -1;
2385 goto the_end;
2387 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2388 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2389 sm_table[i].s = symtab_section;
2391 /* now load strtab */
2392 sh = &shdr[sh->sh_link];
2393 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2397 /* now examine each section and try to merge its content with the
2398 ones in memory */
2399 for(i = 1; i < ehdr.e_shnum; i++) {
2400 /* no need to examine section name strtab */
2401 if (i == ehdr.e_shstrndx)
2402 continue;
2403 sh = &shdr[i];
2404 sh_name = (char *) strsec + sh->sh_name;
2405 /* ignore sections types we do not handle */
2406 if (sh->sh_type != SHT_PROGBITS &&
2407 sh->sh_type != SHT_RELX &&
2408 #ifdef TCC_ARM_EABI
2409 sh->sh_type != SHT_ARM_EXIDX &&
2410 #endif
2411 sh->sh_type != SHT_NOBITS &&
2412 sh->sh_type != SHT_PREINIT_ARRAY &&
2413 sh->sh_type != SHT_INIT_ARRAY &&
2414 sh->sh_type != SHT_FINI_ARRAY &&
2415 strcmp(sh_name, ".stabstr")
2417 continue;
2418 if (sh->sh_addralign < 1)
2419 sh->sh_addralign = 1;
2420 /* find corresponding section, if any */
2421 for(j = 1; j < s1->nb_sections;j++) {
2422 s = s1->sections[j];
2423 if (!strcmp(s->name, sh_name)) {
2424 if (!strncmp(sh_name, ".gnu.linkonce",
2425 sizeof(".gnu.linkonce") - 1)) {
2426 /* if a 'linkonce' section is already present, we
2427 do not add it again. It is a little tricky as
2428 symbols can still be defined in
2429 it. */
2430 sm_table[i].link_once = 1;
2431 goto next;
2432 } else {
2433 goto found;
2437 /* not found: create new section */
2438 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2439 /* take as much info as possible from the section. sh_link and
2440 sh_info will be updated later */
2441 s->sh_addralign = sh->sh_addralign;
2442 s->sh_entsize = sh->sh_entsize;
2443 sm_table[i].new_section = 1;
2444 found:
2445 if (sh->sh_type != s->sh_type) {
2446 tcc_error_noabort("invalid section type");
2447 goto fail;
2450 /* align start of section */
2451 offset = s->data_offset;
2453 if (0 == strcmp(sh_name, ".stab")) {
2454 stab_index = i;
2455 goto no_align;
2457 if (0 == strcmp(sh_name, ".stabstr")) {
2458 stabstr_index = i;
2459 goto no_align;
2462 size = sh->sh_addralign - 1;
2463 offset = (offset + size) & ~size;
2464 if (sh->sh_addralign > s->sh_addralign)
2465 s->sh_addralign = sh->sh_addralign;
2466 s->data_offset = offset;
2467 no_align:
2468 sm_table[i].offset = offset;
2469 sm_table[i].s = s;
2470 /* concatenate sections */
2471 size = sh->sh_size;
2472 if (sh->sh_type != SHT_NOBITS) {
2473 unsigned char *ptr;
2474 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2475 ptr = section_ptr_add(s, size);
2476 read(fd, ptr, size);
2477 } else {
2478 s->data_offset += size;
2480 next: ;
2483 /* gr relocate stab strings */
2484 if (stab_index && stabstr_index) {
2485 Stab_Sym *a, *b;
2486 unsigned o;
2487 s = sm_table[stab_index].s;
2488 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2489 b = (Stab_Sym *)(s->data + s->data_offset);
2490 o = sm_table[stabstr_index].offset;
2491 while (a < b)
2492 a->n_strx += o, a++;
2495 /* second short pass to update sh_link and sh_info fields of new
2496 sections */
2497 for(i = 1; i < ehdr.e_shnum; i++) {
2498 s = sm_table[i].s;
2499 if (!s || !sm_table[i].new_section)
2500 continue;
2501 sh = &shdr[i];
2502 if (sh->sh_link > 0)
2503 s->link = sm_table[sh->sh_link].s;
2504 if (sh->sh_type == SHT_RELX) {
2505 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2506 /* update backward link */
2507 s1->sections[s->sh_info]->reloc = s;
2510 sm = sm_table;
2512 /* resolve symbols */
2513 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2515 sym = symtab + 1;
2516 for(i = 1; i < nb_syms; i++, sym++) {
2517 if (sym->st_shndx != SHN_UNDEF &&
2518 sym->st_shndx < SHN_LORESERVE) {
2519 sm = &sm_table[sym->st_shndx];
2520 if (sm->link_once) {
2521 /* if a symbol is in a link once section, we use the
2522 already defined symbol. It is very important to get
2523 correct relocations */
2524 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2525 name = (char *) strtab + sym->st_name;
2526 sym_index = find_elf_sym(symtab_section, name);
2527 if (sym_index)
2528 old_to_new_syms[i] = sym_index;
2530 continue;
2532 /* if no corresponding section added, no need to add symbol */
2533 if (!sm->s)
2534 continue;
2535 /* convert section number */
2536 sym->st_shndx = sm->s->sh_num;
2537 /* offset value */
2538 sym->st_value += sm->offset;
2540 /* add symbol */
2541 name = (char *) strtab + sym->st_name;
2542 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2543 sym->st_info, sym->st_other,
2544 sym->st_shndx, name);
2545 old_to_new_syms[i] = sym_index;
2548 /* third pass to patch relocation entries */
2549 for(i = 1; i < ehdr.e_shnum; i++) {
2550 s = sm_table[i].s;
2551 if (!s)
2552 continue;
2553 sh = &shdr[i];
2554 offset = sm_table[i].offset;
2555 switch(s->sh_type) {
2556 case SHT_RELX:
2557 /* take relocation offset information */
2558 offseti = sm_table[sh->sh_info].offset;
2559 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2560 int type;
2561 unsigned sym_index;
2562 /* convert symbol index */
2563 type = ELFW(R_TYPE)(rel->r_info);
2564 sym_index = ELFW(R_SYM)(rel->r_info);
2565 /* NOTE: only one symtab assumed */
2566 if (sym_index >= nb_syms)
2567 goto invalid_reloc;
2568 sym_index = old_to_new_syms[sym_index];
2569 /* ignore link_once in rel section. */
2570 if (!sym_index && !sm->link_once
2571 #ifdef TCC_TARGET_ARM
2572 && type != R_ARM_V4BX
2573 #endif
2575 invalid_reloc:
2576 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2577 i, strsec + sh->sh_name, rel->r_offset);
2578 goto fail;
2580 rel->r_info = ELFW(R_INFO)(sym_index, type);
2581 /* offset the relocation offset */
2582 rel->r_offset += offseti;
2583 #ifdef TCC_TARGET_ARM
2584 /* Jumps and branches from a Thumb code to a PLT entry need
2585 special handling since PLT entries are ARM code.
2586 Unconditional bl instructions referencing PLT entries are
2587 handled by converting these instructions into blx
2588 instructions. Other case of instructions referencing a PLT
2589 entry require to add a Thumb stub before the PLT entry to
2590 switch to ARM mode. We set bit plt_thumb_stub of the
2591 attribute of a symbol to indicate such a case. */
2592 if (type == R_ARM_THM_JUMP24)
2593 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2594 #endif
2596 break;
2597 default:
2598 break;
2602 ret = 0;
2603 the_end:
2604 tcc_free(symtab);
2605 tcc_free(strtab);
2606 tcc_free(old_to_new_syms);
2607 tcc_free(sm_table);
2608 tcc_free(strsec);
2609 tcc_free(shdr);
2610 return ret;
2613 typedef struct ArchiveHeader {
2614 char ar_name[16]; /* name of this member */
2615 char ar_date[12]; /* file mtime */
2616 char ar_uid[6]; /* owner uid; printed as decimal */
2617 char ar_gid[6]; /* owner gid; printed as decimal */
2618 char ar_mode[8]; /* file mode, printed as octal */
2619 char ar_size[10]; /* file size, printed as decimal */
2620 char ar_fmag[2]; /* should contain ARFMAG */
2621 } ArchiveHeader;
2623 static int get_be32(const uint8_t *b)
2625 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2628 static long get_be64(const uint8_t *b)
2630 long long ret = get_be32(b);
2631 ret = (ret << 32) | (unsigned)get_be32(b+4);
2632 return (long)ret;
2635 /* load only the objects which resolve undefined symbols */
2636 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2638 long i, bound, nsyms, sym_index, off, ret;
2639 uint8_t *data;
2640 const char *ar_names, *p;
2641 const uint8_t *ar_index;
2642 ElfW(Sym) *sym;
2644 data = tcc_malloc(size);
2645 if (read(fd, data, size) != size)
2646 goto fail;
2647 nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
2648 ar_index = data + entrysize;
2649 ar_names = (char *) ar_index + nsyms * entrysize;
2651 do {
2652 bound = 0;
2653 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2654 sym_index = find_elf_sym(symtab_section, p);
2655 if(sym_index) {
2656 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2657 if(sym->st_shndx == SHN_UNDEF) {
2658 off = (entrysize == 4
2659 ? get_be32(ar_index + i * 4)
2660 : get_be64(ar_index + i * 8))
2661 + sizeof(ArchiveHeader);
2662 ++bound;
2663 if(tcc_load_object_file(s1, fd, off) < 0) {
2664 fail:
2665 ret = -1;
2666 goto the_end;
2671 } while(bound);
2672 ret = 0;
2673 the_end:
2674 tcc_free(data);
2675 return ret;
2678 /* load a '.a' file */
2679 ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
2681 ArchiveHeader hdr;
2682 char ar_size[11];
2683 char ar_name[17];
2684 char magic[8];
2685 int size, len, i;
2686 unsigned long file_offset;
2688 /* skip magic which was already checked */
2689 read(fd, magic, sizeof(magic));
2691 for(;;) {
2692 len = read(fd, &hdr, sizeof(hdr));
2693 if (len == 0)
2694 break;
2695 if (len != sizeof(hdr)) {
2696 tcc_error_noabort("invalid archive");
2697 return -1;
2699 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2700 ar_size[sizeof(hdr.ar_size)] = '\0';
2701 size = strtol(ar_size, NULL, 0);
2702 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2703 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2704 if (ar_name[i] != ' ')
2705 break;
2707 ar_name[i + 1] = '\0';
2708 file_offset = lseek(fd, 0, SEEK_CUR);
2709 /* align to even */
2710 size = (size + 1) & ~1;
2711 if (!strcmp(ar_name, "/")) {
2712 /* coff symbol table : we handle it */
2713 if(s1->alacarte_link)
2714 return tcc_load_alacarte(s1, fd, size, 4);
2715 } else if (!strcmp(ar_name, "/SYM64/")) {
2716 if(s1->alacarte_link)
2717 return tcc_load_alacarte(s1, fd, size, 8);
2718 } else {
2719 ElfW(Ehdr) ehdr;
2720 if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2721 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2722 return -1;
2725 lseek(fd, file_offset + size, SEEK_SET);
2727 return 0;
2730 #ifndef TCC_TARGET_PE
2731 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2732 is referenced by the user (so it should be added as DT_NEEDED in
2733 the generated ELF file) */
2734 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2736 ElfW(Ehdr) ehdr;
2737 ElfW(Shdr) *shdr, *sh, *sh1;
2738 int i, j, nb_syms, nb_dts, sym_bind, ret;
2739 ElfW(Sym) *sym, *dynsym;
2740 ElfW(Dyn) *dt, *dynamic;
2741 unsigned char *dynstr;
2742 const char *name, *soname;
2743 DLLReference *dllref;
2745 read(fd, &ehdr, sizeof(ehdr));
2747 /* test CPU specific stuff */
2748 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2749 ehdr.e_machine != EM_TCC_TARGET) {
2750 tcc_error_noabort("bad architecture");
2751 return -1;
2754 /* read sections */
2755 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2757 /* load dynamic section and dynamic symbols */
2758 nb_syms = 0;
2759 nb_dts = 0;
2760 dynamic = NULL;
2761 dynsym = NULL; /* avoid warning */
2762 dynstr = NULL; /* avoid warning */
2763 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2764 switch(sh->sh_type) {
2765 case SHT_DYNAMIC:
2766 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2767 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2768 break;
2769 case SHT_DYNSYM:
2770 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2771 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2772 sh1 = &shdr[sh->sh_link];
2773 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2774 break;
2775 default:
2776 break;
2780 /* compute the real library name */
2781 soname = tcc_basename(filename);
2783 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2784 if (dt->d_tag == DT_SONAME) {
2785 soname = (char *) dynstr + dt->d_un.d_val;
2789 /* if the dll is already loaded, do not load it */
2790 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2791 dllref = s1->loaded_dlls[i];
2792 if (!strcmp(soname, dllref->name)) {
2793 /* but update level if needed */
2794 if (level < dllref->level)
2795 dllref->level = level;
2796 ret = 0;
2797 goto the_end;
2801 /* add the dll and its level */
2802 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2803 dllref->level = level;
2804 strcpy(dllref->name, soname);
2805 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2807 /* add dynamic symbols in dynsym_section */
2808 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2809 sym_bind = ELFW(ST_BIND)(sym->st_info);
2810 if (sym_bind == STB_LOCAL)
2811 continue;
2812 name = (char *) dynstr + sym->st_name;
2813 set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2814 sym->st_info, sym->st_other, sym->st_shndx, name);
2817 /* load all referenced DLLs */
2818 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2819 switch(dt->d_tag) {
2820 case DT_NEEDED:
2821 name = (char *) dynstr + dt->d_un.d_val;
2822 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2823 dllref = s1->loaded_dlls[j];
2824 if (!strcmp(name, dllref->name))
2825 goto already_loaded;
2827 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2828 tcc_error_noabort("referenced dll '%s' not found", name);
2829 ret = -1;
2830 goto the_end;
2832 already_loaded:
2833 break;
2836 ret = 0;
2837 the_end:
2838 tcc_free(dynstr);
2839 tcc_free(dynsym);
2840 tcc_free(dynamic);
2841 tcc_free(shdr);
2842 return ret;
2845 #define LD_TOK_NAME 256
2846 #define LD_TOK_EOF (-1)
2848 /* return next ld script token */
2849 static int ld_next(TCCState *s1, char *name, int name_size)
2851 int c;
2852 char *q;
2854 redo:
2855 switch(ch) {
2856 case ' ':
2857 case '\t':
2858 case '\f':
2859 case '\v':
2860 case '\r':
2861 case '\n':
2862 inp();
2863 goto redo;
2864 case '/':
2865 minp();
2866 if (ch == '*') {
2867 file->buf_ptr = parse_comment(file->buf_ptr);
2868 ch = file->buf_ptr[0];
2869 goto redo;
2870 } else {
2871 q = name;
2872 *q++ = '/';
2873 goto parse_name;
2875 break;
2876 case '\\':
2877 ch = handle_eob();
2878 if (ch != '\\')
2879 goto redo;
2880 /* fall through */
2881 /* case 'a' ... 'z': */
2882 case 'a':
2883 case 'b':
2884 case 'c':
2885 case 'd':
2886 case 'e':
2887 case 'f':
2888 case 'g':
2889 case 'h':
2890 case 'i':
2891 case 'j':
2892 case 'k':
2893 case 'l':
2894 case 'm':
2895 case 'n':
2896 case 'o':
2897 case 'p':
2898 case 'q':
2899 case 'r':
2900 case 's':
2901 case 't':
2902 case 'u':
2903 case 'v':
2904 case 'w':
2905 case 'x':
2906 case 'y':
2907 case 'z':
2908 /* case 'A' ... 'z': */
2909 case 'A':
2910 case 'B':
2911 case 'C':
2912 case 'D':
2913 case 'E':
2914 case 'F':
2915 case 'G':
2916 case 'H':
2917 case 'I':
2918 case 'J':
2919 case 'K':
2920 case 'L':
2921 case 'M':
2922 case 'N':
2923 case 'O':
2924 case 'P':
2925 case 'Q':
2926 case 'R':
2927 case 'S':
2928 case 'T':
2929 case 'U':
2930 case 'V':
2931 case 'W':
2932 case 'X':
2933 case 'Y':
2934 case 'Z':
2935 case '_':
2936 case '.':
2937 case '$':
2938 case '~':
2939 q = name;
2940 parse_name:
2941 for(;;) {
2942 if (!((ch >= 'a' && ch <= 'z') ||
2943 (ch >= 'A' && ch <= 'Z') ||
2944 (ch >= '0' && ch <= '9') ||
2945 strchr("/.-_+=$:\\,~", ch)))
2946 break;
2947 if ((q - name) < name_size - 1) {
2948 *q++ = ch;
2950 minp();
2952 *q = '\0';
2953 c = LD_TOK_NAME;
2954 break;
2955 case CH_EOF:
2956 c = LD_TOK_EOF;
2957 break;
2958 default:
2959 c = ch;
2960 inp();
2961 break;
2963 return c;
2966 static int ld_add_file(TCCState *s1, const char filename[])
2968 int ret;
2970 ret = tcc_add_file_internal(s1, filename, AFF_TYPE_BIN);
2971 if (ret)
2972 ret = tcc_add_dll(s1, filename, 0);
2973 return ret;
2976 static inline int new_undef_syms(void)
2978 int ret = 0;
2979 ret = new_undef_sym;
2980 new_undef_sym = 0;
2981 return ret;
2984 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
2986 char filename[1024], libname[1024];
2987 int t, group, nblibs = 0, ret = 0;
2988 char **libs = NULL;
2990 group = !strcmp(cmd, "GROUP");
2991 if (!as_needed)
2992 new_undef_syms();
2993 t = ld_next(s1, filename, sizeof(filename));
2994 if (t != '(')
2995 expect("(");
2996 t = ld_next(s1, filename, sizeof(filename));
2997 for(;;) {
2998 libname[0] = '\0';
2999 if (t == LD_TOK_EOF) {
3000 tcc_error_noabort("unexpected end of file");
3001 ret = -1;
3002 goto lib_parse_error;
3003 } else if (t == ')') {
3004 break;
3005 } else if (t == '-') {
3006 t = ld_next(s1, filename, sizeof(filename));
3007 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3008 tcc_error_noabort("library name expected");
3009 ret = -1;
3010 goto lib_parse_error;
3012 pstrcpy(libname, sizeof libname, &filename[1]);
3013 if (s1->static_link) {
3014 snprintf(filename, sizeof filename, "lib%s.a", libname);
3015 } else {
3016 snprintf(filename, sizeof filename, "lib%s.so", libname);
3018 } else if (t != LD_TOK_NAME) {
3019 tcc_error_noabort("filename expected");
3020 ret = -1;
3021 goto lib_parse_error;
3023 if (!strcmp(filename, "AS_NEEDED")) {
3024 ret = ld_add_file_list(s1, cmd, 1);
3025 if (ret)
3026 goto lib_parse_error;
3027 } else {
3028 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3029 if (!as_needed) {
3030 ret = ld_add_file(s1, filename);
3031 if (ret)
3032 goto lib_parse_error;
3033 if (group) {
3034 /* Add the filename *and* the libname to avoid future conversions */
3035 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename));
3036 if (libname[0] != '\0')
3037 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname));
3041 t = ld_next(s1, filename, sizeof(filename));
3042 if (t == ',') {
3043 t = ld_next(s1, filename, sizeof(filename));
3046 if (group && !as_needed) {
3047 while (new_undef_syms()) {
3048 int i;
3050 for (i = 0; i < nblibs; i ++)
3051 ld_add_file(s1, libs[i]);
3054 lib_parse_error:
3055 dynarray_reset(&libs, &nblibs);
3056 return ret;
3059 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3060 files */
3061 ST_FUNC int tcc_load_ldscript(TCCState *s1)
3063 char cmd[64];
3064 char filename[1024];
3065 int t, ret;
3067 ch = handle_eob();
3068 for(;;) {
3069 t = ld_next(s1, cmd, sizeof(cmd));
3070 if (t == LD_TOK_EOF)
3071 return 0;
3072 else if (t != LD_TOK_NAME)
3073 return -1;
3074 if (!strcmp(cmd, "INPUT") ||
3075 !strcmp(cmd, "GROUP")) {
3076 ret = ld_add_file_list(s1, cmd, 0);
3077 if (ret)
3078 return ret;
3079 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3080 !strcmp(cmd, "TARGET")) {
3081 /* ignore some commands */
3082 t = ld_next(s1, cmd, sizeof(cmd));
3083 if (t != '(')
3084 expect("(");
3085 for(;;) {
3086 t = ld_next(s1, filename, sizeof(filename));
3087 if (t == LD_TOK_EOF) {
3088 tcc_error_noabort("unexpected end of file");
3089 return -1;
3090 } else if (t == ')') {
3091 break;
3094 } else {
3095 return -1;
3098 return 0;
3100 #endif /* !TCC_TARGET_PE */