arm64: Fix regression introduced by 6245db9.
[tinycc.git] / tccelf.c
blob7f1679dc1d8acc3b7361510c0960dc2c4f43c66f
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];
1046 if (type >= R_NUM || !relocs_info[type].known)
1047 tcc_error("Unknown relocation: %d\n", type);
1049 if (relocs_info[type].gotplt_entry == NO_GOTPLT_ENTRY)
1050 continue;
1052 /* Proceed with PLT/GOT [entry] creation if any of the following
1053 condition is met:
1054 - it is an undefined reference (dynamic relocation needed)
1055 - symbol is absolute (probably created by tcc_add_symbol)
1056 - relocation requires a PLT/GOT (BUILD_GOTPLT_ENTRY or
1057 ALWAYS_GOTPLT_ENTRY). */
1058 if (sym->st_shndx != SHN_UNDEF &&
1059 sym->st_shndx != SHN_ABS &&
1060 relocs_info[type].gotplt_entry == AUTO_GOTPLT_ENTRY)
1061 continue;
1063 #ifdef TCC_TARGET_X86_64
1064 if (type == R_X86_64_PLT32 &&
1065 ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT) {
1066 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1067 continue;
1069 #endif
1071 if (!s1->got)
1072 build_got(s1);
1074 if (relocs_info[type].gotplt_entry == BUILD_GOT_ONLY)
1075 continue;
1077 if (relocs_info[type].code_reloc)
1078 reloc_type = R_JMP_SLOT;
1079 else
1080 reloc_type = R_GLOB_DAT;
1081 put_got_entry(s1, reloc_type, type, sym->st_size, sym->st_info,
1082 sym_index);
1087 ST_FUNC Section *new_symtab(TCCState *s1,
1088 const char *symtab_name, int sh_type, int sh_flags,
1089 const char *strtab_name,
1090 const char *hash_name, int hash_sh_flags)
1092 Section *symtab, *strtab, *hash;
1093 int *ptr, nb_buckets;
1095 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1096 symtab->sh_entsize = sizeof(ElfW(Sym));
1097 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1098 put_elf_str(strtab, "");
1099 symtab->link = strtab;
1100 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1102 nb_buckets = 1;
1104 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1105 hash->sh_entsize = sizeof(int);
1106 symtab->hash = hash;
1107 hash->link = symtab;
1109 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1110 ptr[0] = nb_buckets;
1111 ptr[1] = 1;
1112 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1113 return symtab;
1116 /* put dynamic tag */
1117 static void put_dt(Section *dynamic, int dt, addr_t val)
1119 ElfW(Dyn) *dyn;
1120 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1121 dyn->d_tag = dt;
1122 dyn->d_un.d_val = val;
1125 #ifndef TCC_TARGET_PE
1126 static void add_init_array_defines(TCCState *s1, const char *section_name)
1128 Section *s;
1129 long end_offset;
1130 char sym_start[1024];
1131 char sym_end[1024];
1133 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1134 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1136 s = find_section(s1, section_name);
1137 if (!s) {
1138 end_offset = 0;
1139 s = data_section;
1140 } else {
1141 end_offset = s->data_offset;
1144 set_elf_sym(symtab_section,
1145 0, 0,
1146 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1147 s->sh_num, sym_start);
1148 set_elf_sym(symtab_section,
1149 end_offset, 0,
1150 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1151 s->sh_num, sym_end);
1153 #endif
1155 static int tcc_add_support(TCCState *s1, const char *filename)
1157 char buf[1024];
1158 snprintf(buf, sizeof(buf), "%s/"TCC_ARCH_DIR"%s", s1->tcc_lib_path, filename);
1159 return tcc_add_file(s1, buf);
1162 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1164 #ifdef CONFIG_TCC_BCHECK
1165 addr_t *ptr;
1166 int sym_index;
1168 if (0 == s1->do_bounds_check)
1169 return;
1170 /* XXX: add an object file to do that */
1171 ptr = section_ptr_add(bounds_section, sizeof(*ptr));
1172 *ptr = 0;
1173 set_elf_sym(symtab_section, 0, 0,
1174 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1175 bounds_section->sh_num, "__bounds_start");
1176 /* pull bcheck.o from libtcc1.a */
1177 sym_index = set_elf_sym(symtab_section, 0, 0,
1178 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1179 SHN_UNDEF, "__bound_init");
1180 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1181 /* add 'call __bound_init()' in .init section */
1182 Section *init_section = find_section(s1, ".init");
1183 unsigned char *pinit = section_ptr_add(init_section, 5);
1184 pinit[0] = 0xe8;
1185 write32le(pinit + 1, -4);
1186 put_elf_reloc(symtab_section, init_section,
1187 init_section->data_offset - 4, R_386_PC32, sym_index);
1188 /* R_386_PC32 = R_X86_64_PC32 = 2 */
1190 #endif
1193 /* add tcc runtime libraries */
1194 ST_FUNC void tcc_add_runtime(TCCState *s1)
1196 tcc_add_bcheck(s1);
1197 tcc_add_pragma_libs(s1);
1198 /* add libc */
1199 if (!s1->nostdlib) {
1200 tcc_add_library_err(s1, "c");
1201 #ifdef CONFIG_USE_LIBGCC
1202 if (!s1->static_link) {
1203 tcc_add_file(s1, TCC_LIBGCC);
1205 #endif
1206 tcc_add_support(s1, "libtcc1.a");
1207 /* add crt end if not memory output */
1208 if (s1->output_type != TCC_OUTPUT_MEMORY)
1209 tcc_add_crt(s1, "crtn.o");
1213 /* add various standard linker symbols (must be done after the
1214 sections are filled (for example after allocating common
1215 symbols)) */
1216 ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
1218 char buf[1024];
1219 int i;
1220 Section *s;
1222 set_elf_sym(symtab_section,
1223 text_section->data_offset, 0,
1224 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1225 text_section->sh_num, "_etext");
1226 set_elf_sym(symtab_section,
1227 data_section->data_offset, 0,
1228 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1229 data_section->sh_num, "_edata");
1230 set_elf_sym(symtab_section,
1231 bss_section->data_offset, 0,
1232 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1233 bss_section->sh_num, "_end");
1234 #ifndef TCC_TARGET_PE
1235 /* horrible new standard ldscript defines */
1236 add_init_array_defines(s1, ".preinit_array");
1237 add_init_array_defines(s1, ".init_array");
1238 add_init_array_defines(s1, ".fini_array");
1239 #endif
1241 /* add start and stop symbols for sections whose name can be
1242 expressed in C */
1243 for(i = 1; i < s1->nb_sections; i++) {
1244 s = s1->sections[i];
1245 if (s->sh_type == SHT_PROGBITS &&
1246 (s->sh_flags & SHF_ALLOC)) {
1247 const char *p;
1248 int ch;
1250 /* check if section name can be expressed in C */
1251 p = s->name;
1252 for(;;) {
1253 ch = *p;
1254 if (!ch)
1255 break;
1256 if (!isid(ch) && !isnum(ch))
1257 goto next_sec;
1258 p++;
1260 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1261 set_elf_sym(symtab_section,
1262 0, 0,
1263 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1264 s->sh_num, buf);
1265 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1266 set_elf_sym(symtab_section,
1267 s->data_offset, 0,
1268 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1269 s->sh_num, buf);
1271 next_sec: ;
1275 static void tcc_output_binary(TCCState *s1, FILE *f,
1276 const int *sec_order)
1278 Section *s;
1279 int i, offset, size;
1281 offset = 0;
1282 for(i=1;i<s1->nb_sections;i++) {
1283 s = s1->sections[sec_order[i]];
1284 if (s->sh_type != SHT_NOBITS &&
1285 (s->sh_flags & SHF_ALLOC)) {
1286 while (offset < s->sh_offset) {
1287 fputc(0, f);
1288 offset++;
1290 size = s->sh_size;
1291 fwrite(s->data, 1, size, f);
1292 offset += size;
1297 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1298 #define HAVE_PHDR 1
1299 #define EXTRA_RELITEMS 14
1301 /* move the relocation value from .dynsym to .got */
1302 static void patch_dynsym_undef(TCCState *s1, Section *s)
1304 uint32_t *gotd = (void *)s1->got->data;
1305 ElfW(Sym) *sym;
1307 gotd += 3; /* dummy entries in .got */
1308 /* relocate symbols in .dynsym */
1309 for_each_elem(s, 1, sym, ElfW(Sym)) {
1310 if (sym->st_shndx == SHN_UNDEF) {
1311 *gotd++ = sym->st_value + 6; /* XXX 6 is magic ? */
1312 sym->st_value = 0;
1316 #else
1317 #define HAVE_PHDR 1
1318 #define EXTRA_RELITEMS 9
1320 /* zero plt offsets of weak symbols in .dynsym */
1321 static void patch_dynsym_undef(TCCState *s1, Section *s)
1323 ElfW(Sym) *sym;
1325 for_each_elem(s, 1, sym, ElfW(Sym))
1326 if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
1327 sym->st_value = 0;
1329 #endif
1331 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1333 int sym_index = ELFW(R_SYM) (rel->r_info);
1334 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1335 unsigned long offset;
1337 if (sym_index >= s1->nb_sym_attrs)
1338 return;
1339 offset = s1->sym_attrs[sym_index].got_offset;
1340 section_reserve(s1->got, offset + PTR_SIZE);
1341 #ifdef TCC_TARGET_X86_64
1342 /* only works for x86-64 */
1343 write32le(s1->got->data + offset + 4, sym->st_value >> 32);
1344 #endif
1345 write32le(s1->got->data + offset, sym->st_value & 0xffffffff);
1348 /* Perform relocation to GOT or PLT entries */
1349 ST_FUNC void fill_got(TCCState *s1)
1351 Section *s;
1352 ElfW_Rel *rel;
1353 int i;
1355 for(i = 1; i < s1->nb_sections; i++) {
1356 s = s1->sections[i];
1357 if (s->sh_type != SHT_RELX)
1358 continue;
1359 /* no need to handle got relocations */
1360 if (s->link != symtab_section)
1361 continue;
1362 for_each_elem(s, 0, rel, ElfW_Rel) {
1363 switch (ELFW(R_TYPE) (rel->r_info)) {
1364 case R_X86_64_GOT32:
1365 case R_X86_64_GOTPCREL:
1366 case R_X86_64_GOTPCRELX:
1367 case R_X86_64_REX_GOTPCRELX:
1368 case R_X86_64_PLT32:
1369 fill_got_entry(s1, rel);
1370 break;
1376 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1377 in shared libraries and export non local defined symbols to shared libraries
1378 if -rdynamic switch was given on command line */
1379 static void bind_exe_dynsyms(TCCState *s1)
1381 const char *name;
1382 int sym_index, index;
1383 ElfW(Sym) *sym, *esym;
1384 int type;
1386 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1387 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1388 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1389 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1390 if (sym->st_shndx == SHN_UNDEF) {
1391 name = (char *) symtab_section->link->data + sym->st_name;
1392 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1393 if (sym_index) {
1394 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1395 type = ELFW(ST_TYPE)(esym->st_info);
1396 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1397 /* Indirect functions shall have STT_FUNC type in executable
1398 * dynsym section. Indeed, a dlsym call following a lazy
1399 * resolution would pick the symbol value from the
1400 * executable dynsym entry which would contain the address
1401 * of the function wanted by the caller of dlsym instead of
1402 * the address of the function that would return that
1403 * address */
1404 put_elf_sym(s1->dynsym, 0, esym->st_size,
1405 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1406 name);
1407 } else if (type == STT_OBJECT) {
1408 unsigned long offset;
1409 ElfW(Sym) *dynsym;
1410 offset = bss_section->data_offset;
1411 /* XXX: which alignment ? */
1412 offset = (offset + 16 - 1) & -16;
1413 set_elf_sym (s1->symtab, offset, esym->st_size,
1414 esym->st_info, 0, bss_section->sh_num, name);
1415 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1416 esym->st_info, 0, bss_section->sh_num,
1417 name);
1418 /* Ensure R_COPY works for weak symbol aliases */
1419 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1420 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1421 if ((dynsym->st_value == esym->st_value)
1422 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1423 char *dynname = (char *) s1->dynsymtab_section->link->data
1424 + dynsym->st_name;
1425 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1426 dynsym->st_info, 0,
1427 bss_section->sh_num, dynname);
1428 break;
1432 put_elf_reloc(s1->dynsym, bss_section,
1433 offset, R_COPY, index);
1434 offset += esym->st_size;
1435 bss_section->data_offset = offset;
1437 } else {
1438 /* STB_WEAK undefined symbols are accepted */
1439 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1440 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1441 !strcmp(name, "_fp_hw")) {
1442 } else {
1443 tcc_error_noabort("undefined symbol '%s'", name);
1446 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1447 /* if -rdynamic option, then export all non local symbols */
1448 name = (char *) symtab_section->link->data + sym->st_name;
1449 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1450 0, sym->st_shndx, name);
1455 /* Bind symbols of libraries: export all non local symbols of executable that
1456 are referenced by shared libraries. The reason is that the dynamic loader
1457 search symbol first in executable and then in libraries. Therefore a
1458 reference to a symbol already defined by a library can still be resolved by
1459 a symbol in the executable. */
1460 static void bind_libs_dynsyms(TCCState *s1)
1462 const char *name;
1463 int sym_index;
1464 ElfW(Sym) *sym, *esym;
1466 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1467 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1468 sym_index = find_elf_sym(symtab_section, name);
1469 /* XXX: avoid adding a symbol if already present because of
1470 -rdynamic ? */
1471 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1472 if (sym_index && sym->st_shndx != SHN_UNDEF)
1473 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1474 0, sym->st_shndx, name);
1475 else if (esym->st_shndx == SHN_UNDEF) {
1476 /* weak symbols can stay undefined */
1477 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1478 tcc_warning("undefined dynamic symbol '%s'", name);
1483 /* Export all non local symbols. This is used by shared libraries so that the
1484 non local symbols they define can resolve a reference in another shared
1485 library or in the executable. Correspondingly, it allows undefined local
1486 symbols to be resolved by other shared libraries or by the executable. */
1487 static void export_global_syms(TCCState *s1)
1489 int nb_syms, dynindex, index;
1490 const char *name;
1491 ElfW(Sym) *sym;
1493 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1494 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1495 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1496 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1497 name = (char *) symtab_section->link->data + sym->st_name;
1498 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1499 sym->st_info, 0, sym->st_shndx, name);
1500 index = sym - (ElfW(Sym) *) symtab_section->data;
1501 s1->symtab_to_dynsym[index] = dynindex;
1506 /* relocate the PLT: compute addresses and offsets in the PLT now that final
1507 address for PLT and GOT are known (see fill_program_header) */
1508 ST_FUNC void relocate_plt(TCCState *s1)
1510 uint8_t *p, *p_end;
1512 if (!s1->plt)
1513 return;
1515 p = s1->plt->data;
1516 p_end = p + s1->plt->data_offset;
1517 if (p < p_end) {
1518 #if defined(TCC_TARGET_I386)
1519 add32le(p + 2, s1->got->sh_addr);
1520 add32le(p + 8, s1->got->sh_addr);
1521 p += 16;
1522 while (p < p_end) {
1523 add32le(p + 2, s1->got->sh_addr);
1524 p += 16;
1526 #elif defined(TCC_TARGET_X86_64)
1527 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
1528 add32le(p + 2, x);
1529 add32le(p + 8, x - 6);
1530 p += 16;
1531 while (p < p_end) {
1532 add32le(p + 2, x + s1->plt->data - p);
1533 p += 16;
1535 #elif defined(TCC_TARGET_ARM)
1536 int x = s1->got->sh_addr - s1->plt->sh_addr - 12;
1537 write32le(s1->plt->data + 16, x - 16);
1538 p += 20;
1539 while (p < p_end) {
1540 if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
1541 p += 4;
1542 add32le(p + 12, x + s1->plt->data - p);
1543 p += 16;
1545 #elif defined(TCC_TARGET_ARM64)
1546 uint64_t plt = s1->plt->sh_addr;
1547 uint64_t got = s1->got->sh_addr;
1548 uint64_t off = (got >> 12) - (plt >> 12);
1549 if ((off + ((uint32_t)1 << 20)) >> 21)
1550 tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt);
1551 write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
1552 write32le(p + 4, (0x90000010 | // adrp x16,...
1553 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1554 write32le(p + 8, (0xf9400211 | // ldr x17,[x16,#...]
1555 (got & 0xff8) << 7));
1556 write32le(p + 12, (0x91000210 | // add x16,x16,#...
1557 (got & 0xfff) << 10));
1558 write32le(p + 16, 0xd61f0220); // br x17
1559 write32le(p + 20, 0xd503201f); // nop
1560 write32le(p + 24, 0xd503201f); // nop
1561 write32le(p + 28, 0xd503201f); // nop
1562 p += 32;
1563 while (p < p_end) {
1564 uint64_t pc = plt + (p - s1->plt->data);
1565 uint64_t addr = got + read64le(p);
1566 uint64_t off = (addr >> 12) - (pc >> 12);
1567 if ((off + ((uint32_t)1 << 20)) >> 21)
1568 tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc);
1569 write32le(p, (0x90000010 | // adrp x16,...
1570 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1571 write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
1572 (addr & 0xff8) << 7));
1573 write32le(p + 8, (0x91000210 | // add x16,x16,#...
1574 (addr & 0xfff) << 10));
1575 write32le(p + 12, 0xd61f0220); // br x17
1576 p += 16;
1578 #elif defined(TCC_TARGET_C67)
1579 /* XXX: TODO */
1580 #else
1581 #error unsupported CPU
1582 #endif
1586 /* Allocate strings for section names and decide if an unallocated section
1587 should be output.
1589 NOTE: the strsec section comes last, so its size is also correct ! */
1590 static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1592 int i;
1593 Section *s;
1595 /* Allocate strings for section names */
1596 for(i = 1; i < s1->nb_sections; i++) {
1597 s = s1->sections[i];
1598 s->sh_name = put_elf_str(strsec, s->name);
1599 /* when generating a DLL, we include relocations but we may
1600 patch them */
1601 if (file_type == TCC_OUTPUT_DLL &&
1602 s->sh_type == SHT_RELX &&
1603 !(s->sh_flags & SHF_ALLOC)) {
1604 /* gr: avoid bogus relocs for empty (debug) sections */
1605 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1606 prepare_dynamic_rel(s1, s);
1607 else if (s1->do_debug)
1608 s->sh_size = s->data_offset;
1609 } else if (s1->do_debug ||
1610 file_type == TCC_OUTPUT_OBJ ||
1611 (s->sh_flags & SHF_ALLOC) ||
1612 i == (s1->nb_sections - 1)) {
1613 /* we output all sections if debug or object file */
1614 s->sh_size = s->data_offset;
1619 /* Info to be copied in dynamic section */
1620 struct dyn_inf {
1621 Section *dynamic;
1622 Section *dynstr;
1623 unsigned long dyn_rel_off;
1624 addr_t rel_addr;
1625 addr_t rel_size;
1626 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1627 addr_t bss_addr;
1628 addr_t bss_size;
1629 #endif
1632 /* Assign sections to segments and decide how are sections laid out when loaded
1633 in memory. This function also fills corresponding program headers. */
1634 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1635 Section *interp, Section* strsec,
1636 struct dyn_inf *dyninf, int *sec_order)
1638 int i, j, k, file_type, sh_order_index, file_offset;
1639 unsigned long s_align;
1640 long long tmp;
1641 addr_t addr;
1642 ElfW(Phdr) *ph;
1643 Section *s;
1645 file_type = s1->output_type;
1646 sh_order_index = 1;
1647 file_offset = 0;
1648 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1649 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1650 s_align = ELF_PAGE_SIZE;
1651 if (s1->section_align)
1652 s_align = s1->section_align;
1654 if (phnum > 0) {
1655 if (s1->has_text_addr) {
1656 int a_offset, p_offset;
1657 addr = s1->text_addr;
1658 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1659 ELF_PAGE_SIZE */
1660 a_offset = (int) (addr & (s_align - 1));
1661 p_offset = file_offset & (s_align - 1);
1662 if (a_offset < p_offset)
1663 a_offset += s_align;
1664 file_offset += (a_offset - p_offset);
1665 } else {
1666 if (file_type == TCC_OUTPUT_DLL)
1667 addr = 0;
1668 else
1669 addr = ELF_START_ADDR;
1670 /* compute address after headers */
1671 addr += (file_offset & (s_align - 1));
1674 ph = &phdr[0];
1675 /* Leave one program headers for the program interpreter and one for
1676 the program header table itself if needed. These are done later as
1677 they require section layout to be done first. */
1678 if (interp)
1679 ph += 1 + HAVE_PHDR;
1681 /* dynamic relocation table information, for .dynamic section */
1682 dyninf->rel_addr = dyninf->rel_size = 0;
1683 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1684 dyninf->bss_addr = dyninf->bss_size = 0;
1685 #endif
1687 for(j = 0; j < 2; j++) {
1688 ph->p_type = PT_LOAD;
1689 if (j == 0)
1690 ph->p_flags = PF_R | PF_X;
1691 else
1692 ph->p_flags = PF_R | PF_W;
1693 ph->p_align = s_align;
1695 /* Decide the layout of sections loaded in memory. This must
1696 be done before program headers are filled since they contain
1697 info about the layout. We do the following ordering: interp,
1698 symbol tables, relocations, progbits, nobits */
1699 /* XXX: do faster and simpler sorting */
1700 for(k = 0; k < 5; k++) {
1701 for(i = 1; i < s1->nb_sections; i++) {
1702 s = s1->sections[i];
1703 /* compute if section should be included */
1704 if (j == 0) {
1705 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1706 SHF_ALLOC)
1707 continue;
1708 } else {
1709 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1710 (SHF_ALLOC | SHF_WRITE))
1711 continue;
1713 if (s == interp) {
1714 if (k != 0)
1715 continue;
1716 } else if (s->sh_type == SHT_DYNSYM ||
1717 s->sh_type == SHT_STRTAB ||
1718 s->sh_type == SHT_HASH) {
1719 if (k != 1)
1720 continue;
1721 } else if (s->sh_type == SHT_RELX) {
1722 if (k != 2)
1723 continue;
1724 } else if (s->sh_type == SHT_NOBITS) {
1725 if (k != 4)
1726 continue;
1727 } else {
1728 if (k != 3)
1729 continue;
1731 sec_order[sh_order_index++] = i;
1733 /* section matches: we align it and add its size */
1734 tmp = addr;
1735 addr = (addr + s->sh_addralign - 1) &
1736 ~(s->sh_addralign - 1);
1737 file_offset += (int) ( addr - tmp );
1738 s->sh_offset = file_offset;
1739 s->sh_addr = addr;
1741 /* update program header infos */
1742 if (ph->p_offset == 0) {
1743 ph->p_offset = file_offset;
1744 ph->p_vaddr = addr;
1745 ph->p_paddr = ph->p_vaddr;
1747 /* update dynamic relocation infos */
1748 if (s->sh_type == SHT_RELX) {
1749 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1750 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1751 dyninf->rel_addr = addr;
1752 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1754 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1755 dyninf->bss_addr = addr;
1756 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1758 #else
1759 if (dyninf->rel_size == 0)
1760 dyninf->rel_addr = addr;
1761 dyninf->rel_size += s->sh_size;
1762 #endif
1764 addr += s->sh_size;
1765 if (s->sh_type != SHT_NOBITS)
1766 file_offset += s->sh_size;
1769 if (j == 0) {
1770 /* Make the first PT_LOAD segment include the program
1771 headers itself (and the ELF header as well), it'll
1772 come out with same memory use but will make various
1773 tools like binutils strip work better. */
1774 ph->p_offset &= ~(ph->p_align - 1);
1775 ph->p_vaddr &= ~(ph->p_align - 1);
1776 ph->p_paddr &= ~(ph->p_align - 1);
1778 ph->p_filesz = file_offset - ph->p_offset;
1779 ph->p_memsz = addr - ph->p_vaddr;
1780 ph++;
1781 if (j == 0) {
1782 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1783 /* if in the middle of a page, we duplicate the page in
1784 memory so that one copy is RX and the other is RW */
1785 if ((addr & (s_align - 1)) != 0)
1786 addr += s_align;
1787 } else {
1788 addr = (addr + s_align - 1) & ~(s_align - 1);
1789 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1795 /* all other sections come after */
1796 for(i = 1; i < s1->nb_sections; i++) {
1797 s = s1->sections[i];
1798 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1799 continue;
1800 sec_order[sh_order_index++] = i;
1802 file_offset = (file_offset + s->sh_addralign - 1) &
1803 ~(s->sh_addralign - 1);
1804 s->sh_offset = file_offset;
1805 if (s->sh_type != SHT_NOBITS)
1806 file_offset += s->sh_size;
1809 return file_offset;
1812 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1813 Section *dynamic)
1815 ElfW(Phdr) *ph;
1817 /* if interpreter, then add corresponding program header */
1818 if (interp) {
1819 ph = &phdr[0];
1821 if (HAVE_PHDR)
1823 int len = phnum * sizeof(ElfW(Phdr));
1825 ph->p_type = PT_PHDR;
1826 ph->p_offset = sizeof(ElfW(Ehdr));
1827 ph->p_vaddr = interp->sh_addr - len;
1828 ph->p_paddr = ph->p_vaddr;
1829 ph->p_filesz = ph->p_memsz = len;
1830 ph->p_flags = PF_R | PF_X;
1831 ph->p_align = 4; /* interp->sh_addralign; */
1832 ph++;
1835 ph->p_type = PT_INTERP;
1836 ph->p_offset = interp->sh_offset;
1837 ph->p_vaddr = interp->sh_addr;
1838 ph->p_paddr = ph->p_vaddr;
1839 ph->p_filesz = interp->sh_size;
1840 ph->p_memsz = interp->sh_size;
1841 ph->p_flags = PF_R;
1842 ph->p_align = interp->sh_addralign;
1845 /* if dynamic section, then add corresponding program header */
1846 if (dynamic) {
1847 ph = &phdr[phnum - 1];
1849 ph->p_type = PT_DYNAMIC;
1850 ph->p_offset = dynamic->sh_offset;
1851 ph->p_vaddr = dynamic->sh_addr;
1852 ph->p_paddr = ph->p_vaddr;
1853 ph->p_filesz = dynamic->sh_size;
1854 ph->p_memsz = dynamic->sh_size;
1855 ph->p_flags = PF_R | PF_W;
1856 ph->p_align = dynamic->sh_addralign;
1860 /* Fill the dynamic section with tags describing the address and size of
1861 sections */
1862 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
1864 Section *dynamic;
1866 dynamic = dyninf->dynamic;
1868 /* put dynamic section entries */
1869 dynamic->data_offset = dyninf->dyn_rel_off;
1870 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1871 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
1872 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1873 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
1874 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1875 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1876 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
1877 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
1878 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
1879 #else
1880 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1881 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
1882 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
1883 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
1884 put_dt(dynamic, DT_PLTREL, DT_REL);
1885 put_dt(dynamic, DT_REL, dyninf->bss_addr);
1886 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
1887 #else
1888 put_dt(dynamic, DT_REL, dyninf->rel_addr);
1889 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
1890 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1891 #endif
1892 #endif
1893 if (s1->do_debug)
1894 put_dt(dynamic, DT_DEBUG, 0);
1895 put_dt(dynamic, DT_NULL, 0);
1898 /* Relocate remaining sections and symbols (that is those not related to
1899 dynamic linking) */
1900 static int final_sections_reloc(TCCState *s1)
1902 int i;
1903 Section *s;
1905 relocate_syms(s1, s1->symtab, 0);
1907 if (s1->nb_errors != 0)
1908 return -1;
1910 /* relocate sections */
1911 /* XXX: ignore sections with allocated relocations ? */
1912 for(i = 1; i < s1->nb_sections; i++) {
1913 s = s1->sections[i];
1914 #ifdef TCC_TARGET_I386
1915 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
1916 /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
1917 checking is removed */
1918 #else
1919 if (s->reloc && s != s1->got)
1920 /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
1921 #endif
1922 relocate_section(s1, s);
1925 /* relocate relocation entries if the relocation tables are
1926 allocated in the executable */
1927 for(i = 1; i < s1->nb_sections; i++) {
1928 s = s1->sections[i];
1929 if ((s->sh_flags & SHF_ALLOC) &&
1930 s->sh_type == SHT_RELX) {
1931 relocate_rel(s1, s);
1934 return 0;
1937 /* Create an ELF file on disk.
1938 This function handle ELF specific layout requirements */
1939 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
1940 int file_offset, int *sec_order)
1942 int i, shnum, offset, size, file_type;
1943 Section *s;
1944 ElfW(Ehdr) ehdr;
1945 ElfW(Shdr) shdr, *sh;
1947 file_type = s1->output_type;
1948 shnum = s1->nb_sections;
1950 memset(&ehdr, 0, sizeof(ehdr));
1952 if (phnum > 0) {
1953 ehdr.e_phentsize = sizeof(ElfW(Phdr));
1954 ehdr.e_phnum = phnum;
1955 ehdr.e_phoff = sizeof(ElfW(Ehdr));
1958 /* align to 4 */
1959 file_offset = (file_offset + 3) & -4;
1961 /* fill header */
1962 ehdr.e_ident[0] = ELFMAG0;
1963 ehdr.e_ident[1] = ELFMAG1;
1964 ehdr.e_ident[2] = ELFMAG2;
1965 ehdr.e_ident[3] = ELFMAG3;
1966 ehdr.e_ident[4] = ELFCLASSW;
1967 ehdr.e_ident[5] = ELFDATA2LSB;
1968 ehdr.e_ident[6] = EV_CURRENT;
1969 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1970 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1971 #endif
1972 #ifdef TCC_TARGET_ARM
1973 #ifdef TCC_ARM_EABI
1974 ehdr.e_ident[EI_OSABI] = 0;
1975 ehdr.e_flags = EF_ARM_EABI_VER4;
1976 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
1977 ehdr.e_flags |= EF_ARM_HASENTRY;
1978 if (s1->float_abi == ARM_HARD_FLOAT)
1979 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
1980 else
1981 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
1982 #else
1983 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1984 #endif
1985 #endif
1986 switch(file_type) {
1987 default:
1988 case TCC_OUTPUT_EXE:
1989 ehdr.e_type = ET_EXEC;
1990 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
1991 break;
1992 case TCC_OUTPUT_DLL:
1993 ehdr.e_type = ET_DYN;
1994 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1995 break;
1996 case TCC_OUTPUT_OBJ:
1997 ehdr.e_type = ET_REL;
1998 break;
2000 ehdr.e_machine = EM_TCC_TARGET;
2001 ehdr.e_version = EV_CURRENT;
2002 ehdr.e_shoff = file_offset;
2003 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2004 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2005 ehdr.e_shnum = shnum;
2006 ehdr.e_shstrndx = shnum - 1;
2008 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2009 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2010 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2012 sort_syms(s1, symtab_section);
2013 for(i = 1; i < s1->nb_sections; i++) {
2014 s = s1->sections[sec_order[i]];
2015 if (s->sh_type != SHT_NOBITS) {
2016 if (s->sh_type == SHT_DYNSYM)
2017 patch_dynsym_undef(s1, s);
2018 while (offset < s->sh_offset) {
2019 fputc(0, f);
2020 offset++;
2022 size = s->sh_size;
2023 if (size)
2024 fwrite(s->data, 1, size, f);
2025 offset += size;
2029 /* output section headers */
2030 while (offset < ehdr.e_shoff) {
2031 fputc(0, f);
2032 offset++;
2035 for(i = 0; i < s1->nb_sections; i++) {
2036 sh = &shdr;
2037 memset(sh, 0, sizeof(ElfW(Shdr)));
2038 s = s1->sections[i];
2039 if (s) {
2040 sh->sh_name = s->sh_name;
2041 sh->sh_type = s->sh_type;
2042 sh->sh_flags = s->sh_flags;
2043 sh->sh_entsize = s->sh_entsize;
2044 sh->sh_info = s->sh_info;
2045 if (s->link)
2046 sh->sh_link = s->link->sh_num;
2047 sh->sh_addralign = s->sh_addralign;
2048 sh->sh_addr = s->sh_addr;
2049 sh->sh_offset = s->sh_offset;
2050 sh->sh_size = s->sh_size;
2052 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2056 /* Write an elf, coff or "binary" file */
2057 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2058 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2060 int fd, mode, file_type;
2061 FILE *f;
2063 file_type = s1->output_type;
2064 if (file_type == TCC_OUTPUT_OBJ)
2065 mode = 0666;
2066 else
2067 mode = 0777;
2068 unlink(filename);
2069 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2070 if (fd < 0) {
2071 tcc_error_noabort("could not write '%s'", filename);
2072 return -1;
2074 f = fdopen(fd, "wb");
2075 if (s1->verbose)
2076 printf("<- %s\n", filename);
2078 #ifdef TCC_TARGET_COFF
2079 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2080 tcc_output_coff(s1, f);
2081 else
2082 #endif
2083 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2084 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2085 else
2086 tcc_output_binary(s1, f, sec_order);
2087 fclose(f);
2089 return 0;
2092 /* Output an elf, coff or binary file */
2093 /* XXX: suppress unneeded sections */
2094 static int elf_output_file(TCCState *s1, const char *filename)
2096 int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
2097 struct dyn_inf dyninf;
2098 ElfW(Phdr) *phdr;
2099 ElfW(Sym) *sym;
2100 Section *strsec, *interp, *dynamic, *dynstr;
2102 file_type = s1->output_type;
2103 s1->nb_errors = 0;
2105 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2106 if (file_type != TCC_OUTPUT_OBJ) {
2107 tcc_add_runtime(s1);
2110 phdr = NULL;
2111 sec_order = NULL;
2112 interp = dynamic = dynstr = NULL; /* avoid warning */
2113 dyninf.dyn_rel_off = 0; /* avoid warning */
2115 if (file_type != TCC_OUTPUT_OBJ) {
2116 relocate_common_syms();
2118 tcc_add_linker_symbols(s1);
2120 if (!s1->static_link) {
2121 if (file_type == TCC_OUTPUT_EXE) {
2122 char *ptr;
2123 /* allow override the dynamic loader */
2124 const char *elfint = getenv("LD_SO");
2125 if (elfint == NULL)
2126 elfint = DEFAULT_ELFINTERP(s1);
2127 /* add interpreter section only if executable */
2128 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2129 interp->sh_addralign = 1;
2130 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2131 strcpy(ptr, elfint);
2134 /* add dynamic symbol table */
2135 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2136 ".dynstr",
2137 ".hash", SHF_ALLOC);
2138 dynstr = s1->dynsym->link;
2140 /* add dynamic section */
2141 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2142 SHF_ALLOC | SHF_WRITE);
2143 dynamic->link = dynstr;
2144 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2146 build_got(s1);
2148 if (file_type == TCC_OUTPUT_EXE) {
2149 bind_exe_dynsyms(s1);
2151 if (s1->nb_errors) {
2152 ret = -1;
2153 goto the_end;
2156 bind_libs_dynsyms(s1);
2157 } else /* shared library case: simply export all global symbols */
2158 export_global_syms(s1);
2160 build_got_entries(s1);
2162 /* add a list of needed dlls */
2163 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2164 DLLReference *dllref = s1->loaded_dlls[i];
2165 if (dllref->level == 0)
2166 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2169 if (s1->rpath)
2170 put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath));
2172 /* XXX: currently, since we do not handle PIC code, we
2173 must relocate the readonly segments */
2174 if (file_type == TCC_OUTPUT_DLL) {
2175 if (s1->soname)
2176 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2177 put_dt(dynamic, DT_TEXTREL, 0);
2180 if (s1->symbolic)
2181 put_dt(dynamic, DT_SYMBOLIC, 0);
2183 /* add necessary space for other entries */
2184 dyninf.dyn_rel_off = dynamic->data_offset;
2185 dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
2186 } else {
2187 /* still need to build got entries in case of static link */
2188 build_got_entries(s1);
2192 /* we add a section for symbols */
2193 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2194 put_elf_str(strsec, "");
2196 /* compute number of sections */
2197 shnum = s1->nb_sections;
2199 /* this array is used to reorder sections in the output file */
2200 sec_order = tcc_malloc(sizeof(int) * shnum);
2201 sec_order[0] = 0;
2203 /* compute number of program headers */
2204 switch(file_type) {
2205 default:
2206 case TCC_OUTPUT_OBJ:
2207 phnum = 0;
2208 break;
2209 case TCC_OUTPUT_EXE:
2210 if (!s1->static_link)
2211 phnum = 4 + HAVE_PHDR;
2212 else
2213 phnum = 2;
2214 break;
2215 case TCC_OUTPUT_DLL:
2216 phnum = 3;
2217 break;
2220 /* Allocate strings for section names */
2221 alloc_sec_names(s1, file_type, strsec);
2223 /* allocate program segment headers */
2224 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2226 /* compute section to program header mapping */
2227 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2228 sec_order);
2230 /* Fill remaining program header and finalize relocation related to dynamic
2231 linking. */
2232 if (phnum > 0) {
2233 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2234 if (dynamic) {
2235 dyninf.dynamic = dynamic;
2236 dyninf.dynstr = dynstr;
2238 fill_dynamic(s1, &dyninf);
2240 /* put in GOT the dynamic section address and relocate PLT */
2241 write32le(s1->got->data, dynamic->sh_addr);
2242 if (file_type == TCC_OUTPUT_EXE
2243 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
2244 || file_type == TCC_OUTPUT_DLL
2245 #endif
2247 relocate_plt(s1);
2249 /* relocate symbols in .dynsym now that final addresses are known */
2250 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2251 if (sym->st_shndx == SHN_UNDEF) {
2252 /* relocate to PLT if symbol corresponds to a PLT entry,
2253 but not if it's a weak symbol */
2254 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
2255 sym->st_value = 0;
2256 else if (sym->st_value)
2257 sym->st_value += s1->plt->sh_addr;
2258 } else if (sym->st_shndx < SHN_LORESERVE) {
2259 /* do symbol relocation */
2260 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2266 /* if building executable or DLL, then relocate each section
2267 except the GOT which is already relocated */
2268 if (file_type != TCC_OUTPUT_OBJ) {
2269 ret = final_sections_reloc(s1);
2270 if (ret)
2271 goto the_end;
2274 /* Perform relocation to GOT or PLT entries */
2275 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2276 fill_got(s1);
2278 /* Create the ELF file with name 'filename' */
2279 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2280 the_end:
2281 tcc_free(s1->symtab_to_dynsym);
2282 tcc_free(sec_order);
2283 tcc_free(phdr);
2284 tcc_free(s1->sym_attrs);
2285 s1->sym_attrs = NULL;
2286 return ret;
2289 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2291 int ret;
2292 #ifdef TCC_TARGET_PE
2293 if (s->output_type != TCC_OUTPUT_OBJ) {
2294 ret = pe_output_file(s, filename);
2295 } else
2296 #endif
2297 ret = elf_output_file(s, filename);
2298 return ret;
2301 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2303 void *data;
2305 data = tcc_malloc(size);
2306 lseek(fd, file_offset, SEEK_SET);
2307 read(fd, data, size);
2308 return data;
2311 typedef struct SectionMergeInfo {
2312 Section *s; /* corresponding existing section */
2313 unsigned long offset; /* offset of the new section in the existing section */
2314 uint8_t new_section; /* true if section 's' was added */
2315 uint8_t link_once; /* true if link once section */
2316 } SectionMergeInfo;
2318 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2320 int size = read(fd, h, sizeof *h);
2321 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2322 if (h->e_type == ET_REL)
2323 return AFF_BINTYPE_REL;
2324 if (h->e_type == ET_DYN)
2325 return AFF_BINTYPE_DYN;
2326 } else if (size >= 8) {
2327 if (0 == memcmp(h, ARMAG, 8))
2328 return AFF_BINTYPE_AR;
2329 #ifdef TCC_TARGET_COFF
2330 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2331 return AFF_BINTYPE_C67;
2332 #endif
2334 return 0;
2337 /* load an object file and merge it with current files */
2338 /* XXX: handle correctly stab (debug) info */
2339 ST_FUNC int tcc_load_object_file(TCCState *s1,
2340 int fd, unsigned long file_offset)
2342 ElfW(Ehdr) ehdr;
2343 ElfW(Shdr) *shdr, *sh;
2344 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2345 unsigned char *strsec, *strtab;
2346 int *old_to_new_syms;
2347 char *sh_name, *name;
2348 SectionMergeInfo *sm_table, *sm;
2349 ElfW(Sym) *sym, *symtab;
2350 ElfW_Rel *rel;
2351 Section *s;
2353 int stab_index;
2354 int stabstr_index;
2356 stab_index = stabstr_index = 0;
2358 lseek(fd, file_offset, SEEK_SET);
2359 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2360 goto fail1;
2361 /* test CPU specific stuff */
2362 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2363 ehdr.e_machine != EM_TCC_TARGET) {
2364 fail1:
2365 tcc_error_noabort("invalid object file");
2366 return -1;
2368 /* read sections */
2369 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2370 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2371 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2373 /* load section names */
2374 sh = &shdr[ehdr.e_shstrndx];
2375 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2377 /* load symtab and strtab */
2378 old_to_new_syms = NULL;
2379 symtab = NULL;
2380 strtab = NULL;
2381 nb_syms = 0;
2382 for(i = 1; i < ehdr.e_shnum; i++) {
2383 sh = &shdr[i];
2384 if (sh->sh_type == SHT_SYMTAB) {
2385 if (symtab) {
2386 tcc_error_noabort("object must contain only one symtab");
2387 fail:
2388 ret = -1;
2389 goto the_end;
2391 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2392 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2393 sm_table[i].s = symtab_section;
2395 /* now load strtab */
2396 sh = &shdr[sh->sh_link];
2397 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2401 /* now examine each section and try to merge its content with the
2402 ones in memory */
2403 for(i = 1; i < ehdr.e_shnum; i++) {
2404 /* no need to examine section name strtab */
2405 if (i == ehdr.e_shstrndx)
2406 continue;
2407 sh = &shdr[i];
2408 sh_name = (char *) strsec + sh->sh_name;
2409 /* ignore sections types we do not handle */
2410 if (sh->sh_type != SHT_PROGBITS &&
2411 sh->sh_type != SHT_RELX &&
2412 #ifdef TCC_ARM_EABI
2413 sh->sh_type != SHT_ARM_EXIDX &&
2414 #endif
2415 sh->sh_type != SHT_NOBITS &&
2416 sh->sh_type != SHT_PREINIT_ARRAY &&
2417 sh->sh_type != SHT_INIT_ARRAY &&
2418 sh->sh_type != SHT_FINI_ARRAY &&
2419 strcmp(sh_name, ".stabstr")
2421 continue;
2422 if (sh->sh_addralign < 1)
2423 sh->sh_addralign = 1;
2424 /* find corresponding section, if any */
2425 for(j = 1; j < s1->nb_sections;j++) {
2426 s = s1->sections[j];
2427 if (!strcmp(s->name, sh_name)) {
2428 if (!strncmp(sh_name, ".gnu.linkonce",
2429 sizeof(".gnu.linkonce") - 1)) {
2430 /* if a 'linkonce' section is already present, we
2431 do not add it again. It is a little tricky as
2432 symbols can still be defined in
2433 it. */
2434 sm_table[i].link_once = 1;
2435 goto next;
2436 } else {
2437 goto found;
2441 /* not found: create new section */
2442 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2443 /* take as much info as possible from the section. sh_link and
2444 sh_info will be updated later */
2445 s->sh_addralign = sh->sh_addralign;
2446 s->sh_entsize = sh->sh_entsize;
2447 sm_table[i].new_section = 1;
2448 found:
2449 if (sh->sh_type != s->sh_type) {
2450 tcc_error_noabort("invalid section type");
2451 goto fail;
2454 /* align start of section */
2455 offset = s->data_offset;
2457 if (0 == strcmp(sh_name, ".stab")) {
2458 stab_index = i;
2459 goto no_align;
2461 if (0 == strcmp(sh_name, ".stabstr")) {
2462 stabstr_index = i;
2463 goto no_align;
2466 size = sh->sh_addralign - 1;
2467 offset = (offset + size) & ~size;
2468 if (sh->sh_addralign > s->sh_addralign)
2469 s->sh_addralign = sh->sh_addralign;
2470 s->data_offset = offset;
2471 no_align:
2472 sm_table[i].offset = offset;
2473 sm_table[i].s = s;
2474 /* concatenate sections */
2475 size = sh->sh_size;
2476 if (sh->sh_type != SHT_NOBITS) {
2477 unsigned char *ptr;
2478 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2479 ptr = section_ptr_add(s, size);
2480 read(fd, ptr, size);
2481 } else {
2482 s->data_offset += size;
2484 next: ;
2487 /* gr relocate stab strings */
2488 if (stab_index && stabstr_index) {
2489 Stab_Sym *a, *b;
2490 unsigned o;
2491 s = sm_table[stab_index].s;
2492 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2493 b = (Stab_Sym *)(s->data + s->data_offset);
2494 o = sm_table[stabstr_index].offset;
2495 while (a < b)
2496 a->n_strx += o, a++;
2499 /* second short pass to update sh_link and sh_info fields of new
2500 sections */
2501 for(i = 1; i < ehdr.e_shnum; i++) {
2502 s = sm_table[i].s;
2503 if (!s || !sm_table[i].new_section)
2504 continue;
2505 sh = &shdr[i];
2506 if (sh->sh_link > 0)
2507 s->link = sm_table[sh->sh_link].s;
2508 if (sh->sh_type == SHT_RELX) {
2509 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2510 /* update backward link */
2511 s1->sections[s->sh_info]->reloc = s;
2514 sm = sm_table;
2516 /* resolve symbols */
2517 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2519 sym = symtab + 1;
2520 for(i = 1; i < nb_syms; i++, sym++) {
2521 if (sym->st_shndx != SHN_UNDEF &&
2522 sym->st_shndx < SHN_LORESERVE) {
2523 sm = &sm_table[sym->st_shndx];
2524 if (sm->link_once) {
2525 /* if a symbol is in a link once section, we use the
2526 already defined symbol. It is very important to get
2527 correct relocations */
2528 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2529 name = (char *) strtab + sym->st_name;
2530 sym_index = find_elf_sym(symtab_section, name);
2531 if (sym_index)
2532 old_to_new_syms[i] = sym_index;
2534 continue;
2536 /* if no corresponding section added, no need to add symbol */
2537 if (!sm->s)
2538 continue;
2539 /* convert section number */
2540 sym->st_shndx = sm->s->sh_num;
2541 /* offset value */
2542 sym->st_value += sm->offset;
2544 /* add symbol */
2545 name = (char *) strtab + sym->st_name;
2546 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2547 sym->st_info, sym->st_other,
2548 sym->st_shndx, name);
2549 old_to_new_syms[i] = sym_index;
2552 /* third pass to patch relocation entries */
2553 for(i = 1; i < ehdr.e_shnum; i++) {
2554 s = sm_table[i].s;
2555 if (!s)
2556 continue;
2557 sh = &shdr[i];
2558 offset = sm_table[i].offset;
2559 switch(s->sh_type) {
2560 case SHT_RELX:
2561 /* take relocation offset information */
2562 offseti = sm_table[sh->sh_info].offset;
2563 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2564 int type;
2565 unsigned sym_index;
2566 /* convert symbol index */
2567 type = ELFW(R_TYPE)(rel->r_info);
2568 sym_index = ELFW(R_SYM)(rel->r_info);
2569 /* NOTE: only one symtab assumed */
2570 if (sym_index >= nb_syms)
2571 goto invalid_reloc;
2572 sym_index = old_to_new_syms[sym_index];
2573 /* ignore link_once in rel section. */
2574 if (!sym_index && !sm->link_once
2575 #ifdef TCC_TARGET_ARM
2576 && type != R_ARM_V4BX
2577 #endif
2579 invalid_reloc:
2580 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2581 i, strsec + sh->sh_name, rel->r_offset);
2582 goto fail;
2584 rel->r_info = ELFW(R_INFO)(sym_index, type);
2585 /* offset the relocation offset */
2586 rel->r_offset += offseti;
2587 #ifdef TCC_TARGET_ARM
2588 /* Jumps and branches from a Thumb code to a PLT entry need
2589 special handling since PLT entries are ARM code.
2590 Unconditional bl instructions referencing PLT entries are
2591 handled by converting these instructions into blx
2592 instructions. Other case of instructions referencing a PLT
2593 entry require to add a Thumb stub before the PLT entry to
2594 switch to ARM mode. We set bit plt_thumb_stub of the
2595 attribute of a symbol to indicate such a case. */
2596 if (type == R_ARM_THM_JUMP24)
2597 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2598 #endif
2600 break;
2601 default:
2602 break;
2606 ret = 0;
2607 the_end:
2608 tcc_free(symtab);
2609 tcc_free(strtab);
2610 tcc_free(old_to_new_syms);
2611 tcc_free(sm_table);
2612 tcc_free(strsec);
2613 tcc_free(shdr);
2614 return ret;
2617 typedef struct ArchiveHeader {
2618 char ar_name[16]; /* name of this member */
2619 char ar_date[12]; /* file mtime */
2620 char ar_uid[6]; /* owner uid; printed as decimal */
2621 char ar_gid[6]; /* owner gid; printed as decimal */
2622 char ar_mode[8]; /* file mode, printed as octal */
2623 char ar_size[10]; /* file size, printed as decimal */
2624 char ar_fmag[2]; /* should contain ARFMAG */
2625 } ArchiveHeader;
2627 static int get_be32(const uint8_t *b)
2629 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2632 static long get_be64(const uint8_t *b)
2634 long long ret = get_be32(b);
2635 ret = (ret << 32) | (unsigned)get_be32(b+4);
2636 return (long)ret;
2639 /* load only the objects which resolve undefined symbols */
2640 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2642 long i, bound, nsyms, sym_index, off, ret;
2643 uint8_t *data;
2644 const char *ar_names, *p;
2645 const uint8_t *ar_index;
2646 ElfW(Sym) *sym;
2648 data = tcc_malloc(size);
2649 if (read(fd, data, size) != size)
2650 goto fail;
2651 nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
2652 ar_index = data + entrysize;
2653 ar_names = (char *) ar_index + nsyms * entrysize;
2655 do {
2656 bound = 0;
2657 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2658 sym_index = find_elf_sym(symtab_section, p);
2659 if(sym_index) {
2660 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2661 if(sym->st_shndx == SHN_UNDEF) {
2662 off = (entrysize == 4
2663 ? get_be32(ar_index + i * 4)
2664 : get_be64(ar_index + i * 8))
2665 + sizeof(ArchiveHeader);
2666 ++bound;
2667 if(tcc_load_object_file(s1, fd, off) < 0) {
2668 fail:
2669 ret = -1;
2670 goto the_end;
2675 } while(bound);
2676 ret = 0;
2677 the_end:
2678 tcc_free(data);
2679 return ret;
2682 /* load a '.a' file */
2683 ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
2685 ArchiveHeader hdr;
2686 char ar_size[11];
2687 char ar_name[17];
2688 char magic[8];
2689 int size, len, i;
2690 unsigned long file_offset;
2692 /* skip magic which was already checked */
2693 read(fd, magic, sizeof(magic));
2695 for(;;) {
2696 len = read(fd, &hdr, sizeof(hdr));
2697 if (len == 0)
2698 break;
2699 if (len != sizeof(hdr)) {
2700 tcc_error_noabort("invalid archive");
2701 return -1;
2703 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2704 ar_size[sizeof(hdr.ar_size)] = '\0';
2705 size = strtol(ar_size, NULL, 0);
2706 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2707 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2708 if (ar_name[i] != ' ')
2709 break;
2711 ar_name[i + 1] = '\0';
2712 file_offset = lseek(fd, 0, SEEK_CUR);
2713 /* align to even */
2714 size = (size + 1) & ~1;
2715 if (!strcmp(ar_name, "/")) {
2716 /* coff symbol table : we handle it */
2717 if(s1->alacarte_link)
2718 return tcc_load_alacarte(s1, fd, size, 4);
2719 } else if (!strcmp(ar_name, "/SYM64/")) {
2720 if(s1->alacarte_link)
2721 return tcc_load_alacarte(s1, fd, size, 8);
2722 } else {
2723 ElfW(Ehdr) ehdr;
2724 if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2725 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2726 return -1;
2729 lseek(fd, file_offset + size, SEEK_SET);
2731 return 0;
2734 #ifndef TCC_TARGET_PE
2735 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2736 is referenced by the user (so it should be added as DT_NEEDED in
2737 the generated ELF file) */
2738 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2740 ElfW(Ehdr) ehdr;
2741 ElfW(Shdr) *shdr, *sh, *sh1;
2742 int i, j, nb_syms, nb_dts, sym_bind, ret;
2743 ElfW(Sym) *sym, *dynsym;
2744 ElfW(Dyn) *dt, *dynamic;
2745 unsigned char *dynstr;
2746 const char *name, *soname;
2747 DLLReference *dllref;
2749 read(fd, &ehdr, sizeof(ehdr));
2751 /* test CPU specific stuff */
2752 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2753 ehdr.e_machine != EM_TCC_TARGET) {
2754 tcc_error_noabort("bad architecture");
2755 return -1;
2758 /* read sections */
2759 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2761 /* load dynamic section and dynamic symbols */
2762 nb_syms = 0;
2763 nb_dts = 0;
2764 dynamic = NULL;
2765 dynsym = NULL; /* avoid warning */
2766 dynstr = NULL; /* avoid warning */
2767 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2768 switch(sh->sh_type) {
2769 case SHT_DYNAMIC:
2770 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2771 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2772 break;
2773 case SHT_DYNSYM:
2774 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2775 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2776 sh1 = &shdr[sh->sh_link];
2777 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2778 break;
2779 default:
2780 break;
2784 /* compute the real library name */
2785 soname = tcc_basename(filename);
2787 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2788 if (dt->d_tag == DT_SONAME) {
2789 soname = (char *) dynstr + dt->d_un.d_val;
2793 /* if the dll is already loaded, do not load it */
2794 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2795 dllref = s1->loaded_dlls[i];
2796 if (!strcmp(soname, dllref->name)) {
2797 /* but update level if needed */
2798 if (level < dllref->level)
2799 dllref->level = level;
2800 ret = 0;
2801 goto the_end;
2805 /* add the dll and its level */
2806 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2807 dllref->level = level;
2808 strcpy(dllref->name, soname);
2809 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2811 /* add dynamic symbols in dynsym_section */
2812 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2813 sym_bind = ELFW(ST_BIND)(sym->st_info);
2814 if (sym_bind == STB_LOCAL)
2815 continue;
2816 name = (char *) dynstr + sym->st_name;
2817 set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2818 sym->st_info, sym->st_other, sym->st_shndx, name);
2821 /* load all referenced DLLs */
2822 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2823 switch(dt->d_tag) {
2824 case DT_NEEDED:
2825 name = (char *) dynstr + dt->d_un.d_val;
2826 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2827 dllref = s1->loaded_dlls[j];
2828 if (!strcmp(name, dllref->name))
2829 goto already_loaded;
2831 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2832 tcc_error_noabort("referenced dll '%s' not found", name);
2833 ret = -1;
2834 goto the_end;
2836 already_loaded:
2837 break;
2840 ret = 0;
2841 the_end:
2842 tcc_free(dynstr);
2843 tcc_free(dynsym);
2844 tcc_free(dynamic);
2845 tcc_free(shdr);
2846 return ret;
2849 #define LD_TOK_NAME 256
2850 #define LD_TOK_EOF (-1)
2852 /* return next ld script token */
2853 static int ld_next(TCCState *s1, char *name, int name_size)
2855 int c;
2856 char *q;
2858 redo:
2859 switch(ch) {
2860 case ' ':
2861 case '\t':
2862 case '\f':
2863 case '\v':
2864 case '\r':
2865 case '\n':
2866 inp();
2867 goto redo;
2868 case '/':
2869 minp();
2870 if (ch == '*') {
2871 file->buf_ptr = parse_comment(file->buf_ptr);
2872 ch = file->buf_ptr[0];
2873 goto redo;
2874 } else {
2875 q = name;
2876 *q++ = '/';
2877 goto parse_name;
2879 break;
2880 case '\\':
2881 ch = handle_eob();
2882 if (ch != '\\')
2883 goto redo;
2884 /* fall through */
2885 /* case 'a' ... 'z': */
2886 case 'a':
2887 case 'b':
2888 case 'c':
2889 case 'd':
2890 case 'e':
2891 case 'f':
2892 case 'g':
2893 case 'h':
2894 case 'i':
2895 case 'j':
2896 case 'k':
2897 case 'l':
2898 case 'm':
2899 case 'n':
2900 case 'o':
2901 case 'p':
2902 case 'q':
2903 case 'r':
2904 case 's':
2905 case 't':
2906 case 'u':
2907 case 'v':
2908 case 'w':
2909 case 'x':
2910 case 'y':
2911 case 'z':
2912 /* case 'A' ... 'z': */
2913 case 'A':
2914 case 'B':
2915 case 'C':
2916 case 'D':
2917 case 'E':
2918 case 'F':
2919 case 'G':
2920 case 'H':
2921 case 'I':
2922 case 'J':
2923 case 'K':
2924 case 'L':
2925 case 'M':
2926 case 'N':
2927 case 'O':
2928 case 'P':
2929 case 'Q':
2930 case 'R':
2931 case 'S':
2932 case 'T':
2933 case 'U':
2934 case 'V':
2935 case 'W':
2936 case 'X':
2937 case 'Y':
2938 case 'Z':
2939 case '_':
2940 case '.':
2941 case '$':
2942 case '~':
2943 q = name;
2944 parse_name:
2945 for(;;) {
2946 if (!((ch >= 'a' && ch <= 'z') ||
2947 (ch >= 'A' && ch <= 'Z') ||
2948 (ch >= '0' && ch <= '9') ||
2949 strchr("/.-_+=$:\\,~", ch)))
2950 break;
2951 if ((q - name) < name_size - 1) {
2952 *q++ = ch;
2954 minp();
2956 *q = '\0';
2957 c = LD_TOK_NAME;
2958 break;
2959 case CH_EOF:
2960 c = LD_TOK_EOF;
2961 break;
2962 default:
2963 c = ch;
2964 inp();
2965 break;
2967 return c;
2970 static int ld_add_file(TCCState *s1, const char filename[])
2972 int ret;
2974 ret = tcc_add_file_internal(s1, filename, AFF_TYPE_BIN);
2975 if (ret)
2976 ret = tcc_add_dll(s1, filename, 0);
2977 return ret;
2980 static inline int new_undef_syms(void)
2982 int ret = 0;
2983 ret = new_undef_sym;
2984 new_undef_sym = 0;
2985 return ret;
2988 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
2990 char filename[1024], libname[1024];
2991 int t, group, nblibs = 0, ret = 0;
2992 char **libs = NULL;
2994 group = !strcmp(cmd, "GROUP");
2995 if (!as_needed)
2996 new_undef_syms();
2997 t = ld_next(s1, filename, sizeof(filename));
2998 if (t != '(')
2999 expect("(");
3000 t = ld_next(s1, filename, sizeof(filename));
3001 for(;;) {
3002 libname[0] = '\0';
3003 if (t == LD_TOK_EOF) {
3004 tcc_error_noabort("unexpected end of file");
3005 ret = -1;
3006 goto lib_parse_error;
3007 } else if (t == ')') {
3008 break;
3009 } else if (t == '-') {
3010 t = ld_next(s1, filename, sizeof(filename));
3011 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3012 tcc_error_noabort("library name expected");
3013 ret = -1;
3014 goto lib_parse_error;
3016 pstrcpy(libname, sizeof libname, &filename[1]);
3017 if (s1->static_link) {
3018 snprintf(filename, sizeof filename, "lib%s.a", libname);
3019 } else {
3020 snprintf(filename, sizeof filename, "lib%s.so", libname);
3022 } else if (t != LD_TOK_NAME) {
3023 tcc_error_noabort("filename expected");
3024 ret = -1;
3025 goto lib_parse_error;
3027 if (!strcmp(filename, "AS_NEEDED")) {
3028 ret = ld_add_file_list(s1, cmd, 1);
3029 if (ret)
3030 goto lib_parse_error;
3031 } else {
3032 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3033 if (!as_needed) {
3034 ret = ld_add_file(s1, filename);
3035 if (ret)
3036 goto lib_parse_error;
3037 if (group) {
3038 /* Add the filename *and* the libname to avoid future conversions */
3039 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename));
3040 if (libname[0] != '\0')
3041 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname));
3045 t = ld_next(s1, filename, sizeof(filename));
3046 if (t == ',') {
3047 t = ld_next(s1, filename, sizeof(filename));
3050 if (group && !as_needed) {
3051 while (new_undef_syms()) {
3052 int i;
3054 for (i = 0; i < nblibs; i ++)
3055 ld_add_file(s1, libs[i]);
3058 lib_parse_error:
3059 dynarray_reset(&libs, &nblibs);
3060 return ret;
3063 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3064 files */
3065 ST_FUNC int tcc_load_ldscript(TCCState *s1)
3067 char cmd[64];
3068 char filename[1024];
3069 int t, ret;
3071 ch = handle_eob();
3072 for(;;) {
3073 t = ld_next(s1, cmd, sizeof(cmd));
3074 if (t == LD_TOK_EOF)
3075 return 0;
3076 else if (t != LD_TOK_NAME)
3077 return -1;
3078 if (!strcmp(cmd, "INPUT") ||
3079 !strcmp(cmd, "GROUP")) {
3080 ret = ld_add_file_list(s1, cmd, 0);
3081 if (ret)
3082 return ret;
3083 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3084 !strcmp(cmd, "TARGET")) {
3085 /* ignore some commands */
3086 t = ld_next(s1, cmd, sizeof(cmd));
3087 if (t != '(')
3088 expect("(");
3089 for(;;) {
3090 t = ld_next(s1, filename, sizeof(filename));
3091 if (t == LD_TOK_EOF) {
3092 tcc_error_noabort("unexpected end of file");
3093 return -1;
3094 } else if (t == ')') {
3095 break;
3098 } else {
3099 return -1;
3102 return 0;
3104 #endif /* !TCC_TARGET_PE */