Allow PLT/GOT entry for weak static symbol
[tinycc/jakubkaszycki.git] / tccelf.c
blob41b60816e1d4036deda1f3782167014b4b5d2db9
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 ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1013 relocs_info[reloc_type].gotplt_entry == ALWAYS_GOTPLT_ENTRY)
1014 index = put_elf_sym(s1->dynsym, offset, size, info, 0,
1015 sym->st_shndx, name);
1016 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type, index);
1017 } else
1018 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1019 sym_index);
1021 if (need_plt_entry)
1022 return symattr->plt_offset;
1023 else
1024 return symattr->got_offset;
1027 /* build GOT and PLT entries */
1028 ST_FUNC void build_got_entries(TCCState *s1)
1030 Section *s;
1031 ElfW_Rel *rel;
1032 ElfW(Sym) *sym;
1033 int i, type, reloc_type, sym_index;
1035 for(i = 1; i < s1->nb_sections; i++) {
1036 s = s1->sections[i];
1037 if (s->sh_type != SHT_RELX)
1038 continue;
1039 /* no need to handle got relocations */
1040 if (s->link != symtab_section)
1041 continue;
1042 for_each_elem(s, 0, rel, ElfW_Rel) {
1043 type = ELFW(R_TYPE)(rel->r_info);
1044 sym_index = ELFW(R_SYM)(rel->r_info);
1045 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1047 if (type >= R_NUM || !relocs_info[type].known)
1048 tcc_error("Unknown relocation: %d\n", type);
1050 if (relocs_info[type].gotplt_entry == NO_GOTPLT_ENTRY)
1051 continue;
1053 /* Proceed with PLT/GOT [entry] creation if any of the following
1054 condition is met:
1055 - it is an undefined reference (dynamic relocation needed)
1056 - symbol is absolute (probably created by tcc_add_symbol and
1057 thus might be too far from application code)
1058 - relocation requires a PLT/GOT (BUILD_GOTPLT_ENTRY or
1059 ALWAYS_GOTPLT_ENTRY). */
1060 if (sym->st_shndx != SHN_UNDEF &&
1061 sym->st_shndx != SHN_ABS &&
1062 relocs_info[type].gotplt_entry == AUTO_GOTPLT_ENTRY)
1063 continue;
1065 /* Building a dynamic library but target is not capable of PC
1066 relative PLT entries. It can thus only use PLT entries if
1067 it expects one to be used (ALWAYS_GOTPLT_ENTRY). */
1068 if (sym->st_shndx == SHN_UNDEF &&
1069 s1->output_type == TCC_OUTPUT_DLL &&
1070 !PCRELATIVE_DLLPLT &&
1071 relocs_info[type].gotplt_entry == AUTO_GOTPLT_ENTRY)
1072 continue;
1074 #ifdef TCC_TARGET_X86_64
1075 if (type == R_X86_64_PLT32 &&
1076 ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT) {
1077 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1078 continue;
1080 #endif
1082 if (!s1->got)
1083 build_got(s1);
1085 if (relocs_info[type].gotplt_entry == BUILD_GOT_ONLY)
1086 continue;
1088 if (relocs_info[type].code_reloc)
1089 reloc_type = R_JMP_SLOT;
1090 else
1091 reloc_type = R_GLOB_DAT;
1092 put_got_entry(s1, reloc_type, type, sym->st_size, sym->st_info,
1093 sym_index);
1098 ST_FUNC Section *new_symtab(TCCState *s1,
1099 const char *symtab_name, int sh_type, int sh_flags,
1100 const char *strtab_name,
1101 const char *hash_name, int hash_sh_flags)
1103 Section *symtab, *strtab, *hash;
1104 int *ptr, nb_buckets;
1106 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1107 symtab->sh_entsize = sizeof(ElfW(Sym));
1108 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1109 put_elf_str(strtab, "");
1110 symtab->link = strtab;
1111 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1113 nb_buckets = 1;
1115 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1116 hash->sh_entsize = sizeof(int);
1117 symtab->hash = hash;
1118 hash->link = symtab;
1120 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1121 ptr[0] = nb_buckets;
1122 ptr[1] = 1;
1123 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1124 return symtab;
1127 /* put dynamic tag */
1128 static void put_dt(Section *dynamic, int dt, addr_t val)
1130 ElfW(Dyn) *dyn;
1131 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1132 dyn->d_tag = dt;
1133 dyn->d_un.d_val = val;
1136 #ifndef TCC_TARGET_PE
1137 static void add_init_array_defines(TCCState *s1, const char *section_name)
1139 Section *s;
1140 long end_offset;
1141 char sym_start[1024];
1142 char sym_end[1024];
1144 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1145 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1147 s = find_section(s1, section_name);
1148 if (!s) {
1149 end_offset = 0;
1150 s = data_section;
1151 } else {
1152 end_offset = s->data_offset;
1155 set_elf_sym(symtab_section,
1156 0, 0,
1157 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1158 s->sh_num, sym_start);
1159 set_elf_sym(symtab_section,
1160 end_offset, 0,
1161 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1162 s->sh_num, sym_end);
1164 #endif
1166 static int tcc_add_support(TCCState *s1, const char *filename)
1168 char buf[1024];
1169 snprintf(buf, sizeof(buf), "%s/"TCC_ARCH_DIR"%s", s1->tcc_lib_path, filename);
1170 return tcc_add_file(s1, buf);
1173 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1175 #ifdef CONFIG_TCC_BCHECK
1176 addr_t *ptr;
1177 int sym_index;
1179 if (0 == s1->do_bounds_check)
1180 return;
1181 /* XXX: add an object file to do that */
1182 ptr = section_ptr_add(bounds_section, sizeof(*ptr));
1183 *ptr = 0;
1184 set_elf_sym(symtab_section, 0, 0,
1185 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1186 bounds_section->sh_num, "__bounds_start");
1187 /* pull bcheck.o from libtcc1.a */
1188 sym_index = set_elf_sym(symtab_section, 0, 0,
1189 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1190 SHN_UNDEF, "__bound_init");
1191 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1192 /* add 'call __bound_init()' in .init section */
1193 Section *init_section = find_section(s1, ".init");
1194 unsigned char *pinit = section_ptr_add(init_section, 5);
1195 pinit[0] = 0xe8;
1196 write32le(pinit + 1, -4);
1197 put_elf_reloc(symtab_section, init_section,
1198 init_section->data_offset - 4, R_386_PC32, sym_index);
1199 /* R_386_PC32 = R_X86_64_PC32 = 2 */
1201 #endif
1204 /* add tcc runtime libraries */
1205 ST_FUNC void tcc_add_runtime(TCCState *s1)
1207 tcc_add_bcheck(s1);
1208 tcc_add_pragma_libs(s1);
1209 /* add libc */
1210 if (!s1->nostdlib) {
1211 tcc_add_library_err(s1, "c");
1212 #ifdef CONFIG_USE_LIBGCC
1213 if (!s1->static_link) {
1214 tcc_add_file(s1, TCC_LIBGCC);
1216 #endif
1217 tcc_add_support(s1, "libtcc1.a");
1218 /* add crt end if not memory output */
1219 if (s1->output_type != TCC_OUTPUT_MEMORY)
1220 tcc_add_crt(s1, "crtn.o");
1224 /* add various standard linker symbols (must be done after the
1225 sections are filled (for example after allocating common
1226 symbols)) */
1227 ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
1229 char buf[1024];
1230 int i;
1231 Section *s;
1233 set_elf_sym(symtab_section,
1234 text_section->data_offset, 0,
1235 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1236 text_section->sh_num, "_etext");
1237 set_elf_sym(symtab_section,
1238 data_section->data_offset, 0,
1239 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1240 data_section->sh_num, "_edata");
1241 set_elf_sym(symtab_section,
1242 bss_section->data_offset, 0,
1243 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1244 bss_section->sh_num, "_end");
1245 #ifndef TCC_TARGET_PE
1246 /* horrible new standard ldscript defines */
1247 add_init_array_defines(s1, ".preinit_array");
1248 add_init_array_defines(s1, ".init_array");
1249 add_init_array_defines(s1, ".fini_array");
1250 #endif
1252 /* add start and stop symbols for sections whose name can be
1253 expressed in C */
1254 for(i = 1; i < s1->nb_sections; i++) {
1255 s = s1->sections[i];
1256 if (s->sh_type == SHT_PROGBITS &&
1257 (s->sh_flags & SHF_ALLOC)) {
1258 const char *p;
1259 int ch;
1261 /* check if section name can be expressed in C */
1262 p = s->name;
1263 for(;;) {
1264 ch = *p;
1265 if (!ch)
1266 break;
1267 if (!isid(ch) && !isnum(ch))
1268 goto next_sec;
1269 p++;
1271 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1272 set_elf_sym(symtab_section,
1273 0, 0,
1274 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1275 s->sh_num, buf);
1276 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1277 set_elf_sym(symtab_section,
1278 s->data_offset, 0,
1279 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1280 s->sh_num, buf);
1282 next_sec: ;
1286 static void tcc_output_binary(TCCState *s1, FILE *f,
1287 const int *sec_order)
1289 Section *s;
1290 int i, offset, size;
1292 offset = 0;
1293 for(i=1;i<s1->nb_sections;i++) {
1294 s = s1->sections[sec_order[i]];
1295 if (s->sh_type != SHT_NOBITS &&
1296 (s->sh_flags & SHF_ALLOC)) {
1297 while (offset < s->sh_offset) {
1298 fputc(0, f);
1299 offset++;
1301 size = s->sh_size;
1302 fwrite(s->data, 1, size, f);
1303 offset += size;
1308 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1309 #define HAVE_PHDR 1
1310 #define EXTRA_RELITEMS 14
1312 /* move the relocation value from .dynsym to .got */
1313 static void patch_dynsym_undef(TCCState *s1, Section *s)
1315 uint32_t *gotd = (void *)s1->got->data;
1316 ElfW(Sym) *sym;
1318 gotd += 3; /* dummy entries in .got */
1319 /* relocate symbols in .dynsym */
1320 for_each_elem(s, 1, sym, ElfW(Sym)) {
1321 if (sym->st_shndx == SHN_UNDEF) {
1322 *gotd++ = sym->st_value + 6; /* XXX 6 is magic ? */
1323 sym->st_value = 0;
1327 #else
1328 #define HAVE_PHDR 1
1329 #define EXTRA_RELITEMS 9
1331 /* zero plt offsets of weak symbols in .dynsym */
1332 static void patch_dynsym_undef(TCCState *s1, Section *s)
1334 ElfW(Sym) *sym;
1336 for_each_elem(s, 1, sym, ElfW(Sym))
1337 if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
1338 sym->st_value = 0;
1340 #endif
1342 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1344 int sym_index = ELFW(R_SYM) (rel->r_info);
1345 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1346 unsigned long offset;
1348 if (sym_index >= s1->nb_sym_attrs)
1349 return;
1350 offset = s1->sym_attrs[sym_index].got_offset;
1351 section_reserve(s1->got, offset + PTR_SIZE);
1352 #ifdef TCC_TARGET_X86_64
1353 /* only works for x86-64 */
1354 write32le(s1->got->data + offset + 4, sym->st_value >> 32);
1355 #endif
1356 write32le(s1->got->data + offset, sym->st_value & 0xffffffff);
1359 /* Perform relocation to GOT or PLT entries */
1360 ST_FUNC void fill_got(TCCState *s1)
1362 Section *s;
1363 ElfW_Rel *rel;
1364 int i;
1366 for(i = 1; i < s1->nb_sections; i++) {
1367 s = s1->sections[i];
1368 if (s->sh_type != SHT_RELX)
1369 continue;
1370 /* no need to handle got relocations */
1371 if (s->link != symtab_section)
1372 continue;
1373 for_each_elem(s, 0, rel, ElfW_Rel) {
1374 switch (ELFW(R_TYPE) (rel->r_info)) {
1375 case R_X86_64_GOT32:
1376 case R_X86_64_GOTPCREL:
1377 case R_X86_64_GOTPCRELX:
1378 case R_X86_64_REX_GOTPCRELX:
1379 case R_X86_64_PLT32:
1380 fill_got_entry(s1, rel);
1381 break;
1387 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1388 in shared libraries and export non local defined symbols to shared libraries
1389 if -rdynamic switch was given on command line */
1390 static void bind_exe_dynsyms(TCCState *s1)
1392 const char *name;
1393 int sym_index, index;
1394 ElfW(Sym) *sym, *esym;
1395 int type;
1397 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1398 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1399 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1400 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1401 if (sym->st_shndx == SHN_UNDEF) {
1402 name = (char *) symtab_section->link->data + sym->st_name;
1403 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1404 if (sym_index) {
1405 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1406 type = ELFW(ST_TYPE)(esym->st_info);
1407 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1408 /* Indirect functions shall have STT_FUNC type in executable
1409 * dynsym section. Indeed, a dlsym call following a lazy
1410 * resolution would pick the symbol value from the
1411 * executable dynsym entry which would contain the address
1412 * of the function wanted by the caller of dlsym instead of
1413 * the address of the function that would return that
1414 * address */
1415 put_elf_sym(s1->dynsym, 0, esym->st_size,
1416 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1417 name);
1418 } else if (type == STT_OBJECT) {
1419 unsigned long offset;
1420 ElfW(Sym) *dynsym;
1421 offset = bss_section->data_offset;
1422 /* XXX: which alignment ? */
1423 offset = (offset + 16 - 1) & -16;
1424 set_elf_sym (s1->symtab, offset, esym->st_size,
1425 esym->st_info, 0, bss_section->sh_num, name);
1426 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1427 esym->st_info, 0, bss_section->sh_num,
1428 name);
1429 /* Ensure R_COPY works for weak symbol aliases */
1430 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1431 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1432 if ((dynsym->st_value == esym->st_value)
1433 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1434 char *dynname = (char *) s1->dynsymtab_section->link->data
1435 + dynsym->st_name;
1436 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1437 dynsym->st_info, 0,
1438 bss_section->sh_num, dynname);
1439 break;
1443 put_elf_reloc(s1->dynsym, bss_section,
1444 offset, R_COPY, index);
1445 offset += esym->st_size;
1446 bss_section->data_offset = offset;
1448 } else {
1449 /* STB_WEAK undefined symbols are accepted */
1450 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1451 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1452 !strcmp(name, "_fp_hw")) {
1453 } else {
1454 tcc_error_noabort("undefined symbol '%s'", name);
1457 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1458 /* if -rdynamic option, then export all non local symbols */
1459 name = (char *) symtab_section->link->data + sym->st_name;
1460 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1461 0, sym->st_shndx, name);
1466 /* Bind symbols of libraries: export all non local symbols of executable that
1467 are referenced by shared libraries. The reason is that the dynamic loader
1468 search symbol first in executable and then in libraries. Therefore a
1469 reference to a symbol already defined by a library can still be resolved by
1470 a symbol in the executable. */
1471 static void bind_libs_dynsyms(TCCState *s1)
1473 const char *name;
1474 int sym_index;
1475 ElfW(Sym) *sym, *esym;
1477 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1478 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1479 sym_index = find_elf_sym(symtab_section, name);
1480 /* XXX: avoid adding a symbol if already present because of
1481 -rdynamic ? */
1482 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1483 if (sym_index && sym->st_shndx != SHN_UNDEF)
1484 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1485 0, sym->st_shndx, name);
1486 else if (esym->st_shndx == SHN_UNDEF) {
1487 /* weak symbols can stay undefined */
1488 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1489 tcc_warning("undefined dynamic symbol '%s'", name);
1494 /* Export all non local symbols. This is used by shared libraries so that the
1495 non local symbols they define can resolve a reference in another shared
1496 library or in the executable. Correspondingly, it allows undefined local
1497 symbols to be resolved by other shared libraries or by the executable. */
1498 static void export_global_syms(TCCState *s1)
1500 int nb_syms, dynindex, index;
1501 const char *name;
1502 ElfW(Sym) *sym;
1504 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1505 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1506 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1507 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1508 name = (char *) symtab_section->link->data + sym->st_name;
1509 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1510 sym->st_info, 0, sym->st_shndx, name);
1511 index = sym - (ElfW(Sym) *) symtab_section->data;
1512 s1->symtab_to_dynsym[index] = dynindex;
1517 /* relocate the PLT: compute addresses and offsets in the PLT now that final
1518 address for PLT and GOT are known (see fill_program_header) */
1519 ST_FUNC void relocate_plt(TCCState *s1)
1521 uint8_t *p, *p_end;
1523 if (!s1->plt)
1524 return;
1526 p = s1->plt->data;
1527 p_end = p + s1->plt->data_offset;
1528 if (p < p_end) {
1529 #if defined(TCC_TARGET_I386)
1530 add32le(p + 2, s1->got->sh_addr);
1531 add32le(p + 8, s1->got->sh_addr);
1532 p += 16;
1533 while (p < p_end) {
1534 add32le(p + 2, s1->got->sh_addr);
1535 p += 16;
1537 #elif defined(TCC_TARGET_X86_64)
1538 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
1539 add32le(p + 2, x);
1540 add32le(p + 8, x - 6);
1541 p += 16;
1542 while (p < p_end) {
1543 add32le(p + 2, x + s1->plt->data - p);
1544 p += 16;
1546 #elif defined(TCC_TARGET_ARM)
1547 int x = s1->got->sh_addr - s1->plt->sh_addr - 12;
1548 write32le(s1->plt->data + 16, x - 16);
1549 p += 20;
1550 while (p < p_end) {
1551 if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
1552 p += 4;
1553 add32le(p + 12, x + s1->plt->data - p);
1554 p += 16;
1556 #elif defined(TCC_TARGET_ARM64)
1557 uint64_t plt = s1->plt->sh_addr;
1558 uint64_t got = s1->got->sh_addr;
1559 uint64_t off = (got >> 12) - (plt >> 12);
1560 if ((off + ((uint32_t)1 << 20)) >> 21)
1561 tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt);
1562 write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
1563 write32le(p + 4, (0x90000010 | // adrp x16,...
1564 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1565 write32le(p + 8, (0xf9400211 | // ldr x17,[x16,#...]
1566 (got & 0xff8) << 7));
1567 write32le(p + 12, (0x91000210 | // add x16,x16,#...
1568 (got & 0xfff) << 10));
1569 write32le(p + 16, 0xd61f0220); // br x17
1570 write32le(p + 20, 0xd503201f); // nop
1571 write32le(p + 24, 0xd503201f); // nop
1572 write32le(p + 28, 0xd503201f); // nop
1573 p += 32;
1574 while (p < p_end) {
1575 uint64_t pc = plt + (p - s1->plt->data);
1576 uint64_t addr = got + read64le(p);
1577 uint64_t off = (addr >> 12) - (pc >> 12);
1578 if ((off + ((uint32_t)1 << 20)) >> 21)
1579 tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc);
1580 write32le(p, (0x90000010 | // adrp x16,...
1581 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1582 write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
1583 (addr & 0xff8) << 7));
1584 write32le(p + 8, (0x91000210 | // add x16,x16,#...
1585 (addr & 0xfff) << 10));
1586 write32le(p + 12, 0xd61f0220); // br x17
1587 p += 16;
1589 #elif defined(TCC_TARGET_C67)
1590 /* XXX: TODO */
1591 #else
1592 #error unsupported CPU
1593 #endif
1597 /* Allocate strings for section names and decide if an unallocated section
1598 should be output.
1600 NOTE: the strsec section comes last, so its size is also correct ! */
1601 static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1603 int i;
1604 Section *s;
1606 /* Allocate strings for section names */
1607 for(i = 1; i < s1->nb_sections; i++) {
1608 s = s1->sections[i];
1609 s->sh_name = put_elf_str(strsec, s->name);
1610 /* when generating a DLL, we include relocations but we may
1611 patch them */
1612 if (file_type == TCC_OUTPUT_DLL &&
1613 s->sh_type == SHT_RELX &&
1614 !(s->sh_flags & SHF_ALLOC)) {
1615 /* gr: avoid bogus relocs for empty (debug) sections */
1616 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1617 prepare_dynamic_rel(s1, s);
1618 else if (s1->do_debug)
1619 s->sh_size = s->data_offset;
1620 } else if (s1->do_debug ||
1621 file_type == TCC_OUTPUT_OBJ ||
1622 (s->sh_flags & SHF_ALLOC) ||
1623 i == (s1->nb_sections - 1)) {
1624 /* we output all sections if debug or object file */
1625 s->sh_size = s->data_offset;
1630 /* Info to be copied in dynamic section */
1631 struct dyn_inf {
1632 Section *dynamic;
1633 Section *dynstr;
1634 unsigned long dyn_rel_off;
1635 addr_t rel_addr;
1636 addr_t rel_size;
1637 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1638 addr_t bss_addr;
1639 addr_t bss_size;
1640 #endif
1643 /* Assign sections to segments and decide how are sections laid out when loaded
1644 in memory. This function also fills corresponding program headers. */
1645 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1646 Section *interp, Section* strsec,
1647 struct dyn_inf *dyninf, int *sec_order)
1649 int i, j, k, file_type, sh_order_index, file_offset;
1650 unsigned long s_align;
1651 long long tmp;
1652 addr_t addr;
1653 ElfW(Phdr) *ph;
1654 Section *s;
1656 file_type = s1->output_type;
1657 sh_order_index = 1;
1658 file_offset = 0;
1659 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1660 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1661 s_align = ELF_PAGE_SIZE;
1662 if (s1->section_align)
1663 s_align = s1->section_align;
1665 if (phnum > 0) {
1666 if (s1->has_text_addr) {
1667 int a_offset, p_offset;
1668 addr = s1->text_addr;
1669 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1670 ELF_PAGE_SIZE */
1671 a_offset = (int) (addr & (s_align - 1));
1672 p_offset = file_offset & (s_align - 1);
1673 if (a_offset < p_offset)
1674 a_offset += s_align;
1675 file_offset += (a_offset - p_offset);
1676 } else {
1677 if (file_type == TCC_OUTPUT_DLL)
1678 addr = 0;
1679 else
1680 addr = ELF_START_ADDR;
1681 /* compute address after headers */
1682 addr += (file_offset & (s_align - 1));
1685 ph = &phdr[0];
1686 /* Leave one program headers for the program interpreter and one for
1687 the program header table itself if needed. These are done later as
1688 they require section layout to be done first. */
1689 if (interp)
1690 ph += 1 + HAVE_PHDR;
1692 /* dynamic relocation table information, for .dynamic section */
1693 dyninf->rel_addr = dyninf->rel_size = 0;
1694 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1695 dyninf->bss_addr = dyninf->bss_size = 0;
1696 #endif
1698 for(j = 0; j < 2; j++) {
1699 ph->p_type = PT_LOAD;
1700 if (j == 0)
1701 ph->p_flags = PF_R | PF_X;
1702 else
1703 ph->p_flags = PF_R | PF_W;
1704 ph->p_align = s_align;
1706 /* Decide the layout of sections loaded in memory. This must
1707 be done before program headers are filled since they contain
1708 info about the layout. We do the following ordering: interp,
1709 symbol tables, relocations, progbits, nobits */
1710 /* XXX: do faster and simpler sorting */
1711 for(k = 0; k < 5; k++) {
1712 for(i = 1; i < s1->nb_sections; i++) {
1713 s = s1->sections[i];
1714 /* compute if section should be included */
1715 if (j == 0) {
1716 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1717 SHF_ALLOC)
1718 continue;
1719 } else {
1720 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1721 (SHF_ALLOC | SHF_WRITE))
1722 continue;
1724 if (s == interp) {
1725 if (k != 0)
1726 continue;
1727 } else if (s->sh_type == SHT_DYNSYM ||
1728 s->sh_type == SHT_STRTAB ||
1729 s->sh_type == SHT_HASH) {
1730 if (k != 1)
1731 continue;
1732 } else if (s->sh_type == SHT_RELX) {
1733 if (k != 2)
1734 continue;
1735 } else if (s->sh_type == SHT_NOBITS) {
1736 if (k != 4)
1737 continue;
1738 } else {
1739 if (k != 3)
1740 continue;
1742 sec_order[sh_order_index++] = i;
1744 /* section matches: we align it and add its size */
1745 tmp = addr;
1746 addr = (addr + s->sh_addralign - 1) &
1747 ~(s->sh_addralign - 1);
1748 file_offset += (int) ( addr - tmp );
1749 s->sh_offset = file_offset;
1750 s->sh_addr = addr;
1752 /* update program header infos */
1753 if (ph->p_offset == 0) {
1754 ph->p_offset = file_offset;
1755 ph->p_vaddr = addr;
1756 ph->p_paddr = ph->p_vaddr;
1758 /* update dynamic relocation infos */
1759 if (s->sh_type == SHT_RELX) {
1760 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1761 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1762 dyninf->rel_addr = addr;
1763 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1765 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1766 dyninf->bss_addr = addr;
1767 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1769 #else
1770 if (dyninf->rel_size == 0)
1771 dyninf->rel_addr = addr;
1772 dyninf->rel_size += s->sh_size;
1773 #endif
1775 addr += s->sh_size;
1776 if (s->sh_type != SHT_NOBITS)
1777 file_offset += s->sh_size;
1780 if (j == 0) {
1781 /* Make the first PT_LOAD segment include the program
1782 headers itself (and the ELF header as well), it'll
1783 come out with same memory use but will make various
1784 tools like binutils strip work better. */
1785 ph->p_offset &= ~(ph->p_align - 1);
1786 ph->p_vaddr &= ~(ph->p_align - 1);
1787 ph->p_paddr &= ~(ph->p_align - 1);
1789 ph->p_filesz = file_offset - ph->p_offset;
1790 ph->p_memsz = addr - ph->p_vaddr;
1791 ph++;
1792 if (j == 0) {
1793 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1794 /* if in the middle of a page, we duplicate the page in
1795 memory so that one copy is RX and the other is RW */
1796 if ((addr & (s_align - 1)) != 0)
1797 addr += s_align;
1798 } else {
1799 addr = (addr + s_align - 1) & ~(s_align - 1);
1800 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1806 /* all other sections come after */
1807 for(i = 1; i < s1->nb_sections; i++) {
1808 s = s1->sections[i];
1809 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1810 continue;
1811 sec_order[sh_order_index++] = i;
1813 file_offset = (file_offset + s->sh_addralign - 1) &
1814 ~(s->sh_addralign - 1);
1815 s->sh_offset = file_offset;
1816 if (s->sh_type != SHT_NOBITS)
1817 file_offset += s->sh_size;
1820 return file_offset;
1823 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1824 Section *dynamic)
1826 ElfW(Phdr) *ph;
1828 /* if interpreter, then add corresponding program header */
1829 if (interp) {
1830 ph = &phdr[0];
1832 if (HAVE_PHDR)
1834 int len = phnum * sizeof(ElfW(Phdr));
1836 ph->p_type = PT_PHDR;
1837 ph->p_offset = sizeof(ElfW(Ehdr));
1838 ph->p_vaddr = interp->sh_addr - len;
1839 ph->p_paddr = ph->p_vaddr;
1840 ph->p_filesz = ph->p_memsz = len;
1841 ph->p_flags = PF_R | PF_X;
1842 ph->p_align = 4; /* interp->sh_addralign; */
1843 ph++;
1846 ph->p_type = PT_INTERP;
1847 ph->p_offset = interp->sh_offset;
1848 ph->p_vaddr = interp->sh_addr;
1849 ph->p_paddr = ph->p_vaddr;
1850 ph->p_filesz = interp->sh_size;
1851 ph->p_memsz = interp->sh_size;
1852 ph->p_flags = PF_R;
1853 ph->p_align = interp->sh_addralign;
1856 /* if dynamic section, then add corresponding program header */
1857 if (dynamic) {
1858 ph = &phdr[phnum - 1];
1860 ph->p_type = PT_DYNAMIC;
1861 ph->p_offset = dynamic->sh_offset;
1862 ph->p_vaddr = dynamic->sh_addr;
1863 ph->p_paddr = ph->p_vaddr;
1864 ph->p_filesz = dynamic->sh_size;
1865 ph->p_memsz = dynamic->sh_size;
1866 ph->p_flags = PF_R | PF_W;
1867 ph->p_align = dynamic->sh_addralign;
1871 /* Fill the dynamic section with tags describing the address and size of
1872 sections */
1873 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
1875 Section *dynamic;
1877 dynamic = dyninf->dynamic;
1879 /* put dynamic section entries */
1880 dynamic->data_offset = dyninf->dyn_rel_off;
1881 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1882 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
1883 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1884 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
1885 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1886 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1887 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
1888 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
1889 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
1890 #else
1891 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1892 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
1893 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
1894 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
1895 put_dt(dynamic, DT_PLTREL, DT_REL);
1896 put_dt(dynamic, DT_REL, dyninf->bss_addr);
1897 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
1898 #else
1899 put_dt(dynamic, DT_REL, dyninf->rel_addr);
1900 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
1901 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1902 #endif
1903 #endif
1904 if (s1->do_debug)
1905 put_dt(dynamic, DT_DEBUG, 0);
1906 put_dt(dynamic, DT_NULL, 0);
1909 /* Relocate remaining sections and symbols (that is those not related to
1910 dynamic linking) */
1911 static int final_sections_reloc(TCCState *s1)
1913 int i;
1914 Section *s;
1916 relocate_syms(s1, s1->symtab, 0);
1918 if (s1->nb_errors != 0)
1919 return -1;
1921 /* relocate sections */
1922 /* XXX: ignore sections with allocated relocations ? */
1923 for(i = 1; i < s1->nb_sections; i++) {
1924 s = s1->sections[i];
1925 #ifdef TCC_TARGET_I386
1926 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
1927 /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
1928 checking is removed */
1929 #else
1930 if (s->reloc && s != s1->got)
1931 /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
1932 #endif
1933 relocate_section(s1, s);
1936 /* relocate relocation entries if the relocation tables are
1937 allocated in the executable */
1938 for(i = 1; i < s1->nb_sections; i++) {
1939 s = s1->sections[i];
1940 if ((s->sh_flags & SHF_ALLOC) &&
1941 s->sh_type == SHT_RELX) {
1942 relocate_rel(s1, s);
1945 return 0;
1948 /* Create an ELF file on disk.
1949 This function handle ELF specific layout requirements */
1950 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
1951 int file_offset, int *sec_order)
1953 int i, shnum, offset, size, file_type;
1954 Section *s;
1955 ElfW(Ehdr) ehdr;
1956 ElfW(Shdr) shdr, *sh;
1958 file_type = s1->output_type;
1959 shnum = s1->nb_sections;
1961 memset(&ehdr, 0, sizeof(ehdr));
1963 if (phnum > 0) {
1964 ehdr.e_phentsize = sizeof(ElfW(Phdr));
1965 ehdr.e_phnum = phnum;
1966 ehdr.e_phoff = sizeof(ElfW(Ehdr));
1969 /* align to 4 */
1970 file_offset = (file_offset + 3) & -4;
1972 /* fill header */
1973 ehdr.e_ident[0] = ELFMAG0;
1974 ehdr.e_ident[1] = ELFMAG1;
1975 ehdr.e_ident[2] = ELFMAG2;
1976 ehdr.e_ident[3] = ELFMAG3;
1977 ehdr.e_ident[4] = ELFCLASSW;
1978 ehdr.e_ident[5] = ELFDATA2LSB;
1979 ehdr.e_ident[6] = EV_CURRENT;
1980 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1981 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1982 #endif
1983 #ifdef TCC_TARGET_ARM
1984 #ifdef TCC_ARM_EABI
1985 ehdr.e_ident[EI_OSABI] = 0;
1986 ehdr.e_flags = EF_ARM_EABI_VER4;
1987 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
1988 ehdr.e_flags |= EF_ARM_HASENTRY;
1989 if (s1->float_abi == ARM_HARD_FLOAT)
1990 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
1991 else
1992 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
1993 #else
1994 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1995 #endif
1996 #endif
1997 switch(file_type) {
1998 default:
1999 case TCC_OUTPUT_EXE:
2000 ehdr.e_type = ET_EXEC;
2001 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
2002 break;
2003 case TCC_OUTPUT_DLL:
2004 ehdr.e_type = ET_DYN;
2005 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2006 break;
2007 case TCC_OUTPUT_OBJ:
2008 ehdr.e_type = ET_REL;
2009 break;
2011 ehdr.e_machine = EM_TCC_TARGET;
2012 ehdr.e_version = EV_CURRENT;
2013 ehdr.e_shoff = file_offset;
2014 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2015 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2016 ehdr.e_shnum = shnum;
2017 ehdr.e_shstrndx = shnum - 1;
2019 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2020 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2021 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2023 sort_syms(s1, symtab_section);
2024 for(i = 1; i < s1->nb_sections; i++) {
2025 s = s1->sections[sec_order[i]];
2026 if (s->sh_type != SHT_NOBITS) {
2027 if (s->sh_type == SHT_DYNSYM)
2028 patch_dynsym_undef(s1, s);
2029 while (offset < s->sh_offset) {
2030 fputc(0, f);
2031 offset++;
2033 size = s->sh_size;
2034 if (size)
2035 fwrite(s->data, 1, size, f);
2036 offset += size;
2040 /* output section headers */
2041 while (offset < ehdr.e_shoff) {
2042 fputc(0, f);
2043 offset++;
2046 for(i = 0; i < s1->nb_sections; i++) {
2047 sh = &shdr;
2048 memset(sh, 0, sizeof(ElfW(Shdr)));
2049 s = s1->sections[i];
2050 if (s) {
2051 sh->sh_name = s->sh_name;
2052 sh->sh_type = s->sh_type;
2053 sh->sh_flags = s->sh_flags;
2054 sh->sh_entsize = s->sh_entsize;
2055 sh->sh_info = s->sh_info;
2056 if (s->link)
2057 sh->sh_link = s->link->sh_num;
2058 sh->sh_addralign = s->sh_addralign;
2059 sh->sh_addr = s->sh_addr;
2060 sh->sh_offset = s->sh_offset;
2061 sh->sh_size = s->sh_size;
2063 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2067 /* Write an elf, coff or "binary" file */
2068 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2069 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2071 int fd, mode, file_type;
2072 FILE *f;
2074 file_type = s1->output_type;
2075 if (file_type == TCC_OUTPUT_OBJ)
2076 mode = 0666;
2077 else
2078 mode = 0777;
2079 unlink(filename);
2080 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2081 if (fd < 0) {
2082 tcc_error_noabort("could not write '%s'", filename);
2083 return -1;
2085 f = fdopen(fd, "wb");
2086 if (s1->verbose)
2087 printf("<- %s\n", filename);
2089 #ifdef TCC_TARGET_COFF
2090 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2091 tcc_output_coff(s1, f);
2092 else
2093 #endif
2094 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2095 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2096 else
2097 tcc_output_binary(s1, f, sec_order);
2098 fclose(f);
2100 return 0;
2103 /* Output an elf, coff or binary file */
2104 /* XXX: suppress unneeded sections */
2105 static int elf_output_file(TCCState *s1, const char *filename)
2107 int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
2108 struct dyn_inf dyninf;
2109 ElfW(Phdr) *phdr;
2110 ElfW(Sym) *sym;
2111 Section *strsec, *interp, *dynamic, *dynstr;
2113 file_type = s1->output_type;
2114 s1->nb_errors = 0;
2116 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2117 if (file_type != TCC_OUTPUT_OBJ) {
2118 tcc_add_runtime(s1);
2121 phdr = NULL;
2122 sec_order = NULL;
2123 interp = dynamic = dynstr = NULL; /* avoid warning */
2124 dyninf.dyn_rel_off = 0; /* avoid warning */
2126 if (file_type != TCC_OUTPUT_OBJ) {
2127 relocate_common_syms();
2129 tcc_add_linker_symbols(s1);
2131 if (!s1->static_link) {
2132 if (file_type == TCC_OUTPUT_EXE) {
2133 char *ptr;
2134 /* allow override the dynamic loader */
2135 const char *elfint = getenv("LD_SO");
2136 if (elfint == NULL)
2137 elfint = DEFAULT_ELFINTERP(s1);
2138 /* add interpreter section only if executable */
2139 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2140 interp->sh_addralign = 1;
2141 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2142 strcpy(ptr, elfint);
2145 /* add dynamic symbol table */
2146 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2147 ".dynstr",
2148 ".hash", SHF_ALLOC);
2149 dynstr = s1->dynsym->link;
2151 /* add dynamic section */
2152 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2153 SHF_ALLOC | SHF_WRITE);
2154 dynamic->link = dynstr;
2155 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2157 build_got(s1);
2159 if (file_type == TCC_OUTPUT_EXE) {
2160 bind_exe_dynsyms(s1);
2162 if (s1->nb_errors) {
2163 ret = -1;
2164 goto the_end;
2167 bind_libs_dynsyms(s1);
2168 } else /* shared library case: simply export all global symbols */
2169 export_global_syms(s1);
2171 build_got_entries(s1);
2173 /* add a list of needed dlls */
2174 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2175 DLLReference *dllref = s1->loaded_dlls[i];
2176 if (dllref->level == 0)
2177 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2180 if (s1->rpath)
2181 put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath));
2183 /* XXX: currently, since we do not handle PIC code, we
2184 must relocate the readonly segments */
2185 if (file_type == TCC_OUTPUT_DLL) {
2186 if (s1->soname)
2187 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2188 put_dt(dynamic, DT_TEXTREL, 0);
2191 if (s1->symbolic)
2192 put_dt(dynamic, DT_SYMBOLIC, 0);
2194 /* add necessary space for other entries */
2195 dyninf.dyn_rel_off = dynamic->data_offset;
2196 dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
2197 } else {
2198 /* still need to build got entries in case of static link */
2199 build_got_entries(s1);
2203 /* we add a section for symbols */
2204 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2205 put_elf_str(strsec, "");
2207 /* compute number of sections */
2208 shnum = s1->nb_sections;
2210 /* this array is used to reorder sections in the output file */
2211 sec_order = tcc_malloc(sizeof(int) * shnum);
2212 sec_order[0] = 0;
2214 /* compute number of program headers */
2215 switch(file_type) {
2216 default:
2217 case TCC_OUTPUT_OBJ:
2218 phnum = 0;
2219 break;
2220 case TCC_OUTPUT_EXE:
2221 if (!s1->static_link)
2222 phnum = 4 + HAVE_PHDR;
2223 else
2224 phnum = 2;
2225 break;
2226 case TCC_OUTPUT_DLL:
2227 phnum = 3;
2228 break;
2231 /* Allocate strings for section names */
2232 alloc_sec_names(s1, file_type, strsec);
2234 /* allocate program segment headers */
2235 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2237 /* compute section to program header mapping */
2238 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2239 sec_order);
2241 /* Fill remaining program header and finalize relocation related to dynamic
2242 linking. */
2243 if (phnum > 0) {
2244 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2245 if (dynamic) {
2246 dyninf.dynamic = dynamic;
2247 dyninf.dynstr = dynstr;
2249 fill_dynamic(s1, &dyninf);
2251 /* put in GOT the dynamic section address and relocate PLT */
2252 write32le(s1->got->data, dynamic->sh_addr);
2253 if (file_type == TCC_OUTPUT_EXE
2254 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
2255 || file_type == TCC_OUTPUT_DLL
2256 #endif
2258 relocate_plt(s1);
2260 /* relocate symbols in .dynsym now that final addresses are known */
2261 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2262 if (sym->st_shndx == SHN_UNDEF) {
2263 /* relocate to PLT if symbol corresponds to a PLT entry,
2264 but not if it's a weak symbol */
2265 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
2266 sym->st_value = 0;
2267 else if (sym->st_value)
2268 sym->st_value += s1->plt->sh_addr;
2269 } else if (sym->st_shndx < SHN_LORESERVE) {
2270 /* do symbol relocation */
2271 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2277 /* if building executable or DLL, then relocate each section
2278 except the GOT which is already relocated */
2279 if (file_type != TCC_OUTPUT_OBJ) {
2280 ret = final_sections_reloc(s1);
2281 if (ret)
2282 goto the_end;
2285 /* Perform relocation to GOT or PLT entries */
2286 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2287 fill_got(s1);
2289 /* Create the ELF file with name 'filename' */
2290 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2291 the_end:
2292 tcc_free(s1->symtab_to_dynsym);
2293 tcc_free(sec_order);
2294 tcc_free(phdr);
2295 tcc_free(s1->sym_attrs);
2296 s1->sym_attrs = NULL;
2297 return ret;
2300 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2302 int ret;
2303 #ifdef TCC_TARGET_PE
2304 if (s->output_type != TCC_OUTPUT_OBJ) {
2305 ret = pe_output_file(s, filename);
2306 } else
2307 #endif
2308 ret = elf_output_file(s, filename);
2309 return ret;
2312 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2314 void *data;
2316 data = tcc_malloc(size);
2317 lseek(fd, file_offset, SEEK_SET);
2318 read(fd, data, size);
2319 return data;
2322 typedef struct SectionMergeInfo {
2323 Section *s; /* corresponding existing section */
2324 unsigned long offset; /* offset of the new section in the existing section */
2325 uint8_t new_section; /* true if section 's' was added */
2326 uint8_t link_once; /* true if link once section */
2327 } SectionMergeInfo;
2329 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2331 int size = read(fd, h, sizeof *h);
2332 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2333 if (h->e_type == ET_REL)
2334 return AFF_BINTYPE_REL;
2335 if (h->e_type == ET_DYN)
2336 return AFF_BINTYPE_DYN;
2337 } else if (size >= 8) {
2338 if (0 == memcmp(h, ARMAG, 8))
2339 return AFF_BINTYPE_AR;
2340 #ifdef TCC_TARGET_COFF
2341 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2342 return AFF_BINTYPE_C67;
2343 #endif
2345 return 0;
2348 /* load an object file and merge it with current files */
2349 /* XXX: handle correctly stab (debug) info */
2350 ST_FUNC int tcc_load_object_file(TCCState *s1,
2351 int fd, unsigned long file_offset)
2353 ElfW(Ehdr) ehdr;
2354 ElfW(Shdr) *shdr, *sh;
2355 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2356 unsigned char *strsec, *strtab;
2357 int *old_to_new_syms;
2358 char *sh_name, *name;
2359 SectionMergeInfo *sm_table, *sm;
2360 ElfW(Sym) *sym, *symtab;
2361 ElfW_Rel *rel;
2362 Section *s;
2364 int stab_index;
2365 int stabstr_index;
2367 stab_index = stabstr_index = 0;
2369 lseek(fd, file_offset, SEEK_SET);
2370 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2371 goto fail1;
2372 /* test CPU specific stuff */
2373 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2374 ehdr.e_machine != EM_TCC_TARGET) {
2375 fail1:
2376 tcc_error_noabort("invalid object file");
2377 return -1;
2379 /* read sections */
2380 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2381 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2382 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2384 /* load section names */
2385 sh = &shdr[ehdr.e_shstrndx];
2386 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2388 /* load symtab and strtab */
2389 old_to_new_syms = NULL;
2390 symtab = NULL;
2391 strtab = NULL;
2392 nb_syms = 0;
2393 for(i = 1; i < ehdr.e_shnum; i++) {
2394 sh = &shdr[i];
2395 if (sh->sh_type == SHT_SYMTAB) {
2396 if (symtab) {
2397 tcc_error_noabort("object must contain only one symtab");
2398 fail:
2399 ret = -1;
2400 goto the_end;
2402 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2403 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2404 sm_table[i].s = symtab_section;
2406 /* now load strtab */
2407 sh = &shdr[sh->sh_link];
2408 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2412 /* now examine each section and try to merge its content with the
2413 ones in memory */
2414 for(i = 1; i < ehdr.e_shnum; i++) {
2415 /* no need to examine section name strtab */
2416 if (i == ehdr.e_shstrndx)
2417 continue;
2418 sh = &shdr[i];
2419 sh_name = (char *) strsec + sh->sh_name;
2420 /* ignore sections types we do not handle */
2421 if (sh->sh_type != SHT_PROGBITS &&
2422 sh->sh_type != SHT_RELX &&
2423 #ifdef TCC_ARM_EABI
2424 sh->sh_type != SHT_ARM_EXIDX &&
2425 #endif
2426 sh->sh_type != SHT_NOBITS &&
2427 sh->sh_type != SHT_PREINIT_ARRAY &&
2428 sh->sh_type != SHT_INIT_ARRAY &&
2429 sh->sh_type != SHT_FINI_ARRAY &&
2430 strcmp(sh_name, ".stabstr")
2432 continue;
2433 if (sh->sh_addralign < 1)
2434 sh->sh_addralign = 1;
2435 /* find corresponding section, if any */
2436 for(j = 1; j < s1->nb_sections;j++) {
2437 s = s1->sections[j];
2438 if (!strcmp(s->name, sh_name)) {
2439 if (!strncmp(sh_name, ".gnu.linkonce",
2440 sizeof(".gnu.linkonce") - 1)) {
2441 /* if a 'linkonce' section is already present, we
2442 do not add it again. It is a little tricky as
2443 symbols can still be defined in
2444 it. */
2445 sm_table[i].link_once = 1;
2446 goto next;
2447 } else {
2448 goto found;
2452 /* not found: create new section */
2453 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2454 /* take as much info as possible from the section. sh_link and
2455 sh_info will be updated later */
2456 s->sh_addralign = sh->sh_addralign;
2457 s->sh_entsize = sh->sh_entsize;
2458 sm_table[i].new_section = 1;
2459 found:
2460 if (sh->sh_type != s->sh_type) {
2461 tcc_error_noabort("invalid section type");
2462 goto fail;
2465 /* align start of section */
2466 offset = s->data_offset;
2468 if (0 == strcmp(sh_name, ".stab")) {
2469 stab_index = i;
2470 goto no_align;
2472 if (0 == strcmp(sh_name, ".stabstr")) {
2473 stabstr_index = i;
2474 goto no_align;
2477 size = sh->sh_addralign - 1;
2478 offset = (offset + size) & ~size;
2479 if (sh->sh_addralign > s->sh_addralign)
2480 s->sh_addralign = sh->sh_addralign;
2481 s->data_offset = offset;
2482 no_align:
2483 sm_table[i].offset = offset;
2484 sm_table[i].s = s;
2485 /* concatenate sections */
2486 size = sh->sh_size;
2487 if (sh->sh_type != SHT_NOBITS) {
2488 unsigned char *ptr;
2489 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2490 ptr = section_ptr_add(s, size);
2491 read(fd, ptr, size);
2492 } else {
2493 s->data_offset += size;
2495 next: ;
2498 /* gr relocate stab strings */
2499 if (stab_index && stabstr_index) {
2500 Stab_Sym *a, *b;
2501 unsigned o;
2502 s = sm_table[stab_index].s;
2503 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2504 b = (Stab_Sym *)(s->data + s->data_offset);
2505 o = sm_table[stabstr_index].offset;
2506 while (a < b)
2507 a->n_strx += o, a++;
2510 /* second short pass to update sh_link and sh_info fields of new
2511 sections */
2512 for(i = 1; i < ehdr.e_shnum; i++) {
2513 s = sm_table[i].s;
2514 if (!s || !sm_table[i].new_section)
2515 continue;
2516 sh = &shdr[i];
2517 if (sh->sh_link > 0)
2518 s->link = sm_table[sh->sh_link].s;
2519 if (sh->sh_type == SHT_RELX) {
2520 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2521 /* update backward link */
2522 s1->sections[s->sh_info]->reloc = s;
2525 sm = sm_table;
2527 /* resolve symbols */
2528 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2530 sym = symtab + 1;
2531 for(i = 1; i < nb_syms; i++, sym++) {
2532 if (sym->st_shndx != SHN_UNDEF &&
2533 sym->st_shndx < SHN_LORESERVE) {
2534 sm = &sm_table[sym->st_shndx];
2535 if (sm->link_once) {
2536 /* if a symbol is in a link once section, we use the
2537 already defined symbol. It is very important to get
2538 correct relocations */
2539 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2540 name = (char *) strtab + sym->st_name;
2541 sym_index = find_elf_sym(symtab_section, name);
2542 if (sym_index)
2543 old_to_new_syms[i] = sym_index;
2545 continue;
2547 /* if no corresponding section added, no need to add symbol */
2548 if (!sm->s)
2549 continue;
2550 /* convert section number */
2551 sym->st_shndx = sm->s->sh_num;
2552 /* offset value */
2553 sym->st_value += sm->offset;
2555 /* add symbol */
2556 name = (char *) strtab + sym->st_name;
2557 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2558 sym->st_info, sym->st_other,
2559 sym->st_shndx, name);
2560 old_to_new_syms[i] = sym_index;
2563 /* third pass to patch relocation entries */
2564 for(i = 1; i < ehdr.e_shnum; i++) {
2565 s = sm_table[i].s;
2566 if (!s)
2567 continue;
2568 sh = &shdr[i];
2569 offset = sm_table[i].offset;
2570 switch(s->sh_type) {
2571 case SHT_RELX:
2572 /* take relocation offset information */
2573 offseti = sm_table[sh->sh_info].offset;
2574 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2575 int type;
2576 unsigned sym_index;
2577 /* convert symbol index */
2578 type = ELFW(R_TYPE)(rel->r_info);
2579 sym_index = ELFW(R_SYM)(rel->r_info);
2580 /* NOTE: only one symtab assumed */
2581 if (sym_index >= nb_syms)
2582 goto invalid_reloc;
2583 sym_index = old_to_new_syms[sym_index];
2584 /* ignore link_once in rel section. */
2585 if (!sym_index && !sm->link_once
2586 #ifdef TCC_TARGET_ARM
2587 && type != R_ARM_V4BX
2588 #endif
2590 invalid_reloc:
2591 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2592 i, strsec + sh->sh_name, rel->r_offset);
2593 goto fail;
2595 rel->r_info = ELFW(R_INFO)(sym_index, type);
2596 /* offset the relocation offset */
2597 rel->r_offset += offseti;
2598 #ifdef TCC_TARGET_ARM
2599 /* Jumps and branches from a Thumb code to a PLT entry need
2600 special handling since PLT entries are ARM code.
2601 Unconditional bl instructions referencing PLT entries are
2602 handled by converting these instructions into blx
2603 instructions. Other case of instructions referencing a PLT
2604 entry require to add a Thumb stub before the PLT entry to
2605 switch to ARM mode. We set bit plt_thumb_stub of the
2606 attribute of a symbol to indicate such a case. */
2607 if (type == R_ARM_THM_JUMP24)
2608 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2609 #endif
2611 break;
2612 default:
2613 break;
2617 ret = 0;
2618 the_end:
2619 tcc_free(symtab);
2620 tcc_free(strtab);
2621 tcc_free(old_to_new_syms);
2622 tcc_free(sm_table);
2623 tcc_free(strsec);
2624 tcc_free(shdr);
2625 return ret;
2628 typedef struct ArchiveHeader {
2629 char ar_name[16]; /* name of this member */
2630 char ar_date[12]; /* file mtime */
2631 char ar_uid[6]; /* owner uid; printed as decimal */
2632 char ar_gid[6]; /* owner gid; printed as decimal */
2633 char ar_mode[8]; /* file mode, printed as octal */
2634 char ar_size[10]; /* file size, printed as decimal */
2635 char ar_fmag[2]; /* should contain ARFMAG */
2636 } ArchiveHeader;
2638 static int get_be32(const uint8_t *b)
2640 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2643 static long get_be64(const uint8_t *b)
2645 long long ret = get_be32(b);
2646 ret = (ret << 32) | (unsigned)get_be32(b+4);
2647 return (long)ret;
2650 /* load only the objects which resolve undefined symbols */
2651 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2653 long i, bound, nsyms, sym_index, off, ret;
2654 uint8_t *data;
2655 const char *ar_names, *p;
2656 const uint8_t *ar_index;
2657 ElfW(Sym) *sym;
2659 data = tcc_malloc(size);
2660 if (read(fd, data, size) != size)
2661 goto fail;
2662 nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
2663 ar_index = data + entrysize;
2664 ar_names = (char *) ar_index + nsyms * entrysize;
2666 do {
2667 bound = 0;
2668 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2669 sym_index = find_elf_sym(symtab_section, p);
2670 if(sym_index) {
2671 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2672 if(sym->st_shndx == SHN_UNDEF) {
2673 off = (entrysize == 4
2674 ? get_be32(ar_index + i * 4)
2675 : get_be64(ar_index + i * 8))
2676 + sizeof(ArchiveHeader);
2677 ++bound;
2678 if(tcc_load_object_file(s1, fd, off) < 0) {
2679 fail:
2680 ret = -1;
2681 goto the_end;
2686 } while(bound);
2687 ret = 0;
2688 the_end:
2689 tcc_free(data);
2690 return ret;
2693 /* load a '.a' file */
2694 ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
2696 ArchiveHeader hdr;
2697 char ar_size[11];
2698 char ar_name[17];
2699 char magic[8];
2700 int size, len, i;
2701 unsigned long file_offset;
2703 /* skip magic which was already checked */
2704 read(fd, magic, sizeof(magic));
2706 for(;;) {
2707 len = read(fd, &hdr, sizeof(hdr));
2708 if (len == 0)
2709 break;
2710 if (len != sizeof(hdr)) {
2711 tcc_error_noabort("invalid archive");
2712 return -1;
2714 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2715 ar_size[sizeof(hdr.ar_size)] = '\0';
2716 size = strtol(ar_size, NULL, 0);
2717 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2718 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2719 if (ar_name[i] != ' ')
2720 break;
2722 ar_name[i + 1] = '\0';
2723 file_offset = lseek(fd, 0, SEEK_CUR);
2724 /* align to even */
2725 size = (size + 1) & ~1;
2726 if (!strcmp(ar_name, "/")) {
2727 /* coff symbol table : we handle it */
2728 if(s1->alacarte_link)
2729 return tcc_load_alacarte(s1, fd, size, 4);
2730 } else if (!strcmp(ar_name, "/SYM64/")) {
2731 if(s1->alacarte_link)
2732 return tcc_load_alacarte(s1, fd, size, 8);
2733 } else {
2734 ElfW(Ehdr) ehdr;
2735 if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2736 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2737 return -1;
2740 lseek(fd, file_offset + size, SEEK_SET);
2742 return 0;
2745 #ifndef TCC_TARGET_PE
2746 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2747 is referenced by the user (so it should be added as DT_NEEDED in
2748 the generated ELF file) */
2749 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2751 ElfW(Ehdr) ehdr;
2752 ElfW(Shdr) *shdr, *sh, *sh1;
2753 int i, j, nb_syms, nb_dts, sym_bind, ret;
2754 ElfW(Sym) *sym, *dynsym;
2755 ElfW(Dyn) *dt, *dynamic;
2756 unsigned char *dynstr;
2757 const char *name, *soname;
2758 DLLReference *dllref;
2760 read(fd, &ehdr, sizeof(ehdr));
2762 /* test CPU specific stuff */
2763 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2764 ehdr.e_machine != EM_TCC_TARGET) {
2765 tcc_error_noabort("bad architecture");
2766 return -1;
2769 /* read sections */
2770 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2772 /* load dynamic section and dynamic symbols */
2773 nb_syms = 0;
2774 nb_dts = 0;
2775 dynamic = NULL;
2776 dynsym = NULL; /* avoid warning */
2777 dynstr = NULL; /* avoid warning */
2778 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2779 switch(sh->sh_type) {
2780 case SHT_DYNAMIC:
2781 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2782 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2783 break;
2784 case SHT_DYNSYM:
2785 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2786 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2787 sh1 = &shdr[sh->sh_link];
2788 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2789 break;
2790 default:
2791 break;
2795 /* compute the real library name */
2796 soname = tcc_basename(filename);
2798 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2799 if (dt->d_tag == DT_SONAME) {
2800 soname = (char *) dynstr + dt->d_un.d_val;
2804 /* if the dll is already loaded, do not load it */
2805 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2806 dllref = s1->loaded_dlls[i];
2807 if (!strcmp(soname, dllref->name)) {
2808 /* but update level if needed */
2809 if (level < dllref->level)
2810 dllref->level = level;
2811 ret = 0;
2812 goto the_end;
2816 /* add the dll and its level */
2817 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2818 dllref->level = level;
2819 strcpy(dllref->name, soname);
2820 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2822 /* add dynamic symbols in dynsym_section */
2823 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2824 sym_bind = ELFW(ST_BIND)(sym->st_info);
2825 if (sym_bind == STB_LOCAL)
2826 continue;
2827 name = (char *) dynstr + sym->st_name;
2828 set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2829 sym->st_info, sym->st_other, sym->st_shndx, name);
2832 /* load all referenced DLLs */
2833 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2834 switch(dt->d_tag) {
2835 case DT_NEEDED:
2836 name = (char *) dynstr + dt->d_un.d_val;
2837 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2838 dllref = s1->loaded_dlls[j];
2839 if (!strcmp(name, dllref->name))
2840 goto already_loaded;
2842 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2843 tcc_error_noabort("referenced dll '%s' not found", name);
2844 ret = -1;
2845 goto the_end;
2847 already_loaded:
2848 break;
2851 ret = 0;
2852 the_end:
2853 tcc_free(dynstr);
2854 tcc_free(dynsym);
2855 tcc_free(dynamic);
2856 tcc_free(shdr);
2857 return ret;
2860 #define LD_TOK_NAME 256
2861 #define LD_TOK_EOF (-1)
2863 /* return next ld script token */
2864 static int ld_next(TCCState *s1, char *name, int name_size)
2866 int c;
2867 char *q;
2869 redo:
2870 switch(ch) {
2871 case ' ':
2872 case '\t':
2873 case '\f':
2874 case '\v':
2875 case '\r':
2876 case '\n':
2877 inp();
2878 goto redo;
2879 case '/':
2880 minp();
2881 if (ch == '*') {
2882 file->buf_ptr = parse_comment(file->buf_ptr);
2883 ch = file->buf_ptr[0];
2884 goto redo;
2885 } else {
2886 q = name;
2887 *q++ = '/';
2888 goto parse_name;
2890 break;
2891 case '\\':
2892 ch = handle_eob();
2893 if (ch != '\\')
2894 goto redo;
2895 /* fall through */
2896 /* case 'a' ... 'z': */
2897 case 'a':
2898 case 'b':
2899 case 'c':
2900 case 'd':
2901 case 'e':
2902 case 'f':
2903 case 'g':
2904 case 'h':
2905 case 'i':
2906 case 'j':
2907 case 'k':
2908 case 'l':
2909 case 'm':
2910 case 'n':
2911 case 'o':
2912 case 'p':
2913 case 'q':
2914 case 'r':
2915 case 's':
2916 case 't':
2917 case 'u':
2918 case 'v':
2919 case 'w':
2920 case 'x':
2921 case 'y':
2922 case 'z':
2923 /* case 'A' ... 'z': */
2924 case 'A':
2925 case 'B':
2926 case 'C':
2927 case 'D':
2928 case 'E':
2929 case 'F':
2930 case 'G':
2931 case 'H':
2932 case 'I':
2933 case 'J':
2934 case 'K':
2935 case 'L':
2936 case 'M':
2937 case 'N':
2938 case 'O':
2939 case 'P':
2940 case 'Q':
2941 case 'R':
2942 case 'S':
2943 case 'T':
2944 case 'U':
2945 case 'V':
2946 case 'W':
2947 case 'X':
2948 case 'Y':
2949 case 'Z':
2950 case '_':
2951 case '.':
2952 case '$':
2953 case '~':
2954 q = name;
2955 parse_name:
2956 for(;;) {
2957 if (!((ch >= 'a' && ch <= 'z') ||
2958 (ch >= 'A' && ch <= 'Z') ||
2959 (ch >= '0' && ch <= '9') ||
2960 strchr("/.-_+=$:\\,~", ch)))
2961 break;
2962 if ((q - name) < name_size - 1) {
2963 *q++ = ch;
2965 minp();
2967 *q = '\0';
2968 c = LD_TOK_NAME;
2969 break;
2970 case CH_EOF:
2971 c = LD_TOK_EOF;
2972 break;
2973 default:
2974 c = ch;
2975 inp();
2976 break;
2978 return c;
2981 static int ld_add_file(TCCState *s1, const char filename[])
2983 int ret;
2985 ret = tcc_add_file_internal(s1, filename, AFF_TYPE_BIN);
2986 if (ret)
2987 ret = tcc_add_dll(s1, filename, 0);
2988 return ret;
2991 static inline int new_undef_syms(void)
2993 int ret = 0;
2994 ret = new_undef_sym;
2995 new_undef_sym = 0;
2996 return ret;
2999 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3001 char filename[1024], libname[1024];
3002 int t, group, nblibs = 0, ret = 0;
3003 char **libs = NULL;
3005 group = !strcmp(cmd, "GROUP");
3006 if (!as_needed)
3007 new_undef_syms();
3008 t = ld_next(s1, filename, sizeof(filename));
3009 if (t != '(')
3010 expect("(");
3011 t = ld_next(s1, filename, sizeof(filename));
3012 for(;;) {
3013 libname[0] = '\0';
3014 if (t == LD_TOK_EOF) {
3015 tcc_error_noabort("unexpected end of file");
3016 ret = -1;
3017 goto lib_parse_error;
3018 } else if (t == ')') {
3019 break;
3020 } else if (t == '-') {
3021 t = ld_next(s1, filename, sizeof(filename));
3022 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3023 tcc_error_noabort("library name expected");
3024 ret = -1;
3025 goto lib_parse_error;
3027 pstrcpy(libname, sizeof libname, &filename[1]);
3028 if (s1->static_link) {
3029 snprintf(filename, sizeof filename, "lib%s.a", libname);
3030 } else {
3031 snprintf(filename, sizeof filename, "lib%s.so", libname);
3033 } else if (t != LD_TOK_NAME) {
3034 tcc_error_noabort("filename expected");
3035 ret = -1;
3036 goto lib_parse_error;
3038 if (!strcmp(filename, "AS_NEEDED")) {
3039 ret = ld_add_file_list(s1, cmd, 1);
3040 if (ret)
3041 goto lib_parse_error;
3042 } else {
3043 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3044 if (!as_needed) {
3045 ret = ld_add_file(s1, filename);
3046 if (ret)
3047 goto lib_parse_error;
3048 if (group) {
3049 /* Add the filename *and* the libname to avoid future conversions */
3050 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename));
3051 if (libname[0] != '\0')
3052 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname));
3056 t = ld_next(s1, filename, sizeof(filename));
3057 if (t == ',') {
3058 t = ld_next(s1, filename, sizeof(filename));
3061 if (group && !as_needed) {
3062 while (new_undef_syms()) {
3063 int i;
3065 for (i = 0; i < nblibs; i ++)
3066 ld_add_file(s1, libs[i]);
3069 lib_parse_error:
3070 dynarray_reset(&libs, &nblibs);
3071 return ret;
3074 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3075 files */
3076 ST_FUNC int tcc_load_ldscript(TCCState *s1)
3078 char cmd[64];
3079 char filename[1024];
3080 int t, ret;
3082 ch = handle_eob();
3083 for(;;) {
3084 t = ld_next(s1, cmd, sizeof(cmd));
3085 if (t == LD_TOK_EOF)
3086 return 0;
3087 else if (t != LD_TOK_NAME)
3088 return -1;
3089 if (!strcmp(cmd, "INPUT") ||
3090 !strcmp(cmd, "GROUP")) {
3091 ret = ld_add_file_list(s1, cmd, 0);
3092 if (ret)
3093 return ret;
3094 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3095 !strcmp(cmd, "TARGET")) {
3096 /* ignore some commands */
3097 t = ld_next(s1, cmd, sizeof(cmd));
3098 if (t != '(')
3099 expect("(");
3100 for(;;) {
3101 t = ld_next(s1, filename, sizeof(filename));
3102 if (t == LD_TOK_EOF) {
3103 tcc_error_noabort("unexpected end of file");
3104 return -1;
3105 } else if (t == ')') {
3106 break;
3109 } else {
3110 return -1;
3113 return 0;
3115 #endif /* !TCC_TARGET_PE */