Allow to get sym attr and fail if no entry
[tinycc.git] / tccelf.c
blobe65235117f4e64e24036ec2981b86e2d271019f7
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, int do_resolve)
657 ElfW(Sym) *sym, *esym;
658 int sym_bind, sh_num, sym_index;
659 const char *name;
661 for_each_elem(symtab_section, 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;
669 name = (char *) symtab_section->link->data + sym->st_name;
670 addr = dlsym(RTLD_DEFAULT, name);
671 if (addr) {
672 sym->st_value = (addr_t)addr;
673 #ifdef DEBUG_RELOC
674 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
675 #endif
676 goto found;
678 #endif
679 } else if (s1->dynsym) {
680 /* if dynamic symbol exist, then use it */
681 sym_index = find_elf_sym(s1->dynsym, name);
682 if (sym_index) {
683 esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
684 sym->st_value = esym->st_value;
685 goto found;
688 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
689 it */
690 if (!strcmp(name, "_fp_hw"))
691 goto found;
692 /* only weak symbols are accepted to be undefined. Their
693 value is zero */
694 sym_bind = ELFW(ST_BIND)(sym->st_info);
695 if (sym_bind == STB_WEAK) {
696 sym->st_value = 0;
697 } else {
698 tcc_error_noabort("undefined symbol '%s'", name);
700 } else if (sh_num < SHN_LORESERVE) {
701 /* add section base */
702 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
704 found: ;
708 /* relocate a given section (CPU dependent) by applying the relocations
709 in the associated relocation section */
710 ST_FUNC void relocate_section(TCCState *s1, Section *s)
712 Section *sr = s->reloc;
713 ElfW_Rel *rel;
714 ElfW(Sym) *sym;
715 int type, sym_index;
716 unsigned char *ptr;
717 addr_t val, addr;
719 relocate_init(sr);
720 for_each_elem(sr, 0, rel, ElfW_Rel) {
721 ptr = s->data + rel->r_offset;
723 sym_index = ELFW(R_SYM)(rel->r_info);
724 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
725 val = sym->st_value;
726 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
727 val += rel->r_addend;
728 #endif
729 type = ELFW(R_TYPE)(rel->r_info);
730 addr = s->sh_addr + rel->r_offset;
732 relocate(s1, rel, type, ptr, addr, val);
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;
1033 unsigned long ofs;
1035 for(i = 1; i < s1->nb_sections; i++) {
1036 s = s1->sections[i];
1037 if (s->sh_type != SHT_RELX)
1038 continue;
1039 /* no need to handle got relocations */
1040 if (s->link != symtab_section)
1041 continue;
1042 for_each_elem(s, 0, rel, ElfW_Rel) {
1043 type = ELFW(R_TYPE)(rel->r_info);
1044 sym_index = ELFW(R_SYM)(rel->r_info);
1045 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1046 if (relocs_info[type].gotplt_entry == NO_GOTPLT_ENTRY)
1047 continue;
1049 /* Proceed with PLT/GOT [entry] creation if any of the following
1050 condition is met:
1051 - it is an undefined reference (dynamic relocation needed)
1052 - symbol is absolute (probably created by tcc_add_symbol)
1053 - relocation requires a PLT/GOT (BUILD_GOTPLT_ENTRY or
1054 ALWAYS_GOTPLT_ENTRY). */
1055 if (sym->st_shndx != SHN_UNDEF &&
1056 sym->st_shndx != SHN_ABS &&
1057 relocs_info[type].gotplt_entry == AUTO_GOTPLT_ENTRY)
1058 continue;
1060 #ifdef TCC_TARGET_X86_64
1061 if (type == R_X86_64_PLT32 &&
1062 ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT) {
1063 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1064 continue;
1066 #endif
1068 if (!s1->got)
1069 build_got(s1);
1071 if (relocs_info[type].gotplt_entry == BUILD_GOT_ONLY)
1072 continue;
1074 if (relocs_info[type].code_reloc)
1075 reloc_type = R_JMP_SLOT;
1076 else
1077 reloc_type = R_GLOB_DAT;
1078 ofs = put_got_entry(s1, reloc_type, type, sym->st_size,
1079 sym->st_info, sym_index);
1081 #ifdef DEBUG_RELOC
1082 printf ("maybegot: %s, %d, %d --> ofs=0x%x\n",
1083 (char *) symtab_section->link->data + sym->st_name, type,
1084 sym->st_shndx, ofs);
1085 #endif
1087 #if defined (TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64)
1088 /* We store the place of the generated PLT slot in our addend. */
1089 if (relocs_info[type].pltoff_addend)
1090 rel->r_addend += ofs;
1092 #elif defined (TCC_TARGET_ARM)
1093 if (type == R_ARM_PC24 || type == R_ARM_CALL ||
1094 type == R_ARM_JUMP24 || type == R_ARM_PLT32) {
1095 addr_t *ptr = (addr_t*)(s1->sections[s->sh_info]->data
1096 + rel->r_offset);
1097 /* x must be signed! */
1098 int x = *ptr & 0xffffff;
1099 x = (x << 8) >> 8;
1100 x <<= 2;
1101 x += ofs;
1102 x >>= 2;
1103 #ifdef DEBUG_RELOC
1104 printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr,
1105 (*ptr & 0xff000000) | x, x);
1106 #endif
1107 *ptr = (*ptr & 0xff000000) | x;
1109 #endif
1114 ST_FUNC Section *new_symtab(TCCState *s1,
1115 const char *symtab_name, int sh_type, int sh_flags,
1116 const char *strtab_name,
1117 const char *hash_name, int hash_sh_flags)
1119 Section *symtab, *strtab, *hash;
1120 int *ptr, nb_buckets;
1122 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1123 symtab->sh_entsize = sizeof(ElfW(Sym));
1124 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1125 put_elf_str(strtab, "");
1126 symtab->link = strtab;
1127 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1129 nb_buckets = 1;
1131 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1132 hash->sh_entsize = sizeof(int);
1133 symtab->hash = hash;
1134 hash->link = symtab;
1136 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1137 ptr[0] = nb_buckets;
1138 ptr[1] = 1;
1139 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1140 return symtab;
1143 /* put dynamic tag */
1144 static void put_dt(Section *dynamic, int dt, addr_t val)
1146 ElfW(Dyn) *dyn;
1147 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1148 dyn->d_tag = dt;
1149 dyn->d_un.d_val = val;
1152 #ifndef TCC_TARGET_PE
1153 static void add_init_array_defines(TCCState *s1, const char *section_name)
1155 Section *s;
1156 long end_offset;
1157 char sym_start[1024];
1158 char sym_end[1024];
1160 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1161 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1163 s = find_section(s1, section_name);
1164 if (!s) {
1165 end_offset = 0;
1166 s = data_section;
1167 } else {
1168 end_offset = s->data_offset;
1171 set_elf_sym(symtab_section,
1172 0, 0,
1173 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1174 s->sh_num, sym_start);
1175 set_elf_sym(symtab_section,
1176 end_offset, 0,
1177 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1178 s->sh_num, sym_end);
1180 #endif
1182 static int tcc_add_support(TCCState *s1, const char *filename)
1184 char buf[1024];
1185 snprintf(buf, sizeof(buf), "%s/"TCC_ARCH_DIR"%s", s1->tcc_lib_path, filename);
1186 return tcc_add_file(s1, buf);
1189 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1191 #ifdef CONFIG_TCC_BCHECK
1192 addr_t *ptr;
1193 int sym_index;
1195 if (0 == s1->do_bounds_check)
1196 return;
1197 /* XXX: add an object file to do that */
1198 ptr = section_ptr_add(bounds_section, sizeof(*ptr));
1199 *ptr = 0;
1200 set_elf_sym(symtab_section, 0, 0,
1201 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1202 bounds_section->sh_num, "__bounds_start");
1203 /* pull bcheck.o from libtcc1.a */
1204 sym_index = set_elf_sym(symtab_section, 0, 0,
1205 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1206 SHN_UNDEF, "__bound_init");
1207 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1208 /* add 'call __bound_init()' in .init section */
1209 Section *init_section = find_section(s1, ".init");
1210 unsigned char *pinit = section_ptr_add(init_section, 5);
1211 pinit[0] = 0xe8;
1212 write32le(pinit + 1, -4);
1213 put_elf_reloc(symtab_section, init_section,
1214 init_section->data_offset - 4, R_386_PC32, sym_index);
1215 /* R_386_PC32 = R_X86_64_PC32 = 2 */
1217 #endif
1220 /* add tcc runtime libraries */
1221 ST_FUNC void tcc_add_runtime(TCCState *s1)
1223 tcc_add_bcheck(s1);
1224 tcc_add_pragma_libs(s1);
1225 /* add libc */
1226 if (!s1->nostdlib) {
1227 tcc_add_library_err(s1, "c");
1228 #ifdef CONFIG_USE_LIBGCC
1229 if (!s1->static_link) {
1230 tcc_add_file(s1, TCC_LIBGCC);
1232 #endif
1233 tcc_add_support(s1, "libtcc1.a");
1234 /* add crt end if not memory output */
1235 if (s1->output_type != TCC_OUTPUT_MEMORY)
1236 tcc_add_crt(s1, "crtn.o");
1240 /* add various standard linker symbols (must be done after the
1241 sections are filled (for example after allocating common
1242 symbols)) */
1243 ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
1245 char buf[1024];
1246 int i;
1247 Section *s;
1249 set_elf_sym(symtab_section,
1250 text_section->data_offset, 0,
1251 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1252 text_section->sh_num, "_etext");
1253 set_elf_sym(symtab_section,
1254 data_section->data_offset, 0,
1255 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1256 data_section->sh_num, "_edata");
1257 set_elf_sym(symtab_section,
1258 bss_section->data_offset, 0,
1259 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1260 bss_section->sh_num, "_end");
1261 #ifndef TCC_TARGET_PE
1262 /* horrible new standard ldscript defines */
1263 add_init_array_defines(s1, ".preinit_array");
1264 add_init_array_defines(s1, ".init_array");
1265 add_init_array_defines(s1, ".fini_array");
1266 #endif
1268 /* add start and stop symbols for sections whose name can be
1269 expressed in C */
1270 for(i = 1; i < s1->nb_sections; i++) {
1271 s = s1->sections[i];
1272 if (s->sh_type == SHT_PROGBITS &&
1273 (s->sh_flags & SHF_ALLOC)) {
1274 const char *p;
1275 int ch;
1277 /* check if section name can be expressed in C */
1278 p = s->name;
1279 for(;;) {
1280 ch = *p;
1281 if (!ch)
1282 break;
1283 if (!isid(ch) && !isnum(ch))
1284 goto next_sec;
1285 p++;
1287 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1288 set_elf_sym(symtab_section,
1289 0, 0,
1290 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1291 s->sh_num, buf);
1292 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1293 set_elf_sym(symtab_section,
1294 s->data_offset, 0,
1295 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1296 s->sh_num, buf);
1298 next_sec: ;
1302 static void tcc_output_binary(TCCState *s1, FILE *f,
1303 const int *sec_order)
1305 Section *s;
1306 int i, offset, size;
1308 offset = 0;
1309 for(i=1;i<s1->nb_sections;i++) {
1310 s = s1->sections[sec_order[i]];
1311 if (s->sh_type != SHT_NOBITS &&
1312 (s->sh_flags & SHF_ALLOC)) {
1313 while (offset < s->sh_offset) {
1314 fputc(0, f);
1315 offset++;
1317 size = s->sh_size;
1318 fwrite(s->data, 1, size, f);
1319 offset += size;
1324 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1325 #define HAVE_PHDR 1
1326 #define EXTRA_RELITEMS 14
1328 /* move the relocation value from .dynsym to .got */
1329 static void patch_dynsym_undef(TCCState *s1, Section *s)
1331 uint32_t *gotd = (void *)s1->got->data;
1332 ElfW(Sym) *sym;
1334 gotd += 3; /* dummy entries in .got */
1335 /* relocate symbols in .dynsym */
1336 for_each_elem(s, 1, sym, ElfW(Sym)) {
1337 if (sym->st_shndx == SHN_UNDEF) {
1338 *gotd++ = sym->st_value + 6; /* XXX 6 is magic ? */
1339 sym->st_value = 0;
1343 #else
1344 #define HAVE_PHDR 1
1345 #define EXTRA_RELITEMS 9
1347 /* zero plt offsets of weak symbols in .dynsym */
1348 static void patch_dynsym_undef(TCCState *s1, Section *s)
1350 ElfW(Sym) *sym;
1352 for_each_elem(s, 1, sym, ElfW(Sym))
1353 if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
1354 sym->st_value = 0;
1356 #endif
1358 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1360 int sym_index = ELFW(R_SYM) (rel->r_info);
1361 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1362 unsigned long offset;
1364 if (sym_index >= s1->nb_sym_attrs)
1365 return;
1366 offset = s1->sym_attrs[sym_index].got_offset;
1367 section_reserve(s1->got, offset + PTR_SIZE);
1368 #ifdef TCC_TARGET_X86_64
1369 /* only works for x86-64 */
1370 write32le(s1->got->data + offset + 4, sym->st_value >> 32);
1371 #endif
1372 write32le(s1->got->data + offset, sym->st_value & 0xffffffff);
1375 /* Perform relocation to GOT or PLT entries */
1376 ST_FUNC void fill_got(TCCState *s1)
1378 Section *s;
1379 ElfW_Rel *rel;
1380 int i;
1382 for(i = 1; i < s1->nb_sections; i++) {
1383 s = s1->sections[i];
1384 if (s->sh_type != SHT_RELX)
1385 continue;
1386 /* no need to handle got relocations */
1387 if (s->link != symtab_section)
1388 continue;
1389 for_each_elem(s, 0, rel, ElfW_Rel) {
1390 switch (ELFW(R_TYPE) (rel->r_info)) {
1391 case R_X86_64_GOT32:
1392 case R_X86_64_GOTPCREL:
1393 case R_X86_64_GOTPCRELX:
1394 case R_X86_64_REX_GOTPCRELX:
1395 case R_X86_64_PLT32:
1396 fill_got_entry(s1, rel);
1397 break;
1403 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1404 in shared libraries and export non local defined symbols to shared libraries
1405 if -rdynamic switch was given on command line */
1406 static void bind_exe_dynsyms(TCCState *s1)
1408 const char *name;
1409 int sym_index, index;
1410 ElfW(Sym) *sym, *esym;
1411 int type;
1413 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1414 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1415 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1416 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1417 if (sym->st_shndx == SHN_UNDEF) {
1418 name = (char *) symtab_section->link->data + sym->st_name;
1419 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1420 if (sym_index) {
1421 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1422 type = ELFW(ST_TYPE)(esym->st_info);
1423 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1424 /* Indirect functions shall have STT_FUNC type in executable
1425 * dynsym section. Indeed, a dlsym call following a lazy
1426 * resolution would pick the symbol value from the
1427 * executable dynsym entry which would contain the address
1428 * of the function wanted by the caller of dlsym instead of
1429 * the address of the function that would return that
1430 * address */
1431 put_elf_sym(s1->dynsym, 0, esym->st_size,
1432 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
1433 name);
1434 } else if (type == STT_OBJECT) {
1435 unsigned long offset;
1436 ElfW(Sym) *dynsym;
1437 offset = bss_section->data_offset;
1438 /* XXX: which alignment ? */
1439 offset = (offset + 16 - 1) & -16;
1440 set_elf_sym (s1->symtab, offset, esym->st_size,
1441 esym->st_info, 0, bss_section->sh_num, name);
1442 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1443 esym->st_info, 0, bss_section->sh_num,
1444 name);
1445 /* Ensure R_COPY works for weak symbol aliases */
1446 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1447 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1448 if ((dynsym->st_value == esym->st_value)
1449 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1450 char *dynname = (char *) s1->dynsymtab_section->link->data
1451 + dynsym->st_name;
1452 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1453 dynsym->st_info, 0,
1454 bss_section->sh_num, dynname);
1455 break;
1459 put_elf_reloc(s1->dynsym, bss_section,
1460 offset, R_COPY, index);
1461 offset += esym->st_size;
1462 bss_section->data_offset = offset;
1464 } else {
1465 /* STB_WEAK undefined symbols are accepted */
1466 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1467 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1468 !strcmp(name, "_fp_hw")) {
1469 } else {
1470 tcc_error_noabort("undefined symbol '%s'", name);
1473 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1474 /* if -rdynamic option, then export all non local symbols */
1475 name = (char *) symtab_section->link->data + sym->st_name;
1476 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1477 0, sym->st_shndx, name);
1482 /* Bind symbols of libraries: export all non local symbols of executable that
1483 are referenced by shared libraries. The reason is that the dynamic loader
1484 search symbol first in executable and then in libraries. Therefore a
1485 reference to a symbol already defined by a library can still be resolved by
1486 a symbol in the executable. */
1487 static void bind_libs_dynsyms(TCCState *s1)
1489 const char *name;
1490 int sym_index;
1491 ElfW(Sym) *sym, *esym;
1493 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1494 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1495 sym_index = find_elf_sym(symtab_section, name);
1496 /* XXX: avoid adding a symbol if already present because of
1497 -rdynamic ? */
1498 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1499 if (sym_index && sym->st_shndx != SHN_UNDEF)
1500 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1501 0, sym->st_shndx, name);
1502 else if (esym->st_shndx == SHN_UNDEF) {
1503 /* weak symbols can stay undefined */
1504 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1505 tcc_warning("undefined dynamic symbol '%s'", name);
1510 /* Export all non local symbols. This is used by shared libraries so that the
1511 non local symbols they define can resolve a reference in another shared
1512 library or in the executable. Correspondingly, it allows undefined local
1513 symbols to be resolved by other shared libraries or by the executable. */
1514 static void export_global_syms(TCCState *s1)
1516 int nb_syms, dynindex, index;
1517 const char *name;
1518 ElfW(Sym) *sym;
1520 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1521 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1522 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1523 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1524 name = (char *) symtab_section->link->data + sym->st_name;
1525 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1526 sym->st_info, 0, sym->st_shndx, name);
1527 index = sym - (ElfW(Sym) *) symtab_section->data;
1528 s1->symtab_to_dynsym[index] = dynindex;
1533 /* relocate the PLT: compute addresses and offsets in the PLT now that final
1534 address for PLT and GOT are known (see fill_program_header) */
1535 ST_FUNC void relocate_plt(TCCState *s1)
1537 uint8_t *p, *p_end;
1539 if (!s1->plt)
1540 return;
1542 p = s1->plt->data;
1543 p_end = p + s1->plt->data_offset;
1544 if (p < p_end) {
1545 #if defined(TCC_TARGET_I386)
1546 add32le(p + 2, s1->got->sh_addr);
1547 add32le(p + 8, s1->got->sh_addr);
1548 p += 16;
1549 while (p < p_end) {
1550 add32le(p + 2, s1->got->sh_addr);
1551 p += 16;
1553 #elif defined(TCC_TARGET_X86_64)
1554 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
1555 add32le(p + 2, x);
1556 add32le(p + 8, x - 6);
1557 p += 16;
1558 while (p < p_end) {
1559 add32le(p + 2, x + s1->plt->data - p);
1560 p += 16;
1562 #elif defined(TCC_TARGET_ARM)
1563 int x = s1->got->sh_addr - s1->plt->sh_addr - 12;
1564 write32le(s1->plt->data + 16, x - 16);
1565 p += 20;
1566 while (p < p_end) {
1567 if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
1568 p += 4;
1569 add32le(p + 12, x + s1->plt->data - p);
1570 p += 16;
1572 #elif defined(TCC_TARGET_ARM64)
1573 uint64_t plt = s1->plt->sh_addr;
1574 uint64_t got = s1->got->sh_addr;
1575 uint64_t off = (got >> 12) - (plt >> 12);
1576 if ((off + ((uint32_t)1 << 20)) >> 21)
1577 tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt);
1578 write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
1579 write32le(p + 4, (0x90000010 | // adrp x16,...
1580 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1581 write32le(p + 8, (0xf9400211 | // ldr x17,[x16,#...]
1582 (got & 0xff8) << 7));
1583 write32le(p + 12, (0x91000210 | // add x16,x16,#...
1584 (got & 0xfff) << 10));
1585 write32le(p + 16, 0xd61f0220); // br x17
1586 write32le(p + 20, 0xd503201f); // nop
1587 write32le(p + 24, 0xd503201f); // nop
1588 write32le(p + 28, 0xd503201f); // nop
1589 p += 32;
1590 while (p < p_end) {
1591 uint64_t pc = plt + (p - s1->plt->data);
1592 uint64_t addr = got + read64le(p);
1593 uint64_t off = (addr >> 12) - (pc >> 12);
1594 if ((off + ((uint32_t)1 << 20)) >> 21)
1595 tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc);
1596 write32le(p, (0x90000010 | // adrp x16,...
1597 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1598 write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
1599 (addr & 0xff8) << 7));
1600 write32le(p + 8, (0x91000210 | // add x16,x16,#...
1601 (addr & 0xfff) << 10));
1602 write32le(p + 12, 0xd61f0220); // br x17
1603 p += 16;
1605 #elif defined(TCC_TARGET_C67)
1606 /* XXX: TODO */
1607 #else
1608 #error unsupported CPU
1609 #endif
1613 /* Allocate strings for section names and decide if an unallocated section
1614 should be output.
1616 NOTE: the strsec section comes last, so its size is also correct ! */
1617 static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1619 int i;
1620 Section *s;
1622 /* Allocate strings for section names */
1623 for(i = 1; i < s1->nb_sections; i++) {
1624 s = s1->sections[i];
1625 s->sh_name = put_elf_str(strsec, s->name);
1626 /* when generating a DLL, we include relocations but we may
1627 patch them */
1628 if (file_type == TCC_OUTPUT_DLL &&
1629 s->sh_type == SHT_RELX &&
1630 !(s->sh_flags & SHF_ALLOC)) {
1631 /* gr: avoid bogus relocs for empty (debug) sections */
1632 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1633 prepare_dynamic_rel(s1, s);
1634 else if (s1->do_debug)
1635 s->sh_size = s->data_offset;
1636 } else if (s1->do_debug ||
1637 file_type == TCC_OUTPUT_OBJ ||
1638 (s->sh_flags & SHF_ALLOC) ||
1639 i == (s1->nb_sections - 1)) {
1640 /* we output all sections if debug or object file */
1641 s->sh_size = s->data_offset;
1646 /* Info to be copied in dynamic section */
1647 struct dyn_inf {
1648 Section *dynamic;
1649 Section *dynstr;
1650 unsigned long dyn_rel_off;
1651 addr_t rel_addr;
1652 addr_t rel_size;
1653 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1654 addr_t bss_addr;
1655 addr_t bss_size;
1656 #endif
1659 /* Assign sections to segments and decide how are sections laid out when loaded
1660 in memory. This function also fills corresponding program headers. */
1661 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1662 Section *interp, Section* strsec,
1663 struct dyn_inf *dyninf, int *sec_order)
1665 int i, j, k, file_type, sh_order_index, file_offset;
1666 unsigned long s_align;
1667 long long tmp;
1668 addr_t addr;
1669 ElfW(Phdr) *ph;
1670 Section *s;
1672 file_type = s1->output_type;
1673 sh_order_index = 1;
1674 file_offset = 0;
1675 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1676 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1677 s_align = ELF_PAGE_SIZE;
1678 if (s1->section_align)
1679 s_align = s1->section_align;
1681 if (phnum > 0) {
1682 if (s1->has_text_addr) {
1683 int a_offset, p_offset;
1684 addr = s1->text_addr;
1685 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1686 ELF_PAGE_SIZE */
1687 a_offset = (int) (addr & (s_align - 1));
1688 p_offset = file_offset & (s_align - 1);
1689 if (a_offset < p_offset)
1690 a_offset += s_align;
1691 file_offset += (a_offset - p_offset);
1692 } else {
1693 if (file_type == TCC_OUTPUT_DLL)
1694 addr = 0;
1695 else
1696 addr = ELF_START_ADDR;
1697 /* compute address after headers */
1698 addr += (file_offset & (s_align - 1));
1701 ph = &phdr[0];
1702 /* Leave one program headers for the program interpreter and one for
1703 the program header table itself if needed. These are done later as
1704 they require section layout to be done first. */
1705 if (interp)
1706 ph += 1 + HAVE_PHDR;
1708 /* dynamic relocation table information, for .dynamic section */
1709 dyninf->rel_addr = dyninf->rel_size = 0;
1710 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1711 dyninf->bss_addr = dyninf->bss_size = 0;
1712 #endif
1714 for(j = 0; j < 2; j++) {
1715 ph->p_type = PT_LOAD;
1716 if (j == 0)
1717 ph->p_flags = PF_R | PF_X;
1718 else
1719 ph->p_flags = PF_R | PF_W;
1720 ph->p_align = s_align;
1722 /* Decide the layout of sections loaded in memory. This must
1723 be done before program headers are filled since they contain
1724 info about the layout. We do the following ordering: interp,
1725 symbol tables, relocations, progbits, nobits */
1726 /* XXX: do faster and simpler sorting */
1727 for(k = 0; k < 5; k++) {
1728 for(i = 1; i < s1->nb_sections; i++) {
1729 s = s1->sections[i];
1730 /* compute if section should be included */
1731 if (j == 0) {
1732 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1733 SHF_ALLOC)
1734 continue;
1735 } else {
1736 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1737 (SHF_ALLOC | SHF_WRITE))
1738 continue;
1740 if (s == interp) {
1741 if (k != 0)
1742 continue;
1743 } else if (s->sh_type == SHT_DYNSYM ||
1744 s->sh_type == SHT_STRTAB ||
1745 s->sh_type == SHT_HASH) {
1746 if (k != 1)
1747 continue;
1748 } else if (s->sh_type == SHT_RELX) {
1749 if (k != 2)
1750 continue;
1751 } else if (s->sh_type == SHT_NOBITS) {
1752 if (k != 4)
1753 continue;
1754 } else {
1755 if (k != 3)
1756 continue;
1758 sec_order[sh_order_index++] = i;
1760 /* section matches: we align it and add its size */
1761 tmp = addr;
1762 addr = (addr + s->sh_addralign - 1) &
1763 ~(s->sh_addralign - 1);
1764 file_offset += (int) ( addr - tmp );
1765 s->sh_offset = file_offset;
1766 s->sh_addr = addr;
1768 /* update program header infos */
1769 if (ph->p_offset == 0) {
1770 ph->p_offset = file_offset;
1771 ph->p_vaddr = addr;
1772 ph->p_paddr = ph->p_vaddr;
1774 /* update dynamic relocation infos */
1775 if (s->sh_type == SHT_RELX) {
1776 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1777 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1778 dyninf->rel_addr = addr;
1779 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1781 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1782 dyninf->bss_addr = addr;
1783 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1785 #else
1786 if (dyninf->rel_size == 0)
1787 dyninf->rel_addr = addr;
1788 dyninf->rel_size += s->sh_size;
1789 #endif
1791 addr += s->sh_size;
1792 if (s->sh_type != SHT_NOBITS)
1793 file_offset += s->sh_size;
1796 if (j == 0) {
1797 /* Make the first PT_LOAD segment include the program
1798 headers itself (and the ELF header as well), it'll
1799 come out with same memory use but will make various
1800 tools like binutils strip work better. */
1801 ph->p_offset &= ~(ph->p_align - 1);
1802 ph->p_vaddr &= ~(ph->p_align - 1);
1803 ph->p_paddr &= ~(ph->p_align - 1);
1805 ph->p_filesz = file_offset - ph->p_offset;
1806 ph->p_memsz = addr - ph->p_vaddr;
1807 ph++;
1808 if (j == 0) {
1809 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1810 /* if in the middle of a page, we duplicate the page in
1811 memory so that one copy is RX and the other is RW */
1812 if ((addr & (s_align - 1)) != 0)
1813 addr += s_align;
1814 } else {
1815 addr = (addr + s_align - 1) & ~(s_align - 1);
1816 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1822 /* all other sections come after */
1823 for(i = 1; i < s1->nb_sections; i++) {
1824 s = s1->sections[i];
1825 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1826 continue;
1827 sec_order[sh_order_index++] = i;
1829 file_offset = (file_offset + s->sh_addralign - 1) &
1830 ~(s->sh_addralign - 1);
1831 s->sh_offset = file_offset;
1832 if (s->sh_type != SHT_NOBITS)
1833 file_offset += s->sh_size;
1836 return file_offset;
1839 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1840 Section *dynamic)
1842 ElfW(Phdr) *ph;
1844 /* if interpreter, then add corresponding program header */
1845 if (interp) {
1846 ph = &phdr[0];
1848 if (HAVE_PHDR)
1850 int len = phnum * sizeof(ElfW(Phdr));
1852 ph->p_type = PT_PHDR;
1853 ph->p_offset = sizeof(ElfW(Ehdr));
1854 ph->p_vaddr = interp->sh_addr - len;
1855 ph->p_paddr = ph->p_vaddr;
1856 ph->p_filesz = ph->p_memsz = len;
1857 ph->p_flags = PF_R | PF_X;
1858 ph->p_align = 4; /* interp->sh_addralign; */
1859 ph++;
1862 ph->p_type = PT_INTERP;
1863 ph->p_offset = interp->sh_offset;
1864 ph->p_vaddr = interp->sh_addr;
1865 ph->p_paddr = ph->p_vaddr;
1866 ph->p_filesz = interp->sh_size;
1867 ph->p_memsz = interp->sh_size;
1868 ph->p_flags = PF_R;
1869 ph->p_align = interp->sh_addralign;
1872 /* if dynamic section, then add corresponding program header */
1873 if (dynamic) {
1874 ph = &phdr[phnum - 1];
1876 ph->p_type = PT_DYNAMIC;
1877 ph->p_offset = dynamic->sh_offset;
1878 ph->p_vaddr = dynamic->sh_addr;
1879 ph->p_paddr = ph->p_vaddr;
1880 ph->p_filesz = dynamic->sh_size;
1881 ph->p_memsz = dynamic->sh_size;
1882 ph->p_flags = PF_R | PF_W;
1883 ph->p_align = dynamic->sh_addralign;
1887 /* Fill the dynamic section with tags describing the address and size of
1888 sections */
1889 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
1891 Section *dynamic;
1893 dynamic = dyninf->dynamic;
1895 /* put dynamic section entries */
1896 dynamic->data_offset = dyninf->dyn_rel_off;
1897 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1898 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
1899 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1900 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
1901 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1902 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
1903 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
1904 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
1905 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
1906 #else
1907 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1908 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
1909 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
1910 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
1911 put_dt(dynamic, DT_PLTREL, DT_REL);
1912 put_dt(dynamic, DT_REL, dyninf->bss_addr);
1913 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
1914 #else
1915 put_dt(dynamic, DT_REL, dyninf->rel_addr);
1916 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
1917 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1918 #endif
1919 #endif
1920 if (s1->do_debug)
1921 put_dt(dynamic, DT_DEBUG, 0);
1922 put_dt(dynamic, DT_NULL, 0);
1925 /* Relocate remaining sections and symbols (that is those not related to
1926 dynamic linking) */
1927 static int final_sections_reloc(TCCState *s1)
1929 int i;
1930 Section *s;
1932 relocate_syms(s1, 0);
1934 if (s1->nb_errors != 0)
1935 return -1;
1937 /* relocate sections */
1938 /* XXX: ignore sections with allocated relocations ? */
1939 for(i = 1; i < s1->nb_sections; i++) {
1940 s = s1->sections[i];
1941 #ifdef TCC_TARGET_I386
1942 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
1943 /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
1944 checking is removed */
1945 #else
1946 if (s->reloc && s != s1->got)
1947 /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
1948 #endif
1949 relocate_section(s1, s);
1952 /* relocate relocation entries if the relocation tables are
1953 allocated in the executable */
1954 for(i = 1; i < s1->nb_sections; i++) {
1955 s = s1->sections[i];
1956 if ((s->sh_flags & SHF_ALLOC) &&
1957 s->sh_type == SHT_RELX) {
1958 relocate_rel(s1, s);
1961 return 0;
1964 /* Create an ELF file on disk.
1965 This function handle ELF specific layout requirements */
1966 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
1967 int file_offset, int *sec_order)
1969 int i, shnum, offset, size, file_type;
1970 Section *s;
1971 ElfW(Ehdr) ehdr;
1972 ElfW(Shdr) shdr, *sh;
1974 file_type = s1->output_type;
1975 shnum = s1->nb_sections;
1977 memset(&ehdr, 0, sizeof(ehdr));
1979 if (phnum > 0) {
1980 ehdr.e_phentsize = sizeof(ElfW(Phdr));
1981 ehdr.e_phnum = phnum;
1982 ehdr.e_phoff = sizeof(ElfW(Ehdr));
1985 /* align to 4 */
1986 file_offset = (file_offset + 3) & -4;
1988 /* fill header */
1989 ehdr.e_ident[0] = ELFMAG0;
1990 ehdr.e_ident[1] = ELFMAG1;
1991 ehdr.e_ident[2] = ELFMAG2;
1992 ehdr.e_ident[3] = ELFMAG3;
1993 ehdr.e_ident[4] = ELFCLASSW;
1994 ehdr.e_ident[5] = ELFDATA2LSB;
1995 ehdr.e_ident[6] = EV_CURRENT;
1996 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1997 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1998 #endif
1999 #ifdef TCC_TARGET_ARM
2000 #ifdef TCC_ARM_EABI
2001 ehdr.e_ident[EI_OSABI] = 0;
2002 ehdr.e_flags = EF_ARM_EABI_VER4;
2003 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2004 ehdr.e_flags |= EF_ARM_HASENTRY;
2005 if (s1->float_abi == ARM_HARD_FLOAT)
2006 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2007 else
2008 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2009 #else
2010 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2011 #endif
2012 #endif
2013 switch(file_type) {
2014 default:
2015 case TCC_OUTPUT_EXE:
2016 ehdr.e_type = ET_EXEC;
2017 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
2018 break;
2019 case TCC_OUTPUT_DLL:
2020 ehdr.e_type = ET_DYN;
2021 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2022 break;
2023 case TCC_OUTPUT_OBJ:
2024 ehdr.e_type = ET_REL;
2025 break;
2027 ehdr.e_machine = EM_TCC_TARGET;
2028 ehdr.e_version = EV_CURRENT;
2029 ehdr.e_shoff = file_offset;
2030 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2031 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2032 ehdr.e_shnum = shnum;
2033 ehdr.e_shstrndx = shnum - 1;
2035 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2036 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2037 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2039 sort_syms(s1, symtab_section);
2040 for(i = 1; i < s1->nb_sections; i++) {
2041 s = s1->sections[sec_order[i]];
2042 if (s->sh_type != SHT_NOBITS) {
2043 if (s->sh_type == SHT_DYNSYM)
2044 patch_dynsym_undef(s1, s);
2045 while (offset < s->sh_offset) {
2046 fputc(0, f);
2047 offset++;
2049 size = s->sh_size;
2050 if (size)
2051 fwrite(s->data, 1, size, f);
2052 offset += size;
2056 /* output section headers */
2057 while (offset < ehdr.e_shoff) {
2058 fputc(0, f);
2059 offset++;
2062 for(i = 0; i < s1->nb_sections; i++) {
2063 sh = &shdr;
2064 memset(sh, 0, sizeof(ElfW(Shdr)));
2065 s = s1->sections[i];
2066 if (s) {
2067 sh->sh_name = s->sh_name;
2068 sh->sh_type = s->sh_type;
2069 sh->sh_flags = s->sh_flags;
2070 sh->sh_entsize = s->sh_entsize;
2071 sh->sh_info = s->sh_info;
2072 if (s->link)
2073 sh->sh_link = s->link->sh_num;
2074 sh->sh_addralign = s->sh_addralign;
2075 sh->sh_addr = s->sh_addr;
2076 sh->sh_offset = s->sh_offset;
2077 sh->sh_size = s->sh_size;
2079 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2083 /* Write an elf, coff or "binary" file */
2084 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2085 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2087 int fd, mode, file_type;
2088 FILE *f;
2090 file_type = s1->output_type;
2091 if (file_type == TCC_OUTPUT_OBJ)
2092 mode = 0666;
2093 else
2094 mode = 0777;
2095 unlink(filename);
2096 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2097 if (fd < 0) {
2098 tcc_error_noabort("could not write '%s'", filename);
2099 return -1;
2101 f = fdopen(fd, "wb");
2102 if (s1->verbose)
2103 printf("<- %s\n", filename);
2105 #ifdef TCC_TARGET_COFF
2106 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2107 tcc_output_coff(s1, f);
2108 else
2109 #endif
2110 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2111 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2112 else
2113 tcc_output_binary(s1, f, sec_order);
2114 fclose(f);
2116 return 0;
2119 /* Output an elf, coff or binary file */
2120 /* XXX: suppress unneeded sections */
2121 static int elf_output_file(TCCState *s1, const char *filename)
2123 int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
2124 struct dyn_inf dyninf;
2125 ElfW(Phdr) *phdr;
2126 ElfW(Sym) *sym;
2127 Section *strsec, *interp, *dynamic, *dynstr;
2129 file_type = s1->output_type;
2130 s1->nb_errors = 0;
2132 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2133 if (file_type != TCC_OUTPUT_OBJ) {
2134 tcc_add_runtime(s1);
2137 phdr = NULL;
2138 sec_order = NULL;
2139 interp = dynamic = dynstr = NULL; /* avoid warning */
2140 dyninf.dyn_rel_off = 0; /* avoid warning */
2142 if (file_type != TCC_OUTPUT_OBJ) {
2143 relocate_common_syms();
2145 tcc_add_linker_symbols(s1);
2147 if (!s1->static_link) {
2148 if (file_type == TCC_OUTPUT_EXE) {
2149 char *ptr;
2150 /* allow override the dynamic loader */
2151 const char *elfint = getenv("LD_SO");
2152 if (elfint == NULL)
2153 elfint = DEFAULT_ELFINTERP(s1);
2154 /* add interpreter section only if executable */
2155 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2156 interp->sh_addralign = 1;
2157 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2158 strcpy(ptr, elfint);
2161 /* add dynamic symbol table */
2162 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2163 ".dynstr",
2164 ".hash", SHF_ALLOC);
2165 dynstr = s1->dynsym->link;
2167 /* add dynamic section */
2168 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2169 SHF_ALLOC | SHF_WRITE);
2170 dynamic->link = dynstr;
2171 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2173 build_got(s1);
2175 if (file_type == TCC_OUTPUT_EXE) {
2176 bind_exe_dynsyms(s1);
2178 if (s1->nb_errors) {
2179 ret = -1;
2180 goto the_end;
2183 bind_libs_dynsyms(s1);
2184 } else /* shared library case: simply export all global symbols */
2185 export_global_syms(s1);
2187 build_got_entries(s1);
2189 /* add a list of needed dlls */
2190 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2191 DLLReference *dllref = s1->loaded_dlls[i];
2192 if (dllref->level == 0)
2193 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2196 if (s1->rpath)
2197 put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath));
2199 /* XXX: currently, since we do not handle PIC code, we
2200 must relocate the readonly segments */
2201 if (file_type == TCC_OUTPUT_DLL) {
2202 if (s1->soname)
2203 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2204 put_dt(dynamic, DT_TEXTREL, 0);
2207 if (s1->symbolic)
2208 put_dt(dynamic, DT_SYMBOLIC, 0);
2210 /* add necessary space for other entries */
2211 dyninf.dyn_rel_off = dynamic->data_offset;
2212 dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
2213 } else {
2214 /* still need to build got entries in case of static link */
2215 build_got_entries(s1);
2219 /* we add a section for symbols */
2220 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2221 put_elf_str(strsec, "");
2223 /* compute number of sections */
2224 shnum = s1->nb_sections;
2226 /* this array is used to reorder sections in the output file */
2227 sec_order = tcc_malloc(sizeof(int) * shnum);
2228 sec_order[0] = 0;
2230 /* compute number of program headers */
2231 switch(file_type) {
2232 default:
2233 case TCC_OUTPUT_OBJ:
2234 phnum = 0;
2235 break;
2236 case TCC_OUTPUT_EXE:
2237 if (!s1->static_link)
2238 phnum = 4 + HAVE_PHDR;
2239 else
2240 phnum = 2;
2241 break;
2242 case TCC_OUTPUT_DLL:
2243 phnum = 3;
2244 break;
2247 /* Allocate strings for section names */
2248 alloc_sec_names(s1, file_type, strsec);
2250 /* allocate program segment headers */
2251 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2253 /* compute section to program header mapping */
2254 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2255 sec_order);
2257 /* Fill remaining program header and finalize relocation related to dynamic
2258 linking. */
2259 if (phnum > 0) {
2260 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2261 if (dynamic) {
2262 dyninf.dynamic = dynamic;
2263 dyninf.dynstr = dynstr;
2265 fill_dynamic(s1, &dyninf);
2267 /* put in GOT the dynamic section address and relocate PLT */
2268 write32le(s1->got->data, dynamic->sh_addr);
2269 if (file_type == TCC_OUTPUT_EXE
2270 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
2271 || file_type == TCC_OUTPUT_DLL
2272 #endif
2274 relocate_plt(s1);
2276 /* relocate symbols in .dynsym now that final addresses are known */
2277 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2278 if (sym->st_shndx == SHN_UNDEF) {
2279 /* relocate to PLT if symbol corresponds to a PLT entry,
2280 but not if it's a weak symbol */
2281 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
2282 sym->st_value = 0;
2283 else if (sym->st_value)
2284 sym->st_value += s1->plt->sh_addr;
2285 } else if (sym->st_shndx < SHN_LORESERVE) {
2286 /* do symbol relocation */
2287 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2293 /* if building executable or DLL, then relocate each section
2294 except the GOT which is already relocated */
2295 if (file_type != TCC_OUTPUT_OBJ) {
2296 ret = final_sections_reloc(s1);
2297 if (ret)
2298 goto the_end;
2301 /* Perform relocation to GOT or PLT entries */
2302 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2303 fill_got(s1);
2305 /* Create the ELF file with name 'filename' */
2306 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2307 the_end:
2308 tcc_free(s1->symtab_to_dynsym);
2309 tcc_free(sec_order);
2310 tcc_free(phdr);
2311 tcc_free(s1->sym_attrs);
2312 s1->sym_attrs = NULL;
2313 return ret;
2316 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2318 int ret;
2319 #ifdef TCC_TARGET_PE
2320 if (s->output_type != TCC_OUTPUT_OBJ) {
2321 ret = pe_output_file(s, filename);
2322 } else
2323 #endif
2324 ret = elf_output_file(s, filename);
2325 return ret;
2328 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2330 void *data;
2332 data = tcc_malloc(size);
2333 lseek(fd, file_offset, SEEK_SET);
2334 read(fd, data, size);
2335 return data;
2338 typedef struct SectionMergeInfo {
2339 Section *s; /* corresponding existing section */
2340 unsigned long offset; /* offset of the new section in the existing section */
2341 uint8_t new_section; /* true if section 's' was added */
2342 uint8_t link_once; /* true if link once section */
2343 } SectionMergeInfo;
2345 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2347 int size = read(fd, h, sizeof *h);
2348 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2349 if (h->e_type == ET_REL)
2350 return AFF_BINTYPE_REL;
2351 if (h->e_type == ET_DYN)
2352 return AFF_BINTYPE_DYN;
2353 } else if (size >= 8) {
2354 if (0 == memcmp(h, ARMAG, 8))
2355 return AFF_BINTYPE_AR;
2356 #ifdef TCC_TARGET_COFF
2357 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2358 return AFF_BINTYPE_C67;
2359 #endif
2361 return 0;
2364 /* load an object file and merge it with current files */
2365 /* XXX: handle correctly stab (debug) info */
2366 ST_FUNC int tcc_load_object_file(TCCState *s1,
2367 int fd, unsigned long file_offset)
2369 ElfW(Ehdr) ehdr;
2370 ElfW(Shdr) *shdr, *sh;
2371 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2372 unsigned char *strsec, *strtab;
2373 int *old_to_new_syms;
2374 char *sh_name, *name;
2375 SectionMergeInfo *sm_table, *sm;
2376 ElfW(Sym) *sym, *symtab;
2377 ElfW_Rel *rel;
2378 Section *s;
2380 int stab_index;
2381 int stabstr_index;
2383 stab_index = stabstr_index = 0;
2385 lseek(fd, file_offset, SEEK_SET);
2386 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2387 goto fail1;
2388 /* test CPU specific stuff */
2389 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2390 ehdr.e_machine != EM_TCC_TARGET) {
2391 fail1:
2392 tcc_error_noabort("invalid object file");
2393 return -1;
2395 /* read sections */
2396 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2397 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2398 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2400 /* load section names */
2401 sh = &shdr[ehdr.e_shstrndx];
2402 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2404 /* load symtab and strtab */
2405 old_to_new_syms = NULL;
2406 symtab = NULL;
2407 strtab = NULL;
2408 nb_syms = 0;
2409 for(i = 1; i < ehdr.e_shnum; i++) {
2410 sh = &shdr[i];
2411 if (sh->sh_type == SHT_SYMTAB) {
2412 if (symtab) {
2413 tcc_error_noabort("object must contain only one symtab");
2414 fail:
2415 ret = -1;
2416 goto the_end;
2418 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2419 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2420 sm_table[i].s = symtab_section;
2422 /* now load strtab */
2423 sh = &shdr[sh->sh_link];
2424 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2428 /* now examine each section and try to merge its content with the
2429 ones in memory */
2430 for(i = 1; i < ehdr.e_shnum; i++) {
2431 /* no need to examine section name strtab */
2432 if (i == ehdr.e_shstrndx)
2433 continue;
2434 sh = &shdr[i];
2435 sh_name = (char *) strsec + sh->sh_name;
2436 /* ignore sections types we do not handle */
2437 if (sh->sh_type != SHT_PROGBITS &&
2438 sh->sh_type != SHT_RELX &&
2439 #ifdef TCC_ARM_EABI
2440 sh->sh_type != SHT_ARM_EXIDX &&
2441 #endif
2442 sh->sh_type != SHT_NOBITS &&
2443 sh->sh_type != SHT_PREINIT_ARRAY &&
2444 sh->sh_type != SHT_INIT_ARRAY &&
2445 sh->sh_type != SHT_FINI_ARRAY &&
2446 strcmp(sh_name, ".stabstr")
2448 continue;
2449 if (sh->sh_addralign < 1)
2450 sh->sh_addralign = 1;
2451 /* find corresponding section, if any */
2452 for(j = 1; j < s1->nb_sections;j++) {
2453 s = s1->sections[j];
2454 if (!strcmp(s->name, sh_name)) {
2455 if (!strncmp(sh_name, ".gnu.linkonce",
2456 sizeof(".gnu.linkonce") - 1)) {
2457 /* if a 'linkonce' section is already present, we
2458 do not add it again. It is a little tricky as
2459 symbols can still be defined in
2460 it. */
2461 sm_table[i].link_once = 1;
2462 goto next;
2463 } else {
2464 goto found;
2468 /* not found: create new section */
2469 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2470 /* take as much info as possible from the section. sh_link and
2471 sh_info will be updated later */
2472 s->sh_addralign = sh->sh_addralign;
2473 s->sh_entsize = sh->sh_entsize;
2474 sm_table[i].new_section = 1;
2475 found:
2476 if (sh->sh_type != s->sh_type) {
2477 tcc_error_noabort("invalid section type");
2478 goto fail;
2481 /* align start of section */
2482 offset = s->data_offset;
2484 if (0 == strcmp(sh_name, ".stab")) {
2485 stab_index = i;
2486 goto no_align;
2488 if (0 == strcmp(sh_name, ".stabstr")) {
2489 stabstr_index = i;
2490 goto no_align;
2493 size = sh->sh_addralign - 1;
2494 offset = (offset + size) & ~size;
2495 if (sh->sh_addralign > s->sh_addralign)
2496 s->sh_addralign = sh->sh_addralign;
2497 s->data_offset = offset;
2498 no_align:
2499 sm_table[i].offset = offset;
2500 sm_table[i].s = s;
2501 /* concatenate sections */
2502 size = sh->sh_size;
2503 if (sh->sh_type != SHT_NOBITS) {
2504 unsigned char *ptr;
2505 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2506 ptr = section_ptr_add(s, size);
2507 read(fd, ptr, size);
2508 } else {
2509 s->data_offset += size;
2511 next: ;
2514 /* gr relocate stab strings */
2515 if (stab_index && stabstr_index) {
2516 Stab_Sym *a, *b;
2517 unsigned o;
2518 s = sm_table[stab_index].s;
2519 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2520 b = (Stab_Sym *)(s->data + s->data_offset);
2521 o = sm_table[stabstr_index].offset;
2522 while (a < b)
2523 a->n_strx += o, a++;
2526 /* second short pass to update sh_link and sh_info fields of new
2527 sections */
2528 for(i = 1; i < ehdr.e_shnum; i++) {
2529 s = sm_table[i].s;
2530 if (!s || !sm_table[i].new_section)
2531 continue;
2532 sh = &shdr[i];
2533 if (sh->sh_link > 0)
2534 s->link = sm_table[sh->sh_link].s;
2535 if (sh->sh_type == SHT_RELX) {
2536 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2537 /* update backward link */
2538 s1->sections[s->sh_info]->reloc = s;
2541 sm = sm_table;
2543 /* resolve symbols */
2544 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2546 sym = symtab + 1;
2547 for(i = 1; i < nb_syms; i++, sym++) {
2548 if (sym->st_shndx != SHN_UNDEF &&
2549 sym->st_shndx < SHN_LORESERVE) {
2550 sm = &sm_table[sym->st_shndx];
2551 if (sm->link_once) {
2552 /* if a symbol is in a link once section, we use the
2553 already defined symbol. It is very important to get
2554 correct relocations */
2555 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2556 name = (char *) strtab + sym->st_name;
2557 sym_index = find_elf_sym(symtab_section, name);
2558 if (sym_index)
2559 old_to_new_syms[i] = sym_index;
2561 continue;
2563 /* if no corresponding section added, no need to add symbol */
2564 if (!sm->s)
2565 continue;
2566 /* convert section number */
2567 sym->st_shndx = sm->s->sh_num;
2568 /* offset value */
2569 sym->st_value += sm->offset;
2571 /* add symbol */
2572 name = (char *) strtab + sym->st_name;
2573 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2574 sym->st_info, sym->st_other,
2575 sym->st_shndx, name);
2576 old_to_new_syms[i] = sym_index;
2579 /* third pass to patch relocation entries */
2580 for(i = 1; i < ehdr.e_shnum; i++) {
2581 s = sm_table[i].s;
2582 if (!s)
2583 continue;
2584 sh = &shdr[i];
2585 offset = sm_table[i].offset;
2586 switch(s->sh_type) {
2587 case SHT_RELX:
2588 /* take relocation offset information */
2589 offseti = sm_table[sh->sh_info].offset;
2590 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2591 int type;
2592 unsigned sym_index;
2593 /* convert symbol index */
2594 type = ELFW(R_TYPE)(rel->r_info);
2595 sym_index = ELFW(R_SYM)(rel->r_info);
2596 /* NOTE: only one symtab assumed */
2597 if (sym_index >= nb_syms)
2598 goto invalid_reloc;
2599 sym_index = old_to_new_syms[sym_index];
2600 /* ignore link_once in rel section. */
2601 if (!sym_index && !sm->link_once
2602 #ifdef TCC_TARGET_ARM
2603 && type != R_ARM_V4BX
2604 #endif
2606 invalid_reloc:
2607 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2608 i, strsec + sh->sh_name, rel->r_offset);
2609 goto fail;
2611 rel->r_info = ELFW(R_INFO)(sym_index, type);
2612 /* offset the relocation offset */
2613 rel->r_offset += offseti;
2614 #ifdef TCC_TARGET_ARM
2615 /* Jumps and branches from a Thumb code to a PLT entry need
2616 special handling since PLT entries are ARM code.
2617 Unconditional bl instructions referencing PLT entries are
2618 handled by converting these instructions into blx
2619 instructions. Other case of instructions referencing a PLT
2620 entry require to add a Thumb stub before the PLT entry to
2621 switch to ARM mode. We set bit plt_thumb_stub of the
2622 attribute of a symbol to indicate such a case. */
2623 if (type == R_ARM_THM_JUMP24)
2624 get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
2625 #endif
2627 break;
2628 default:
2629 break;
2633 ret = 0;
2634 the_end:
2635 tcc_free(symtab);
2636 tcc_free(strtab);
2637 tcc_free(old_to_new_syms);
2638 tcc_free(sm_table);
2639 tcc_free(strsec);
2640 tcc_free(shdr);
2641 return ret;
2644 typedef struct ArchiveHeader {
2645 char ar_name[16]; /* name of this member */
2646 char ar_date[12]; /* file mtime */
2647 char ar_uid[6]; /* owner uid; printed as decimal */
2648 char ar_gid[6]; /* owner gid; printed as decimal */
2649 char ar_mode[8]; /* file mode, printed as octal */
2650 char ar_size[10]; /* file size, printed as decimal */
2651 char ar_fmag[2]; /* should contain ARFMAG */
2652 } ArchiveHeader;
2654 static int get_be32(const uint8_t *b)
2656 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2659 static long get_be64(const uint8_t *b)
2661 long long ret = get_be32(b);
2662 ret = (ret << 32) | (unsigned)get_be32(b+4);
2663 return (long)ret;
2666 /* load only the objects which resolve undefined symbols */
2667 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2669 long i, bound, nsyms, sym_index, off, ret;
2670 uint8_t *data;
2671 const char *ar_names, *p;
2672 const uint8_t *ar_index;
2673 ElfW(Sym) *sym;
2675 data = tcc_malloc(size);
2676 if (read(fd, data, size) != size)
2677 goto fail;
2678 nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
2679 ar_index = data + entrysize;
2680 ar_names = (char *) ar_index + nsyms * entrysize;
2682 do {
2683 bound = 0;
2684 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2685 sym_index = find_elf_sym(symtab_section, p);
2686 if(sym_index) {
2687 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2688 if(sym->st_shndx == SHN_UNDEF) {
2689 off = (entrysize == 4
2690 ? get_be32(ar_index + i * 4)
2691 : get_be64(ar_index + i * 8))
2692 + sizeof(ArchiveHeader);
2693 ++bound;
2694 if(tcc_load_object_file(s1, fd, off) < 0) {
2695 fail:
2696 ret = -1;
2697 goto the_end;
2702 } while(bound);
2703 ret = 0;
2704 the_end:
2705 tcc_free(data);
2706 return ret;
2709 /* load a '.a' file */
2710 ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
2712 ArchiveHeader hdr;
2713 char ar_size[11];
2714 char ar_name[17];
2715 char magic[8];
2716 int size, len, i;
2717 unsigned long file_offset;
2719 /* skip magic which was already checked */
2720 read(fd, magic, sizeof(magic));
2722 for(;;) {
2723 len = read(fd, &hdr, sizeof(hdr));
2724 if (len == 0)
2725 break;
2726 if (len != sizeof(hdr)) {
2727 tcc_error_noabort("invalid archive");
2728 return -1;
2730 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2731 ar_size[sizeof(hdr.ar_size)] = '\0';
2732 size = strtol(ar_size, NULL, 0);
2733 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2734 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2735 if (ar_name[i] != ' ')
2736 break;
2738 ar_name[i + 1] = '\0';
2739 file_offset = lseek(fd, 0, SEEK_CUR);
2740 /* align to even */
2741 size = (size + 1) & ~1;
2742 if (!strcmp(ar_name, "/")) {
2743 /* coff symbol table : we handle it */
2744 if(s1->alacarte_link)
2745 return tcc_load_alacarte(s1, fd, size, 4);
2746 } else if (!strcmp(ar_name, "/SYM64/")) {
2747 if(s1->alacarte_link)
2748 return tcc_load_alacarte(s1, fd, size, 8);
2749 } else {
2750 ElfW(Ehdr) ehdr;
2751 if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2752 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2753 return -1;
2756 lseek(fd, file_offset + size, SEEK_SET);
2758 return 0;
2761 #ifndef TCC_TARGET_PE
2762 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2763 is referenced by the user (so it should be added as DT_NEEDED in
2764 the generated ELF file) */
2765 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2767 ElfW(Ehdr) ehdr;
2768 ElfW(Shdr) *shdr, *sh, *sh1;
2769 int i, j, nb_syms, nb_dts, sym_bind, ret;
2770 ElfW(Sym) *sym, *dynsym;
2771 ElfW(Dyn) *dt, *dynamic;
2772 unsigned char *dynstr;
2773 const char *name, *soname;
2774 DLLReference *dllref;
2776 read(fd, &ehdr, sizeof(ehdr));
2778 /* test CPU specific stuff */
2779 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2780 ehdr.e_machine != EM_TCC_TARGET) {
2781 tcc_error_noabort("bad architecture");
2782 return -1;
2785 /* read sections */
2786 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2788 /* load dynamic section and dynamic symbols */
2789 nb_syms = 0;
2790 nb_dts = 0;
2791 dynamic = NULL;
2792 dynsym = NULL; /* avoid warning */
2793 dynstr = NULL; /* avoid warning */
2794 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2795 switch(sh->sh_type) {
2796 case SHT_DYNAMIC:
2797 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2798 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2799 break;
2800 case SHT_DYNSYM:
2801 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2802 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2803 sh1 = &shdr[sh->sh_link];
2804 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2805 break;
2806 default:
2807 break;
2811 /* compute the real library name */
2812 soname = tcc_basename(filename);
2814 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2815 if (dt->d_tag == DT_SONAME) {
2816 soname = (char *) dynstr + dt->d_un.d_val;
2820 /* if the dll is already loaded, do not load it */
2821 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2822 dllref = s1->loaded_dlls[i];
2823 if (!strcmp(soname, dllref->name)) {
2824 /* but update level if needed */
2825 if (level < dllref->level)
2826 dllref->level = level;
2827 ret = 0;
2828 goto the_end;
2832 /* add the dll and its level */
2833 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2834 dllref->level = level;
2835 strcpy(dllref->name, soname);
2836 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2838 /* add dynamic symbols in dynsym_section */
2839 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2840 sym_bind = ELFW(ST_BIND)(sym->st_info);
2841 if (sym_bind == STB_LOCAL)
2842 continue;
2843 name = (char *) dynstr + sym->st_name;
2844 set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2845 sym->st_info, sym->st_other, sym->st_shndx, name);
2848 /* load all referenced DLLs */
2849 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2850 switch(dt->d_tag) {
2851 case DT_NEEDED:
2852 name = (char *) dynstr + dt->d_un.d_val;
2853 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2854 dllref = s1->loaded_dlls[j];
2855 if (!strcmp(name, dllref->name))
2856 goto already_loaded;
2858 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2859 tcc_error_noabort("referenced dll '%s' not found", name);
2860 ret = -1;
2861 goto the_end;
2863 already_loaded:
2864 break;
2867 ret = 0;
2868 the_end:
2869 tcc_free(dynstr);
2870 tcc_free(dynsym);
2871 tcc_free(dynamic);
2872 tcc_free(shdr);
2873 return ret;
2876 #define LD_TOK_NAME 256
2877 #define LD_TOK_EOF (-1)
2879 /* return next ld script token */
2880 static int ld_next(TCCState *s1, char *name, int name_size)
2882 int c;
2883 char *q;
2885 redo:
2886 switch(ch) {
2887 case ' ':
2888 case '\t':
2889 case '\f':
2890 case '\v':
2891 case '\r':
2892 case '\n':
2893 inp();
2894 goto redo;
2895 case '/':
2896 minp();
2897 if (ch == '*') {
2898 file->buf_ptr = parse_comment(file->buf_ptr);
2899 ch = file->buf_ptr[0];
2900 goto redo;
2901 } else {
2902 q = name;
2903 *q++ = '/';
2904 goto parse_name;
2906 break;
2907 case '\\':
2908 ch = handle_eob();
2909 if (ch != '\\')
2910 goto redo;
2911 /* fall through */
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 'A' ... 'z': */
2940 case 'A':
2941 case 'B':
2942 case 'C':
2943 case 'D':
2944 case 'E':
2945 case 'F':
2946 case 'G':
2947 case 'H':
2948 case 'I':
2949 case 'J':
2950 case 'K':
2951 case 'L':
2952 case 'M':
2953 case 'N':
2954 case 'O':
2955 case 'P':
2956 case 'Q':
2957 case 'R':
2958 case 'S':
2959 case 'T':
2960 case 'U':
2961 case 'V':
2962 case 'W':
2963 case 'X':
2964 case 'Y':
2965 case 'Z':
2966 case '_':
2967 case '.':
2968 case '$':
2969 case '~':
2970 q = name;
2971 parse_name:
2972 for(;;) {
2973 if (!((ch >= 'a' && ch <= 'z') ||
2974 (ch >= 'A' && ch <= 'Z') ||
2975 (ch >= '0' && ch <= '9') ||
2976 strchr("/.-_+=$:\\,~", ch)))
2977 break;
2978 if ((q - name) < name_size - 1) {
2979 *q++ = ch;
2981 minp();
2983 *q = '\0';
2984 c = LD_TOK_NAME;
2985 break;
2986 case CH_EOF:
2987 c = LD_TOK_EOF;
2988 break;
2989 default:
2990 c = ch;
2991 inp();
2992 break;
2994 return c;
2997 static int ld_add_file(TCCState *s1, const char filename[])
2999 int ret;
3001 ret = tcc_add_file_internal(s1, filename, AFF_TYPE_BIN);
3002 if (ret)
3003 ret = tcc_add_dll(s1, filename, 0);
3004 return ret;
3007 static inline int new_undef_syms(void)
3009 int ret = 0;
3010 ret = new_undef_sym;
3011 new_undef_sym = 0;
3012 return ret;
3015 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3017 char filename[1024], libname[1024];
3018 int t, group, nblibs = 0, ret = 0;
3019 char **libs = NULL;
3021 group = !strcmp(cmd, "GROUP");
3022 if (!as_needed)
3023 new_undef_syms();
3024 t = ld_next(s1, filename, sizeof(filename));
3025 if (t != '(')
3026 expect("(");
3027 t = ld_next(s1, filename, sizeof(filename));
3028 for(;;) {
3029 libname[0] = '\0';
3030 if (t == LD_TOK_EOF) {
3031 tcc_error_noabort("unexpected end of file");
3032 ret = -1;
3033 goto lib_parse_error;
3034 } else if (t == ')') {
3035 break;
3036 } else if (t == '-') {
3037 t = ld_next(s1, filename, sizeof(filename));
3038 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3039 tcc_error_noabort("library name expected");
3040 ret = -1;
3041 goto lib_parse_error;
3043 pstrcpy(libname, sizeof libname, &filename[1]);
3044 if (s1->static_link) {
3045 snprintf(filename, sizeof filename, "lib%s.a", libname);
3046 } else {
3047 snprintf(filename, sizeof filename, "lib%s.so", libname);
3049 } else if (t != LD_TOK_NAME) {
3050 tcc_error_noabort("filename expected");
3051 ret = -1;
3052 goto lib_parse_error;
3054 if (!strcmp(filename, "AS_NEEDED")) {
3055 ret = ld_add_file_list(s1, cmd, 1);
3056 if (ret)
3057 goto lib_parse_error;
3058 } else {
3059 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3060 if (!as_needed) {
3061 ret = ld_add_file(s1, filename);
3062 if (ret)
3063 goto lib_parse_error;
3064 if (group) {
3065 /* Add the filename *and* the libname to avoid future conversions */
3066 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename));
3067 if (libname[0] != '\0')
3068 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname));
3072 t = ld_next(s1, filename, sizeof(filename));
3073 if (t == ',') {
3074 t = ld_next(s1, filename, sizeof(filename));
3077 if (group && !as_needed) {
3078 while (new_undef_syms()) {
3079 int i;
3081 for (i = 0; i < nblibs; i ++)
3082 ld_add_file(s1, libs[i]);
3085 lib_parse_error:
3086 dynarray_reset(&libs, &nblibs);
3087 return ret;
3090 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3091 files */
3092 ST_FUNC int tcc_load_ldscript(TCCState *s1)
3094 char cmd[64];
3095 char filename[1024];
3096 int t, ret;
3098 ch = handle_eob();
3099 for(;;) {
3100 t = ld_next(s1, cmd, sizeof(cmd));
3101 if (t == LD_TOK_EOF)
3102 return 0;
3103 else if (t != LD_TOK_NAME)
3104 return -1;
3105 if (!strcmp(cmd, "INPUT") ||
3106 !strcmp(cmd, "GROUP")) {
3107 ret = ld_add_file_list(s1, cmd, 0);
3108 if (ret)
3109 return ret;
3110 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3111 !strcmp(cmd, "TARGET")) {
3112 /* ignore some commands */
3113 t = ld_next(s1, cmd, sizeof(cmd));
3114 if (t != '(')
3115 expect("(");
3116 for(;;) {
3117 t = ld_next(s1, filename, sizeof(filename));
3118 if (t == LD_TOK_EOF) {
3119 tcc_error_noabort("unexpected end of file");
3120 return -1;
3121 } else if (t == ')') {
3122 break;
3125 } else {
3126 return -1;
3129 return 0;
3131 #endif /* !TCC_TARGET_PE */