ELF: Make first PT_LOAD cover headers
[tinycc.git] / tccelf.c
blobf92021c59b8c8a7306e0c2eb23f8eee04080942d
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 /* XXX: avoid static variable */
24 static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */
26 ST_FUNC int put_elf_str(Section *s, const char *sym)
28 int offset, len;
29 char *ptr;
31 len = strlen(sym) + 1;
32 offset = s->data_offset;
33 ptr = section_ptr_add(s, len);
34 memcpy(ptr, sym, len);
35 return offset;
38 /* elf symbol hashing function */
39 static unsigned long elf_hash(const unsigned char *name)
41 unsigned long h = 0, g;
43 while (*name) {
44 h = (h << 4) + *name++;
45 g = h & 0xf0000000;
46 if (g)
47 h ^= g >> 24;
48 h &= ~g;
50 return h;
53 /* rebuild hash table of section s */
54 /* NOTE: we do factorize the hash table code to go faster */
55 static void rebuild_hash(Section *s, unsigned int nb_buckets)
57 ElfW(Sym) *sym;
58 int *ptr, *hash, nb_syms, sym_index, h;
59 unsigned char *strtab;
61 strtab = s->link->data;
62 nb_syms = s->data_offset / sizeof(ElfW(Sym));
64 s->hash->data_offset = 0;
65 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
66 ptr[0] = nb_buckets;
67 ptr[1] = nb_syms;
68 ptr += 2;
69 hash = ptr;
70 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
71 ptr += nb_buckets + 1;
73 sym = (ElfW(Sym) *)s->data + 1;
74 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
75 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
76 h = elf_hash(strtab + sym->st_name) % nb_buckets;
77 *ptr = hash[h];
78 hash[h] = sym_index;
79 } else {
80 *ptr = 0;
82 ptr++;
83 sym++;
87 /* return the symbol number */
88 ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
89 int info, int other, int shndx, const char *name)
91 int name_offset, sym_index;
92 int nbuckets, h;
93 ElfW(Sym) *sym;
94 Section *hs;
96 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
97 if (name)
98 name_offset = put_elf_str(s->link, name);
99 else
100 name_offset = 0;
101 /* XXX: endianness */
102 sym->st_name = name_offset;
103 sym->st_value = value;
104 sym->st_size = size;
105 sym->st_info = info;
106 sym->st_other = other;
107 sym->st_shndx = shndx;
108 sym_index = sym - (ElfW(Sym) *)s->data;
109 hs = s->hash;
110 if (hs) {
111 int *ptr, *base;
112 ptr = section_ptr_add(hs, sizeof(int));
113 base = (int *)hs->data;
114 /* only add global or weak symbols */
115 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
116 /* add another hashing entry */
117 nbuckets = base[0];
118 h = elf_hash((unsigned char *) name) % nbuckets;
119 *ptr = base[2 + h];
120 base[2 + h] = sym_index;
121 base[1]++;
122 /* we resize the hash table */
123 hs->nb_hashed_syms++;
124 if (hs->nb_hashed_syms > 2 * nbuckets) {
125 rebuild_hash(s, 2 * nbuckets);
127 } else {
128 *ptr = 0;
129 base[1]++;
132 return sym_index;
135 /* find global ELF symbol 'name' and return its index. Return 0 if not
136 found. */
137 ST_FUNC int find_elf_sym(Section *s, const char *name)
139 ElfW(Sym) *sym;
140 Section *hs;
141 int nbuckets, sym_index, h;
142 const char *name1;
144 hs = s->hash;
145 if (!hs)
146 return 0;
147 nbuckets = ((int *)hs->data)[0];
148 h = elf_hash((unsigned char *) name) % nbuckets;
149 sym_index = ((int *)hs->data)[2 + h];
150 while (sym_index != 0) {
151 sym = &((ElfW(Sym) *)s->data)[sym_index];
152 name1 = (char *) s->link->data + sym->st_name;
153 if (!strcmp(name, name1))
154 return sym_index;
155 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
157 return 0;
160 /* return elf symbol value, signal error if 'err' is nonzero */
161 ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err)
163 int sym_index;
164 ElfW(Sym) *sym;
166 sym_index = find_elf_sym(s->symtab, name);
167 sym = &((ElfW(Sym) *)s->symtab->data)[sym_index];
168 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
169 if (err)
170 tcc_error("%s not defined", name);
171 return 0;
173 return sym->st_value;
176 /* return elf symbol value */
177 LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
179 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0);
182 #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
183 /* return elf symbol value or error */
184 ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
186 return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1);
188 #endif
190 /* add an elf symbol : check if it is already defined and patch
191 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
192 ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size,
193 int info, int other, int sh_num, const char *name)
195 ElfW(Sym) *esym;
196 int sym_bind, sym_index, sym_type, esym_bind;
197 unsigned char sym_vis, esym_vis, new_vis;
199 sym_bind = ELFW(ST_BIND)(info);
200 sym_type = ELFW(ST_TYPE)(info);
201 sym_vis = ELFW(ST_VISIBILITY)(other);
203 if (sym_bind != STB_LOCAL) {
204 /* we search global or weak symbols */
205 sym_index = find_elf_sym(s, name);
206 if (!sym_index)
207 goto do_def;
208 esym = &((ElfW(Sym) *)s->data)[sym_index];
209 if (esym->st_shndx != SHN_UNDEF) {
210 esym_bind = ELFW(ST_BIND)(esym->st_info);
211 /* propagate the most constraining visibility */
212 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
213 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
214 if (esym_vis == STV_DEFAULT) {
215 new_vis = sym_vis;
216 } else if (sym_vis == STV_DEFAULT) {
217 new_vis = esym_vis;
218 } else {
219 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
221 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
222 | new_vis;
223 other = esym->st_other; /* in case we have to patch esym */
224 if (sh_num == SHN_UNDEF) {
225 /* ignore adding of undefined symbol if the
226 corresponding symbol is already defined */
227 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
228 /* global overrides weak, so patch */
229 goto do_patch;
230 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
231 /* weak is ignored if already global */
232 } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
233 /* keep first-found weak definition, ignore subsequents */
234 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
235 /* ignore hidden symbols after */
236 } else if (esym->st_shndx == SHN_COMMON
237 && (sh_num < SHN_LORESERVE || sh_num == SHN_COMMON)) {
238 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
239 No idea if this is the correct solution ... */
240 goto do_patch;
241 } else if (s == tcc_state->dynsymtab_section) {
242 /* we accept that two DLL define the same symbol */
243 } else {
244 #if 0
245 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
246 sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
247 #endif
248 tcc_error_noabort("'%s' defined twice", name);
250 } else {
251 do_patch:
252 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
253 esym->st_shndx = sh_num;
254 new_undef_sym = 1;
255 esym->st_value = value;
256 esym->st_size = size;
257 esym->st_other = other;
259 } else {
260 do_def:
261 sym_index = put_elf_sym(s, value, size,
262 ELFW(ST_INFO)(sym_bind, sym_type), other,
263 sh_num, name);
265 return sym_index;
268 /* put relocation */
269 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
270 int type, int symbol)
272 char buf[256];
273 Section *sr;
274 ElfW_Rel *rel;
276 sr = s->reloc;
277 if (!sr) {
278 /* if no relocation section, create it */
279 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
280 /* if the symtab is allocated, then we consider the relocation
281 are also */
282 sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
283 sr->sh_entsize = sizeof(ElfW_Rel);
284 sr->link = symtab;
285 sr->sh_info = s->sh_num;
286 s->reloc = sr;
288 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
289 rel->r_offset = offset;
290 rel->r_info = ELFW(R_INFO)(symbol, type);
291 #ifdef TCC_TARGET_X86_64
292 rel->r_addend = 0;
293 #endif
296 /* put stab debug information */
298 ST_FUNC void put_stabs(const char *str, int type, int other, int desc,
299 unsigned long value)
301 Stab_Sym *sym;
303 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
304 if (str) {
305 sym->n_strx = put_elf_str(stabstr_section, str);
306 } else {
307 sym->n_strx = 0;
309 sym->n_type = type;
310 sym->n_other = other;
311 sym->n_desc = desc;
312 sym->n_value = value;
315 ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc,
316 unsigned long value, Section *sec, int sym_index)
318 put_stabs(str, type, other, desc, value);
319 put_elf_reloc(symtab_section, stab_section,
320 stab_section->data_offset - sizeof(unsigned int),
321 R_DATA_32, sym_index);
324 ST_FUNC void put_stabn(int type, int other, int desc, int value)
326 put_stabs(NULL, type, other, desc, value);
329 ST_FUNC void put_stabd(int type, int other, int desc)
331 put_stabs(NULL, type, other, desc, 0);
334 /* Browse each elem of type <type> in section <sec> starting at elem <startoff>
335 using variable <elem> */
336 #define for_each_elem(sec, startoff, elem, type) \
337 for (elem = (type *) sec->data + startoff; \
338 elem < (type *) (sec->data + sec->data_offset); elem++)
340 /* In an ELF file symbol table, the local symbols must appear below
341 the global and weak ones. Since TCC cannot sort it while generating
342 the code, we must do it after. All the relocation tables are also
343 modified to take into account the symbol table sorting */
344 static void sort_syms(TCCState *s1, Section *s)
346 int *old_to_new_syms;
347 ElfW(Sym) *new_syms;
348 int nb_syms, i;
349 ElfW(Sym) *p, *q;
350 ElfW_Rel *rel;
351 Section *sr;
352 int type, sym_index;
354 nb_syms = s->data_offset / sizeof(ElfW(Sym));
355 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
356 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
358 /* first pass for local symbols */
359 p = (ElfW(Sym) *)s->data;
360 q = new_syms;
361 for(i = 0; i < nb_syms; i++) {
362 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
363 old_to_new_syms[i] = q - new_syms;
364 *q++ = *p;
366 p++;
368 /* save the number of local symbols in section header */
369 s->sh_info = q - new_syms;
371 /* then second pass for non local symbols */
372 p = (ElfW(Sym) *)s->data;
373 for(i = 0; i < nb_syms; i++) {
374 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
375 old_to_new_syms[i] = q - new_syms;
376 *q++ = *p;
378 p++;
381 /* we copy the new symbols to the old */
382 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
383 tcc_free(new_syms);
385 /* now we modify all the relocations */
386 for(i = 1; i < s1->nb_sections; i++) {
387 sr = s1->sections[i];
388 if (sr->sh_type == SHT_RELX && sr->link == s) {
389 for_each_elem(sr, 0, rel, ElfW_Rel) {
390 sym_index = ELFW(R_SYM)(rel->r_info);
391 type = ELFW(R_TYPE)(rel->r_info);
392 sym_index = old_to_new_syms[sym_index];
393 rel->r_info = ELFW(R_INFO)(sym_index, type);
398 tcc_free(old_to_new_syms);
401 /* relocate common symbols in the .bss section */
402 ST_FUNC void relocate_common_syms(void)
404 ElfW(Sym) *sym;
405 unsigned long offset, align;
407 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
408 if (sym->st_shndx == SHN_COMMON) {
409 /* align symbol */
410 align = sym->st_value;
411 offset = bss_section->data_offset;
412 offset = (offset + align - 1) & -align;
413 sym->st_value = offset;
414 sym->st_shndx = bss_section->sh_num;
415 offset += sym->st_size;
416 bss_section->data_offset = offset;
421 /* relocate symbol table, resolve undefined symbols if do_resolve is
422 true and output error if undefined symbol. */
423 ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
425 ElfW(Sym) *sym, *esym;
426 int sym_bind, sh_num, sym_index;
427 const char *name;
429 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
430 sh_num = sym->st_shndx;
431 if (sh_num == SHN_UNDEF) {
432 name = (char *) strtab_section->data + sym->st_name;
433 /* Use ld.so to resolve symbol for us (for tcc -run) */
434 if (do_resolve) {
435 #if defined TCC_IS_NATIVE && !defined _WIN32
436 void *addr;
437 name = (char *) symtab_section->link->data + sym->st_name;
438 addr = resolve_sym(s1, name);
439 if (addr) {
440 sym->st_value = (addr_t)addr;
441 goto found;
443 #endif
444 } else if (s1->dynsym) {
445 /* if dynamic symbol exist, then use it */
446 sym_index = find_elf_sym(s1->dynsym, name);
447 if (sym_index) {
448 esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
449 sym->st_value = esym->st_value;
450 goto found;
453 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
454 it */
455 if (!strcmp(name, "_fp_hw"))
456 goto found;
457 /* only weak symbols are accepted to be undefined. Their
458 value is zero */
459 sym_bind = ELFW(ST_BIND)(sym->st_info);
460 if (sym_bind == STB_WEAK) {
461 sym->st_value = 0;
462 } else {
463 tcc_error_noabort("undefined symbol '%s'", name);
465 } else if (sh_num < SHN_LORESERVE) {
466 /* add section base */
467 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
469 found: ;
473 #ifdef TCC_HAS_RUNTIME_PLTGOT
474 #ifdef TCC_TARGET_X86_64
475 #define JMP_TABLE_ENTRY_SIZE 14
476 static addr_t add_jmp_table(TCCState *s1, addr_t val)
478 char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset;
479 s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE;
480 /* jmp *0x0(%rip) */
481 p[0] = 0xff;
482 p[1] = 0x25;
483 *(int *)(p + 2) = 0;
484 *(addr_t *)(p + 6) = val;
485 return (addr_t)p;
488 static addr_t add_got_table(TCCState *s1, addr_t val)
490 addr_t *p = (addr_t *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset);
491 s1->runtime_plt_and_got_offset += sizeof(addr_t);
492 *p = val;
493 return (addr_t)p;
495 #elif defined TCC_TARGET_ARM
496 #define JMP_TABLE_ENTRY_SIZE 8
497 static addr_t add_jmp_table(TCCState *s1, int val)
499 uint32_t *p = (uint32_t *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset);
500 s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE;
501 /* ldr pc, [pc, #-4] */
502 p[0] = 0xE51FF004;
503 p[1] = val;
504 return (addr_t)p;
506 #endif
507 #endif /* def TCC_HAS_RUNTIME_PLTGOT */
509 /* relocate a given section (CPU dependent) by applying the relocations
510 in the associated relocation section */
511 ST_FUNC void relocate_section(TCCState *s1, Section *s)
513 Section *sr = s->reloc;
514 ElfW_Rel *rel;
515 ElfW(Sym) *sym;
516 int type, sym_index;
517 unsigned char *ptr;
518 addr_t val, addr;
519 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
520 ElfW_Rel *qrel = (ElfW_Rel *) sr->data; /* ptr to next reloc entry reused */
521 int esym_index;
522 #endif
524 for_each_elem(sr, 0, rel, ElfW_Rel) {
525 ptr = s->data + rel->r_offset;
527 sym_index = ELFW(R_SYM)(rel->r_info);
528 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
529 val = sym->st_value;
530 #ifdef TCC_TARGET_X86_64
531 val += rel->r_addend;
532 #endif
533 type = ELFW(R_TYPE)(rel->r_info);
534 addr = s->sh_addr + rel->r_offset;
536 /* CPU specific */
537 switch(type) {
538 #if defined(TCC_TARGET_I386)
539 case R_386_32:
540 if (s1->output_type == TCC_OUTPUT_DLL) {
541 esym_index = s1->symtab_to_dynsym[sym_index];
542 qrel->r_offset = rel->r_offset;
543 if (esym_index) {
544 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
545 qrel++;
546 break;
547 } else {
548 qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
549 qrel++;
552 *(int *)ptr += val;
553 break;
554 case R_386_PC32:
555 if (s1->output_type == TCC_OUTPUT_DLL) {
556 /* DLL relocation */
557 esym_index = s1->symtab_to_dynsym[sym_index];
558 if (esym_index) {
559 qrel->r_offset = rel->r_offset;
560 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
561 qrel++;
562 break;
565 *(int *)ptr += val - addr;
566 break;
567 case R_386_PLT32:
568 *(int *)ptr += val - addr;
569 break;
570 case R_386_GLOB_DAT:
571 case R_386_JMP_SLOT:
572 *(int *)ptr = val;
573 break;
574 case R_386_GOTPC:
575 *(int *)ptr += s1->got->sh_addr - addr;
576 break;
577 case R_386_GOTOFF:
578 *(int *)ptr += val - s1->got->sh_addr;
579 break;
580 case R_386_GOT32:
581 /* we load the got offset */
582 *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
583 break;
584 case R_386_16:
585 if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {
586 output_file:
587 tcc_error("can only produce 16-bit binary files");
589 *(short *)ptr += val;
590 break;
591 case R_386_PC16:
592 if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY)
593 goto output_file;
594 *(short *)ptr += val - addr;
595 break;
596 #elif defined(TCC_TARGET_ARM)
597 case R_ARM_PC24:
598 case R_ARM_CALL:
599 case R_ARM_JUMP24:
600 case R_ARM_PLT32:
602 int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko;
603 x = (*(int *) ptr) & 0xffffff;
604 (*(int *)ptr) &= 0xff000000;
605 if (x & 0x800000)
606 x -= 0x1000000;
607 x <<= 2;
608 blx_avail = (TCC_ARM_VERSION >= 5);
609 is_thumb = val & 1;
610 is_bl = (*(unsigned *) ptr) >> 24 == 0xeb;
611 is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl));
612 x += val - addr;
613 h = x & 2;
614 th_ko = (x & 3) && (!blx_avail || !is_call);
615 #ifdef TCC_HAS_RUNTIME_PLTGOT
616 if (s1->output_type == TCC_OUTPUT_MEMORY) {
617 if (th_ko || x >= 0x2000000 || x < -0x2000000) {
618 x += add_jmp_table(s1, val) - val; /* add veneer */
619 th_ko = (x & 3) && (!blx_avail || !is_call);
620 is_thumb = 0; /* Veneer uses ARM instructions */
623 #endif
624 if (th_ko || x >= 0x2000000 || x < -0x2000000)
625 tcc_error("can't relocate value at %x",addr);
626 x >>= 2;
627 x &= 0xffffff;
628 /* Only reached if blx is avail and it is a call */
629 if (is_thumb) {
630 x |= h << 24;
631 (*(int *)ptr) = 0xfa << 24; /* bl -> blx */
633 (*(int *) ptr) |= x;
635 break;
636 /* Since these relocations only concern Thumb-2 and blx instruction was
637 introduced before Thumb-2, we can assume blx is available and not
638 guard its use */
639 case R_ARM_THM_PC22:
640 case R_ARM_THM_JUMP24:
642 int x, hi, lo, s, j1, j2, i1, i2, imm10, imm11;
643 int to_thumb, is_call, to_plt, blx_bit = 1 << 12;
644 Section *plt;
646 /* weak reference */
647 if (sym->st_shndx == SHN_UNDEF &&
648 ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
649 break;
651 /* Get initial offset */
652 hi = (*(uint16_t *)ptr);
653 lo = (*(uint16_t *)(ptr+2));
654 s = (hi >> 10) & 1;
655 j1 = (lo >> 13) & 1;
656 j2 = (lo >> 11) & 1;
657 i1 = (j1 ^ s) ^ 1;
658 i2 = (j2 ^ s) ^ 1;
659 imm10 = hi & 0x3ff;
660 imm11 = lo & 0x7ff;
661 x = (s << 24) | (i1 << 23) | (i2 << 22) |
662 (imm10 << 12) | (imm11 << 1);
663 if (x & 0x01000000)
664 x -= 0x02000000;
666 /* Relocation infos */
667 to_thumb = val & 1;
668 plt = s1->plt;
669 to_plt = (val >= plt->sh_addr) &&
670 (val < plt->sh_addr + plt->data_offset);
671 is_call = (type == R_ARM_THM_PC22);
673 /* Compute final offset */
674 if (to_plt && !is_call) /* Point to 1st instr of Thumb stub */
675 x -= 4;
676 x += val - addr;
677 if (!to_thumb && is_call) {
678 blx_bit = 0; /* bl -> blx */
679 x = (x + 3) & -4; /* Compute offset from aligned PC */
682 /* Check that relocation is possible
683 * offset must not be out of range
684 * if target is to be entered in arm mode:
685 - bit 1 must not set
686 - instruction must be a call (bl) or a jump to PLT */
687 if (!to_thumb || x >= 0x1000000 || x < -0x1000000)
688 if (to_thumb || (val & 2) || (!is_call && !to_plt))
689 tcc_error("can't relocate value at %x",addr);
691 /* Compute and store final offset */
692 s = (x >> 24) & 1;
693 i1 = (x >> 23) & 1;
694 i2 = (x >> 22) & 1;
695 j1 = s ^ (i1 ^ 1);
696 j2 = s ^ (i2 ^ 1);
697 imm10 = (x >> 12) & 0x3ff;
698 imm11 = (x >> 1) & 0x7ff;
699 (*(uint16_t *)ptr) = (uint16_t) ((hi & 0xf800) |
700 (s << 10) | imm10);
701 (*(uint16_t *)(ptr+2)) = (uint16_t) ((lo & 0xc000) |
702 (j1 << 13) | blx_bit | (j2 << 11) |
703 imm11);
705 break;
706 case R_ARM_MOVT_ABS:
707 case R_ARM_MOVW_ABS_NC:
709 int x, imm4, imm12;
710 if (type == R_ARM_MOVT_ABS)
711 val >>= 16;
712 imm12 = val & 0xfff;
713 imm4 = (val >> 12) & 0xf;
714 x = (imm4 << 16) | imm12;
715 if (type == R_ARM_THM_MOVT_ABS)
716 *(int *)ptr |= x;
717 else
718 *(int *)ptr += x;
720 break;
721 case R_ARM_THM_MOVT_ABS:
722 case R_ARM_THM_MOVW_ABS_NC:
724 int x, i, imm4, imm3, imm8;
725 if (type == R_ARM_THM_MOVT_ABS)
726 val >>= 16;
727 imm8 = val & 0xff;
728 imm3 = (val >> 8) & 0x7;
729 i = (val >> 11) & 1;
730 imm4 = (val >> 12) & 0xf;
731 x = (imm3 << 28) | (imm8 << 16) | (i << 10) | imm4;
732 if (type == R_ARM_THM_MOVT_ABS)
733 *(int *)ptr |= x;
734 else
735 *(int *)ptr += x;
737 break;
738 case R_ARM_PREL31:
740 int x;
741 x = (*(int *)ptr) & 0x7fffffff;
742 (*(int *)ptr) &= 0x80000000;
743 x = (x * 2) / 2;
744 x += val - addr;
745 if((x^(x>>1))&0x40000000)
746 tcc_error("can't relocate value at %x",addr);
747 (*(int *)ptr) |= x & 0x7fffffff;
749 case R_ARM_ABS32:
750 *(int *)ptr += val;
751 break;
752 case R_ARM_REL32:
753 *(int *)ptr += val - addr;
754 break;
755 case R_ARM_GOTPC:
756 *(int *)ptr += s1->got->sh_addr - addr;
757 break;
758 case R_ARM_GOTOFF:
759 *(int *)ptr += val - s1->got->sh_addr;
760 break;
761 case R_ARM_GOT32:
762 /* we load the got offset */
763 *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
764 break;
765 case R_ARM_COPY:
766 break;
767 case R_ARM_V4BX:
768 /* trade Thumb support for ARMv4 support */
769 if ((0x0ffffff0 & *(int*)ptr) == 0x012FFF10)
770 *(int*)ptr ^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */
771 break;
772 default:
773 fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
774 type, (unsigned)addr, ptr, (unsigned)val);
775 break;
776 #elif defined(TCC_TARGET_C67)
777 case R_C60_32:
778 *(int *)ptr += val;
779 break;
780 case R_C60LO16:
782 uint32_t orig;
784 /* put the low 16 bits of the absolute address
785 add to what is already there */
787 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
788 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
790 /* patch both at once - assumes always in pairs Low - High */
792 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
793 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
795 break;
796 case R_C60HI16:
797 break;
798 default:
799 fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
800 type, (unsigned)addr, ptr, (unsigned)val);
801 break;
802 #elif defined(TCC_TARGET_X86_64)
803 case R_X86_64_64:
804 if (s1->output_type == TCC_OUTPUT_DLL) {
805 esym_index = s1->symtab_to_dynsym[sym_index];
806 qrel->r_offset = rel->r_offset;
807 if (esym_index) {
808 qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64);
809 qrel->r_addend = rel->r_addend;
810 qrel++;
811 break;
812 } else {
813 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
814 qrel->r_addend = *(long long *)ptr + val;
815 qrel++;
818 *(long long *)ptr += val;
819 break;
820 case R_X86_64_32:
821 case R_X86_64_32S:
822 if (s1->output_type == TCC_OUTPUT_DLL) {
823 /* XXX: this logic may depend on TCC's codegen
824 now TCC uses R_X86_64_32 even for a 64bit pointer */
825 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
826 qrel->r_addend = *(int *)ptr + val;
827 qrel++;
829 *(int *)ptr += val;
830 break;
832 case R_X86_64_PC32:
833 if (s1->output_type == TCC_OUTPUT_DLL) {
834 /* DLL relocation */
835 esym_index = s1->symtab_to_dynsym[sym_index];
836 if (esym_index) {
837 qrel->r_offset = rel->r_offset;
838 qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
839 qrel->r_addend = *(int *)ptr;
840 qrel++;
841 break;
844 goto plt32pc32;
846 case R_X86_64_PLT32:
847 /* We've put the PLT slot offset into r_addend when generating
848 it, and that's what we must use as relocation value (adjusted
849 by section offset of course). */
850 if (s1->output_type != TCC_OUTPUT_MEMORY)
851 val = s1->plt->sh_addr + rel->r_addend;
852 /* fallthrough. */
854 plt32pc32:
856 long long diff;
857 diff = (long long)val - addr;
858 if (diff <= -2147483647 || diff > 2147483647) {
859 #ifdef TCC_HAS_RUNTIME_PLTGOT
860 /* XXX: naive support for over 32bit jump */
861 if (s1->output_type == TCC_OUTPUT_MEMORY) {
862 val = (add_jmp_table(s1, val - rel->r_addend) +
863 rel->r_addend);
864 diff = val - addr;
866 #endif
867 if (diff <= -2147483647 || diff > 2147483647) {
868 tcc_error("internal error: relocation failed");
871 *(int *)ptr += diff;
873 break;
874 case R_X86_64_GLOB_DAT:
875 case R_X86_64_JUMP_SLOT:
876 /* They don't need addend */
877 *(int *)ptr = val - rel->r_addend;
878 break;
879 case R_X86_64_GOTPCREL:
880 #ifdef TCC_HAS_RUNTIME_PLTGOT
881 if (s1->output_type == TCC_OUTPUT_MEMORY) {
882 val = add_got_table(s1, val - rel->r_addend) + rel->r_addend;
883 *(int *)ptr += val - addr;
884 break;
886 #endif
887 *(int *)ptr += (s1->got->sh_addr - addr +
888 s1->sym_attrs[sym_index].got_offset - 4);
889 break;
890 case R_X86_64_GOTTPOFF:
891 *(int *)ptr += val - s1->got->sh_addr;
892 break;
893 case R_X86_64_GOT32:
894 /* we load the got offset */
895 *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
896 break;
897 #else
898 #error unsupported processor
899 #endif
902 /* if the relocation is allocated, we change its symbol table */
903 if (sr->sh_flags & SHF_ALLOC)
904 sr->link = s1->dynsym;
907 /* relocate relocation table in 'sr' */
908 static void relocate_rel(TCCState *s1, Section *sr)
910 Section *s;
911 ElfW_Rel *rel;
913 s = s1->sections[sr->sh_info];
914 for_each_elem(sr, 0, rel, ElfW_Rel)
915 rel->r_offset += s->sh_addr;
918 /* count the number of dynamic relocations so that we can reserve
919 their space */
920 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
922 ElfW_Rel *rel;
923 int sym_index, esym_index, type, count;
925 count = 0;
926 for_each_elem(sr, 0, rel, ElfW_Rel) {
927 sym_index = ELFW(R_SYM)(rel->r_info);
928 type = ELFW(R_TYPE)(rel->r_info);
929 switch(type) {
930 #if defined(TCC_TARGET_I386)
931 case R_386_32:
932 #elif defined(TCC_TARGET_X86_64)
933 case R_X86_64_32:
934 case R_X86_64_32S:
935 case R_X86_64_64:
936 #endif
937 count++;
938 break;
939 #if defined(TCC_TARGET_I386)
940 case R_386_PC32:
941 #elif defined(TCC_TARGET_X86_64)
942 case R_X86_64_PC32:
943 #endif
944 esym_index = s1->symtab_to_dynsym[sym_index];
945 if (esym_index)
946 count++;
947 break;
948 default:
949 break;
952 if (count) {
953 /* allocate the section */
954 sr->sh_flags |= SHF_ALLOC;
955 sr->sh_size = count * sizeof(ElfW_Rel);
957 return count;
960 static struct sym_attr *alloc_sym_attr(TCCState *s1, int index)
962 int n;
963 struct sym_attr *tab;
965 if (index >= s1->nb_sym_attrs) {
966 /* find immediately bigger power of 2 and reallocate array */
967 n = 1;
968 while (index >= n)
969 n *= 2;
970 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
971 s1->sym_attrs = tab;
972 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
973 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
974 s1->nb_sym_attrs = n;
976 return &s1->sym_attrs[index];
979 /* XXX: suppress that */
980 static void put32(unsigned char *p, uint32_t val)
982 p[0] = val;
983 p[1] = val >> 8;
984 p[2] = val >> 16;
985 p[3] = val >> 24;
988 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
989 defined(TCC_TARGET_X86_64)
990 static uint32_t get32(unsigned char *p)
992 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
994 #endif
996 static void build_got(TCCState *s1)
998 unsigned char *ptr;
1000 /* if no got, then create it */
1001 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
1002 s1->got->sh_entsize = 4;
1003 add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
1004 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
1005 ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
1006 #if PTR_SIZE == 4
1007 /* keep space for _DYNAMIC pointer, if present */
1008 put32(ptr, 0);
1009 /* two dummy got entries */
1010 put32(ptr + 4, 0);
1011 put32(ptr + 8, 0);
1012 #else
1013 /* keep space for _DYNAMIC pointer, if present */
1014 put32(ptr, 0);
1015 put32(ptr + 4, 0);
1016 /* two dummy got entries */
1017 put32(ptr + 8, 0);
1018 put32(ptr + 12, 0);
1019 put32(ptr + 16, 0);
1020 put32(ptr + 20, 0);
1021 #endif
1024 /* put a got or plt entry corresponding to a symbol in symtab_section. 'size'
1025 and 'info' can be modifed if more precise info comes from the DLL.
1026 Returns offset of GOT or PLT slot. */
1027 static unsigned long put_got_entry(TCCState *s1,
1028 int reloc_type, unsigned long size, int info,
1029 int sym_index)
1031 int index, need_plt_entry;
1032 const char *name;
1033 ElfW(Sym) *sym;
1034 unsigned long offset;
1035 int *ptr;
1036 struct sym_attr *symattr;
1038 if (!s1->got)
1039 build_got(s1);
1041 need_plt_entry = s1->dynsym &&
1042 #ifdef TCC_TARGET_X86_64
1043 (reloc_type == R_X86_64_JUMP_SLOT);
1044 #elif defined(TCC_TARGET_I386)
1045 (reloc_type == R_386_JMP_SLOT);
1046 #elif defined(TCC_TARGET_ARM)
1047 (reloc_type == R_ARM_JUMP_SLOT);
1048 #else
1050 #endif
1052 /* If a got/plt entry already exists for that symbol, no need to add one */
1053 if (sym_index < s1->nb_sym_attrs) {
1054 if (need_plt_entry && s1->sym_attrs[sym_index].plt_offset)
1055 return s1->sym_attrs[sym_index].plt_offset;
1056 else if (!need_plt_entry && s1->sym_attrs[sym_index].got_offset)
1057 return s1->sym_attrs[sym_index].got_offset;
1060 symattr = alloc_sym_attr(s1, sym_index);
1062 /* Only store the GOT offset if it's not generated for the PLT entry. */
1063 if (!need_plt_entry)
1064 symattr->got_offset = s1->got->data_offset;
1066 if (s1->dynsym) {
1067 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1068 name = (char *) symtab_section->link->data + sym->st_name;
1069 offset = sym->st_value;
1070 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1071 if (need_plt_entry) {
1072 Section *plt;
1073 uint8_t *p;
1074 int modrm;
1075 unsigned long relofs;
1077 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1078 modrm = 0x25;
1079 #else
1080 /* if we build a DLL, we add a %ebx offset */
1081 if (s1->output_type == TCC_OUTPUT_DLL)
1082 modrm = 0xa3;
1083 else
1084 modrm = 0x25;
1085 #endif
1087 /* add a PLT entry */
1088 plt = s1->plt;
1089 if (plt->data_offset == 0) {
1090 /* first plt entry */
1091 p = section_ptr_add(plt, 16);
1092 p[0] = 0xff; /* pushl got + PTR_SIZE */
1093 p[1] = modrm + 0x10;
1094 put32(p + 2, PTR_SIZE);
1095 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
1096 p[7] = modrm;
1097 put32(p + 8, PTR_SIZE * 2);
1100 /* The PLT slot refers to the relocation entry it needs
1101 via offset. The reloc entry is created below, so its
1102 offset is the current data_offset. */
1103 relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
1104 symattr->plt_offset = plt->data_offset;
1105 p = section_ptr_add(plt, 16);
1106 p[0] = 0xff; /* jmp *(got + x) */
1107 p[1] = modrm;
1108 put32(p + 2, s1->got->data_offset);
1109 p[6] = 0x68; /* push $xxx */
1110 #ifdef TCC_TARGET_X86_64
1111 /* On x86-64, the relocation is referred to by _index_. */
1112 put32(p + 7, relofs / sizeof (ElfW_Rel));
1113 #else
1114 put32(p + 7, relofs);
1115 #endif
1116 p[11] = 0xe9; /* jmp plt_start */
1117 put32(p + 12, -(plt->data_offset));
1119 /* If this was an UNDEF symbol set the offset in the
1120 dynsymtab to the PLT slot, so that PC32 relocs to it
1121 can be resolved. */
1122 if (sym->st_shndx == SHN_UNDEF)
1123 offset = plt->data_offset - 16;
1125 #elif defined(TCC_TARGET_ARM)
1126 if (need_plt_entry) {
1127 Section *plt;
1128 uint8_t *p;
1130 /* if we build a DLL, we add a %ebx offset */
1131 if (s1->output_type == TCC_OUTPUT_DLL)
1132 tcc_error("DLLs unimplemented!");
1134 /* add a PLT entry */
1135 plt = s1->plt;
1136 if (plt->data_offset == 0) {
1137 /* first plt entry */
1138 p = section_ptr_add(plt, 16);
1139 put32(p, 0xe52de004); /* push {lr} */
1140 put32(p+4, 0xe59fe010); /* ldr lr, [pc, #16] */
1141 put32(p+8, 0xe08fe00e); /* add lr, pc, lr */
1142 put32(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */
1145 symattr->plt_offset = plt->data_offset;
1146 if (symattr->plt_thumb_stub) {
1147 p = section_ptr_add(plt, 20);
1148 put32(p, 0x4778); /* bx pc */
1149 put32(p+2, 0x46c0); /* nop */
1150 p += 4;
1151 } else
1152 p = section_ptr_add(plt, 16);
1153 put32(p, 0xe59fc004); /* ldr ip, [pc, #4] ; GOT entry offset */
1154 put32(p+4, 0xe08fc00c); /* add ip, pc, ip ; addr of GOT entry */
1155 put32(p+8, 0xe59cf000); /* ldr pc, [ip] ; jump to GOT entry */
1156 put32(p+12, s1->got->data_offset); /* GOT entry off once patched */
1158 /* the symbol is modified so that it will be relocated to
1159 the PLT */
1160 if (s1->output_type == TCC_OUTPUT_EXE)
1161 offset = plt->data_offset - 16;
1163 #elif defined(TCC_TARGET_C67)
1164 tcc_error("C67 got not implemented");
1165 #else
1166 #error unsupported CPU
1167 #endif
1168 /* XXX This might generate multiple syms for name. */
1169 index = put_elf_sym(s1->dynsym, offset,
1170 size, info, 0, sym->st_shndx, name);
1171 /* Create the relocation (it's against the GOT for PLT
1172 and GOT relocs). */
1173 put_elf_reloc(s1->dynsym, s1->got,
1174 s1->got->data_offset,
1175 reloc_type, index);
1177 /* And now create the GOT slot itself. */
1178 ptr = section_ptr_add(s1->got, PTR_SIZE);
1179 *ptr = 0;
1180 if (need_plt_entry)
1181 return symattr->plt_offset;
1182 else
1183 return symattr->got_offset;
1186 /* build GOT and PLT entries */
1187 ST_FUNC void build_got_entries(TCCState *s1)
1189 Section *s;
1190 ElfW_Rel *rel;
1191 ElfW(Sym) *sym;
1192 int i, type, reloc_type, sym_index;
1194 for(i = 1; i < s1->nb_sections; i++) {
1195 s = s1->sections[i];
1196 if (s->sh_type != SHT_RELX)
1197 continue;
1198 /* no need to handle got relocations */
1199 if (s->link != symtab_section)
1200 continue;
1201 for_each_elem(s, 0, rel, ElfW_Rel) {
1202 type = ELFW(R_TYPE)(rel->r_info);
1203 switch(type) {
1204 #if defined(TCC_TARGET_I386)
1205 case R_386_GOT32:
1206 case R_386_GOTOFF:
1207 case R_386_GOTPC:
1208 case R_386_PLT32:
1209 if (!s1->got)
1210 build_got(s1);
1211 if (type == R_386_GOT32 || type == R_386_PLT32) {
1212 sym_index = ELFW(R_SYM)(rel->r_info);
1213 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1214 /* look at the symbol got offset. If none, then add one */
1215 if (type == R_386_GOT32)
1216 reloc_type = R_386_GLOB_DAT;
1217 else
1218 reloc_type = R_386_JMP_SLOT;
1219 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1220 sym_index);
1222 break;
1223 #elif defined(TCC_TARGET_ARM)
1224 case R_ARM_GOT32:
1225 case R_ARM_GOTOFF:
1226 case R_ARM_GOTPC:
1227 case R_ARM_PLT32:
1228 if (!s1->got)
1229 build_got(s1);
1230 if (type == R_ARM_GOT32 || type == R_ARM_PLT32) {
1231 sym_index = ELFW(R_SYM)(rel->r_info);
1232 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1233 /* look at the symbol got offset. If none, then add one */
1234 if (type == R_ARM_GOT32)
1235 reloc_type = R_ARM_GLOB_DAT;
1236 else
1237 reloc_type = R_ARM_JUMP_SLOT;
1238 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1239 sym_index);
1241 break;
1242 case R_ARM_THM_JUMP24:
1243 sym_index = ELFW(R_SYM)(rel->r_info);
1244 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1245 /* We are relocating a jump from thumb code to arm code */
1246 if (sym->st_shndx != SHN_UNDEF && !(sym->st_value & 1)) {
1247 int index;
1248 uint8_t *p;
1249 char *name, buf[1024];
1250 Section *text_section;
1252 name = (char *) symtab_section->link->data + sym->st_name;
1253 text_section = s1->sections[sym->st_shndx];
1254 /* Modify reloc to target a thumb stub to switch to ARM */
1255 snprintf(buf, sizeof(buf), "%s_from_thumb", name);
1256 index = put_elf_sym(symtab_section,
1257 text_section->data_offset + 1,
1258 sym->st_size, sym->st_info, 0,
1259 sym->st_shndx, buf);
1260 rel->r_info = ELFW(R_INFO)(index, type);
1261 /* Create a thumb stub fonction to switch to ARM mode */
1262 put_elf_reloc(symtab_section, text_section,
1263 text_section->data_offset + 4, R_ARM_JUMP24,
1264 sym_index);
1265 p = section_ptr_add(text_section, 8);
1266 put32(p, 0x4778); /* bx pc */
1267 put32(p+2, 0x46c0); /* nop */
1268 put32(p+4, 0xeafffffe); /* b $sym */
1270 #elif defined(TCC_TARGET_C67)
1271 case R_C60_GOT32:
1272 case R_C60_GOTOFF:
1273 case R_C60_GOTPC:
1274 case R_C60_PLT32:
1275 if (!s1->got)
1276 build_got(s1);
1277 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
1278 sym_index = ELFW(R_SYM)(rel->r_info);
1279 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1280 /* look at the symbol got offset. If none, then add one */
1281 if (type == R_C60_GOT32)
1282 reloc_type = R_C60_GLOB_DAT;
1283 else
1284 reloc_type = R_C60_JMP_SLOT;
1285 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1286 sym_index);
1288 break;
1289 #elif defined(TCC_TARGET_X86_64)
1290 case R_X86_64_GOT32:
1291 case R_X86_64_GOTTPOFF:
1292 case R_X86_64_GOTPCREL:
1293 case R_X86_64_PLT32:
1294 if (!s1->got)
1295 build_got(s1);
1296 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
1297 type == R_X86_64_PLT32) {
1298 unsigned long ofs;
1299 sym_index = ELFW(R_SYM)(rel->r_info);
1300 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1301 /* look at the symbol got offset. If none, then add one */
1302 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL)
1303 reloc_type = R_X86_64_GLOB_DAT;
1304 else
1305 reloc_type = R_X86_64_JUMP_SLOT;
1306 ofs = put_got_entry(s1, reloc_type, sym->st_size,
1307 sym->st_info, sym_index);
1308 if (type == R_X86_64_PLT32
1309 && s1->output_type != TCC_OUTPUT_MEMORY)
1310 /* We store the place of the generated PLT slot
1311 in our addend. */
1312 rel->r_addend += ofs;
1314 break;
1315 #else
1316 #error unsupported CPU
1317 #endif
1318 default:
1319 break;
1325 ST_FUNC Section *new_symtab(TCCState *s1,
1326 const char *symtab_name, int sh_type, int sh_flags,
1327 const char *strtab_name,
1328 const char *hash_name, int hash_sh_flags)
1330 Section *symtab, *strtab, *hash;
1331 int *ptr, nb_buckets;
1333 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1334 symtab->sh_entsize = sizeof(ElfW(Sym));
1335 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1336 put_elf_str(strtab, "");
1337 symtab->link = strtab;
1338 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1340 nb_buckets = 1;
1342 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1343 hash->sh_entsize = sizeof(int);
1344 symtab->hash = hash;
1345 hash->link = symtab;
1347 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1348 ptr[0] = nb_buckets;
1349 ptr[1] = 1;
1350 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1351 return symtab;
1354 /* put dynamic tag */
1355 static void put_dt(Section *dynamic, int dt, addr_t val)
1357 ElfW(Dyn) *dyn;
1358 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1359 dyn->d_tag = dt;
1360 dyn->d_un.d_val = val;
1363 static void add_init_array_defines(TCCState *s1, const char *section_name)
1365 Section *s;
1366 long end_offset;
1367 char sym_start[1024];
1368 char sym_end[1024];
1370 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1371 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1373 s = find_section(s1, section_name);
1374 if (!s) {
1375 end_offset = 0;
1376 s = data_section;
1377 } else {
1378 end_offset = s->data_offset;
1381 add_elf_sym(symtab_section,
1382 0, 0,
1383 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1384 s->sh_num, sym_start);
1385 add_elf_sym(symtab_section,
1386 end_offset, 0,
1387 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1388 s->sh_num, sym_end);
1391 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1393 #ifdef CONFIG_TCC_BCHECK
1394 unsigned long *ptr;
1395 Section *init_section;
1396 unsigned char *pinit;
1397 int sym_index;
1399 if (0 == s1->do_bounds_check)
1400 return;
1402 /* XXX: add an object file to do that */
1403 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
1404 *ptr = 0;
1405 add_elf_sym(symtab_section, 0, 0,
1406 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1407 bounds_section->sh_num, "__bounds_start");
1408 #ifdef TCC_TARGET_I386
1409 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1410 /* add 'call __bound_init()' in .init section */
1411 init_section = find_section(s1, ".init");
1412 pinit = section_ptr_add(init_section, 5);
1413 pinit[0] = 0xe8;
1414 put32(pinit + 1, -4);
1415 sym_index = find_elf_sym(symtab_section, "__bound_init");
1416 put_elf_reloc(symtab_section, init_section,
1417 init_section->data_offset - 4, R_386_PC32, sym_index);
1419 #endif
1420 #endif
1423 static inline int tcc_add_support(TCCState *s1, const char *filename)
1425 char buf[1024];
1426 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1427 return tcc_add_file(s1, buf);
1430 /* add tcc runtime libraries */
1431 ST_FUNC void tcc_add_runtime(TCCState *s1)
1433 /* add libc */
1434 if (!s1->nostdlib) {
1435 tcc_add_library(s1, "c");
1436 #ifdef CONFIG_USE_LIBGCC
1437 if (!s1->static_link) {
1438 tcc_add_file(s1, TCC_LIBGCC);
1439 tcc_add_support(s1, "libtcc1.a");
1440 } else
1441 tcc_add_support(s1, "libtcc1.a");
1442 #else
1443 tcc_add_support(s1, "libtcc1.a");
1444 #endif
1447 /* tcc_add_bcheck tries to relocate a call to __bound_init in _init so
1448 libtcc1.a must be loaded before for __bound_init to be defined and
1449 crtn.o must be loaded after to not finalize _init too early. */
1450 tcc_add_bcheck(s1);
1452 if (!s1->nostdlib) {
1453 /* add crt end if not memory output */
1454 if (s1->output_type != TCC_OUTPUT_MEMORY)
1455 tcc_add_crt(s1, "crtn.o");
1459 /* add various standard linker symbols (must be done after the
1460 sections are filled (for example after allocating common
1461 symbols)) */
1462 ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
1464 char buf[1024];
1465 int i;
1466 Section *s;
1468 add_elf_sym(symtab_section,
1469 text_section->data_offset, 0,
1470 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1471 text_section->sh_num, "_etext");
1472 add_elf_sym(symtab_section,
1473 data_section->data_offset, 0,
1474 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1475 data_section->sh_num, "_edata");
1476 add_elf_sym(symtab_section,
1477 bss_section->data_offset, 0,
1478 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1479 bss_section->sh_num, "_end");
1480 /* horrible new standard ldscript defines */
1481 add_init_array_defines(s1, ".preinit_array");
1482 add_init_array_defines(s1, ".init_array");
1483 add_init_array_defines(s1, ".fini_array");
1485 /* add start and stop symbols for sections whose name can be
1486 expressed in C */
1487 for(i = 1; i < s1->nb_sections; i++) {
1488 s = s1->sections[i];
1489 if (s->sh_type == SHT_PROGBITS &&
1490 (s->sh_flags & SHF_ALLOC)) {
1491 const char *p;
1492 int ch;
1494 /* check if section name can be expressed in C */
1495 p = s->name;
1496 for(;;) {
1497 ch = *p;
1498 if (!ch)
1499 break;
1500 if (!isid(ch) && !isnum(ch))
1501 goto next_sec;
1502 p++;
1504 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1505 add_elf_sym(symtab_section,
1506 0, 0,
1507 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1508 s->sh_num, buf);
1509 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1510 add_elf_sym(symtab_section,
1511 s->data_offset, 0,
1512 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1513 s->sh_num, buf);
1515 next_sec: ;
1519 static void tcc_output_binary(TCCState *s1, FILE *f,
1520 const int *sec_order)
1522 Section *s;
1523 int i, offset, size;
1525 offset = 0;
1526 for(i=1;i<s1->nb_sections;i++) {
1527 s = s1->sections[sec_order[i]];
1528 if (s->sh_type != SHT_NOBITS &&
1529 (s->sh_flags & SHF_ALLOC)) {
1530 while (offset < s->sh_offset) {
1531 fputc(0, f);
1532 offset++;
1534 size = s->sh_size;
1535 fwrite(s->data, 1, size, f);
1536 offset += size;
1541 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1542 #define HAVE_PHDR 1
1543 #define EXTRA_RELITEMS 14
1545 /* move the relocation value from .dynsym to .got */
1546 void patch_dynsym_undef(TCCState *s1, Section *s)
1548 uint32_t *gotd = (void *)s1->got->data;
1549 ElfW(Sym) *sym;
1551 gotd += 3; /* dummy entries in .got */
1552 /* relocate symbols in .dynsym */
1553 for_each_elem(s, 1, sym, ElfW(Sym)) {
1554 if (sym->st_shndx == SHN_UNDEF) {
1555 *gotd++ = sym->st_value + 6; /* XXX 6 is magic ? */
1556 sym->st_value = 0;
1560 #else
1561 #define HAVE_PHDR 1
1562 #define EXTRA_RELITEMS 9
1564 /* zero plt offsets of weak symbols in .dynsym */
1565 void patch_dynsym_undef(TCCState *s1, Section *s)
1567 ElfW(Sym) *sym;
1569 for_each_elem(s, 1, sym, ElfW(Sym))
1570 if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
1571 sym->st_value = 0;
1573 #endif
1575 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1577 int sym_index = ELFW(R_SYM) (rel->r_info);
1578 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1579 unsigned long offset;
1581 if (sym_index >= s1->nb_sym_attrs)
1582 return;
1583 offset = s1->sym_attrs[sym_index].got_offset;
1584 section_reserve(s1->got, offset + PTR_SIZE);
1585 #ifdef TCC_TARGET_X86_64
1586 /* only works for x86-64 */
1587 put32(s1->got->data + offset + 4, sym->st_value >> 32);
1588 #endif
1589 put32(s1->got->data + offset, sym->st_value & 0xffffffff);
1592 /* Perform relocation to GOT or PLT entries */
1593 ST_FUNC void fill_got(TCCState *s1)
1595 Section *s;
1596 ElfW_Rel *rel;
1597 int i;
1599 for(i = 1; i < s1->nb_sections; i++) {
1600 s = s1->sections[i];
1601 if (s->sh_type != SHT_RELX)
1602 continue;
1603 /* no need to handle got relocations */
1604 if (s->link != symtab_section)
1605 continue;
1606 for_each_elem(s, 0, rel, ElfW_Rel) {
1607 switch (ELFW(R_TYPE) (rel->r_info)) {
1608 case R_X86_64_GOT32:
1609 case R_X86_64_GOTPCREL:
1610 case R_X86_64_PLT32:
1611 fill_got_entry(s1, rel);
1612 break;
1618 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1619 in shared libraries and export non local defined symbols to shared libraries
1620 if -rdynamic switch was given on command line */
1621 static void bind_exe_dynsyms(TCCState *s1)
1623 const char *name;
1624 int sym_index, index;
1625 ElfW(Sym) *sym, *esym;
1626 int type;
1628 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1629 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1630 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1631 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1632 if (sym->st_shndx == SHN_UNDEF) {
1633 name = (char *) symtab_section->link->data + sym->st_name;
1634 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1635 if (sym_index) {
1636 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1637 type = ELFW(ST_TYPE)(esym->st_info);
1638 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1639 /* Indirect functions shall have STT_FUNC type in executable
1640 * dynsym section. Indeed, a dlsym call following a lazy
1641 * resolution would pick the symbol value from the
1642 * executable dynsym entry which would contain the address
1643 * of the function wanted by the caller of dlsym instead of
1644 * the address of the function that would return that
1645 * address */
1646 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1647 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC),
1648 sym - (ElfW(Sym) *)symtab_section->data);
1649 } else if (type == STT_OBJECT) {
1650 unsigned long offset;
1651 ElfW(Sym) *dynsym;
1652 offset = bss_section->data_offset;
1653 /* XXX: which alignment ? */
1654 offset = (offset + 16 - 1) & -16;
1655 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1656 esym->st_info, 0, bss_section->sh_num,
1657 name);
1658 /* Ensure R_COPY works for weak symbol aliases */
1659 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1660 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1661 if ((dynsym->st_value == esym->st_value)
1662 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1663 char *dynname = (char *) s1->dynsymtab_section->link->data
1664 + dynsym->st_name;
1665 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1666 dynsym->st_info, 0,
1667 bss_section->sh_num, dynname);
1668 break;
1672 put_elf_reloc(s1->dynsym, bss_section,
1673 offset, R_COPY, index);
1674 offset += esym->st_size;
1675 bss_section->data_offset = offset;
1677 } else {
1678 /* STB_WEAK undefined symbols are accepted */
1679 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1680 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1681 !strcmp(name, "_fp_hw")) {
1682 } else {
1683 tcc_error_noabort("undefined symbol '%s'", name);
1686 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1687 /* if -rdynamic option, then export all non local symbols */
1688 name = (char *) symtab_section->link->data + sym->st_name;
1689 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1690 0, sym->st_shndx, name);
1695 /* Bind symbols of libraries: export non local symbols of executable that
1696 resolve undefined symbols of shared libraries */
1697 static void bind_libs_dynsyms(TCCState *s1)
1699 const char *name;
1700 int sym_index;
1701 ElfW(Sym) *sym, *esym;
1703 /* now look at unresolved dynamic symbols and export
1704 corresponding symbol */
1705 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1706 if (esym->st_shndx == SHN_UNDEF) {
1707 name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
1708 sym_index = find_elf_sym(symtab_section, name);
1709 if (sym_index) {
1710 /* XXX: avoid adding a symbol if already present because of
1711 -rdynamic ? */
1712 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1713 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1714 sym->st_info, 0, sym->st_shndx, name);
1715 } else {
1716 /* weak symbols can stay undefined */
1717 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1718 tcc_warning("undefined dynamic symbol '%s'", name);
1724 /* Export all non local symbols (for shared libraries) */
1725 static void export_global_syms(TCCState *s1)
1727 int nb_syms, dynindex, index;
1728 const char *name;
1729 ElfW(Sym) *sym;
1731 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1732 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1733 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1734 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1735 name = (char *) symtab_section->link->data + sym->st_name;
1736 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1737 sym->st_info, 0, sym->st_shndx, name);
1738 index = sym - (ElfW(Sym) *) symtab_section->data;
1739 s1->symtab_to_dynsym[index] = dynindex;
1744 /* relocate the PLT: compute addresses and offsets in the PLT now that final
1745 address for PLT and GOT are known (see fill_program_header) */
1746 static void relocate_plt(TCCState *s1)
1748 uint8_t *p, *p_end;
1750 p = s1->plt->data;
1751 p_end = p + s1->plt->data_offset;
1752 if (p < p_end) {
1753 #if defined(TCC_TARGET_I386)
1754 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1755 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1756 p += 16;
1757 while (p < p_end) {
1758 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1759 p += 16;
1761 #elif defined(TCC_TARGET_X86_64)
1762 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
1763 put32(p + 2, get32(p + 2) + x);
1764 put32(p + 8, get32(p + 8) + x - 6);
1765 p += 16;
1766 while (p < p_end) {
1767 put32(p + 2, get32(p + 2) + x + s1->plt->data - p);
1768 p += 16;
1770 #elif defined(TCC_TARGET_ARM)
1771 int x;
1772 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1773 p += 16;
1774 while (p < p_end) {
1775 if (get32(p) == 0x46c04778) /* PLT Thumb stub present */
1776 p += 4;
1777 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1778 p += 16;
1780 #elif defined(TCC_TARGET_C67)
1781 /* XXX: TODO */
1782 #else
1783 #error unsupported CPU
1784 #endif
1788 /* Allocate strings for section names and decide if an unallocated section
1789 should be output.
1791 NOTE: the strsec section comes last, so its size is also correct ! */
1792 static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1794 int i;
1795 Section *s;
1797 /* Allocate strings for section names */
1798 for(i = 1; i < s1->nb_sections; i++) {
1799 s = s1->sections[i];
1800 s->sh_name = put_elf_str(strsec, s->name);
1801 /* when generating a DLL, we include relocations but we may
1802 patch them */
1803 if (file_type == TCC_OUTPUT_DLL &&
1804 s->sh_type == SHT_RELX &&
1805 !(s->sh_flags & SHF_ALLOC)) {
1806 /* gr: avoid bogus relocs for empty (debug) sections */
1807 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1808 prepare_dynamic_rel(s1, s);
1809 else if (s1->do_debug)
1810 s->sh_size = s->data_offset;
1811 } else if (s1->do_debug ||
1812 file_type == TCC_OUTPUT_OBJ ||
1813 (s->sh_flags & SHF_ALLOC) ||
1814 i == (s1->nb_sections - 1)) {
1815 /* we output all sections if debug or object file */
1816 s->sh_size = s->data_offset;
1821 /* Info to be copied in dynamic section */
1822 struct dyn_inf {
1823 Section *dynamic;
1824 Section *dynstr;
1825 unsigned long dyn_rel_off;
1826 addr_t rel_addr;
1827 addr_t rel_size;
1828 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1829 addr_t bss_addr;
1830 addr_t bss_size;
1831 #endif
1834 /* Assign sections to segments and decide how are sections laid out when loaded
1835 in memory. This function also fills corresponding program headers. */
1836 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1837 Section *interp, struct dyn_inf *dyninf,
1838 int *sec_order)
1840 int i, j, k, file_type, sh_order_index, file_offset;
1841 long long tmp;
1842 addr_t addr;
1843 ElfW(Phdr) *ph;
1844 Section *s;
1846 file_type = s1->output_type;
1847 sh_order_index = 1;
1848 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1849 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1850 else
1851 file_offset = 0;
1853 if (phnum > 0) {
1854 if (s1->has_text_addr) {
1855 int a_offset, p_offset;
1856 addr = s1->text_addr;
1857 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1858 ELF_PAGE_SIZE */
1859 a_offset = (int) (addr & (s1->section_align - 1));
1860 p_offset = file_offset & (s1->section_align - 1);
1861 if (a_offset < p_offset)
1862 a_offset += s1->section_align;
1863 file_offset += (a_offset - p_offset);
1864 } else {
1865 if (file_type == TCC_OUTPUT_DLL)
1866 addr = 0;
1867 else
1868 addr = ELF_START_ADDR;
1869 /* compute address after headers */
1870 addr += (file_offset & (s1->section_align - 1));
1873 ph = &phdr[0];
1874 /* Leave one program headers for the program interpreter and one for
1875 the program header table itself if needed. These are done later as
1876 they require section layout to be done first. */
1877 if (interp)
1878 ph += 1 + HAVE_PHDR;
1880 /* dynamic relocation table information, for .dynamic section */
1881 dyninf->rel_addr = dyninf->rel_size = 0;
1882 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1883 dyninf->bss_addr = dyninf->bss_size = 0;
1884 #endif
1886 for(j = 0; j < 2; j++) {
1887 ph->p_type = PT_LOAD;
1888 if (j == 0)
1889 ph->p_flags = PF_R | PF_X;
1890 else
1891 ph->p_flags = PF_R | PF_W;
1892 ph->p_align = s1->section_align;
1894 /* Decide the layout of sections loaded in memory. This must
1895 be done before program headers are filled since they contain
1896 info about the layout. We do the following ordering: interp,
1897 symbol tables, relocations, progbits, nobits */
1898 /* XXX: do faster and simpler sorting */
1899 for(k = 0; k < 5; k++) {
1900 for(i = 1; i < s1->nb_sections; i++) {
1901 s = s1->sections[i];
1902 /* compute if section should be included */
1903 if (j == 0) {
1904 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1905 SHF_ALLOC)
1906 continue;
1907 } else {
1908 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1909 (SHF_ALLOC | SHF_WRITE))
1910 continue;
1912 if (s == interp) {
1913 if (k != 0)
1914 continue;
1915 } else if (s->sh_type == SHT_DYNSYM ||
1916 s->sh_type == SHT_STRTAB ||
1917 s->sh_type == SHT_HASH) {
1918 if (k != 1)
1919 continue;
1920 } else if (s->sh_type == SHT_RELX) {
1921 if (k != 2)
1922 continue;
1923 } else if (s->sh_type == SHT_NOBITS) {
1924 if (k != 4)
1925 continue;
1926 } else {
1927 if (k != 3)
1928 continue;
1930 sec_order[sh_order_index++] = i;
1932 /* section matches: we align it and add its size */
1933 tmp = addr;
1934 addr = (addr + s->sh_addralign - 1) &
1935 ~(s->sh_addralign - 1);
1936 file_offset += (int) ( addr - tmp );
1937 s->sh_offset = file_offset;
1938 s->sh_addr = addr;
1940 /* update program header infos */
1941 if (ph->p_offset == 0) {
1942 ph->p_offset = file_offset;
1943 ph->p_vaddr = addr;
1944 ph->p_paddr = ph->p_vaddr;
1946 /* update dynamic relocation infos */
1947 if (s->sh_type == SHT_RELX) {
1948 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1949 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1950 dyninf->rel_addr = addr;
1951 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1953 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1954 dyninf->bss_addr = addr;
1955 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1957 #else
1958 if (dyninf->rel_size == 0)
1959 dyninf->rel_addr = addr;
1960 dyninf->rel_size += s->sh_size;
1961 #endif
1963 addr += s->sh_size;
1964 if (s->sh_type != SHT_NOBITS)
1965 file_offset += s->sh_size;
1968 if (j == 0) {
1969 /* Make the first PT_LOAD segment include the program
1970 headers itself (and the ELF header as well), it'll
1971 come out with same memory use but will make various
1972 tools like binutils strip work better. */
1973 ph->p_offset &= ~(ph->p_align - 1);
1974 ph->p_vaddr &= ~(ph->p_align - 1);
1975 ph->p_paddr &= ~(ph->p_align - 1);
1977 ph->p_filesz = file_offset - ph->p_offset;
1978 ph->p_memsz = addr - ph->p_vaddr;
1979 ph++;
1980 if (j == 0) {
1981 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1982 /* if in the middle of a page, we duplicate the page in
1983 memory so that one copy is RX and the other is RW */
1984 if ((addr & (s1->section_align - 1)) != 0)
1985 addr += s1->section_align;
1986 } else {
1987 addr = (addr + s1->section_align - 1) & ~(s1->section_align - 1);
1988 file_offset = (file_offset + s1->section_align - 1) &
1989 ~(s1->section_align - 1);
1995 /* all other sections come after */
1996 for(i = 1; i < s1->nb_sections; i++) {
1997 s = s1->sections[i];
1998 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1999 continue;
2000 sec_order[sh_order_index++] = i;
2002 file_offset = (file_offset + s->sh_addralign - 1) &
2003 ~(s->sh_addralign - 1);
2004 s->sh_offset = file_offset;
2005 if (s->sh_type != SHT_NOBITS)
2006 file_offset += s->sh_size;
2009 return file_offset;
2012 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
2013 Section *dynamic)
2015 ElfW(Phdr) *ph;
2017 /* if interpreter, then add corresponding program header */
2018 if (interp) {
2019 ph = &phdr[0];
2021 if (HAVE_PHDR)
2023 int len = phnum * sizeof(ElfW(Phdr));
2025 ph->p_type = PT_PHDR;
2026 ph->p_offset = sizeof(ElfW(Ehdr));
2027 ph->p_vaddr = interp->sh_addr - len;
2028 ph->p_paddr = ph->p_vaddr;
2029 ph->p_filesz = ph->p_memsz = len;
2030 ph->p_flags = PF_R | PF_X;
2031 ph->p_align = 4; /* interp->sh_addralign; */
2032 ph++;
2035 ph->p_type = PT_INTERP;
2036 ph->p_offset = interp->sh_offset;
2037 ph->p_vaddr = interp->sh_addr;
2038 ph->p_paddr = ph->p_vaddr;
2039 ph->p_filesz = interp->sh_size;
2040 ph->p_memsz = interp->sh_size;
2041 ph->p_flags = PF_R;
2042 ph->p_align = interp->sh_addralign;
2045 /* if dynamic section, then add corresponding program header */
2046 if (dynamic) {
2047 ph = &phdr[phnum - 1];
2049 ph->p_type = PT_DYNAMIC;
2050 ph->p_offset = dynamic->sh_offset;
2051 ph->p_vaddr = dynamic->sh_addr;
2052 ph->p_paddr = ph->p_vaddr;
2053 ph->p_filesz = dynamic->sh_size;
2054 ph->p_memsz = dynamic->sh_size;
2055 ph->p_flags = PF_R | PF_W;
2056 ph->p_align = dynamic->sh_addralign;
2060 /* Fill the dynamic section with tags describing the address and size of
2061 sections */
2062 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
2064 Section *dynamic;
2066 dynamic = dyninf->dynamic;
2068 /* put dynamic section entries */
2069 dynamic->data_offset = dyninf->dyn_rel_off;
2070 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
2071 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
2072 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
2073 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
2074 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
2075 #ifdef TCC_TARGET_X86_64
2076 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
2077 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
2078 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
2079 #else
2080 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2081 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
2082 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
2083 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2084 put_dt(dynamic, DT_PLTREL, DT_REL);
2085 put_dt(dynamic, DT_REL, dyninf->bss_addr);
2086 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
2087 #else
2088 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2089 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2090 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2091 #endif
2092 #endif
2093 if (s1->do_debug)
2094 put_dt(dynamic, DT_DEBUG, 0);
2095 put_dt(dynamic, DT_NULL, 0);
2098 /* Relocate remaining sections and symbols (that is those not related to
2099 dynamic linking) */
2100 static int final_sections_reloc(TCCState *s1)
2102 int i;
2103 Section *s;
2105 relocate_syms(s1, 0);
2107 if (s1->nb_errors != 0)
2108 return -1;
2110 /* relocate sections */
2111 /* XXX: ignore sections with allocated relocations ? */
2112 for(i = 1; i < s1->nb_sections; i++) {
2113 s = s1->sections[i];
2114 if (s->reloc && s != s1->got)
2115 relocate_section(s1, s);
2118 /* relocate relocation entries if the relocation tables are
2119 allocated in the executable */
2120 for(i = 1; i < s1->nb_sections; i++) {
2121 s = s1->sections[i];
2122 if ((s->sh_flags & SHF_ALLOC) &&
2123 s->sh_type == SHT_RELX) {
2124 relocate_rel(s1, s);
2127 return 0;
2130 /* Create an ELF file on disk.
2131 This function handle ELF specific layout requirements */
2132 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2133 int file_offset, int *sec_order)
2135 int i, shnum, offset, size, file_type;
2136 Section *s;
2137 ElfW(Ehdr) ehdr;
2138 ElfW(Shdr) shdr, *sh;
2140 file_type = s1->output_type;
2141 shnum = s1->nb_sections;
2143 memset(&ehdr, 0, sizeof(ehdr));
2145 if (phnum > 0) {
2146 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2147 ehdr.e_phnum = phnum;
2148 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2151 /* align to 4 */
2152 file_offset = (file_offset + 3) & -4;
2154 /* fill header */
2155 ehdr.e_ident[0] = ELFMAG0;
2156 ehdr.e_ident[1] = ELFMAG1;
2157 ehdr.e_ident[2] = ELFMAG2;
2158 ehdr.e_ident[3] = ELFMAG3;
2159 ehdr.e_ident[4] = ELFCLASSW;
2160 ehdr.e_ident[5] = ELFDATA2LSB;
2161 ehdr.e_ident[6] = EV_CURRENT;
2162 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2163 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2164 #endif
2165 #ifdef TCC_TARGET_ARM
2166 #ifdef TCC_ARM_EABI
2167 ehdr.e_ident[EI_OSABI] = 0;
2168 ehdr.e_flags = EF_ARM_EABI_VER4;
2169 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2170 ehdr.e_flags |= EF_ARM_HASENTRY;
2171 if (s1->float_abi == ARM_HARD_FLOAT)
2172 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2173 else
2174 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2175 #else
2176 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2177 #endif
2178 #endif
2179 switch(file_type) {
2180 default:
2181 case TCC_OUTPUT_EXE:
2182 ehdr.e_type = ET_EXEC;
2183 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
2184 break;
2185 case TCC_OUTPUT_DLL:
2186 ehdr.e_type = ET_DYN;
2187 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2188 break;
2189 case TCC_OUTPUT_OBJ:
2190 ehdr.e_type = ET_REL;
2191 break;
2193 ehdr.e_machine = EM_TCC_TARGET;
2194 ehdr.e_version = EV_CURRENT;
2195 ehdr.e_shoff = file_offset;
2196 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2197 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2198 ehdr.e_shnum = shnum;
2199 ehdr.e_shstrndx = shnum - 1;
2201 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2202 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2203 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2205 sort_syms(s1, symtab_section);
2206 for(i = 1; i < s1->nb_sections; i++) {
2207 s = s1->sections[sec_order[i]];
2208 if (s->sh_type != SHT_NOBITS) {
2209 if (s->sh_type == SHT_DYNSYM)
2210 patch_dynsym_undef(s1, s);
2211 while (offset < s->sh_offset) {
2212 fputc(0, f);
2213 offset++;
2215 size = s->sh_size;
2216 fwrite(s->data, 1, size, f);
2217 offset += size;
2221 /* output section headers */
2222 while (offset < ehdr.e_shoff) {
2223 fputc(0, f);
2224 offset++;
2227 for(i = 0; i < s1->nb_sections; i++) {
2228 sh = &shdr;
2229 memset(sh, 0, sizeof(ElfW(Shdr)));
2230 s = s1->sections[i];
2231 if (s) {
2232 sh->sh_name = s->sh_name;
2233 sh->sh_type = s->sh_type;
2234 sh->sh_flags = s->sh_flags;
2235 sh->sh_entsize = s->sh_entsize;
2236 sh->sh_info = s->sh_info;
2237 if (s->link)
2238 sh->sh_link = s->link->sh_num;
2239 sh->sh_addralign = s->sh_addralign;
2240 sh->sh_addr = s->sh_addr;
2241 sh->sh_offset = s->sh_offset;
2242 sh->sh_size = s->sh_size;
2244 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2248 /* Write an elf, coff or "binary" file */
2249 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2250 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2252 int fd, mode, file_type;
2253 FILE *f;
2255 file_type = s1->output_type;
2256 if (file_type == TCC_OUTPUT_OBJ)
2257 mode = 0666;
2258 else
2259 mode = 0777;
2260 unlink(filename);
2261 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2262 if (fd < 0) {
2263 tcc_error_noabort("could not write '%s'", filename);
2264 return -1;
2266 f = fdopen(fd, "wb");
2267 if (s1->verbose)
2268 printf("<- %s\n", filename);
2270 #ifdef TCC_TARGET_COFF
2271 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2272 tcc_output_coff(s1, f);
2273 else
2274 #endif
2275 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2276 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2277 else
2278 tcc_output_binary(s1, f, sec_order);
2279 fclose(f);
2281 return 0;
2284 /* Output an elf, coff or binary file */
2285 /* XXX: suppress unneeded sections */
2286 static int elf_output_file(TCCState *s1, const char *filename)
2288 int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
2289 struct dyn_inf dyninf;
2290 ElfW(Phdr) *phdr;
2291 ElfW(Sym) *sym;
2292 Section *strsec, *interp, *dynamic, *dynstr;
2294 file_type = s1->output_type;
2295 s1->nb_errors = 0;
2297 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2298 if (file_type != TCC_OUTPUT_OBJ) {
2299 tcc_add_runtime(s1);
2302 phdr = NULL;
2303 sec_order = NULL;
2304 interp = dynamic = dynstr = NULL; /* avoid warning */
2305 dyninf.dyn_rel_off = 0; /* avoid warning */
2307 if (file_type != TCC_OUTPUT_OBJ) {
2308 relocate_common_syms();
2310 tcc_add_linker_symbols(s1);
2312 if (!s1->static_link) {
2313 if (file_type == TCC_OUTPUT_EXE) {
2314 char *ptr;
2315 /* allow override the dynamic loader */
2316 const char *elfint = getenv("LD_SO");
2317 if (elfint == NULL)
2318 elfint = DEFAULT_ELFINTERP(s1);
2319 /* add interpreter section only if executable */
2320 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2321 interp->sh_addralign = 1;
2322 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2323 strcpy(ptr, elfint);
2326 /* add dynamic symbol table */
2327 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2328 ".dynstr",
2329 ".hash", SHF_ALLOC);
2330 dynstr = s1->dynsym->link;
2332 /* add dynamic section */
2333 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2334 SHF_ALLOC | SHF_WRITE);
2335 dynamic->link = dynstr;
2336 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2338 /* add PLT */
2339 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
2340 SHF_ALLOC | SHF_EXECINSTR);
2341 s1->plt->sh_entsize = 4;
2343 build_got(s1);
2345 if (file_type == TCC_OUTPUT_EXE) {
2346 bind_exe_dynsyms(s1);
2348 if (s1->nb_errors) {
2349 ret = -1;
2350 goto the_end;
2353 bind_libs_dynsyms(s1);
2354 } else /* shared library case: simply export all global symbols */
2355 export_global_syms(s1);
2357 build_got_entries(s1);
2359 /* add a list of needed dlls */
2360 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2361 DLLReference *dllref = s1->loaded_dlls[i];
2362 if (dllref->level == 0)
2363 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2366 if (s1->rpath)
2367 put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath));
2369 /* XXX: currently, since we do not handle PIC code, we
2370 must relocate the readonly segments */
2371 if (file_type == TCC_OUTPUT_DLL) {
2372 if (s1->soname)
2373 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2374 put_dt(dynamic, DT_TEXTREL, 0);
2377 if (s1->symbolic)
2378 put_dt(dynamic, DT_SYMBOLIC, 0);
2380 /* add necessary space for other entries */
2381 dyninf.dyn_rel_off = dynamic->data_offset;
2382 dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
2383 } else {
2384 /* still need to build got entries in case of static link */
2385 build_got_entries(s1);
2389 /* we add a section for symbols */
2390 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2391 put_elf_str(strsec, "");
2393 /* compute number of sections */
2394 shnum = s1->nb_sections;
2396 /* this array is used to reorder sections in the output file */
2397 sec_order = tcc_malloc(sizeof(int) * shnum);
2398 sec_order[0] = 0;
2400 /* compute number of program headers */
2401 switch(file_type) {
2402 default:
2403 case TCC_OUTPUT_OBJ:
2404 phnum = 0;
2405 break;
2406 case TCC_OUTPUT_EXE:
2407 if (!s1->static_link)
2408 phnum = 4 + HAVE_PHDR;
2409 else
2410 phnum = 2;
2411 break;
2412 case TCC_OUTPUT_DLL:
2413 phnum = 3;
2414 break;
2417 /* Allocate strings for section names */
2418 alloc_sec_names(s1, file_type, strsec);
2420 /* allocate program segment headers */
2421 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2423 /* compute section to program header mapping */
2424 file_offset = layout_sections(s1, phdr, phnum, interp, &dyninf, sec_order);
2426 /* Fill remaining program header and finalize relocation related to dynamic
2427 linking. */
2428 if (phnum > 0) {
2429 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2430 if (dynamic) {
2431 dyninf.dynamic = dynamic;
2432 dyninf.dynstr = dynstr;
2434 fill_dynamic(s1, &dyninf);
2436 /* put in GOT the dynamic section address and relocate PLT */
2437 put32(s1->got->data, dynamic->sh_addr);
2438 if (file_type == TCC_OUTPUT_EXE
2439 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
2440 || file_type == TCC_OUTPUT_DLL
2441 #endif
2443 relocate_plt(s1);
2445 /* relocate symbols in .dynsym now that final addresses are known */
2446 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2447 /* relocate to PLT if symbol corresponds to a PLT entry */
2448 if (sym->st_shndx == SHN_UNDEF) {
2449 if (sym->st_value)
2450 sym->st_value += s1->plt->sh_addr;
2451 } else if (sym->st_shndx < SHN_LORESERVE) {
2452 /* do symbol relocation */
2453 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2459 /* if building executable or DLL, then relocate each section
2460 except the GOT which is already relocated */
2461 if (file_type != TCC_OUTPUT_OBJ) {
2462 ret = final_sections_reloc(s1);
2463 if (ret)
2464 goto the_end;
2467 /* Perform relocation to GOT or PLT entries */
2468 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2469 fill_got(s1);
2471 /* Create the ELF file with name 'filename' */
2472 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2473 the_end:
2474 tcc_free(s1->symtab_to_dynsym);
2475 tcc_free(sec_order);
2476 tcc_free(phdr);
2477 tcc_free(s1->sym_attrs);
2478 s1->sym_attrs = NULL;
2479 return ret;
2482 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2484 int ret;
2485 #ifdef TCC_TARGET_PE
2486 if (s->output_type != TCC_OUTPUT_OBJ) {
2487 ret = pe_output_file(s, filename);
2488 } else
2489 #endif
2490 ret = elf_output_file(s, filename);
2491 return ret;
2494 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2496 void *data;
2498 data = tcc_malloc(size);
2499 lseek(fd, file_offset, SEEK_SET);
2500 read(fd, data, size);
2501 return data;
2504 typedef struct SectionMergeInfo {
2505 Section *s; /* corresponding existing section */
2506 unsigned long offset; /* offset of the new section in the existing section */
2507 uint8_t new_section; /* true if section 's' was added */
2508 uint8_t link_once; /* true if link once section */
2509 } SectionMergeInfo;
2511 /* load an object file and merge it with current files */
2512 /* XXX: handle correctly stab (debug) info */
2513 ST_FUNC int tcc_load_object_file(TCCState *s1,
2514 int fd, unsigned long file_offset)
2516 ElfW(Ehdr) ehdr;
2517 ElfW(Shdr) *shdr, *sh;
2518 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2519 unsigned char *strsec, *strtab;
2520 int *old_to_new_syms;
2521 char *sh_name, *name;
2522 SectionMergeInfo *sm_table, *sm;
2523 ElfW(Sym) *sym, *symtab;
2524 ElfW_Rel *rel;
2525 Section *s;
2527 int stab_index;
2528 int stabstr_index;
2530 stab_index = stabstr_index = 0;
2532 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
2533 goto fail1;
2534 if (ehdr.e_ident[0] != ELFMAG0 ||
2535 ehdr.e_ident[1] != ELFMAG1 ||
2536 ehdr.e_ident[2] != ELFMAG2 ||
2537 ehdr.e_ident[3] != ELFMAG3)
2538 goto fail1;
2539 /* test if object file */
2540 if (ehdr.e_type != ET_REL)
2541 goto fail1;
2542 /* test CPU specific stuff */
2543 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2544 ehdr.e_machine != EM_TCC_TARGET) {
2545 fail1:
2546 tcc_error_noabort("invalid object file");
2547 return -1;
2549 /* read sections */
2550 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2551 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2552 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2554 /* load section names */
2555 sh = &shdr[ehdr.e_shstrndx];
2556 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2558 /* load symtab and strtab */
2559 old_to_new_syms = NULL;
2560 symtab = NULL;
2561 strtab = NULL;
2562 nb_syms = 0;
2563 for(i = 1; i < ehdr.e_shnum; i++) {
2564 sh = &shdr[i];
2565 if (sh->sh_type == SHT_SYMTAB) {
2566 if (symtab) {
2567 tcc_error_noabort("object must contain only one symtab");
2568 fail:
2569 ret = -1;
2570 goto the_end;
2572 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2573 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2574 sm_table[i].s = symtab_section;
2576 /* now load strtab */
2577 sh = &shdr[sh->sh_link];
2578 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2582 /* now examine each section and try to merge its content with the
2583 ones in memory */
2584 for(i = 1; i < ehdr.e_shnum; i++) {
2585 /* no need to examine section name strtab */
2586 if (i == ehdr.e_shstrndx)
2587 continue;
2588 sh = &shdr[i];
2589 sh_name = (char *) strsec + sh->sh_name;
2590 /* ignore sections types we do not handle */
2591 if (sh->sh_type != SHT_PROGBITS &&
2592 sh->sh_type != SHT_RELX &&
2593 #ifdef TCC_ARM_EABI
2594 sh->sh_type != SHT_ARM_EXIDX &&
2595 #endif
2596 sh->sh_type != SHT_NOBITS &&
2597 sh->sh_type != SHT_PREINIT_ARRAY &&
2598 sh->sh_type != SHT_INIT_ARRAY &&
2599 sh->sh_type != SHT_FINI_ARRAY &&
2600 strcmp(sh_name, ".stabstr")
2602 continue;
2603 if (sh->sh_addralign < 1)
2604 sh->sh_addralign = 1;
2605 /* find corresponding section, if any */
2606 for(j = 1; j < s1->nb_sections;j++) {
2607 s = s1->sections[j];
2608 if (!strcmp(s->name, sh_name)) {
2609 if (!strncmp(sh_name, ".gnu.linkonce",
2610 sizeof(".gnu.linkonce") - 1)) {
2611 /* if a 'linkonce' section is already present, we
2612 do not add it again. It is a little tricky as
2613 symbols can still be defined in
2614 it. */
2615 sm_table[i].link_once = 1;
2616 goto next;
2617 } else {
2618 goto found;
2622 /* not found: create new section */
2623 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
2624 /* take as much info as possible from the section. sh_link and
2625 sh_info will be updated later */
2626 s->sh_addralign = sh->sh_addralign;
2627 s->sh_entsize = sh->sh_entsize;
2628 sm_table[i].new_section = 1;
2629 found:
2630 if (sh->sh_type != s->sh_type) {
2631 tcc_error_noabort("invalid section type");
2632 goto fail;
2635 /* align start of section */
2636 offset = s->data_offset;
2638 if (0 == strcmp(sh_name, ".stab")) {
2639 stab_index = i;
2640 goto no_align;
2642 if (0 == strcmp(sh_name, ".stabstr")) {
2643 stabstr_index = i;
2644 goto no_align;
2647 size = sh->sh_addralign - 1;
2648 offset = (offset + size) & ~size;
2649 if (sh->sh_addralign > s->sh_addralign)
2650 s->sh_addralign = sh->sh_addralign;
2651 s->data_offset = offset;
2652 no_align:
2653 sm_table[i].offset = offset;
2654 sm_table[i].s = s;
2655 /* concatenate sections */
2656 size = sh->sh_size;
2657 if (sh->sh_type != SHT_NOBITS) {
2658 unsigned char *ptr;
2659 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2660 ptr = section_ptr_add(s, size);
2661 read(fd, ptr, size);
2662 } else {
2663 s->data_offset += size;
2665 next: ;
2668 /* gr relocate stab strings */
2669 if (stab_index && stabstr_index) {
2670 Stab_Sym *a, *b;
2671 unsigned o;
2672 s = sm_table[stab_index].s;
2673 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2674 b = (Stab_Sym *)(s->data + s->data_offset);
2675 o = sm_table[stabstr_index].offset;
2676 while (a < b)
2677 a->n_strx += o, a++;
2680 /* second short pass to update sh_link and sh_info fields of new
2681 sections */
2682 for(i = 1; i < ehdr.e_shnum; i++) {
2683 s = sm_table[i].s;
2684 if (!s || !sm_table[i].new_section)
2685 continue;
2686 sh = &shdr[i];
2687 if (sh->sh_link > 0)
2688 s->link = sm_table[sh->sh_link].s;
2689 if (sh->sh_type == SHT_RELX) {
2690 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2691 /* update backward link */
2692 s1->sections[s->sh_info]->reloc = s;
2695 sm = sm_table;
2697 /* resolve symbols */
2698 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2700 sym = symtab + 1;
2701 for(i = 1; i < nb_syms; i++, sym++) {
2702 if (sym->st_shndx != SHN_UNDEF &&
2703 sym->st_shndx < SHN_LORESERVE) {
2704 sm = &sm_table[sym->st_shndx];
2705 if (sm->link_once) {
2706 /* if a symbol is in a link once section, we use the
2707 already defined symbol. It is very important to get
2708 correct relocations */
2709 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2710 name = (char *) strtab + sym->st_name;
2711 sym_index = find_elf_sym(symtab_section, name);
2712 if (sym_index)
2713 old_to_new_syms[i] = sym_index;
2715 continue;
2717 /* if no corresponding section added, no need to add symbol */
2718 if (!sm->s)
2719 continue;
2720 /* convert section number */
2721 sym->st_shndx = sm->s->sh_num;
2722 /* offset value */
2723 sym->st_value += sm->offset;
2725 /* add symbol */
2726 name = (char *) strtab + sym->st_name;
2727 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
2728 sym->st_info, sym->st_other,
2729 sym->st_shndx, name);
2730 old_to_new_syms[i] = sym_index;
2733 /* third pass to patch relocation entries */
2734 for(i = 1; i < ehdr.e_shnum; i++) {
2735 s = sm_table[i].s;
2736 if (!s)
2737 continue;
2738 sh = &shdr[i];
2739 offset = sm_table[i].offset;
2740 switch(s->sh_type) {
2741 case SHT_RELX:
2742 /* take relocation offset information */
2743 offseti = sm_table[sh->sh_info].offset;
2744 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2745 int type;
2746 unsigned sym_index;
2747 /* convert symbol index */
2748 type = ELFW(R_TYPE)(rel->r_info);
2749 sym_index = ELFW(R_SYM)(rel->r_info);
2750 /* NOTE: only one symtab assumed */
2751 if (sym_index >= nb_syms)
2752 goto invalid_reloc;
2753 sym_index = old_to_new_syms[sym_index];
2754 /* ignore link_once in rel section. */
2755 if (!sym_index && !sm->link_once
2756 #ifdef TCC_TARGET_ARM
2757 && type != R_ARM_V4BX
2758 #endif
2760 invalid_reloc:
2761 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2762 i, strsec + sh->sh_name, rel->r_offset);
2763 goto fail;
2765 rel->r_info = ELFW(R_INFO)(sym_index, type);
2766 /* offset the relocation offset */
2767 rel->r_offset += offseti;
2768 #ifdef TCC_TARGET_ARM
2769 /* Jumps and branches from a Thumb code to a PLT entry need
2770 special handling since PLT entries are ARM code.
2771 Unconditional bl instructions referencing PLT entries are
2772 handled by converting these instructions into blx
2773 instructions. Other case of instructions referencing a PLT
2774 entry require to add a Thumb stub before the PLT entry to
2775 switch to ARM mode. We set bit plt_thumb_stub of the
2776 attribute of a symbol to indicate such a case. */
2777 if (type == R_ARM_THM_JUMP24)
2778 alloc_sym_attr(s1, sym_index)->plt_thumb_stub = 1;
2779 #endif
2781 break;
2782 default:
2783 break;
2787 ret = 0;
2788 the_end:
2789 tcc_free(symtab);
2790 tcc_free(strtab);
2791 tcc_free(old_to_new_syms);
2792 tcc_free(sm_table);
2793 tcc_free(strsec);
2794 tcc_free(shdr);
2795 return ret;
2798 typedef struct ArchiveHeader {
2799 char ar_name[16]; /* name of this member */
2800 char ar_date[12]; /* file mtime */
2801 char ar_uid[6]; /* owner uid; printed as decimal */
2802 char ar_gid[6]; /* owner gid; printed as decimal */
2803 char ar_mode[8]; /* file mode, printed as octal */
2804 char ar_size[10]; /* file size, printed as decimal */
2805 char ar_fmag[2]; /* should contain ARFMAG */
2806 } ArchiveHeader;
2808 static int get_be32(const uint8_t *b)
2810 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2813 /* load only the objects which resolve undefined symbols */
2814 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
2816 int i, bound, nsyms, sym_index, off, ret;
2817 uint8_t *data;
2818 const char *ar_names, *p;
2819 const uint8_t *ar_index;
2820 ElfW(Sym) *sym;
2822 data = tcc_malloc(size);
2823 if (read(fd, data, size) != size)
2824 goto fail;
2825 nsyms = get_be32(data);
2826 ar_index = data + 4;
2827 ar_names = (char *) ar_index + nsyms * 4;
2829 do {
2830 bound = 0;
2831 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2832 sym_index = find_elf_sym(symtab_section, p);
2833 if(sym_index) {
2834 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2835 if(sym->st_shndx == SHN_UNDEF) {
2836 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2837 ++bound;
2838 lseek(fd, off, SEEK_SET);
2839 if(tcc_load_object_file(s1, fd, off) < 0) {
2840 fail:
2841 ret = -1;
2842 goto the_end;
2847 } while(bound);
2848 ret = 0;
2849 the_end:
2850 tcc_free(data);
2851 return ret;
2854 /* load a '.a' file */
2855 ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
2857 ArchiveHeader hdr;
2858 char ar_size[11];
2859 char ar_name[17];
2860 char magic[8];
2861 int size, len, i;
2862 unsigned long file_offset;
2864 /* skip magic which was already checked */
2865 read(fd, magic, sizeof(magic));
2867 for(;;) {
2868 len = read(fd, &hdr, sizeof(hdr));
2869 if (len == 0)
2870 break;
2871 if (len != sizeof(hdr)) {
2872 tcc_error_noabort("invalid archive");
2873 return -1;
2875 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2876 ar_size[sizeof(hdr.ar_size)] = '\0';
2877 size = strtol(ar_size, NULL, 0);
2878 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2879 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2880 if (ar_name[i] != ' ')
2881 break;
2883 ar_name[i + 1] = '\0';
2884 file_offset = lseek(fd, 0, SEEK_CUR);
2885 /* align to even */
2886 size = (size + 1) & ~1;
2887 if (!strcmp(ar_name, "/")) {
2888 /* coff symbol table : we handle it */
2889 if(s1->alacarte_link)
2890 return tcc_load_alacarte(s1, fd, size);
2891 } else if (!strcmp(ar_name, "//") ||
2892 !strcmp(ar_name, "__.SYMDEF") ||
2893 !strcmp(ar_name, "__.SYMDEF/") ||
2894 !strcmp(ar_name, "ARFILENAMES/")) {
2895 /* skip symbol table or archive names */
2896 } else {
2897 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2898 return -1;
2900 lseek(fd, file_offset + size, SEEK_SET);
2902 return 0;
2905 #ifndef TCC_TARGET_PE
2906 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2907 is referenced by the user (so it should be added as DT_NEEDED in
2908 the generated ELF file) */
2909 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2911 ElfW(Ehdr) ehdr;
2912 ElfW(Shdr) *shdr, *sh, *sh1;
2913 int i, j, nb_syms, nb_dts, sym_bind, ret;
2914 ElfW(Sym) *sym, *dynsym;
2915 ElfW(Dyn) *dt, *dynamic;
2916 unsigned char *dynstr;
2917 const char *name, *soname;
2918 DLLReference *dllref;
2920 read(fd, &ehdr, sizeof(ehdr));
2922 /* test CPU specific stuff */
2923 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2924 ehdr.e_machine != EM_TCC_TARGET) {
2925 tcc_error_noabort("bad architecture");
2926 return -1;
2929 /* read sections */
2930 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2932 /* load dynamic section and dynamic symbols */
2933 nb_syms = 0;
2934 nb_dts = 0;
2935 dynamic = NULL;
2936 dynsym = NULL; /* avoid warning */
2937 dynstr = NULL; /* avoid warning */
2938 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2939 switch(sh->sh_type) {
2940 case SHT_DYNAMIC:
2941 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2942 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2943 break;
2944 case SHT_DYNSYM:
2945 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2946 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2947 sh1 = &shdr[sh->sh_link];
2948 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2949 break;
2950 default:
2951 break;
2955 /* compute the real library name */
2956 soname = tcc_basename(filename);
2958 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2959 if (dt->d_tag == DT_SONAME) {
2960 soname = (char *) dynstr + dt->d_un.d_val;
2964 /* if the dll is already loaded, do not load it */
2965 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2966 dllref = s1->loaded_dlls[i];
2967 if (!strcmp(soname, dllref->name)) {
2968 /* but update level if needed */
2969 if (level < dllref->level)
2970 dllref->level = level;
2971 ret = 0;
2972 goto the_end;
2976 /* add the dll and its level */
2977 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2978 dllref->level = level;
2979 strcpy(dllref->name, soname);
2980 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2982 /* add dynamic symbols in dynsym_section */
2983 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2984 sym_bind = ELFW(ST_BIND)(sym->st_info);
2985 if (sym_bind == STB_LOCAL)
2986 continue;
2987 name = (char *) dynstr + sym->st_name;
2988 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2989 sym->st_info, sym->st_other, sym->st_shndx, name);
2992 /* load all referenced DLLs */
2993 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2994 switch(dt->d_tag) {
2995 case DT_NEEDED:
2996 name = (char *) dynstr + dt->d_un.d_val;
2997 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2998 dllref = s1->loaded_dlls[j];
2999 if (!strcmp(name, dllref->name))
3000 goto already_loaded;
3002 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
3003 tcc_error_noabort("referenced dll '%s' not found", name);
3004 ret = -1;
3005 goto the_end;
3007 already_loaded:
3008 break;
3011 ret = 0;
3012 the_end:
3013 tcc_free(dynstr);
3014 tcc_free(dynsym);
3015 tcc_free(dynamic);
3016 tcc_free(shdr);
3017 return ret;
3020 #define LD_TOK_NAME 256
3021 #define LD_TOK_EOF (-1)
3023 /* return next ld script token */
3024 static int ld_next(TCCState *s1, char *name, int name_size)
3026 int c;
3027 char *q;
3029 redo:
3030 switch(ch) {
3031 case ' ':
3032 case '\t':
3033 case '\f':
3034 case '\v':
3035 case '\r':
3036 case '\n':
3037 inp();
3038 goto redo;
3039 case '/':
3040 minp();
3041 if (ch == '*') {
3042 file->buf_ptr = parse_comment(file->buf_ptr);
3043 ch = file->buf_ptr[0];
3044 goto redo;
3045 } else {
3046 q = name;
3047 *q++ = '/';
3048 goto parse_name;
3050 break;
3051 /* case 'a' ... 'z': */
3052 case 'a':
3053 case 'b':
3054 case 'c':
3055 case 'd':
3056 case 'e':
3057 case 'f':
3058 case 'g':
3059 case 'h':
3060 case 'i':
3061 case 'j':
3062 case 'k':
3063 case 'l':
3064 case 'm':
3065 case 'n':
3066 case 'o':
3067 case 'p':
3068 case 'q':
3069 case 'r':
3070 case 's':
3071 case 't':
3072 case 'u':
3073 case 'v':
3074 case 'w':
3075 case 'x':
3076 case 'y':
3077 case 'z':
3078 /* case 'A' ... 'z': */
3079 case 'A':
3080 case 'B':
3081 case 'C':
3082 case 'D':
3083 case 'E':
3084 case 'F':
3085 case 'G':
3086 case 'H':
3087 case 'I':
3088 case 'J':
3089 case 'K':
3090 case 'L':
3091 case 'M':
3092 case 'N':
3093 case 'O':
3094 case 'P':
3095 case 'Q':
3096 case 'R':
3097 case 'S':
3098 case 'T':
3099 case 'U':
3100 case 'V':
3101 case 'W':
3102 case 'X':
3103 case 'Y':
3104 case 'Z':
3105 case '_':
3106 case '\\':
3107 case '.':
3108 case '$':
3109 case '~':
3110 q = name;
3111 parse_name:
3112 for(;;) {
3113 if (!((ch >= 'a' && ch <= 'z') ||
3114 (ch >= 'A' && ch <= 'Z') ||
3115 (ch >= '0' && ch <= '9') ||
3116 strchr("/.-_+=$:\\,~", ch)))
3117 break;
3118 if ((q - name) < name_size - 1) {
3119 *q++ = ch;
3121 minp();
3123 *q = '\0';
3124 c = LD_TOK_NAME;
3125 break;
3126 case CH_EOF:
3127 c = LD_TOK_EOF;
3128 break;
3129 default:
3130 c = ch;
3131 inp();
3132 break;
3134 return c;
3137 static int ld_add_file(TCCState *s1, const char filename[])
3139 int ret;
3141 ret = tcc_add_file_internal(s1, filename, 0);
3142 if (ret)
3143 ret = tcc_add_dll(s1, filename, 0);
3144 return ret;
3147 static inline int new_undef_syms(void)
3149 int ret = 0;
3150 ret = new_undef_sym;
3151 new_undef_sym = 0;
3152 return ret;
3155 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3157 char filename[1024], libname[1024];
3158 int t, group, nblibs = 0, ret = 0;
3159 char **libs = NULL;
3161 group = !strcmp(cmd, "GROUP");
3162 if (!as_needed)
3163 new_undef_syms();
3164 t = ld_next(s1, filename, sizeof(filename));
3165 if (t != '(')
3166 expect("(");
3167 t = ld_next(s1, filename, sizeof(filename));
3168 for(;;) {
3169 libname[0] = '\0';
3170 if (t == LD_TOK_EOF) {
3171 tcc_error_noabort("unexpected end of file");
3172 ret = -1;
3173 goto lib_parse_error;
3174 } else if (t == ')') {
3175 break;
3176 } else if (t == '-') {
3177 t = ld_next(s1, filename, sizeof(filename));
3178 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3179 tcc_error_noabort("library name expected");
3180 ret = -1;
3181 goto lib_parse_error;
3183 pstrcpy(libname, sizeof libname, &filename[1]);
3184 if (s1->static_link) {
3185 snprintf(filename, sizeof filename, "lib%s.a", libname);
3186 } else {
3187 snprintf(filename, sizeof filename, "lib%s.so", libname);
3189 } else if (t != LD_TOK_NAME) {
3190 tcc_error_noabort("filename expected");
3191 ret = -1;
3192 goto lib_parse_error;
3194 if (!strcmp(filename, "AS_NEEDED")) {
3195 ret = ld_add_file_list(s1, cmd, 1);
3196 if (ret)
3197 goto lib_parse_error;
3198 } else {
3199 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3200 if (!as_needed) {
3201 ret = ld_add_file(s1, filename);
3202 if (ret)
3203 goto lib_parse_error;
3204 if (group) {
3205 /* Add the filename *and* the libname to avoid future conversions */
3206 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename));
3207 if (libname[0] != '\0')
3208 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname));
3212 t = ld_next(s1, filename, sizeof(filename));
3213 if (t == ',') {
3214 t = ld_next(s1, filename, sizeof(filename));
3217 if (group && !as_needed) {
3218 while (new_undef_syms()) {
3219 int i;
3221 for (i = 0; i < nblibs; i ++)
3222 ld_add_file(s1, libs[i]);
3225 lib_parse_error:
3226 dynarray_reset(&libs, &nblibs);
3227 return ret;
3230 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3231 files */
3232 ST_FUNC int tcc_load_ldscript(TCCState *s1)
3234 char cmd[64];
3235 char filename[1024];
3236 int t, ret;
3238 ch = file->buf_ptr[0];
3239 ch = handle_eob();
3240 for(;;) {
3241 t = ld_next(s1, cmd, sizeof(cmd));
3242 if (t == LD_TOK_EOF)
3243 return 0;
3244 else if (t != LD_TOK_NAME)
3245 return -1;
3246 if (!strcmp(cmd, "INPUT") ||
3247 !strcmp(cmd, "GROUP")) {
3248 ret = ld_add_file_list(s1, cmd, 0);
3249 if (ret)
3250 return ret;
3251 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3252 !strcmp(cmd, "TARGET")) {
3253 /* ignore some commands */
3254 t = ld_next(s1, cmd, sizeof(cmd));
3255 if (t != '(')
3256 expect("(");
3257 for(;;) {
3258 t = ld_next(s1, filename, sizeof(filename));
3259 if (t == LD_TOK_EOF) {
3260 tcc_error_noabort("unexpected end of file");
3261 return -1;
3262 } else if (t == ')') {
3263 break;
3266 } else {
3267 return -1;
3270 return 0;
3272 #endif /* !TCC_TARGET_PE */