Do section relocation in architecture backend
[tinycc.git] / tccelf.c
blob8147c2ce2849eb3540b3b80428b32d841ce7f26e
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 /* Browse each elem of type <type> in section <sec> starting at elem <startoff>
546 using variable <elem> */
547 #define for_each_elem(sec, startoff, elem, type) \
548 for (elem = (type *) sec->data + startoff; \
549 elem < (type *) (sec->data + sec->data_offset); elem++)
551 /* In an ELF file symbol table, the local symbols must appear below
552 the global and weak ones. Since TCC cannot sort it while generating
553 the code, we must do it after. All the relocation tables are also
554 modified to take into account the symbol table sorting */
555 static void sort_syms(TCCState *s1, Section *s)
557 int *old_to_new_syms;
558 ElfW(Sym) *new_syms;
559 int nb_syms, i;
560 ElfW(Sym) *p, *q;
561 ElfW_Rel *rel;
562 Section *sr;
563 int type, sym_index;
565 nb_syms = s->data_offset / sizeof(ElfW(Sym));
566 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
567 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
569 /* first pass for local symbols */
570 p = (ElfW(Sym) *)s->data;
571 q = new_syms;
572 for(i = 0; i < nb_syms; i++) {
573 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
574 old_to_new_syms[i] = q - new_syms;
575 *q++ = *p;
577 p++;
579 /* save the number of local symbols in section header */
580 s->sh_info = q - new_syms;
582 /* then second pass for non local symbols */
583 p = (ElfW(Sym) *)s->data;
584 for(i = 0; i < nb_syms; i++) {
585 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
586 old_to_new_syms[i] = q - new_syms;
587 *q++ = *p;
589 p++;
592 /* we copy the new symbols to the old */
593 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
594 tcc_free(new_syms);
596 /* now we modify all the relocations */
597 for(i = 1; i < s1->nb_sections; i++) {
598 sr = s1->sections[i];
599 if (sr->sh_type == SHT_RELX && sr->link == s) {
600 for_each_elem(sr, 0, rel, ElfW_Rel) {
601 sym_index = ELFW(R_SYM)(rel->r_info);
602 type = ELFW(R_TYPE)(rel->r_info);
603 sym_index = old_to_new_syms[sym_index];
604 rel->r_info = ELFW(R_INFO)(sym_index, type);
609 tcc_free(old_to_new_syms);
612 /* relocate common symbols in the .bss section */
613 ST_FUNC void relocate_common_syms(void)
615 ElfW(Sym) *sym;
616 unsigned long offset, align;
618 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
619 if (sym->st_shndx == SHN_COMMON) {
620 /* align symbol */
621 align = sym->st_value;
622 offset = bss_section->data_offset;
623 offset = (offset + align - 1) & -align;
624 sym->st_value = offset;
625 sym->st_shndx = bss_section->sh_num;
626 offset += sym->st_size;
627 bss_section->data_offset = offset;
632 /* relocate symbol table, resolve undefined symbols if do_resolve is
633 true and output error if undefined symbol. */
634 ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
636 ElfW(Sym) *sym, *esym;
637 int sym_bind, sh_num, sym_index;
638 const char *name;
640 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
641 sh_num = sym->st_shndx;
642 if (sh_num == SHN_UNDEF) {
643 name = (char *) strtab_section->data + sym->st_name;
644 /* Use ld.so to resolve symbol for us (for tcc -run) */
645 if (do_resolve) {
646 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
647 void *addr;
648 name = (char *) symtab_section->link->data + sym->st_name;
649 addr = dlsym(RTLD_DEFAULT, name);
650 if (addr) {
651 sym->st_value = (addr_t)addr;
652 #ifdef DEBUG_RELOC
653 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
654 #endif
655 goto found;
657 #endif
658 } else if (s1->dynsym) {
659 /* if dynamic symbol exist, then use it */
660 sym_index = find_elf_sym(s1->dynsym, name);
661 if (sym_index) {
662 esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
663 sym->st_value = esym->st_value;
664 goto found;
667 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
668 it */
669 if (!strcmp(name, "_fp_hw"))
670 goto found;
671 /* only weak symbols are accepted to be undefined. Their
672 value is zero */
673 sym_bind = ELFW(ST_BIND)(sym->st_info);
674 if (sym_bind == STB_WEAK) {
675 sym->st_value = 0;
676 } else {
677 tcc_error_noabort("undefined symbol '%s'", name);
679 } else if (sh_num < SHN_LORESERVE) {
680 /* add section base */
681 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
683 found: ;
687 /* relocate a given section (CPU dependent) by applying the relocations
688 in the associated relocation section */
689 ST_FUNC void relocate_section(TCCState *s1, Section *s)
691 Section *sr = s->reloc;
692 ElfW_Rel *rel;
693 ElfW(Sym) *sym;
694 int type, sym_index;
695 unsigned char *ptr;
696 addr_t val, addr;
698 relocate_init(sr);
699 for_each_elem(sr, 0, rel, ElfW_Rel) {
700 ptr = s->data + rel->r_offset;
702 sym_index = ELFW(R_SYM)(rel->r_info);
703 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
704 val = sym->st_value;
705 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
706 val += rel->r_addend;
707 #endif
708 type = ELFW(R_TYPE)(rel->r_info);
709 addr = s->sh_addr + rel->r_offset;
711 relocate(s1, rel, type, ptr, addr, val);
713 /* if the relocation is allocated, we change its symbol table */
714 if (sr->sh_flags & SHF_ALLOC)
715 sr->link = s1->dynsym;
718 /* relocate relocation table in 'sr' */
719 static void relocate_rel(TCCState *s1, Section *sr)
721 Section *s;
722 ElfW_Rel *rel;
724 s = s1->sections[sr->sh_info];
725 for_each_elem(sr, 0, rel, ElfW_Rel)
726 rel->r_offset += s->sh_addr;
729 /* count the number of dynamic relocations so that we can reserve
730 their space */
731 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
733 ElfW_Rel *rel;
734 int sym_index, esym_index, type, count;
736 count = 0;
737 for_each_elem(sr, 0, rel, ElfW_Rel) {
738 sym_index = ELFW(R_SYM)(rel->r_info);
739 type = ELFW(R_TYPE)(rel->r_info);
740 switch(type) {
741 #if defined(TCC_TARGET_I386)
742 case R_386_32:
743 #elif defined(TCC_TARGET_X86_64)
744 case R_X86_64_32:
745 case R_X86_64_32S:
746 case R_X86_64_64:
747 #endif
748 count++;
749 break;
750 #if defined(TCC_TARGET_I386)
751 case R_386_PC32:
752 #elif defined(TCC_TARGET_X86_64)
753 case R_X86_64_PC32:
754 #endif
755 esym_index = s1->symtab_to_dynsym[sym_index];
756 if (esym_index)
757 count++;
758 break;
759 default:
760 break;
763 if (count) {
764 /* allocate the section */
765 sr->sh_flags |= SHF_ALLOC;
766 sr->sh_size = count * sizeof(ElfW_Rel);
768 return count;
771 static struct sym_attr *alloc_sym_attr(TCCState *s1, int index)
773 int n;
774 struct sym_attr *tab;
776 if (index >= s1->nb_sym_attrs) {
777 /* find immediately bigger power of 2 and reallocate array */
778 n = 1;
779 while (index >= n)
780 n *= 2;
781 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
782 s1->sym_attrs = tab;
783 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
784 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
785 s1->nb_sym_attrs = n;
787 return &s1->sym_attrs[index];
790 static void build_got(TCCState *s1)
792 unsigned char *ptr;
794 /* if no got, then create it */
795 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
796 s1->got->sh_entsize = 4;
797 set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
798 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
799 ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
800 #if PTR_SIZE == 4
801 /* keep space for _DYNAMIC pointer, if present */
802 write32le(ptr, 0);
803 /* two dummy got entries */
804 write32le(ptr + 4, 0);
805 write32le(ptr + 8, 0);
806 #else
807 /* keep space for _DYNAMIC pointer, if present */
808 write32le(ptr, 0);
809 write32le(ptr + 4, 0);
810 /* two dummy got entries */
811 write32le(ptr + 8, 0);
812 write32le(ptr + 12, 0);
813 write32le(ptr + 16, 0);
814 write32le(ptr + 20, 0);
815 #endif
818 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
819 in s1->symtab. When creating the dynamic symbol table entry for the GOT
820 relocation, use 'size' and 'info' for the corresponding symbol metadata.
821 Returns the offset of the GOT or (if any) PLT entry. */
822 static unsigned long put_got_entry(TCCState *s1,
823 int reloc_type, unsigned long size, int info,
824 int sym_index)
826 int index, need_plt_entry = 0;
827 const char *name;
828 ElfW(Sym) *sym;
829 unsigned long offset;
830 int *ptr;
831 size_t got_offset;
832 struct sym_attr *symattr;
834 need_plt_entry = (reloc_type == R_JMP_SLOT);
836 if (!s1->got)
837 build_got(s1);
839 /* create PLT if needed */
840 if (need_plt_entry && !s1->plt) {
841 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
842 SHF_ALLOC | SHF_EXECINSTR);
843 s1->plt->sh_entsize = 4;
846 /* already a GOT and/or PLT entry, no need to add one */
847 if (sym_index < s1->nb_sym_attrs) {
848 if (need_plt_entry && s1->sym_attrs[sym_index].plt_offset)
849 return s1->sym_attrs[sym_index].plt_offset;
850 else if (!need_plt_entry && s1->sym_attrs[sym_index].got_offset)
851 return s1->sym_attrs[sym_index].got_offset;
854 symattr = alloc_sym_attr(s1, sym_index);
856 /* create the GOT entry */
857 ptr = section_ptr_add(s1->got, PTR_SIZE);
858 *ptr = 0;
859 got_offset = OFFSET_FROM_SECTION_START (s1->got, ptr);
861 /* In case a function is both called and its address taken 2 GOT entries
862 are created, one for taking the address (GOT) and the other for the PLT
863 entry (PLTGOT). We don't record the offset of the PLTGOT entry in the
864 got_offset field since it might overwrite the offset of a GOT entry.
865 Besides, for PLT entry the static relocation is against the PLT entry
866 and the dynamic relocation for PLTGOT is created in this function. */
867 if (!need_plt_entry)
868 symattr->got_offset = got_offset;
870 sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
871 name = (char *) symtab_section->link->data + sym->st_name;
872 offset = sym->st_value;
874 /* create PLT entry */
875 if (need_plt_entry) {
876 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
877 Section *plt;
878 uint8_t *p;
879 int modrm;
880 unsigned long relofs;
882 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
883 modrm = 0x25;
884 #else
885 /* if we build a DLL, we add a %ebx offset */
886 if (s1->output_type == TCC_OUTPUT_DLL)
887 modrm = 0xa3;
888 else
889 modrm = 0x25;
890 #endif
892 plt = s1->plt;
893 /* empty PLT: create PLT0 entry that pushes the library indentifier
894 (GOT + PTR_SIZE) and jumps to ld.so resolution routine
895 (GOT + 2 * PTR_SIZE) */
896 if (plt->data_offset == 0) {
897 p = section_ptr_add(plt, 16);
898 p[0] = 0xff; /* pushl got + PTR_SIZE */
899 p[1] = modrm + 0x10;
900 write32le(p + 2, PTR_SIZE);
901 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
902 p[7] = modrm;
903 write32le(p + 8, PTR_SIZE * 2);
906 /* The PLT slot refers to the relocation entry it needs via offset.
907 The reloc entry is created below, so its offset is the current
908 data_offset */
909 relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
910 symattr->plt_offset = plt->data_offset;
912 /* Jump to GOT entry where ld.so initially put the address of ip + 4 */
913 p = section_ptr_add(plt, 16);
914 p[0] = 0xff; /* jmp *(got + x) */
915 p[1] = modrm;
916 write32le(p + 2, got_offset);
917 p[6] = 0x68; /* push $xxx */
918 #ifdef TCC_TARGET_X86_64
919 /* On x86-64, the relocation is referred to by _index_ */
920 write32le(p + 7, relofs / sizeof (ElfW_Rel));
921 #else
922 write32le(p + 7, relofs);
923 #endif
924 p[11] = 0xe9; /* jmp plt_start */
925 write32le(p + 12, -(plt->data_offset));
927 /* If this was an UNDEF symbol set the offset in the dynsymtab to the
928 PLT slot, so that PC32 relocs to it can be resolved */
929 if (sym->st_shndx == SHN_UNDEF)
930 offset = plt->data_offset - 16;
931 #elif defined(TCC_TARGET_ARM)
932 Section *plt;
933 uint8_t *p;
935 /* when building a DLL, GOT entry accesses must be done relative to
936 start of GOT (see x86_64 examble above) */
937 if (s1->output_type == TCC_OUTPUT_DLL)
938 tcc_error("DLLs unimplemented!");
940 plt = s1->plt;
941 /* empty PLT: create PLT0 entry that push address of call site and
942 jump to ld.so resolution routine (GOT + 8) */
943 if (plt->data_offset == 0) {
944 p = section_ptr_add(plt, 20);
945 write32le(p, 0xe52de004); /* push {lr} */
946 write32le(p+4, 0xe59fe004); /* ldr lr, [pc, #4] */
947 write32le(p+8, 0xe08fe00e); /* add lr, pc, lr */
948 write32le(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */
949 /* p+16 is set in relocate_plt */
952 symattr->plt_offset = plt->data_offset;
953 if (symattr->plt_thumb_stub) {
954 p = section_ptr_add(plt, 4);
955 write32le(p, 0x4778); /* bx pc */
956 write32le(p+2, 0x46c0); /* nop */
958 p = section_ptr_add(plt, 16);
959 /* Jump to GOT entry where ld.so initially put address of PLT0 */
960 write32le(p, 0xe59fc004); /* ldr ip, [pc, #4] */
961 write32le(p+4, 0xe08fc00c); /* add ip, pc, ip */
962 write32le(p+8, 0xe59cf000); /* ldr pc, [ip] */
963 /* p + 12 contains offset to GOT entry once patched by relocate_plt */
964 write32le(p+12, got_offset);
966 /* the symbol is modified so that it will be relocated to the PLT */
967 if (sym->st_shndx == SHN_UNDEF)
968 offset = plt->data_offset - 16;
969 #elif defined(TCC_TARGET_ARM64)
970 Section *plt;
971 uint8_t *p;
973 if (s1->output_type == TCC_OUTPUT_DLL)
974 tcc_error("DLLs unimplemented!");
976 plt = s1->plt;
977 if (plt->data_offset == 0)
978 section_ptr_add(plt, 32);
979 symattr->plt_offset = plt->data_offset;
980 p = section_ptr_add(plt, 16);
981 write32le(p, got_offset);
982 write32le(p + 4, (uint64_t) got_offset >> 32);
984 if (sym->st_shndx == SHN_UNDEF)
985 offset = plt->data_offset - 16;
986 #elif defined(TCC_TARGET_C67)
987 tcc_error("C67 got not implemented");
988 #else
989 #error unsupported CPU
990 #endif
993 /* Create the GOT relocation that will insert the address of the object or
994 function of interest in the GOT entry. This is a static relocation for
995 memory output (dlsym will give us the address of symbols) and dynamic
996 relocation otherwise (executable and DLLs). The relocation should be
997 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
998 associated to a PLT entry) but is currently done at load time for an
999 unknown reason. */
1000 if (s1->dynsym) {
1001 /* create the dynamic symbol table entry that the relocation refers to
1002 in its r_info field to identify the symbol */
1003 /* XXX This might generate multiple syms for name. */
1004 index = put_elf_sym(s1->dynsym, offset, size, info, 0, sym->st_shndx,
1005 name);
1006 put_elf_reloc(s1->dynsym, s1->got, got_offset, reloc_type, index);
1007 } else {
1008 put_elf_reloc(symtab_section, s1->got, got_offset, reloc_type,
1009 sym_index);
1012 if (need_plt_entry)
1013 return symattr->plt_offset;
1014 else
1015 return symattr->got_offset;
1018 /* build GOT and PLT entries */
1019 ST_FUNC void build_got_entries(TCCState *s1)
1021 Section *s;
1022 ElfW_Rel *rel;
1023 ElfW(Sym) *sym;
1024 int i, type, reloc_type, sym_index;
1026 for(i = 1; i < s1->nb_sections; i++) {
1027 s = s1->sections[i];
1028 if (s->sh_type != SHT_RELX)
1029 continue;
1030 /* no need to handle got relocations */
1031 if (s->link != symtab_section)
1032 continue;
1033 for_each_elem(s, 0, rel, ElfW_Rel) {
1034 type = ELFW(R_TYPE)(rel->r_info);
1035 switch(type) {
1036 #if defined(TCC_TARGET_I386)
1037 case R_386_GOT32:
1038 case R_386_GOT32X:
1039 case R_386_GOTOFF:
1040 case R_386_GOTPC:
1041 case R_386_PLT32:
1042 if (!s1->got)
1043 build_got(s1);
1044 if (type == R_386_GOT32 || type == R_386_GOT32X ||
1045 type == R_386_PLT32) {
1046 sym_index = ELFW(R_SYM)(rel->r_info);
1047 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1048 /* look at the symbol got offset. If none, then add one */
1049 if (type == R_386_GOT32 || type == R_386_GOT32X)
1050 reloc_type = R_386_GLOB_DAT;
1051 else
1052 reloc_type = R_386_JMP_SLOT;
1053 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1054 sym_index);
1056 break;
1057 #elif defined(TCC_TARGET_ARM)
1058 case R_ARM_PC24:
1059 case R_ARM_CALL:
1060 case R_ARM_JUMP24:
1061 case R_ARM_GOT32:
1062 case R_ARM_GOTOFF:
1063 case R_ARM_GOTPC:
1064 case R_ARM_PLT32:
1065 if (!s1->got)
1066 build_got(s1);
1067 sym_index = ELFW(R_SYM)(rel->r_info);
1068 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1069 if (type != R_ARM_GOTOFF && type != R_ARM_GOTPC
1070 && (sym->st_shndx == SHN_UNDEF
1071 || s1->output_type == TCC_OUTPUT_MEMORY)) {
1072 unsigned long ofs;
1073 /* look at the symbol got offset. If none, then add one */
1074 if (type == R_ARM_GOT32)
1075 reloc_type = R_ARM_GLOB_DAT;
1076 else
1077 reloc_type = R_ARM_JUMP_SLOT;
1078 ofs = put_got_entry(s1, reloc_type, sym->st_size,
1079 sym->st_info, sym_index);
1080 #ifdef DEBUG_RELOC
1081 printf ("maybegot: %s, %d, %d --> ofs=0x%x\n",
1082 (char *) symtab_section->link->data + sym->st_name,
1083 type, sym->st_shndx, ofs);
1084 #endif
1085 if (type != R_ARM_GOT32) {
1086 addr_t *ptr = (addr_t*)(s1->sections[s->sh_info]->data
1087 + rel->r_offset);
1088 /* x must be signed! */
1089 int x = *ptr & 0xffffff;
1090 x = (x << 8) >> 8;
1091 x <<= 2;
1092 x += ofs;
1093 x >>= 2;
1094 #ifdef DEBUG_RELOC
1095 printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr,
1096 (*ptr & 0xff000000) | x, x);
1097 #endif
1098 *ptr = (*ptr & 0xff000000) | x;
1101 break;
1102 case R_ARM_THM_JUMP24:
1103 sym_index = ELFW(R_SYM)(rel->r_info);
1104 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1105 /* We are relocating a jump from thumb code to arm code */
1106 if (sym->st_shndx != SHN_UNDEF && !(sym->st_value & 1)) {
1107 int index;
1108 uint8_t *p;
1109 char *name, buf[1024];
1110 Section *text_section;
1112 name = (char *) symtab_section->link->data + sym->st_name;
1113 text_section = s1->sections[sym->st_shndx];
1114 /* Modify reloc to target a thumb stub to switch to ARM */
1115 snprintf(buf, sizeof(buf), "%s_from_thumb", name);
1116 index = put_elf_sym(symtab_section,
1117 text_section->data_offset + 1,
1118 sym->st_size, sym->st_info, 0,
1119 sym->st_shndx, buf);
1120 rel->r_info = ELFW(R_INFO)(index, type);
1121 /* Create a thumb stub fonction to switch to ARM mode */
1122 put_elf_reloc(symtab_section, text_section,
1123 text_section->data_offset + 4, R_ARM_JUMP24,
1124 sym_index);
1125 p = section_ptr_add(text_section, 8);
1126 write32le(p, 0x4778); /* bx pc */
1127 write32le(p+2, 0x46c0); /* nop */
1128 write32le(p+4, 0xeafffffe); /* b $sym */
1130 #elif defined(TCC_TARGET_ARM64)
1131 //xx Other cases may be required here:
1132 case R_AARCH64_ADR_GOT_PAGE:
1133 case R_AARCH64_LD64_GOT_LO12_NC:
1134 if (!s1->got)
1135 build_got(s1);
1136 sym_index = ELFW(R_SYM)(rel->r_info);
1137 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1138 reloc_type = R_AARCH64_GLOB_DAT;
1139 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1140 sym_index);
1141 break;
1143 case R_AARCH64_JUMP26:
1144 case R_AARCH64_CALL26:
1145 if (!s1->got)
1146 build_got(s1);
1147 sym_index = ELFW(R_SYM)(rel->r_info);
1148 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1149 if (sym->st_shndx == SHN_UNDEF ||
1150 s1->output_type == TCC_OUTPUT_MEMORY) {
1151 unsigned long ofs;
1152 reloc_type = R_AARCH64_JUMP_SLOT;
1153 ofs = put_got_entry(s1, reloc_type, sym->st_size,
1154 sym->st_info, sym_index);
1155 /* We store the place of the generated PLT slot
1156 in our addend. */
1157 rel->r_addend += ofs;
1159 break;
1160 #elif defined(TCC_TARGET_C67)
1161 case R_C60_GOT32:
1162 case R_C60_GOTOFF:
1163 case R_C60_GOTPC:
1164 case R_C60_PLT32:
1165 if (!s1->got)
1166 build_got(s1);
1167 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
1168 sym_index = ELFW(R_SYM)(rel->r_info);
1169 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1170 /* look at the symbol got offset. If none, then add one */
1171 if (type == R_C60_GOT32)
1172 reloc_type = R_C60_GLOB_DAT;
1173 else
1174 reloc_type = R_C60_JMP_SLOT;
1175 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1176 sym_index);
1178 break;
1179 #elif defined(TCC_TARGET_X86_64)
1180 case R_X86_64_GOT32:
1181 case R_X86_64_GOTTPOFF:
1182 case R_X86_64_GOTPCREL:
1183 case R_X86_64_GOTPCRELX:
1184 case R_X86_64_REX_GOTPCRELX:
1185 case R_X86_64_PLT32:
1186 sym_index = ELFW(R_SYM)(rel->r_info);
1187 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1188 if (type == R_X86_64_PLT32 &&
1189 ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT)
1191 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1192 break;
1195 if (!s1->got) {
1196 build_got(s1);
1197 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1199 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
1200 type == R_X86_64_GOTPCRELX ||
1201 type == R_X86_64_REX_GOTPCRELX ||
1202 type == R_X86_64_PLT32) {
1203 unsigned long ofs;
1204 /* look at the symbol got offset. If none, then add one */
1205 if (type == R_X86_64_PLT32)
1206 reloc_type = R_X86_64_JUMP_SLOT;
1207 else
1208 reloc_type = R_X86_64_GLOB_DAT;
1209 ofs = put_got_entry(s1, reloc_type, sym->st_size,
1210 sym->st_info, sym_index);
1211 if (type == R_X86_64_PLT32)
1212 /* We store the place of the generated PLT slot
1213 in our addend. */
1214 rel->r_addend += ofs;
1216 break;
1217 #else
1218 #error unsupported CPU
1219 #endif
1220 default:
1221 break;
1227 ST_FUNC Section *new_symtab(TCCState *s1,
1228 const char *symtab_name, int sh_type, int sh_flags,
1229 const char *strtab_name,
1230 const char *hash_name, int hash_sh_flags)
1232 Section *symtab, *strtab, *hash;
1233 int *ptr, nb_buckets;
1235 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1236 symtab->sh_entsize = sizeof(ElfW(Sym));
1237 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1238 put_elf_str(strtab, "");
1239 symtab->link = strtab;
1240 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1242 nb_buckets = 1;
1244 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1245 hash->sh_entsize = sizeof(int);
1246 symtab->hash = hash;
1247 hash->link = symtab;
1249 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1250 ptr[0] = nb_buckets;
1251 ptr[1] = 1;
1252 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1253 return symtab;
1256 /* put dynamic tag */
1257 static void put_dt(Section *dynamic, int dt, addr_t val)
1259 ElfW(Dyn) *dyn;
1260 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1261 dyn->d_tag = dt;
1262 dyn->d_un.d_val = val;
1265 #ifndef TCC_TARGET_PE
1266 static void add_init_array_defines(TCCState *s1, const char *section_name)
1268 Section *s;
1269 long end_offset;
1270 char sym_start[1024];
1271 char sym_end[1024];
1273 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1274 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1276 s = find_section(s1, section_name);
1277 if (!s) {
1278 end_offset = 0;
1279 s = data_section;
1280 } else {
1281 end_offset = s->data_offset;
1284 set_elf_sym(symtab_section,
1285 0, 0,
1286 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1287 s->sh_num, sym_start);
1288 set_elf_sym(symtab_section,
1289 end_offset, 0,
1290 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1291 s->sh_num, sym_end);
1293 #endif
1295 static int tcc_add_support(TCCState *s1, const char *filename)
1297 char buf[1024];
1298 snprintf(buf, sizeof(buf), "%s/"TCC_ARCH_DIR"%s", s1->tcc_lib_path, filename);
1299 return tcc_add_file(s1, buf);
1302 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1304 #ifdef CONFIG_TCC_BCHECK
1305 addr_t *ptr;
1306 int sym_index;
1308 if (0 == s1->do_bounds_check)
1309 return;
1310 /* XXX: add an object file to do that */
1311 ptr = section_ptr_add(bounds_section, sizeof(*ptr));
1312 *ptr = 0;
1313 set_elf_sym(symtab_section, 0, 0,
1314 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1315 bounds_section->sh_num, "__bounds_start");
1316 /* pull bcheck.o from libtcc1.a */
1317 sym_index = set_elf_sym(symtab_section, 0, 0,
1318 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1319 SHN_UNDEF, "__bound_init");
1320 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1321 /* add 'call __bound_init()' in .init section */
1322 Section *init_section = find_section(s1, ".init");
1323 unsigned char *pinit = section_ptr_add(init_section, 5);
1324 pinit[0] = 0xe8;
1325 write32le(pinit + 1, -4);
1326 put_elf_reloc(symtab_section, init_section,
1327 init_section->data_offset - 4, R_386_PC32, sym_index);
1328 /* R_386_PC32 = R_X86_64_PC32 = 2 */
1330 #endif
1333 /* add tcc runtime libraries */
1334 ST_FUNC void tcc_add_runtime(TCCState *s1)
1336 tcc_add_bcheck(s1);
1337 tcc_add_pragma_libs(s1);
1338 /* add libc */
1339 if (!s1->nostdlib) {
1340 tcc_add_library_err(s1, "c");
1341 #ifdef CONFIG_USE_LIBGCC
1342 if (!s1->static_link) {
1343 tcc_add_file(s1, TCC_LIBGCC);
1345 #endif
1346 tcc_add_support(s1, "libtcc1.a");
1347 /* add crt end if not memory output */
1348 if (s1->output_type != TCC_OUTPUT_MEMORY)
1349 tcc_add_crt(s1, "crtn.o");
1353 /* add various standard linker symbols (must be done after the
1354 sections are filled (for example after allocating common
1355 symbols)) */
1356 ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
1358 char buf[1024];
1359 int i;
1360 Section *s;
1362 set_elf_sym(symtab_section,
1363 text_section->data_offset, 0,
1364 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1365 text_section->sh_num, "_etext");
1366 set_elf_sym(symtab_section,
1367 data_section->data_offset, 0,
1368 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1369 data_section->sh_num, "_edata");
1370 set_elf_sym(symtab_section,
1371 bss_section->data_offset, 0,
1372 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1373 bss_section->sh_num, "_end");
1374 #ifndef TCC_TARGET_PE
1375 /* horrible new standard ldscript defines */
1376 add_init_array_defines(s1, ".preinit_array");
1377 add_init_array_defines(s1, ".init_array");
1378 add_init_array_defines(s1, ".fini_array");
1379 #endif
1381 /* add start and stop symbols for sections whose name can be
1382 expressed in C */
1383 for(i = 1; i < s1->nb_sections; i++) {
1384 s = s1->sections[i];
1385 if (s->sh_type == SHT_PROGBITS &&
1386 (s->sh_flags & SHF_ALLOC)) {
1387 const char *p;
1388 int ch;
1390 /* check if section name can be expressed in C */
1391 p = s->name;
1392 for(;;) {
1393 ch = *p;
1394 if (!ch)
1395 break;
1396 if (!isid(ch) && !isnum(ch))
1397 goto next_sec;
1398 p++;
1400 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1401 set_elf_sym(symtab_section,
1402 0, 0,
1403 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1404 s->sh_num, buf);
1405 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1406 set_elf_sym(symtab_section,
1407 s->data_offset, 0,
1408 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1409 s->sh_num, buf);
1411 next_sec: ;
1415 static void tcc_output_binary(TCCState *s1, FILE *f,
1416 const int *sec_order)
1418 Section *s;
1419 int i, offset, size;
1421 offset = 0;
1422 for(i=1;i<s1->nb_sections;i++) {
1423 s = s1->sections[sec_order[i]];
1424 if (s->sh_type != SHT_NOBITS &&
1425 (s->sh_flags & SHF_ALLOC)) {
1426 while (offset < s->sh_offset) {
1427 fputc(0, f);
1428 offset++;
1430 size = s->sh_size;
1431 fwrite(s->data, 1, size, f);
1432 offset += size;
1437 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1438 #define HAVE_PHDR 1
1439 #define EXTRA_RELITEMS 14
1441 /* move the relocation value from .dynsym to .got */
1442 static void patch_dynsym_undef(TCCState *s1, Section *s)
1444 uint32_t *gotd = (void *)s1->got->data;
1445 ElfW(Sym) *sym;
1447 gotd += 3; /* dummy entries in .got */
1448 /* relocate symbols in .dynsym */
1449 for_each_elem(s, 1, sym, ElfW(Sym)) {
1450 if (sym->st_shndx == SHN_UNDEF) {
1451 *gotd++ = sym->st_value + 6; /* XXX 6 is magic ? */
1452 sym->st_value = 0;
1456 #else
1457 #define HAVE_PHDR 1
1458 #define EXTRA_RELITEMS 9
1460 /* zero plt offsets of weak symbols in .dynsym */
1461 static void patch_dynsym_undef(TCCState *s1, Section *s)
1463 ElfW(Sym) *sym;
1465 for_each_elem(s, 1, sym, ElfW(Sym))
1466 if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
1467 sym->st_value = 0;
1469 #endif
1471 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1473 int sym_index = ELFW(R_SYM) (rel->r_info);
1474 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1475 unsigned long offset;
1477 if (sym_index >= s1->nb_sym_attrs)
1478 return;
1479 offset = s1->sym_attrs[sym_index].got_offset;
1480 section_reserve(s1->got, offset + PTR_SIZE);
1481 #ifdef TCC_TARGET_X86_64
1482 /* only works for x86-64 */
1483 write32le(s1->got->data + offset + 4, sym->st_value >> 32);
1484 #endif
1485 write32le(s1->got->data + offset, sym->st_value & 0xffffffff);
1488 /* Perform relocation to GOT or PLT entries */
1489 ST_FUNC void fill_got(TCCState *s1)
1491 Section *s;
1492 ElfW_Rel *rel;
1493 int i;
1495 for(i = 1; i < s1->nb_sections; i++) {
1496 s = s1->sections[i];
1497 if (s->sh_type != SHT_RELX)
1498 continue;
1499 /* no need to handle got relocations */
1500 if (s->link != symtab_section)
1501 continue;
1502 for_each_elem(s, 0, rel, ElfW_Rel) {
1503 switch (ELFW(R_TYPE) (rel->r_info)) {
1504 case R_X86_64_GOT32:
1505 case R_X86_64_GOTPCREL:
1506 case R_X86_64_GOTPCRELX:
1507 case R_X86_64_REX_GOTPCRELX:
1508 case R_X86_64_PLT32:
1509 fill_got_entry(s1, rel);
1510 break;
1516 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1517 in shared libraries and export non local defined symbols to shared libraries
1518 if -rdynamic switch was given on command line */
1519 static void bind_exe_dynsyms(TCCState *s1)
1521 const char *name;
1522 int sym_index, index;
1523 ElfW(Sym) *sym, *esym;
1524 int type;
1526 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1527 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1528 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1529 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1530 if (sym->st_shndx == SHN_UNDEF) {
1531 name = (char *) symtab_section->link->data + sym->st_name;
1532 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1533 if (sym_index) {
1534 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1535 type = ELFW(ST_TYPE)(esym->st_info);
1536 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1537 /* Indirect functions shall have STT_FUNC type in executable
1538 * dynsym section. Indeed, a dlsym call following a lazy
1539 * resolution would pick the symbol value from the
1540 * executable dynsym entry which would contain the address
1541 * of the function wanted by the caller of dlsym instead of
1542 * the address of the function that would return that
1543 * address */
1544 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1545 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC),
1546 sym - (ElfW(Sym) *)symtab_section->data);
1547 } else if (type == STT_OBJECT) {
1548 unsigned long offset;
1549 ElfW(Sym) *dynsym;
1550 offset = bss_section->data_offset;
1551 /* XXX: which alignment ? */
1552 offset = (offset + 16 - 1) & -16;
1553 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1554 esym->st_info, 0, bss_section->sh_num,
1555 name);
1556 /* Ensure R_COPY works for weak symbol aliases */
1557 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1558 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1559 if ((dynsym->st_value == esym->st_value)
1560 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1561 char *dynname = (char *) s1->dynsymtab_section->link->data
1562 + dynsym->st_name;
1563 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1564 dynsym->st_info, 0,
1565 bss_section->sh_num, dynname);
1566 break;
1570 put_elf_reloc(s1->dynsym, bss_section,
1571 offset, R_COPY, index);
1572 offset += esym->st_size;
1573 bss_section->data_offset = offset;
1575 } else {
1576 /* STB_WEAK undefined symbols are accepted */
1577 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1578 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1579 !strcmp(name, "_fp_hw")) {
1580 } else {
1581 tcc_error_noabort("undefined symbol '%s'", name);
1584 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1585 /* if -rdynamic option, then export all non local symbols */
1586 name = (char *) symtab_section->link->data + sym->st_name;
1587 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1588 0, sym->st_shndx, name);
1593 /* Bind symbols of libraries: export all non local symbols of executable that
1594 are referenced by shared libraries. The reason is that the dynamic loader
1595 search symbol first in executable and then in libraries. Therefore a
1596 reference to a symbol already defined by a library can still be resolved by
1597 a symbol in the executable. */
1598 static void bind_libs_dynsyms(TCCState *s1)
1600 const char *name;
1601 int sym_index;
1602 ElfW(Sym) *sym, *esym;
1604 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1605 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1606 sym_index = find_elf_sym(symtab_section, name);
1607 /* XXX: avoid adding a symbol if already present because of
1608 -rdynamic ? */
1609 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1610 if (sym_index && sym->st_shndx != SHN_UNDEF)
1611 set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1612 0, sym->st_shndx, name);
1613 else if (esym->st_shndx == SHN_UNDEF) {
1614 /* weak symbols can stay undefined */
1615 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1616 tcc_warning("undefined dynamic symbol '%s'", name);
1621 /* Export all non local symbols. This is used by shared libraries so that the
1622 non local symbols they define can resolve a reference in another shared
1623 library or in the executable. Correspondingly, it allows undefined local
1624 symbols to be resolved by other shared libraries or by the executable. */
1625 static void export_global_syms(TCCState *s1)
1627 int nb_syms, dynindex, index;
1628 const char *name;
1629 ElfW(Sym) *sym;
1631 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1632 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1633 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1634 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1635 name = (char *) symtab_section->link->data + sym->st_name;
1636 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1637 sym->st_info, 0, sym->st_shndx, name);
1638 index = sym - (ElfW(Sym) *) symtab_section->data;
1639 s1->symtab_to_dynsym[index] = dynindex;
1644 /* relocate the PLT: compute addresses and offsets in the PLT now that final
1645 address for PLT and GOT are known (see fill_program_header) */
1646 ST_FUNC void relocate_plt(TCCState *s1)
1648 uint8_t *p, *p_end;
1650 if (!s1->plt)
1651 return;
1653 p = s1->plt->data;
1654 p_end = p + s1->plt->data_offset;
1655 if (p < p_end) {
1656 #if defined(TCC_TARGET_I386)
1657 add32le(p + 2, s1->got->sh_addr);
1658 add32le(p + 8, s1->got->sh_addr);
1659 p += 16;
1660 while (p < p_end) {
1661 add32le(p + 2, s1->got->sh_addr);
1662 p += 16;
1664 #elif defined(TCC_TARGET_X86_64)
1665 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
1666 add32le(p + 2, x);
1667 add32le(p + 8, x - 6);
1668 p += 16;
1669 while (p < p_end) {
1670 add32le(p + 2, x + s1->plt->data - p);
1671 p += 16;
1673 #elif defined(TCC_TARGET_ARM)
1674 int x = s1->got->sh_addr - s1->plt->sh_addr - 12;
1675 write32le(s1->plt->data + 16, x - 16);
1676 p += 20;
1677 while (p < p_end) {
1678 if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
1679 p += 4;
1680 add32le(p + 12, x + s1->plt->data - p);
1681 p += 16;
1683 #elif defined(TCC_TARGET_ARM64)
1684 uint64_t plt = s1->plt->sh_addr;
1685 uint64_t got = s1->got->sh_addr;
1686 uint64_t off = (got >> 12) - (plt >> 12);
1687 if ((off + ((uint32_t)1 << 20)) >> 21)
1688 tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt);
1689 write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
1690 write32le(p + 4, (0x90000010 | // adrp x16,...
1691 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1692 write32le(p + 8, (0xf9400211 | // ldr x17,[x16,#...]
1693 (got & 0xff8) << 7));
1694 write32le(p + 12, (0x91000210 | // add x16,x16,#...
1695 (got & 0xfff) << 10));
1696 write32le(p + 16, 0xd61f0220); // br x17
1697 write32le(p + 20, 0xd503201f); // nop
1698 write32le(p + 24, 0xd503201f); // nop
1699 write32le(p + 28, 0xd503201f); // nop
1700 p += 32;
1701 while (p < p_end) {
1702 uint64_t pc = plt + (p - s1->plt->data);
1703 uint64_t addr = got + read64le(p);
1704 uint64_t off = (addr >> 12) - (pc >> 12);
1705 if ((off + ((uint32_t)1 << 20)) >> 21)
1706 tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc);
1707 write32le(p, (0x90000010 | // adrp x16,...
1708 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1709 write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
1710 (addr & 0xff8) << 7));
1711 write32le(p + 8, (0x91000210 | // add x16,x16,#...
1712 (addr & 0xfff) << 10));
1713 write32le(p + 12, 0xd61f0220); // br x17
1714 p += 16;
1716 #elif defined(TCC_TARGET_C67)
1717 /* XXX: TODO */
1718 #else
1719 #error unsupported CPU
1720 #endif
1724 /* Allocate strings for section names and decide if an unallocated section
1725 should be output.
1727 NOTE: the strsec section comes last, so its size is also correct ! */
1728 static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1730 int i;
1731 Section *s;
1733 /* Allocate strings for section names */
1734 for(i = 1; i < s1->nb_sections; i++) {
1735 s = s1->sections[i];
1736 s->sh_name = put_elf_str(strsec, s->name);
1737 /* when generating a DLL, we include relocations but we may
1738 patch them */
1739 if (file_type == TCC_OUTPUT_DLL &&
1740 s->sh_type == SHT_RELX &&
1741 !(s->sh_flags & SHF_ALLOC)) {
1742 /* gr: avoid bogus relocs for empty (debug) sections */
1743 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1744 prepare_dynamic_rel(s1, s);
1745 else if (s1->do_debug)
1746 s->sh_size = s->data_offset;
1747 } else if (s1->do_debug ||
1748 file_type == TCC_OUTPUT_OBJ ||
1749 (s->sh_flags & SHF_ALLOC) ||
1750 i == (s1->nb_sections - 1)) {
1751 /* we output all sections if debug or object file */
1752 s->sh_size = s->data_offset;
1757 /* Info to be copied in dynamic section */
1758 struct dyn_inf {
1759 Section *dynamic;
1760 Section *dynstr;
1761 unsigned long dyn_rel_off;
1762 addr_t rel_addr;
1763 addr_t rel_size;
1764 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1765 addr_t bss_addr;
1766 addr_t bss_size;
1767 #endif
1770 /* Assign sections to segments and decide how are sections laid out when loaded
1771 in memory. This function also fills corresponding program headers. */
1772 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1773 Section *interp, Section* strsec,
1774 struct dyn_inf *dyninf, int *sec_order)
1776 int i, j, k, file_type, sh_order_index, file_offset;
1777 unsigned long s_align;
1778 long long tmp;
1779 addr_t addr;
1780 ElfW(Phdr) *ph;
1781 Section *s;
1783 file_type = s1->output_type;
1784 sh_order_index = 1;
1785 file_offset = 0;
1786 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1787 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1788 s_align = ELF_PAGE_SIZE;
1789 if (s1->section_align)
1790 s_align = s1->section_align;
1792 if (phnum > 0) {
1793 if (s1->has_text_addr) {
1794 int a_offset, p_offset;
1795 addr = s1->text_addr;
1796 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1797 ELF_PAGE_SIZE */
1798 a_offset = (int) (addr & (s_align - 1));
1799 p_offset = file_offset & (s_align - 1);
1800 if (a_offset < p_offset)
1801 a_offset += s_align;
1802 file_offset += (a_offset - p_offset);
1803 } else {
1804 if (file_type == TCC_OUTPUT_DLL)
1805 addr = 0;
1806 else
1807 addr = ELF_START_ADDR;
1808 /* compute address after headers */
1809 addr += (file_offset & (s_align - 1));
1812 ph = &phdr[0];
1813 /* Leave one program headers for the program interpreter and one for
1814 the program header table itself if needed. These are done later as
1815 they require section layout to be done first. */
1816 if (interp)
1817 ph += 1 + HAVE_PHDR;
1819 /* dynamic relocation table information, for .dynamic section */
1820 dyninf->rel_addr = dyninf->rel_size = 0;
1821 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1822 dyninf->bss_addr = dyninf->bss_size = 0;
1823 #endif
1825 for(j = 0; j < 2; j++) {
1826 ph->p_type = PT_LOAD;
1827 if (j == 0)
1828 ph->p_flags = PF_R | PF_X;
1829 else
1830 ph->p_flags = PF_R | PF_W;
1831 ph->p_align = s_align;
1833 /* Decide the layout of sections loaded in memory. This must
1834 be done before program headers are filled since they contain
1835 info about the layout. We do the following ordering: interp,
1836 symbol tables, relocations, progbits, nobits */
1837 /* XXX: do faster and simpler sorting */
1838 for(k = 0; k < 5; k++) {
1839 for(i = 1; i < s1->nb_sections; i++) {
1840 s = s1->sections[i];
1841 /* compute if section should be included */
1842 if (j == 0) {
1843 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1844 SHF_ALLOC)
1845 continue;
1846 } else {
1847 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1848 (SHF_ALLOC | SHF_WRITE))
1849 continue;
1851 if (s == interp) {
1852 if (k != 0)
1853 continue;
1854 } else if (s->sh_type == SHT_DYNSYM ||
1855 s->sh_type == SHT_STRTAB ||
1856 s->sh_type == SHT_HASH) {
1857 if (k != 1)
1858 continue;
1859 } else if (s->sh_type == SHT_RELX) {
1860 if (k != 2)
1861 continue;
1862 } else if (s->sh_type == SHT_NOBITS) {
1863 if (k != 4)
1864 continue;
1865 } else {
1866 if (k != 3)
1867 continue;
1869 sec_order[sh_order_index++] = i;
1871 /* section matches: we align it and add its size */
1872 tmp = addr;
1873 addr = (addr + s->sh_addralign - 1) &
1874 ~(s->sh_addralign - 1);
1875 file_offset += (int) ( addr - tmp );
1876 s->sh_offset = file_offset;
1877 s->sh_addr = addr;
1879 /* update program header infos */
1880 if (ph->p_offset == 0) {
1881 ph->p_offset = file_offset;
1882 ph->p_vaddr = addr;
1883 ph->p_paddr = ph->p_vaddr;
1885 /* update dynamic relocation infos */
1886 if (s->sh_type == SHT_RELX) {
1887 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1888 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1889 dyninf->rel_addr = addr;
1890 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1892 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1893 dyninf->bss_addr = addr;
1894 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1896 #else
1897 if (dyninf->rel_size == 0)
1898 dyninf->rel_addr = addr;
1899 dyninf->rel_size += s->sh_size;
1900 #endif
1902 addr += s->sh_size;
1903 if (s->sh_type != SHT_NOBITS)
1904 file_offset += s->sh_size;
1907 if (j == 0) {
1908 /* Make the first PT_LOAD segment include the program
1909 headers itself (and the ELF header as well), it'll
1910 come out with same memory use but will make various
1911 tools like binutils strip work better. */
1912 ph->p_offset &= ~(ph->p_align - 1);
1913 ph->p_vaddr &= ~(ph->p_align - 1);
1914 ph->p_paddr &= ~(ph->p_align - 1);
1916 ph->p_filesz = file_offset - ph->p_offset;
1917 ph->p_memsz = addr - ph->p_vaddr;
1918 ph++;
1919 if (j == 0) {
1920 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1921 /* if in the middle of a page, we duplicate the page in
1922 memory so that one copy is RX and the other is RW */
1923 if ((addr & (s_align - 1)) != 0)
1924 addr += s_align;
1925 } else {
1926 addr = (addr + s_align - 1) & ~(s_align - 1);
1927 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
1933 /* all other sections come after */
1934 for(i = 1; i < s1->nb_sections; i++) {
1935 s = s1->sections[i];
1936 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1937 continue;
1938 sec_order[sh_order_index++] = i;
1940 file_offset = (file_offset + s->sh_addralign - 1) &
1941 ~(s->sh_addralign - 1);
1942 s->sh_offset = file_offset;
1943 if (s->sh_type != SHT_NOBITS)
1944 file_offset += s->sh_size;
1947 return file_offset;
1950 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1951 Section *dynamic)
1953 ElfW(Phdr) *ph;
1955 /* if interpreter, then add corresponding program header */
1956 if (interp) {
1957 ph = &phdr[0];
1959 if (HAVE_PHDR)
1961 int len = phnum * sizeof(ElfW(Phdr));
1963 ph->p_type = PT_PHDR;
1964 ph->p_offset = sizeof(ElfW(Ehdr));
1965 ph->p_vaddr = interp->sh_addr - len;
1966 ph->p_paddr = ph->p_vaddr;
1967 ph->p_filesz = ph->p_memsz = len;
1968 ph->p_flags = PF_R | PF_X;
1969 ph->p_align = 4; /* interp->sh_addralign; */
1970 ph++;
1973 ph->p_type = PT_INTERP;
1974 ph->p_offset = interp->sh_offset;
1975 ph->p_vaddr = interp->sh_addr;
1976 ph->p_paddr = ph->p_vaddr;
1977 ph->p_filesz = interp->sh_size;
1978 ph->p_memsz = interp->sh_size;
1979 ph->p_flags = PF_R;
1980 ph->p_align = interp->sh_addralign;
1983 /* if dynamic section, then add corresponding program header */
1984 if (dynamic) {
1985 ph = &phdr[phnum - 1];
1987 ph->p_type = PT_DYNAMIC;
1988 ph->p_offset = dynamic->sh_offset;
1989 ph->p_vaddr = dynamic->sh_addr;
1990 ph->p_paddr = ph->p_vaddr;
1991 ph->p_filesz = dynamic->sh_size;
1992 ph->p_memsz = dynamic->sh_size;
1993 ph->p_flags = PF_R | PF_W;
1994 ph->p_align = dynamic->sh_addralign;
1998 /* Fill the dynamic section with tags describing the address and size of
1999 sections */
2000 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2002 Section *dynamic;
2004 dynamic = dyninf->dynamic;
2006 /* put dynamic section entries */
2007 dynamic->data_offset = dyninf->dyn_rel_off;
2008 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2009 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2010 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2011 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2012 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2013 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2014 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2015 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2016 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2017 #else
2018 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2019 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2020 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
2021 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2022 put_dt(dynamic, DT_PLTREL, DT_REL);
2023 put_dt(dynamic, DT_REL, dyninf->bss_addr);
2024 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
2025 #else
2026 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2027 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2028 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2029 #endif
2030 #endif
2031 if (s1->do_debug)
2032 put_dt(dynamic, DT_DEBUG, 0);
2033 put_dt(dynamic, DT_NULL, 0);
2036 /* Relocate remaining sections and symbols (that is those not related to
2037 dynamic linking) */
2038 static int final_sections_reloc(TCCState *s1)
2040 int i;
2041 Section *s;
2043 relocate_syms(s1, 0);
2045 if (s1->nb_errors != 0)
2046 return -1;
2048 /* relocate sections */
2049 /* XXX: ignore sections with allocated relocations ? */
2050 for(i = 1; i < s1->nb_sections; i++) {
2051 s = s1->sections[i];
2052 #ifdef TCC_TARGET_I386
2053 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
2054 /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
2055 checking is removed */
2056 #else
2057 if (s->reloc && s != s1->got)
2058 /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
2059 #endif
2060 relocate_section(s1, s);
2063 /* relocate relocation entries if the relocation tables are
2064 allocated in the executable */
2065 for(i = 1; i < s1->nb_sections; i++) {
2066 s = s1->sections[i];
2067 if ((s->sh_flags & SHF_ALLOC) &&
2068 s->sh_type == SHT_RELX) {
2069 relocate_rel(s1, s);
2072 return 0;
2075 /* Create an ELF file on disk.
2076 This function handle ELF specific layout requirements */
2077 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2078 int file_offset, int *sec_order)
2080 int i, shnum, offset, size, file_type;
2081 Section *s;
2082 ElfW(Ehdr) ehdr;
2083 ElfW(Shdr) shdr, *sh;
2085 file_type = s1->output_type;
2086 shnum = s1->nb_sections;
2088 memset(&ehdr, 0, sizeof(ehdr));
2090 if (phnum > 0) {
2091 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2092 ehdr.e_phnum = phnum;
2093 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2096 /* align to 4 */
2097 file_offset = (file_offset + 3) & -4;
2099 /* fill header */
2100 ehdr.e_ident[0] = ELFMAG0;
2101 ehdr.e_ident[1] = ELFMAG1;
2102 ehdr.e_ident[2] = ELFMAG2;
2103 ehdr.e_ident[3] = ELFMAG3;
2104 ehdr.e_ident[4] = ELFCLASSW;
2105 ehdr.e_ident[5] = ELFDATA2LSB;
2106 ehdr.e_ident[6] = EV_CURRENT;
2107 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2108 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2109 #endif
2110 #ifdef TCC_TARGET_ARM
2111 #ifdef TCC_ARM_EABI
2112 ehdr.e_ident[EI_OSABI] = 0;
2113 ehdr.e_flags = EF_ARM_EABI_VER4;
2114 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2115 ehdr.e_flags |= EF_ARM_HASENTRY;
2116 if (s1->float_abi == ARM_HARD_FLOAT)
2117 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2118 else
2119 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2120 #else
2121 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2122 #endif
2123 #endif
2124 switch(file_type) {
2125 default:
2126 case TCC_OUTPUT_EXE:
2127 ehdr.e_type = ET_EXEC;
2128 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
2129 break;
2130 case TCC_OUTPUT_DLL:
2131 ehdr.e_type = ET_DYN;
2132 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2133 break;
2134 case TCC_OUTPUT_OBJ:
2135 ehdr.e_type = ET_REL;
2136 break;
2138 ehdr.e_machine = EM_TCC_TARGET;
2139 ehdr.e_version = EV_CURRENT;
2140 ehdr.e_shoff = file_offset;
2141 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2142 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2143 ehdr.e_shnum = shnum;
2144 ehdr.e_shstrndx = shnum - 1;
2146 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2147 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2148 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2150 sort_syms(s1, symtab_section);
2151 for(i = 1; i < s1->nb_sections; i++) {
2152 s = s1->sections[sec_order[i]];
2153 if (s->sh_type != SHT_NOBITS) {
2154 if (s->sh_type == SHT_DYNSYM)
2155 patch_dynsym_undef(s1, s);
2156 while (offset < s->sh_offset) {
2157 fputc(0, f);
2158 offset++;
2160 size = s->sh_size;
2161 if (size)
2162 fwrite(s->data, 1, size, f);
2163 offset += size;
2167 /* output section headers */
2168 while (offset < ehdr.e_shoff) {
2169 fputc(0, f);
2170 offset++;
2173 for(i = 0; i < s1->nb_sections; i++) {
2174 sh = &shdr;
2175 memset(sh, 0, sizeof(ElfW(Shdr)));
2176 s = s1->sections[i];
2177 if (s) {
2178 sh->sh_name = s->sh_name;
2179 sh->sh_type = s->sh_type;
2180 sh->sh_flags = s->sh_flags;
2181 sh->sh_entsize = s->sh_entsize;
2182 sh->sh_info = s->sh_info;
2183 if (s->link)
2184 sh->sh_link = s->link->sh_num;
2185 sh->sh_addralign = s->sh_addralign;
2186 sh->sh_addr = s->sh_addr;
2187 sh->sh_offset = s->sh_offset;
2188 sh->sh_size = s->sh_size;
2190 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2194 /* Write an elf, coff or "binary" file */
2195 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2196 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2198 int fd, mode, file_type;
2199 FILE *f;
2201 file_type = s1->output_type;
2202 if (file_type == TCC_OUTPUT_OBJ)
2203 mode = 0666;
2204 else
2205 mode = 0777;
2206 unlink(filename);
2207 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2208 if (fd < 0) {
2209 tcc_error_noabort("could not write '%s'", filename);
2210 return -1;
2212 f = fdopen(fd, "wb");
2213 if (s1->verbose)
2214 printf("<- %s\n", filename);
2216 #ifdef TCC_TARGET_COFF
2217 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2218 tcc_output_coff(s1, f);
2219 else
2220 #endif
2221 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2222 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2223 else
2224 tcc_output_binary(s1, f, sec_order);
2225 fclose(f);
2227 return 0;
2230 /* Output an elf, coff or binary file */
2231 /* XXX: suppress unneeded sections */
2232 static int elf_output_file(TCCState *s1, const char *filename)
2234 int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
2235 struct dyn_inf dyninf;
2236 ElfW(Phdr) *phdr;
2237 ElfW(Sym) *sym;
2238 Section *strsec, *interp, *dynamic, *dynstr;
2240 file_type = s1->output_type;
2241 s1->nb_errors = 0;
2243 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2244 if (file_type != TCC_OUTPUT_OBJ) {
2245 tcc_add_runtime(s1);
2248 phdr = NULL;
2249 sec_order = NULL;
2250 interp = dynamic = dynstr = NULL; /* avoid warning */
2251 dyninf.dyn_rel_off = 0; /* avoid warning */
2253 if (file_type != TCC_OUTPUT_OBJ) {
2254 relocate_common_syms();
2256 tcc_add_linker_symbols(s1);
2258 if (!s1->static_link) {
2259 if (file_type == TCC_OUTPUT_EXE) {
2260 char *ptr;
2261 /* allow override the dynamic loader */
2262 const char *elfint = getenv("LD_SO");
2263 if (elfint == NULL)
2264 elfint = DEFAULT_ELFINTERP(s1);
2265 /* add interpreter section only if executable */
2266 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2267 interp->sh_addralign = 1;
2268 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2269 strcpy(ptr, elfint);
2272 /* add dynamic symbol table */
2273 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2274 ".dynstr",
2275 ".hash", SHF_ALLOC);
2276 dynstr = s1->dynsym->link;
2278 /* add dynamic section */
2279 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2280 SHF_ALLOC | SHF_WRITE);
2281 dynamic->link = dynstr;
2282 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2284 build_got(s1);
2286 if (file_type == TCC_OUTPUT_EXE) {
2287 bind_exe_dynsyms(s1);
2289 if (s1->nb_errors) {
2290 ret = -1;
2291 goto the_end;
2294 bind_libs_dynsyms(s1);
2295 } else /* shared library case: simply export all global symbols */
2296 export_global_syms(s1);
2298 build_got_entries(s1);
2300 /* add a list of needed dlls */
2301 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2302 DLLReference *dllref = s1->loaded_dlls[i];
2303 if (dllref->level == 0)
2304 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2307 if (s1->rpath)
2308 put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath));
2310 /* XXX: currently, since we do not handle PIC code, we
2311 must relocate the readonly segments */
2312 if (file_type == TCC_OUTPUT_DLL) {
2313 if (s1->soname)
2314 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2315 put_dt(dynamic, DT_TEXTREL, 0);
2318 if (s1->symbolic)
2319 put_dt(dynamic, DT_SYMBOLIC, 0);
2321 /* add necessary space for other entries */
2322 dyninf.dyn_rel_off = dynamic->data_offset;
2323 dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
2324 } else {
2325 /* still need to build got entries in case of static link */
2326 build_got_entries(s1);
2330 /* we add a section for symbols */
2331 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2332 put_elf_str(strsec, "");
2334 /* compute number of sections */
2335 shnum = s1->nb_sections;
2337 /* this array is used to reorder sections in the output file */
2338 sec_order = tcc_malloc(sizeof(int) * shnum);
2339 sec_order[0] = 0;
2341 /* compute number of program headers */
2342 switch(file_type) {
2343 default:
2344 case TCC_OUTPUT_OBJ:
2345 phnum = 0;
2346 break;
2347 case TCC_OUTPUT_EXE:
2348 if (!s1->static_link)
2349 phnum = 4 + HAVE_PHDR;
2350 else
2351 phnum = 2;
2352 break;
2353 case TCC_OUTPUT_DLL:
2354 phnum = 3;
2355 break;
2358 /* Allocate strings for section names */
2359 alloc_sec_names(s1, file_type, strsec);
2361 /* allocate program segment headers */
2362 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2364 /* compute section to program header mapping */
2365 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2366 sec_order);
2368 /* Fill remaining program header and finalize relocation related to dynamic
2369 linking. */
2370 if (phnum > 0) {
2371 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2372 if (dynamic) {
2373 dyninf.dynamic = dynamic;
2374 dyninf.dynstr = dynstr;
2376 fill_dynamic(s1, &dyninf);
2378 /* put in GOT the dynamic section address and relocate PLT */
2379 write32le(s1->got->data, dynamic->sh_addr);
2380 if (file_type == TCC_OUTPUT_EXE
2381 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
2382 || file_type == TCC_OUTPUT_DLL
2383 #endif
2385 relocate_plt(s1);
2387 /* relocate symbols in .dynsym now that final addresses are known */
2388 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2389 if (sym->st_shndx == SHN_UNDEF) {
2390 /* relocate to PLT if symbol corresponds to a PLT entry,
2391 but not if it's a weak symbol */
2392 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
2393 sym->st_value = 0;
2394 else if (sym->st_value)
2395 sym->st_value += s1->plt->sh_addr;
2396 } else if (sym->st_shndx < SHN_LORESERVE) {
2397 /* do symbol relocation */
2398 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2404 /* if building executable or DLL, then relocate each section
2405 except the GOT which is already relocated */
2406 if (file_type != TCC_OUTPUT_OBJ) {
2407 ret = final_sections_reloc(s1);
2408 if (ret)
2409 goto the_end;
2412 /* Perform relocation to GOT or PLT entries */
2413 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2414 fill_got(s1);
2416 /* Create the ELF file with name 'filename' */
2417 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2418 the_end:
2419 tcc_free(s1->symtab_to_dynsym);
2420 tcc_free(sec_order);
2421 tcc_free(phdr);
2422 tcc_free(s1->sym_attrs);
2423 s1->sym_attrs = NULL;
2424 return ret;
2427 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2429 int ret;
2430 #ifdef TCC_TARGET_PE
2431 if (s->output_type != TCC_OUTPUT_OBJ) {
2432 ret = pe_output_file(s, filename);
2433 } else
2434 #endif
2435 ret = elf_output_file(s, filename);
2436 return ret;
2439 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2441 void *data;
2443 data = tcc_malloc(size);
2444 lseek(fd, file_offset, SEEK_SET);
2445 read(fd, data, size);
2446 return data;
2449 typedef struct SectionMergeInfo {
2450 Section *s; /* corresponding existing section */
2451 unsigned long offset; /* offset of the new section in the existing section */
2452 uint8_t new_section; /* true if section 's' was added */
2453 uint8_t link_once; /* true if link once section */
2454 } SectionMergeInfo;
2456 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2458 int size = read(fd, h, sizeof *h);
2459 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2460 if (h->e_type == ET_REL)
2461 return AFF_BINTYPE_REL;
2462 if (h->e_type == ET_DYN)
2463 return AFF_BINTYPE_DYN;
2464 } else if (size >= 8) {
2465 if (0 == memcmp(h, ARMAG, 8))
2466 return AFF_BINTYPE_AR;
2467 #ifdef TCC_TARGET_COFF
2468 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2469 return AFF_BINTYPE_C67;
2470 #endif
2472 return 0;
2475 /* load an object file and merge it with current files */
2476 /* XXX: handle correctly stab (debug) info */
2477 ST_FUNC int tcc_load_object_file(TCCState *s1,
2478 int fd, unsigned long file_offset)
2480 ElfW(Ehdr) ehdr;
2481 ElfW(Shdr) *shdr, *sh;
2482 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2483 unsigned char *strsec, *strtab;
2484 int *old_to_new_syms;
2485 char *sh_name, *name;
2486 SectionMergeInfo *sm_table, *sm;
2487 ElfW(Sym) *sym, *symtab;
2488 ElfW_Rel *rel;
2489 Section *s;
2491 int stab_index;
2492 int stabstr_index;
2494 stab_index = stabstr_index = 0;
2496 lseek(fd, file_offset, SEEK_SET);
2497 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2498 goto fail1;
2499 /* test CPU specific stuff */
2500 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2501 ehdr.e_machine != EM_TCC_TARGET) {
2502 fail1:
2503 tcc_error_noabort("invalid object file");
2504 return -1;
2506 /* read sections */
2507 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2508 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2509 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2511 /* load section names */
2512 sh = &shdr[ehdr.e_shstrndx];
2513 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2515 /* load symtab and strtab */
2516 old_to_new_syms = NULL;
2517 symtab = NULL;
2518 strtab = NULL;
2519 nb_syms = 0;
2520 for(i = 1; i < ehdr.e_shnum; i++) {
2521 sh = &shdr[i];
2522 if (sh->sh_type == SHT_SYMTAB) {
2523 if (symtab) {
2524 tcc_error_noabort("object must contain only one symtab");
2525 fail:
2526 ret = -1;
2527 goto the_end;
2529 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2530 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2531 sm_table[i].s = symtab_section;
2533 /* now load strtab */
2534 sh = &shdr[sh->sh_link];
2535 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2539 /* now examine each section and try to merge its content with the
2540 ones in memory */
2541 for(i = 1; i < ehdr.e_shnum; i++) {
2542 /* no need to examine section name strtab */
2543 if (i == ehdr.e_shstrndx)
2544 continue;
2545 sh = &shdr[i];
2546 sh_name = (char *) strsec + sh->sh_name;
2547 /* ignore sections types we do not handle */
2548 if (sh->sh_type != SHT_PROGBITS &&
2549 sh->sh_type != SHT_RELX &&
2550 #ifdef TCC_ARM_EABI
2551 sh->sh_type != SHT_ARM_EXIDX &&
2552 #endif
2553 sh->sh_type != SHT_NOBITS &&
2554 sh->sh_type != SHT_PREINIT_ARRAY &&
2555 sh->sh_type != SHT_INIT_ARRAY &&
2556 sh->sh_type != SHT_FINI_ARRAY &&
2557 strcmp(sh_name, ".stabstr")
2559 continue;
2560 if (sh->sh_addralign < 1)
2561 sh->sh_addralign = 1;
2562 /* find corresponding section, if any */
2563 for(j = 1; j < s1->nb_sections;j++) {
2564 s = s1->sections[j];
2565 if (!strcmp(s->name, sh_name)) {
2566 if (!strncmp(sh_name, ".gnu.linkonce",
2567 sizeof(".gnu.linkonce") - 1)) {
2568 /* if a 'linkonce' section is already present, we
2569 do not add it again. It is a little tricky as
2570 symbols can still be defined in
2571 it. */
2572 sm_table[i].link_once = 1;
2573 goto next;
2574 } else {
2575 goto found;
2579 /* not found: create new section */
2580 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
2581 /* take as much info as possible from the section. sh_link and
2582 sh_info will be updated later */
2583 s->sh_addralign = sh->sh_addralign;
2584 s->sh_entsize = sh->sh_entsize;
2585 sm_table[i].new_section = 1;
2586 found:
2587 if (sh->sh_type != s->sh_type) {
2588 tcc_error_noabort("invalid section type");
2589 goto fail;
2592 /* align start of section */
2593 offset = s->data_offset;
2595 if (0 == strcmp(sh_name, ".stab")) {
2596 stab_index = i;
2597 goto no_align;
2599 if (0 == strcmp(sh_name, ".stabstr")) {
2600 stabstr_index = i;
2601 goto no_align;
2604 size = sh->sh_addralign - 1;
2605 offset = (offset + size) & ~size;
2606 if (sh->sh_addralign > s->sh_addralign)
2607 s->sh_addralign = sh->sh_addralign;
2608 s->data_offset = offset;
2609 no_align:
2610 sm_table[i].offset = offset;
2611 sm_table[i].s = s;
2612 /* concatenate sections */
2613 size = sh->sh_size;
2614 if (sh->sh_type != SHT_NOBITS) {
2615 unsigned char *ptr;
2616 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2617 ptr = section_ptr_add(s, size);
2618 read(fd, ptr, size);
2619 } else {
2620 s->data_offset += size;
2622 next: ;
2625 /* gr relocate stab strings */
2626 if (stab_index && stabstr_index) {
2627 Stab_Sym *a, *b;
2628 unsigned o;
2629 s = sm_table[stab_index].s;
2630 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2631 b = (Stab_Sym *)(s->data + s->data_offset);
2632 o = sm_table[stabstr_index].offset;
2633 while (a < b)
2634 a->n_strx += o, a++;
2637 /* second short pass to update sh_link and sh_info fields of new
2638 sections */
2639 for(i = 1; i < ehdr.e_shnum; i++) {
2640 s = sm_table[i].s;
2641 if (!s || !sm_table[i].new_section)
2642 continue;
2643 sh = &shdr[i];
2644 if (sh->sh_link > 0)
2645 s->link = sm_table[sh->sh_link].s;
2646 if (sh->sh_type == SHT_RELX) {
2647 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2648 /* update backward link */
2649 s1->sections[s->sh_info]->reloc = s;
2652 sm = sm_table;
2654 /* resolve symbols */
2655 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2657 sym = symtab + 1;
2658 for(i = 1; i < nb_syms; i++, sym++) {
2659 if (sym->st_shndx != SHN_UNDEF &&
2660 sym->st_shndx < SHN_LORESERVE) {
2661 sm = &sm_table[sym->st_shndx];
2662 if (sm->link_once) {
2663 /* if a symbol is in a link once section, we use the
2664 already defined symbol. It is very important to get
2665 correct relocations */
2666 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2667 name = (char *) strtab + sym->st_name;
2668 sym_index = find_elf_sym(symtab_section, name);
2669 if (sym_index)
2670 old_to_new_syms[i] = sym_index;
2672 continue;
2674 /* if no corresponding section added, no need to add symbol */
2675 if (!sm->s)
2676 continue;
2677 /* convert section number */
2678 sym->st_shndx = sm->s->sh_num;
2679 /* offset value */
2680 sym->st_value += sm->offset;
2682 /* add symbol */
2683 name = (char *) strtab + sym->st_name;
2684 sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
2685 sym->st_info, sym->st_other,
2686 sym->st_shndx, name);
2687 old_to_new_syms[i] = sym_index;
2690 /* third pass to patch relocation entries */
2691 for(i = 1; i < ehdr.e_shnum; i++) {
2692 s = sm_table[i].s;
2693 if (!s)
2694 continue;
2695 sh = &shdr[i];
2696 offset = sm_table[i].offset;
2697 switch(s->sh_type) {
2698 case SHT_RELX:
2699 /* take relocation offset information */
2700 offseti = sm_table[sh->sh_info].offset;
2701 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2702 int type;
2703 unsigned sym_index;
2704 /* convert symbol index */
2705 type = ELFW(R_TYPE)(rel->r_info);
2706 sym_index = ELFW(R_SYM)(rel->r_info);
2707 /* NOTE: only one symtab assumed */
2708 if (sym_index >= nb_syms)
2709 goto invalid_reloc;
2710 sym_index = old_to_new_syms[sym_index];
2711 /* ignore link_once in rel section. */
2712 if (!sym_index && !sm->link_once
2713 #ifdef TCC_TARGET_ARM
2714 && type != R_ARM_V4BX
2715 #endif
2717 invalid_reloc:
2718 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2719 i, strsec + sh->sh_name, rel->r_offset);
2720 goto fail;
2722 rel->r_info = ELFW(R_INFO)(sym_index, type);
2723 /* offset the relocation offset */
2724 rel->r_offset += offseti;
2725 #ifdef TCC_TARGET_ARM
2726 /* Jumps and branches from a Thumb code to a PLT entry need
2727 special handling since PLT entries are ARM code.
2728 Unconditional bl instructions referencing PLT entries are
2729 handled by converting these instructions into blx
2730 instructions. Other case of instructions referencing a PLT
2731 entry require to add a Thumb stub before the PLT entry to
2732 switch to ARM mode. We set bit plt_thumb_stub of the
2733 attribute of a symbol to indicate such a case. */
2734 if (type == R_ARM_THM_JUMP24)
2735 alloc_sym_attr(s1, sym_index)->plt_thumb_stub = 1;
2736 #endif
2738 break;
2739 default:
2740 break;
2744 ret = 0;
2745 the_end:
2746 tcc_free(symtab);
2747 tcc_free(strtab);
2748 tcc_free(old_to_new_syms);
2749 tcc_free(sm_table);
2750 tcc_free(strsec);
2751 tcc_free(shdr);
2752 return ret;
2755 typedef struct ArchiveHeader {
2756 char ar_name[16]; /* name of this member */
2757 char ar_date[12]; /* file mtime */
2758 char ar_uid[6]; /* owner uid; printed as decimal */
2759 char ar_gid[6]; /* owner gid; printed as decimal */
2760 char ar_mode[8]; /* file mode, printed as octal */
2761 char ar_size[10]; /* file size, printed as decimal */
2762 char ar_fmag[2]; /* should contain ARFMAG */
2763 } ArchiveHeader;
2765 static int get_be32(const uint8_t *b)
2767 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2770 static long get_be64(const uint8_t *b)
2772 long long ret = get_be32(b);
2773 ret = (ret << 32) | (unsigned)get_be32(b+4);
2774 return (long)ret;
2777 /* load only the objects which resolve undefined symbols */
2778 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
2780 long i, bound, nsyms, sym_index, off, ret;
2781 uint8_t *data;
2782 const char *ar_names, *p;
2783 const uint8_t *ar_index;
2784 ElfW(Sym) *sym;
2786 data = tcc_malloc(size);
2787 if (read(fd, data, size) != size)
2788 goto fail;
2789 nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
2790 ar_index = data + entrysize;
2791 ar_names = (char *) ar_index + nsyms * entrysize;
2793 do {
2794 bound = 0;
2795 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2796 sym_index = find_elf_sym(symtab_section, p);
2797 if(sym_index) {
2798 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2799 if(sym->st_shndx == SHN_UNDEF) {
2800 off = (entrysize == 4
2801 ? get_be32(ar_index + i * 4)
2802 : get_be64(ar_index + i * 8))
2803 + sizeof(ArchiveHeader);
2804 ++bound;
2805 if(tcc_load_object_file(s1, fd, off) < 0) {
2806 fail:
2807 ret = -1;
2808 goto the_end;
2813 } while(bound);
2814 ret = 0;
2815 the_end:
2816 tcc_free(data);
2817 return ret;
2820 /* load a '.a' file */
2821 ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
2823 ArchiveHeader hdr;
2824 char ar_size[11];
2825 char ar_name[17];
2826 char magic[8];
2827 int size, len, i;
2828 unsigned long file_offset;
2830 /* skip magic which was already checked */
2831 read(fd, magic, sizeof(magic));
2833 for(;;) {
2834 len = read(fd, &hdr, sizeof(hdr));
2835 if (len == 0)
2836 break;
2837 if (len != sizeof(hdr)) {
2838 tcc_error_noabort("invalid archive");
2839 return -1;
2841 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2842 ar_size[sizeof(hdr.ar_size)] = '\0';
2843 size = strtol(ar_size, NULL, 0);
2844 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2845 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2846 if (ar_name[i] != ' ')
2847 break;
2849 ar_name[i + 1] = '\0';
2850 file_offset = lseek(fd, 0, SEEK_CUR);
2851 /* align to even */
2852 size = (size + 1) & ~1;
2853 if (!strcmp(ar_name, "/")) {
2854 /* coff symbol table : we handle it */
2855 if(s1->alacarte_link)
2856 return tcc_load_alacarte(s1, fd, size, 4);
2857 } else if (!strcmp(ar_name, "/SYM64/")) {
2858 if(s1->alacarte_link)
2859 return tcc_load_alacarte(s1, fd, size, 8);
2860 } else {
2861 ElfW(Ehdr) ehdr;
2862 if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
2863 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2864 return -1;
2867 lseek(fd, file_offset + size, SEEK_SET);
2869 return 0;
2872 #ifndef TCC_TARGET_PE
2873 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2874 is referenced by the user (so it should be added as DT_NEEDED in
2875 the generated ELF file) */
2876 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2878 ElfW(Ehdr) ehdr;
2879 ElfW(Shdr) *shdr, *sh, *sh1;
2880 int i, j, nb_syms, nb_dts, sym_bind, ret;
2881 ElfW(Sym) *sym, *dynsym;
2882 ElfW(Dyn) *dt, *dynamic;
2883 unsigned char *dynstr;
2884 const char *name, *soname;
2885 DLLReference *dllref;
2887 read(fd, &ehdr, sizeof(ehdr));
2889 /* test CPU specific stuff */
2890 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2891 ehdr.e_machine != EM_TCC_TARGET) {
2892 tcc_error_noabort("bad architecture");
2893 return -1;
2896 /* read sections */
2897 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2899 /* load dynamic section and dynamic symbols */
2900 nb_syms = 0;
2901 nb_dts = 0;
2902 dynamic = NULL;
2903 dynsym = NULL; /* avoid warning */
2904 dynstr = NULL; /* avoid warning */
2905 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2906 switch(sh->sh_type) {
2907 case SHT_DYNAMIC:
2908 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2909 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2910 break;
2911 case SHT_DYNSYM:
2912 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2913 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2914 sh1 = &shdr[sh->sh_link];
2915 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2916 break;
2917 default:
2918 break;
2922 /* compute the real library name */
2923 soname = tcc_basename(filename);
2925 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2926 if (dt->d_tag == DT_SONAME) {
2927 soname = (char *) dynstr + dt->d_un.d_val;
2931 /* if the dll is already loaded, do not load it */
2932 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2933 dllref = s1->loaded_dlls[i];
2934 if (!strcmp(soname, dllref->name)) {
2935 /* but update level if needed */
2936 if (level < dllref->level)
2937 dllref->level = level;
2938 ret = 0;
2939 goto the_end;
2943 /* add the dll and its level */
2944 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2945 dllref->level = level;
2946 strcpy(dllref->name, soname);
2947 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2949 /* add dynamic symbols in dynsym_section */
2950 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2951 sym_bind = ELFW(ST_BIND)(sym->st_info);
2952 if (sym_bind == STB_LOCAL)
2953 continue;
2954 name = (char *) dynstr + sym->st_name;
2955 set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2956 sym->st_info, sym->st_other, sym->st_shndx, name);
2959 /* load all referenced DLLs */
2960 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2961 switch(dt->d_tag) {
2962 case DT_NEEDED:
2963 name = (char *) dynstr + dt->d_un.d_val;
2964 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2965 dllref = s1->loaded_dlls[j];
2966 if (!strcmp(name, dllref->name))
2967 goto already_loaded;
2969 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2970 tcc_error_noabort("referenced dll '%s' not found", name);
2971 ret = -1;
2972 goto the_end;
2974 already_loaded:
2975 break;
2978 ret = 0;
2979 the_end:
2980 tcc_free(dynstr);
2981 tcc_free(dynsym);
2982 tcc_free(dynamic);
2983 tcc_free(shdr);
2984 return ret;
2987 #define LD_TOK_NAME 256
2988 #define LD_TOK_EOF (-1)
2990 /* return next ld script token */
2991 static int ld_next(TCCState *s1, char *name, int name_size)
2993 int c;
2994 char *q;
2996 redo:
2997 switch(ch) {
2998 case ' ':
2999 case '\t':
3000 case '\f':
3001 case '\v':
3002 case '\r':
3003 case '\n':
3004 inp();
3005 goto redo;
3006 case '/':
3007 minp();
3008 if (ch == '*') {
3009 file->buf_ptr = parse_comment(file->buf_ptr);
3010 ch = file->buf_ptr[0];
3011 goto redo;
3012 } else {
3013 q = name;
3014 *q++ = '/';
3015 goto parse_name;
3017 break;
3018 case '\\':
3019 ch = handle_eob();
3020 if (ch != '\\')
3021 goto redo;
3022 /* fall through */
3023 /* case 'a' ... 'z': */
3024 case 'a':
3025 case 'b':
3026 case 'c':
3027 case 'd':
3028 case 'e':
3029 case 'f':
3030 case 'g':
3031 case 'h':
3032 case 'i':
3033 case 'j':
3034 case 'k':
3035 case 'l':
3036 case 'm':
3037 case 'n':
3038 case 'o':
3039 case 'p':
3040 case 'q':
3041 case 'r':
3042 case 's':
3043 case 't':
3044 case 'u':
3045 case 'v':
3046 case 'w':
3047 case 'x':
3048 case 'y':
3049 case 'z':
3050 /* case 'A' ... 'z': */
3051 case 'A':
3052 case 'B':
3053 case 'C':
3054 case 'D':
3055 case 'E':
3056 case 'F':
3057 case 'G':
3058 case 'H':
3059 case 'I':
3060 case 'J':
3061 case 'K':
3062 case 'L':
3063 case 'M':
3064 case 'N':
3065 case 'O':
3066 case 'P':
3067 case 'Q':
3068 case 'R':
3069 case 'S':
3070 case 'T':
3071 case 'U':
3072 case 'V':
3073 case 'W':
3074 case 'X':
3075 case 'Y':
3076 case 'Z':
3077 case '_':
3078 case '.':
3079 case '$':
3080 case '~':
3081 q = name;
3082 parse_name:
3083 for(;;) {
3084 if (!((ch >= 'a' && ch <= 'z') ||
3085 (ch >= 'A' && ch <= 'Z') ||
3086 (ch >= '0' && ch <= '9') ||
3087 strchr("/.-_+=$:\\,~", ch)))
3088 break;
3089 if ((q - name) < name_size - 1) {
3090 *q++ = ch;
3092 minp();
3094 *q = '\0';
3095 c = LD_TOK_NAME;
3096 break;
3097 case CH_EOF:
3098 c = LD_TOK_EOF;
3099 break;
3100 default:
3101 c = ch;
3102 inp();
3103 break;
3105 return c;
3108 static int ld_add_file(TCCState *s1, const char filename[])
3110 int ret;
3112 ret = tcc_add_file_internal(s1, filename, AFF_TYPE_BIN);
3113 if (ret)
3114 ret = tcc_add_dll(s1, filename, 0);
3115 return ret;
3118 static inline int new_undef_syms(void)
3120 int ret = 0;
3121 ret = new_undef_sym;
3122 new_undef_sym = 0;
3123 return ret;
3126 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3128 char filename[1024], libname[1024];
3129 int t, group, nblibs = 0, ret = 0;
3130 char **libs = NULL;
3132 group = !strcmp(cmd, "GROUP");
3133 if (!as_needed)
3134 new_undef_syms();
3135 t = ld_next(s1, filename, sizeof(filename));
3136 if (t != '(')
3137 expect("(");
3138 t = ld_next(s1, filename, sizeof(filename));
3139 for(;;) {
3140 libname[0] = '\0';
3141 if (t == LD_TOK_EOF) {
3142 tcc_error_noabort("unexpected end of file");
3143 ret = -1;
3144 goto lib_parse_error;
3145 } else if (t == ')') {
3146 break;
3147 } else if (t == '-') {
3148 t = ld_next(s1, filename, sizeof(filename));
3149 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3150 tcc_error_noabort("library name expected");
3151 ret = -1;
3152 goto lib_parse_error;
3154 pstrcpy(libname, sizeof libname, &filename[1]);
3155 if (s1->static_link) {
3156 snprintf(filename, sizeof filename, "lib%s.a", libname);
3157 } else {
3158 snprintf(filename, sizeof filename, "lib%s.so", libname);
3160 } else if (t != LD_TOK_NAME) {
3161 tcc_error_noabort("filename expected");
3162 ret = -1;
3163 goto lib_parse_error;
3165 if (!strcmp(filename, "AS_NEEDED")) {
3166 ret = ld_add_file_list(s1, cmd, 1);
3167 if (ret)
3168 goto lib_parse_error;
3169 } else {
3170 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3171 if (!as_needed) {
3172 ret = ld_add_file(s1, filename);
3173 if (ret)
3174 goto lib_parse_error;
3175 if (group) {
3176 /* Add the filename *and* the libname to avoid future conversions */
3177 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename));
3178 if (libname[0] != '\0')
3179 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname));
3183 t = ld_next(s1, filename, sizeof(filename));
3184 if (t == ',') {
3185 t = ld_next(s1, filename, sizeof(filename));
3188 if (group && !as_needed) {
3189 while (new_undef_syms()) {
3190 int i;
3192 for (i = 0; i < nblibs; i ++)
3193 ld_add_file(s1, libs[i]);
3196 lib_parse_error:
3197 dynarray_reset(&libs, &nblibs);
3198 return ret;
3201 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3202 files */
3203 ST_FUNC int tcc_load_ldscript(TCCState *s1)
3205 char cmd[64];
3206 char filename[1024];
3207 int t, ret;
3209 ch = handle_eob();
3210 for(;;) {
3211 t = ld_next(s1, cmd, sizeof(cmd));
3212 if (t == LD_TOK_EOF)
3213 return 0;
3214 else if (t != LD_TOK_NAME)
3215 return -1;
3216 if (!strcmp(cmd, "INPUT") ||
3217 !strcmp(cmd, "GROUP")) {
3218 ret = ld_add_file_list(s1, cmd, 0);
3219 if (ret)
3220 return ret;
3221 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3222 !strcmp(cmd, "TARGET")) {
3223 /* ignore some commands */
3224 t = ld_next(s1, cmd, sizeof(cmd));
3225 if (t != '(')
3226 expect("(");
3227 for(;;) {
3228 t = ld_next(s1, filename, sizeof(filename));
3229 if (t == LD_TOK_EOF) {
3230 tcc_error_noabort("unexpected end of file");
3231 return -1;
3232 } else if (t == ')') {
3233 break;
3236 } else {
3237 return -1;
3240 return 0;
3242 #endif /* !TCC_TARGET_PE */