Error out in put_got_entry if no dynamic symbol
[tinycc/jakubkaszycki.git] / tccelf.c
blobde792f4dd29781668e3bd3dfad5ceb22163f32bf
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 else
1017 tcc_error("Runtime relocation without dynamic symbol: %s", name);
1018 put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type, index);
1019 } else
1020 put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
1021 sym_index);
1023 if (need_plt_entry)
1024 return symattr->plt_offset;
1025 else
1026 return symattr->got_offset;
1029 /* build GOT and PLT entries */
1030 ST_FUNC void build_got_entries(TCCState *s1)
1032 Section *s;
1033 ElfW_Rel *rel;
1034 ElfW(Sym) *sym;
1035 int i, type, reloc_type, sym_index;
1037 for(i = 1; i < s1->nb_sections; i++) {
1038 s = s1->sections[i];
1039 if (s->sh_type != SHT_RELX)
1040 continue;
1041 /* no need to handle got relocations */
1042 if (s->link != symtab_section)
1043 continue;
1044 for_each_elem(s, 0, rel, ElfW_Rel) {
1045 type = ELFW(R_TYPE)(rel->r_info);
1046 sym_index = ELFW(R_SYM)(rel->r_info);
1047 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1049 if (type >= R_NUM || !relocs_info[type].known)
1050 tcc_error("Unknown relocation: %d\n", type);
1052 if (relocs_info[type].gotplt_entry == NO_GOTPLT_ENTRY)
1053 continue;
1055 /* Proceed with PLT/GOT [entry] creation if any of the following
1056 condition is met:
1057 - it is an undefined reference (dynamic relocation needed)
1058 - symbol is absolute (probably created by tcc_add_symbol and
1059 thus might be too far from application code)
1060 - relocation requires a PLT/GOT (BUILD_GOTPLT_ENTRY or
1061 ALWAYS_GOTPLT_ENTRY). */
1062 if (sym->st_shndx != SHN_UNDEF &&
1063 sym->st_shndx != SHN_ABS &&
1064 relocs_info[type].gotplt_entry == AUTO_GOTPLT_ENTRY)
1065 continue;
1067 /* Building a dynamic library but target is not capable of PC
1068 relative PLT entries. It can thus only use PLT entries if
1069 it expects one to be used (ALWAYS_GOTPLT_ENTRY). */
1070 if (sym->st_shndx == SHN_UNDEF &&
1071 s1->output_type == TCC_OUTPUT_DLL &&
1072 !PCRELATIVE_DLLPLT &&
1073 relocs_info[type].gotplt_entry == AUTO_GOTPLT_ENTRY)
1074 continue;
1076 #ifdef TCC_TARGET_X86_64
1077 if (type == R_X86_64_PLT32 &&
1078 ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT) {
1079 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1080 continue;
1082 #endif
1084 if (!s1->got)
1085 build_got(s1);
1087 if (relocs_info[type].gotplt_entry == BUILD_GOT_ONLY)
1088 continue;
1090 if (relocs_info[type].code_reloc)
1091 reloc_type = R_JMP_SLOT;
1092 else
1093 reloc_type = R_GLOB_DAT;
1094 put_got_entry(s1, reloc_type, type, sym->st_size, sym->st_info,
1095 sym_index);
1100 ST_FUNC Section *new_symtab(TCCState *s1,
1101 const char *symtab_name, int sh_type, int sh_flags,
1102 const char *strtab_name,
1103 const char *hash_name, int hash_sh_flags)
1105 Section *symtab, *strtab, *hash;
1106 int *ptr, nb_buckets;
1108 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1109 symtab->sh_entsize = sizeof(ElfW(Sym));
1110 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1111 put_elf_str(strtab, "");
1112 symtab->link = strtab;
1113 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1115 nb_buckets = 1;
1117 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1118 hash->sh_entsize = sizeof(int);
1119 symtab->hash = hash;
1120 hash->link = symtab;
1122 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1123 ptr[0] = nb_buckets;
1124 ptr[1] = 1;
1125 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1126 return symtab;
1129 /* put dynamic tag */
1130 static void put_dt(Section *dynamic, int dt, addr_t val)
1132 ElfW(Dyn) *dyn;
1133 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1134 dyn->d_tag = dt;
1135 dyn->d_un.d_val = val;
1138 #ifndef TCC_TARGET_PE
1139 static void add_init_array_defines(TCCState *s1, const char *section_name)
1141 Section *s;
1142 long end_offset;
1143 char sym_start[1024];
1144 char sym_end[1024];
1146 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1147 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1149 s = find_section(s1, section_name);
1150 if (!s) {
1151 end_offset = 0;
1152 s = data_section;
1153 } else {
1154 end_offset = s->data_offset;
1157 set_elf_sym(symtab_section,
1158 0, 0,
1159 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1160 s->sh_num, sym_start);
1161 set_elf_sym(symtab_section,
1162 end_offset, 0,
1163 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1164 s->sh_num, sym_end);
1166 #endif
1168 static int tcc_add_support(TCCState *s1, const char *filename)
1170 char buf[1024];
1171 snprintf(buf, sizeof(buf), "%s/"TCC_ARCH_DIR"%s", s1->tcc_lib_path, filename);
1172 return tcc_add_file(s1, buf);
1175 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1177 #ifdef CONFIG_TCC_BCHECK
1178 addr_t *ptr;
1179 int sym_index;
1181 if (0 == s1->do_bounds_check)
1182 return;
1183 /* XXX: add an object file to do that */
1184 ptr = section_ptr_add(bounds_section, sizeof(*ptr));
1185 *ptr = 0;
1186 set_elf_sym(symtab_section, 0, 0,
1187 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1188 bounds_section->sh_num, "__bounds_start");
1189 /* pull bcheck.o from libtcc1.a */
1190 sym_index = set_elf_sym(symtab_section, 0, 0,
1191 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1192 SHN_UNDEF, "__bound_init");
1193 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1194 /* add 'call __bound_init()' in .init section */
1195 Section *init_section = find_section(s1, ".init");
1196 unsigned char *pinit = section_ptr_add(init_section, 5);
1197 pinit[0] = 0xe8;
1198 write32le(pinit + 1, -4);
1199 put_elf_reloc(symtab_section, init_section,
1200 init_section->data_offset - 4, R_386_PC32, sym_index);
1201 /* R_386_PC32 = R_X86_64_PC32 = 2 */
1203 #endif
1206 /* add tcc runtime libraries */
1207 ST_FUNC void tcc_add_runtime(TCCState *s1)
1209 tcc_add_bcheck(s1);
1210 tcc_add_pragma_libs(s1);
1211 /* add libc */
1212 if (!s1->nostdlib) {
1213 tcc_add_library_err(s1, "c");
1214 #ifdef CONFIG_USE_LIBGCC
1215 if (!s1->static_link) {
1216 tcc_add_file(s1, TCC_LIBGCC);
1218 #endif
1219 tcc_add_support(s1, "libtcc1.a");
1220 /* add crt end if not memory output */
1221 if (s1->output_type != TCC_OUTPUT_MEMORY)
1222 tcc_add_crt(s1, "crtn.o");
1226 /* add various standard linker symbols (must be done after the
1227 sections are filled (for example after allocating common
1228 symbols)) */
1229 ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
1231 char buf[1024];
1232 int i;
1233 Section *s;
1235 set_elf_sym(symtab_section,
1236 text_section->data_offset, 0,
1237 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1238 text_section->sh_num, "_etext");
1239 set_elf_sym(symtab_section,
1240 data_section->data_offset, 0,
1241 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1242 data_section->sh_num, "_edata");
1243 set_elf_sym(symtab_section,
1244 bss_section->data_offset, 0,
1245 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1246 bss_section->sh_num, "_end");
1247 #ifndef TCC_TARGET_PE
1248 /* horrible new standard ldscript defines */
1249 add_init_array_defines(s1, ".preinit_array");
1250 add_init_array_defines(s1, ".init_array");
1251 add_init_array_defines(s1, ".fini_array");
1252 #endif
1254 /* add start and stop symbols for sections whose name can be
1255 expressed in C */
1256 for(i = 1; i < s1->nb_sections; i++) {
1257 s = s1->sections[i];
1258 if (s->sh_type == SHT_PROGBITS &&
1259 (s->sh_flags & SHF_ALLOC)) {
1260 const char *p;
1261 int ch;
1263 /* check if section name can be expressed in C */
1264 p = s->name;
1265 for(;;) {
1266 ch = *p;
1267 if (!ch)
1268 break;
1269 if (!isid(ch) && !isnum(ch))
1270 goto next_sec;
1271 p++;
1273 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1274 set_elf_sym(symtab_section,
1275 0, 0,
1276 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1277 s->sh_num, buf);
1278 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1279 set_elf_sym(symtab_section,
1280 s->data_offset, 0,
1281 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1282 s->sh_num, buf);
1284 next_sec: ;
1288 static void tcc_output_binary(TCCState *s1, FILE *f,
1289 const int *sec_order)
1291 Section *s;
1292 int i, offset, size;
1294 offset = 0;
1295 for(i=1;i<s1->nb_sections;i++) {
1296 s = s1->sections[sec_order[i]];
1297 if (s->sh_type != SHT_NOBITS &&
1298 (s->sh_flags & SHF_ALLOC)) {
1299 while (offset < s->sh_offset) {
1300 fputc(0, f);
1301 offset++;
1303 size = s->sh_size;
1304 fwrite(s->data, 1, size, f);
1305 offset += size;
1310 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1311 #define HAVE_PHDR 1
1312 #define EXTRA_RELITEMS 14
1314 /* move the relocation value from .dynsym to .got */
1315 static void patch_dynsym_undef(TCCState *s1, Section *s)
1317 uint32_t *gotd = (void *)s1->got->data;
1318 ElfW(Sym) *sym;
1320 gotd += 3; /* dummy entries in .got */
1321 /* relocate symbols in .dynsym */
1322 for_each_elem(s, 1, sym, ElfW(Sym)) {
1323 if (sym->st_shndx == SHN_UNDEF) {
1324 *gotd++ = sym->st_value + 6; /* XXX 6 is magic ? */
1325 sym->st_value = 0;
1329 #else
1330 #define HAVE_PHDR 1
1331 #define EXTRA_RELITEMS 9
1333 /* zero plt offsets of weak symbols in .dynsym */
1334 static void patch_dynsym_undef(TCCState *s1, Section *s)
1336 ElfW(Sym) *sym;
1338 for_each_elem(s, 1, sym, ElfW(Sym))
1339 if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
1340 sym->st_value = 0;
1342 #endif
1344 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1346 int sym_index = ELFW(R_SYM) (rel->r_info);
1347 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1348 unsigned long offset;
1350 if (sym_index >= s1->nb_sym_attrs)
1351 return;
1352 offset = s1->sym_attrs[sym_index].got_offset;
1353 section_reserve(s1->got, offset + PTR_SIZE);
1354 #ifdef TCC_TARGET_X86_64
1355 /* only works for x86-64 */
1356 write32le(s1->got->data + offset + 4, sym->st_value >> 32);
1357 #endif
1358 write32le(s1->got->data + offset, sym->st_value & 0xffffffff);
1361 /* Perform relocation to GOT or PLT entries */
1362 ST_FUNC void fill_got(TCCState *s1)
1364 Section *s;
1365 ElfW_Rel *rel;
1366 int i;
1368 for(i = 1; i < s1->nb_sections; i++) {
1369 s = s1->sections[i];
1370 if (s->sh_type != SHT_RELX)
1371 continue;
1372 /* no need to handle got relocations */
1373 if (s->link != symtab_section)
1374 continue;
1375 for_each_elem(s, 0, rel, ElfW_Rel) {
1376 switch (ELFW(R_TYPE) (rel->r_info)) {
1377 case R_X86_64_GOT32:
1378 case R_X86_64_GOTPCREL:
1379 case R_X86_64_GOTPCRELX:
1380 case R_X86_64_REX_GOTPCRELX:
1381 case R_X86_64_PLT32:
1382 fill_got_entry(s1, rel);
1383 break;
1389 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1390 in shared libraries and export non local defined symbols to shared libraries
1391 if -rdynamic switch was given on command line */
1392 static void bind_exe_dynsyms(TCCState *s1)
1394 const char *name;
1395 int sym_index, index;
1396 ElfW(Sym) *sym, *esym;
1397 int type;
1399 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1400 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1401 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1402 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1403 if (sym->st_shndx == SHN_UNDEF) {
1404 name = (char *) symtab_section->link->data + sym->st_name;
1405 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1406 if (sym_index) {
1407 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1408 type = ELFW(ST_TYPE)(esym->st_info);
1409 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1410 /* Indirect functions shall have STT_FUNC type in executable
1411 * dynsym section. Indeed, a dlsym call following a lazy
1412 * resolution would pick the symbol value from the
1413 * executable dynsym entry which would contain the address
1414 * of the function wanted by the caller of dlsym instead of
1415 * the address of the function that would return that
1416 * address */
1417 put_elf_sym(s1->dynsym, 0, esym->st_size,
1418 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1419 name);
1420 } else if (type == STT_OBJECT) {
1421 unsigned long offset;
1422 ElfW(Sym) *dynsym;
1423 offset = bss_section->data_offset;
1424 /* XXX: which alignment ? */
1425 offset = (offset + 16 - 1) & -16;
1426 set_elf_sym (s1->symtab, offset, esym->st_size,
1427 esym->st_info, 0, bss_section->sh_num, name);
1428 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1429 esym->st_info, 0, bss_section->sh_num,
1430 name);
1431 /* Ensure R_COPY works for weak symbol aliases */
1432 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1433 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1434 if ((dynsym->st_value == esym->st_value)
1435 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1436 char *dynname = (char *) s1->dynsymtab_section->link->data
1437 + dynsym->st_name;
1438 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1439 dynsym->st_info, 0,
1440 bss_section->sh_num, dynname);
1441 break;
1445 put_elf_reloc(s1->dynsym, bss_section,
1446 offset, R_COPY, index);
1447 offset += esym->st_size;
1448 bss_section->data_offset = offset;
1450 } else {
1451 /* STB_WEAK undefined symbols are accepted */
1452 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1453 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1454 !strcmp(name, "_fp_hw")) {
1455 } else {
1456 tcc_error_noabort("undefined symbol '%s'", name);
1459 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1460 /* if -rdynamic option, then export all non local symbols */
1461 name = (char *) symtab_section->link->data + sym->st_name;
1462 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1463 0, sym->st_shndx, name);
1468 /* Bind symbols of libraries: export all non local symbols of executable that
1469 are referenced by shared libraries. The reason is that the dynamic loader
1470 search symbol first in executable and then in libraries. Therefore a
1471 reference to a symbol already defined by a library can still be resolved by
1472 a symbol in the executable. */
1473 static void bind_libs_dynsyms(TCCState *s1)
1475 const char *name;
1476 int sym_index;
1477 ElfW(Sym) *sym, *esym;
1479 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1480 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1481 sym_index = find_elf_sym(symtab_section, name);
1482 /* XXX: avoid adding a symbol if already present because of
1483 -rdynamic ? */
1484 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1485 if (sym_index && sym->st_shndx != SHN_UNDEF)
1486 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1487 0, sym->st_shndx, name);
1488 else if (esym->st_shndx == SHN_UNDEF) {
1489 /* weak symbols can stay undefined */
1490 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1491 tcc_warning("undefined dynamic symbol '%s'", name);
1496 /* Export all non local symbols. This is used by shared libraries so that the
1497 non local symbols they define can resolve a reference in another shared
1498 library or in the executable. Correspondingly, it allows undefined local
1499 symbols to be resolved by other shared libraries or by the executable. */
1500 static void export_global_syms(TCCState *s1)
1502 int nb_syms, dynindex, index;
1503 const char *name;
1504 ElfW(Sym) *sym;
1506 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1507 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1508 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1509 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1510 name = (char *) symtab_section->link->data + sym->st_name;
1511 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1512 sym->st_info, 0, sym->st_shndx, name);
1513 index = sym - (ElfW(Sym) *) symtab_section->data;
1514 s1->symtab_to_dynsym[index] = dynindex;
1519 /* relocate the PLT: compute addresses and offsets in the PLT now that final
1520 address for PLT and GOT are known (see fill_program_header) */
1521 ST_FUNC void relocate_plt(TCCState *s1)
1523 uint8_t *p, *p_end;
1525 if (!s1->plt)
1526 return;
1528 p = s1->plt->data;
1529 p_end = p + s1->plt->data_offset;
1530 if (p < p_end) {
1531 #if defined(TCC_TARGET_I386)
1532 add32le(p + 2, s1->got->sh_addr);
1533 add32le(p + 8, s1->got->sh_addr);
1534 p += 16;
1535 while (p < p_end) {
1536 add32le(p + 2, s1->got->sh_addr);
1537 p += 16;
1539 #elif defined(TCC_TARGET_X86_64)
1540 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
1541 add32le(p + 2, x);
1542 add32le(p + 8, x - 6);
1543 p += 16;
1544 while (p < p_end) {
1545 add32le(p + 2, x + s1->plt->data - p);
1546 p += 16;
1548 #elif defined(TCC_TARGET_ARM)
1549 int x = s1->got->sh_addr - s1->plt->sh_addr - 12;
1550 write32le(s1->plt->data + 16, x - 16);
1551 p += 20;
1552 while (p < p_end) {
1553 if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
1554 p += 4;
1555 add32le(p + 12, x + s1->plt->data - p);
1556 p += 16;
1558 #elif defined(TCC_TARGET_ARM64)
1559 uint64_t plt = s1->plt->sh_addr;
1560 uint64_t got = s1->got->sh_addr;
1561 uint64_t off = (got >> 12) - (plt >> 12);
1562 if ((off + ((uint32_t)1 << 20)) >> 21)
1563 tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt);
1564 write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
1565 write32le(p + 4, (0x90000010 | // adrp x16,...
1566 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1567 write32le(p + 8, (0xf9400211 | // ldr x17,[x16,#...]
1568 (got & 0xff8) << 7));
1569 write32le(p + 12, (0x91000210 | // add x16,x16,#...
1570 (got & 0xfff) << 10));
1571 write32le(p + 16, 0xd61f0220); // br x17
1572 write32le(p + 20, 0xd503201f); // nop
1573 write32le(p + 24, 0xd503201f); // nop
1574 write32le(p + 28, 0xd503201f); // nop
1575 p += 32;
1576 while (p < p_end) {
1577 uint64_t pc = plt + (p - s1->plt->data);
1578 uint64_t addr = got + read64le(p);
1579 uint64_t off = (addr >> 12) - (pc >> 12);
1580 if ((off + ((uint32_t)1 << 20)) >> 21)
1581 tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc);
1582 write32le(p, (0x90000010 | // adrp x16,...
1583 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1584 write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
1585 (addr & 0xff8) << 7));
1586 write32le(p + 8, (0x91000210 | // add x16,x16,#...
1587 (addr & 0xfff) << 10));
1588 write32le(p + 12, 0xd61f0220); // br x17
1589 p += 16;
1591 #elif defined(TCC_TARGET_C67)
1592 /* XXX: TODO */
1593 #else
1594 #error unsupported CPU
1595 #endif
1599 /* Allocate strings for section names and decide if an unallocated section
1600 should be output.
1602 NOTE: the strsec section comes last, so its size is also correct ! */
1603 static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1605 int i;
1606 Section *s;
1608 /* Allocate strings for section names */
1609 for(i = 1; i < s1->nb_sections; i++) {
1610 s = s1->sections[i];
1611 s->sh_name = put_elf_str(strsec, s->name);
1612 /* when generating a DLL, we include relocations but we may
1613 patch them */
1614 if (file_type == TCC_OUTPUT_DLL &&
1615 s->sh_type == SHT_RELX &&
1616 !(s->sh_flags & SHF_ALLOC)) {
1617 /* gr: avoid bogus relocs for empty (debug) sections */
1618 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1619 prepare_dynamic_rel(s1, s);
1620 else if (s1->do_debug)
1621 s->sh_size = s->data_offset;
1622 } else if (s1->do_debug ||
1623 file_type == TCC_OUTPUT_OBJ ||
1624 (s->sh_flags & SHF_ALLOC) ||
1625 i == (s1->nb_sections - 1)) {
1626 /* we output all sections if debug or object file */
1627 s->sh_size = s->data_offset;
1632 /* Info to be copied in dynamic section */
1633 struct dyn_inf {
1634 Section *dynamic;
1635 Section *dynstr;
1636 unsigned long dyn_rel_off;
1637 addr_t rel_addr;
1638 addr_t rel_size;
1639 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1640 addr_t bss_addr;
1641 addr_t bss_size;
1642 #endif
1645 /* Assign sections to segments and decide how are sections laid out when loaded
1646 in memory. This function also fills corresponding program headers. */
1647 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1648 Section *interp, Section* strsec,
1649 struct dyn_inf *dyninf, int *sec_order)
1651 int i, j, k, file_type, sh_order_index, file_offset;
1652 unsigned long s_align;
1653 long long tmp;
1654 addr_t addr;
1655 ElfW(Phdr) *ph;
1656 Section *s;
1658 file_type = s1->output_type;
1659 sh_order_index = 1;
1660 file_offset = 0;
1661 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1662 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1663 s_align = ELF_PAGE_SIZE;
1664 if (s1->section_align)
1665 s_align = s1->section_align;
1667 if (phnum > 0) {
1668 if (s1->has_text_addr) {
1669 int a_offset, p_offset;
1670 addr = s1->text_addr;
1671 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1672 ELF_PAGE_SIZE */
1673 a_offset = (int) (addr & (s_align - 1));
1674 p_offset = file_offset & (s_align - 1);
1675 if (a_offset < p_offset)
1676 a_offset += s_align;
1677 file_offset += (a_offset - p_offset);
1678 } else {
1679 if (file_type == TCC_OUTPUT_DLL)
1680 addr = 0;
1681 else
1682 addr = ELF_START_ADDR;
1683 /* compute address after headers */
1684 addr += (file_offset & (s_align - 1));
1687 ph = &phdr[0];
1688 /* Leave one program headers for the program interpreter and one for
1689 the program header table itself if needed. These are done later as
1690 they require section layout to be done first. */
1691 if (interp)
1692 ph += 1 + HAVE_PHDR;
1694 /* dynamic relocation table information, for .dynamic section */
1695 dyninf->rel_addr = dyninf->rel_size = 0;
1696 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1697 dyninf->bss_addr = dyninf->bss_size = 0;
1698 #endif
1700 for(j = 0; j < 2; j++) {
1701 ph->p_type = PT_LOAD;
1702 if (j == 0)
1703 ph->p_flags = PF_R | PF_X;
1704 else
1705 ph->p_flags = PF_R | PF_W;
1706 ph->p_align = s_align;
1708 /* Decide the layout of sections loaded in memory. This must
1709 be done before program headers are filled since they contain
1710 info about the layout. We do the following ordering: interp,
1711 symbol tables, relocations, progbits, nobits */
1712 /* XXX: do faster and simpler sorting */
1713 for(k = 0; k < 5; k++) {
1714 for(i = 1; i < s1->nb_sections; i++) {
1715 s = s1->sections[i];
1716 /* compute if section should be included */
1717 if (j == 0) {
1718 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1719 SHF_ALLOC)
1720 continue;
1721 } else {
1722 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1723 (SHF_ALLOC | SHF_WRITE))
1724 continue;
1726 if (s == interp) {
1727 if (k != 0)
1728 continue;
1729 } else if (s->sh_type == SHT_DYNSYM ||
1730 s->sh_type == SHT_STRTAB ||
1731 s->sh_type == SHT_HASH) {
1732 if (k != 1)
1733 continue;
1734 } else if (s->sh_type == SHT_RELX) {
1735 if (k != 2)
1736 continue;
1737 } else if (s->sh_type == SHT_NOBITS) {
1738 if (k != 4)
1739 continue;
1740 } else {
1741 if (k != 3)
1742 continue;
1744 sec_order[sh_order_index++] = i;
1746 /* section matches: we align it and add its size */
1747 tmp = addr;
1748 addr = (addr + s->sh_addralign - 1) &
1749 ~(s->sh_addralign - 1);
1750 file_offset += (int) ( addr - tmp );
1751 s->sh_offset = file_offset;
1752 s->sh_addr = addr;
1754 /* update program header infos */
1755 if (ph->p_offset == 0) {
1756 ph->p_offset = file_offset;
1757 ph->p_vaddr = addr;
1758 ph->p_paddr = ph->p_vaddr;
1760 /* update dynamic relocation infos */
1761 if (s->sh_type == SHT_RELX) {
1762 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1763 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1764 dyninf->rel_addr = addr;
1765 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1767 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1768 dyninf->bss_addr = addr;
1769 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1771 #else
1772 if (dyninf->rel_size == 0)
1773 dyninf->rel_addr = addr;
1774 dyninf->rel_size += s->sh_size;
1775 #endif
1777 addr += s->sh_size;
1778 if (s->sh_type != SHT_NOBITS)
1779 file_offset += s->sh_size;
1782 if (j == 0) {
1783 /* Make the first PT_LOAD segment include the program
1784 headers itself (and the ELF header as well), it'll
1785 come out with same memory use but will make various
1786 tools like binutils strip work better. */
1787 ph->p_offset &= ~(ph->p_align - 1);
1788 ph->p_vaddr &= ~(ph->p_align - 1);
1789 ph->p_paddr &= ~(ph->p_align - 1);
1791 ph->p_filesz = file_offset - ph->p_offset;
1792 ph->p_memsz = addr - ph->p_vaddr;
1793 ph++;
1794 if (j == 0) {
1795 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1796 /* if in the middle of a page, we duplicate the page in
1797 memory so that one copy is RX and the other is RW */
1798 if ((addr & (s_align - 1)) != 0)
1799 addr += s_align;
1800 } else {
1801 addr = (addr + s_align - 1) & ~(s_align - 1);
1802 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1808 /* all other sections come after */
1809 for(i = 1; i < s1->nb_sections; i++) {
1810 s = s1->sections[i];
1811 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1812 continue;
1813 sec_order[sh_order_index++] = i;
1815 file_offset = (file_offset + s->sh_addralign - 1) &
1816 ~(s->sh_addralign - 1);
1817 s->sh_offset = file_offset;
1818 if (s->sh_type != SHT_NOBITS)
1819 file_offset += s->sh_size;
1822 return file_offset;
1825 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1826 Section *dynamic)
1828 ElfW(Phdr) *ph;
1830 /* if interpreter, then add corresponding program header */
1831 if (interp) {
1832 ph = &phdr[0];
1834 if (HAVE_PHDR)
1836 int len = phnum * sizeof(ElfW(Phdr));
1838 ph->p_type = PT_PHDR;
1839 ph->p_offset = sizeof(ElfW(Ehdr));
1840 ph->p_vaddr = interp->sh_addr - len;
1841 ph->p_paddr = ph->p_vaddr;
1842 ph->p_filesz = ph->p_memsz = len;
1843 ph->p_flags = PF_R | PF_X;
1844 ph->p_align = 4; /* interp->sh_addralign; */
1845 ph++;
1848 ph->p_type = PT_INTERP;
1849 ph->p_offset = interp->sh_offset;
1850 ph->p_vaddr = interp->sh_addr;
1851 ph->p_paddr = ph->p_vaddr;
1852 ph->p_filesz = interp->sh_size;
1853 ph->p_memsz = interp->sh_size;
1854 ph->p_flags = PF_R;
1855 ph->p_align = interp->sh_addralign;
1858 /* if dynamic section, then add corresponding program header */
1859 if (dynamic) {
1860 ph = &phdr[phnum - 1];
1862 ph->p_type = PT_DYNAMIC;
1863 ph->p_offset = dynamic->sh_offset;
1864 ph->p_vaddr = dynamic->sh_addr;
1865 ph->p_paddr = ph->p_vaddr;
1866 ph->p_filesz = dynamic->sh_size;
1867 ph->p_memsz = dynamic->sh_size;
1868 ph->p_flags = PF_R | PF_W;
1869 ph->p_align = dynamic->sh_addralign;
1873 /* Fill the dynamic section with tags describing the address and size of
1874 sections */
1875 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
1877 Section *dynamic;
1879 dynamic = dyninf->dynamic;
1881 /* put dynamic section entries */
1882 dynamic->data_offset = dyninf->dyn_rel_off;
1883 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1884 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
1885 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1886 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
1887 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1888 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1889 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
1890 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
1891 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
1892 #else
1893 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1894 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
1895 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
1896 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
1897 put_dt(dynamic, DT_PLTREL, DT_REL);
1898 put_dt(dynamic, DT_REL, dyninf->bss_addr);
1899 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
1900 #else
1901 put_dt(dynamic, DT_REL, dyninf->rel_addr);
1902 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
1903 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1904 #endif
1905 #endif
1906 if (s1->do_debug)
1907 put_dt(dynamic, DT_DEBUG, 0);
1908 put_dt(dynamic, DT_NULL, 0);
1911 /* Relocate remaining sections and symbols (that is those not related to
1912 dynamic linking) */
1913 static int final_sections_reloc(TCCState *s1)
1915 int i;
1916 Section *s;
1918 relocate_syms(s1, s1->symtab, 0);
1920 if (s1->nb_errors != 0)
1921 return -1;
1923 /* relocate sections */
1924 /* XXX: ignore sections with allocated relocations ? */
1925 for(i = 1; i < s1->nb_sections; i++) {
1926 s = s1->sections[i];
1927 #ifdef TCC_TARGET_I386
1928 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
1929 /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
1930 checking is removed */
1931 #else
1932 if (s->reloc && s != s1->got)
1933 /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
1934 #endif
1935 relocate_section(s1, s);
1938 /* relocate relocation entries if the relocation tables are
1939 allocated in the executable */
1940 for(i = 1; i < s1->nb_sections; i++) {
1941 s = s1->sections[i];
1942 if ((s->sh_flags & SHF_ALLOC) &&
1943 s->sh_type == SHT_RELX) {
1944 relocate_rel(s1, s);
1947 return 0;
1950 /* Create an ELF file on disk.
1951 This function handle ELF specific layout requirements */
1952 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
1953 int file_offset, int *sec_order)
1955 int i, shnum, offset, size, file_type;
1956 Section *s;
1957 ElfW(Ehdr) ehdr;
1958 ElfW(Shdr) shdr, *sh;
1960 file_type = s1->output_type;
1961 shnum = s1->nb_sections;
1963 memset(&ehdr, 0, sizeof(ehdr));
1965 if (phnum > 0) {
1966 ehdr.e_phentsize = sizeof(ElfW(Phdr));
1967 ehdr.e_phnum = phnum;
1968 ehdr.e_phoff = sizeof(ElfW(Ehdr));
1971 /* align to 4 */
1972 file_offset = (file_offset + 3) & -4;
1974 /* fill header */
1975 ehdr.e_ident[0] = ELFMAG0;
1976 ehdr.e_ident[1] = ELFMAG1;
1977 ehdr.e_ident[2] = ELFMAG2;
1978 ehdr.e_ident[3] = ELFMAG3;
1979 ehdr.e_ident[4] = ELFCLASSW;
1980 ehdr.e_ident[5] = ELFDATA2LSB;
1981 ehdr.e_ident[6] = EV_CURRENT;
1982 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1983 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1984 #endif
1985 #ifdef TCC_TARGET_ARM
1986 #ifdef TCC_ARM_EABI
1987 ehdr.e_ident[EI_OSABI] = 0;
1988 ehdr.e_flags = EF_ARM_EABI_VER4;
1989 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
1990 ehdr.e_flags |= EF_ARM_HASENTRY;
1991 if (s1->float_abi == ARM_HARD_FLOAT)
1992 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
1993 else
1994 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
1995 #else
1996 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1997 #endif
1998 #endif
1999 switch(file_type) {
2000 default:
2001 case TCC_OUTPUT_EXE:
2002 ehdr.e_type = ET_EXEC;
2003 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
2004 break;
2005 case TCC_OUTPUT_DLL:
2006 ehdr.e_type = ET_DYN;
2007 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2008 break;
2009 case TCC_OUTPUT_OBJ:
2010 ehdr.e_type = ET_REL;
2011 break;
2013 ehdr.e_machine = EM_TCC_TARGET;
2014 ehdr.e_version = EV_CURRENT;
2015 ehdr.e_shoff = file_offset;
2016 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2017 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2018 ehdr.e_shnum = shnum;
2019 ehdr.e_shstrndx = shnum - 1;
2021 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2022 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2023 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2025 sort_syms(s1, symtab_section);
2026 for(i = 1; i < s1->nb_sections; i++) {
2027 s = s1->sections[sec_order[i]];
2028 if (s->sh_type != SHT_NOBITS) {
2029 if (s->sh_type == SHT_DYNSYM)
2030 patch_dynsym_undef(s1, s);
2031 while (offset < s->sh_offset) {
2032 fputc(0, f);
2033 offset++;
2035 size = s->sh_size;
2036 if (size)
2037 fwrite(s->data, 1, size, f);
2038 offset += size;
2042 /* output section headers */
2043 while (offset < ehdr.e_shoff) {
2044 fputc(0, f);
2045 offset++;
2048 for(i = 0; i < s1->nb_sections; i++) {
2049 sh = &shdr;
2050 memset(sh, 0, sizeof(ElfW(Shdr)));
2051 s = s1->sections[i];
2052 if (s) {
2053 sh->sh_name = s->sh_name;
2054 sh->sh_type = s->sh_type;
2055 sh->sh_flags = s->sh_flags;
2056 sh->sh_entsize = s->sh_entsize;
2057 sh->sh_info = s->sh_info;
2058 if (s->link)
2059 sh->sh_link = s->link->sh_num;
2060 sh->sh_addralign = s->sh_addralign;
2061 sh->sh_addr = s->sh_addr;
2062 sh->sh_offset = s->sh_offset;
2063 sh->sh_size = s->sh_size;
2065 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2069 /* Write an elf, coff or "binary" file */
2070 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2071 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2073 int fd, mode, file_type;
2074 FILE *f;
2076 file_type = s1->output_type;
2077 if (file_type == TCC_OUTPUT_OBJ)
2078 mode = 0666;
2079 else
2080 mode = 0777;
2081 unlink(filename);
2082 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2083 if (fd < 0) {
2084 tcc_error_noabort("could not write '%s'", filename);
2085 return -1;
2087 f = fdopen(fd, "wb");
2088 if (s1->verbose)
2089 printf("<- %s\n", filename);
2091 #ifdef TCC_TARGET_COFF
2092 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2093 tcc_output_coff(s1, f);
2094 else
2095 #endif
2096 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2097 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2098 else
2099 tcc_output_binary(s1, f, sec_order);
2100 fclose(f);
2102 return 0;
2105 /* Output an elf, coff or binary file */
2106 /* XXX: suppress unneeded sections */
2107 static int elf_output_file(TCCState *s1, const char *filename)
2109 int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
2110 struct dyn_inf dyninf;
2111 ElfW(Phdr) *phdr;
2112 ElfW(Sym) *sym;
2113 Section *strsec, *interp, *dynamic, *dynstr;
2115 file_type = s1->output_type;
2116 s1->nb_errors = 0;
2118 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2119 if (file_type != TCC_OUTPUT_OBJ) {
2120 tcc_add_runtime(s1);
2123 phdr = NULL;
2124 sec_order = NULL;
2125 interp = dynamic = dynstr = NULL; /* avoid warning */
2126 dyninf.dyn_rel_off = 0; /* avoid warning */
2128 if (file_type != TCC_OUTPUT_OBJ) {
2129 relocate_common_syms();
2131 tcc_add_linker_symbols(s1);
2133 if (!s1->static_link) {
2134 if (file_type == TCC_OUTPUT_EXE) {
2135 char *ptr;
2136 /* allow override the dynamic loader */
2137 const char *elfint = getenv("LD_SO");
2138 if (elfint == NULL)
2139 elfint = DEFAULT_ELFINTERP(s1);
2140 /* add interpreter section only if executable */
2141 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2142 interp->sh_addralign = 1;
2143 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2144 strcpy(ptr, elfint);
2147 /* add dynamic symbol table */
2148 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2149 ".dynstr",
2150 ".hash", SHF_ALLOC);
2151 dynstr = s1->dynsym->link;
2153 /* add dynamic section */
2154 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2155 SHF_ALLOC | SHF_WRITE);
2156 dynamic->link = dynstr;
2157 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2159 build_got(s1);
2161 if (file_type == TCC_OUTPUT_EXE) {
2162 bind_exe_dynsyms(s1);
2164 if (s1->nb_errors) {
2165 ret = -1;
2166 goto the_end;
2169 bind_libs_dynsyms(s1);
2170 } else /* shared library case: simply export all global symbols */
2171 export_global_syms(s1);
2173 build_got_entries(s1);
2175 /* add a list of needed dlls */
2176 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2177 DLLReference *dllref = s1->loaded_dlls[i];
2178 if (dllref->level == 0)
2179 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2182 if (s1->rpath)
2183 put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath));
2185 /* XXX: currently, since we do not handle PIC code, we
2186 must relocate the readonly segments */
2187 if (file_type == TCC_OUTPUT_DLL) {
2188 if (s1->soname)
2189 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2190 put_dt(dynamic, DT_TEXTREL, 0);
2193 if (s1->symbolic)
2194 put_dt(dynamic, DT_SYMBOLIC, 0);
2196 /* add necessary space for other entries */
2197 dyninf.dyn_rel_off = dynamic->data_offset;
2198 dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
2199 } else {
2200 /* still need to build got entries in case of static link */
2201 build_got_entries(s1);
2205 /* we add a section for symbols */
2206 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2207 put_elf_str(strsec, "");
2209 /* compute number of sections */
2210 shnum = s1->nb_sections;
2212 /* this array is used to reorder sections in the output file */
2213 sec_order = tcc_malloc(sizeof(int) * shnum);
2214 sec_order[0] = 0;
2216 /* compute number of program headers */
2217 switch(file_type) {
2218 default:
2219 case TCC_OUTPUT_OBJ:
2220 phnum = 0;
2221 break;
2222 case TCC_OUTPUT_EXE:
2223 if (!s1->static_link)
2224 phnum = 4 + HAVE_PHDR;
2225 else
2226 phnum = 2;
2227 break;
2228 case TCC_OUTPUT_DLL:
2229 phnum = 3;
2230 break;
2233 /* Allocate strings for section names */
2234 alloc_sec_names(s1, file_type, strsec);
2236 /* allocate program segment headers */
2237 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2239 /* compute section to program header mapping */
2240 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2241 sec_order);
2243 /* Fill remaining program header and finalize relocation related to dynamic
2244 linking. */
2245 if (phnum > 0) {
2246 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2247 if (dynamic) {
2248 dyninf.dynamic = dynamic;
2249 dyninf.dynstr = dynstr;
2251 fill_dynamic(s1, &dyninf);
2253 /* put in GOT the dynamic section address and relocate PLT */
2254 write32le(s1->got->data, dynamic->sh_addr);
2255 if (file_type == TCC_OUTPUT_EXE
2256 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
2257 || file_type == TCC_OUTPUT_DLL
2258 #endif
2260 relocate_plt(s1);
2262 /* relocate symbols in .dynsym now that final addresses are known */
2263 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2264 if (sym->st_shndx == SHN_UNDEF) {
2265 /* relocate to PLT if symbol corresponds to a PLT entry,
2266 but not if it's a weak symbol */
2267 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
2268 sym->st_value = 0;
2269 else if (sym->st_value)
2270 sym->st_value += s1->plt->sh_addr;
2271 } else if (sym->st_shndx < SHN_LORESERVE) {
2272 /* do symbol relocation */
2273 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2279 /* if building executable or DLL, then relocate each section
2280 except the GOT which is already relocated */
2281 if (file_type != TCC_OUTPUT_OBJ) {
2282 ret = final_sections_reloc(s1);
2283 if (ret)
2284 goto the_end;
2287 /* Perform relocation to GOT or PLT entries */
2288 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2289 fill_got(s1);
2291 /* Create the ELF file with name 'filename' */
2292 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2293 the_end:
2294 tcc_free(s1->symtab_to_dynsym);
2295 tcc_free(sec_order);
2296 tcc_free(phdr);
2297 tcc_free(s1->sym_attrs);
2298 s1->sym_attrs = NULL;
2299 return ret;
2302 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2304 int ret;
2305 #ifdef TCC_TARGET_PE
2306 if (s->output_type != TCC_OUTPUT_OBJ) {
2307 ret = pe_output_file(s, filename);
2308 } else
2309 #endif
2310 ret = elf_output_file(s, filename);
2311 return ret;
2314 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2316 void *data;
2318 data = tcc_malloc(size);
2319 lseek(fd, file_offset, SEEK_SET);
2320 read(fd, data, size);
2321 return data;
2324 typedef struct SectionMergeInfo {
2325 Section *s; /* corresponding existing section */
2326 unsigned long offset; /* offset of the new section in the existing section */
2327 uint8_t new_section; /* true if section 's' was added */
2328 uint8_t link_once; /* true if link once section */
2329 } SectionMergeInfo;
2331 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2333 int size = read(fd, h, sizeof *h);
2334 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2335 if (h->e_type == ET_REL)
2336 return AFF_BINTYPE_REL;
2337 if (h->e_type == ET_DYN)
2338 return AFF_BINTYPE_DYN;
2339 } else if (size >= 8) {
2340 if (0 == memcmp(h, ARMAG, 8))
2341 return AFF_BINTYPE_AR;
2342 #ifdef TCC_TARGET_COFF
2343 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2344 return AFF_BINTYPE_C67;
2345 #endif
2347 return 0;
2350 /* load an object file and merge it with current files */
2351 /* XXX: handle correctly stab (debug) info */
2352 ST_FUNC int tcc_load_object_file(TCCState *s1,
2353 int fd, unsigned long file_offset)
2355 ElfW(Ehdr) ehdr;
2356 ElfW(Shdr) *shdr, *sh;
2357 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2358 unsigned char *strsec, *strtab;
2359 int *old_to_new_syms;
2360 char *sh_name, *name;
2361 SectionMergeInfo *sm_table, *sm;
2362 ElfW(Sym) *sym, *symtab;
2363 ElfW_Rel *rel;
2364 Section *s;
2366 int stab_index;
2367 int stabstr_index;
2369 stab_index = stabstr_index = 0;
2371 lseek(fd, file_offset, SEEK_SET);
2372 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2373 goto fail1;
2374 /* test CPU specific stuff */
2375 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2376 ehdr.e_machine != EM_TCC_TARGET) {
2377 fail1:
2378 tcc_error_noabort("invalid object file");
2379 return -1;
2381 /* read sections */
2382 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2383 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2384 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2386 /* load section names */
2387 sh = &shdr[ehdr.e_shstrndx];
2388 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2390 /* load symtab and strtab */
2391 old_to_new_syms = NULL;
2392 symtab = NULL;
2393 strtab = NULL;
2394 nb_syms = 0;
2395 for(i = 1; i < ehdr.e_shnum; i++) {
2396 sh = &shdr[i];
2397 if (sh->sh_type == SHT_SYMTAB) {
2398 if (symtab) {
2399 tcc_error_noabort("object must contain only one symtab");
2400 fail:
2401 ret = -1;
2402 goto the_end;
2404 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2405 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2406 sm_table[i].s = symtab_section;
2408 /* now load strtab */
2409 sh = &shdr[sh->sh_link];
2410 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2414 /* now examine each section and try to merge its content with the
2415 ones in memory */
2416 for(i = 1; i < ehdr.e_shnum; i++) {
2417 /* no need to examine section name strtab */
2418 if (i == ehdr.e_shstrndx)
2419 continue;
2420 sh = &shdr[i];
2421 sh_name = (char *) strsec + sh->sh_name;
2422 /* ignore sections types we do not handle */
2423 if (sh->sh_type != SHT_PROGBITS &&
2424 sh->sh_type != SHT_RELX &&
2425 #ifdef TCC_ARM_EABI
2426 sh->sh_type != SHT_ARM_EXIDX &&
2427 #endif
2428 sh->sh_type != SHT_NOBITS &&
2429 sh->sh_type != SHT_PREINIT_ARRAY &&
2430 sh->sh_type != SHT_INIT_ARRAY &&
2431 sh->sh_type != SHT_FINI_ARRAY &&
2432 strcmp(sh_name, ".stabstr")
2434 continue;
2435 if (sh->sh_addralign < 1)
2436 sh->sh_addralign = 1;
2437 /* find corresponding section, if any */
2438 for(j = 1; j < s1->nb_sections;j++) {
2439 s = s1->sections[j];
2440 if (!strcmp(s->name, sh_name)) {
2441 if (!strncmp(sh_name, ".gnu.linkonce",
2442 sizeof(".gnu.linkonce") - 1)) {
2443 /* if a 'linkonce' section is already present, we
2444 do not add it again. It is a little tricky as
2445 symbols can still be defined in
2446 it. */
2447 sm_table[i].link_once = 1;
2448 goto next;
2449 } else {
2450 goto found;
2454 /* not found: create new section */
2455 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2456 /* take as much info as possible from the section. sh_link and
2457 sh_info will be updated later */
2458 s->sh_addralign = sh->sh_addralign;
2459 s->sh_entsize = sh->sh_entsize;
2460 sm_table[i].new_section = 1;
2461 found:
2462 if (sh->sh_type != s->sh_type) {
2463 tcc_error_noabort("invalid section type");
2464 goto fail;
2467 /* align start of section */
2468 offset = s->data_offset;
2470 if (0 == strcmp(sh_name, ".stab")) {
2471 stab_index = i;
2472 goto no_align;
2474 if (0 == strcmp(sh_name, ".stabstr")) {
2475 stabstr_index = i;
2476 goto no_align;
2479 size = sh->sh_addralign - 1;
2480 offset = (offset + size) & ~size;
2481 if (sh->sh_addralign > s->sh_addralign)
2482 s->sh_addralign = sh->sh_addralign;
2483 s->data_offset = offset;
2484 no_align:
2485 sm_table[i].offset = offset;
2486 sm_table[i].s = s;
2487 /* concatenate sections */
2488 size = sh->sh_size;
2489 if (sh->sh_type != SHT_NOBITS) {
2490 unsigned char *ptr;
2491 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2492 ptr = section_ptr_add(s, size);
2493 read(fd, ptr, size);
2494 } else {
2495 s->data_offset += size;
2497 next: ;
2500 /* gr relocate stab strings */
2501 if (stab_index && stabstr_index) {
2502 Stab_Sym *a, *b;
2503 unsigned o;
2504 s = sm_table[stab_index].s;
2505 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2506 b = (Stab_Sym *)(s->data + s->data_offset);
2507 o = sm_table[stabstr_index].offset;
2508 while (a < b)
2509 a->n_strx += o, a++;
2512 /* second short pass to update sh_link and sh_info fields of new
2513 sections */
2514 for(i = 1; i < ehdr.e_shnum; i++) {
2515 s = sm_table[i].s;
2516 if (!s || !sm_table[i].new_section)
2517 continue;
2518 sh = &shdr[i];
2519 if (sh->sh_link > 0)
2520 s->link = sm_table[sh->sh_link].s;
2521 if (sh->sh_type == SHT_RELX) {
2522 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2523 /* update backward link */
2524 s1->sections[s->sh_info]->reloc = s;
2527 sm = sm_table;
2529 /* resolve symbols */
2530 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2532 sym = symtab + 1;
2533 for(i = 1; i < nb_syms; i++, sym++) {
2534 if (sym->st_shndx != SHN_UNDEF &&
2535 sym->st_shndx < SHN_LORESERVE) {
2536 sm = &sm_table[sym->st_shndx];
2537 if (sm->link_once) {
2538 /* if a symbol is in a link once section, we use the
2539 already defined symbol. It is very important to get
2540 correct relocations */
2541 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2542 name = (char *) strtab + sym->st_name;
2543 sym_index = find_elf_sym(symtab_section, name);
2544 if (sym_index)
2545 old_to_new_syms[i] = sym_index;
2547 continue;
2549 /* if no corresponding section added, no need to add symbol */
2550 if (!sm->s)
2551 continue;
2552 /* convert section number */
2553 sym->st_shndx = sm->s->sh_num;
2554 /* offset value */
2555 sym->st_value += sm->offset;
2557 /* add symbol */
2558 name = (char *) strtab + sym->st_name;
2559 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2560 sym->st_info, sym->st_other,
2561 sym->st_shndx, name);
2562 old_to_new_syms[i] = sym_index;
2565 /* third pass to patch relocation entries */
2566 for(i = 1; i < ehdr.e_shnum; i++) {
2567 s = sm_table[i].s;
2568 if (!s)
2569 continue;
2570 sh = &shdr[i];
2571 offset = sm_table[i].offset;
2572 switch(s->sh_type) {
2573 case SHT_RELX:
2574 /* take relocation offset information */
2575 offseti = sm_table[sh->sh_info].offset;
2576 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2577 int type;
2578 unsigned sym_index;
2579 /* convert symbol index */
2580 type = ELFW(R_TYPE)(rel->r_info);
2581 sym_index = ELFW(R_SYM)(rel->r_info);
2582 /* NOTE: only one symtab assumed */
2583 if (sym_index >= nb_syms)
2584 goto invalid_reloc;
2585 sym_index = old_to_new_syms[sym_index];
2586 /* ignore link_once in rel section. */
2587 if (!sym_index && !sm->link_once
2588 #ifdef TCC_TARGET_ARM
2589 && type != R_ARM_V4BX
2590 #endif
2592 invalid_reloc:
2593 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2594 i, strsec + sh->sh_name, rel->r_offset);
2595 goto fail;
2597 rel->r_info = ELFW(R_INFO)(sym_index, type);
2598 /* offset the relocation offset */
2599 rel->r_offset += offseti;
2600 #ifdef TCC_TARGET_ARM
2601 /* Jumps and branches from a Thumb code to a PLT entry need
2602 special handling since PLT entries are ARM code.
2603 Unconditional bl instructions referencing PLT entries are
2604 handled by converting these instructions into blx
2605 instructions. Other case of instructions referencing a PLT
2606 entry require to add a Thumb stub before the PLT entry to
2607 switch to ARM mode. We set bit plt_thumb_stub of the
2608 attribute of a symbol to indicate such a case. */
2609 if (type == R_ARM_THM_JUMP24)
2610 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2611 #endif
2613 break;
2614 default:
2615 break;
2619 ret = 0;
2620 the_end:
2621 tcc_free(symtab);
2622 tcc_free(strtab);
2623 tcc_free(old_to_new_syms);
2624 tcc_free(sm_table);
2625 tcc_free(strsec);
2626 tcc_free(shdr);
2627 return ret;
2630 typedef struct ArchiveHeader {
2631 char ar_name[16]; /* name of this member */
2632 char ar_date[12]; /* file mtime */
2633 char ar_uid[6]; /* owner uid; printed as decimal */
2634 char ar_gid[6]; /* owner gid; printed as decimal */
2635 char ar_mode[8]; /* file mode, printed as octal */
2636 char ar_size[10]; /* file size, printed as decimal */
2637 char ar_fmag[2]; /* should contain ARFMAG */
2638 } ArchiveHeader;
2640 static int get_be32(const uint8_t *b)
2642 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2645 static long get_be64(const uint8_t *b)
2647 long long ret = get_be32(b);
2648 ret = (ret << 32) | (unsigned)get_be32(b+4);
2649 return (long)ret;
2652 /* load only the objects which resolve undefined symbols */
2653 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2655 long i, bound, nsyms, sym_index, off, ret;
2656 uint8_t *data;
2657 const char *ar_names, *p;
2658 const uint8_t *ar_index;
2659 ElfW(Sym) *sym;
2661 data = tcc_malloc(size);
2662 if (read(fd, data, size) != size)
2663 goto fail;
2664 nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
2665 ar_index = data + entrysize;
2666 ar_names = (char *) ar_index + nsyms * entrysize;
2668 do {
2669 bound = 0;
2670 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2671 sym_index = find_elf_sym(symtab_section, p);
2672 if(sym_index) {
2673 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2674 if(sym->st_shndx == SHN_UNDEF) {
2675 off = (entrysize == 4
2676 ? get_be32(ar_index + i * 4)
2677 : get_be64(ar_index + i * 8))
2678 + sizeof(ArchiveHeader);
2679 ++bound;
2680 if(tcc_load_object_file(s1, fd, off) < 0) {
2681 fail:
2682 ret = -1;
2683 goto the_end;
2688 } while(bound);
2689 ret = 0;
2690 the_end:
2691 tcc_free(data);
2692 return ret;
2695 /* load a '.a' file */
2696 ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
2698 ArchiveHeader hdr;
2699 char ar_size[11];
2700 char ar_name[17];
2701 char magic[8];
2702 int size, len, i;
2703 unsigned long file_offset;
2705 /* skip magic which was already checked */
2706 read(fd, magic, sizeof(magic));
2708 for(;;) {
2709 len = read(fd, &hdr, sizeof(hdr));
2710 if (len == 0)
2711 break;
2712 if (len != sizeof(hdr)) {
2713 tcc_error_noabort("invalid archive");
2714 return -1;
2716 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2717 ar_size[sizeof(hdr.ar_size)] = '\0';
2718 size = strtol(ar_size, NULL, 0);
2719 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2720 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2721 if (ar_name[i] != ' ')
2722 break;
2724 ar_name[i + 1] = '\0';
2725 file_offset = lseek(fd, 0, SEEK_CUR);
2726 /* align to even */
2727 size = (size + 1) & ~1;
2728 if (!strcmp(ar_name, "/")) {
2729 /* coff symbol table : we handle it */
2730 if(s1->alacarte_link)
2731 return tcc_load_alacarte(s1, fd, size, 4);
2732 } else if (!strcmp(ar_name, "/SYM64/")) {
2733 if(s1->alacarte_link)
2734 return tcc_load_alacarte(s1, fd, size, 8);
2735 } else {
2736 ElfW(Ehdr) ehdr;
2737 if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2738 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2739 return -1;
2742 lseek(fd, file_offset + size, SEEK_SET);
2744 return 0;
2747 #ifndef TCC_TARGET_PE
2748 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2749 is referenced by the user (so it should be added as DT_NEEDED in
2750 the generated ELF file) */
2751 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2753 ElfW(Ehdr) ehdr;
2754 ElfW(Shdr) *shdr, *sh, *sh1;
2755 int i, j, nb_syms, nb_dts, sym_bind, ret;
2756 ElfW(Sym) *sym, *dynsym;
2757 ElfW(Dyn) *dt, *dynamic;
2758 unsigned char *dynstr;
2759 const char *name, *soname;
2760 DLLReference *dllref;
2762 read(fd, &ehdr, sizeof(ehdr));
2764 /* test CPU specific stuff */
2765 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2766 ehdr.e_machine != EM_TCC_TARGET) {
2767 tcc_error_noabort("bad architecture");
2768 return -1;
2771 /* read sections */
2772 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2774 /* load dynamic section and dynamic symbols */
2775 nb_syms = 0;
2776 nb_dts = 0;
2777 dynamic = NULL;
2778 dynsym = NULL; /* avoid warning */
2779 dynstr = NULL; /* avoid warning */
2780 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2781 switch(sh->sh_type) {
2782 case SHT_DYNAMIC:
2783 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2784 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2785 break;
2786 case SHT_DYNSYM:
2787 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2788 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2789 sh1 = &shdr[sh->sh_link];
2790 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2791 break;
2792 default:
2793 break;
2797 /* compute the real library name */
2798 soname = tcc_basename(filename);
2800 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2801 if (dt->d_tag == DT_SONAME) {
2802 soname = (char *) dynstr + dt->d_un.d_val;
2806 /* if the dll is already loaded, do not load it */
2807 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2808 dllref = s1->loaded_dlls[i];
2809 if (!strcmp(soname, dllref->name)) {
2810 /* but update level if needed */
2811 if (level < dllref->level)
2812 dllref->level = level;
2813 ret = 0;
2814 goto the_end;
2818 /* add the dll and its level */
2819 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2820 dllref->level = level;
2821 strcpy(dllref->name, soname);
2822 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2824 /* add dynamic symbols in dynsym_section */
2825 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2826 sym_bind = ELFW(ST_BIND)(sym->st_info);
2827 if (sym_bind == STB_LOCAL)
2828 continue;
2829 name = (char *) dynstr + sym->st_name;
2830 set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2831 sym->st_info, sym->st_other, sym->st_shndx, name);
2834 /* load all referenced DLLs */
2835 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2836 switch(dt->d_tag) {
2837 case DT_NEEDED:
2838 name = (char *) dynstr + dt->d_un.d_val;
2839 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2840 dllref = s1->loaded_dlls[j];
2841 if (!strcmp(name, dllref->name))
2842 goto already_loaded;
2844 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2845 tcc_error_noabort("referenced dll '%s' not found", name);
2846 ret = -1;
2847 goto the_end;
2849 already_loaded:
2850 break;
2853 ret = 0;
2854 the_end:
2855 tcc_free(dynstr);
2856 tcc_free(dynsym);
2857 tcc_free(dynamic);
2858 tcc_free(shdr);
2859 return ret;
2862 #define LD_TOK_NAME 256
2863 #define LD_TOK_EOF (-1)
2865 /* return next ld script token */
2866 static int ld_next(TCCState *s1, char *name, int name_size)
2868 int c;
2869 char *q;
2871 redo:
2872 switch(ch) {
2873 case ' ':
2874 case '\t':
2875 case '\f':
2876 case '\v':
2877 case '\r':
2878 case '\n':
2879 inp();
2880 goto redo;
2881 case '/':
2882 minp();
2883 if (ch == '*') {
2884 file->buf_ptr = parse_comment(file->buf_ptr);
2885 ch = file->buf_ptr[0];
2886 goto redo;
2887 } else {
2888 q = name;
2889 *q++ = '/';
2890 goto parse_name;
2892 break;
2893 case '\\':
2894 ch = handle_eob();
2895 if (ch != '\\')
2896 goto redo;
2897 /* fall through */
2898 /* case 'a' ... 'z': */
2899 case 'a':
2900 case 'b':
2901 case 'c':
2902 case 'd':
2903 case 'e':
2904 case 'f':
2905 case 'g':
2906 case 'h':
2907 case 'i':
2908 case 'j':
2909 case 'k':
2910 case 'l':
2911 case 'm':
2912 case 'n':
2913 case 'o':
2914 case 'p':
2915 case 'q':
2916 case 'r':
2917 case 's':
2918 case 't':
2919 case 'u':
2920 case 'v':
2921 case 'w':
2922 case 'x':
2923 case 'y':
2924 case 'z':
2925 /* case 'A' ... 'z': */
2926 case 'A':
2927 case 'B':
2928 case 'C':
2929 case 'D':
2930 case 'E':
2931 case 'F':
2932 case 'G':
2933 case 'H':
2934 case 'I':
2935 case 'J':
2936 case 'K':
2937 case 'L':
2938 case 'M':
2939 case 'N':
2940 case 'O':
2941 case 'P':
2942 case 'Q':
2943 case 'R':
2944 case 'S':
2945 case 'T':
2946 case 'U':
2947 case 'V':
2948 case 'W':
2949 case 'X':
2950 case 'Y':
2951 case 'Z':
2952 case '_':
2953 case '.':
2954 case '$':
2955 case '~':
2956 q = name;
2957 parse_name:
2958 for(;;) {
2959 if (!((ch >= 'a' && ch <= 'z') ||
2960 (ch >= 'A' && ch <= 'Z') ||
2961 (ch >= '0' && ch <= '9') ||
2962 strchr("/.-_+=$:\\,~", ch)))
2963 break;
2964 if ((q - name) < name_size - 1) {
2965 *q++ = ch;
2967 minp();
2969 *q = '\0';
2970 c = LD_TOK_NAME;
2971 break;
2972 case CH_EOF:
2973 c = LD_TOK_EOF;
2974 break;
2975 default:
2976 c = ch;
2977 inp();
2978 break;
2980 return c;
2983 static int ld_add_file(TCCState *s1, const char filename[])
2985 int ret;
2987 ret = tcc_add_file_internal(s1, filename, AFF_TYPE_BIN);
2988 if (ret)
2989 ret = tcc_add_dll(s1, filename, 0);
2990 return ret;
2993 static inline int new_undef_syms(void)
2995 int ret = 0;
2996 ret = new_undef_sym;
2997 new_undef_sym = 0;
2998 return ret;
3001 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3003 char filename[1024], libname[1024];
3004 int t, group, nblibs = 0, ret = 0;
3005 char **libs = NULL;
3007 group = !strcmp(cmd, "GROUP");
3008 if (!as_needed)
3009 new_undef_syms();
3010 t = ld_next(s1, filename, sizeof(filename));
3011 if (t != '(')
3012 expect("(");
3013 t = ld_next(s1, filename, sizeof(filename));
3014 for(;;) {
3015 libname[0] = '\0';
3016 if (t == LD_TOK_EOF) {
3017 tcc_error_noabort("unexpected end of file");
3018 ret = -1;
3019 goto lib_parse_error;
3020 } else if (t == ')') {
3021 break;
3022 } else if (t == '-') {
3023 t = ld_next(s1, filename, sizeof(filename));
3024 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3025 tcc_error_noabort("library name expected");
3026 ret = -1;
3027 goto lib_parse_error;
3029 pstrcpy(libname, sizeof libname, &filename[1]);
3030 if (s1->static_link) {
3031 snprintf(filename, sizeof filename, "lib%s.a", libname);
3032 } else {
3033 snprintf(filename, sizeof filename, "lib%s.so", libname);
3035 } else if (t != LD_TOK_NAME) {
3036 tcc_error_noabort("filename expected");
3037 ret = -1;
3038 goto lib_parse_error;
3040 if (!strcmp(filename, "AS_NEEDED")) {
3041 ret = ld_add_file_list(s1, cmd, 1);
3042 if (ret)
3043 goto lib_parse_error;
3044 } else {
3045 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3046 if (!as_needed) {
3047 ret = ld_add_file(s1, filename);
3048 if (ret)
3049 goto lib_parse_error;
3050 if (group) {
3051 /* Add the filename *and* the libname to avoid future conversions */
3052 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename));
3053 if (libname[0] != '\0')
3054 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname));
3058 t = ld_next(s1, filename, sizeof(filename));
3059 if (t == ',') {
3060 t = ld_next(s1, filename, sizeof(filename));
3063 if (group && !as_needed) {
3064 while (new_undef_syms()) {
3065 int i;
3067 for (i = 0; i < nblibs; i ++)
3068 ld_add_file(s1, libs[i]);
3071 lib_parse_error:
3072 dynarray_reset(&libs, &nblibs);
3073 return ret;
3076 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3077 files */
3078 ST_FUNC int tcc_load_ldscript(TCCState *s1)
3080 char cmd[64];
3081 char filename[1024];
3082 int t, ret;
3084 ch = handle_eob();
3085 for(;;) {
3086 t = ld_next(s1, cmd, sizeof(cmd));
3087 if (t == LD_TOK_EOF)
3088 return 0;
3089 else if (t != LD_TOK_NAME)
3090 return -1;
3091 if (!strcmp(cmd, "INPUT") ||
3092 !strcmp(cmd, "GROUP")) {
3093 ret = ld_add_file_list(s1, cmd, 0);
3094 if (ret)
3095 return ret;
3096 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3097 !strcmp(cmd, "TARGET")) {
3098 /* ignore some commands */
3099 t = ld_next(s1, cmd, sizeof(cmd));
3100 if (t != '(')
3101 expect("(");
3102 for(;;) {
3103 t = ld_next(s1, filename, sizeof(filename));
3104 if (t == LD_TOK_EOF) {
3105 tcc_error_noabort("unexpected end of file");
3106 return -1;
3107 } else if (t == ')') {
3108 break;
3111 } else {
3112 return -1;
3115 return 0;
3117 #endif /* !TCC_TARGET_PE */