Backslash was missing after reindentation to let code be < 80 col.
[tinycc.git] / tccelf.c
blob8fe40c9ffe234eac6d02e9b917990d53635e246c
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 static void free_section(Section *s)
74 tcc_free(s->data);
77 ST_FUNC void tccelf_delete(TCCState *s1)
79 int i;
81 /* free all sections */
82 for(i = 1; i < s1->nb_sections; i++)
83 free_section(s1->sections[i]);
84 dynarray_reset(&s1->sections, &s1->nb_sections);
86 for(i = 0; i < s1->nb_priv_sections; i++)
87 free_section(s1->priv_sections[i]);
88 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
90 /* free any loaded DLLs */
91 #ifdef TCC_IS_NATIVE
92 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
93 DLLReference *ref = s1->loaded_dlls[i];
94 if ( ref->handle )
95 # ifdef _WIN32
96 FreeLibrary((HMODULE)ref->handle);
97 # else
98 dlclose(ref->handle);
99 # endif
101 #endif
102 /* free loaded dlls array */
103 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
106 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
108 Section *sec;
110 sec = tcc_mallocz(sizeof(Section) + strlen(name));
111 strcpy(sec->name, name);
112 sec->sh_type = sh_type;
113 sec->sh_flags = sh_flags;
114 switch(sh_type) {
115 case SHT_HASH:
116 case SHT_REL:
117 case SHT_RELA:
118 case SHT_DYNSYM:
119 case SHT_SYMTAB:
120 case SHT_DYNAMIC:
121 sec->sh_addralign = 4;
122 break;
123 case SHT_STRTAB:
124 sec->sh_addralign = 1;
125 break;
126 default:
127 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default aligment */
128 break;
131 if (sh_flags & SHF_PRIVATE) {
132 dynarray_add((void ***)&s1->priv_sections, &s1->nb_priv_sections, sec);
133 } else {
134 sec->sh_num = s1->nb_sections;
135 dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
138 return sec;
141 /* realloc section and set its content to zero */
142 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
144 unsigned long size;
145 unsigned char *data;
147 size = sec->data_allocated;
148 if (size == 0)
149 size = 1;
150 while (size < new_size)
151 size = size * 2;
152 data = tcc_realloc(sec->data, size);
153 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
154 sec->data = data;
155 sec->data_allocated = size;
158 /* reserve at least 'size' bytes in section 'sec' from
159 sec->data_offset. */
160 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
162 size_t offset, offset1;
164 offset = sec->data_offset;
165 offset1 = offset + size;
166 if (offset1 > sec->data_allocated)
167 section_realloc(sec, offset1);
168 sec->data_offset = offset1;
169 return sec->data + offset;
172 /* reserve at least 'size' bytes from section start */
173 ST_FUNC void section_reserve(Section *sec, unsigned long size)
175 if (size > sec->data_allocated)
176 section_realloc(sec, size);
177 if (size > sec->data_offset)
178 sec->data_offset = size;
181 /* return a reference to a section, and create it if it does not
182 exists */
183 ST_FUNC Section *find_section(TCCState *s1, const char *name)
185 Section *sec;
186 int i;
187 for(i = 1; i < s1->nb_sections; i++) {
188 sec = s1->sections[i];
189 if (!strcmp(name, sec->name))
190 return sec;
192 /* sections are created as PROGBITS */
193 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
196 /* ------------------------------------------------------------------------- */
198 ST_FUNC int put_elf_str(Section *s, const char *sym)
200 int offset, len;
201 char *ptr;
203 len = strlen(sym) + 1;
204 offset = s->data_offset;
205 ptr = section_ptr_add(s, len);
206 memcpy(ptr, sym, len);
207 return offset;
210 /* elf symbol hashing function */
211 static unsigned long elf_hash(const unsigned char *name)
213 unsigned long h = 0, g;
215 while (*name) {
216 h = (h << 4) + *name++;
217 g = h & 0xf0000000;
218 if (g)
219 h ^= g >> 24;
220 h &= ~g;
222 return h;
225 /* rebuild hash table of section s */
226 /* NOTE: we do factorize the hash table code to go faster */
227 static void rebuild_hash(Section *s, unsigned int nb_buckets)
229 ElfW(Sym) *sym;
230 int *ptr, *hash, nb_syms, sym_index, h;
231 unsigned char *strtab;
233 strtab = s->link->data;
234 nb_syms = s->data_offset / sizeof(ElfW(Sym));
236 s->hash->data_offset = 0;
237 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
238 ptr[0] = nb_buckets;
239 ptr[1] = nb_syms;
240 ptr += 2;
241 hash = ptr;
242 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
243 ptr += nb_buckets + 1;
245 sym = (ElfW(Sym) *)s->data + 1;
246 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
247 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
248 h = elf_hash(strtab + sym->st_name) % nb_buckets;
249 *ptr = hash[h];
250 hash[h] = sym_index;
251 } else {
252 *ptr = 0;
254 ptr++;
255 sym++;
259 /* return the symbol number */
260 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
261 int info, int other, int shndx, const char *name)
263 int name_offset, sym_index;
264 int nbuckets, h;
265 ElfW(Sym) *sym;
266 Section *hs;
268 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
269 if (name)
270 name_offset = put_elf_str(s->link, name);
271 else
272 name_offset = 0;
273 /* XXX: endianness */
274 sym->st_name = name_offset;
275 sym->st_value = value;
276 sym->st_size = size;
277 sym->st_info = info;
278 sym->st_other = other;
279 sym->st_shndx = shndx;
280 sym_index = sym - (ElfW(Sym) *)s->data;
281 hs = s->hash;
282 if (hs) {
283 int *ptr, *base;
284 ptr = section_ptr_add(hs, sizeof(int));
285 base = (int *)hs->data;
286 /* only add global or weak symbols */
287 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
288 /* add another hashing entry */
289 nbuckets = base[0];
290 h = elf_hash((unsigned char *) name) % nbuckets;
291 *ptr = base[2 + h];
292 base[2 + h] = sym_index;
293 base[1]++;
294 /* we resize the hash table */
295 hs->nb_hashed_syms++;
296 if (hs->nb_hashed_syms > 2 * nbuckets) {
297 rebuild_hash(s, 2 * nbuckets);
299 } else {
300 *ptr = 0;
301 base[1]++;
304 return sym_index;
307 /* find global ELF symbol 'name' and return its index. Return 0 if not
308 found. */
309 ST_FUNC int find_elf_sym(Section *s, const char *name)
311 ElfW(Sym) *sym;
312 Section *hs;
313 int nbuckets, sym_index, h;
314 const char *name1;
316 hs = s->hash;
317 if (!hs)
318 return 0;
319 nbuckets = ((int *)hs->data)[0];
320 h = elf_hash((unsigned char *) name) % nbuckets;
321 sym_index = ((int *)hs->data)[2 + h];
322 while (sym_index != 0) {
323 sym = &((ElfW(Sym) *)s->data)[sym_index];
324 name1 = (char *) s->link->data + sym->st_name;
325 if (!strcmp(name, name1))
326 return sym_index;
327 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
329 return 0;
332 /* return elf symbol value, signal error if 'err' is nonzero */
333 ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err)
335 int sym_index;
336 ElfW(Sym) *sym;
338 sym_index = find_elf_sym(s->symtab, name);
339 sym = &((ElfW(Sym) *)s->symtab->data)[sym_index];
340 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
341 if (err)
342 tcc_error("%s not defined", name);
343 return 0;
345 return sym->st_value;
348 /* return elf symbol value */
349 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
351 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0);
354 #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
355 /* return elf symbol value or error */
356 ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
358 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1);
360 #endif
362 /* add an elf symbol : check if it is already defined and patch
363 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
364 ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size,
365 int info, int other, int sh_num, const char *name)
367 ElfW(Sym) *esym;
368 int sym_bind, sym_index, sym_type, esym_bind;
369 unsigned char sym_vis, esym_vis, new_vis;
371 sym_bind = ELFW(ST_BIND)(info);
372 sym_type = ELFW(ST_TYPE)(info);
373 sym_vis = ELFW(ST_VISIBILITY)(other);
375 if (sym_bind != STB_LOCAL) {
376 /* we search global or weak symbols */
377 sym_index = find_elf_sym(s, name);
378 if (!sym_index)
379 goto do_def;
380 esym = &((ElfW(Sym) *)s->data)[sym_index];
381 if (esym->st_shndx != SHN_UNDEF) {
382 esym_bind = ELFW(ST_BIND)(esym->st_info);
383 /* propagate the most constraining visibility */
384 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
385 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
386 if (esym_vis == STV_DEFAULT) {
387 new_vis = sym_vis;
388 } else if (sym_vis == STV_DEFAULT) {
389 new_vis = esym_vis;
390 } else {
391 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
393 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
394 | new_vis;
395 other = esym->st_other; /* in case we have to patch esym */
396 if (sh_num == SHN_UNDEF) {
397 /* ignore adding of undefined symbol if the
398 corresponding symbol is already defined */
399 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
400 /* global overrides weak, so patch */
401 goto do_patch;
402 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
403 /* weak is ignored if already global */
404 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
405 /* keep first-found weak definition, ignore subsequents */
406 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
407 /* ignore hidden symbols after */
408 } else if ((esym->st_shndx == SHN_COMMON
409 || esym->st_shndx == bss_section->sh_num)
410 && (sh_num < SHN_LORESERVE
411 && sh_num != bss_section->sh_num)) {
412 /* data symbol gets precedence over common/bss */
413 goto do_patch;
414 } else if (sh_num == SHN_COMMON || sh_num == bss_section->sh_num) {
415 /* data symbol keeps precedence over common/bss */
416 } else if (s == tcc_state->dynsymtab_section) {
417 /* we accept that two DLL define the same symbol */
418 } else {
419 #if 0
420 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
421 sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
422 #endif
423 tcc_error_noabort("'%s' defined twice", name);
425 } else {
426 do_patch:
427 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
428 esym->st_shndx = sh_num;
429 new_undef_sym = 1;
430 esym->st_value = value;
431 esym->st_size = size;
432 esym->st_other = other;
434 } else {
435 do_def:
436 sym_index = put_elf_sym(s, value, size,
437 ELFW(ST_INFO)(sym_bind, sym_type), other,
438 sh_num, name);
440 return sym_index;
443 /* put relocation */
444 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
445 int type, int symbol, addr_t addend)
447 char buf[256];
448 Section *sr;
449 ElfW_Rel *rel;
451 sr = s->reloc;
452 if (!sr) {
453 /* if no relocation section, create it */
454 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
455 /* if the symtab is allocated, then we consider the relocation
456 are also */
457 sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
458 sr->sh_entsize = sizeof(ElfW_Rel);
459 sr->link = symtab;
460 sr->sh_info = s->sh_num;
461 s->reloc = sr;
463 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
464 rel->r_offset = offset;
465 rel->r_info = ELFW(R_INFO)(symbol, type);
466 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
467 rel->r_addend = addend;
468 #else
469 if (addend)
470 tcc_error("non-zero addend on REL architecture");
471 #endif
474 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
475 int type, int symbol)
477 put_elf_reloca(symtab, s, offset, type, symbol, 0);
480 /* put stab debug information */
482 ST_FUNC void put_stabs(const char *str, int type, int other, int desc,
483 unsigned long value)
485 Stab_Sym *sym;
487 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
488 if (str) {
489 sym->n_strx = put_elf_str(stabstr_section, str);
490 } else {
491 sym->n_strx = 0;
493 sym->n_type = type;
494 sym->n_other = other;
495 sym->n_desc = desc;
496 sym->n_value = value;
499 ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc,
500 unsigned long value, Section *sec, int sym_index)
502 put_stabs(str, type, other, desc, value);
503 put_elf_reloc(symtab_section, stab_section,
504 stab_section->data_offset - sizeof(unsigned int),
505 R_DATA_32, sym_index);
508 ST_FUNC void put_stabn(int type, int other, int desc, int value)
510 put_stabs(NULL, type, other, desc, value);
513 ST_FUNC void put_stabd(int type, int other, int desc)
515 put_stabs(NULL, type, other, desc, 0);
518 /* Browse each elem of type <type> in section <sec> starting at elem <startoff>
519 using variable <elem> */
520 #define for_each_elem(sec, startoff, elem, type) \
521 for (elem = (type *) sec->data + startoff; \
522 elem < (type *) (sec->data + sec->data_offset); elem++)
524 /* In an ELF file symbol table, the local symbols must appear below
525 the global and weak ones. Since TCC cannot sort it while generating
526 the code, we must do it after. All the relocation tables are also
527 modified to take into account the symbol table sorting */
528 static void sort_syms(TCCState *s1, Section *s)
530 int *old_to_new_syms;
531 ElfW(Sym) *new_syms;
532 int nb_syms, i;
533 ElfW(Sym) *p, *q;
534 ElfW_Rel *rel;
535 Section *sr;
536 int type, sym_index;
538 nb_syms = s->data_offset / sizeof(ElfW(Sym));
539 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
540 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
542 /* first pass for local symbols */
543 p = (ElfW(Sym) *)s->data;
544 q = new_syms;
545 for(i = 0; i < nb_syms; i++) {
546 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
547 old_to_new_syms[i] = q - new_syms;
548 *q++ = *p;
550 p++;
552 /* save the number of local symbols in section header */
553 s->sh_info = q - new_syms;
555 /* then second pass for non local symbols */
556 p = (ElfW(Sym) *)s->data;
557 for(i = 0; i < nb_syms; i++) {
558 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
559 old_to_new_syms[i] = q - new_syms;
560 *q++ = *p;
562 p++;
565 /* we copy the new symbols to the old */
566 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
567 tcc_free(new_syms);
569 /* now we modify all the relocations */
570 for(i = 1; i < s1->nb_sections; i++) {
571 sr = s1->sections[i];
572 if (sr->sh_type == SHT_RELX && sr->link == s) {
573 for_each_elem(sr, 0, rel, ElfW_Rel) {
574 sym_index = ELFW(R_SYM)(rel->r_info);
575 type = ELFW(R_TYPE)(rel->r_info);
576 sym_index = old_to_new_syms[sym_index];
577 rel->r_info = ELFW(R_INFO)(sym_index, type);
582 tcc_free(old_to_new_syms);
585 /* relocate common symbols in the .bss section */
586 ST_FUNC void relocate_common_syms(void)
588 ElfW(Sym) *sym;
589 unsigned long offset, align;
591 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
592 if (sym->st_shndx == SHN_COMMON) {
593 /* align symbol */
594 align = sym->st_value;
595 offset = bss_section->data_offset;
596 offset = (offset + align - 1) & -align;
597 sym->st_value = offset;
598 sym->st_shndx = bss_section->sh_num;
599 offset += sym->st_size;
600 bss_section->data_offset = offset;
605 /* relocate symbol table, resolve undefined symbols if do_resolve is
606 true and output error if undefined symbol. */
607 ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
609 ElfW(Sym) *sym, *esym;
610 int sym_bind, sh_num, sym_index;
611 const char *name;
613 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
614 sh_num = sym->st_shndx;
615 if (sh_num == SHN_UNDEF) {
616 name = (char *) strtab_section->data + sym->st_name;
617 /* Use ld.so to resolve symbol for us (for tcc -run) */
618 if (do_resolve) {
619 #if defined TCC_IS_NATIVE && !defined _WIN32
620 void *addr;
621 name = (char *) symtab_section->link->data + sym->st_name;
622 addr = dlsym(RTLD_DEFAULT, name);
623 if (addr) {
624 sym->st_value = (addr_t)addr;
625 #ifdef DEBUG_RELOC
626 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
627 #endif
628 goto found;
630 #endif
631 } else if (s1->dynsym) {
632 /* if dynamic symbol exist, then use it */
633 sym_index = find_elf_sym(s1->dynsym, name);
634 if (sym_index) {
635 esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
636 sym->st_value = esym->st_value;
637 goto found;
640 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
641 it */
642 if (!strcmp(name, "_fp_hw"))
643 goto found;
644 /* only weak symbols are accepted to be undefined. Their
645 value is zero */
646 sym_bind = ELFW(ST_BIND)(sym->st_info);
647 if (sym_bind == STB_WEAK) {
648 sym->st_value = 0;
649 } else {
650 tcc_error_noabort("undefined symbol '%s'", name);
652 } else if (sh_num < SHN_LORESERVE) {
653 /* add section base */
654 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
656 found: ;
660 /* relocate a given section (CPU dependent) by applying the relocations
661 in the associated relocation section */
662 ST_FUNC void relocate_section(TCCState *s1, Section *s)
664 Section *sr = s->reloc;
665 ElfW_Rel *rel;
666 ElfW(Sym) *sym;
667 int type, sym_index;
668 unsigned char *ptr;
669 addr_t val, addr;
670 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
671 ElfW_Rel *qrel = (ElfW_Rel *) sr->data; /* ptr to next reloc entry reused */
672 int esym_index;
673 #endif
675 for_each_elem(sr, 0, rel, ElfW_Rel) {
676 ptr = s->data + rel->r_offset;
678 sym_index = ELFW(R_SYM)(rel->r_info);
679 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
680 val = sym->st_value;
681 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
682 val += rel->r_addend;
683 #endif
684 type = ELFW(R_TYPE)(rel->r_info);
685 addr = s->sh_addr + rel->r_offset;
687 /* CPU specific */
688 switch(type) {
689 #if defined(TCC_TARGET_I386)
690 case R_386_32:
691 if (s1->output_type == TCC_OUTPUT_DLL) {
692 esym_index = s1->symtab_to_dynsym[sym_index];
693 qrel->r_offset = rel->r_offset;
694 if (esym_index) {
695 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
696 qrel++;
697 break;
698 } else {
699 qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
700 qrel++;
703 write32le(ptr, read32le(ptr) + val);
704 break;
705 case R_386_PC32:
706 if (s1->output_type == TCC_OUTPUT_DLL) {
707 /* DLL relocation */
708 esym_index = s1->symtab_to_dynsym[sym_index];
709 if (esym_index) {
710 qrel->r_offset = rel->r_offset;
711 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
712 qrel++;
713 break;
716 write32le(ptr, read32le(ptr) + val - addr);
717 break;
718 case R_386_PLT32:
719 write32le(ptr, read32le(ptr) + val - addr);
720 break;
721 case R_386_GLOB_DAT:
722 case R_386_JMP_SLOT:
723 write32le(ptr, val);
724 break;
725 case R_386_GOTPC:
726 write32le(ptr, read32le(ptr) + s1->got->sh_addr - addr);
727 break;
728 case R_386_GOTOFF:
729 write32le(ptr, read32le(ptr) + val - s1->got->sh_addr);
730 break;
731 case R_386_GOT32:
732 case R_386_GOT32X:
733 /* we load the got offset */
734 write32le(ptr, read32le(ptr) + s1->sym_attrs[sym_index].got_offset);
735 break;
736 case R_386_16:
737 if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {
738 output_file:
739 tcc_error("can only produce 16-bit binary files");
741 write16le(ptr, read16le(ptr) + val);
742 break;
743 case R_386_PC16:
744 if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY)
745 goto output_file;
746 write16le(ptr, read16le(ptr) + val - addr);
747 break;
749 #ifdef TCC_TARGET_PE
750 case R_386_RELATIVE: /* handled in pe_relocate_rva() */
751 break;
752 #endif
753 case R_386_COPY:
754 /* This reloction must copy initialized data from the library
755 to the program .bss segment. Currently made like for ARM
756 (to remove noise of defaukt case). Is this true?
758 break;
760 default:
761 fprintf(stderr,"FIXME: handle reloc type %d at %x [%p] to %x\n",
762 type, (unsigned)addr, ptr, (unsigned)val);
763 break;
764 #elif defined(TCC_TARGET_ARM)
765 case R_ARM_PC24:
766 case R_ARM_CALL:
767 case R_ARM_JUMP24:
768 case R_ARM_PLT32:
770 int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko;
771 x = (*(int *) ptr) & 0xffffff;
772 if (sym->st_shndx == SHN_UNDEF)
773 val = s1->plt->sh_addr;
774 #ifdef DEBUG_RELOC
775 printf ("reloc %d: x=0x%x val=0x%x ", type, x, val);
776 #endif
777 (*(int *)ptr) &= 0xff000000;
778 if (x & 0x800000)
779 x -= 0x1000000;
780 x <<= 2;
781 blx_avail = (TCC_ARM_VERSION >= 5);
782 is_thumb = val & 1;
783 is_bl = (*(unsigned *) ptr) >> 24 == 0xeb;
784 is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl));
785 x += val - addr;
786 #ifdef DEBUG_RELOC
787 printf (" newx=0x%x name=%s\n", x,
788 (char *) symtab_section->link->data + sym->st_name);
789 #endif
790 h = x & 2;
791 th_ko = (x & 3) && (!blx_avail || !is_call);
792 if (th_ko || x >= 0x2000000 || x < -0x2000000)
793 tcc_error("can't relocate value at %x,%d",addr, type);
794 x >>= 2;
795 x &= 0xffffff;
796 /* Only reached if blx is avail and it is a call */
797 if (is_thumb) {
798 x |= h << 24;
799 (*(int *)ptr) = 0xfa << 24; /* bl -> blx */
801 (*(int *) ptr) |= x;
803 break;
804 /* Since these relocations only concern Thumb-2 and blx instruction was
805 introduced before Thumb-2, we can assume blx is available and not
806 guard its use */
807 case R_ARM_THM_PC22:
808 case R_ARM_THM_JUMP24:
810 int x, hi, lo, s, j1, j2, i1, i2, imm10, imm11;
811 int to_thumb, is_call, to_plt, blx_bit = 1 << 12;
812 Section *plt;
814 /* weak reference */
815 if (sym->st_shndx == SHN_UNDEF &&
816 ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
817 break;
819 /* Get initial offset */
820 hi = (*(uint16_t *)ptr);
821 lo = (*(uint16_t *)(ptr+2));
822 s = (hi >> 10) & 1;
823 j1 = (lo >> 13) & 1;
824 j2 = (lo >> 11) & 1;
825 i1 = (j1 ^ s) ^ 1;
826 i2 = (j2 ^ s) ^ 1;
827 imm10 = hi & 0x3ff;
828 imm11 = lo & 0x7ff;
829 x = (s << 24) | (i1 << 23) | (i2 << 22) |
830 (imm10 << 12) | (imm11 << 1);
831 if (x & 0x01000000)
832 x -= 0x02000000;
834 /* Relocation infos */
835 to_thumb = val & 1;
836 plt = s1->plt;
837 to_plt = (val >= plt->sh_addr) &&
838 (val < plt->sh_addr + plt->data_offset);
839 is_call = (type == R_ARM_THM_PC22);
841 /* Compute final offset */
842 if (to_plt && !is_call) /* Point to 1st instr of Thumb stub */
843 x -= 4;
844 x += val - addr;
845 if (!to_thumb && is_call) {
846 blx_bit = 0; /* bl -> blx */
847 x = (x + 3) & -4; /* Compute offset from aligned PC */
850 /* Check that relocation is possible
851 * offset must not be out of range
852 * if target is to be entered in arm mode:
853 - bit 1 must not set
854 - instruction must be a call (bl) or a jump to PLT */
855 if (!to_thumb || x >= 0x1000000 || x < -0x1000000)
856 if (to_thumb || (val & 2) || (!is_call && !to_plt))
857 tcc_error("can't relocate value at %x,%d",addr, type);
859 /* Compute and store final offset */
860 s = (x >> 24) & 1;
861 i1 = (x >> 23) & 1;
862 i2 = (x >> 22) & 1;
863 j1 = s ^ (i1 ^ 1);
864 j2 = s ^ (i2 ^ 1);
865 imm10 = (x >> 12) & 0x3ff;
866 imm11 = (x >> 1) & 0x7ff;
867 (*(uint16_t *)ptr) = (uint16_t) ((hi & 0xf800) |
868 (s << 10) | imm10);
869 (*(uint16_t *)(ptr+2)) = (uint16_t) ((lo & 0xc000) |
870 (j1 << 13) | blx_bit | (j2 << 11) |
871 imm11);
873 break;
874 case R_ARM_MOVT_ABS:
875 case R_ARM_MOVW_ABS_NC:
877 int x, imm4, imm12;
878 if (type == R_ARM_MOVT_ABS)
879 val >>= 16;
880 imm12 = val & 0xfff;
881 imm4 = (val >> 12) & 0xf;
882 x = (imm4 << 16) | imm12;
883 if (type == R_ARM_THM_MOVT_ABS)
884 *(int *)ptr |= x;
885 else
886 *(int *)ptr += x;
888 break;
889 case R_ARM_THM_MOVT_ABS:
890 case R_ARM_THM_MOVW_ABS_NC:
892 int x, i, imm4, imm3, imm8;
893 if (type == R_ARM_THM_MOVT_ABS)
894 val >>= 16;
895 imm8 = val & 0xff;
896 imm3 = (val >> 8) & 0x7;
897 i = (val >> 11) & 1;
898 imm4 = (val >> 12) & 0xf;
899 x = (imm3 << 28) | (imm8 << 16) | (i << 10) | imm4;
900 if (type == R_ARM_THM_MOVT_ABS)
901 *(int *)ptr |= x;
902 else
903 *(int *)ptr += x;
905 break;
906 case R_ARM_PREL31:
908 int x;
909 x = (*(int *)ptr) & 0x7fffffff;
910 (*(int *)ptr) &= 0x80000000;
911 x = (x * 2) / 2;
912 x += val - addr;
913 if((x^(x>>1))&0x40000000)
914 tcc_error("can't relocate value at %x,%d",addr, type);
915 (*(int *)ptr) |= x & 0x7fffffff;
917 case R_ARM_ABS32:
918 *(int *)ptr += val;
919 break;
920 case R_ARM_REL32:
921 *(int *)ptr += val - addr;
922 break;
923 case R_ARM_GOTPC:
924 *(int *)ptr += s1->got->sh_addr - addr;
925 break;
926 case R_ARM_GOTOFF:
927 *(int *)ptr += val - s1->got->sh_addr;
928 break;
929 case R_ARM_GOT32:
930 /* we load the got offset */
931 *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
932 break;
933 case R_ARM_COPY:
934 break;
935 case R_ARM_V4BX:
936 /* trade Thumb support for ARMv4 support */
937 if ((0x0ffffff0 & *(int*)ptr) == 0x012FFF10)
938 *(int*)ptr ^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */
939 break;
940 case R_ARM_GLOB_DAT:
941 case R_ARM_JUMP_SLOT:
942 *(addr_t *)ptr = val;
943 break;
944 case R_ARM_NONE:
945 /* Nothing to do. Normally used to indicate a dependency
946 on a certain symbol (like for exception handling under EABI). */
947 break;
948 #ifdef TCC_TARGET_PE
949 case R_ARM_RELATIVE: /* handled in pe_relocate_rva() */
950 break;
951 #endif
952 default:
953 fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
954 type, (unsigned)addr, ptr, (unsigned)val);
955 break;
956 #elif defined(TCC_TARGET_ARM64)
957 case R_AARCH64_ABS64:
958 write64le(ptr, val);
959 break;
960 case R_AARCH64_ABS32:
961 write32le(ptr, val);
962 break;
963 case R_AARCH64_PREL32:
964 write32le(ptr, val - addr);
965 break;
966 case R_AARCH64_MOVW_UABS_G0_NC:
967 write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
968 (val & 0xffff) << 5));
969 break;
970 case R_AARCH64_MOVW_UABS_G1_NC:
971 write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
972 (val >> 16 & 0xffff) << 5));
973 break;
974 case R_AARCH64_MOVW_UABS_G2_NC:
975 write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
976 (val >> 32 & 0xffff) << 5));
977 break;
978 case R_AARCH64_MOVW_UABS_G3:
979 write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
980 (val >> 48 & 0xffff) << 5));
981 break;
982 case R_AARCH64_ADR_PREL_PG_HI21: {
983 uint64_t off = (val >> 12) - (addr >> 12);
984 if ((off + ((uint64_t)1 << 20)) >> 21)
985 tcc_error("R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
986 write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
987 (off & 0x1ffffc) << 3 | (off & 3) << 29));
988 break;
990 case R_AARCH64_ADD_ABS_LO12_NC:
991 write32le(ptr, ((read32le(ptr) & 0xffc003ff) |
992 (val & 0xfff) << 10));
993 break;
994 case R_AARCH64_JUMP26:
995 case R_AARCH64_CALL26:
996 /* This check must match the one in build_got_entries, testing
997 if we really need a PLT slot. */
998 if (sym->st_shndx == SHN_UNDEF ||
999 s1->output_type == TCC_OUTPUT_MEMORY)
1000 /* We've put the PLT slot offset into r_addend when generating
1001 it, and that's what we must use as relocation value (adjusted
1002 by section offset of course). */
1003 val = s1->plt->sh_addr + rel->r_addend;
1004 #ifdef DEBUG_RELOC
1005 printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val,
1006 (char *) symtab_section->link->data + sym->st_name);
1007 #endif
1008 if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)
1010 tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed (val=%lx, addr=%lx)", addr, val);
1012 write32le(ptr, (0x14000000 |
1013 (uint32_t)(type == R_AARCH64_CALL26) << 31 |
1014 ((val - addr) >> 2 & 0x3ffffff)));
1015 break;
1016 case R_AARCH64_ADR_GOT_PAGE: {
1017 uint64_t off =
1018 (((s1->got->sh_addr +
1019 s1->sym_attrs[sym_index].got_offset) >> 12) - (addr >> 12));
1020 if ((off + ((uint64_t)1 << 20)) >> 21)
1021 tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed");
1022 write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
1023 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1024 break;
1026 case R_AARCH64_LD64_GOT_LO12_NC:
1027 write32le(ptr,
1028 ((read32le(ptr) & 0xfff803ff) |
1029 ((s1->got->sh_addr +
1030 s1->sym_attrs[sym_index].got_offset) & 0xff8) << 7));
1031 break;
1032 case R_AARCH64_COPY:
1033 break;
1034 case R_AARCH64_GLOB_DAT:
1035 case R_AARCH64_JUMP_SLOT:
1036 /* They don't need addend */
1037 #ifdef DEBUG_RELOC
1038 printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr,
1039 val - rel->r_addend,
1040 (char *) symtab_section->link->data + sym->st_name);
1041 #endif
1042 write64le(ptr, val - rel->r_addend);
1043 break;
1044 default:
1045 fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n",
1046 type, (unsigned)addr, ptr, (unsigned)val);
1047 break;
1048 #elif defined(TCC_TARGET_C67)
1049 case R_C60_32:
1050 *(int *)ptr += val;
1051 break;
1052 case R_C60LO16:
1054 uint32_t orig;
1056 /* put the low 16 bits of the absolute address
1057 add to what is already there */
1059 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
1060 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
1062 /* patch both at once - assumes always in pairs Low - High */
1064 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
1065 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
1067 break;
1068 case R_C60HI16:
1069 break;
1070 default:
1071 fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
1072 type, (unsigned)addr, ptr, (unsigned)val);
1073 break;
1074 #elif defined(TCC_TARGET_X86_64)
1075 case R_X86_64_64:
1076 if (s1->output_type == TCC_OUTPUT_DLL) {
1077 esym_index = s1->symtab_to_dynsym[sym_index];
1078 qrel->r_offset = rel->r_offset;
1079 if (esym_index) {
1080 qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64);
1081 qrel->r_addend = rel->r_addend;
1082 qrel++;
1083 break;
1084 } else {
1085 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
1086 qrel->r_addend = read64le(ptr) + val;
1087 qrel++;
1090 write64le(ptr, read64le(ptr) + val);
1091 break;
1092 case R_X86_64_32:
1093 case R_X86_64_32S:
1094 if (s1->output_type == TCC_OUTPUT_DLL) {
1095 /* XXX: this logic may depend on TCC's codegen
1096 now TCC uses R_X86_64_32 even for a 64bit pointer */
1097 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
1098 /* Use sign extension! */
1099 qrel->r_addend = (int)read32le(ptr) + val;
1100 qrel++;
1102 write32le(ptr, read32le(ptr) + val);
1103 break;
1105 case R_X86_64_PC32:
1106 if (s1->output_type == TCC_OUTPUT_DLL) {
1107 /* DLL relocation */
1108 esym_index = s1->symtab_to_dynsym[sym_index];
1109 if (esym_index) {
1110 qrel->r_offset = rel->r_offset;
1111 qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
1112 /* Use sign extension! */
1113 qrel->r_addend = (int)read32le(ptr) + rel->r_addend;
1114 qrel++;
1115 break;
1118 goto plt32pc32;
1120 case R_X86_64_PLT32:
1121 /* We've put the PLT slot offset into r_addend when generating
1122 it, and that's what we must use as relocation value (adjusted
1123 by section offset of course). */
1124 val = s1->plt->sh_addr + rel->r_addend;
1125 /* fallthrough. */
1127 plt32pc32:
1129 long long diff;
1130 diff = (long long)val - addr;
1131 if (diff < -2147483648LL || diff > 2147483647LL) {
1132 tcc_error("internal error: relocation failed");
1134 write32le(ptr, read32le(ptr) + diff);
1136 break;
1137 case R_X86_64_GLOB_DAT:
1138 case R_X86_64_JUMP_SLOT:
1139 /* They don't need addend */
1140 write64le(ptr, val - rel->r_addend);
1141 break;
1142 case R_X86_64_GOTPCREL:
1143 case R_X86_64_GOTPCRELX:
1144 case R_X86_64_REX_GOTPCRELX:
1145 write32le(ptr, read32le(ptr) +
1146 (s1->got->sh_addr - addr +
1147 s1->sym_attrs[sym_index].got_offset - 4));
1148 break;
1149 case R_X86_64_GOTTPOFF:
1150 write32le(ptr, read32le(ptr) + val - s1->got->sh_addr);
1151 break;
1152 case R_X86_64_GOT32:
1153 /* we load the got offset */
1154 write32le(ptr, read32le(ptr) + s1->sym_attrs[sym_index].got_offset);
1155 break;
1156 #ifdef TCC_TARGET_PE
1157 case R_X86_64_RELATIVE: /* handled in pe_relocate_rva() */
1158 break;
1159 #endif
1161 #else
1162 #error unsupported processor
1163 #endif
1166 /* if the relocation is allocated, we change its symbol table */
1167 if (sr->sh_flags & SHF_ALLOC)
1168 sr->link = s1->dynsym;
1171 /* relocate relocation table in 'sr' */
1172 static void relocate_rel(TCCState *s1, Section *sr)
1174 Section *s;
1175 ElfW_Rel *rel;
1177 s = s1->sections[sr->sh_info];
1178 for_each_elem(sr, 0, rel, ElfW_Rel)
1179 rel->r_offset += s->sh_addr;
1182 /* count the number of dynamic relocations so that we can reserve
1183 their space */
1184 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
1186 ElfW_Rel *rel;
1187 int sym_index, esym_index, type, count;
1189 count = 0;
1190 for_each_elem(sr, 0, rel, ElfW_Rel) {
1191 sym_index = ELFW(R_SYM)(rel->r_info);
1192 type = ELFW(R_TYPE)(rel->r_info);
1193 switch(type) {
1194 #if defined(TCC_TARGET_I386)
1195 case R_386_32:
1196 #elif defined(TCC_TARGET_X86_64)
1197 case R_X86_64_32:
1198 case R_X86_64_32S:
1199 case R_X86_64_64:
1200 #endif
1201 count++;
1202 break;
1203 #if defined(TCC_TARGET_I386)
1204 case R_386_PC32:
1205 #elif defined(TCC_TARGET_X86_64)
1206 case R_X86_64_PC32:
1207 #endif
1208 esym_index = s1->symtab_to_dynsym[sym_index];
1209 if (esym_index)
1210 count++;
1211 break;
1212 default:
1213 break;
1216 if (count) {
1217 /* allocate the section */
1218 sr->sh_flags |= SHF_ALLOC;
1219 sr->sh_size = count * sizeof(ElfW_Rel);
1221 return count;
1224 static struct sym_attr *alloc_sym_attr(TCCState *s1, int index)
1226 int n;
1227 struct sym_attr *tab;
1229 if (index >= s1->nb_sym_attrs) {
1230 /* find immediately bigger power of 2 and reallocate array */
1231 n = 1;
1232 while (index >= n)
1233 n *= 2;
1234 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
1235 s1->sym_attrs = tab;
1236 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
1237 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
1238 s1->nb_sym_attrs = n;
1240 return &s1->sym_attrs[index];
1243 static void build_got(TCCState *s1)
1245 unsigned char *ptr;
1247 /* if no got, then create it */
1248 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1249 s1->got->sh_entsize = 4;
1250 add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1251 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1252 ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
1253 #if PTR_SIZE == 4
1254 /* keep space for _DYNAMIC pointer, if present */
1255 write32le(ptr, 0);
1256 /* two dummy got entries */
1257 write32le(ptr + 4, 0);
1258 write32le(ptr + 8, 0);
1259 #else
1260 /* keep space for _DYNAMIC pointer, if present */
1261 write32le(ptr, 0);
1262 write32le(ptr + 4, 0);
1263 /* two dummy got entries */
1264 write32le(ptr + 8, 0);
1265 write32le(ptr + 12, 0);
1266 write32le(ptr + 16, 0);
1267 write32le(ptr + 20, 0);
1268 #endif
1271 /* put a got or plt entry corresponding to a symbol in symtab_section. 'size'
1272 and 'info' can be modifed if more precise info comes from the DLL.
1273 Returns offset of GOT or PLT slot. */
1274 static unsigned long put_got_entry(TCCState *s1,
1275 int reloc_type, unsigned long size, int info,
1276 int sym_index)
1278 int index, need_plt_entry;
1279 const char *name;
1280 ElfW(Sym) *sym;
1281 unsigned long offset;
1282 int *ptr;
1283 struct sym_attr *symattr;
1285 if (!s1->got)
1286 build_got(s1);
1288 need_plt_entry =
1289 #ifdef TCC_TARGET_X86_64
1290 (reloc_type == R_X86_64_JUMP_SLOT);
1291 #elif defined(TCC_TARGET_I386)
1292 (reloc_type == R_386_JMP_SLOT);
1293 #elif defined(TCC_TARGET_ARM)
1294 (reloc_type == R_ARM_JUMP_SLOT);
1295 #elif defined(TCC_TARGET_ARM64)
1296 (reloc_type == R_AARCH64_JUMP_SLOT);
1297 #else
1299 #endif
1301 if (need_plt_entry && !s1->plt) {
1302 /* add PLT */
1303 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1304 SHF_ALLOC | SHF_EXECINSTR);
1305 s1->plt->sh_entsize = 4;
1308 /* If a got/plt entry already exists for that symbol, no need to add one */
1309 if (sym_index < s1->nb_sym_attrs) {
1310 if (need_plt_entry && s1->sym_attrs[sym_index].plt_offset)
1311 return s1->sym_attrs[sym_index].plt_offset;
1312 else if (!need_plt_entry && s1->sym_attrs[sym_index].got_offset)
1313 return s1->sym_attrs[sym_index].got_offset;
1316 symattr = alloc_sym_attr(s1, sym_index);
1318 /* Only store the GOT offset if it's not generated for the PLT entry. */
1319 if (!need_plt_entry)
1320 symattr->got_offset = s1->got->data_offset;
1322 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1323 name = (char *) symtab_section->link->data + sym->st_name;
1324 offset = sym->st_value;
1325 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1326 if (need_plt_entry) {
1327 Section *plt;
1328 uint8_t *p;
1329 int modrm;
1330 unsigned long relofs;
1332 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1333 modrm = 0x25;
1334 #else
1335 /* if we build a DLL, we add a %ebx offset */
1336 if (s1->output_type == TCC_OUTPUT_DLL)
1337 modrm = 0xa3;
1338 else
1339 modrm = 0x25;
1340 #endif
1342 /* add a PLT entry */
1343 plt = s1->plt;
1344 if (plt->data_offset == 0) {
1345 /* first plt entry */
1346 p = section_ptr_add(plt, 16);
1347 p[0] = 0xff; /* pushl got + PTR_SIZE */
1348 p[1] = modrm + 0x10;
1349 write32le(p + 2, PTR_SIZE);
1350 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
1351 p[7] = modrm;
1352 write32le(p + 8, PTR_SIZE * 2);
1355 /* The PLT slot refers to the relocation entry it needs
1356 via offset. The reloc entry is created below, so its
1357 offset is the current data_offset. */
1358 relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
1359 symattr->plt_offset = plt->data_offset;
1360 p = section_ptr_add(plt, 16);
1361 p[0] = 0xff; /* jmp *(got + x) */
1362 p[1] = modrm;
1363 write32le(p + 2, s1->got->data_offset);
1364 p[6] = 0x68; /* push $xxx */
1365 #ifdef TCC_TARGET_X86_64
1366 /* On x86-64, the relocation is referred to by _index_. */
1367 write32le(p + 7, relofs / sizeof (ElfW_Rel));
1368 #else
1369 write32le(p + 7, relofs);
1370 #endif
1371 p[11] = 0xe9; /* jmp plt_start */
1372 write32le(p + 12, -(plt->data_offset));
1374 /* If this was an UNDEF symbol set the offset in the
1375 dynsymtab to the PLT slot, so that PC32 relocs to it
1376 can be resolved. */
1377 if (sym->st_shndx == SHN_UNDEF)
1378 offset = plt->data_offset - 16;
1380 #elif defined(TCC_TARGET_ARM)
1381 if (need_plt_entry) {
1382 Section *plt;
1383 uint8_t *p;
1385 /* if we build a DLL, we add a %ebx offset */
1386 if (s1->output_type == TCC_OUTPUT_DLL)
1387 tcc_error("DLLs unimplemented!");
1389 /* add a PLT entry */
1390 plt = s1->plt;
1391 if (plt->data_offset == 0) {
1392 /* first plt entry */
1393 p = section_ptr_add(plt, 16);
1394 write32le(p, 0xe52de004); /* push {lr} */
1395 write32le(p+4, 0xe59fe010); /* ldr lr, [pc, #16] */
1396 write32le(p+8, 0xe08fe00e); /* add lr, pc, lr */
1397 write32le(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */
1400 symattr->plt_offset = plt->data_offset;
1401 if (symattr->plt_thumb_stub) {
1402 p = section_ptr_add(plt, 20);
1403 write32le(p, 0x4778); /* bx pc */
1404 write32le(p+2, 0x46c0); /* nop */
1405 p += 4;
1406 } else
1407 p = section_ptr_add(plt, 16);
1408 write32le(p, 0xe59fc004); /* ldr ip, [pc, #4] ; GOT entry offset */
1409 write32le(p+4, 0xe08fc00c); /* add ip, pc, ip ; addr of GOT entry */
1410 write32le(p+8, 0xe59cf000); /* ldr pc, [ip] ; jump to GOT entry */
1411 write32le(p+12, s1->got->data_offset); /* GOT entry off once patched */
1413 /* the symbol is modified so that it will be relocated to
1414 the PLT */
1415 if (sym->st_shndx == SHN_UNDEF)
1416 offset = plt->data_offset - 16;
1418 #elif defined(TCC_TARGET_ARM64)
1419 if (need_plt_entry) {
1420 Section *plt;
1421 uint8_t *p;
1423 if (s1->output_type == TCC_OUTPUT_DLL)
1424 tcc_error("DLLs unimplemented!");
1426 plt = s1->plt;
1427 if (plt->data_offset == 0)
1428 section_ptr_add(plt, 32);
1429 symattr->plt_offset = plt->data_offset;
1430 p = section_ptr_add(plt, 16);
1431 write32le(p, s1->got->data_offset);
1432 write32le(p + 4, (uint64_t)s1->got->data_offset >> 32);
1434 if (sym->st_shndx == SHN_UNDEF)
1435 offset = plt->data_offset - 16;
1437 #elif defined(TCC_TARGET_C67)
1438 if (s1->dynsym) {
1439 tcc_error("C67 got not implemented");
1441 #else
1442 #error unsupported CPU
1443 #endif
1444 if (s1->dynsym) {
1445 /* XXX This might generate multiple syms for name. */
1446 index = put_elf_sym(s1->dynsym, offset,
1447 size, info, 0, sym->st_shndx, name);
1448 /* Create the relocation (it's against the GOT for PLT
1449 and GOT relocs). */
1450 put_elf_reloc(s1->dynsym, s1->got,
1451 s1->got->data_offset,
1452 reloc_type, index);
1453 } else {
1454 /* Without .dynsym (i.e. static link or memory output) we
1455 still need relocs against the generated got, so as to fill
1456 the entries with the symbol values (determined later). */
1457 put_elf_reloc(symtab_section, s1->got,
1458 s1->got->data_offset,
1459 reloc_type, sym_index);
1461 /* And now create the GOT slot itself. */
1462 ptr = section_ptr_add(s1->got, PTR_SIZE);
1463 *ptr = 0;
1464 if (need_plt_entry)
1465 return symattr->plt_offset;
1466 else
1467 return symattr->got_offset;
1470 /* build GOT and PLT entries */
1471 ST_FUNC void build_got_entries(TCCState *s1)
1473 Section *s;
1474 ElfW_Rel *rel;
1475 ElfW(Sym) *sym;
1476 int i, type, reloc_type, sym_index;
1478 for(i = 1; i < s1->nb_sections; i++) {
1479 s = s1->sections[i];
1480 if (s->sh_type != SHT_RELX)
1481 continue;
1482 /* no need to handle got relocations */
1483 if (s->link != symtab_section)
1484 continue;
1485 for_each_elem(s, 0, rel, ElfW_Rel) {
1486 type = ELFW(R_TYPE)(rel->r_info);
1487 switch(type) {
1488 #if defined(TCC_TARGET_I386)
1489 case R_386_GOT32:
1490 case R_386_GOT32X:
1491 case R_386_GOTOFF:
1492 case R_386_GOTPC:
1493 case R_386_PLT32:
1494 if (!s1->got)
1495 build_got(s1);
1496 if (type == R_386_GOT32 || type == R_386_GOT32X ||
1497 type == R_386_PLT32) {
1498 sym_index = ELFW(R_SYM)(rel->r_info);
1499 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1500 /* look at the symbol got offset. If none, then add one */
1501 if (type == R_386_GOT32 || type == R_386_GOT32X)
1502 reloc_type = R_386_GLOB_DAT;
1503 else
1504 reloc_type = R_386_JMP_SLOT;
1505 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1506 sym_index);
1508 break;
1509 #elif defined(TCC_TARGET_ARM)
1510 case R_ARM_PC24:
1511 case R_ARM_CALL:
1512 case R_ARM_JUMP24:
1513 case R_ARM_GOT32:
1514 case R_ARM_GOTOFF:
1515 case R_ARM_GOTPC:
1516 case R_ARM_PLT32:
1517 if (!s1->got)
1518 build_got(s1);
1519 sym_index = ELFW(R_SYM)(rel->r_info);
1520 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1521 if (type != R_ARM_GOTOFF && type != R_ARM_GOTPC
1522 && sym->st_shndx == SHN_UNDEF) {
1523 unsigned long ofs;
1524 /* look at the symbol got offset. If none, then add one */
1525 if (type == R_ARM_GOT32)
1526 reloc_type = R_ARM_GLOB_DAT;
1527 else
1528 reloc_type = R_ARM_JUMP_SLOT;
1529 ofs = put_got_entry(s1, reloc_type, sym->st_size,
1530 sym->st_info, sym_index);
1531 #ifdef DEBUG_RELOC
1532 printf ("maybegot: %s, %d, %d --> ofs=0x%x\n",
1533 (char *) symtab_section->link->data + sym->st_name,
1534 type, sym->st_shndx, ofs);
1535 #endif
1536 if (type != R_ARM_GOT32) {
1537 addr_t *ptr = (addr_t*)(s1->sections[s->sh_info]->data
1538 + rel->r_offset);
1539 /* x must be signed! */
1540 int x = *ptr & 0xffffff;
1541 x = (x << 8) >> 8;
1542 x <<= 2;
1543 x += ofs;
1544 x >>= 2;
1545 #ifdef DEBUG_RELOC
1546 printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr,
1547 (*ptr & 0xff000000) | x, x);
1548 #endif
1549 *ptr = (*ptr & 0xff000000) | x;
1552 break;
1553 case R_ARM_THM_JUMP24:
1554 sym_index = ELFW(R_SYM)(rel->r_info);
1555 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1556 /* We are relocating a jump from thumb code to arm code */
1557 if (sym->st_shndx != SHN_UNDEF && !(sym->st_value & 1)) {
1558 int index;
1559 uint8_t *p;
1560 char *name, buf[1024];
1561 Section *text_section;
1563 name = (char *) symtab_section->link->data + sym->st_name;
1564 text_section = s1->sections[sym->st_shndx];
1565 /* Modify reloc to target a thumb stub to switch to ARM */
1566 snprintf(buf, sizeof(buf), "%s_from_thumb", name);
1567 index = put_elf_sym(symtab_section,
1568 text_section->data_offset + 1,
1569 sym->st_size, sym->st_info, 0,
1570 sym->st_shndx, buf);
1571 rel->r_info = ELFW(R_INFO)(index, type);
1572 /* Create a thumb stub fonction to switch to ARM mode */
1573 put_elf_reloc(symtab_section, text_section,
1574 text_section->data_offset + 4, R_ARM_JUMP24,
1575 sym_index);
1576 p = section_ptr_add(text_section, 8);
1577 write32le(p, 0x4778); /* bx pc */
1578 write32le(p+2, 0x46c0); /* nop */
1579 write32le(p+4, 0xeafffffe); /* b $sym */
1581 #elif defined(TCC_TARGET_ARM64)
1582 //xx Other cases may be required here:
1583 case R_AARCH64_ADR_GOT_PAGE:
1584 case R_AARCH64_LD64_GOT_LO12_NC:
1585 if (!s1->got)
1586 build_got(s1);
1587 sym_index = ELFW(R_SYM)(rel->r_info);
1588 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1589 reloc_type = R_AARCH64_GLOB_DAT;
1590 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1591 sym_index);
1592 break;
1594 case R_AARCH64_JUMP26:
1595 case R_AARCH64_CALL26:
1596 if (!s1->got)
1597 build_got(s1);
1598 sym_index = ELFW(R_SYM)(rel->r_info);
1599 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1600 if (sym->st_shndx == SHN_UNDEF ||
1601 s1->output_type == TCC_OUTPUT_MEMORY) {
1602 unsigned long ofs;
1603 reloc_type = R_AARCH64_JUMP_SLOT;
1604 ofs = put_got_entry(s1, reloc_type, sym->st_size,
1605 sym->st_info, sym_index);
1606 /* We store the place of the generated PLT slot
1607 in our addend. */
1608 rel->r_addend += ofs;
1610 break;
1611 #elif defined(TCC_TARGET_C67)
1612 case R_C60_GOT32:
1613 case R_C60_GOTOFF:
1614 case R_C60_GOTPC:
1615 case R_C60_PLT32:
1616 if (!s1->got)
1617 build_got(s1);
1618 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
1619 sym_index = ELFW(R_SYM)(rel->r_info);
1620 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1621 /* look at the symbol got offset. If none, then add one */
1622 if (type == R_C60_GOT32)
1623 reloc_type = R_C60_GLOB_DAT;
1624 else
1625 reloc_type = R_C60_JMP_SLOT;
1626 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1627 sym_index);
1629 break;
1630 #elif defined(TCC_TARGET_X86_64)
1631 case R_X86_64_GOT32:
1632 case R_X86_64_GOTTPOFF:
1633 case R_X86_64_GOTPCREL:
1634 case R_X86_64_GOTPCRELX:
1635 case R_X86_64_REX_GOTPCRELX:
1636 case R_X86_64_PLT32:
1637 sym_index = ELFW(R_SYM)(rel->r_info);
1638 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1639 if (type == R_X86_64_PLT32 &&
1640 ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT)
1642 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1643 break;
1646 if (!s1->got) {
1647 build_got(s1);
1648 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1650 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
1651 type == R_X86_64_GOTPCRELX ||
1652 type == R_X86_64_REX_GOTPCRELX ||
1653 type == R_X86_64_PLT32) {
1654 unsigned long ofs;
1655 /* look at the symbol got offset. If none, then add one */
1656 if (type == R_X86_64_PLT32)
1657 reloc_type = R_X86_64_JUMP_SLOT;
1658 else
1659 reloc_type = R_X86_64_GLOB_DAT;
1660 ofs = put_got_entry(s1, reloc_type, sym->st_size,
1661 sym->st_info, sym_index);
1662 if (type == R_X86_64_PLT32)
1663 /* We store the place of the generated PLT slot
1664 in our addend. */
1665 rel->r_addend += ofs;
1667 break;
1668 #else
1669 #error unsupported CPU
1670 #endif
1671 default:
1672 break;
1678 ST_FUNC Section *new_symtab(TCCState *s1,
1679 const char *symtab_name, int sh_type, int sh_flags,
1680 const char *strtab_name,
1681 const char *hash_name, int hash_sh_flags)
1683 Section *symtab, *strtab, *hash;
1684 int *ptr, nb_buckets;
1686 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1687 symtab->sh_entsize = sizeof(ElfW(Sym));
1688 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1689 put_elf_str(strtab, "");
1690 symtab->link = strtab;
1691 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1693 nb_buckets = 1;
1695 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1696 hash->sh_entsize = sizeof(int);
1697 symtab->hash = hash;
1698 hash->link = symtab;
1700 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1701 ptr[0] = nb_buckets;
1702 ptr[1] = 1;
1703 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1704 return symtab;
1707 /* put dynamic tag */
1708 static void put_dt(Section *dynamic, int dt, addr_t val)
1710 ElfW(Dyn) *dyn;
1711 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1712 dyn->d_tag = dt;
1713 dyn->d_un.d_val = val;
1716 static void add_init_array_defines(TCCState *s1, const char *section_name)
1718 Section *s;
1719 long end_offset;
1720 char sym_start[1024];
1721 char sym_end[1024];
1723 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1724 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1726 s = find_section(s1, section_name);
1727 if (!s) {
1728 end_offset = 0;
1729 s = data_section;
1730 } else {
1731 end_offset = s->data_offset;
1734 add_elf_sym(symtab_section,
1735 0, 0,
1736 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1737 s->sh_num, sym_start);
1738 add_elf_sym(symtab_section,
1739 end_offset, 0,
1740 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1741 s->sh_num, sym_end);
1744 static int tcc_add_support(TCCState *s1, const char *filename)
1746 char buf[1024];
1747 snprintf(buf, sizeof(buf), "%s/"TCC_ARCH_DIR"%s", s1->tcc_lib_path, filename);
1748 return tcc_add_file(s1, buf);
1751 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1753 #ifdef CONFIG_TCC_BCHECK
1754 addr_t *ptr;
1755 int sym_index;
1757 if (0 == s1->do_bounds_check)
1758 return;
1759 /* XXX: add an object file to do that */
1760 ptr = section_ptr_add(bounds_section, sizeof(*ptr));
1761 *ptr = 0;
1762 add_elf_sym(symtab_section, 0, 0,
1763 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1764 bounds_section->sh_num, "__bounds_start");
1765 /* pull bcheck.o from libtcc1.a */
1766 sym_index = add_elf_sym(symtab_section, 0, 0,
1767 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1768 SHN_UNDEF, "__bound_init");
1769 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1770 /* add 'call __bound_init()' in .init section */
1771 Section *init_section = find_section(s1, ".init");
1772 unsigned char *pinit = section_ptr_add(init_section, 5);
1773 pinit[0] = 0xe8;
1774 write32le(pinit + 1, -4);
1775 put_elf_reloc(symtab_section, init_section,
1776 init_section->data_offset - 4, R_386_PC32, sym_index);
1777 /* R_386_PC32 = R_X86_64_PC32 = 2 */
1779 #endif
1782 /* add tcc runtime libraries */
1783 ST_FUNC void tcc_add_runtime(TCCState *s1)
1785 tcc_add_bcheck(s1);
1786 tcc_add_pragma_libs(s1);
1787 /* add libc */
1788 if (!s1->nostdlib) {
1789 tcc_add_library(s1, "c");
1790 #ifdef CONFIG_USE_LIBGCC
1791 if (!s1->static_link) {
1792 tcc_add_file(s1, TCC_LIBGCC);
1794 #endif
1795 tcc_add_support(s1, "libtcc1.a");
1796 /* add crt end if not memory output */
1797 if (s1->output_type != TCC_OUTPUT_MEMORY)
1798 tcc_add_crt(s1, "crtn.o");
1802 /* add various standard linker symbols (must be done after the
1803 sections are filled (for example after allocating common
1804 symbols)) */
1805 ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
1807 char buf[1024];
1808 int i;
1809 Section *s;
1811 add_elf_sym(symtab_section,
1812 text_section->data_offset, 0,
1813 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1814 text_section->sh_num, "_etext");
1815 add_elf_sym(symtab_section,
1816 data_section->data_offset, 0,
1817 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1818 data_section->sh_num, "_edata");
1819 add_elf_sym(symtab_section,
1820 bss_section->data_offset, 0,
1821 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1822 bss_section->sh_num, "_end");
1823 /* horrible new standard ldscript defines */
1824 add_init_array_defines(s1, ".preinit_array");
1825 add_init_array_defines(s1, ".init_array");
1826 add_init_array_defines(s1, ".fini_array");
1828 /* add start and stop symbols for sections whose name can be
1829 expressed in C */
1830 for(i = 1; i < s1->nb_sections; i++) {
1831 s = s1->sections[i];
1832 if (s->sh_type == SHT_PROGBITS &&
1833 (s->sh_flags & SHF_ALLOC)) {
1834 const char *p;
1835 int ch;
1837 /* check if section name can be expressed in C */
1838 p = s->name;
1839 for(;;) {
1840 ch = *p;
1841 if (!ch)
1842 break;
1843 if (!isid(ch) && !isnum(ch))
1844 goto next_sec;
1845 p++;
1847 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1848 add_elf_sym(symtab_section,
1849 0, 0,
1850 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1851 s->sh_num, buf);
1852 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1853 add_elf_sym(symtab_section,
1854 s->data_offset, 0,
1855 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1856 s->sh_num, buf);
1858 next_sec: ;
1862 static void tcc_output_binary(TCCState *s1, FILE *f,
1863 const int *sec_order)
1865 Section *s;
1866 int i, offset, size;
1868 offset = 0;
1869 for(i=1;i<s1->nb_sections;i++) {
1870 s = s1->sections[sec_order[i]];
1871 if (s->sh_type != SHT_NOBITS &&
1872 (s->sh_flags & SHF_ALLOC)) {
1873 while (offset < s->sh_offset) {
1874 fputc(0, f);
1875 offset++;
1877 size = s->sh_size;
1878 fwrite(s->data, 1, size, f);
1879 offset += size;
1884 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1885 #define HAVE_PHDR 1
1886 #define EXTRA_RELITEMS 14
1888 /* move the relocation value from .dynsym to .got */
1889 static void patch_dynsym_undef(TCCState *s1, Section *s)
1891 uint32_t *gotd = (void *)s1->got->data;
1892 ElfW(Sym) *sym;
1894 gotd += 3; /* dummy entries in .got */
1895 /* relocate symbols in .dynsym */
1896 for_each_elem(s, 1, sym, ElfW(Sym)) {
1897 if (sym->st_shndx == SHN_UNDEF) {
1898 *gotd++ = sym->st_value + 6; /* XXX 6 is magic ? */
1899 sym->st_value = 0;
1903 #else
1904 #define HAVE_PHDR 1
1905 #define EXTRA_RELITEMS 9
1907 /* zero plt offsets of weak symbols in .dynsym */
1908 static void patch_dynsym_undef(TCCState *s1, Section *s)
1910 ElfW(Sym) *sym;
1912 for_each_elem(s, 1, sym, ElfW(Sym))
1913 if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
1914 sym->st_value = 0;
1916 #endif
1918 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1920 int sym_index = ELFW(R_SYM) (rel->r_info);
1921 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1922 unsigned long offset;
1924 if (sym_index >= s1->nb_sym_attrs)
1925 return;
1926 offset = s1->sym_attrs[sym_index].got_offset;
1927 section_reserve(s1->got, offset + PTR_SIZE);
1928 #ifdef TCC_TARGET_X86_64
1929 /* only works for x86-64 */
1930 write32le(s1->got->data + offset + 4, sym->st_value >> 32);
1931 #endif
1932 write32le(s1->got->data + offset, sym->st_value & 0xffffffff);
1935 /* Perform relocation to GOT or PLT entries */
1936 ST_FUNC void fill_got(TCCState *s1)
1938 Section *s;
1939 ElfW_Rel *rel;
1940 int i;
1942 for(i = 1; i < s1->nb_sections; i++) {
1943 s = s1->sections[i];
1944 if (s->sh_type != SHT_RELX)
1945 continue;
1946 /* no need to handle got relocations */
1947 if (s->link != symtab_section)
1948 continue;
1949 for_each_elem(s, 0, rel, ElfW_Rel) {
1950 switch (ELFW(R_TYPE) (rel->r_info)) {
1951 case R_X86_64_GOT32:
1952 case R_X86_64_GOTPCREL:
1953 case R_X86_64_GOTPCRELX:
1954 case R_X86_64_REX_GOTPCRELX:
1955 case R_X86_64_PLT32:
1956 fill_got_entry(s1, rel);
1957 break;
1963 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1964 in shared libraries and export non local defined symbols to shared libraries
1965 if -rdynamic switch was given on command line */
1966 static void bind_exe_dynsyms(TCCState *s1)
1968 const char *name;
1969 int sym_index, index;
1970 ElfW(Sym) *sym, *esym;
1971 int type;
1973 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1974 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1975 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1976 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1977 if (sym->st_shndx == SHN_UNDEF) {
1978 name = (char *) symtab_section->link->data + sym->st_name;
1979 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1980 if (sym_index) {
1981 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1982 type = ELFW(ST_TYPE)(esym->st_info);
1983 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1984 /* Indirect functions shall have STT_FUNC type in executable
1985 * dynsym section. Indeed, a dlsym call following a lazy
1986 * resolution would pick the symbol value from the
1987 * executable dynsym entry which would contain the address
1988 * of the function wanted by the caller of dlsym instead of
1989 * the address of the function that would return that
1990 * address */
1991 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1992 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC),
1993 sym - (ElfW(Sym) *)symtab_section->data);
1994 } else if (type == STT_OBJECT) {
1995 unsigned long offset;
1996 ElfW(Sym) *dynsym;
1997 offset = bss_section->data_offset;
1998 /* XXX: which alignment ? */
1999 offset = (offset + 16 - 1) & -16;
2000 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
2001 esym->st_info, 0, bss_section->sh_num,
2002 name);
2003 /* Ensure R_COPY works for weak symbol aliases */
2004 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
2005 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
2006 if ((dynsym->st_value == esym->st_value)
2007 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
2008 char *dynname = (char *) s1->dynsymtab_section->link->data
2009 + dynsym->st_name;
2010 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
2011 dynsym->st_info, 0,
2012 bss_section->sh_num, dynname);
2013 break;
2017 put_elf_reloc(s1->dynsym, bss_section,
2018 offset, R_COPY, index);
2019 offset += esym->st_size;
2020 bss_section->data_offset = offset;
2022 } else {
2023 /* STB_WEAK undefined symbols are accepted */
2024 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
2025 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
2026 !strcmp(name, "_fp_hw")) {
2027 } else {
2028 tcc_error_noabort("undefined symbol '%s'", name);
2031 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2032 /* if -rdynamic option, then export all non local symbols */
2033 name = (char *) symtab_section->link->data + sym->st_name;
2034 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
2035 0, sym->st_shndx, name);
2040 /* Bind symbols of libraries: export non local symbols of executable that
2041 resolve undefined symbols of shared libraries */
2042 static void bind_libs_dynsyms(TCCState *s1)
2044 const char *name;
2045 int sym_index;
2046 ElfW(Sym) *sym, *esym;
2048 /* now look at unresolved dynamic symbols and export
2049 corresponding symbol */
2050 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
2051 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
2052 sym_index = find_elf_sym(symtab_section, name);
2053 if (sym_index) {
2054 /* XXX: avoid adding a symbol if already present because of
2055 -rdynamic ? */
2056 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2057 if (sym->st_shndx != SHN_UNDEF)
2058 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
2059 sym->st_info, 0, sym->st_shndx, name);
2060 } else if (esym->st_shndx == SHN_UNDEF) {
2061 /* weak symbols can stay undefined */
2062 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
2063 tcc_warning("undefined dynamic symbol '%s'", name);
2068 /* Export all non local symbols (for shared libraries) */
2069 static void export_global_syms(TCCState *s1)
2071 int nb_syms, dynindex, index;
2072 const char *name;
2073 ElfW(Sym) *sym;
2075 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
2076 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
2077 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
2078 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2079 name = (char *) symtab_section->link->data + sym->st_name;
2080 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
2081 sym->st_info, 0, sym->st_shndx, name);
2082 index = sym - (ElfW(Sym) *) symtab_section->data;
2083 s1->symtab_to_dynsym[index] = dynindex;
2088 /* relocate the PLT: compute addresses and offsets in the PLT now that final
2089 address for PLT and GOT are known (see fill_program_header) */
2090 ST_FUNC void relocate_plt(TCCState *s1)
2092 uint8_t *p, *p_end;
2094 if (!s1->plt)
2095 return;
2097 p = s1->plt->data;
2098 p_end = p + s1->plt->data_offset;
2099 if (p < p_end) {
2100 #if defined(TCC_TARGET_I386)
2101 write32le(p + 2, read32le(p + 2) + s1->got->sh_addr);
2102 write32le(p + 8, read32le(p + 8) + s1->got->sh_addr);
2103 p += 16;
2104 while (p < p_end) {
2105 write32le(p + 2, read32le(p + 2) + s1->got->sh_addr);
2106 p += 16;
2108 #elif defined(TCC_TARGET_X86_64)
2109 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
2110 write32le(p + 2, read32le(p + 2) + x);
2111 write32le(p + 8, read32le(p + 8) + x - 6);
2112 p += 16;
2113 while (p < p_end) {
2114 write32le(p + 2, read32le(p + 2) + x + s1->plt->data - p);
2115 p += 16;
2117 #elif defined(TCC_TARGET_ARM)
2118 int x;
2119 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
2120 p += 16;
2121 while (p < p_end) {
2122 if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
2123 p += 4;
2124 write32le(p + 12, x + read32le(p + 12) + s1->plt->data - p);
2125 p += 16;
2127 #elif defined(TCC_TARGET_ARM64)
2128 uint64_t plt = s1->plt->sh_addr;
2129 uint64_t got = s1->got->sh_addr;
2130 uint64_t off = (got >> 12) - (plt >> 12);
2131 if ((off + ((uint32_t)1 << 20)) >> 21)
2132 tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt);
2133 write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
2134 write32le(p + 4, (0x90000010 | // adrp x16,...
2135 (off & 0x1ffffc) << 3 | (off & 3) << 29));
2136 write32le(p + 8, (0xf9400211 | // ldr x17,[x16,#...]
2137 (got & 0xff8) << 7));
2138 write32le(p + 12, (0x91000210 | // add x16,x16,#...
2139 (got & 0xfff) << 10));
2140 write32le(p + 16, 0xd61f0220); // br x17
2141 write32le(p + 20, 0xd503201f); // nop
2142 write32le(p + 24, 0xd503201f); // nop
2143 write32le(p + 28, 0xd503201f); // nop
2144 p += 32;
2145 while (p < p_end) {
2146 uint64_t pc = plt + (p - s1->plt->data);
2147 uint64_t addr = got + read64le(p);
2148 uint64_t off = (addr >> 12) - (pc >> 12);
2149 if ((off + ((uint32_t)1 << 20)) >> 21)
2150 tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc);
2151 write32le(p, (0x90000010 | // adrp x16,...
2152 (off & 0x1ffffc) << 3 | (off & 3) << 29));
2153 write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
2154 (addr & 0xff8) << 7));
2155 write32le(p + 8, (0x91000210 | // add x16,x16,#...
2156 (addr & 0xfff) << 10));
2157 write32le(p + 12, 0xd61f0220); // br x17
2158 p += 16;
2160 #elif defined(TCC_TARGET_C67)
2161 /* XXX: TODO */
2162 #else
2163 #error unsupported CPU
2164 #endif
2168 /* Allocate strings for section names and decide if an unallocated section
2169 should be output.
2171 NOTE: the strsec section comes last, so its size is also correct ! */
2172 static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
2174 int i;
2175 Section *s;
2177 /* Allocate strings for section names */
2178 for(i = 1; i < s1->nb_sections; i++) {
2179 s = s1->sections[i];
2180 s->sh_name = put_elf_str(strsec, s->name);
2181 /* when generating a DLL, we include relocations but we may
2182 patch them */
2183 if (file_type == TCC_OUTPUT_DLL &&
2184 s->sh_type == SHT_RELX &&
2185 !(s->sh_flags & SHF_ALLOC)) {
2186 /* gr: avoid bogus relocs for empty (debug) sections */
2187 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
2188 prepare_dynamic_rel(s1, s);
2189 else if (s1->do_debug)
2190 s->sh_size = s->data_offset;
2191 } else if (s1->do_debug ||
2192 file_type == TCC_OUTPUT_OBJ ||
2193 (s->sh_flags & SHF_ALLOC) ||
2194 i == (s1->nb_sections - 1)) {
2195 /* we output all sections if debug or object file */
2196 s->sh_size = s->data_offset;
2201 /* Info to be copied in dynamic section */
2202 struct dyn_inf {
2203 Section *dynamic;
2204 Section *dynstr;
2205 unsigned long dyn_rel_off;
2206 addr_t rel_addr;
2207 addr_t rel_size;
2208 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2209 addr_t bss_addr;
2210 addr_t bss_size;
2211 #endif
2214 /* Assign sections to segments and decide how are sections laid out when loaded
2215 in memory. This function also fills corresponding program headers. */
2216 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
2217 Section *interp, Section* strsec,
2218 struct dyn_inf *dyninf, int *sec_order)
2220 int i, j, k, file_type, sh_order_index, file_offset;
2221 unsigned long s_align;
2222 long long tmp;
2223 addr_t addr;
2224 ElfW(Phdr) *ph;
2225 Section *s;
2227 file_type = s1->output_type;
2228 sh_order_index = 1;
2229 file_offset = 0;
2230 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2231 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2232 s_align = ELF_PAGE_SIZE;
2233 if (s1->section_align)
2234 s_align = s1->section_align;
2236 if (phnum > 0) {
2237 if (s1->has_text_addr) {
2238 int a_offset, p_offset;
2239 addr = s1->text_addr;
2240 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
2241 ELF_PAGE_SIZE */
2242 a_offset = (int) (addr & (s_align - 1));
2243 p_offset = file_offset & (s_align - 1);
2244 if (a_offset < p_offset)
2245 a_offset += s_align;
2246 file_offset += (a_offset - p_offset);
2247 } else {
2248 if (file_type == TCC_OUTPUT_DLL)
2249 addr = 0;
2250 else
2251 addr = ELF_START_ADDR;
2252 /* compute address after headers */
2253 addr += (file_offset & (s_align - 1));
2256 ph = &phdr[0];
2257 /* Leave one program headers for the program interpreter and one for
2258 the program header table itself if needed. These are done later as
2259 they require section layout to be done first. */
2260 if (interp)
2261 ph += 1 + HAVE_PHDR;
2263 /* dynamic relocation table information, for .dynamic section */
2264 dyninf->rel_addr = dyninf->rel_size = 0;
2265 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2266 dyninf->bss_addr = dyninf->bss_size = 0;
2267 #endif
2269 for(j = 0; j < 2; j++) {
2270 ph->p_type = PT_LOAD;
2271 if (j == 0)
2272 ph->p_flags = PF_R | PF_X;
2273 else
2274 ph->p_flags = PF_R | PF_W;
2275 ph->p_align = s_align;
2277 /* Decide the layout of sections loaded in memory. This must
2278 be done before program headers are filled since they contain
2279 info about the layout. We do the following ordering: interp,
2280 symbol tables, relocations, progbits, nobits */
2281 /* XXX: do faster and simpler sorting */
2282 for(k = 0; k < 5; k++) {
2283 for(i = 1; i < s1->nb_sections; i++) {
2284 s = s1->sections[i];
2285 /* compute if section should be included */
2286 if (j == 0) {
2287 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
2288 SHF_ALLOC)
2289 continue;
2290 } else {
2291 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
2292 (SHF_ALLOC | SHF_WRITE))
2293 continue;
2295 if (s == interp) {
2296 if (k != 0)
2297 continue;
2298 } else if (s->sh_type == SHT_DYNSYM ||
2299 s->sh_type == SHT_STRTAB ||
2300 s->sh_type == SHT_HASH) {
2301 if (k != 1)
2302 continue;
2303 } else if (s->sh_type == SHT_RELX) {
2304 if (k != 2)
2305 continue;
2306 } else if (s->sh_type == SHT_NOBITS) {
2307 if (k != 4)
2308 continue;
2309 } else {
2310 if (k != 3)
2311 continue;
2313 sec_order[sh_order_index++] = i;
2315 /* section matches: we align it and add its size */
2316 tmp = addr;
2317 addr = (addr + s->sh_addralign - 1) &
2318 ~(s->sh_addralign - 1);
2319 file_offset += (int) ( addr - tmp );
2320 s->sh_offset = file_offset;
2321 s->sh_addr = addr;
2323 /* update program header infos */
2324 if (ph->p_offset == 0) {
2325 ph->p_offset = file_offset;
2326 ph->p_vaddr = addr;
2327 ph->p_paddr = ph->p_vaddr;
2329 /* update dynamic relocation infos */
2330 if (s->sh_type == SHT_RELX) {
2331 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2332 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
2333 dyninf->rel_addr = addr;
2334 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
2336 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
2337 dyninf->bss_addr = addr;
2338 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
2340 #else
2341 if (dyninf->rel_size == 0)
2342 dyninf->rel_addr = addr;
2343 dyninf->rel_size += s->sh_size;
2344 #endif
2346 addr += s->sh_size;
2347 if (s->sh_type != SHT_NOBITS)
2348 file_offset += s->sh_size;
2351 if (j == 0) {
2352 /* Make the first PT_LOAD segment include the program
2353 headers itself (and the ELF header as well), it'll
2354 come out with same memory use but will make various
2355 tools like binutils strip work better. */
2356 ph->p_offset &= ~(ph->p_align - 1);
2357 ph->p_vaddr &= ~(ph->p_align - 1);
2358 ph->p_paddr &= ~(ph->p_align - 1);
2360 ph->p_filesz = file_offset - ph->p_offset;
2361 ph->p_memsz = addr - ph->p_vaddr;
2362 ph++;
2363 if (j == 0) {
2364 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
2365 /* if in the middle of a page, we duplicate the page in
2366 memory so that one copy is RX and the other is RW */
2367 if ((addr & (s_align - 1)) != 0)
2368 addr += s_align;
2369 } else {
2370 addr = (addr + s_align - 1) & ~(s_align - 1);
2371 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
2377 /* all other sections come after */
2378 for(i = 1; i < s1->nb_sections; i++) {
2379 s = s1->sections[i];
2380 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
2381 continue;
2382 sec_order[sh_order_index++] = i;
2384 file_offset = (file_offset + s->sh_addralign - 1) &
2385 ~(s->sh_addralign - 1);
2386 s->sh_offset = file_offset;
2387 if (s->sh_type != SHT_NOBITS)
2388 file_offset += s->sh_size;
2391 return file_offset;
2394 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
2395 Section *dynamic)
2397 ElfW(Phdr) *ph;
2399 /* if interpreter, then add corresponding program header */
2400 if (interp) {
2401 ph = &phdr[0];
2403 if (HAVE_PHDR)
2405 int len = phnum * sizeof(ElfW(Phdr));
2407 ph->p_type = PT_PHDR;
2408 ph->p_offset = sizeof(ElfW(Ehdr));
2409 ph->p_vaddr = interp->sh_addr - len;
2410 ph->p_paddr = ph->p_vaddr;
2411 ph->p_filesz = ph->p_memsz = len;
2412 ph->p_flags = PF_R | PF_X;
2413 ph->p_align = 4; /* interp->sh_addralign; */
2414 ph++;
2417 ph->p_type = PT_INTERP;
2418 ph->p_offset = interp->sh_offset;
2419 ph->p_vaddr = interp->sh_addr;
2420 ph->p_paddr = ph->p_vaddr;
2421 ph->p_filesz = interp->sh_size;
2422 ph->p_memsz = interp->sh_size;
2423 ph->p_flags = PF_R;
2424 ph->p_align = interp->sh_addralign;
2427 /* if dynamic section, then add corresponding program header */
2428 if (dynamic) {
2429 ph = &phdr[phnum - 1];
2431 ph->p_type = PT_DYNAMIC;
2432 ph->p_offset = dynamic->sh_offset;
2433 ph->p_vaddr = dynamic->sh_addr;
2434 ph->p_paddr = ph->p_vaddr;
2435 ph->p_filesz = dynamic->sh_size;
2436 ph->p_memsz = dynamic->sh_size;
2437 ph->p_flags = PF_R | PF_W;
2438 ph->p_align = dynamic->sh_addralign;
2442 /* Fill the dynamic section with tags describing the address and size of
2443 sections */
2444 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2446 Section *dynamic;
2448 dynamic = dyninf->dynamic;
2450 /* put dynamic section entries */
2451 dynamic->data_offset = dyninf->dyn_rel_off;
2452 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2453 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2454 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2455 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2456 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2457 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2458 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2459 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2460 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2461 #else
2462 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2463 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2464 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
2465 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2466 put_dt(dynamic, DT_PLTREL, DT_REL);
2467 put_dt(dynamic, DT_REL, dyninf->bss_addr);
2468 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
2469 #else
2470 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2471 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2472 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2473 #endif
2474 #endif
2475 if (s1->do_debug)
2476 put_dt(dynamic, DT_DEBUG, 0);
2477 put_dt(dynamic, DT_NULL, 0);
2480 /* Relocate remaining sections and symbols (that is those not related to
2481 dynamic linking) */
2482 static int final_sections_reloc(TCCState *s1)
2484 int i;
2485 Section *s;
2487 relocate_syms(s1, 0);
2489 if (s1->nb_errors != 0)
2490 return -1;
2492 /* relocate sections */
2493 /* XXX: ignore sections with allocated relocations ? */
2494 for(i = 1; i < s1->nb_sections; i++) {
2495 s = s1->sections[i];
2496 #ifdef TCC_TARGET_I386
2497 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
2498 /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
2499 checking is removed */
2500 #else
2501 if (s->reloc && s != s1->got)
2502 /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
2503 #endif
2504 relocate_section(s1, s);
2507 /* relocate relocation entries if the relocation tables are
2508 allocated in the executable */
2509 for(i = 1; i < s1->nb_sections; i++) {
2510 s = s1->sections[i];
2511 if ((s->sh_flags & SHF_ALLOC) &&
2512 s->sh_type == SHT_RELX) {
2513 relocate_rel(s1, s);
2516 return 0;
2519 /* Create an ELF file on disk.
2520 This function handle ELF specific layout requirements */
2521 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2522 int file_offset, int *sec_order)
2524 int i, shnum, offset, size, file_type;
2525 Section *s;
2526 ElfW(Ehdr) ehdr;
2527 ElfW(Shdr) shdr, *sh;
2529 file_type = s1->output_type;
2530 shnum = s1->nb_sections;
2532 memset(&ehdr, 0, sizeof(ehdr));
2534 if (phnum > 0) {
2535 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2536 ehdr.e_phnum = phnum;
2537 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2540 /* align to 4 */
2541 file_offset = (file_offset + 3) & -4;
2543 /* fill header */
2544 ehdr.e_ident[0] = ELFMAG0;
2545 ehdr.e_ident[1] = ELFMAG1;
2546 ehdr.e_ident[2] = ELFMAG2;
2547 ehdr.e_ident[3] = ELFMAG3;
2548 ehdr.e_ident[4] = ELFCLASSW;
2549 ehdr.e_ident[5] = ELFDATA2LSB;
2550 ehdr.e_ident[6] = EV_CURRENT;
2551 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2552 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2553 #endif
2554 #ifdef TCC_TARGET_ARM
2555 #ifdef TCC_ARM_EABI
2556 ehdr.e_ident[EI_OSABI] = 0;
2557 ehdr.e_flags = EF_ARM_EABI_VER4;
2558 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2559 ehdr.e_flags |= EF_ARM_HASENTRY;
2560 if (s1->float_abi == ARM_HARD_FLOAT)
2561 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2562 else
2563 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2564 #else
2565 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2566 #endif
2567 #endif
2568 switch(file_type) {
2569 default:
2570 case TCC_OUTPUT_EXE:
2571 ehdr.e_type = ET_EXEC;
2572 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
2573 break;
2574 case TCC_OUTPUT_DLL:
2575 ehdr.e_type = ET_DYN;
2576 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2577 break;
2578 case TCC_OUTPUT_OBJ:
2579 ehdr.e_type = ET_REL;
2580 break;
2582 ehdr.e_machine = EM_TCC_TARGET;
2583 ehdr.e_version = EV_CURRENT;
2584 ehdr.e_shoff = file_offset;
2585 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2586 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2587 ehdr.e_shnum = shnum;
2588 ehdr.e_shstrndx = shnum - 1;
2590 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2591 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2592 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2594 sort_syms(s1, symtab_section);
2595 for(i = 1; i < s1->nb_sections; i++) {
2596 s = s1->sections[sec_order[i]];
2597 if (s->sh_type != SHT_NOBITS) {
2598 if (s->sh_type == SHT_DYNSYM)
2599 patch_dynsym_undef(s1, s);
2600 while (offset < s->sh_offset) {
2601 fputc(0, f);
2602 offset++;
2604 size = s->sh_size;
2605 if (size)
2606 fwrite(s->data, 1, size, f);
2607 offset += size;
2611 /* output section headers */
2612 while (offset < ehdr.e_shoff) {
2613 fputc(0, f);
2614 offset++;
2617 for(i = 0; i < s1->nb_sections; i++) {
2618 sh = &shdr;
2619 memset(sh, 0, sizeof(ElfW(Shdr)));
2620 s = s1->sections[i];
2621 if (s) {
2622 sh->sh_name = s->sh_name;
2623 sh->sh_type = s->sh_type;
2624 sh->sh_flags = s->sh_flags;
2625 sh->sh_entsize = s->sh_entsize;
2626 sh->sh_info = s->sh_info;
2627 if (s->link)
2628 sh->sh_link = s->link->sh_num;
2629 sh->sh_addralign = s->sh_addralign;
2630 sh->sh_addr = s->sh_addr;
2631 sh->sh_offset = s->sh_offset;
2632 sh->sh_size = s->sh_size;
2634 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2638 /* Write an elf, coff or "binary" file */
2639 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2640 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2642 int fd, mode, file_type;
2643 FILE *f;
2645 file_type = s1->output_type;
2646 if (file_type == TCC_OUTPUT_OBJ)
2647 mode = 0666;
2648 else
2649 mode = 0777;
2650 unlink(filename);
2651 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2652 if (fd < 0) {
2653 tcc_error_noabort("could not write '%s'", filename);
2654 return -1;
2656 f = fdopen(fd, "wb");
2657 if (s1->verbose)
2658 printf("<- %s\n", filename);
2660 #ifdef TCC_TARGET_COFF
2661 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2662 tcc_output_coff(s1, f);
2663 else
2664 #endif
2665 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2666 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2667 else
2668 tcc_output_binary(s1, f, sec_order);
2669 fclose(f);
2671 return 0;
2674 /* Output an elf, coff or binary file */
2675 /* XXX: suppress unneeded sections */
2676 static int elf_output_file(TCCState *s1, const char *filename)
2678 int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
2679 struct dyn_inf dyninf;
2680 ElfW(Phdr) *phdr;
2681 ElfW(Sym) *sym;
2682 Section *strsec, *interp, *dynamic, *dynstr;
2684 file_type = s1->output_type;
2685 s1->nb_errors = 0;
2687 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2688 if (file_type != TCC_OUTPUT_OBJ) {
2689 tcc_add_runtime(s1);
2692 phdr = NULL;
2693 sec_order = NULL;
2694 interp = dynamic = dynstr = NULL; /* avoid warning */
2695 dyninf.dyn_rel_off = 0; /* avoid warning */
2697 if (file_type != TCC_OUTPUT_OBJ) {
2698 relocate_common_syms();
2700 tcc_add_linker_symbols(s1);
2702 if (!s1->static_link) {
2703 if (file_type == TCC_OUTPUT_EXE) {
2704 char *ptr;
2705 /* allow override the dynamic loader */
2706 const char *elfint = getenv("LD_SO");
2707 if (elfint == NULL)
2708 elfint = DEFAULT_ELFINTERP(s1);
2709 /* add interpreter section only if executable */
2710 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2711 interp->sh_addralign = 1;
2712 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2713 strcpy(ptr, elfint);
2716 /* add dynamic symbol table */
2717 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2718 ".dynstr",
2719 ".hash", SHF_ALLOC);
2720 dynstr = s1->dynsym->link;
2722 /* add dynamic section */
2723 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2724 SHF_ALLOC | SHF_WRITE);
2725 dynamic->link = dynstr;
2726 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2728 build_got(s1);
2730 if (file_type == TCC_OUTPUT_EXE) {
2731 bind_exe_dynsyms(s1);
2733 if (s1->nb_errors) {
2734 ret = -1;
2735 goto the_end;
2738 bind_libs_dynsyms(s1);
2739 } else /* shared library case: simply export all global symbols */
2740 export_global_syms(s1);
2742 build_got_entries(s1);
2744 /* add a list of needed dlls */
2745 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2746 DLLReference *dllref = s1->loaded_dlls[i];
2747 if (dllref->level == 0)
2748 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2751 if (s1->rpath)
2752 put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath));
2754 /* XXX: currently, since we do not handle PIC code, we
2755 must relocate the readonly segments */
2756 if (file_type == TCC_OUTPUT_DLL) {
2757 if (s1->soname)
2758 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2759 put_dt(dynamic, DT_TEXTREL, 0);
2762 if (s1->symbolic)
2763 put_dt(dynamic, DT_SYMBOLIC, 0);
2765 /* add necessary space for other entries */
2766 dyninf.dyn_rel_off = dynamic->data_offset;
2767 dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
2768 } else {
2769 /* still need to build got entries in case of static link */
2770 build_got_entries(s1);
2774 /* we add a section for symbols */
2775 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2776 put_elf_str(strsec, "");
2778 /* compute number of sections */
2779 shnum = s1->nb_sections;
2781 /* this array is used to reorder sections in the output file */
2782 sec_order = tcc_malloc(sizeof(int) * shnum);
2783 sec_order[0] = 0;
2785 /* compute number of program headers */
2786 switch(file_type) {
2787 default:
2788 case TCC_OUTPUT_OBJ:
2789 phnum = 0;
2790 break;
2791 case TCC_OUTPUT_EXE:
2792 if (!s1->static_link)
2793 phnum = 4 + HAVE_PHDR;
2794 else
2795 phnum = 2;
2796 break;
2797 case TCC_OUTPUT_DLL:
2798 phnum = 3;
2799 break;
2802 /* Allocate strings for section names */
2803 alloc_sec_names(s1, file_type, strsec);
2805 /* allocate program segment headers */
2806 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2808 /* compute section to program header mapping */
2809 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2810 sec_order);
2812 /* Fill remaining program header and finalize relocation related to dynamic
2813 linking. */
2814 if (phnum > 0) {
2815 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2816 if (dynamic) {
2817 dyninf.dynamic = dynamic;
2818 dyninf.dynstr = dynstr;
2820 fill_dynamic(s1, &dyninf);
2822 /* put in GOT the dynamic section address and relocate PLT */
2823 write32le(s1->got->data, dynamic->sh_addr);
2824 if (file_type == TCC_OUTPUT_EXE
2825 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
2826 || file_type == TCC_OUTPUT_DLL
2827 #endif
2829 relocate_plt(s1);
2831 /* relocate symbols in .dynsym now that final addresses are known */
2832 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2833 if (sym->st_shndx == SHN_UNDEF) {
2834 /* relocate to PLT if symbol corresponds to a PLT entry,
2835 but not if it's a weak symbol */
2836 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
2837 sym->st_value = 0;
2838 else if (sym->st_value)
2839 sym->st_value += s1->plt->sh_addr;
2840 } else if (sym->st_shndx < SHN_LORESERVE) {
2841 /* do symbol relocation */
2842 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2848 /* if building executable or DLL, then relocate each section
2849 except the GOT which is already relocated */
2850 if (file_type != TCC_OUTPUT_OBJ) {
2851 ret = final_sections_reloc(s1);
2852 if (ret)
2853 goto the_end;
2856 /* Perform relocation to GOT or PLT entries */
2857 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2858 fill_got(s1);
2860 /* Create the ELF file with name 'filename' */
2861 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2862 the_end:
2863 tcc_free(s1->symtab_to_dynsym);
2864 tcc_free(sec_order);
2865 tcc_free(phdr);
2866 tcc_free(s1->sym_attrs);
2867 s1->sym_attrs = NULL;
2868 return ret;
2871 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2873 int ret;
2874 #ifdef TCC_TARGET_PE
2875 if (s->output_type != TCC_OUTPUT_OBJ) {
2876 ret = pe_output_file(s, filename);
2877 } else
2878 #endif
2879 ret = elf_output_file(s, filename);
2880 return ret;
2883 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2885 void *data;
2887 data = tcc_malloc(size);
2888 lseek(fd, file_offset, SEEK_SET);
2889 read(fd, data, size);
2890 return data;
2893 typedef struct SectionMergeInfo {
2894 Section *s; /* corresponding existing section */
2895 unsigned long offset; /* offset of the new section in the existing section */
2896 uint8_t new_section; /* true if section 's' was added */
2897 uint8_t link_once; /* true if link once section */
2898 } SectionMergeInfo;
2900 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2902 int size = read(fd, h, sizeof *h);
2903 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2904 if (h->e_type == ET_REL)
2905 return AFF_BINTYPE_REL;
2906 if (h->e_type == ET_DYN)
2907 return AFF_BINTYPE_DYN;
2908 } else if (size >= 8) {
2909 if (0 == memcmp(h, ARMAG, 8))
2910 return AFF_BINTYPE_AR;
2911 #ifdef TCC_TARGET_COFF
2912 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2913 return AFF_BINTYPE_C67;
2914 #endif
2916 return 0;
2919 /* load an object file and merge it with current files */
2920 /* XXX: handle correctly stab (debug) info */
2921 ST_FUNC int tcc_load_object_file(TCCState *s1,
2922 int fd, unsigned long file_offset)
2924 ElfW(Ehdr) ehdr;
2925 ElfW(Shdr) *shdr, *sh;
2926 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2927 unsigned char *strsec, *strtab;
2928 int *old_to_new_syms;
2929 char *sh_name, *name;
2930 SectionMergeInfo *sm_table, *sm;
2931 ElfW(Sym) *sym, *symtab;
2932 ElfW_Rel *rel;
2933 Section *s;
2935 int stab_index;
2936 int stabstr_index;
2938 stab_index = stabstr_index = 0;
2940 lseek(fd, file_offset, SEEK_SET);
2941 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2942 goto fail1;
2943 /* test CPU specific stuff */
2944 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2945 ehdr.e_machine != EM_TCC_TARGET) {
2946 fail1:
2947 tcc_error_noabort("invalid object file");
2948 return -1;
2950 /* read sections */
2951 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2952 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2953 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2955 /* load section names */
2956 sh = &shdr[ehdr.e_shstrndx];
2957 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2959 /* load symtab and strtab */
2960 old_to_new_syms = NULL;
2961 symtab = NULL;
2962 strtab = NULL;
2963 nb_syms = 0;
2964 for(i = 1; i < ehdr.e_shnum; i++) {
2965 sh = &shdr[i];
2966 if (sh->sh_type == SHT_SYMTAB) {
2967 if (symtab) {
2968 tcc_error_noabort("object must contain only one symtab");
2969 fail:
2970 ret = -1;
2971 goto the_end;
2973 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2974 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2975 sm_table[i].s = symtab_section;
2977 /* now load strtab */
2978 sh = &shdr[sh->sh_link];
2979 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2983 /* now examine each section and try to merge its content with the
2984 ones in memory */
2985 for(i = 1; i < ehdr.e_shnum; i++) {
2986 /* no need to examine section name strtab */
2987 if (i == ehdr.e_shstrndx)
2988 continue;
2989 sh = &shdr[i];
2990 sh_name = (char *) strsec + sh->sh_name;
2991 /* ignore sections types we do not handle */
2992 if (sh->sh_type != SHT_PROGBITS &&
2993 sh->sh_type != SHT_RELX &&
2994 #ifdef TCC_ARM_EABI
2995 sh->sh_type != SHT_ARM_EXIDX &&
2996 #endif
2997 sh->sh_type != SHT_NOBITS &&
2998 sh->sh_type != SHT_PREINIT_ARRAY &&
2999 sh->sh_type != SHT_INIT_ARRAY &&
3000 sh->sh_type != SHT_FINI_ARRAY &&
3001 strcmp(sh_name, ".stabstr")
3003 continue;
3004 if (sh->sh_addralign < 1)
3005 sh->sh_addralign = 1;
3006 /* find corresponding section, if any */
3007 for(j = 1; j < s1->nb_sections;j++) {
3008 s = s1->sections[j];
3009 if (!strcmp(s->name, sh_name)) {
3010 if (!strncmp(sh_name, ".gnu.linkonce",
3011 sizeof(".gnu.linkonce") - 1)) {
3012 /* if a 'linkonce' section is already present, we
3013 do not add it again. It is a little tricky as
3014 symbols can still be defined in
3015 it. */
3016 sm_table[i].link_once = 1;
3017 goto next;
3018 } else {
3019 goto found;
3023 /* not found: create new section */
3024 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
3025 /* take as much info as possible from the section. sh_link and
3026 sh_info will be updated later */
3027 s->sh_addralign = sh->sh_addralign;
3028 s->sh_entsize = sh->sh_entsize;
3029 sm_table[i].new_section = 1;
3030 found:
3031 if (sh->sh_type != s->sh_type) {
3032 tcc_error_noabort("invalid section type");
3033 goto fail;
3036 /* align start of section */
3037 offset = s->data_offset;
3039 if (0 == strcmp(sh_name, ".stab")) {
3040 stab_index = i;
3041 goto no_align;
3043 if (0 == strcmp(sh_name, ".stabstr")) {
3044 stabstr_index = i;
3045 goto no_align;
3048 size = sh->sh_addralign - 1;
3049 offset = (offset + size) & ~size;
3050 if (sh->sh_addralign > s->sh_addralign)
3051 s->sh_addralign = sh->sh_addralign;
3052 s->data_offset = offset;
3053 no_align:
3054 sm_table[i].offset = offset;
3055 sm_table[i].s = s;
3056 /* concatenate sections */
3057 size = sh->sh_size;
3058 if (sh->sh_type != SHT_NOBITS) {
3059 unsigned char *ptr;
3060 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
3061 ptr = section_ptr_add(s, size);
3062 read(fd, ptr, size);
3063 } else {
3064 s->data_offset += size;
3066 next: ;
3069 /* gr relocate stab strings */
3070 if (stab_index && stabstr_index) {
3071 Stab_Sym *a, *b;
3072 unsigned o;
3073 s = sm_table[stab_index].s;
3074 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
3075 b = (Stab_Sym *)(s->data + s->data_offset);
3076 o = sm_table[stabstr_index].offset;
3077 while (a < b)
3078 a->n_strx += o, a++;
3081 /* second short pass to update sh_link and sh_info fields of new
3082 sections */
3083 for(i = 1; i < ehdr.e_shnum; i++) {
3084 s = sm_table[i].s;
3085 if (!s || !sm_table[i].new_section)
3086 continue;
3087 sh = &shdr[i];
3088 if (sh->sh_link > 0)
3089 s->link = sm_table[sh->sh_link].s;
3090 if (sh->sh_type == SHT_RELX) {
3091 s->sh_info = sm_table[sh->sh_info].s->sh_num;
3092 /* update backward link */
3093 s1->sections[s->sh_info]->reloc = s;
3096 sm = sm_table;
3098 /* resolve symbols */
3099 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
3101 sym = symtab + 1;
3102 for(i = 1; i < nb_syms; i++, sym++) {
3103 if (sym->st_shndx != SHN_UNDEF &&
3104 sym->st_shndx < SHN_LORESERVE) {
3105 sm = &sm_table[sym->st_shndx];
3106 if (sm->link_once) {
3107 /* if a symbol is in a link once section, we use the
3108 already defined symbol. It is very important to get
3109 correct relocations */
3110 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
3111 name = (char *) strtab + sym->st_name;
3112 sym_index = find_elf_sym(symtab_section, name);
3113 if (sym_index)
3114 old_to_new_syms[i] = sym_index;
3116 continue;
3118 /* if no corresponding section added, no need to add symbol */
3119 if (!sm->s)
3120 continue;
3121 /* convert section number */
3122 sym->st_shndx = sm->s->sh_num;
3123 /* offset value */
3124 sym->st_value += sm->offset;
3126 /* add symbol */
3127 name = (char *) strtab + sym->st_name;
3128 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
3129 sym->st_info, sym->st_other,
3130 sym->st_shndx, name);
3131 old_to_new_syms[i] = sym_index;
3134 /* third pass to patch relocation entries */
3135 for(i = 1; i < ehdr.e_shnum; i++) {
3136 s = sm_table[i].s;
3137 if (!s)
3138 continue;
3139 sh = &shdr[i];
3140 offset = sm_table[i].offset;
3141 switch(s->sh_type) {
3142 case SHT_RELX:
3143 /* take relocation offset information */
3144 offseti = sm_table[sh->sh_info].offset;
3145 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
3146 int type;
3147 unsigned sym_index;
3148 /* convert symbol index */
3149 type = ELFW(R_TYPE)(rel->r_info);
3150 sym_index = ELFW(R_SYM)(rel->r_info);
3151 /* NOTE: only one symtab assumed */
3152 if (sym_index >= nb_syms)
3153 goto invalid_reloc;
3154 sym_index = old_to_new_syms[sym_index];
3155 /* ignore link_once in rel section. */
3156 if (!sym_index && !sm->link_once
3157 #ifdef TCC_TARGET_ARM
3158 && type != R_ARM_V4BX
3159 #endif
3161 invalid_reloc:
3162 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3163 i, strsec + sh->sh_name, rel->r_offset);
3164 goto fail;
3166 rel->r_info = ELFW(R_INFO)(sym_index, type);
3167 /* offset the relocation offset */
3168 rel->r_offset += offseti;
3169 #ifdef TCC_TARGET_ARM
3170 /* Jumps and branches from a Thumb code to a PLT entry need
3171 special handling since PLT entries are ARM code.
3172 Unconditional bl instructions referencing PLT entries are
3173 handled by converting these instructions into blx
3174 instructions. Other case of instructions referencing a PLT
3175 entry require to add a Thumb stub before the PLT entry to
3176 switch to ARM mode. We set bit plt_thumb_stub of the
3177 attribute of a symbol to indicate such a case. */
3178 if (type == R_ARM_THM_JUMP24)
3179 alloc_sym_attr(s1, sym_index)->plt_thumb_stub = 1;
3180 #endif
3182 break;
3183 default:
3184 break;
3188 ret = 0;
3189 the_end:
3190 tcc_free(symtab);
3191 tcc_free(strtab);
3192 tcc_free(old_to_new_syms);
3193 tcc_free(sm_table);
3194 tcc_free(strsec);
3195 tcc_free(shdr);
3196 return ret;
3199 typedef struct ArchiveHeader {
3200 char ar_name[16]; /* name of this member */
3201 char ar_date[12]; /* file mtime */
3202 char ar_uid[6]; /* owner uid; printed as decimal */
3203 char ar_gid[6]; /* owner gid; printed as decimal */
3204 char ar_mode[8]; /* file mode, printed as octal */
3205 char ar_size[10]; /* file size, printed as decimal */
3206 char ar_fmag[2]; /* should contain ARFMAG */
3207 } ArchiveHeader;
3209 static int get_be32(const uint8_t *b)
3211 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
3214 static long get_be64(const uint8_t *b)
3216 long long ret = get_be32(b);
3217 ret = (ret << 32) | (unsigned)get_be32(b+4);
3218 return (long)ret;
3221 /* load only the objects which resolve undefined symbols */
3222 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
3224 long i, bound, nsyms, sym_index, off, ret;
3225 uint8_t *data;
3226 const char *ar_names, *p;
3227 const uint8_t *ar_index;
3228 ElfW(Sym) *sym;
3230 data = tcc_malloc(size);
3231 if (read(fd, data, size) != size)
3232 goto fail;
3233 nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
3234 ar_index = data + entrysize;
3235 ar_names = (char *) ar_index + nsyms * entrysize;
3237 do {
3238 bound = 0;
3239 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
3240 sym_index = find_elf_sym(symtab_section, p);
3241 if(sym_index) {
3242 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
3243 if(sym->st_shndx == SHN_UNDEF) {
3244 off = (entrysize == 4
3245 ? get_be32(ar_index + i * 4)
3246 : get_be64(ar_index + i * 8))
3247 + sizeof(ArchiveHeader);
3248 ++bound;
3249 if(tcc_load_object_file(s1, fd, off) < 0) {
3250 fail:
3251 ret = -1;
3252 goto the_end;
3257 } while(bound);
3258 ret = 0;
3259 the_end:
3260 tcc_free(data);
3261 return ret;
3264 /* load a '.a' file */
3265 ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
3267 ArchiveHeader hdr;
3268 char ar_size[11];
3269 char ar_name[17];
3270 char magic[8];
3271 int size, len, i;
3272 unsigned long file_offset;
3274 /* skip magic which was already checked */
3275 read(fd, magic, sizeof(magic));
3277 for(;;) {
3278 len = read(fd, &hdr, sizeof(hdr));
3279 if (len == 0)
3280 break;
3281 if (len != sizeof(hdr)) {
3282 tcc_error_noabort("invalid archive");
3283 return -1;
3285 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
3286 ar_size[sizeof(hdr.ar_size)] = '\0';
3287 size = strtol(ar_size, NULL, 0);
3288 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
3289 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
3290 if (ar_name[i] != ' ')
3291 break;
3293 ar_name[i + 1] = '\0';
3294 file_offset = lseek(fd, 0, SEEK_CUR);
3295 /* align to even */
3296 size = (size + 1) & ~1;
3297 if (!strcmp(ar_name, "/")) {
3298 /* coff symbol table : we handle it */
3299 if(s1->alacarte_link)
3300 return tcc_load_alacarte(s1, fd, size, 4);
3301 } else if (!strcmp(ar_name, "/SYM64/")) {
3302 if(s1->alacarte_link)
3303 return tcc_load_alacarte(s1, fd, size, 8);
3304 } else {
3305 ElfW(Ehdr) ehdr;
3306 if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3307 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3308 return -1;
3311 lseek(fd, file_offset + size, SEEK_SET);
3313 return 0;
3316 #ifndef TCC_TARGET_PE
3317 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3318 is referenced by the user (so it should be added as DT_NEEDED in
3319 the generated ELF file) */
3320 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3322 ElfW(Ehdr) ehdr;
3323 ElfW(Shdr) *shdr, *sh, *sh1;
3324 int i, j, nb_syms, nb_dts, sym_bind, ret;
3325 ElfW(Sym) *sym, *dynsym;
3326 ElfW(Dyn) *dt, *dynamic;
3327 unsigned char *dynstr;
3328 const char *name, *soname;
3329 DLLReference *dllref;
3331 read(fd, &ehdr, sizeof(ehdr));
3333 /* test CPU specific stuff */
3334 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3335 ehdr.e_machine != EM_TCC_TARGET) {
3336 tcc_error_noabort("bad architecture");
3337 return -1;
3340 /* read sections */
3341 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3343 /* load dynamic section and dynamic symbols */
3344 nb_syms = 0;
3345 nb_dts = 0;
3346 dynamic = NULL;
3347 dynsym = NULL; /* avoid warning */
3348 dynstr = NULL; /* avoid warning */
3349 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3350 switch(sh->sh_type) {
3351 case SHT_DYNAMIC:
3352 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3353 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3354 break;
3355 case SHT_DYNSYM:
3356 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3357 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3358 sh1 = &shdr[sh->sh_link];
3359 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3360 break;
3361 default:
3362 break;
3366 /* compute the real library name */
3367 soname = tcc_basename(filename);
3369 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3370 if (dt->d_tag == DT_SONAME) {
3371 soname = (char *) dynstr + dt->d_un.d_val;
3375 /* if the dll is already loaded, do not load it */
3376 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3377 dllref = s1->loaded_dlls[i];
3378 if (!strcmp(soname, dllref->name)) {
3379 /* but update level if needed */
3380 if (level < dllref->level)
3381 dllref->level = level;
3382 ret = 0;
3383 goto the_end;
3387 /* add the dll and its level */
3388 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
3389 dllref->level = level;
3390 strcpy(dllref->name, soname);
3391 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
3393 /* add dynamic symbols in dynsym_section */
3394 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3395 sym_bind = ELFW(ST_BIND)(sym->st_info);
3396 if (sym_bind == STB_LOCAL)
3397 continue;
3398 name = (char *) dynstr + sym->st_name;
3399 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3400 sym->st_info, sym->st_other, sym->st_shndx, name);
3403 /* load all referenced DLLs */
3404 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3405 switch(dt->d_tag) {
3406 case DT_NEEDED:
3407 name = (char *) dynstr + dt->d_un.d_val;
3408 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3409 dllref = s1->loaded_dlls[j];
3410 if (!strcmp(name, dllref->name))
3411 goto already_loaded;
3413 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3414 tcc_error_noabort("referenced dll '%s' not found", name);
3415 ret = -1;
3416 goto the_end;
3418 already_loaded:
3419 break;
3422 ret = 0;
3423 the_end:
3424 tcc_free(dynstr);
3425 tcc_free(dynsym);
3426 tcc_free(dynamic);
3427 tcc_free(shdr);
3428 return ret;
3431 #define LD_TOK_NAME 256
3432 #define LD_TOK_EOF (-1)
3434 /* return next ld script token */
3435 static int ld_next(TCCState *s1, char *name, int name_size)
3437 int c;
3438 char *q;
3440 redo:
3441 switch(ch) {
3442 case ' ':
3443 case '\t':
3444 case '\f':
3445 case '\v':
3446 case '\r':
3447 case '\n':
3448 inp();
3449 goto redo;
3450 case '/':
3451 minp();
3452 if (ch == '*') {
3453 file->buf_ptr = parse_comment(file->buf_ptr);
3454 ch = file->buf_ptr[0];
3455 goto redo;
3456 } else {
3457 q = name;
3458 *q++ = '/';
3459 goto parse_name;
3461 break;
3462 case '\\':
3463 ch = handle_eob();
3464 if (ch != '\\')
3465 goto redo;
3466 /* fall through */
3467 /* case 'a' ... 'z': */
3468 case 'a':
3469 case 'b':
3470 case 'c':
3471 case 'd':
3472 case 'e':
3473 case 'f':
3474 case 'g':
3475 case 'h':
3476 case 'i':
3477 case 'j':
3478 case 'k':
3479 case 'l':
3480 case 'm':
3481 case 'n':
3482 case 'o':
3483 case 'p':
3484 case 'q':
3485 case 'r':
3486 case 's':
3487 case 't':
3488 case 'u':
3489 case 'v':
3490 case 'w':
3491 case 'x':
3492 case 'y':
3493 case 'z':
3494 /* case 'A' ... 'z': */
3495 case 'A':
3496 case 'B':
3497 case 'C':
3498 case 'D':
3499 case 'E':
3500 case 'F':
3501 case 'G':
3502 case 'H':
3503 case 'I':
3504 case 'J':
3505 case 'K':
3506 case 'L':
3507 case 'M':
3508 case 'N':
3509 case 'O':
3510 case 'P':
3511 case 'Q':
3512 case 'R':
3513 case 'S':
3514 case 'T':
3515 case 'U':
3516 case 'V':
3517 case 'W':
3518 case 'X':
3519 case 'Y':
3520 case 'Z':
3521 case '_':
3522 case '.':
3523 case '$':
3524 case '~':
3525 q = name;
3526 parse_name:
3527 for(;;) {
3528 if (!((ch >= 'a' && ch <= 'z') ||
3529 (ch >= 'A' && ch <= 'Z') ||
3530 (ch >= '0' && ch <= '9') ||
3531 strchr("/.-_+=$:\\,~", ch)))
3532 break;
3533 if ((q - name) < name_size - 1) {
3534 *q++ = ch;
3536 minp();
3538 *q = '\0';
3539 c = LD_TOK_NAME;
3540 break;
3541 case CH_EOF:
3542 c = LD_TOK_EOF;
3543 break;
3544 default:
3545 c = ch;
3546 inp();
3547 break;
3549 return c;
3552 static int ld_add_file(TCCState *s1, const char filename[])
3554 int ret;
3556 ret = tcc_add_file_internal(s1, filename, AFF_TYPE_BIN);
3557 if (ret)
3558 ret = tcc_add_dll(s1, filename, 0);
3559 return ret;
3562 static inline int new_undef_syms(void)
3564 int ret = 0;
3565 ret = new_undef_sym;
3566 new_undef_sym = 0;
3567 return ret;
3570 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3572 char filename[1024], libname[1024];
3573 int t, group, nblibs = 0, ret = 0;
3574 char **libs = NULL;
3576 group = !strcmp(cmd, "GROUP");
3577 if (!as_needed)
3578 new_undef_syms();
3579 t = ld_next(s1, filename, sizeof(filename));
3580 if (t != '(')
3581 expect("(");
3582 t = ld_next(s1, filename, sizeof(filename));
3583 for(;;) {
3584 libname[0] = '\0';
3585 if (t == LD_TOK_EOF) {
3586 tcc_error_noabort("unexpected end of file");
3587 ret = -1;
3588 goto lib_parse_error;
3589 } else if (t == ')') {
3590 break;
3591 } else if (t == '-') {
3592 t = ld_next(s1, filename, sizeof(filename));
3593 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3594 tcc_error_noabort("library name expected");
3595 ret = -1;
3596 goto lib_parse_error;
3598 pstrcpy(libname, sizeof libname, &filename[1]);
3599 if (s1->static_link) {
3600 snprintf(filename, sizeof filename, "lib%s.a", libname);
3601 } else {
3602 snprintf(filename, sizeof filename, "lib%s.so", libname);
3604 } else if (t != LD_TOK_NAME) {
3605 tcc_error_noabort("filename expected");
3606 ret = -1;
3607 goto lib_parse_error;
3609 if (!strcmp(filename, "AS_NEEDED")) {
3610 ret = ld_add_file_list(s1, cmd, 1);
3611 if (ret)
3612 goto lib_parse_error;
3613 } else {
3614 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3615 if (!as_needed) {
3616 ret = ld_add_file(s1, filename);
3617 if (ret)
3618 goto lib_parse_error;
3619 if (group) {
3620 /* Add the filename *and* the libname to avoid future conversions */
3621 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename));
3622 if (libname[0] != '\0')
3623 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname));
3627 t = ld_next(s1, filename, sizeof(filename));
3628 if (t == ',') {
3629 t = ld_next(s1, filename, sizeof(filename));
3632 if (group && !as_needed) {
3633 while (new_undef_syms()) {
3634 int i;
3636 for (i = 0; i < nblibs; i ++)
3637 ld_add_file(s1, libs[i]);
3640 lib_parse_error:
3641 dynarray_reset(&libs, &nblibs);
3642 return ret;
3645 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3646 files */
3647 ST_FUNC int tcc_load_ldscript(TCCState *s1)
3649 char cmd[64];
3650 char filename[1024];
3651 int t, ret;
3653 ch = handle_eob();
3654 for(;;) {
3655 t = ld_next(s1, cmd, sizeof(cmd));
3656 if (t == LD_TOK_EOF)
3657 return 0;
3658 else if (t != LD_TOK_NAME)
3659 return -1;
3660 if (!strcmp(cmd, "INPUT") ||
3661 !strcmp(cmd, "GROUP")) {
3662 ret = ld_add_file_list(s1, cmd, 0);
3663 if (ret)
3664 return ret;
3665 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3666 !strcmp(cmd, "TARGET")) {
3667 /* ignore some commands */
3668 t = ld_next(s1, cmd, sizeof(cmd));
3669 if (t != '(')
3670 expect("(");
3671 for(;;) {
3672 t = ld_next(s1, filename, sizeof(filename));
3673 if (t == LD_TOK_EOF) {
3674 tcc_error_noabort("unexpected end of file");
3675 return -1;
3676 } else if (t == ')') {
3677 break;
3680 } else {
3681 return -1;
3684 return 0;
3686 #endif /* !TCC_TARGET_PE */