Fix error logic for undefined reference in library
[tinycc.git] / tccelf.c
blob9b019a2cda485db37f6e8c86979870a9137cdc93
1 /*
2 * ELF file handling for TCC
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "tcc.h"
23 /* Define this to get some debug output during relocation processing. */
24 #undef DEBUG_RELOC
26 /********************************************************/
27 /* global variables */
29 ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
30 ST_DATA Section *cur_text_section; /* current section where function code is generated */
31 #ifdef CONFIG_TCC_ASM
32 ST_DATA Section *last_text_section; /* to handle .previous asm directive */
33 #endif
34 #ifdef CONFIG_TCC_BCHECK
35 /* bound check related sections */
36 ST_DATA Section *bounds_section; /* contains global data bound description */
37 ST_DATA Section *lbounds_section; /* contains local data bound description */
38 #endif
39 /* symbol sections */
40 ST_DATA Section *symtab_section, *strtab_section;
41 /* debug sections */
42 ST_DATA Section *stab_section, *stabstr_section;
44 /* XXX: avoid static variable */
45 static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */
47 /* ------------------------------------------------------------------------- */
49 ST_FUNC void tccelf_new(TCCState *s)
51 /* no section zero */
52 dynarray_add((void ***)&s->sections, &s->nb_sections, NULL);
54 /* create standard sections */
55 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
56 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
57 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
59 /* symbols are always generated for linking stage */
60 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
61 ".strtab",
62 ".hashtab", SHF_PRIVATE);
63 strtab_section = symtab_section->link;
64 s->symtab = symtab_section;
66 /* private symbol table for dynamic symbols */
67 s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE,
68 ".dynstrtab",
69 ".dynhashtab", SHF_PRIVATE);
72 #ifdef CONFIG_TCC_BCHECK
73 ST_FUNC void tccelf_bounds_new(TCCState *s)
75 /* create bounds sections */
76 bounds_section = new_section(s, ".bounds",
77 SHT_PROGBITS, SHF_ALLOC);
78 lbounds_section = new_section(s, ".lbounds",
79 SHT_PROGBITS, SHF_ALLOC);
81 #endif
83 ST_FUNC void tccelf_stab_new(TCCState *s)
85 stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
86 stab_section->sh_entsize = sizeof(Stab_Sym);
87 stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
88 put_elf_str(stabstr_section, "");
89 stab_section->link = stabstr_section;
90 /* put first entry */
91 put_stabs("", 0, 0, 0, 0);
94 static void free_section(Section *s)
96 tcc_free(s->data);
99 ST_FUNC void tccelf_delete(TCCState *s1)
101 int i;
103 /* free all sections */
104 for(i = 1; i < s1->nb_sections; i++)
105 free_section(s1->sections[i]);
106 dynarray_reset(&s1->sections, &s1->nb_sections);
108 for(i = 0; i < s1->nb_priv_sections; i++)
109 free_section(s1->priv_sections[i]);
110 dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
112 /* free any loaded DLLs */
113 #ifdef TCC_IS_NATIVE
114 for ( i = 0; i < s1->nb_loaded_dlls; i++) {
115 DLLReference *ref = s1->loaded_dlls[i];
116 if ( ref->handle )
117 # ifdef _WIN32
118 FreeLibrary((HMODULE)ref->handle);
119 # else
120 dlclose(ref->handle);
121 # endif
123 #endif
124 /* free loaded dlls array */
125 dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
128 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
130 Section *sec;
132 sec = tcc_mallocz(sizeof(Section) + strlen(name));
133 strcpy(sec->name, name);
134 sec->sh_type = sh_type;
135 sec->sh_flags = sh_flags;
136 switch(sh_type) {
137 case SHT_HASH:
138 case SHT_REL:
139 case SHT_RELA:
140 case SHT_DYNSYM:
141 case SHT_SYMTAB:
142 case SHT_DYNAMIC:
143 sec->sh_addralign = 4;
144 break;
145 case SHT_STRTAB:
146 sec->sh_addralign = 1;
147 break;
148 default:
149 sec->sh_addralign = PTR_SIZE; /* gcc/pcc default aligment */
150 break;
153 if (sh_flags & SHF_PRIVATE) {
154 dynarray_add((void ***)&s1->priv_sections, &s1->nb_priv_sections, sec);
155 } else {
156 sec->sh_num = s1->nb_sections;
157 dynarray_add((void ***)&s1->sections, &s1->nb_sections, sec);
160 return sec;
163 /* realloc section and set its content to zero */
164 ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
166 unsigned long size;
167 unsigned char *data;
169 size = sec->data_allocated;
170 if (size == 0)
171 size = 1;
172 while (size < new_size)
173 size = size * 2;
174 data = tcc_realloc(sec->data, size);
175 memset(data + sec->data_allocated, 0, size - sec->data_allocated);
176 sec->data = data;
177 sec->data_allocated = size;
180 /* reserve at least 'size' bytes in section 'sec' from
181 sec->data_offset. */
182 ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
184 size_t offset, offset1;
186 offset = sec->data_offset;
187 offset1 = offset + size;
188 if (offset1 > sec->data_allocated)
189 section_realloc(sec, offset1);
190 sec->data_offset = offset1;
191 return sec->data + offset;
194 /* reserve at least 'size' bytes from section start */
195 ST_FUNC void section_reserve(Section *sec, unsigned long size)
197 if (size > sec->data_allocated)
198 section_realloc(sec, size);
199 if (size > sec->data_offset)
200 sec->data_offset = size;
203 /* return a reference to a section, and create it if it does not
204 exists */
205 ST_FUNC Section *find_section(TCCState *s1, const char *name)
207 Section *sec;
208 int i;
209 for(i = 1; i < s1->nb_sections; i++) {
210 sec = s1->sections[i];
211 if (!strcmp(name, sec->name))
212 return sec;
214 /* sections are created as PROGBITS */
215 return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
218 /* ------------------------------------------------------------------------- */
220 ST_FUNC int put_elf_str(Section *s, const char *sym)
222 int offset, len;
223 char *ptr;
225 len = strlen(sym) + 1;
226 offset = s->data_offset;
227 ptr = section_ptr_add(s, len);
228 memcpy(ptr, sym, len);
229 return offset;
232 /* elf symbol hashing function */
233 static unsigned long elf_hash(const unsigned char *name)
235 unsigned long h = 0, g;
237 while (*name) {
238 h = (h << 4) + *name++;
239 g = h & 0xf0000000;
240 if (g)
241 h ^= g >> 24;
242 h &= ~g;
244 return h;
247 /* rebuild hash table of section s */
248 /* NOTE: we do factorize the hash table code to go faster */
249 static void rebuild_hash(Section *s, unsigned int nb_buckets)
251 ElfW(Sym) *sym;
252 int *ptr, *hash, nb_syms, sym_index, h;
253 unsigned char *strtab;
255 strtab = s->link->data;
256 nb_syms = s->data_offset / sizeof(ElfW(Sym));
258 s->hash->data_offset = 0;
259 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
260 ptr[0] = nb_buckets;
261 ptr[1] = nb_syms;
262 ptr += 2;
263 hash = ptr;
264 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
265 ptr += nb_buckets + 1;
267 sym = (ElfW(Sym) *)s->data + 1;
268 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
269 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
270 h = elf_hash(strtab + sym->st_name) % nb_buckets;
271 *ptr = hash[h];
272 hash[h] = sym_index;
273 } else {
274 *ptr = 0;
276 ptr++;
277 sym++;
281 /* return the symbol number */
282 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
283 int info, int other, int shndx, const char *name)
285 int name_offset, sym_index;
286 int nbuckets, h;
287 ElfW(Sym) *sym;
288 Section *hs;
290 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
291 if (name)
292 name_offset = put_elf_str(s->link, name);
293 else
294 name_offset = 0;
295 /* XXX: endianness */
296 sym->st_name = name_offset;
297 sym->st_value = value;
298 sym->st_size = size;
299 sym->st_info = info;
300 sym->st_other = other;
301 sym->st_shndx = shndx;
302 sym_index = sym - (ElfW(Sym) *)s->data;
303 hs = s->hash;
304 if (hs) {
305 int *ptr, *base;
306 ptr = section_ptr_add(hs, sizeof(int));
307 base = (int *)hs->data;
308 /* only add global or weak symbols */
309 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
310 /* add another hashing entry */
311 nbuckets = base[0];
312 h = elf_hash((unsigned char *) name) % nbuckets;
313 *ptr = base[2 + h];
314 base[2 + h] = sym_index;
315 base[1]++;
316 /* we resize the hash table */
317 hs->nb_hashed_syms++;
318 if (hs->nb_hashed_syms > 2 * nbuckets) {
319 rebuild_hash(s, 2 * nbuckets);
321 } else {
322 *ptr = 0;
323 base[1]++;
326 return sym_index;
329 /* find global ELF symbol 'name' and return its index. Return 0 if not
330 found. */
331 ST_FUNC int find_elf_sym(Section *s, const char *name)
333 ElfW(Sym) *sym;
334 Section *hs;
335 int nbuckets, sym_index, h;
336 const char *name1;
338 hs = s->hash;
339 if (!hs)
340 return 0;
341 nbuckets = ((int *)hs->data)[0];
342 h = elf_hash((unsigned char *) name) % nbuckets;
343 sym_index = ((int *)hs->data)[2 + h];
344 while (sym_index != 0) {
345 sym = &((ElfW(Sym) *)s->data)[sym_index];
346 name1 = (char *) s->link->data + sym->st_name;
347 if (!strcmp(name, name1))
348 return sym_index;
349 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
351 return 0;
354 /* return elf symbol value, signal error if 'err' is nonzero */
355 ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err)
357 int sym_index;
358 ElfW(Sym) *sym;
360 sym_index = find_elf_sym(s->symtab, name);
361 sym = &((ElfW(Sym) *)s->symtab->data)[sym_index];
362 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
363 if (err)
364 tcc_error("%s not defined", name);
365 return 0;
367 return sym->st_value;
370 /* return elf symbol value */
371 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
373 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0);
376 #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
377 /* return elf symbol value or error */
378 ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
380 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1);
382 #endif
384 /* add an elf symbol : check if it is already defined and patch
385 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
386 ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size,
387 int info, int other, int sh_num, const char *name)
389 ElfW(Sym) *esym;
390 int sym_bind, sym_index, sym_type, esym_bind;
391 unsigned char sym_vis, esym_vis, new_vis;
393 sym_bind = ELFW(ST_BIND)(info);
394 sym_type = ELFW(ST_TYPE)(info);
395 sym_vis = ELFW(ST_VISIBILITY)(other);
397 if (sym_bind != STB_LOCAL) {
398 /* we search global or weak symbols */
399 sym_index = find_elf_sym(s, name);
400 if (!sym_index)
401 goto do_def;
402 esym = &((ElfW(Sym) *)s->data)[sym_index];
403 if (esym->st_shndx != SHN_UNDEF) {
404 esym_bind = ELFW(ST_BIND)(esym->st_info);
405 /* propagate the most constraining visibility */
406 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
407 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
408 if (esym_vis == STV_DEFAULT) {
409 new_vis = sym_vis;
410 } else if (sym_vis == STV_DEFAULT) {
411 new_vis = esym_vis;
412 } else {
413 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
415 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
416 | new_vis;
417 other = esym->st_other; /* in case we have to patch esym */
418 if (sh_num == SHN_UNDEF) {
419 /* ignore adding of undefined symbol if the
420 corresponding symbol is already defined */
421 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
422 /* global overrides weak, so patch */
423 goto do_patch;
424 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
425 /* weak is ignored if already global */
426 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
427 /* keep first-found weak definition, ignore subsequents */
428 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
429 /* ignore hidden symbols after */
430 } else if ((esym->st_shndx == SHN_COMMON
431 || esym->st_shndx == bss_section->sh_num)
432 && (sh_num < SHN_LORESERVE
433 && sh_num != bss_section->sh_num)) {
434 /* data symbol gets precedence over common/bss */
435 goto do_patch;
436 } else if (sh_num == SHN_COMMON || sh_num == bss_section->sh_num) {
437 /* data symbol keeps precedence over common/bss */
438 } else if (s == tcc_state->dynsymtab_section) {
439 /* we accept that two DLL define the same symbol */
440 } else {
441 #if 0
442 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
443 sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
444 #endif
445 tcc_error_noabort("'%s' defined twice", name);
447 } else {
448 do_patch:
449 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
450 esym->st_shndx = sh_num;
451 new_undef_sym = 1;
452 esym->st_value = value;
453 esym->st_size = size;
454 esym->st_other = other;
456 } else {
457 do_def:
458 sym_index = put_elf_sym(s, value, size,
459 ELFW(ST_INFO)(sym_bind, sym_type), other,
460 sh_num, name);
462 return sym_index;
465 /* put relocation */
466 ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
467 int type, int symbol, addr_t addend)
469 char buf[256];
470 Section *sr;
471 ElfW_Rel *rel;
473 sr = s->reloc;
474 if (!sr) {
475 /* if no relocation section, create it */
476 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
477 /* if the symtab is allocated, then we consider the relocation
478 are also */
479 sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
480 sr->sh_entsize = sizeof(ElfW_Rel);
481 sr->link = symtab;
482 sr->sh_info = s->sh_num;
483 s->reloc = sr;
485 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
486 rel->r_offset = offset;
487 rel->r_info = ELFW(R_INFO)(symbol, type);
488 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
489 rel->r_addend = addend;
490 #else
491 if (addend)
492 tcc_error("non-zero addend on REL architecture");
493 #endif
496 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
497 int type, int symbol)
499 put_elf_reloca(symtab, s, offset, type, symbol, 0);
502 /* put stab debug information */
504 ST_FUNC void put_stabs(const char *str, int type, int other, int desc,
505 unsigned long value)
507 Stab_Sym *sym;
509 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
510 if (str) {
511 sym->n_strx = put_elf_str(stabstr_section, str);
512 } else {
513 sym->n_strx = 0;
515 sym->n_type = type;
516 sym->n_other = other;
517 sym->n_desc = desc;
518 sym->n_value = value;
521 ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc,
522 unsigned long value, Section *sec, int sym_index)
524 put_stabs(str, type, other, desc, value);
525 put_elf_reloc(symtab_section, stab_section,
526 stab_section->data_offset - sizeof(unsigned int),
527 R_DATA_32, sym_index);
530 ST_FUNC void put_stabn(int type, int other, int desc, int value)
532 put_stabs(NULL, type, other, desc, value);
535 ST_FUNC void put_stabd(int type, int other, int desc)
537 put_stabs(NULL, type, other, desc, 0);
540 /* Browse each elem of type <type> in section <sec> starting at elem <startoff>
541 using variable <elem> */
542 #define for_each_elem(sec, startoff, elem, type) \
543 for (elem = (type *) sec->data + startoff; \
544 elem < (type *) (sec->data + sec->data_offset); elem++)
546 /* In an ELF file symbol table, the local symbols must appear below
547 the global and weak ones. Since TCC cannot sort it while generating
548 the code, we must do it after. All the relocation tables are also
549 modified to take into account the symbol table sorting */
550 static void sort_syms(TCCState *s1, Section *s)
552 int *old_to_new_syms;
553 ElfW(Sym) *new_syms;
554 int nb_syms, i;
555 ElfW(Sym) *p, *q;
556 ElfW_Rel *rel;
557 Section *sr;
558 int type, sym_index;
560 nb_syms = s->data_offset / sizeof(ElfW(Sym));
561 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
562 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
564 /* first pass for local symbols */
565 p = (ElfW(Sym) *)s->data;
566 q = new_syms;
567 for(i = 0; i < nb_syms; i++) {
568 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
569 old_to_new_syms[i] = q - new_syms;
570 *q++ = *p;
572 p++;
574 /* save the number of local symbols in section header */
575 s->sh_info = q - new_syms;
577 /* then second pass for non local symbols */
578 p = (ElfW(Sym) *)s->data;
579 for(i = 0; i < nb_syms; i++) {
580 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
581 old_to_new_syms[i] = q - new_syms;
582 *q++ = *p;
584 p++;
587 /* we copy the new symbols to the old */
588 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
589 tcc_free(new_syms);
591 /* now we modify all the relocations */
592 for(i = 1; i < s1->nb_sections; i++) {
593 sr = s1->sections[i];
594 if (sr->sh_type == SHT_RELX && sr->link == s) {
595 for_each_elem(sr, 0, rel, ElfW_Rel) {
596 sym_index = ELFW(R_SYM)(rel->r_info);
597 type = ELFW(R_TYPE)(rel->r_info);
598 sym_index = old_to_new_syms[sym_index];
599 rel->r_info = ELFW(R_INFO)(sym_index, type);
604 tcc_free(old_to_new_syms);
607 /* relocate common symbols in the .bss section */
608 ST_FUNC void relocate_common_syms(void)
610 ElfW(Sym) *sym;
611 unsigned long offset, align;
613 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
614 if (sym->st_shndx == SHN_COMMON) {
615 /* align symbol */
616 align = sym->st_value;
617 offset = bss_section->data_offset;
618 offset = (offset + align - 1) & -align;
619 sym->st_value = offset;
620 sym->st_shndx = bss_section->sh_num;
621 offset += sym->st_size;
622 bss_section->data_offset = offset;
627 /* relocate symbol table, resolve undefined symbols if do_resolve is
628 true and output error if undefined symbol. */
629 ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
631 ElfW(Sym) *sym, *esym;
632 int sym_bind, sh_num, sym_index;
633 const char *name;
635 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
636 sh_num = sym->st_shndx;
637 if (sh_num == SHN_UNDEF) {
638 name = (char *) strtab_section->data + sym->st_name;
639 /* Use ld.so to resolve symbol for us (for tcc -run) */
640 if (do_resolve) {
641 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
642 void *addr;
643 name = (char *) symtab_section->link->data + sym->st_name;
644 addr = dlsym(RTLD_DEFAULT, name);
645 if (addr) {
646 sym->st_value = (addr_t)addr;
647 #ifdef DEBUG_RELOC
648 printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
649 #endif
650 goto found;
652 #endif
653 } else if (s1->dynsym) {
654 /* if dynamic symbol exist, then use it */
655 sym_index = find_elf_sym(s1->dynsym, name);
656 if (sym_index) {
657 esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
658 sym->st_value = esym->st_value;
659 goto found;
662 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
663 it */
664 if (!strcmp(name, "_fp_hw"))
665 goto found;
666 /* only weak symbols are accepted to be undefined. Their
667 value is zero */
668 sym_bind = ELFW(ST_BIND)(sym->st_info);
669 if (sym_bind == STB_WEAK) {
670 sym->st_value = 0;
671 } else {
672 tcc_error_noabort("undefined symbol '%s'", name);
674 } else if (sh_num < SHN_LORESERVE) {
675 /* add section base */
676 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
678 found: ;
682 /* relocate a given section (CPU dependent) by applying the relocations
683 in the associated relocation section */
684 ST_FUNC void relocate_section(TCCState *s1, Section *s)
686 Section *sr = s->reloc;
687 ElfW_Rel *rel;
688 ElfW(Sym) *sym;
689 int type, sym_index;
690 unsigned char *ptr;
691 addr_t val, addr;
692 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
693 ElfW_Rel *qrel = (ElfW_Rel *) sr->data; /* ptr to next reloc entry reused */
694 int esym_index;
695 #endif
697 for_each_elem(sr, 0, rel, ElfW_Rel) {
698 ptr = s->data + rel->r_offset;
700 sym_index = ELFW(R_SYM)(rel->r_info);
701 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
702 val = sym->st_value;
703 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
704 val += rel->r_addend;
705 #endif
706 type = ELFW(R_TYPE)(rel->r_info);
707 addr = s->sh_addr + rel->r_offset;
709 /* CPU specific */
710 switch(type) {
711 #if defined(TCC_TARGET_I386)
712 case R_386_32:
713 if (s1->output_type == TCC_OUTPUT_DLL) {
714 esym_index = s1->symtab_to_dynsym[sym_index];
715 qrel->r_offset = rel->r_offset;
716 if (esym_index) {
717 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
718 qrel++;
719 break;
720 } else {
721 qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
722 qrel++;
725 add32le(ptr, val);
726 break;
727 case R_386_PC32:
728 if (s1->output_type == TCC_OUTPUT_DLL) {
729 /* DLL relocation */
730 esym_index = s1->symtab_to_dynsym[sym_index];
731 if (esym_index) {
732 qrel->r_offset = rel->r_offset;
733 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
734 qrel++;
735 break;
738 add32le(ptr, val - addr);
739 break;
740 case R_386_PLT32:
741 add32le(ptr, val - addr);
742 break;
743 case R_386_GLOB_DAT:
744 case R_386_JMP_SLOT:
745 write32le(ptr, val);
746 break;
747 case R_386_GOTPC:
748 add32le(ptr, s1->got->sh_addr - addr);
749 break;
750 case R_386_GOTOFF:
751 add32le(ptr, val - s1->got->sh_addr);
752 break;
753 case R_386_GOT32:
754 case R_386_GOT32X:
755 /* we load the got offset */
756 add32le(ptr, s1->sym_attrs[sym_index].got_offset);
757 break;
758 case R_386_16:
759 if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {
760 output_file:
761 tcc_error("can only produce 16-bit binary files");
763 write16le(ptr, read16le(ptr) + val);
764 break;
765 case R_386_PC16:
766 if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY)
767 goto output_file;
768 write16le(ptr, read16le(ptr) + val - addr);
769 break;
771 #ifdef TCC_TARGET_PE
772 case R_386_RELATIVE: /* handled in pe_relocate_rva() */
773 break;
774 #endif
775 case R_386_COPY:
776 /* This reloction must copy initialized data from the library
777 to the program .bss segment. Currently made like for ARM
778 (to remove noise of defaukt case). Is this true?
780 break;
782 default:
783 fprintf(stderr,"FIXME: handle reloc type %d at %x [%p] to %x\n",
784 type, (unsigned)addr, ptr, (unsigned)val);
785 break;
786 #elif defined(TCC_TARGET_ARM)
787 case R_ARM_PC24:
788 case R_ARM_CALL:
789 case R_ARM_JUMP24:
790 case R_ARM_PLT32:
792 int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko;
793 x = (*(int *) ptr) & 0xffffff;
794 if (sym->st_shndx == SHN_UNDEF
795 || s1->output_type == TCC_OUTPUT_MEMORY)
796 val = s1->plt->sh_addr;
797 #ifdef DEBUG_RELOC
798 printf ("reloc %d: x=0x%x val=0x%x ", type, x, val);
799 #endif
800 (*(int *)ptr) &= 0xff000000;
801 if (x & 0x800000)
802 x -= 0x1000000;
803 x <<= 2;
804 blx_avail = (TCC_ARM_VERSION >= 5);
805 is_thumb = val & 1;
806 is_bl = (*(unsigned *) ptr) >> 24 == 0xeb;
807 is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl));
808 x += val - addr;
809 #ifdef DEBUG_RELOC
810 printf (" newx=0x%x name=%s\n", x,
811 (char *) symtab_section->link->data + sym->st_name);
812 #endif
813 h = x & 2;
814 th_ko = (x & 3) && (!blx_avail || !is_call);
815 if (th_ko || x >= 0x2000000 || x < -0x2000000)
816 tcc_error("can't relocate value at %x,%d",addr, type);
817 x >>= 2;
818 x &= 0xffffff;
819 /* Only reached if blx is avail and it is a call */
820 if (is_thumb) {
821 x |= h << 24;
822 (*(int *)ptr) = 0xfa << 24; /* bl -> blx */
824 (*(int *) ptr) |= x;
826 break;
827 /* Since these relocations only concern Thumb-2 and blx instruction was
828 introduced before Thumb-2, we can assume blx is available and not
829 guard its use */
830 case R_ARM_THM_PC22:
831 case R_ARM_THM_JUMP24:
833 int x, hi, lo, s, j1, j2, i1, i2, imm10, imm11;
834 int to_thumb, is_call, to_plt, blx_bit = 1 << 12;
835 Section *plt;
837 /* weak reference */
838 if (sym->st_shndx == SHN_UNDEF &&
839 ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
840 break;
842 /* Get initial offset */
843 hi = (*(uint16_t *)ptr);
844 lo = (*(uint16_t *)(ptr+2));
845 s = (hi >> 10) & 1;
846 j1 = (lo >> 13) & 1;
847 j2 = (lo >> 11) & 1;
848 i1 = (j1 ^ s) ^ 1;
849 i2 = (j2 ^ s) ^ 1;
850 imm10 = hi & 0x3ff;
851 imm11 = lo & 0x7ff;
852 x = (s << 24) | (i1 << 23) | (i2 << 22) |
853 (imm10 << 12) | (imm11 << 1);
854 if (x & 0x01000000)
855 x -= 0x02000000;
857 /* Relocation infos */
858 to_thumb = val & 1;
859 plt = s1->plt;
860 to_plt = (val >= plt->sh_addr) &&
861 (val < plt->sh_addr + plt->data_offset);
862 is_call = (type == R_ARM_THM_PC22);
864 /* Compute final offset */
865 if (to_plt && !is_call) /* Point to 1st instr of Thumb stub */
866 x -= 4;
867 x += val - addr;
868 if (!to_thumb && is_call) {
869 blx_bit = 0; /* bl -> blx */
870 x = (x + 3) & -4; /* Compute offset from aligned PC */
873 /* Check that relocation is possible
874 * offset must not be out of range
875 * if target is to be entered in arm mode:
876 - bit 1 must not set
877 - instruction must be a call (bl) or a jump to PLT */
878 if (!to_thumb || x >= 0x1000000 || x < -0x1000000)
879 if (to_thumb || (val & 2) || (!is_call && !to_plt))
880 tcc_error("can't relocate value at %x,%d",addr, type);
882 /* Compute and store final offset */
883 s = (x >> 24) & 1;
884 i1 = (x >> 23) & 1;
885 i2 = (x >> 22) & 1;
886 j1 = s ^ (i1 ^ 1);
887 j2 = s ^ (i2 ^ 1);
888 imm10 = (x >> 12) & 0x3ff;
889 imm11 = (x >> 1) & 0x7ff;
890 (*(uint16_t *)ptr) = (uint16_t) ((hi & 0xf800) |
891 (s << 10) | imm10);
892 (*(uint16_t *)(ptr+2)) = (uint16_t) ((lo & 0xc000) |
893 (j1 << 13) | blx_bit | (j2 << 11) |
894 imm11);
896 break;
897 case R_ARM_MOVT_ABS:
898 case R_ARM_MOVW_ABS_NC:
900 int x, imm4, imm12;
901 if (type == R_ARM_MOVT_ABS)
902 val >>= 16;
903 imm12 = val & 0xfff;
904 imm4 = (val >> 12) & 0xf;
905 x = (imm4 << 16) | imm12;
906 if (type == R_ARM_THM_MOVT_ABS)
907 *(int *)ptr |= x;
908 else
909 *(int *)ptr += x;
911 break;
912 case R_ARM_THM_MOVT_ABS:
913 case R_ARM_THM_MOVW_ABS_NC:
915 int x, i, imm4, imm3, imm8;
916 if (type == R_ARM_THM_MOVT_ABS)
917 val >>= 16;
918 imm8 = val & 0xff;
919 imm3 = (val >> 8) & 0x7;
920 i = (val >> 11) & 1;
921 imm4 = (val >> 12) & 0xf;
922 x = (imm3 << 28) | (imm8 << 16) | (i << 10) | imm4;
923 if (type == R_ARM_THM_MOVT_ABS)
924 *(int *)ptr |= x;
925 else
926 *(int *)ptr += x;
928 break;
929 case R_ARM_PREL31:
931 int x;
932 x = (*(int *)ptr) & 0x7fffffff;
933 (*(int *)ptr) &= 0x80000000;
934 x = (x * 2) / 2;
935 x += val - addr;
936 if((x^(x>>1))&0x40000000)
937 tcc_error("can't relocate value at %x,%d",addr, type);
938 (*(int *)ptr) |= x & 0x7fffffff;
940 case R_ARM_ABS32:
941 *(int *)ptr += val;
942 break;
943 case R_ARM_REL32:
944 *(int *)ptr += val - addr;
945 break;
946 case R_ARM_GOTPC:
947 *(int *)ptr += s1->got->sh_addr - addr;
948 break;
949 case R_ARM_GOTOFF:
950 *(int *)ptr += val - s1->got->sh_addr;
951 break;
952 case R_ARM_GOT32:
953 /* we load the got offset */
954 *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
955 break;
956 case R_ARM_COPY:
957 break;
958 case R_ARM_V4BX:
959 /* trade Thumb support for ARMv4 support */
960 if ((0x0ffffff0 & *(int*)ptr) == 0x012FFF10)
961 *(int*)ptr ^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */
962 break;
963 case R_ARM_GLOB_DAT:
964 case R_ARM_JUMP_SLOT:
965 *(addr_t *)ptr = val;
966 break;
967 case R_ARM_NONE:
968 /* Nothing to do. Normally used to indicate a dependency
969 on a certain symbol (like for exception handling under EABI). */
970 break;
971 #ifdef TCC_TARGET_PE
972 case R_ARM_RELATIVE: /* handled in pe_relocate_rva() */
973 break;
974 #endif
975 default:
976 fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
977 type, (unsigned)addr, ptr, (unsigned)val);
978 break;
979 #elif defined(TCC_TARGET_ARM64)
980 case R_AARCH64_ABS64:
981 write64le(ptr, val);
982 break;
983 case R_AARCH64_ABS32:
984 write32le(ptr, val);
985 break;
986 case R_AARCH64_PREL32:
987 write32le(ptr, val - addr);
988 break;
989 case R_AARCH64_MOVW_UABS_G0_NC:
990 write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
991 (val & 0xffff) << 5));
992 break;
993 case R_AARCH64_MOVW_UABS_G1_NC:
994 write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
995 (val >> 16 & 0xffff) << 5));
996 break;
997 case R_AARCH64_MOVW_UABS_G2_NC:
998 write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
999 (val >> 32 & 0xffff) << 5));
1000 break;
1001 case R_AARCH64_MOVW_UABS_G3:
1002 write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
1003 (val >> 48 & 0xffff) << 5));
1004 break;
1005 case R_AARCH64_ADR_PREL_PG_HI21: {
1006 uint64_t off = (val >> 12) - (addr >> 12);
1007 if ((off + ((uint64_t)1 << 20)) >> 21)
1008 tcc_error("R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
1009 write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
1010 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1011 break;
1013 case R_AARCH64_ADD_ABS_LO12_NC:
1014 write32le(ptr, ((read32le(ptr) & 0xffc003ff) |
1015 (val & 0xfff) << 10));
1016 break;
1017 case R_AARCH64_JUMP26:
1018 case R_AARCH64_CALL26:
1019 /* This check must match the one in build_got_entries, testing
1020 if we really need a PLT slot. */
1021 if (sym->st_shndx == SHN_UNDEF ||
1022 s1->output_type == TCC_OUTPUT_MEMORY)
1023 /* We've put the PLT slot offset into r_addend when generating
1024 it, and that's what we must use as relocation value (adjusted
1025 by section offset of course). */
1026 val = s1->plt->sh_addr + rel->r_addend;
1027 #ifdef DEBUG_RELOC
1028 printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val,
1029 (char *) symtab_section->link->data + sym->st_name);
1030 #endif
1031 if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)
1033 tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed (val=%lx, addr=%lx)", addr, val);
1035 write32le(ptr, (0x14000000 |
1036 (uint32_t)(type == R_AARCH64_CALL26) << 31 |
1037 ((val - addr) >> 2 & 0x3ffffff)));
1038 break;
1039 case R_AARCH64_ADR_GOT_PAGE: {
1040 uint64_t off =
1041 (((s1->got->sh_addr +
1042 s1->sym_attrs[sym_index].got_offset) >> 12) - (addr >> 12));
1043 if ((off + ((uint64_t)1 << 20)) >> 21)
1044 tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed");
1045 write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
1046 (off & 0x1ffffc) << 3 | (off & 3) << 29));
1047 break;
1049 case R_AARCH64_LD64_GOT_LO12_NC:
1050 write32le(ptr,
1051 ((read32le(ptr) & 0xfff803ff) |
1052 ((s1->got->sh_addr +
1053 s1->sym_attrs[sym_index].got_offset) & 0xff8) << 7));
1054 break;
1055 case R_AARCH64_COPY:
1056 break;
1057 case R_AARCH64_GLOB_DAT:
1058 case R_AARCH64_JUMP_SLOT:
1059 /* They don't need addend */
1060 #ifdef DEBUG_RELOC
1061 printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr,
1062 val - rel->r_addend,
1063 (char *) symtab_section->link->data + sym->st_name);
1064 #endif
1065 write64le(ptr, val - rel->r_addend);
1066 break;
1067 default:
1068 fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n",
1069 type, (unsigned)addr, ptr, (unsigned)val);
1070 break;
1071 #elif defined(TCC_TARGET_C67)
1072 case R_C60_32:
1073 *(int *)ptr += val;
1074 break;
1075 case R_C60LO16:
1077 uint32_t orig;
1079 /* put the low 16 bits of the absolute address
1080 add to what is already there */
1082 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
1083 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
1085 /* patch both at once - assumes always in pairs Low - High */
1087 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
1088 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
1090 break;
1091 case R_C60HI16:
1092 break;
1093 default:
1094 fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
1095 type, (unsigned)addr, ptr, (unsigned)val);
1096 break;
1097 #elif defined(TCC_TARGET_X86_64)
1098 case R_X86_64_64:
1099 if (s1->output_type == TCC_OUTPUT_DLL) {
1100 esym_index = s1->symtab_to_dynsym[sym_index];
1101 qrel->r_offset = rel->r_offset;
1102 if (esym_index) {
1103 qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64);
1104 qrel->r_addend = rel->r_addend;
1105 qrel++;
1106 break;
1107 } else {
1108 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
1109 qrel->r_addend = read64le(ptr) + val;
1110 qrel++;
1113 add64le(ptr, val);
1114 break;
1115 case R_X86_64_32:
1116 case R_X86_64_32S:
1117 if (s1->output_type == TCC_OUTPUT_DLL) {
1118 /* XXX: this logic may depend on TCC's codegen
1119 now TCC uses R_X86_64_32 even for a 64bit pointer */
1120 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
1121 /* Use sign extension! */
1122 qrel->r_addend = (int)read32le(ptr) + val;
1123 qrel++;
1125 add32le(ptr, val);
1126 break;
1128 case R_X86_64_PC32:
1129 if (s1->output_type == TCC_OUTPUT_DLL) {
1130 /* DLL relocation */
1131 esym_index = s1->symtab_to_dynsym[sym_index];
1132 if (esym_index) {
1133 qrel->r_offset = rel->r_offset;
1134 qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
1135 /* Use sign extension! */
1136 qrel->r_addend = (int)read32le(ptr) + rel->r_addend;
1137 qrel++;
1138 break;
1141 goto plt32pc32;
1143 case R_X86_64_PLT32:
1144 /* We've put the PLT slot offset into r_addend when generating
1145 it, and that's what we must use as relocation value (adjusted
1146 by section offset of course). */
1147 val = s1->plt->sh_addr + rel->r_addend;
1148 /* fallthrough. */
1150 plt32pc32:
1152 long long diff;
1153 diff = (long long)val - addr;
1154 if (diff < -2147483648LL || diff > 2147483647LL) {
1155 tcc_error("internal error: relocation failed");
1157 add32le(ptr, diff);
1159 break;
1160 case R_X86_64_GLOB_DAT:
1161 case R_X86_64_JUMP_SLOT:
1162 /* They don't need addend */
1163 write64le(ptr, val - rel->r_addend);
1164 break;
1165 case R_X86_64_GOTPCREL:
1166 case R_X86_64_GOTPCRELX:
1167 case R_X86_64_REX_GOTPCRELX:
1168 add32le(ptr, s1->got->sh_addr - addr
1169 + s1->sym_attrs[sym_index].got_offset - 4);
1170 break;
1171 case R_X86_64_GOTTPOFF:
1172 add32le(ptr, val - s1->got->sh_addr);
1173 break;
1174 case R_X86_64_GOT32:
1175 /* we load the got offset */
1176 add32le(ptr, s1->sym_attrs[sym_index].got_offset);
1177 break;
1178 #ifdef TCC_TARGET_PE
1179 case R_X86_64_RELATIVE: /* handled in pe_relocate_rva() */
1180 break;
1181 #endif
1183 #else
1184 #error unsupported processor
1185 #endif
1188 /* if the relocation is allocated, we change its symbol table */
1189 if (sr->sh_flags & SHF_ALLOC)
1190 sr->link = s1->dynsym;
1193 /* relocate relocation table in 'sr' */
1194 static void relocate_rel(TCCState *s1, Section *sr)
1196 Section *s;
1197 ElfW_Rel *rel;
1199 s = s1->sections[sr->sh_info];
1200 for_each_elem(sr, 0, rel, ElfW_Rel)
1201 rel->r_offset += s->sh_addr;
1204 /* count the number of dynamic relocations so that we can reserve
1205 their space */
1206 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
1208 ElfW_Rel *rel;
1209 int sym_index, esym_index, type, count;
1211 count = 0;
1212 for_each_elem(sr, 0, rel, ElfW_Rel) {
1213 sym_index = ELFW(R_SYM)(rel->r_info);
1214 type = ELFW(R_TYPE)(rel->r_info);
1215 switch(type) {
1216 #if defined(TCC_TARGET_I386)
1217 case R_386_32:
1218 #elif defined(TCC_TARGET_X86_64)
1219 case R_X86_64_32:
1220 case R_X86_64_32S:
1221 case R_X86_64_64:
1222 #endif
1223 count++;
1224 break;
1225 #if defined(TCC_TARGET_I386)
1226 case R_386_PC32:
1227 #elif defined(TCC_TARGET_X86_64)
1228 case R_X86_64_PC32:
1229 #endif
1230 esym_index = s1->symtab_to_dynsym[sym_index];
1231 if (esym_index)
1232 count++;
1233 break;
1234 default:
1235 break;
1238 if (count) {
1239 /* allocate the section */
1240 sr->sh_flags |= SHF_ALLOC;
1241 sr->sh_size = count * sizeof(ElfW_Rel);
1243 return count;
1246 static struct sym_attr *alloc_sym_attr(TCCState *s1, int index)
1248 int n;
1249 struct sym_attr *tab;
1251 if (index >= s1->nb_sym_attrs) {
1252 /* find immediately bigger power of 2 and reallocate array */
1253 n = 1;
1254 while (index >= n)
1255 n *= 2;
1256 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
1257 s1->sym_attrs = tab;
1258 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
1259 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
1260 s1->nb_sym_attrs = n;
1262 return &s1->sym_attrs[index];
1265 static void build_got(TCCState *s1)
1267 unsigned char *ptr;
1269 /* if no got, then create it */
1270 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1271 s1->got->sh_entsize = 4;
1272 add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1273 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1274 ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
1275 #if PTR_SIZE == 4
1276 /* keep space for _DYNAMIC pointer, if present */
1277 write32le(ptr, 0);
1278 /* two dummy got entries */
1279 write32le(ptr + 4, 0);
1280 write32le(ptr + 8, 0);
1281 #else
1282 /* keep space for _DYNAMIC pointer, if present */
1283 write32le(ptr, 0);
1284 write32le(ptr + 4, 0);
1285 /* two dummy got entries */
1286 write32le(ptr + 8, 0);
1287 write32le(ptr + 12, 0);
1288 write32le(ptr + 16, 0);
1289 write32le(ptr + 20, 0);
1290 #endif
1293 /* put a got or plt entry corresponding to a symbol in symtab_section. 'size'
1294 and 'info' can be modifed if more precise info comes from the DLL.
1295 Returns offset of GOT or PLT slot. */
1296 static unsigned long put_got_entry(TCCState *s1,
1297 int reloc_type, unsigned long size, int info,
1298 int sym_index)
1300 int index, need_plt_entry;
1301 const char *name;
1302 ElfW(Sym) *sym;
1303 unsigned long offset;
1304 int *ptr;
1305 struct sym_attr *symattr;
1307 if (!s1->got)
1308 build_got(s1);
1310 need_plt_entry =
1311 #ifdef TCC_TARGET_X86_64
1312 (reloc_type == R_X86_64_JUMP_SLOT);
1313 #elif defined(TCC_TARGET_I386)
1314 (reloc_type == R_386_JMP_SLOT);
1315 #elif defined(TCC_TARGET_ARM)
1316 (reloc_type == R_ARM_JUMP_SLOT);
1317 #elif defined(TCC_TARGET_ARM64)
1318 (reloc_type == R_AARCH64_JUMP_SLOT);
1319 #else
1321 #endif
1323 if (need_plt_entry && !s1->plt) {
1324 /* add PLT */
1325 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1326 SHF_ALLOC | SHF_EXECINSTR);
1327 s1->plt->sh_entsize = 4;
1330 /* If a got/plt entry already exists for that symbol, no need to add one */
1331 if (sym_index < s1->nb_sym_attrs) {
1332 if (need_plt_entry && s1->sym_attrs[sym_index].plt_offset)
1333 return s1->sym_attrs[sym_index].plt_offset;
1334 else if (!need_plt_entry && s1->sym_attrs[sym_index].got_offset)
1335 return s1->sym_attrs[sym_index].got_offset;
1338 symattr = alloc_sym_attr(s1, sym_index);
1340 /* Only store the GOT offset if it's not generated for the PLT entry. */
1341 if (!need_plt_entry)
1342 symattr->got_offset = s1->got->data_offset;
1344 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1345 name = (char *) symtab_section->link->data + sym->st_name;
1346 offset = sym->st_value;
1347 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1348 if (need_plt_entry) {
1349 Section *plt;
1350 uint8_t *p;
1351 int modrm;
1352 unsigned long relofs;
1354 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1355 modrm = 0x25;
1356 #else
1357 /* if we build a DLL, we add a %ebx offset */
1358 if (s1->output_type == TCC_OUTPUT_DLL)
1359 modrm = 0xa3;
1360 else
1361 modrm = 0x25;
1362 #endif
1364 /* add a PLT entry */
1365 plt = s1->plt;
1366 if (plt->data_offset == 0) {
1367 /* first plt entry */
1368 p = section_ptr_add(plt, 16);
1369 p[0] = 0xff; /* pushl got + PTR_SIZE */
1370 p[1] = modrm + 0x10;
1371 write32le(p + 2, PTR_SIZE);
1372 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
1373 p[7] = modrm;
1374 write32le(p + 8, PTR_SIZE * 2);
1377 /* The PLT slot refers to the relocation entry it needs
1378 via offset. The reloc entry is created below, so its
1379 offset is the current data_offset. */
1380 relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
1381 symattr->plt_offset = plt->data_offset;
1382 p = section_ptr_add(plt, 16);
1383 p[0] = 0xff; /* jmp *(got + x) */
1384 p[1] = modrm;
1385 write32le(p + 2, s1->got->data_offset);
1386 p[6] = 0x68; /* push $xxx */
1387 #ifdef TCC_TARGET_X86_64
1388 /* On x86-64, the relocation is referred to by _index_. */
1389 write32le(p + 7, relofs / sizeof (ElfW_Rel));
1390 #else
1391 write32le(p + 7, relofs);
1392 #endif
1393 p[11] = 0xe9; /* jmp plt_start */
1394 write32le(p + 12, -(plt->data_offset));
1396 /* If this was an UNDEF symbol set the offset in the
1397 dynsymtab to the PLT slot, so that PC32 relocs to it
1398 can be resolved. */
1399 if (sym->st_shndx == SHN_UNDEF)
1400 offset = plt->data_offset - 16;
1402 #elif defined(TCC_TARGET_ARM)
1403 if (need_plt_entry) {
1404 Section *plt;
1405 uint8_t *p;
1407 /* if we build a DLL, we add a %ebx offset */
1408 if (s1->output_type == TCC_OUTPUT_DLL)
1409 tcc_error("DLLs unimplemented!");
1411 /* add a PLT entry */
1412 plt = s1->plt;
1413 if (plt->data_offset == 0) {
1414 /* first plt entry */
1415 p = section_ptr_add(plt, 16);
1416 write32le(p, 0xe52de004); /* push {lr} */
1417 write32le(p+4, 0xe59fe010); /* ldr lr, [pc, #16] */
1418 write32le(p+8, 0xe08fe00e); /* add lr, pc, lr */
1419 write32le(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */
1422 symattr->plt_offset = plt->data_offset;
1423 if (symattr->plt_thumb_stub) {
1424 p = section_ptr_add(plt, 20);
1425 write32le(p, 0x4778); /* bx pc */
1426 write32le(p+2, 0x46c0); /* nop */
1427 p += 4;
1428 } else
1429 p = section_ptr_add(plt, 16);
1430 write32le(p, 0xe59fc004); /* ldr ip, [pc, #4] ; GOT entry offset */
1431 write32le(p+4, 0xe08fc00c); /* add ip, pc, ip ; addr of GOT entry */
1432 write32le(p+8, 0xe59cf000); /* ldr pc, [ip] ; jump to GOT entry */
1433 write32le(p+12, s1->got->data_offset); /* GOT entry off once patched */
1435 /* the symbol is modified so that it will be relocated to
1436 the PLT */
1437 if (sym->st_shndx == SHN_UNDEF)
1438 offset = plt->data_offset - 16;
1440 #elif defined(TCC_TARGET_ARM64)
1441 if (need_plt_entry) {
1442 Section *plt;
1443 uint8_t *p;
1445 if (s1->output_type == TCC_OUTPUT_DLL)
1446 tcc_error("DLLs unimplemented!");
1448 plt = s1->plt;
1449 if (plt->data_offset == 0)
1450 section_ptr_add(plt, 32);
1451 symattr->plt_offset = plt->data_offset;
1452 p = section_ptr_add(plt, 16);
1453 write32le(p, s1->got->data_offset);
1454 write32le(p + 4, (uint64_t)s1->got->data_offset >> 32);
1456 if (sym->st_shndx == SHN_UNDEF)
1457 offset = plt->data_offset - 16;
1459 #elif defined(TCC_TARGET_C67)
1460 if (s1->dynsym) {
1461 tcc_error("C67 got not implemented");
1463 #else
1464 #error unsupported CPU
1465 #endif
1466 if (s1->dynsym) {
1467 /* XXX This might generate multiple syms for name. */
1468 index = put_elf_sym(s1->dynsym, offset,
1469 size, info, 0, sym->st_shndx, name);
1470 /* Create the relocation (it's against the GOT for PLT
1471 and GOT relocs). */
1472 put_elf_reloc(s1->dynsym, s1->got,
1473 s1->got->data_offset,
1474 reloc_type, index);
1475 } else {
1476 /* Without .dynsym (i.e. static link or memory output) we
1477 still need relocs against the generated got, so as to fill
1478 the entries with the symbol values (determined later). */
1479 put_elf_reloc(symtab_section, s1->got,
1480 s1->got->data_offset,
1481 reloc_type, sym_index);
1483 /* And now create the GOT slot itself. */
1484 ptr = section_ptr_add(s1->got, PTR_SIZE);
1485 *ptr = 0;
1486 if (need_plt_entry)
1487 return symattr->plt_offset;
1488 else
1489 return symattr->got_offset;
1492 /* build GOT and PLT entries */
1493 ST_FUNC void build_got_entries(TCCState *s1)
1495 Section *s;
1496 ElfW_Rel *rel;
1497 ElfW(Sym) *sym;
1498 int i, type, reloc_type, sym_index;
1500 for(i = 1; i < s1->nb_sections; i++) {
1501 s = s1->sections[i];
1502 if (s->sh_type != SHT_RELX)
1503 continue;
1504 /* no need to handle got relocations */
1505 if (s->link != symtab_section)
1506 continue;
1507 for_each_elem(s, 0, rel, ElfW_Rel) {
1508 type = ELFW(R_TYPE)(rel->r_info);
1509 switch(type) {
1510 #if defined(TCC_TARGET_I386)
1511 case R_386_GOT32:
1512 case R_386_GOT32X:
1513 case R_386_GOTOFF:
1514 case R_386_GOTPC:
1515 case R_386_PLT32:
1516 if (!s1->got)
1517 build_got(s1);
1518 if (type == R_386_GOT32 || type == R_386_GOT32X ||
1519 type == R_386_PLT32) {
1520 sym_index = ELFW(R_SYM)(rel->r_info);
1521 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1522 /* look at the symbol got offset. If none, then add one */
1523 if (type == R_386_GOT32 || type == R_386_GOT32X)
1524 reloc_type = R_386_GLOB_DAT;
1525 else
1526 reloc_type = R_386_JMP_SLOT;
1527 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1528 sym_index);
1530 break;
1531 #elif defined(TCC_TARGET_ARM)
1532 case R_ARM_PC24:
1533 case R_ARM_CALL:
1534 case R_ARM_JUMP24:
1535 case R_ARM_GOT32:
1536 case R_ARM_GOTOFF:
1537 case R_ARM_GOTPC:
1538 case R_ARM_PLT32:
1539 if (!s1->got)
1540 build_got(s1);
1541 sym_index = ELFW(R_SYM)(rel->r_info);
1542 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1543 if (type != R_ARM_GOTOFF && type != R_ARM_GOTPC
1544 && (sym->st_shndx == SHN_UNDEF
1545 || s1->output_type == TCC_OUTPUT_MEMORY)) {
1546 unsigned long ofs;
1547 /* look at the symbol got offset. If none, then add one */
1548 if (type == R_ARM_GOT32)
1549 reloc_type = R_ARM_GLOB_DAT;
1550 else
1551 reloc_type = R_ARM_JUMP_SLOT;
1552 ofs = put_got_entry(s1, reloc_type, sym->st_size,
1553 sym->st_info, sym_index);
1554 #ifdef DEBUG_RELOC
1555 printf ("maybegot: %s, %d, %d --> ofs=0x%x\n",
1556 (char *) symtab_section->link->data + sym->st_name,
1557 type, sym->st_shndx, ofs);
1558 #endif
1559 if (type != R_ARM_GOT32) {
1560 addr_t *ptr = (addr_t*)(s1->sections[s->sh_info]->data
1561 + rel->r_offset);
1562 /* x must be signed! */
1563 int x = *ptr & 0xffffff;
1564 x = (x << 8) >> 8;
1565 x <<= 2;
1566 x += ofs;
1567 x >>= 2;
1568 #ifdef DEBUG_RELOC
1569 printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr,
1570 (*ptr & 0xff000000) | x, x);
1571 #endif
1572 *ptr = (*ptr & 0xff000000) | x;
1575 break;
1576 case R_ARM_THM_JUMP24:
1577 sym_index = ELFW(R_SYM)(rel->r_info);
1578 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1579 /* We are relocating a jump from thumb code to arm code */
1580 if (sym->st_shndx != SHN_UNDEF && !(sym->st_value & 1)) {
1581 int index;
1582 uint8_t *p;
1583 char *name, buf[1024];
1584 Section *text_section;
1586 name = (char *) symtab_section->link->data + sym->st_name;
1587 text_section = s1->sections[sym->st_shndx];
1588 /* Modify reloc to target a thumb stub to switch to ARM */
1589 snprintf(buf, sizeof(buf), "%s_from_thumb", name);
1590 index = put_elf_sym(symtab_section,
1591 text_section->data_offset + 1,
1592 sym->st_size, sym->st_info, 0,
1593 sym->st_shndx, buf);
1594 rel->r_info = ELFW(R_INFO)(index, type);
1595 /* Create a thumb stub fonction to switch to ARM mode */
1596 put_elf_reloc(symtab_section, text_section,
1597 text_section->data_offset + 4, R_ARM_JUMP24,
1598 sym_index);
1599 p = section_ptr_add(text_section, 8);
1600 write32le(p, 0x4778); /* bx pc */
1601 write32le(p+2, 0x46c0); /* nop */
1602 write32le(p+4, 0xeafffffe); /* b $sym */
1604 #elif defined(TCC_TARGET_ARM64)
1605 //xx Other cases may be required here:
1606 case R_AARCH64_ADR_GOT_PAGE:
1607 case R_AARCH64_LD64_GOT_LO12_NC:
1608 if (!s1->got)
1609 build_got(s1);
1610 sym_index = ELFW(R_SYM)(rel->r_info);
1611 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1612 reloc_type = R_AARCH64_GLOB_DAT;
1613 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1614 sym_index);
1615 break;
1617 case R_AARCH64_JUMP26:
1618 case R_AARCH64_CALL26:
1619 if (!s1->got)
1620 build_got(s1);
1621 sym_index = ELFW(R_SYM)(rel->r_info);
1622 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1623 if (sym->st_shndx == SHN_UNDEF ||
1624 s1->output_type == TCC_OUTPUT_MEMORY) {
1625 unsigned long ofs;
1626 reloc_type = R_AARCH64_JUMP_SLOT;
1627 ofs = put_got_entry(s1, reloc_type, sym->st_size,
1628 sym->st_info, sym_index);
1629 /* We store the place of the generated PLT slot
1630 in our addend. */
1631 rel->r_addend += ofs;
1633 break;
1634 #elif defined(TCC_TARGET_C67)
1635 case R_C60_GOT32:
1636 case R_C60_GOTOFF:
1637 case R_C60_GOTPC:
1638 case R_C60_PLT32:
1639 if (!s1->got)
1640 build_got(s1);
1641 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
1642 sym_index = ELFW(R_SYM)(rel->r_info);
1643 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1644 /* look at the symbol got offset. If none, then add one */
1645 if (type == R_C60_GOT32)
1646 reloc_type = R_C60_GLOB_DAT;
1647 else
1648 reloc_type = R_C60_JMP_SLOT;
1649 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1650 sym_index);
1652 break;
1653 #elif defined(TCC_TARGET_X86_64)
1654 case R_X86_64_GOT32:
1655 case R_X86_64_GOTTPOFF:
1656 case R_X86_64_GOTPCREL:
1657 case R_X86_64_GOTPCRELX:
1658 case R_X86_64_REX_GOTPCRELX:
1659 case R_X86_64_PLT32:
1660 sym_index = ELFW(R_SYM)(rel->r_info);
1661 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1662 if (type == R_X86_64_PLT32 &&
1663 ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT)
1665 rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
1666 break;
1669 if (!s1->got) {
1670 build_got(s1);
1671 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1673 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
1674 type == R_X86_64_GOTPCRELX ||
1675 type == R_X86_64_REX_GOTPCRELX ||
1676 type == R_X86_64_PLT32) {
1677 unsigned long ofs;
1678 /* look at the symbol got offset. If none, then add one */
1679 if (type == R_X86_64_PLT32)
1680 reloc_type = R_X86_64_JUMP_SLOT;
1681 else
1682 reloc_type = R_X86_64_GLOB_DAT;
1683 ofs = put_got_entry(s1, reloc_type, sym->st_size,
1684 sym->st_info, sym_index);
1685 if (type == R_X86_64_PLT32)
1686 /* We store the place of the generated PLT slot
1687 in our addend. */
1688 rel->r_addend += ofs;
1690 break;
1691 #else
1692 #error unsupported CPU
1693 #endif
1694 default:
1695 break;
1701 ST_FUNC Section *new_symtab(TCCState *s1,
1702 const char *symtab_name, int sh_type, int sh_flags,
1703 const char *strtab_name,
1704 const char *hash_name, int hash_sh_flags)
1706 Section *symtab, *strtab, *hash;
1707 int *ptr, nb_buckets;
1709 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1710 symtab->sh_entsize = sizeof(ElfW(Sym));
1711 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1712 put_elf_str(strtab, "");
1713 symtab->link = strtab;
1714 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1716 nb_buckets = 1;
1718 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1719 hash->sh_entsize = sizeof(int);
1720 symtab->hash = hash;
1721 hash->link = symtab;
1723 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1724 ptr[0] = nb_buckets;
1725 ptr[1] = 1;
1726 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1727 return symtab;
1730 /* put dynamic tag */
1731 static void put_dt(Section *dynamic, int dt, addr_t val)
1733 ElfW(Dyn) *dyn;
1734 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1735 dyn->d_tag = dt;
1736 dyn->d_un.d_val = val;
1739 #ifndef TCC_TARGET_PE
1740 static void add_init_array_defines(TCCState *s1, const char *section_name)
1742 Section *s;
1743 long end_offset;
1744 char sym_start[1024];
1745 char sym_end[1024];
1747 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1748 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1750 s = find_section(s1, section_name);
1751 if (!s) {
1752 end_offset = 0;
1753 s = data_section;
1754 } else {
1755 end_offset = s->data_offset;
1758 add_elf_sym(symtab_section,
1759 0, 0,
1760 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1761 s->sh_num, sym_start);
1762 add_elf_sym(symtab_section,
1763 end_offset, 0,
1764 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1765 s->sh_num, sym_end);
1767 #endif
1769 static int tcc_add_support(TCCState *s1, const char *filename)
1771 char buf[1024];
1772 snprintf(buf, sizeof(buf), "%s/"TCC_ARCH_DIR"%s", s1->tcc_lib_path, filename);
1773 return tcc_add_file(s1, buf);
1776 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1778 #ifdef CONFIG_TCC_BCHECK
1779 addr_t *ptr;
1780 int sym_index;
1782 if (0 == s1->do_bounds_check)
1783 return;
1784 /* XXX: add an object file to do that */
1785 ptr = section_ptr_add(bounds_section, sizeof(*ptr));
1786 *ptr = 0;
1787 add_elf_sym(symtab_section, 0, 0,
1788 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1789 bounds_section->sh_num, "__bounds_start");
1790 /* pull bcheck.o from libtcc1.a */
1791 sym_index = add_elf_sym(symtab_section, 0, 0,
1792 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1793 SHN_UNDEF, "__bound_init");
1794 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1795 /* add 'call __bound_init()' in .init section */
1796 Section *init_section = find_section(s1, ".init");
1797 unsigned char *pinit = section_ptr_add(init_section, 5);
1798 pinit[0] = 0xe8;
1799 write32le(pinit + 1, -4);
1800 put_elf_reloc(symtab_section, init_section,
1801 init_section->data_offset - 4, R_386_PC32, sym_index);
1802 /* R_386_PC32 = R_X86_64_PC32 = 2 */
1804 #endif
1807 /* add tcc runtime libraries */
1808 ST_FUNC void tcc_add_runtime(TCCState *s1)
1810 tcc_add_bcheck(s1);
1811 tcc_add_pragma_libs(s1);
1812 /* add libc */
1813 if (!s1->nostdlib) {
1814 tcc_add_library_err(s1, "c");
1815 #ifdef CONFIG_USE_LIBGCC
1816 if (!s1->static_link) {
1817 tcc_add_file(s1, TCC_LIBGCC);
1819 #endif
1820 tcc_add_support(s1, "libtcc1.a");
1821 /* add crt end if not memory output */
1822 if (s1->output_type != TCC_OUTPUT_MEMORY)
1823 tcc_add_crt(s1, "crtn.o");
1827 /* add various standard linker symbols (must be done after the
1828 sections are filled (for example after allocating common
1829 symbols)) */
1830 ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
1832 char buf[1024];
1833 int i;
1834 Section *s;
1836 add_elf_sym(symtab_section,
1837 text_section->data_offset, 0,
1838 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1839 text_section->sh_num, "_etext");
1840 add_elf_sym(symtab_section,
1841 data_section->data_offset, 0,
1842 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1843 data_section->sh_num, "_edata");
1844 add_elf_sym(symtab_section,
1845 bss_section->data_offset, 0,
1846 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1847 bss_section->sh_num, "_end");
1848 #ifndef TCC_TARGET_PE
1849 /* horrible new standard ldscript defines */
1850 add_init_array_defines(s1, ".preinit_array");
1851 add_init_array_defines(s1, ".init_array");
1852 add_init_array_defines(s1, ".fini_array");
1853 #endif
1855 /* add start and stop symbols for sections whose name can be
1856 expressed in C */
1857 for(i = 1; i < s1->nb_sections; i++) {
1858 s = s1->sections[i];
1859 if (s->sh_type == SHT_PROGBITS &&
1860 (s->sh_flags & SHF_ALLOC)) {
1861 const char *p;
1862 int ch;
1864 /* check if section name can be expressed in C */
1865 p = s->name;
1866 for(;;) {
1867 ch = *p;
1868 if (!ch)
1869 break;
1870 if (!isid(ch) && !isnum(ch))
1871 goto next_sec;
1872 p++;
1874 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1875 add_elf_sym(symtab_section,
1876 0, 0,
1877 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1878 s->sh_num, buf);
1879 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1880 add_elf_sym(symtab_section,
1881 s->data_offset, 0,
1882 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1883 s->sh_num, buf);
1885 next_sec: ;
1889 static void tcc_output_binary(TCCState *s1, FILE *f,
1890 const int *sec_order)
1892 Section *s;
1893 int i, offset, size;
1895 offset = 0;
1896 for(i=1;i<s1->nb_sections;i++) {
1897 s = s1->sections[sec_order[i]];
1898 if (s->sh_type != SHT_NOBITS &&
1899 (s->sh_flags & SHF_ALLOC)) {
1900 while (offset < s->sh_offset) {
1901 fputc(0, f);
1902 offset++;
1904 size = s->sh_size;
1905 fwrite(s->data, 1, size, f);
1906 offset += size;
1911 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1912 #define HAVE_PHDR 1
1913 #define EXTRA_RELITEMS 14
1915 /* move the relocation value from .dynsym to .got */
1916 static void patch_dynsym_undef(TCCState *s1, Section *s)
1918 uint32_t *gotd = (void *)s1->got->data;
1919 ElfW(Sym) *sym;
1921 gotd += 3; /* dummy entries in .got */
1922 /* relocate symbols in .dynsym */
1923 for_each_elem(s, 1, sym, ElfW(Sym)) {
1924 if (sym->st_shndx == SHN_UNDEF) {
1925 *gotd++ = sym->st_value + 6; /* XXX 6 is magic ? */
1926 sym->st_value = 0;
1930 #else
1931 #define HAVE_PHDR 1
1932 #define EXTRA_RELITEMS 9
1934 /* zero plt offsets of weak symbols in .dynsym */
1935 static void patch_dynsym_undef(TCCState *s1, Section *s)
1937 ElfW(Sym) *sym;
1939 for_each_elem(s, 1, sym, ElfW(Sym))
1940 if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
1941 sym->st_value = 0;
1943 #endif
1945 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1947 int sym_index = ELFW(R_SYM) (rel->r_info);
1948 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1949 unsigned long offset;
1951 if (sym_index >= s1->nb_sym_attrs)
1952 return;
1953 offset = s1->sym_attrs[sym_index].got_offset;
1954 section_reserve(s1->got, offset + PTR_SIZE);
1955 #ifdef TCC_TARGET_X86_64
1956 /* only works for x86-64 */
1957 write32le(s1->got->data + offset + 4, sym->st_value >> 32);
1958 #endif
1959 write32le(s1->got->data + offset, sym->st_value & 0xffffffff);
1962 /* Perform relocation to GOT or PLT entries */
1963 ST_FUNC void fill_got(TCCState *s1)
1965 Section *s;
1966 ElfW_Rel *rel;
1967 int i;
1969 for(i = 1; i < s1->nb_sections; i++) {
1970 s = s1->sections[i];
1971 if (s->sh_type != SHT_RELX)
1972 continue;
1973 /* no need to handle got relocations */
1974 if (s->link != symtab_section)
1975 continue;
1976 for_each_elem(s, 0, rel, ElfW_Rel) {
1977 switch (ELFW(R_TYPE) (rel->r_info)) {
1978 case R_X86_64_GOT32:
1979 case R_X86_64_GOTPCREL:
1980 case R_X86_64_GOTPCRELX:
1981 case R_X86_64_REX_GOTPCRELX:
1982 case R_X86_64_PLT32:
1983 fill_got_entry(s1, rel);
1984 break;
1990 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1991 in shared libraries and export non local defined symbols to shared libraries
1992 if -rdynamic switch was given on command line */
1993 static void bind_exe_dynsyms(TCCState *s1)
1995 const char *name;
1996 int sym_index, index;
1997 ElfW(Sym) *sym, *esym;
1998 int type;
2000 /* Resolve undefined symbols from dynamic symbols. When there is a match:
2001 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
2002 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
2003 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
2004 if (sym->st_shndx == SHN_UNDEF) {
2005 name = (char *) symtab_section->link->data + sym->st_name;
2006 sym_index = find_elf_sym(s1->dynsymtab_section, name);
2007 if (sym_index) {
2008 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
2009 type = ELFW(ST_TYPE)(esym->st_info);
2010 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
2011 /* Indirect functions shall have STT_FUNC type in executable
2012 * dynsym section. Indeed, a dlsym call following a lazy
2013 * resolution would pick the symbol value from the
2014 * executable dynsym entry which would contain the address
2015 * of the function wanted by the caller of dlsym instead of
2016 * the address of the function that would return that
2017 * address */
2018 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
2019 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC),
2020 sym - (ElfW(Sym) *)symtab_section->data);
2021 } else if (type == STT_OBJECT) {
2022 unsigned long offset;
2023 ElfW(Sym) *dynsym;
2024 offset = bss_section->data_offset;
2025 /* XXX: which alignment ? */
2026 offset = (offset + 16 - 1) & -16;
2027 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
2028 esym->st_info, 0, bss_section->sh_num,
2029 name);
2030 /* Ensure R_COPY works for weak symbol aliases */
2031 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
2032 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
2033 if ((dynsym->st_value == esym->st_value)
2034 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
2035 char *dynname = (char *) s1->dynsymtab_section->link->data
2036 + dynsym->st_name;
2037 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
2038 dynsym->st_info, 0,
2039 bss_section->sh_num, dynname);
2040 break;
2044 put_elf_reloc(s1->dynsym, bss_section,
2045 offset, R_COPY, index);
2046 offset += esym->st_size;
2047 bss_section->data_offset = offset;
2049 } else {
2050 /* STB_WEAK undefined symbols are accepted */
2051 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
2052 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
2053 !strcmp(name, "_fp_hw")) {
2054 } else {
2055 tcc_error_noabort("undefined symbol '%s'", name);
2058 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2059 /* if -rdynamic option, then export all non local symbols */
2060 name = (char *) symtab_section->link->data + sym->st_name;
2061 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
2062 0, sym->st_shndx, name);
2067 /* Bind symbols of libraries: export non local symbols of executable that
2068 resolve undefined symbols of shared libraries */
2069 static void bind_libs_dynsyms(TCCState *s1)
2071 const char *name;
2072 int sym_index;
2073 ElfW(Sym) *sym, *esym;
2075 /* now look at unresolved dynamic symbols and export
2076 corresponding symbol */
2077 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
2078 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
2079 sym_index = find_elf_sym(symtab_section, name);
2080 /* XXX: avoid adding a symbol if already present because of
2081 -rdynamic ? */
2082 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2083 if (sym_index && sym->st_shndx != SHN_UNDEF)
2084 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
2085 0, sym->st_shndx, name);
2086 else if (esym->st_shndx == SHN_UNDEF) {
2087 /* weak symbols can stay undefined */
2088 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
2089 tcc_warning("undefined dynamic symbol '%s'", name);
2094 /* Export all non local symbols (for shared libraries) */
2095 static void export_global_syms(TCCState *s1)
2097 int nb_syms, dynindex, index;
2098 const char *name;
2099 ElfW(Sym) *sym;
2101 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
2102 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
2103 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
2104 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2105 name = (char *) symtab_section->link->data + sym->st_name;
2106 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
2107 sym->st_info, 0, sym->st_shndx, name);
2108 index = sym - (ElfW(Sym) *) symtab_section->data;
2109 s1->symtab_to_dynsym[index] = dynindex;
2114 /* relocate the PLT: compute addresses and offsets in the PLT now that final
2115 address for PLT and GOT are known (see fill_program_header) */
2116 ST_FUNC void relocate_plt(TCCState *s1)
2118 uint8_t *p, *p_end;
2120 if (!s1->plt)
2121 return;
2123 p = s1->plt->data;
2124 p_end = p + s1->plt->data_offset;
2125 if (p < p_end) {
2126 #if defined(TCC_TARGET_I386)
2127 add32le(p + 2, s1->got->sh_addr);
2128 add32le(p + 8, s1->got->sh_addr);
2129 p += 16;
2130 while (p < p_end) {
2131 add32le(p + 2, s1->got->sh_addr);
2132 p += 16;
2134 #elif defined(TCC_TARGET_X86_64)
2135 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
2136 add32le(p + 2, x);
2137 add32le(p + 8, x - 6);
2138 p += 16;
2139 while (p < p_end) {
2140 add32le(p + 2, x + s1->plt->data - p);
2141 p += 16;
2143 #elif defined(TCC_TARGET_ARM)
2144 int x = s1->got->sh_addr - s1->plt->sh_addr - 12;
2145 p += 16;
2146 while (p < p_end) {
2147 if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
2148 p += 4;
2149 add32le(p + 12, x + s1->plt->data - p);
2150 p += 16;
2152 #elif defined(TCC_TARGET_ARM64)
2153 uint64_t plt = s1->plt->sh_addr;
2154 uint64_t got = s1->got->sh_addr;
2155 uint64_t off = (got >> 12) - (plt >> 12);
2156 if ((off + ((uint32_t)1 << 20)) >> 21)
2157 tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt);
2158 write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
2159 write32le(p + 4, (0x90000010 | // adrp x16,...
2160 (off & 0x1ffffc) << 3 | (off & 3) << 29));
2161 write32le(p + 8, (0xf9400211 | // ldr x17,[x16,#...]
2162 (got & 0xff8) << 7));
2163 write32le(p + 12, (0x91000210 | // add x16,x16,#...
2164 (got & 0xfff) << 10));
2165 write32le(p + 16, 0xd61f0220); // br x17
2166 write32le(p + 20, 0xd503201f); // nop
2167 write32le(p + 24, 0xd503201f); // nop
2168 write32le(p + 28, 0xd503201f); // nop
2169 p += 32;
2170 while (p < p_end) {
2171 uint64_t pc = plt + (p - s1->plt->data);
2172 uint64_t addr = got + read64le(p);
2173 uint64_t off = (addr >> 12) - (pc >> 12);
2174 if ((off + ((uint32_t)1 << 20)) >> 21)
2175 tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc);
2176 write32le(p, (0x90000010 | // adrp x16,...
2177 (off & 0x1ffffc) << 3 | (off & 3) << 29));
2178 write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
2179 (addr & 0xff8) << 7));
2180 write32le(p + 8, (0x91000210 | // add x16,x16,#...
2181 (addr & 0xfff) << 10));
2182 write32le(p + 12, 0xd61f0220); // br x17
2183 p += 16;
2185 #elif defined(TCC_TARGET_C67)
2186 /* XXX: TODO */
2187 #else
2188 #error unsupported CPU
2189 #endif
2193 /* Allocate strings for section names and decide if an unallocated section
2194 should be output.
2196 NOTE: the strsec section comes last, so its size is also correct ! */
2197 static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
2199 int i;
2200 Section *s;
2202 /* Allocate strings for section names */
2203 for(i = 1; i < s1->nb_sections; i++) {
2204 s = s1->sections[i];
2205 s->sh_name = put_elf_str(strsec, s->name);
2206 /* when generating a DLL, we include relocations but we may
2207 patch them */
2208 if (file_type == TCC_OUTPUT_DLL &&
2209 s->sh_type == SHT_RELX &&
2210 !(s->sh_flags & SHF_ALLOC)) {
2211 /* gr: avoid bogus relocs for empty (debug) sections */
2212 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
2213 prepare_dynamic_rel(s1, s);
2214 else if (s1->do_debug)
2215 s->sh_size = s->data_offset;
2216 } else if (s1->do_debug ||
2217 file_type == TCC_OUTPUT_OBJ ||
2218 (s->sh_flags & SHF_ALLOC) ||
2219 i == (s1->nb_sections - 1)) {
2220 /* we output all sections if debug or object file */
2221 s->sh_size = s->data_offset;
2226 /* Info to be copied in dynamic section */
2227 struct dyn_inf {
2228 Section *dynamic;
2229 Section *dynstr;
2230 unsigned long dyn_rel_off;
2231 addr_t rel_addr;
2232 addr_t rel_size;
2233 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2234 addr_t bss_addr;
2235 addr_t bss_size;
2236 #endif
2239 /* Assign sections to segments and decide how are sections laid out when loaded
2240 in memory. This function also fills corresponding program headers. */
2241 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
2242 Section *interp, Section* strsec,
2243 struct dyn_inf *dyninf, int *sec_order)
2245 int i, j, k, file_type, sh_order_index, file_offset;
2246 unsigned long s_align;
2247 long long tmp;
2248 addr_t addr;
2249 ElfW(Phdr) *ph;
2250 Section *s;
2252 file_type = s1->output_type;
2253 sh_order_index = 1;
2254 file_offset = 0;
2255 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2256 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2257 s_align = ELF_PAGE_SIZE;
2258 if (s1->section_align)
2259 s_align = s1->section_align;
2261 if (phnum > 0) {
2262 if (s1->has_text_addr) {
2263 int a_offset, p_offset;
2264 addr = s1->text_addr;
2265 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
2266 ELF_PAGE_SIZE */
2267 a_offset = (int) (addr & (s_align - 1));
2268 p_offset = file_offset & (s_align - 1);
2269 if (a_offset < p_offset)
2270 a_offset += s_align;
2271 file_offset += (a_offset - p_offset);
2272 } else {
2273 if (file_type == TCC_OUTPUT_DLL)
2274 addr = 0;
2275 else
2276 addr = ELF_START_ADDR;
2277 /* compute address after headers */
2278 addr += (file_offset & (s_align - 1));
2281 ph = &phdr[0];
2282 /* Leave one program headers for the program interpreter and one for
2283 the program header table itself if needed. These are done later as
2284 they require section layout to be done first. */
2285 if (interp)
2286 ph += 1 + HAVE_PHDR;
2288 /* dynamic relocation table information, for .dynamic section */
2289 dyninf->rel_addr = dyninf->rel_size = 0;
2290 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2291 dyninf->bss_addr = dyninf->bss_size = 0;
2292 #endif
2294 for(j = 0; j < 2; j++) {
2295 ph->p_type = PT_LOAD;
2296 if (j == 0)
2297 ph->p_flags = PF_R | PF_X;
2298 else
2299 ph->p_flags = PF_R | PF_W;
2300 ph->p_align = s_align;
2302 /* Decide the layout of sections loaded in memory. This must
2303 be done before program headers are filled since they contain
2304 info about the layout. We do the following ordering: interp,
2305 symbol tables, relocations, progbits, nobits */
2306 /* XXX: do faster and simpler sorting */
2307 for(k = 0; k < 5; k++) {
2308 for(i = 1; i < s1->nb_sections; i++) {
2309 s = s1->sections[i];
2310 /* compute if section should be included */
2311 if (j == 0) {
2312 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
2313 SHF_ALLOC)
2314 continue;
2315 } else {
2316 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
2317 (SHF_ALLOC | SHF_WRITE))
2318 continue;
2320 if (s == interp) {
2321 if (k != 0)
2322 continue;
2323 } else if (s->sh_type == SHT_DYNSYM ||
2324 s->sh_type == SHT_STRTAB ||
2325 s->sh_type == SHT_HASH) {
2326 if (k != 1)
2327 continue;
2328 } else if (s->sh_type == SHT_RELX) {
2329 if (k != 2)
2330 continue;
2331 } else if (s->sh_type == SHT_NOBITS) {
2332 if (k != 4)
2333 continue;
2334 } else {
2335 if (k != 3)
2336 continue;
2338 sec_order[sh_order_index++] = i;
2340 /* section matches: we align it and add its size */
2341 tmp = addr;
2342 addr = (addr + s->sh_addralign - 1) &
2343 ~(s->sh_addralign - 1);
2344 file_offset += (int) ( addr - tmp );
2345 s->sh_offset = file_offset;
2346 s->sh_addr = addr;
2348 /* update program header infos */
2349 if (ph->p_offset == 0) {
2350 ph->p_offset = file_offset;
2351 ph->p_vaddr = addr;
2352 ph->p_paddr = ph->p_vaddr;
2354 /* update dynamic relocation infos */
2355 if (s->sh_type == SHT_RELX) {
2356 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2357 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
2358 dyninf->rel_addr = addr;
2359 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
2361 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
2362 dyninf->bss_addr = addr;
2363 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
2365 #else
2366 if (dyninf->rel_size == 0)
2367 dyninf->rel_addr = addr;
2368 dyninf->rel_size += s->sh_size;
2369 #endif
2371 addr += s->sh_size;
2372 if (s->sh_type != SHT_NOBITS)
2373 file_offset += s->sh_size;
2376 if (j == 0) {
2377 /* Make the first PT_LOAD segment include the program
2378 headers itself (and the ELF header as well), it'll
2379 come out with same memory use but will make various
2380 tools like binutils strip work better. */
2381 ph->p_offset &= ~(ph->p_align - 1);
2382 ph->p_vaddr &= ~(ph->p_align - 1);
2383 ph->p_paddr &= ~(ph->p_align - 1);
2385 ph->p_filesz = file_offset - ph->p_offset;
2386 ph->p_memsz = addr - ph->p_vaddr;
2387 ph++;
2388 if (j == 0) {
2389 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
2390 /* if in the middle of a page, we duplicate the page in
2391 memory so that one copy is RX and the other is RW */
2392 if ((addr & (s_align - 1)) != 0)
2393 addr += s_align;
2394 } else {
2395 addr = (addr + s_align - 1) & ~(s_align - 1);
2396 file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
2402 /* all other sections come after */
2403 for(i = 1; i < s1->nb_sections; i++) {
2404 s = s1->sections[i];
2405 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
2406 continue;
2407 sec_order[sh_order_index++] = i;
2409 file_offset = (file_offset + s->sh_addralign - 1) &
2410 ~(s->sh_addralign - 1);
2411 s->sh_offset = file_offset;
2412 if (s->sh_type != SHT_NOBITS)
2413 file_offset += s->sh_size;
2416 return file_offset;
2419 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
2420 Section *dynamic)
2422 ElfW(Phdr) *ph;
2424 /* if interpreter, then add corresponding program header */
2425 if (interp) {
2426 ph = &phdr[0];
2428 if (HAVE_PHDR)
2430 int len = phnum * sizeof(ElfW(Phdr));
2432 ph->p_type = PT_PHDR;
2433 ph->p_offset = sizeof(ElfW(Ehdr));
2434 ph->p_vaddr = interp->sh_addr - len;
2435 ph->p_paddr = ph->p_vaddr;
2436 ph->p_filesz = ph->p_memsz = len;
2437 ph->p_flags = PF_R | PF_X;
2438 ph->p_align = 4; /* interp->sh_addralign; */
2439 ph++;
2442 ph->p_type = PT_INTERP;
2443 ph->p_offset = interp->sh_offset;
2444 ph->p_vaddr = interp->sh_addr;
2445 ph->p_paddr = ph->p_vaddr;
2446 ph->p_filesz = interp->sh_size;
2447 ph->p_memsz = interp->sh_size;
2448 ph->p_flags = PF_R;
2449 ph->p_align = interp->sh_addralign;
2452 /* if dynamic section, then add corresponding program header */
2453 if (dynamic) {
2454 ph = &phdr[phnum - 1];
2456 ph->p_type = PT_DYNAMIC;
2457 ph->p_offset = dynamic->sh_offset;
2458 ph->p_vaddr = dynamic->sh_addr;
2459 ph->p_paddr = ph->p_vaddr;
2460 ph->p_filesz = dynamic->sh_size;
2461 ph->p_memsz = dynamic->sh_size;
2462 ph->p_flags = PF_R | PF_W;
2463 ph->p_align = dynamic->sh_addralign;
2467 /* Fill the dynamic section with tags describing the address and size of
2468 sections */
2469 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2471 Section *dynamic;
2473 dynamic = dyninf->dynamic;
2475 /* put dynamic section entries */
2476 dynamic->data_offset = dyninf->dyn_rel_off;
2477 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2478 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2479 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2480 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2481 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2482 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2483 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2484 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2485 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2486 #else
2487 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2488 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2489 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
2490 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2491 put_dt(dynamic, DT_PLTREL, DT_REL);
2492 put_dt(dynamic, DT_REL, dyninf->bss_addr);
2493 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
2494 #else
2495 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2496 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2497 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2498 #endif
2499 #endif
2500 if (s1->do_debug)
2501 put_dt(dynamic, DT_DEBUG, 0);
2502 put_dt(dynamic, DT_NULL, 0);
2505 /* Relocate remaining sections and symbols (that is those not related to
2506 dynamic linking) */
2507 static int final_sections_reloc(TCCState *s1)
2509 int i;
2510 Section *s;
2512 relocate_syms(s1, 0);
2514 if (s1->nb_errors != 0)
2515 return -1;
2517 /* relocate sections */
2518 /* XXX: ignore sections with allocated relocations ? */
2519 for(i = 1; i < s1->nb_sections; i++) {
2520 s = s1->sections[i];
2521 #ifdef TCC_TARGET_I386
2522 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
2523 /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
2524 checking is removed */
2525 #else
2526 if (s->reloc && s != s1->got)
2527 /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
2528 #endif
2529 relocate_section(s1, s);
2532 /* relocate relocation entries if the relocation tables are
2533 allocated in the executable */
2534 for(i = 1; i < s1->nb_sections; i++) {
2535 s = s1->sections[i];
2536 if ((s->sh_flags & SHF_ALLOC) &&
2537 s->sh_type == SHT_RELX) {
2538 relocate_rel(s1, s);
2541 return 0;
2544 /* Create an ELF file on disk.
2545 This function handle ELF specific layout requirements */
2546 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2547 int file_offset, int *sec_order)
2549 int i, shnum, offset, size, file_type;
2550 Section *s;
2551 ElfW(Ehdr) ehdr;
2552 ElfW(Shdr) shdr, *sh;
2554 file_type = s1->output_type;
2555 shnum = s1->nb_sections;
2557 memset(&ehdr, 0, sizeof(ehdr));
2559 if (phnum > 0) {
2560 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2561 ehdr.e_phnum = phnum;
2562 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2565 /* align to 4 */
2566 file_offset = (file_offset + 3) & -4;
2568 /* fill header */
2569 ehdr.e_ident[0] = ELFMAG0;
2570 ehdr.e_ident[1] = ELFMAG1;
2571 ehdr.e_ident[2] = ELFMAG2;
2572 ehdr.e_ident[3] = ELFMAG3;
2573 ehdr.e_ident[4] = ELFCLASSW;
2574 ehdr.e_ident[5] = ELFDATA2LSB;
2575 ehdr.e_ident[6] = EV_CURRENT;
2576 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2577 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2578 #endif
2579 #ifdef TCC_TARGET_ARM
2580 #ifdef TCC_ARM_EABI
2581 ehdr.e_ident[EI_OSABI] = 0;
2582 ehdr.e_flags = EF_ARM_EABI_VER4;
2583 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2584 ehdr.e_flags |= EF_ARM_HASENTRY;
2585 if (s1->float_abi == ARM_HARD_FLOAT)
2586 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2587 else
2588 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2589 #else
2590 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2591 #endif
2592 #endif
2593 switch(file_type) {
2594 default:
2595 case TCC_OUTPUT_EXE:
2596 ehdr.e_type = ET_EXEC;
2597 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
2598 break;
2599 case TCC_OUTPUT_DLL:
2600 ehdr.e_type = ET_DYN;
2601 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2602 break;
2603 case TCC_OUTPUT_OBJ:
2604 ehdr.e_type = ET_REL;
2605 break;
2607 ehdr.e_machine = EM_TCC_TARGET;
2608 ehdr.e_version = EV_CURRENT;
2609 ehdr.e_shoff = file_offset;
2610 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2611 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2612 ehdr.e_shnum = shnum;
2613 ehdr.e_shstrndx = shnum - 1;
2615 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2616 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2617 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2619 sort_syms(s1, symtab_section);
2620 for(i = 1; i < s1->nb_sections; i++) {
2621 s = s1->sections[sec_order[i]];
2622 if (s->sh_type != SHT_NOBITS) {
2623 if (s->sh_type == SHT_DYNSYM)
2624 patch_dynsym_undef(s1, s);
2625 while (offset < s->sh_offset) {
2626 fputc(0, f);
2627 offset++;
2629 size = s->sh_size;
2630 if (size)
2631 fwrite(s->data, 1, size, f);
2632 offset += size;
2636 /* output section headers */
2637 while (offset < ehdr.e_shoff) {
2638 fputc(0, f);
2639 offset++;
2642 for(i = 0; i < s1->nb_sections; i++) {
2643 sh = &shdr;
2644 memset(sh, 0, sizeof(ElfW(Shdr)));
2645 s = s1->sections[i];
2646 if (s) {
2647 sh->sh_name = s->sh_name;
2648 sh->sh_type = s->sh_type;
2649 sh->sh_flags = s->sh_flags;
2650 sh->sh_entsize = s->sh_entsize;
2651 sh->sh_info = s->sh_info;
2652 if (s->link)
2653 sh->sh_link = s->link->sh_num;
2654 sh->sh_addralign = s->sh_addralign;
2655 sh->sh_addr = s->sh_addr;
2656 sh->sh_offset = s->sh_offset;
2657 sh->sh_size = s->sh_size;
2659 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2663 /* Write an elf, coff or "binary" file */
2664 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2665 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2667 int fd, mode, file_type;
2668 FILE *f;
2670 file_type = s1->output_type;
2671 if (file_type == TCC_OUTPUT_OBJ)
2672 mode = 0666;
2673 else
2674 mode = 0777;
2675 unlink(filename);
2676 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2677 if (fd < 0) {
2678 tcc_error_noabort("could not write '%s'", filename);
2679 return -1;
2681 f = fdopen(fd, "wb");
2682 if (s1->verbose)
2683 printf("<- %s\n", filename);
2685 #ifdef TCC_TARGET_COFF
2686 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2687 tcc_output_coff(s1, f);
2688 else
2689 #endif
2690 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2691 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2692 else
2693 tcc_output_binary(s1, f, sec_order);
2694 fclose(f);
2696 return 0;
2699 /* Output an elf, coff or binary file */
2700 /* XXX: suppress unneeded sections */
2701 static int elf_output_file(TCCState *s1, const char *filename)
2703 int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
2704 struct dyn_inf dyninf;
2705 ElfW(Phdr) *phdr;
2706 ElfW(Sym) *sym;
2707 Section *strsec, *interp, *dynamic, *dynstr;
2709 file_type = s1->output_type;
2710 s1->nb_errors = 0;
2712 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2713 if (file_type != TCC_OUTPUT_OBJ) {
2714 tcc_add_runtime(s1);
2717 phdr = NULL;
2718 sec_order = NULL;
2719 interp = dynamic = dynstr = NULL; /* avoid warning */
2720 dyninf.dyn_rel_off = 0; /* avoid warning */
2722 if (file_type != TCC_OUTPUT_OBJ) {
2723 relocate_common_syms();
2725 tcc_add_linker_symbols(s1);
2727 if (!s1->static_link) {
2728 if (file_type == TCC_OUTPUT_EXE) {
2729 char *ptr;
2730 /* allow override the dynamic loader */
2731 const char *elfint = getenv("LD_SO");
2732 if (elfint == NULL)
2733 elfint = DEFAULT_ELFINTERP(s1);
2734 /* add interpreter section only if executable */
2735 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2736 interp->sh_addralign = 1;
2737 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2738 strcpy(ptr, elfint);
2741 /* add dynamic symbol table */
2742 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2743 ".dynstr",
2744 ".hash", SHF_ALLOC);
2745 dynstr = s1->dynsym->link;
2747 /* add dynamic section */
2748 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2749 SHF_ALLOC | SHF_WRITE);
2750 dynamic->link = dynstr;
2751 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2753 build_got(s1);
2755 if (file_type == TCC_OUTPUT_EXE) {
2756 bind_exe_dynsyms(s1);
2758 if (s1->nb_errors) {
2759 ret = -1;
2760 goto the_end;
2763 bind_libs_dynsyms(s1);
2764 } else /* shared library case: simply export all global symbols */
2765 export_global_syms(s1);
2767 build_got_entries(s1);
2769 /* add a list of needed dlls */
2770 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2771 DLLReference *dllref = s1->loaded_dlls[i];
2772 if (dllref->level == 0)
2773 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2776 if (s1->rpath)
2777 put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath));
2779 /* XXX: currently, since we do not handle PIC code, we
2780 must relocate the readonly segments */
2781 if (file_type == TCC_OUTPUT_DLL) {
2782 if (s1->soname)
2783 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2784 put_dt(dynamic, DT_TEXTREL, 0);
2787 if (s1->symbolic)
2788 put_dt(dynamic, DT_SYMBOLIC, 0);
2790 /* add necessary space for other entries */
2791 dyninf.dyn_rel_off = dynamic->data_offset;
2792 dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
2793 } else {
2794 /* still need to build got entries in case of static link */
2795 build_got_entries(s1);
2799 /* we add a section for symbols */
2800 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2801 put_elf_str(strsec, "");
2803 /* compute number of sections */
2804 shnum = s1->nb_sections;
2806 /* this array is used to reorder sections in the output file */
2807 sec_order = tcc_malloc(sizeof(int) * shnum);
2808 sec_order[0] = 0;
2810 /* compute number of program headers */
2811 switch(file_type) {
2812 default:
2813 case TCC_OUTPUT_OBJ:
2814 phnum = 0;
2815 break;
2816 case TCC_OUTPUT_EXE:
2817 if (!s1->static_link)
2818 phnum = 4 + HAVE_PHDR;
2819 else
2820 phnum = 2;
2821 break;
2822 case TCC_OUTPUT_DLL:
2823 phnum = 3;
2824 break;
2827 /* Allocate strings for section names */
2828 alloc_sec_names(s1, file_type, strsec);
2830 /* allocate program segment headers */
2831 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2833 /* compute section to program header mapping */
2834 file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
2835 sec_order);
2837 /* Fill remaining program header and finalize relocation related to dynamic
2838 linking. */
2839 if (phnum > 0) {
2840 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2841 if (dynamic) {
2842 dyninf.dynamic = dynamic;
2843 dyninf.dynstr = dynstr;
2845 fill_dynamic(s1, &dyninf);
2847 /* put in GOT the dynamic section address and relocate PLT */
2848 write32le(s1->got->data, dynamic->sh_addr);
2849 if (file_type == TCC_OUTPUT_EXE
2850 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
2851 || file_type == TCC_OUTPUT_DLL
2852 #endif
2854 relocate_plt(s1);
2856 /* relocate symbols in .dynsym now that final addresses are known */
2857 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2858 if (sym->st_shndx == SHN_UNDEF) {
2859 /* relocate to PLT if symbol corresponds to a PLT entry,
2860 but not if it's a weak symbol */
2861 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
2862 sym->st_value = 0;
2863 else if (sym->st_value)
2864 sym->st_value += s1->plt->sh_addr;
2865 } else if (sym->st_shndx < SHN_LORESERVE) {
2866 /* do symbol relocation */
2867 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2873 /* if building executable or DLL, then relocate each section
2874 except the GOT which is already relocated */
2875 if (file_type != TCC_OUTPUT_OBJ) {
2876 ret = final_sections_reloc(s1);
2877 if (ret)
2878 goto the_end;
2881 /* Perform relocation to GOT or PLT entries */
2882 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2883 fill_got(s1);
2885 /* Create the ELF file with name 'filename' */
2886 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2887 the_end:
2888 tcc_free(s1->symtab_to_dynsym);
2889 tcc_free(sec_order);
2890 tcc_free(phdr);
2891 tcc_free(s1->sym_attrs);
2892 s1->sym_attrs = NULL;
2893 return ret;
2896 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2898 int ret;
2899 #ifdef TCC_TARGET_PE
2900 if (s->output_type != TCC_OUTPUT_OBJ) {
2901 ret = pe_output_file(s, filename);
2902 } else
2903 #endif
2904 ret = elf_output_file(s, filename);
2905 return ret;
2908 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2910 void *data;
2912 data = tcc_malloc(size);
2913 lseek(fd, file_offset, SEEK_SET);
2914 read(fd, data, size);
2915 return data;
2918 typedef struct SectionMergeInfo {
2919 Section *s; /* corresponding existing section */
2920 unsigned long offset; /* offset of the new section in the existing section */
2921 uint8_t new_section; /* true if section 's' was added */
2922 uint8_t link_once; /* true if link once section */
2923 } SectionMergeInfo;
2925 ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
2927 int size = read(fd, h, sizeof *h);
2928 if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
2929 if (h->e_type == ET_REL)
2930 return AFF_BINTYPE_REL;
2931 if (h->e_type == ET_DYN)
2932 return AFF_BINTYPE_DYN;
2933 } else if (size >= 8) {
2934 if (0 == memcmp(h, ARMAG, 8))
2935 return AFF_BINTYPE_AR;
2936 #ifdef TCC_TARGET_COFF
2937 if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
2938 return AFF_BINTYPE_C67;
2939 #endif
2941 return 0;
2944 /* load an object file and merge it with current files */
2945 /* XXX: handle correctly stab (debug) info */
2946 ST_FUNC int tcc_load_object_file(TCCState *s1,
2947 int fd, unsigned long file_offset)
2949 ElfW(Ehdr) ehdr;
2950 ElfW(Shdr) *shdr, *sh;
2951 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2952 unsigned char *strsec, *strtab;
2953 int *old_to_new_syms;
2954 char *sh_name, *name;
2955 SectionMergeInfo *sm_table, *sm;
2956 ElfW(Sym) *sym, *symtab;
2957 ElfW_Rel *rel;
2958 Section *s;
2960 int stab_index;
2961 int stabstr_index;
2963 stab_index = stabstr_index = 0;
2965 lseek(fd, file_offset, SEEK_SET);
2966 if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
2967 goto fail1;
2968 /* test CPU specific stuff */
2969 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2970 ehdr.e_machine != EM_TCC_TARGET) {
2971 fail1:
2972 tcc_error_noabort("invalid object file");
2973 return -1;
2975 /* read sections */
2976 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2977 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2978 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2980 /* load section names */
2981 sh = &shdr[ehdr.e_shstrndx];
2982 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2984 /* load symtab and strtab */
2985 old_to_new_syms = NULL;
2986 symtab = NULL;
2987 strtab = NULL;
2988 nb_syms = 0;
2989 for(i = 1; i < ehdr.e_shnum; i++) {
2990 sh = &shdr[i];
2991 if (sh->sh_type == SHT_SYMTAB) {
2992 if (symtab) {
2993 tcc_error_noabort("object must contain only one symtab");
2994 fail:
2995 ret = -1;
2996 goto the_end;
2998 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2999 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3000 sm_table[i].s = symtab_section;
3002 /* now load strtab */
3003 sh = &shdr[sh->sh_link];
3004 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
3008 /* now examine each section and try to merge its content with the
3009 ones in memory */
3010 for(i = 1; i < ehdr.e_shnum; i++) {
3011 /* no need to examine section name strtab */
3012 if (i == ehdr.e_shstrndx)
3013 continue;
3014 sh = &shdr[i];
3015 sh_name = (char *) strsec + sh->sh_name;
3016 /* ignore sections types we do not handle */
3017 if (sh->sh_type != SHT_PROGBITS &&
3018 sh->sh_type != SHT_RELX &&
3019 #ifdef TCC_ARM_EABI
3020 sh->sh_type != SHT_ARM_EXIDX &&
3021 #endif
3022 sh->sh_type != SHT_NOBITS &&
3023 sh->sh_type != SHT_PREINIT_ARRAY &&
3024 sh->sh_type != SHT_INIT_ARRAY &&
3025 sh->sh_type != SHT_FINI_ARRAY &&
3026 strcmp(sh_name, ".stabstr")
3028 continue;
3029 if (sh->sh_addralign < 1)
3030 sh->sh_addralign = 1;
3031 /* find corresponding section, if any */
3032 for(j = 1; j < s1->nb_sections;j++) {
3033 s = s1->sections[j];
3034 if (!strcmp(s->name, sh_name)) {
3035 if (!strncmp(sh_name, ".gnu.linkonce",
3036 sizeof(".gnu.linkonce") - 1)) {
3037 /* if a 'linkonce' section is already present, we
3038 do not add it again. It is a little tricky as
3039 symbols can still be defined in
3040 it. */
3041 sm_table[i].link_once = 1;
3042 goto next;
3043 } else {
3044 goto found;
3048 /* not found: create new section */
3049 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
3050 /* take as much info as possible from the section. sh_link and
3051 sh_info will be updated later */
3052 s->sh_addralign = sh->sh_addralign;
3053 s->sh_entsize = sh->sh_entsize;
3054 sm_table[i].new_section = 1;
3055 found:
3056 if (sh->sh_type != s->sh_type) {
3057 tcc_error_noabort("invalid section type");
3058 goto fail;
3061 /* align start of section */
3062 offset = s->data_offset;
3064 if (0 == strcmp(sh_name, ".stab")) {
3065 stab_index = i;
3066 goto no_align;
3068 if (0 == strcmp(sh_name, ".stabstr")) {
3069 stabstr_index = i;
3070 goto no_align;
3073 size = sh->sh_addralign - 1;
3074 offset = (offset + size) & ~size;
3075 if (sh->sh_addralign > s->sh_addralign)
3076 s->sh_addralign = sh->sh_addralign;
3077 s->data_offset = offset;
3078 no_align:
3079 sm_table[i].offset = offset;
3080 sm_table[i].s = s;
3081 /* concatenate sections */
3082 size = sh->sh_size;
3083 if (sh->sh_type != SHT_NOBITS) {
3084 unsigned char *ptr;
3085 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
3086 ptr = section_ptr_add(s, size);
3087 read(fd, ptr, size);
3088 } else {
3089 s->data_offset += size;
3091 next: ;
3094 /* gr relocate stab strings */
3095 if (stab_index && stabstr_index) {
3096 Stab_Sym *a, *b;
3097 unsigned o;
3098 s = sm_table[stab_index].s;
3099 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
3100 b = (Stab_Sym *)(s->data + s->data_offset);
3101 o = sm_table[stabstr_index].offset;
3102 while (a < b)
3103 a->n_strx += o, a++;
3106 /* second short pass to update sh_link and sh_info fields of new
3107 sections */
3108 for(i = 1; i < ehdr.e_shnum; i++) {
3109 s = sm_table[i].s;
3110 if (!s || !sm_table[i].new_section)
3111 continue;
3112 sh = &shdr[i];
3113 if (sh->sh_link > 0)
3114 s->link = sm_table[sh->sh_link].s;
3115 if (sh->sh_type == SHT_RELX) {
3116 s->sh_info = sm_table[sh->sh_info].s->sh_num;
3117 /* update backward link */
3118 s1->sections[s->sh_info]->reloc = s;
3121 sm = sm_table;
3123 /* resolve symbols */
3124 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
3126 sym = symtab + 1;
3127 for(i = 1; i < nb_syms; i++, sym++) {
3128 if (sym->st_shndx != SHN_UNDEF &&
3129 sym->st_shndx < SHN_LORESERVE) {
3130 sm = &sm_table[sym->st_shndx];
3131 if (sm->link_once) {
3132 /* if a symbol is in a link once section, we use the
3133 already defined symbol. It is very important to get
3134 correct relocations */
3135 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
3136 name = (char *) strtab + sym->st_name;
3137 sym_index = find_elf_sym(symtab_section, name);
3138 if (sym_index)
3139 old_to_new_syms[i] = sym_index;
3141 continue;
3143 /* if no corresponding section added, no need to add symbol */
3144 if (!sm->s)
3145 continue;
3146 /* convert section number */
3147 sym->st_shndx = sm->s->sh_num;
3148 /* offset value */
3149 sym->st_value += sm->offset;
3151 /* add symbol */
3152 name = (char *) strtab + sym->st_name;
3153 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
3154 sym->st_info, sym->st_other,
3155 sym->st_shndx, name);
3156 old_to_new_syms[i] = sym_index;
3159 /* third pass to patch relocation entries */
3160 for(i = 1; i < ehdr.e_shnum; i++) {
3161 s = sm_table[i].s;
3162 if (!s)
3163 continue;
3164 sh = &shdr[i];
3165 offset = sm_table[i].offset;
3166 switch(s->sh_type) {
3167 case SHT_RELX:
3168 /* take relocation offset information */
3169 offseti = sm_table[sh->sh_info].offset;
3170 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
3171 int type;
3172 unsigned sym_index;
3173 /* convert symbol index */
3174 type = ELFW(R_TYPE)(rel->r_info);
3175 sym_index = ELFW(R_SYM)(rel->r_info);
3176 /* NOTE: only one symtab assumed */
3177 if (sym_index >= nb_syms)
3178 goto invalid_reloc;
3179 sym_index = old_to_new_syms[sym_index];
3180 /* ignore link_once in rel section. */
3181 if (!sym_index && !sm->link_once
3182 #ifdef TCC_TARGET_ARM
3183 && type != R_ARM_V4BX
3184 #endif
3186 invalid_reloc:
3187 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3188 i, strsec + sh->sh_name, rel->r_offset);
3189 goto fail;
3191 rel->r_info = ELFW(R_INFO)(sym_index, type);
3192 /* offset the relocation offset */
3193 rel->r_offset += offseti;
3194 #ifdef TCC_TARGET_ARM
3195 /* Jumps and branches from a Thumb code to a PLT entry need
3196 special handling since PLT entries are ARM code.
3197 Unconditional bl instructions referencing PLT entries are
3198 handled by converting these instructions into blx
3199 instructions. Other case of instructions referencing a PLT
3200 entry require to add a Thumb stub before the PLT entry to
3201 switch to ARM mode. We set bit plt_thumb_stub of the
3202 attribute of a symbol to indicate such a case. */
3203 if (type == R_ARM_THM_JUMP24)
3204 alloc_sym_attr(s1, sym_index)->plt_thumb_stub = 1;
3205 #endif
3207 break;
3208 default:
3209 break;
3213 ret = 0;
3214 the_end:
3215 tcc_free(symtab);
3216 tcc_free(strtab);
3217 tcc_free(old_to_new_syms);
3218 tcc_free(sm_table);
3219 tcc_free(strsec);
3220 tcc_free(shdr);
3221 return ret;
3224 typedef struct ArchiveHeader {
3225 char ar_name[16]; /* name of this member */
3226 char ar_date[12]; /* file mtime */
3227 char ar_uid[6]; /* owner uid; printed as decimal */
3228 char ar_gid[6]; /* owner gid; printed as decimal */
3229 char ar_mode[8]; /* file mode, printed as octal */
3230 char ar_size[10]; /* file size, printed as decimal */
3231 char ar_fmag[2]; /* should contain ARFMAG */
3232 } ArchiveHeader;
3234 static int get_be32(const uint8_t *b)
3236 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
3239 static long get_be64(const uint8_t *b)
3241 long long ret = get_be32(b);
3242 ret = (ret << 32) | (unsigned)get_be32(b+4);
3243 return (long)ret;
3246 /* load only the objects which resolve undefined symbols */
3247 static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
3249 long i, bound, nsyms, sym_index, off, ret;
3250 uint8_t *data;
3251 const char *ar_names, *p;
3252 const uint8_t *ar_index;
3253 ElfW(Sym) *sym;
3255 data = tcc_malloc(size);
3256 if (read(fd, data, size) != size)
3257 goto fail;
3258 nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
3259 ar_index = data + entrysize;
3260 ar_names = (char *) ar_index + nsyms * entrysize;
3262 do {
3263 bound = 0;
3264 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
3265 sym_index = find_elf_sym(symtab_section, p);
3266 if(sym_index) {
3267 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
3268 if(sym->st_shndx == SHN_UNDEF) {
3269 off = (entrysize == 4
3270 ? get_be32(ar_index + i * 4)
3271 : get_be64(ar_index + i * 8))
3272 + sizeof(ArchiveHeader);
3273 ++bound;
3274 if(tcc_load_object_file(s1, fd, off) < 0) {
3275 fail:
3276 ret = -1;
3277 goto the_end;
3282 } while(bound);
3283 ret = 0;
3284 the_end:
3285 tcc_free(data);
3286 return ret;
3289 /* load a '.a' file */
3290 ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
3292 ArchiveHeader hdr;
3293 char ar_size[11];
3294 char ar_name[17];
3295 char magic[8];
3296 int size, len, i;
3297 unsigned long file_offset;
3299 /* skip magic which was already checked */
3300 read(fd, magic, sizeof(magic));
3302 for(;;) {
3303 len = read(fd, &hdr, sizeof(hdr));
3304 if (len == 0)
3305 break;
3306 if (len != sizeof(hdr)) {
3307 tcc_error_noabort("invalid archive");
3308 return -1;
3310 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
3311 ar_size[sizeof(hdr.ar_size)] = '\0';
3312 size = strtol(ar_size, NULL, 0);
3313 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
3314 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
3315 if (ar_name[i] != ' ')
3316 break;
3318 ar_name[i + 1] = '\0';
3319 file_offset = lseek(fd, 0, SEEK_CUR);
3320 /* align to even */
3321 size = (size + 1) & ~1;
3322 if (!strcmp(ar_name, "/")) {
3323 /* coff symbol table : we handle it */
3324 if(s1->alacarte_link)
3325 return tcc_load_alacarte(s1, fd, size, 4);
3326 } else if (!strcmp(ar_name, "/SYM64/")) {
3327 if(s1->alacarte_link)
3328 return tcc_load_alacarte(s1, fd, size, 8);
3329 } else {
3330 ElfW(Ehdr) ehdr;
3331 if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
3332 if (tcc_load_object_file(s1, fd, file_offset) < 0)
3333 return -1;
3336 lseek(fd, file_offset + size, SEEK_SET);
3338 return 0;
3341 #ifndef TCC_TARGET_PE
3342 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3343 is referenced by the user (so it should be added as DT_NEEDED in
3344 the generated ELF file) */
3345 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
3347 ElfW(Ehdr) ehdr;
3348 ElfW(Shdr) *shdr, *sh, *sh1;
3349 int i, j, nb_syms, nb_dts, sym_bind, ret;
3350 ElfW(Sym) *sym, *dynsym;
3351 ElfW(Dyn) *dt, *dynamic;
3352 unsigned char *dynstr;
3353 const char *name, *soname;
3354 DLLReference *dllref;
3356 read(fd, &ehdr, sizeof(ehdr));
3358 /* test CPU specific stuff */
3359 if (ehdr.e_ident[5] != ELFDATA2LSB ||
3360 ehdr.e_machine != EM_TCC_TARGET) {
3361 tcc_error_noabort("bad architecture");
3362 return -1;
3365 /* read sections */
3366 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
3368 /* load dynamic section and dynamic symbols */
3369 nb_syms = 0;
3370 nb_dts = 0;
3371 dynamic = NULL;
3372 dynsym = NULL; /* avoid warning */
3373 dynstr = NULL; /* avoid warning */
3374 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
3375 switch(sh->sh_type) {
3376 case SHT_DYNAMIC:
3377 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
3378 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
3379 break;
3380 case SHT_DYNSYM:
3381 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
3382 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
3383 sh1 = &shdr[sh->sh_link];
3384 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
3385 break;
3386 default:
3387 break;
3391 /* compute the real library name */
3392 soname = tcc_basename(filename);
3394 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3395 if (dt->d_tag == DT_SONAME) {
3396 soname = (char *) dynstr + dt->d_un.d_val;
3400 /* if the dll is already loaded, do not load it */
3401 for(i = 0; i < s1->nb_loaded_dlls; i++) {
3402 dllref = s1->loaded_dlls[i];
3403 if (!strcmp(soname, dllref->name)) {
3404 /* but update level if needed */
3405 if (level < dllref->level)
3406 dllref->level = level;
3407 ret = 0;
3408 goto the_end;
3412 /* add the dll and its level */
3413 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
3414 dllref->level = level;
3415 strcpy(dllref->name, soname);
3416 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
3418 /* add dynamic symbols in dynsym_section */
3419 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
3420 sym_bind = ELFW(ST_BIND)(sym->st_info);
3421 if (sym_bind == STB_LOCAL)
3422 continue;
3423 name = (char *) dynstr + sym->st_name;
3424 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
3425 sym->st_info, sym->st_other, sym->st_shndx, name);
3428 /* load all referenced DLLs */
3429 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
3430 switch(dt->d_tag) {
3431 case DT_NEEDED:
3432 name = (char *) dynstr + dt->d_un.d_val;
3433 for(j = 0; j < s1->nb_loaded_dlls; j++) {
3434 dllref = s1->loaded_dlls[j];
3435 if (!strcmp(name, dllref->name))
3436 goto already_loaded;
3438 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3439 tcc_error_noabort("referenced dll '%s' not found", name);
3440 ret = -1;
3441 goto the_end;
3443 already_loaded:
3444 break;
3447 ret = 0;
3448 the_end:
3449 tcc_free(dynstr);
3450 tcc_free(dynsym);
3451 tcc_free(dynamic);
3452 tcc_free(shdr);
3453 return ret;
3456 #define LD_TOK_NAME 256
3457 #define LD_TOK_EOF (-1)
3459 /* return next ld script token */
3460 static int ld_next(TCCState *s1, char *name, int name_size)
3462 int c;
3463 char *q;
3465 redo:
3466 switch(ch) {
3467 case ' ':
3468 case '\t':
3469 case '\f':
3470 case '\v':
3471 case '\r':
3472 case '\n':
3473 inp();
3474 goto redo;
3475 case '/':
3476 minp();
3477 if (ch == '*') {
3478 file->buf_ptr = parse_comment(file->buf_ptr);
3479 ch = file->buf_ptr[0];
3480 goto redo;
3481 } else {
3482 q = name;
3483 *q++ = '/';
3484 goto parse_name;
3486 break;
3487 case '\\':
3488 ch = handle_eob();
3489 if (ch != '\\')
3490 goto redo;
3491 /* fall through */
3492 /* case 'a' ... 'z': */
3493 case 'a':
3494 case 'b':
3495 case 'c':
3496 case 'd':
3497 case 'e':
3498 case 'f':
3499 case 'g':
3500 case 'h':
3501 case 'i':
3502 case 'j':
3503 case 'k':
3504 case 'l':
3505 case 'm':
3506 case 'n':
3507 case 'o':
3508 case 'p':
3509 case 'q':
3510 case 'r':
3511 case 's':
3512 case 't':
3513 case 'u':
3514 case 'v':
3515 case 'w':
3516 case 'x':
3517 case 'y':
3518 case 'z':
3519 /* case 'A' ... 'z': */
3520 case 'A':
3521 case 'B':
3522 case 'C':
3523 case 'D':
3524 case 'E':
3525 case 'F':
3526 case 'G':
3527 case 'H':
3528 case 'I':
3529 case 'J':
3530 case 'K':
3531 case 'L':
3532 case 'M':
3533 case 'N':
3534 case 'O':
3535 case 'P':
3536 case 'Q':
3537 case 'R':
3538 case 'S':
3539 case 'T':
3540 case 'U':
3541 case 'V':
3542 case 'W':
3543 case 'X':
3544 case 'Y':
3545 case 'Z':
3546 case '_':
3547 case '.':
3548 case '$':
3549 case '~':
3550 q = name;
3551 parse_name:
3552 for(;;) {
3553 if (!((ch >= 'a' && ch <= 'z') ||
3554 (ch >= 'A' && ch <= 'Z') ||
3555 (ch >= '0' && ch <= '9') ||
3556 strchr("/.-_+=$:\\,~", ch)))
3557 break;
3558 if ((q - name) < name_size - 1) {
3559 *q++ = ch;
3561 minp();
3563 *q = '\0';
3564 c = LD_TOK_NAME;
3565 break;
3566 case CH_EOF:
3567 c = LD_TOK_EOF;
3568 break;
3569 default:
3570 c = ch;
3571 inp();
3572 break;
3574 return c;
3577 static int ld_add_file(TCCState *s1, const char filename[])
3579 int ret;
3581 ret = tcc_add_file_internal(s1, filename, AFF_TYPE_BIN);
3582 if (ret)
3583 ret = tcc_add_dll(s1, filename, 0);
3584 return ret;
3587 static inline int new_undef_syms(void)
3589 int ret = 0;
3590 ret = new_undef_sym;
3591 new_undef_sym = 0;
3592 return ret;
3595 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3597 char filename[1024], libname[1024];
3598 int t, group, nblibs = 0, ret = 0;
3599 char **libs = NULL;
3601 group = !strcmp(cmd, "GROUP");
3602 if (!as_needed)
3603 new_undef_syms();
3604 t = ld_next(s1, filename, sizeof(filename));
3605 if (t != '(')
3606 expect("(");
3607 t = ld_next(s1, filename, sizeof(filename));
3608 for(;;) {
3609 libname[0] = '\0';
3610 if (t == LD_TOK_EOF) {
3611 tcc_error_noabort("unexpected end of file");
3612 ret = -1;
3613 goto lib_parse_error;
3614 } else if (t == ')') {
3615 break;
3616 } else if (t == '-') {
3617 t = ld_next(s1, filename, sizeof(filename));
3618 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3619 tcc_error_noabort("library name expected");
3620 ret = -1;
3621 goto lib_parse_error;
3623 pstrcpy(libname, sizeof libname, &filename[1]);
3624 if (s1->static_link) {
3625 snprintf(filename, sizeof filename, "lib%s.a", libname);
3626 } else {
3627 snprintf(filename, sizeof filename, "lib%s.so", libname);
3629 } else if (t != LD_TOK_NAME) {
3630 tcc_error_noabort("filename expected");
3631 ret = -1;
3632 goto lib_parse_error;
3634 if (!strcmp(filename, "AS_NEEDED")) {
3635 ret = ld_add_file_list(s1, cmd, 1);
3636 if (ret)
3637 goto lib_parse_error;
3638 } else {
3639 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3640 if (!as_needed) {
3641 ret = ld_add_file(s1, filename);
3642 if (ret)
3643 goto lib_parse_error;
3644 if (group) {
3645 /* Add the filename *and* the libname to avoid future conversions */
3646 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename));
3647 if (libname[0] != '\0')
3648 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname));
3652 t = ld_next(s1, filename, sizeof(filename));
3653 if (t == ',') {
3654 t = ld_next(s1, filename, sizeof(filename));
3657 if (group && !as_needed) {
3658 while (new_undef_syms()) {
3659 int i;
3661 for (i = 0; i < nblibs; i ++)
3662 ld_add_file(s1, libs[i]);
3665 lib_parse_error:
3666 dynarray_reset(&libs, &nblibs);
3667 return ret;
3670 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3671 files */
3672 ST_FUNC int tcc_load_ldscript(TCCState *s1)
3674 char cmd[64];
3675 char filename[1024];
3676 int t, ret;
3678 ch = handle_eob();
3679 for(;;) {
3680 t = ld_next(s1, cmd, sizeof(cmd));
3681 if (t == LD_TOK_EOF)
3682 return 0;
3683 else if (t != LD_TOK_NAME)
3684 return -1;
3685 if (!strcmp(cmd, "INPUT") ||
3686 !strcmp(cmd, "GROUP")) {
3687 ret = ld_add_file_list(s1, cmd, 0);
3688 if (ret)
3689 return ret;
3690 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3691 !strcmp(cmd, "TARGET")) {
3692 /* ignore some commands */
3693 t = ld_next(s1, cmd, sizeof(cmd));
3694 if (t != '(')
3695 expect("(");
3696 for(;;) {
3697 t = ld_next(s1, filename, sizeof(filename));
3698 if (t == LD_TOK_EOF) {
3699 tcc_error_noabort("unexpected end of file");
3700 return -1;
3701 } else if (t == ')') {
3702 break;
3705 } else {
3706 return -1;
3709 return 0;
3711 #endif /* !TCC_TARGET_PE */