Split elf_output_file in smaller functions
[tinycc.git] / tccelf.c
blob3bee1b92a52d7c098254401e32e8361888b6d494
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 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(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(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 = 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 = 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 = 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;
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 int esym_index;
521 #endif
523 sr = s->reloc;
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 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
806 qrel->r_addend = *(long long *)ptr + val;
807 qrel++;
809 *(long long *)ptr += val;
810 break;
811 case R_X86_64_32:
812 case R_X86_64_32S:
813 if (s1->output_type == TCC_OUTPUT_DLL) {
814 /* XXX: this logic may depend on TCC's codegen
815 now TCC uses R_X86_64_32 even for a 64bit pointer */
816 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
817 qrel->r_addend = *(int *)ptr + val;
818 qrel++;
820 *(int *)ptr += val;
821 break;
823 case R_X86_64_PC32:
824 if (s1->output_type == TCC_OUTPUT_DLL) {
825 /* DLL relocation */
826 esym_index = s1->symtab_to_dynsym[sym_index];
827 if (esym_index) {
828 qrel->r_offset = rel->r_offset;
829 qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
830 qrel->r_addend = *(int *)ptr;
831 qrel++;
832 break;
835 /* fall through */
836 case R_X86_64_PLT32: {
837 long long diff;
838 diff = (long long)val - addr;
839 if (diff <= -2147483647 || diff > 2147483647) {
840 #ifdef TCC_HAS_RUNTIME_PLTGOT
841 /* XXX: naive support for over 32bit jump */
842 if (s1->output_type == TCC_OUTPUT_MEMORY) {
843 val = (add_jmp_table(s1, val - rel->r_addend) +
844 rel->r_addend);
845 diff = val - addr;
847 #endif
848 if (diff <= -2147483647 || diff > 2147483647) {
849 tcc_error("internal error: relocation failed");
852 *(int *)ptr += diff;
854 break;
855 case R_X86_64_GLOB_DAT:
856 case R_X86_64_JUMP_SLOT:
857 /* They don't need addend */
858 *(int *)ptr = val - rel->r_addend;
859 break;
860 case R_X86_64_GOTPCREL:
861 #ifdef TCC_HAS_RUNTIME_PLTGOT
862 if (s1->output_type == TCC_OUTPUT_MEMORY) {
863 val = add_got_table(s1, val - rel->r_addend) + rel->r_addend;
864 *(int *)ptr += val - addr;
865 break;
867 #endif
868 *(int *)ptr += (s1->got->sh_addr - addr +
869 s1->sym_attrs[sym_index].got_offset - 4);
870 break;
871 case R_X86_64_GOTTPOFF:
872 *(int *)ptr += val - s1->got->sh_addr;
873 break;
874 case R_X86_64_GOT32:
875 /* we load the got offset */
876 *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
877 break;
878 #else
879 #error unsupported processor
880 #endif
883 /* if the relocation is allocated, we change its symbol table */
884 if (sr->sh_flags & SHF_ALLOC)
885 sr->link = s1->dynsym;
888 /* relocate relocation table in 'sr' */
889 static void relocate_rel(TCCState *s1, Section *sr)
891 Section *s;
892 ElfW_Rel *rel;
894 s = s1->sections[sr->sh_info];
895 for_each_elem(sr, 0, rel, ElfW_Rel)
896 rel->r_offset += s->sh_addr;
899 /* count the number of dynamic relocations so that we can reserve
900 their space */
901 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
903 ElfW_Rel *rel;
904 int sym_index, esym_index, type, count;
906 count = 0;
907 for_each_elem(sr, 0, rel, ElfW_Rel) {
908 sym_index = ELFW(R_SYM)(rel->r_info);
909 type = ELFW(R_TYPE)(rel->r_info);
910 switch(type) {
911 #if defined(TCC_TARGET_I386)
912 case R_386_32:
913 #elif defined(TCC_TARGET_X86_64)
914 case R_X86_64_32:
915 case R_X86_64_32S:
916 case R_X86_64_64:
917 #endif
918 count++;
919 break;
920 #if defined(TCC_TARGET_I386)
921 case R_386_PC32:
922 #elif defined(TCC_TARGET_X86_64)
923 case R_X86_64_PC32:
924 #endif
925 esym_index = s1->symtab_to_dynsym[sym_index];
926 if (esym_index)
927 count++;
928 break;
929 default:
930 break;
933 if (count) {
934 /* allocate the section */
935 sr->sh_flags |= SHF_ALLOC;
936 sr->sh_size = count * sizeof(ElfW_Rel);
938 return count;
941 static struct sym_attr *alloc_sym_attr(TCCState *s1, int index)
943 int n;
944 struct sym_attr *tab;
946 if (index >= s1->nb_sym_attrs) {
947 /* find immediately bigger power of 2 and reallocate array */
948 n = 1;
949 while (index >= n)
950 n *= 2;
951 tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
952 s1->sym_attrs = tab;
953 memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
954 (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
955 s1->nb_sym_attrs = n;
957 return &s1->sym_attrs[index];
960 /* XXX: suppress that */
961 static void put32(unsigned char *p, uint32_t val)
963 p[0] = val;
964 p[1] = val >> 8;
965 p[2] = val >> 16;
966 p[3] = val >> 24;
969 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
970 defined(TCC_TARGET_X86_64)
971 static uint32_t get32(unsigned char *p)
973 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
975 #endif
977 static void build_got(TCCState *s1)
979 unsigned char *ptr;
981 /* if no got, then create it */
982 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
983 s1->got->sh_entsize = 4;
984 add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
985 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
986 ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
987 #if PTR_SIZE == 4
988 /* keep space for _DYNAMIC pointer, if present */
989 put32(ptr, 0);
990 /* two dummy got entries */
991 put32(ptr + 4, 0);
992 put32(ptr + 8, 0);
993 #else
994 /* keep space for _DYNAMIC pointer, if present */
995 put32(ptr, 0);
996 put32(ptr + 4, 0);
997 /* two dummy got entries */
998 put32(ptr + 8, 0);
999 put32(ptr + 12, 0);
1000 put32(ptr + 16, 0);
1001 put32(ptr + 20, 0);
1002 #endif
1005 /* put a got entry corresponding to a symbol in symtab_section. 'size'
1006 and 'info' can be modifed if more precise info comes from the DLL */
1007 static void put_got_entry(TCCState *s1,
1008 int reloc_type, unsigned long size, int info,
1009 int sym_index)
1011 int index;
1012 const char *name;
1013 ElfW(Sym) *sym;
1014 unsigned long offset;
1015 int *ptr;
1017 if (!s1->got)
1018 build_got(s1);
1020 /* if a got entry already exists for that symbol, no need to add one */
1021 if (sym_index < s1->nb_sym_attrs &&
1022 s1->sym_attrs[sym_index].got_offset)
1023 return;
1025 alloc_sym_attr(s1, sym_index)->got_offset = s1->got->data_offset;
1027 if (s1->dynsym) {
1028 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1029 name = symtab_section->link->data + sym->st_name;
1030 offset = sym->st_value;
1031 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1032 if (reloc_type ==
1033 #ifdef TCC_TARGET_X86_64
1034 R_X86_64_JUMP_SLOT
1035 #else
1036 R_386_JMP_SLOT
1037 #endif
1039 Section *plt;
1040 uint8_t *p;
1041 int modrm;
1043 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1044 modrm = 0x25;
1045 #else
1046 /* if we build a DLL, we add a %ebx offset */
1047 if (s1->output_type == TCC_OUTPUT_DLL)
1048 modrm = 0xa3;
1049 else
1050 modrm = 0x25;
1051 #endif
1053 /* add a PLT entry */
1054 plt = s1->plt;
1055 if (plt->data_offset == 0) {
1056 /* first plt entry */
1057 p = section_ptr_add(plt, 16);
1058 p[0] = 0xff; /* pushl got + PTR_SIZE */
1059 p[1] = modrm + 0x10;
1060 put32(p + 2, PTR_SIZE);
1061 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
1062 p[7] = modrm;
1063 put32(p + 8, PTR_SIZE * 2);
1066 p = section_ptr_add(plt, 16);
1067 p[0] = 0xff; /* jmp *(got + x) */
1068 p[1] = modrm;
1069 put32(p + 2, s1->got->data_offset);
1070 p[6] = 0x68; /* push $xxx */
1071 put32(p + 7, (plt->data_offset - 32) >> 1);
1072 p[11] = 0xe9; /* jmp plt_start */
1073 put32(p + 12, -(plt->data_offset));
1075 /* the symbol is modified so that it will be relocated to
1076 the PLT */
1077 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
1078 if (s1->output_type == TCC_OUTPUT_EXE)
1079 #endif
1080 offset = plt->data_offset - 16;
1082 #elif defined(TCC_TARGET_ARM)
1083 if (reloc_type == R_ARM_JUMP_SLOT) {
1084 Section *plt;
1085 uint8_t *p;
1087 /* if we build a DLL, we add a %ebx offset */
1088 if (s1->output_type == TCC_OUTPUT_DLL)
1089 tcc_error("DLLs unimplemented!");
1091 /* add a PLT entry */
1092 plt = s1->plt;
1093 if (plt->data_offset == 0) {
1094 /* first plt entry */
1095 p = section_ptr_add(plt, 16);
1096 put32(p, 0xe52de004); /* push {lr} */
1097 put32(p+4, 0xe59fe010); /* ldr lr, [pc, #16] */
1098 put32(p+8, 0xe08fe00e); /* add lr, pc, lr */
1099 put32(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */
1102 if (s1->sym_attrs[sym_index].plt_thumb_stub) {
1103 p = section_ptr_add(plt, 20);
1104 put32(p, 0x4778); /* bx pc */
1105 put32(p+2, 0x46c0); /* nop */
1106 p += 4;
1107 } else
1108 p = section_ptr_add(plt, 16);
1109 put32(p, 0xe59fc004); /* ldr ip, [pc, #4] ; GOT entry offset */
1110 put32(p+4, 0xe08fc00c); /* add ip, pc, ip ; addr of GOT entry */
1111 put32(p+8, 0xe59cf000); /* ldr pc, [ip] ; jump to GOT entry */
1112 put32(p+12, s1->got->data_offset); /* GOT entry off once patched */
1114 /* the symbol is modified so that it will be relocated to
1115 the PLT */
1116 if (s1->output_type == TCC_OUTPUT_EXE)
1117 offset = plt->data_offset - 16;
1119 #elif defined(TCC_TARGET_C67)
1120 tcc_error("C67 got not implemented");
1121 #else
1122 #error unsupported CPU
1123 #endif
1124 index = put_elf_sym(s1->dynsym, offset,
1125 size, info, 0, sym->st_shndx, name);
1126 /* put a got entry */
1127 put_elf_reloc(s1->dynsym, s1->got,
1128 s1->got->data_offset,
1129 reloc_type, index);
1131 ptr = section_ptr_add(s1->got, PTR_SIZE);
1132 *ptr = 0;
1135 /* build GOT and PLT entries */
1136 ST_FUNC void build_got_entries(TCCState *s1)
1138 Section *s;
1139 ElfW_Rel *rel;
1140 ElfW(Sym) *sym;
1141 int i, type, reloc_type, sym_index;
1143 for(i = 1; i < s1->nb_sections; i++) {
1144 s = s1->sections[i];
1145 if (s->sh_type != SHT_RELX)
1146 continue;
1147 /* no need to handle got relocations */
1148 if (s->link != symtab_section)
1149 continue;
1150 for_each_elem(s, 0, rel, ElfW_Rel) {
1151 type = ELFW(R_TYPE)(rel->r_info);
1152 switch(type) {
1153 #if defined(TCC_TARGET_I386)
1154 case R_386_GOT32:
1155 case R_386_GOTOFF:
1156 case R_386_GOTPC:
1157 case R_386_PLT32:
1158 if (!s1->got)
1159 build_got(s1);
1160 if (type == R_386_GOT32 || type == R_386_PLT32) {
1161 sym_index = ELFW(R_SYM)(rel->r_info);
1162 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1163 /* look at the symbol got offset. If none, then add one */
1164 if (type == R_386_GOT32)
1165 reloc_type = R_386_GLOB_DAT;
1166 else
1167 reloc_type = R_386_JMP_SLOT;
1168 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1169 sym_index);
1171 break;
1172 #elif defined(TCC_TARGET_ARM)
1173 case R_ARM_GOT32:
1174 case R_ARM_GOTOFF:
1175 case R_ARM_GOTPC:
1176 case R_ARM_PLT32:
1177 if (!s1->got)
1178 build_got(s1);
1179 if (type == R_ARM_GOT32 || type == R_ARM_PLT32) {
1180 sym_index = ELFW(R_SYM)(rel->r_info);
1181 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1182 /* look at the symbol got offset. If none, then add one */
1183 if (type == R_ARM_GOT32)
1184 reloc_type = R_ARM_GLOB_DAT;
1185 else
1186 reloc_type = R_ARM_JUMP_SLOT;
1187 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1188 sym_index);
1190 break;
1191 #elif defined(TCC_TARGET_C67)
1192 case R_C60_GOT32:
1193 case R_C60_GOTOFF:
1194 case R_C60_GOTPC:
1195 case R_C60_PLT32:
1196 if (!s1->got)
1197 build_got(s1);
1198 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
1199 sym_index = ELFW(R_SYM)(rel->r_info);
1200 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1201 /* look at the symbol got offset. If none, then add one */
1202 if (type == R_C60_GOT32)
1203 reloc_type = R_C60_GLOB_DAT;
1204 else
1205 reloc_type = R_C60_JMP_SLOT;
1206 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1207 sym_index);
1209 break;
1210 #elif defined(TCC_TARGET_X86_64)
1211 case R_X86_64_GOT32:
1212 case R_X86_64_GOTTPOFF:
1213 case R_X86_64_GOTPCREL:
1214 case R_X86_64_PLT32:
1215 if (!s1->got)
1216 build_got(s1);
1217 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
1218 type == R_X86_64_PLT32) {
1219 sym_index = ELFW(R_SYM)(rel->r_info);
1220 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1221 /* look at the symbol got offset. If none, then add one */
1222 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL)
1223 reloc_type = R_X86_64_GLOB_DAT;
1224 else
1225 reloc_type = R_X86_64_JUMP_SLOT;
1226 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1227 sym_index);
1229 break;
1230 #else
1231 #error unsupported CPU
1232 #endif
1233 default:
1234 break;
1240 ST_FUNC Section *new_symtab(TCCState *s1,
1241 const char *symtab_name, int sh_type, int sh_flags,
1242 const char *strtab_name,
1243 const char *hash_name, int hash_sh_flags)
1245 Section *symtab, *strtab, *hash;
1246 int *ptr, nb_buckets;
1248 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1249 symtab->sh_entsize = sizeof(ElfW(Sym));
1250 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1251 put_elf_str(strtab, "");
1252 symtab->link = strtab;
1253 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1255 nb_buckets = 1;
1257 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1258 hash->sh_entsize = sizeof(int);
1259 symtab->hash = hash;
1260 hash->link = symtab;
1262 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1263 ptr[0] = nb_buckets;
1264 ptr[1] = 1;
1265 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1266 return symtab;
1269 /* put dynamic tag */
1270 static void put_dt(Section *dynamic, int dt, addr_t val)
1272 ElfW(Dyn) *dyn;
1273 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1274 dyn->d_tag = dt;
1275 dyn->d_un.d_val = val;
1278 static void add_init_array_defines(TCCState *s1, const char *section_name)
1280 Section *s;
1281 long end_offset;
1282 char sym_start[1024];
1283 char sym_end[1024];
1285 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1286 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1288 s = find_section(s1, section_name);
1289 if (!s) {
1290 end_offset = 0;
1291 s = data_section;
1292 } else {
1293 end_offset = s->data_offset;
1296 add_elf_sym(symtab_section,
1297 0, 0,
1298 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1299 s->sh_num, sym_start);
1300 add_elf_sym(symtab_section,
1301 end_offset, 0,
1302 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1303 s->sh_num, sym_end);
1306 ST_FUNC void tcc_add_bcheck(TCCState *s1)
1308 #ifdef CONFIG_TCC_BCHECK
1309 unsigned long *ptr;
1310 Section *init_section;
1311 unsigned char *pinit;
1312 int sym_index;
1314 if (0 == s1->do_bounds_check)
1315 return;
1317 /* XXX: add an object file to do that */
1318 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
1319 *ptr = 0;
1320 add_elf_sym(symtab_section, 0, 0,
1321 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1322 bounds_section->sh_num, "__bounds_start");
1323 #ifdef TCC_TARGET_I386
1324 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1325 /* add 'call __bound_init()' in .init section */
1326 init_section = find_section(s1, ".init");
1327 pinit = section_ptr_add(init_section, 5);
1328 pinit[0] = 0xe8;
1329 put32(pinit + 1, -4);
1330 sym_index = find_elf_sym(symtab_section, "__bound_init");
1331 put_elf_reloc(symtab_section, init_section,
1332 init_section->data_offset - 4, R_386_PC32, sym_index);
1334 #endif
1335 #endif
1338 static inline int tcc_add_support(TCCState *s1, const char *filename)
1340 char buf[1024];
1341 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
1342 return tcc_add_file(s1, buf);
1345 /* add tcc runtime libraries */
1346 ST_FUNC void tcc_add_runtime(TCCState *s1)
1348 tcc_add_bcheck(s1);
1350 /* add libc */
1351 if (!s1->nostdlib) {
1352 tcc_add_library(s1, "c");
1353 #ifdef CONFIG_USE_LIBGCC
1354 if (!s1->static_link)
1355 tcc_add_file(s1, TCC_LIBGCC);
1356 else
1357 tcc_add_support(s1, "libtcc1.a");
1358 #else
1359 tcc_add_support(s1, "libtcc1.a");
1360 #endif
1361 /* add crt end if not memory output */
1362 if (s1->output_type != TCC_OUTPUT_MEMORY)
1363 tcc_add_crt(s1, "crtn.o");
1367 /* add various standard linker symbols (must be done after the
1368 sections are filled (for example after allocating common
1369 symbols)) */
1370 ST_FUNC void tcc_add_linker_symbols(TCCState *s1)
1372 char buf[1024];
1373 int i;
1374 Section *s;
1376 add_elf_sym(symtab_section,
1377 text_section->data_offset, 0,
1378 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1379 text_section->sh_num, "_etext");
1380 add_elf_sym(symtab_section,
1381 data_section->data_offset, 0,
1382 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1383 data_section->sh_num, "_edata");
1384 add_elf_sym(symtab_section,
1385 bss_section->data_offset, 0,
1386 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1387 bss_section->sh_num, "_end");
1388 /* horrible new standard ldscript defines */
1389 add_init_array_defines(s1, ".preinit_array");
1390 add_init_array_defines(s1, ".init_array");
1391 add_init_array_defines(s1, ".fini_array");
1393 /* add start and stop symbols for sections whose name can be
1394 expressed in C */
1395 for(i = 1; i < s1->nb_sections; i++) {
1396 s = s1->sections[i];
1397 if (s->sh_type == SHT_PROGBITS &&
1398 (s->sh_flags & SHF_ALLOC)) {
1399 const char *p;
1400 int ch;
1402 /* check if section name can be expressed in C */
1403 p = s->name;
1404 for(;;) {
1405 ch = *p;
1406 if (!ch)
1407 break;
1408 if (!isid(ch) && !isnum(ch))
1409 goto next_sec;
1410 p++;
1412 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1413 add_elf_sym(symtab_section,
1414 0, 0,
1415 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1416 s->sh_num, buf);
1417 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1418 add_elf_sym(symtab_section,
1419 s->data_offset, 0,
1420 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1421 s->sh_num, buf);
1423 next_sec: ;
1427 static void tcc_output_binary(TCCState *s1, FILE *f,
1428 const int *sec_order)
1430 Section *s;
1431 int i, offset, size;
1433 offset = 0;
1434 for(i=1;i<s1->nb_sections;i++) {
1435 s = s1->sections[sec_order[i]];
1436 if (s->sh_type != SHT_NOBITS &&
1437 (s->sh_flags & SHF_ALLOC)) {
1438 while (offset < s->sh_offset) {
1439 fputc(0, f);
1440 offset++;
1442 size = s->sh_size;
1443 fwrite(s->data, 1, size, f);
1444 offset += size;
1449 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1450 #define HAVE_PHDR 1
1451 #define EXTRA_RELITEMS 14
1453 /* move the relocation value from .dynsym to .got */
1454 void patch_dynsym_undef(TCCState *s1, Section *s)
1456 uint32_t *gotd = (void *)s1->got->data;
1457 ElfW(Sym) *sym;
1459 gotd += 3; /* dummy entries in .got */
1460 /* relocate symbols in .dynsym */
1461 for_each_elem(s, 1, sym, ElfW(Sym)) {
1462 if (sym->st_shndx == SHN_UNDEF) {
1463 *gotd++ = sym->st_value + 6; /* XXX 6 is magic ? */
1464 sym->st_value = 0;
1468 #else
1469 #define HAVE_PHDR 0
1470 #define EXTRA_RELITEMS 9
1472 /* zero plt offsets of weak symbols in .dynsym */
1473 void patch_dynsym_undef(TCCState *s1, Section *s)
1475 ElfW(Sym) *sym;
1477 for_each_elem(s, 1, sym, ElfW(Sym))
1478 if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
1479 sym->st_value = 0;
1481 #endif
1483 ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
1485 int sym_index = ELFW(R_SYM) (rel->r_info);
1486 ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
1487 unsigned long offset;
1489 if (sym_index >= s1->nb_sym_attrs)
1490 return;
1491 offset = s1->sym_attrs[sym_index].got_offset;
1492 section_reserve(s1->got, offset + PTR_SIZE);
1493 #ifdef TCC_TARGET_X86_64
1494 /* only works for x86-64 */
1495 put32(s1->got->data + offset + 4, sym->st_value >> 32);
1496 #endif
1497 put32(s1->got->data + offset, sym->st_value & 0xffffffff);
1500 /* Perform relocation to GOT or PLT entries */
1501 ST_FUNC void fill_got(TCCState *s1)
1503 Section *s;
1504 ElfW_Rel *rel;
1505 int i;
1507 for(i = 1; i < s1->nb_sections; i++) {
1508 s = s1->sections[i];
1509 if (s->sh_type != SHT_RELX)
1510 continue;
1511 /* no need to handle got relocations */
1512 if (s->link != symtab_section)
1513 continue;
1514 for_each_elem(s, 0, rel, ElfW_Rel) {
1515 switch (ELFW(R_TYPE) (rel->r_info)) {
1516 #ifdef TCC_TARGET_X86_64
1517 case R_X86_64_GOT32:
1518 case R_X86_64_GOTPCREL:
1519 case R_X86_64_PLT32:
1520 fill_got_entry(s1, rel);
1521 break;
1522 #endif
1528 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1529 in shared libraries and export non local defined symbols to shared libraries
1530 if -rdynamic switch was given on command line */
1531 static void bind_exe_dynsyms(TCCState *s1)
1533 const char *name;
1534 int sym_index, index;
1535 ElfW(Sym) *sym, *esym;
1536 int type;
1538 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1539 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1540 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1541 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1542 if (sym->st_shndx == SHN_UNDEF) {
1543 name = symtab_section->link->data + sym->st_name;
1544 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1545 if (sym_index) {
1546 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1547 type = ELFW(ST_TYPE)(esym->st_info);
1548 if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
1549 /* Indirect functions shall have STT_FUNC type in executable
1550 * dynsym section. Indeed, a dlsym call following a lazy
1551 * resolution would pick the symbol value from the
1552 * executable dynsym entry which would contain the address
1553 * of the function wanted by the caller of dlsym instead of
1554 * the address of the function that would return that
1555 * address */
1556 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1557 ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC),
1558 sym - (ElfW(Sym) *)symtab_section->data);
1559 } else if (type == STT_OBJECT) {
1560 unsigned long offset;
1561 ElfW(Sym) *dynsym;
1562 offset = bss_section->data_offset;
1563 /* XXX: which alignment ? */
1564 offset = (offset + 16 - 1) & -16;
1565 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1566 esym->st_info, 0, bss_section->sh_num,
1567 name);
1568 /* Ensure R_COPY works for weak symbol aliases */
1569 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1570 for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
1571 if ((dynsym->st_value == esym->st_value)
1572 && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
1573 char *dynname = s1->dynsymtab_section->link->data
1574 + dynsym->st_name;
1575 put_elf_sym(s1->dynsym, offset, dynsym->st_size,
1576 dynsym->st_info, 0,
1577 bss_section->sh_num, dynname);
1578 break;
1582 put_elf_reloc(s1->dynsym, bss_section,
1583 offset, R_COPY, index);
1584 offset += esym->st_size;
1585 bss_section->data_offset = offset;
1587 } else {
1588 /* STB_WEAK undefined symbols are accepted */
1589 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1590 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1591 !strcmp(name, "_fp_hw")) {
1592 } else {
1593 tcc_error_noabort("undefined symbol '%s'", name);
1596 } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1597 /* if -rdynamic option, then export all non local symbols */
1598 name = symtab_section->link->data + sym->st_name;
1599 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
1600 0, sym->st_shndx, name);
1605 /* Bind symbols of libraries: export non local symbols of executable that
1606 resolve undefined symbols of shared libraries */
1607 static void bind_libs_dynsyms(TCCState *s1)
1609 const char *name;
1610 int sym_index;
1611 ElfW(Sym) *sym, *esym;
1613 /* now look at unresolved dynamic symbols and export
1614 corresponding symbol */
1615 for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
1616 if (esym->st_shndx == SHN_UNDEF) {
1617 name = s1->dynsymtab_section->link->data + esym->st_name;
1618 sym_index = find_elf_sym(symtab_section, name);
1619 if (sym_index) {
1620 /* XXX: avoid adding a symbol if already present because of
1621 -rdynamic ? */
1622 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1623 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1624 sym->st_info, 0, sym->st_shndx, name);
1625 } else {
1626 /* weak symbols can stay undefined */
1627 if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
1628 tcc_warning("undefined dynamic symbol '%s'", name);
1634 /* Export all non local symbols (for shared libraries) */
1635 static void export_global_syms(TCCState *s1)
1637 int nb_syms, dynindex, index;
1638 const char *name;
1639 ElfW(Sym) *sym;
1641 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1642 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1643 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
1644 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1645 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1646 int type = ELFW(ST_TYPE)(sym->st_info);
1647 if ((type == STT_FUNC || type == STT_GNU_IFUNC)
1648 && sym->st_shndx == SHN_UNDEF) {
1649 int visibility = ELFW(ST_BIND)(sym->st_info);
1650 put_got_entry(s1, R_JMP_SLOT, sym->st_size,
1651 ELFW(ST_INFO)(visibility, STT_FUNC),
1652 sym - (ElfW(Sym) *) symtab_section->data);
1653 } else if (type == STT_OBJECT) {
1654 put_got_entry(s1, R_X86_64_GLOB_DAT, sym->st_size, sym->st_info,
1655 sym - (ElfW(Sym) *) symtab_section->data);
1656 } else
1657 #endif
1659 name = symtab_section->link->data + sym->st_name;
1660 dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1661 sym->st_info, 0, sym->st_shndx, name);
1662 index = sym - (ElfW(Sym) *) symtab_section->data;
1663 s1->symtab_to_dynsym[index] = dynindex;
1669 /* relocate the PLT: compute addresses and offsets in the PLT now that final
1670 address for PLT and GOT are known (see fill_program_header) */
1671 static void relocate_plt(TCCState *s1)
1673 uint8_t *p, *p_end;
1675 p = s1->plt->data;
1676 p_end = p + s1->plt->data_offset;
1677 if (p < p_end) {
1678 #if defined(TCC_TARGET_I386)
1679 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1680 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1681 p += 16;
1682 while (p < p_end) {
1683 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1684 p += 16;
1686 #elif defined(TCC_TARGET_X86_64)
1687 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
1688 put32(p + 2, get32(p + 2) + x);
1689 put32(p + 8, get32(p + 8) + x - 6);
1690 p += 16;
1691 while (p < p_end) {
1692 put32(p + 2, get32(p + 2) + x + s1->plt->data - p);
1693 p += 16;
1695 #elif defined(TCC_TARGET_ARM)
1696 int x;
1697 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1698 p += 16;
1699 while (p < p_end) {
1700 if (get32(p) == 0x46c04778) /* PLT Thumb stub present */
1701 p += 4;
1702 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1703 p += 16;
1705 #elif defined(TCC_TARGET_C67)
1706 /* XXX: TODO */
1707 #else
1708 #error unsupported CPU
1709 #endif
1713 /* Allocate strings for section names and decide if an unallocated section
1714 should be output.
1716 NOTE: the strsec section comes last, so its size is also correct ! */
1717 static void alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
1719 int i;
1720 Section *s;
1722 /* Allocate strings for section names */
1723 for(i = 1; i < s1->nb_sections; i++) {
1724 s = s1->sections[i];
1725 s->sh_name = put_elf_str(strsec, s->name);
1726 /* when generating a DLL, we include relocations but we may
1727 patch them */
1728 if (file_type == TCC_OUTPUT_DLL &&
1729 s->sh_type == SHT_RELX &&
1730 !(s->sh_flags & SHF_ALLOC)) {
1731 /* gr: avoid bogus relocs for empty (debug) sections */
1732 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1733 prepare_dynamic_rel(s1, s);
1734 else if (s1->do_debug)
1735 s->sh_size = s->data_offset;
1736 } else if (s1->do_debug ||
1737 file_type == TCC_OUTPUT_OBJ ||
1738 (s->sh_flags & SHF_ALLOC) ||
1739 i == (s1->nb_sections - 1)) {
1740 /* we output all sections if debug or object file */
1741 s->sh_size = s->data_offset;
1746 /* Info to be copied in dynamic section */
1747 struct dyn_inf {
1748 Section *dynamic;
1749 Section *dynstr;
1750 unsigned long dyn_rel_off;
1751 addr_t rel_addr;
1752 addr_t rel_size;
1753 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1754 addr_t bss_addr;
1755 addr_t bss_size;
1756 #endif
1759 /* Assign sections to segments and decide how are sections laid out when loaded
1760 in memory. This function also fills corresponding program headers. */
1761 static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
1762 Section *interp, struct dyn_inf *dyninf,
1763 int *sec_order)
1765 int i, j, k, file_type, sh_order_index, file_offset;
1766 long long tmp;
1767 addr_t addr;
1768 ElfW(Phdr) *ph;
1769 Section *s;
1771 file_type = s1->output_type;
1772 sh_order_index = 1;
1773 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
1774 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1775 else
1776 file_offset = 0;
1778 if (phnum > 0) {
1779 if (s1->has_text_addr) {
1780 int a_offset, p_offset;
1781 addr = s1->text_addr;
1782 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1783 ELF_PAGE_SIZE */
1784 a_offset = (int) (addr & (s1->section_align - 1));
1785 p_offset = file_offset & (s1->section_align - 1);
1786 if (a_offset < p_offset)
1787 a_offset += s1->section_align;
1788 file_offset += (a_offset - p_offset);
1789 } else {
1790 if (file_type == TCC_OUTPUT_DLL)
1791 addr = 0;
1792 else
1793 addr = ELF_START_ADDR;
1794 /* compute address after headers */
1795 addr += (file_offset & (s1->section_align - 1));
1798 ph = &phdr[0];
1799 /* Leave one program headers for the program interpreter and one for
1800 the program header table itself if needed. These are done later as
1801 they require section layout to be done first. */
1802 if (interp)
1803 ph += 1 + HAVE_PHDR;
1805 /* dynamic relocation table information, for .dynamic section */
1806 dyninf->rel_addr = dyninf->rel_size = 0;
1807 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1808 dyninf->bss_addr = dyninf->bss_size = 0;
1809 #endif
1811 for(j = 0; j < 2; j++) {
1812 ph->p_type = PT_LOAD;
1813 if (j == 0)
1814 ph->p_flags = PF_R | PF_X;
1815 else
1816 ph->p_flags = PF_R | PF_W;
1817 ph->p_align = s1->section_align;
1819 /* Decide the layout of sections loaded in memory. This must
1820 be done before program headers are filled since they contain
1821 info about the layout. We do the following ordering: interp,
1822 symbol tables, relocations, progbits, nobits */
1823 /* XXX: do faster and simpler sorting */
1824 for(k = 0; k < 5; k++) {
1825 for(i = 1; i < s1->nb_sections; i++) {
1826 s = s1->sections[i];
1827 /* compute if section should be included */
1828 if (j == 0) {
1829 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1830 SHF_ALLOC)
1831 continue;
1832 } else {
1833 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1834 (SHF_ALLOC | SHF_WRITE))
1835 continue;
1837 if (s == interp) {
1838 if (k != 0)
1839 continue;
1840 } else if (s->sh_type == SHT_DYNSYM ||
1841 s->sh_type == SHT_STRTAB ||
1842 s->sh_type == SHT_HASH) {
1843 if (k != 1)
1844 continue;
1845 } else if (s->sh_type == SHT_RELX) {
1846 if (k != 2)
1847 continue;
1848 } else if (s->sh_type == SHT_NOBITS) {
1849 if (k != 4)
1850 continue;
1851 } else {
1852 if (k != 3)
1853 continue;
1855 sec_order[sh_order_index++] = i;
1857 /* section matches: we align it and add its size */
1858 tmp = addr;
1859 addr = (addr + s->sh_addralign - 1) &
1860 ~(s->sh_addralign - 1);
1861 file_offset += (int) ( addr - tmp );
1862 s->sh_offset = file_offset;
1863 s->sh_addr = addr;
1865 /* update program header infos */
1866 if (ph->p_offset == 0) {
1867 ph->p_offset = file_offset;
1868 ph->p_vaddr = addr;
1869 ph->p_paddr = ph->p_vaddr;
1871 /* update dynamic relocation infos */
1872 if (s->sh_type == SHT_RELX) {
1873 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1874 if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
1875 dyninf->rel_addr = addr;
1876 dyninf->rel_size += s->sh_size; /* XXX only first rel. */
1878 if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
1879 dyninf->bss_addr = addr;
1880 dyninf->bss_size = s->sh_size; /* XXX only first rel. */
1882 #else
1883 if (dyninf->rel_size == 0)
1884 dyninf->rel_addr = addr;
1885 dyninf->rel_size += s->sh_size;
1886 #endif
1888 addr += s->sh_size;
1889 if (s->sh_type != SHT_NOBITS)
1890 file_offset += s->sh_size;
1893 ph->p_filesz = file_offset - ph->p_offset;
1894 ph->p_memsz = addr - ph->p_vaddr;
1895 ph++;
1896 if (j == 0) {
1897 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1898 /* if in the middle of a page, we duplicate the page in
1899 memory so that one copy is RX and the other is RW */
1900 if ((addr & (s1->section_align - 1)) != 0)
1901 addr += s1->section_align;
1902 } else {
1903 addr = (addr + s1->section_align - 1) & ~(s1->section_align - 1);
1904 file_offset = (file_offset + s1->section_align - 1) &
1905 ~(s1->section_align - 1);
1911 /* all other sections come after */
1912 for(i = 1; i < s1->nb_sections; i++) {
1913 s = s1->sections[i];
1914 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1915 continue;
1916 sec_order[sh_order_index++] = i;
1918 file_offset = (file_offset + s->sh_addralign - 1) &
1919 ~(s->sh_addralign - 1);
1920 s->sh_offset = file_offset;
1921 if (s->sh_type != SHT_NOBITS)
1922 file_offset += s->sh_size;
1925 return file_offset;
1928 static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
1929 Section *dynamic)
1931 ElfW(Phdr) *ph;
1933 /* if interpreter, then add corresponding program header */
1934 if (interp) {
1935 ph = &phdr[0];
1937 if (HAVE_PHDR)
1939 int len = phnum * sizeof(ElfW(Phdr));
1941 ph->p_type = PT_PHDR;
1942 ph->p_offset = sizeof(ElfW(Ehdr));
1943 ph->p_vaddr = interp->sh_addr - len;
1944 ph->p_paddr = ph->p_vaddr;
1945 ph->p_filesz = ph->p_memsz = len;
1946 ph->p_flags = PF_R | PF_X;
1947 ph->p_align = 4; /* interp->sh_addralign; */
1948 ph++;
1951 ph->p_type = PT_INTERP;
1952 ph->p_offset = interp->sh_offset;
1953 ph->p_vaddr = interp->sh_addr;
1954 ph->p_paddr = ph->p_vaddr;
1955 ph->p_filesz = interp->sh_size;
1956 ph->p_memsz = interp->sh_size;
1957 ph->p_flags = PF_R;
1958 ph->p_align = interp->sh_addralign;
1961 /* if dynamic section, then add corresponding program header */
1962 if (dynamic) {
1963 ph = &phdr[phnum - 1];
1965 ph->p_type = PT_DYNAMIC;
1966 ph->p_offset = dynamic->sh_offset;
1967 ph->p_vaddr = dynamic->sh_addr;
1968 ph->p_paddr = ph->p_vaddr;
1969 ph->p_filesz = dynamic->sh_size;
1970 ph->p_memsz = dynamic->sh_size;
1971 ph->p_flags = PF_R | PF_W;
1972 ph->p_align = dynamic->sh_addralign;
1976 /* Fill the dynamic section with tags describing the address and size of
1977 sections */
1978 static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
1980 Section *dynamic;
1982 dynamic = dyninf->dynamic;
1984 /* put dynamic section entries */
1985 dynamic->data_offset = dyninf->dyn_rel_off;
1986 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1987 put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
1988 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1989 put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
1990 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1991 #ifdef TCC_TARGET_X86_64
1992 put_dt(dynamic, DT_RELA, dyninf->rel_addr);
1993 put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
1994 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
1995 #else
1996 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1997 put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
1998 put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
1999 put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
2000 put_dt(dynamic, DT_PLTREL, DT_REL);
2001 put_dt(dynamic, DT_REL, dyninf->bss_addr);
2002 put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
2003 #else
2004 put_dt(dynamic, DT_REL, dyninf->rel_addr);
2005 put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
2006 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
2007 #endif
2008 #endif
2009 if (s1->do_debug)
2010 put_dt(dynamic, DT_DEBUG, 0);
2011 put_dt(dynamic, DT_NULL, 0);
2014 /* Relocate remaining sections and symbols (that is those not related to
2015 dynamic linking) */
2016 static int final_sections_reloc(TCCState *s1)
2018 int i;
2019 Section *s;
2021 relocate_syms(s1, 0);
2023 if (s1->nb_errors != 0)
2024 return -1;
2026 /* relocate sections */
2027 /* XXX: ignore sections with allocated relocations ? */
2028 for(i = 1; i < s1->nb_sections; i++) {
2029 s = s1->sections[i];
2030 if (s->reloc && s != s1->got)
2031 relocate_section(s1, s);
2034 /* relocate relocation entries if the relocation tables are
2035 allocated in the executable */
2036 for(i = 1; i < s1->nb_sections; i++) {
2037 s = s1->sections[i];
2038 if ((s->sh_flags & SHF_ALLOC) &&
2039 s->sh_type == SHT_RELX) {
2040 relocate_rel(s1, s);
2043 return 0;
2046 /* Create an ELF file on disk.
2047 This function handle ELF specific layout requirements */
2048 static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
2049 int file_offset, int *sec_order)
2051 int i, shnum, offset, size, file_type;
2052 Section *s;
2053 ElfW(Ehdr) ehdr;
2054 ElfW(Shdr) shdr, *sh;
2056 file_type = s1->output_type;
2057 shnum = s1->nb_sections;
2059 memset(&ehdr, 0, sizeof(ehdr));
2061 if (phnum > 0) {
2062 ehdr.e_phentsize = sizeof(ElfW(Phdr));
2063 ehdr.e_phnum = phnum;
2064 ehdr.e_phoff = sizeof(ElfW(Ehdr));
2067 /* align to 4 */
2068 file_offset = (file_offset + 3) & -4;
2070 /* fill header */
2071 ehdr.e_ident[0] = ELFMAG0;
2072 ehdr.e_ident[1] = ELFMAG1;
2073 ehdr.e_ident[2] = ELFMAG2;
2074 ehdr.e_ident[3] = ELFMAG3;
2075 ehdr.e_ident[4] = ELFCLASSW;
2076 ehdr.e_ident[5] = ELFDATA2LSB;
2077 ehdr.e_ident[6] = EV_CURRENT;
2078 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2079 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
2080 #endif
2081 #ifdef TCC_TARGET_ARM
2082 #ifdef TCC_ARM_EABI
2083 ehdr.e_ident[EI_OSABI] = 0;
2084 ehdr.e_flags = EF_ARM_EABI_VER4;
2085 if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
2086 ehdr.e_flags |= EF_ARM_HASENTRY;
2087 if (s1->float_abi == ARM_HARD_FLOAT)
2088 ehdr.e_flags |= EF_ARM_VFP_FLOAT;
2089 else
2090 ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
2091 #else
2092 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
2093 #endif
2094 #endif
2095 switch(file_type) {
2096 default:
2097 case TCC_OUTPUT_EXE:
2098 ehdr.e_type = ET_EXEC;
2099 ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
2100 break;
2101 case TCC_OUTPUT_DLL:
2102 ehdr.e_type = ET_DYN;
2103 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
2104 break;
2105 case TCC_OUTPUT_OBJ:
2106 ehdr.e_type = ET_REL;
2107 break;
2109 ehdr.e_machine = EM_TCC_TARGET;
2110 ehdr.e_version = EV_CURRENT;
2111 ehdr.e_shoff = file_offset;
2112 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
2113 ehdr.e_shentsize = sizeof(ElfW(Shdr));
2114 ehdr.e_shnum = shnum;
2115 ehdr.e_shstrndx = shnum - 1;
2117 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
2118 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
2119 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
2121 sort_syms(s1, symtab_section);
2122 for(i = 1; i < s1->nb_sections; i++) {
2123 s = s1->sections[sec_order[i]];
2124 if (s->sh_type != SHT_NOBITS) {
2125 if (s->sh_type == SHT_DYNSYM)
2126 patch_dynsym_undef(s1, s);
2127 while (offset < s->sh_offset) {
2128 fputc(0, f);
2129 offset++;
2131 size = s->sh_size;
2132 fwrite(s->data, 1, size, f);
2133 offset += size;
2137 /* output section headers */
2138 while (offset < ehdr.e_shoff) {
2139 fputc(0, f);
2140 offset++;
2143 for(i = 0; i < s1->nb_sections; i++) {
2144 sh = &shdr;
2145 memset(sh, 0, sizeof(ElfW(Shdr)));
2146 s = s1->sections[i];
2147 if (s) {
2148 sh->sh_name = s->sh_name;
2149 sh->sh_type = s->sh_type;
2150 sh->sh_flags = s->sh_flags;
2151 sh->sh_entsize = s->sh_entsize;
2152 sh->sh_info = s->sh_info;
2153 if (s->link)
2154 sh->sh_link = s->link->sh_num;
2155 sh->sh_addralign = s->sh_addralign;
2156 sh->sh_addr = s->sh_addr;
2157 sh->sh_offset = s->sh_offset;
2158 sh->sh_size = s->sh_size;
2160 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2164 /* Write an elf, coff or "binary" file */
2165 static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
2166 ElfW(Phdr) *phdr, int file_offset, int *sec_order)
2168 int fd, mode, file_type;
2169 FILE *f;
2171 file_type = s1->output_type;
2172 if (file_type == TCC_OUTPUT_OBJ)
2173 mode = 0666;
2174 else
2175 mode = 0777;
2176 unlink(filename);
2177 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
2178 if (fd < 0) {
2179 tcc_error_noabort("could not write '%s'", filename);
2180 return -1;
2182 f = fdopen(fd, "wb");
2183 if (s1->verbose)
2184 printf("<- %s\n", filename);
2186 #ifdef TCC_TARGET_COFF
2187 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
2188 tcc_output_coff(s1, f);
2189 else
2190 #endif
2191 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
2192 tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
2193 else
2194 tcc_output_binary(s1, f, sec_order);
2195 fclose(f);
2197 return 0;
2200 /* Output an elf, coff or binary file */
2201 /* XXX: suppress unneeded sections */
2202 static int elf_output_file(TCCState *s1, const char *filename)
2204 int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
2205 struct dyn_inf dyninf;
2206 ElfW(Phdr) *phdr;
2207 ElfW(Sym) *sym;
2208 Section *strsec, *interp, *dynamic, *dynstr;
2210 file_type = s1->output_type;
2211 s1->nb_errors = 0;
2213 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2214 if (file_type != TCC_OUTPUT_OBJ) {
2215 tcc_add_runtime(s1);
2218 phdr = NULL;
2219 sec_order = NULL;
2220 interp = dynamic = dynstr = NULL; /* avoid warning */
2221 dyninf.dyn_rel_off = 0; /* avoid warning */
2223 if (file_type != TCC_OUTPUT_OBJ) {
2224 relocate_common_syms();
2226 tcc_add_linker_symbols(s1);
2228 if (!s1->static_link) {
2229 if (file_type == TCC_OUTPUT_EXE) {
2230 char *ptr;
2231 /* allow override the dynamic loader */
2232 const char *elfint = getenv("LD_SO");
2233 if (elfint == NULL)
2234 elfint = DEFAULT_ELFINTERP(s1);
2235 /* add interpreter section only if executable */
2236 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
2237 interp->sh_addralign = 1;
2238 ptr = section_ptr_add(interp, 1 + strlen(elfint));
2239 strcpy(ptr, elfint);
2242 /* add dynamic symbol table */
2243 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
2244 ".dynstr",
2245 ".hash", SHF_ALLOC);
2246 dynstr = s1->dynsym->link;
2248 /* add dynamic section */
2249 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
2250 SHF_ALLOC | SHF_WRITE);
2251 dynamic->link = dynstr;
2252 dynamic->sh_entsize = sizeof(ElfW(Dyn));
2254 /* add PLT */
2255 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
2256 SHF_ALLOC | SHF_EXECINSTR);
2257 s1->plt->sh_entsize = 4;
2259 build_got(s1);
2261 if (file_type == TCC_OUTPUT_EXE) {
2262 bind_exe_dynsyms(s1);
2264 if (s1->nb_errors) {
2265 ret = -1;
2266 goto the_end;
2269 bind_libs_dynsyms(s1);
2270 } else /* shared library case: simply export all global symbols */
2271 export_global_syms(s1);
2273 build_got_entries(s1);
2275 /* add a list of needed dlls */
2276 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2277 DLLReference *dllref = s1->loaded_dlls[i];
2278 if (dllref->level == 0)
2279 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
2282 if (s1->rpath)
2283 put_dt(dynamic, DT_RPATH, put_elf_str(dynstr, s1->rpath));
2285 /* XXX: currently, since we do not handle PIC code, we
2286 must relocate the readonly segments */
2287 if (file_type == TCC_OUTPUT_DLL) {
2288 if (s1->soname)
2289 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
2290 put_dt(dynamic, DT_TEXTREL, 0);
2293 if (s1->symbolic)
2294 put_dt(dynamic, DT_SYMBOLIC, 0);
2296 /* add necessary space for other entries */
2297 dyninf.dyn_rel_off = dynamic->data_offset;
2298 dynamic->data_offset += sizeof(ElfW(Dyn)) * EXTRA_RELITEMS;
2299 } else {
2300 /* still need to build got entries in case of static link */
2301 build_got_entries(s1);
2305 /* we add a section for symbols */
2306 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
2307 put_elf_str(strsec, "");
2309 /* compute number of sections */
2310 shnum = s1->nb_sections;
2312 /* this array is used to reorder sections in the output file */
2313 sec_order = tcc_malloc(sizeof(int) * shnum);
2314 sec_order[0] = 0;
2316 /* compute number of program headers */
2317 switch(file_type) {
2318 default:
2319 case TCC_OUTPUT_OBJ:
2320 phnum = 0;
2321 break;
2322 case TCC_OUTPUT_EXE:
2323 if (!s1->static_link)
2324 phnum = 4 + HAVE_PHDR;
2325 else
2326 phnum = 2;
2327 break;
2328 case TCC_OUTPUT_DLL:
2329 phnum = 3;
2330 break;
2333 /* Allocate strings for section names */
2334 alloc_sec_names(s1, file_type, strsec);
2336 /* allocate program segment headers */
2337 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
2339 /* compute section to program header mapping */
2340 file_offset = layout_sections(s1, phdr, phnum, interp, &dyninf, sec_order);
2342 /* Fill remaining program header and finalize relocation related to dynamic
2343 linking. */
2344 if (phnum > 0) {
2345 fill_unloadable_phdr(phdr, phnum, interp, dynamic);
2346 if (dynamic) {
2347 dyninf.dynamic = dynamic;
2348 dyninf.dynstr = dynstr;
2350 fill_dynamic(s1, &dyninf);
2352 /* put in GOT the dynamic section address and relocate PLT */
2353 put32(s1->got->data, dynamic->sh_addr);
2354 if (file_type == TCC_OUTPUT_EXE
2355 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
2356 || file_type == TCC_OUTPUT_DLL
2357 #endif
2359 relocate_plt(s1);
2361 /* relocate symbols in .dynsym now that final addresses are known */
2362 for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
2363 /* relocate to PLT if symbol corresponds to a PLT entry */
2364 if (sym->st_shndx == SHN_UNDEF) {
2365 if (sym->st_value)
2366 sym->st_value += s1->plt->sh_addr;
2367 } else if (sym->st_shndx < SHN_LORESERVE) {
2368 /* do symbol relocation */
2369 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
2375 /* if building executable or DLL, then relocate each section
2376 except the GOT which is already relocated */
2377 if (file_type != TCC_OUTPUT_OBJ) {
2378 ret = final_sections_reloc(s1);
2379 if (ret)
2380 goto the_end;
2383 /* Perform relocation to GOT or PLT entries */
2384 if (file_type == TCC_OUTPUT_EXE && s1->static_link)
2385 fill_got(s1);
2387 /* Create the ELF file with name 'filename' */
2388 ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
2389 the_end:
2390 tcc_free(s1->symtab_to_dynsym);
2391 tcc_free(sec_order);
2392 tcc_free(phdr);
2393 tcc_free(s1->sym_attrs);
2394 return ret;
2397 LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
2399 int ret;
2400 #ifdef TCC_TARGET_PE
2401 if (s->output_type != TCC_OUTPUT_OBJ) {
2402 ret = pe_output_file(s, filename);
2403 } else
2404 #endif
2405 ret = elf_output_file(s, filename);
2406 return ret;
2409 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2411 void *data;
2413 data = tcc_malloc(size);
2414 lseek(fd, file_offset, SEEK_SET);
2415 read(fd, data, size);
2416 return data;
2419 typedef struct SectionMergeInfo {
2420 Section *s; /* corresponding existing section */
2421 unsigned long offset; /* offset of the new section in the existing section */
2422 uint8_t new_section; /* true if section 's' was added */
2423 uint8_t link_once; /* true if link once section */
2424 } SectionMergeInfo;
2426 /* load an object file and merge it with current files */
2427 /* XXX: handle correctly stab (debug) info */
2428 ST_FUNC int tcc_load_object_file(TCCState *s1,
2429 int fd, unsigned long file_offset)
2431 ElfW(Ehdr) ehdr;
2432 ElfW(Shdr) *shdr, *sh;
2433 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2434 unsigned char *strsec, *strtab;
2435 int *old_to_new_syms;
2436 char *sh_name, *name;
2437 SectionMergeInfo *sm_table, *sm;
2438 ElfW(Sym) *sym, *symtab;
2439 ElfW_Rel *rel;
2440 Section *s;
2442 int stab_index;
2443 int stabstr_index;
2445 stab_index = stabstr_index = 0;
2447 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
2448 goto fail1;
2449 if (ehdr.e_ident[0] != ELFMAG0 ||
2450 ehdr.e_ident[1] != ELFMAG1 ||
2451 ehdr.e_ident[2] != ELFMAG2 ||
2452 ehdr.e_ident[3] != ELFMAG3)
2453 goto fail1;
2454 /* test if object file */
2455 if (ehdr.e_type != ET_REL)
2456 goto fail1;
2457 /* test CPU specific stuff */
2458 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2459 ehdr.e_machine != EM_TCC_TARGET) {
2460 fail1:
2461 tcc_error_noabort("invalid object file");
2462 return -1;
2464 /* read sections */
2465 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2466 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2467 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2469 /* load section names */
2470 sh = &shdr[ehdr.e_shstrndx];
2471 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2473 /* load symtab and strtab */
2474 old_to_new_syms = NULL;
2475 symtab = NULL;
2476 strtab = NULL;
2477 nb_syms = 0;
2478 for(i = 1; i < ehdr.e_shnum; i++) {
2479 sh = &shdr[i];
2480 if (sh->sh_type == SHT_SYMTAB) {
2481 if (symtab) {
2482 tcc_error_noabort("object must contain only one symtab");
2483 fail:
2484 ret = -1;
2485 goto the_end;
2487 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2488 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2489 sm_table[i].s = symtab_section;
2491 /* now load strtab */
2492 sh = &shdr[sh->sh_link];
2493 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2497 /* now examine each section and try to merge its content with the
2498 ones in memory */
2499 for(i = 1; i < ehdr.e_shnum; i++) {
2500 /* no need to examine section name strtab */
2501 if (i == ehdr.e_shstrndx)
2502 continue;
2503 sh = &shdr[i];
2504 sh_name = strsec + sh->sh_name;
2505 /* ignore sections types we do not handle */
2506 if (sh->sh_type != SHT_PROGBITS &&
2507 sh->sh_type != SHT_RELX &&
2508 #ifdef TCC_ARM_EABI
2509 sh->sh_type != SHT_ARM_EXIDX &&
2510 #endif
2511 sh->sh_type != SHT_NOBITS &&
2512 sh->sh_type != SHT_PREINIT_ARRAY &&
2513 sh->sh_type != SHT_INIT_ARRAY &&
2514 sh->sh_type != SHT_FINI_ARRAY &&
2515 strcmp(sh_name, ".stabstr")
2517 continue;
2518 if (sh->sh_addralign < 1)
2519 sh->sh_addralign = 1;
2520 /* find corresponding section, if any */
2521 for(j = 1; j < s1->nb_sections;j++) {
2522 s = s1->sections[j];
2523 if (!strcmp(s->name, sh_name)) {
2524 if (!strncmp(sh_name, ".gnu.linkonce",
2525 sizeof(".gnu.linkonce") - 1)) {
2526 /* if a 'linkonce' section is already present, we
2527 do not add it again. It is a little tricky as
2528 symbols can still be defined in
2529 it. */
2530 sm_table[i].link_once = 1;
2531 goto next;
2532 } else {
2533 goto found;
2537 /* not found: create new section */
2538 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
2539 /* take as much info as possible from the section. sh_link and
2540 sh_info will be updated later */
2541 s->sh_addralign = sh->sh_addralign;
2542 s->sh_entsize = sh->sh_entsize;
2543 sm_table[i].new_section = 1;
2544 found:
2545 if (sh->sh_type != s->sh_type) {
2546 tcc_error_noabort("invalid section type");
2547 goto fail;
2550 /* align start of section */
2551 offset = s->data_offset;
2553 if (0 == strcmp(sh_name, ".stab")) {
2554 stab_index = i;
2555 goto no_align;
2557 if (0 == strcmp(sh_name, ".stabstr")) {
2558 stabstr_index = i;
2559 goto no_align;
2562 size = sh->sh_addralign - 1;
2563 offset = (offset + size) & ~size;
2564 if (sh->sh_addralign > s->sh_addralign)
2565 s->sh_addralign = sh->sh_addralign;
2566 s->data_offset = offset;
2567 no_align:
2568 sm_table[i].offset = offset;
2569 sm_table[i].s = s;
2570 /* concatenate sections */
2571 size = sh->sh_size;
2572 if (sh->sh_type != SHT_NOBITS) {
2573 unsigned char *ptr;
2574 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2575 ptr = section_ptr_add(s, size);
2576 read(fd, ptr, size);
2577 } else {
2578 s->data_offset += size;
2580 next: ;
2583 /* gr relocate stab strings */
2584 if (stab_index && stabstr_index) {
2585 Stab_Sym *a, *b;
2586 unsigned o;
2587 s = sm_table[stab_index].s;
2588 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2589 b = (Stab_Sym *)(s->data + s->data_offset);
2590 o = sm_table[stabstr_index].offset;
2591 while (a < b)
2592 a->n_strx += o, a++;
2595 /* second short pass to update sh_link and sh_info fields of new
2596 sections */
2597 for(i = 1; i < ehdr.e_shnum; i++) {
2598 s = sm_table[i].s;
2599 if (!s || !sm_table[i].new_section)
2600 continue;
2601 sh = &shdr[i];
2602 if (sh->sh_link > 0)
2603 s->link = sm_table[sh->sh_link].s;
2604 if (sh->sh_type == SHT_RELX) {
2605 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2606 /* update backward link */
2607 s1->sections[s->sh_info]->reloc = s;
2610 sm = sm_table;
2612 /* resolve symbols */
2613 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2615 sym = symtab + 1;
2616 for(i = 1; i < nb_syms; i++, sym++) {
2617 if (sym->st_shndx != SHN_UNDEF &&
2618 sym->st_shndx < SHN_LORESERVE) {
2619 sm = &sm_table[sym->st_shndx];
2620 if (sm->link_once) {
2621 /* if a symbol is in a link once section, we use the
2622 already defined symbol. It is very important to get
2623 correct relocations */
2624 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2625 name = strtab + sym->st_name;
2626 sym_index = find_elf_sym(symtab_section, name);
2627 if (sym_index)
2628 old_to_new_syms[i] = sym_index;
2630 continue;
2632 /* if no corresponding section added, no need to add symbol */
2633 if (!sm->s)
2634 continue;
2635 /* convert section number */
2636 sym->st_shndx = sm->s->sh_num;
2637 /* offset value */
2638 sym->st_value += sm->offset;
2640 /* add symbol */
2641 name = strtab + sym->st_name;
2642 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
2643 sym->st_info, sym->st_other,
2644 sym->st_shndx, name);
2645 old_to_new_syms[i] = sym_index;
2648 /* third pass to patch relocation entries */
2649 for(i = 1; i < ehdr.e_shnum; i++) {
2650 s = sm_table[i].s;
2651 if (!s)
2652 continue;
2653 sh = &shdr[i];
2654 offset = sm_table[i].offset;
2655 switch(s->sh_type) {
2656 case SHT_RELX:
2657 /* take relocation offset information */
2658 offseti = sm_table[sh->sh_info].offset;
2659 for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
2660 int type;
2661 unsigned sym_index;
2662 /* convert symbol index */
2663 type = ELFW(R_TYPE)(rel->r_info);
2664 sym_index = ELFW(R_SYM)(rel->r_info);
2665 /* NOTE: only one symtab assumed */
2666 if (sym_index >= nb_syms)
2667 goto invalid_reloc;
2668 sym_index = old_to_new_syms[sym_index];
2669 /* ignore link_once in rel section. */
2670 if (!sym_index && !sm->link_once
2671 #ifdef TCC_TARGET_ARM
2672 && type != R_ARM_V4BX
2673 #endif
2675 invalid_reloc:
2676 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2677 i, strsec + sh->sh_name, rel->r_offset);
2678 goto fail;
2680 rel->r_info = ELFW(R_INFO)(sym_index, type);
2681 /* offset the relocation offset */
2682 rel->r_offset += offseti;
2683 #ifdef TCC_TARGET_ARM
2684 /* Jumps and branches from a Thumb code to a PLT entry need
2685 special handling since PLT entries are ARM code.
2686 Unconditional bl instructions referencing PLT entries are
2687 handled by converting these instructions into blx
2688 instructions. Other case of instructions referencing a PLT
2689 entry require to add a Thumb stub before the PLT entry to
2690 switch to ARM mode. We set bit plt_thumb_stub of the
2691 attribute of a symbol to indicate such a case. */
2692 if (type == R_ARM_THM_JUMP24)
2693 alloc_sym_attr(s1, sym_index)->plt_thumb_stub = 1;
2694 #endif
2696 break;
2697 default:
2698 break;
2702 ret = 0;
2703 the_end:
2704 tcc_free(symtab);
2705 tcc_free(strtab);
2706 tcc_free(old_to_new_syms);
2707 tcc_free(sm_table);
2708 tcc_free(strsec);
2709 tcc_free(shdr);
2710 return ret;
2713 typedef struct ArchiveHeader {
2714 char ar_name[16]; /* name of this member */
2715 char ar_date[12]; /* file mtime */
2716 char ar_uid[6]; /* owner uid; printed as decimal */
2717 char ar_gid[6]; /* owner gid; printed as decimal */
2718 char ar_mode[8]; /* file mode, printed as octal */
2719 char ar_size[10]; /* file size, printed as decimal */
2720 char ar_fmag[2]; /* should contain ARFMAG */
2721 } ArchiveHeader;
2723 static int get_be32(const uint8_t *b)
2725 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2728 /* load only the objects which resolve undefined symbols */
2729 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
2731 int i, bound, nsyms, sym_index, off, ret;
2732 uint8_t *data;
2733 const char *ar_names, *p;
2734 const uint8_t *ar_index;
2735 ElfW(Sym) *sym;
2737 data = tcc_malloc(size);
2738 if (read(fd, data, size) != size)
2739 goto fail;
2740 nsyms = get_be32(data);
2741 ar_index = data + 4;
2742 ar_names = ar_index + nsyms * 4;
2744 do {
2745 bound = 0;
2746 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2747 sym_index = find_elf_sym(symtab_section, p);
2748 if(sym_index) {
2749 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2750 if(sym->st_shndx == SHN_UNDEF) {
2751 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2752 ++bound;
2753 lseek(fd, off, SEEK_SET);
2754 if(tcc_load_object_file(s1, fd, off) < 0) {
2755 fail:
2756 ret = -1;
2757 goto the_end;
2762 } while(bound);
2763 ret = 0;
2764 the_end:
2765 tcc_free(data);
2766 return ret;
2769 /* load a '.a' file */
2770 ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
2772 ArchiveHeader hdr;
2773 char ar_size[11];
2774 char ar_name[17];
2775 char magic[8];
2776 int size, len, i;
2777 unsigned long file_offset;
2779 /* skip magic which was already checked */
2780 read(fd, magic, sizeof(magic));
2782 for(;;) {
2783 len = read(fd, &hdr, sizeof(hdr));
2784 if (len == 0)
2785 break;
2786 if (len != sizeof(hdr)) {
2787 tcc_error_noabort("invalid archive");
2788 return -1;
2790 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2791 ar_size[sizeof(hdr.ar_size)] = '\0';
2792 size = strtol(ar_size, NULL, 0);
2793 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2794 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2795 if (ar_name[i] != ' ')
2796 break;
2798 ar_name[i + 1] = '\0';
2799 file_offset = lseek(fd, 0, SEEK_CUR);
2800 /* align to even */
2801 size = (size + 1) & ~1;
2802 if (!strcmp(ar_name, "/")) {
2803 /* coff symbol table : we handle it */
2804 if(s1->alacarte_link)
2805 return tcc_load_alacarte(s1, fd, size);
2806 } else if (!strcmp(ar_name, "//") ||
2807 !strcmp(ar_name, "__.SYMDEF") ||
2808 !strcmp(ar_name, "__.SYMDEF/") ||
2809 !strcmp(ar_name, "ARFILENAMES/")) {
2810 /* skip symbol table or archive names */
2811 } else {
2812 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2813 return -1;
2815 lseek(fd, file_offset + size, SEEK_SET);
2817 return 0;
2820 #ifndef TCC_TARGET_PE
2821 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2822 is referenced by the user (so it should be added as DT_NEEDED in
2823 the generated ELF file) */
2824 ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2826 ElfW(Ehdr) ehdr;
2827 ElfW(Shdr) *shdr, *sh, *sh1;
2828 int i, j, nb_syms, nb_dts, sym_bind, ret;
2829 ElfW(Sym) *sym, *dynsym;
2830 ElfW(Dyn) *dt, *dynamic;
2831 unsigned char *dynstr;
2832 const char *name, *soname;
2833 DLLReference *dllref;
2835 read(fd, &ehdr, sizeof(ehdr));
2837 /* test CPU specific stuff */
2838 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2839 ehdr.e_machine != EM_TCC_TARGET) {
2840 tcc_error_noabort("bad architecture");
2841 return -1;
2844 /* read sections */
2845 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2847 /* load dynamic section and dynamic symbols */
2848 nb_syms = 0;
2849 nb_dts = 0;
2850 dynamic = NULL;
2851 dynsym = NULL; /* avoid warning */
2852 dynstr = NULL; /* avoid warning */
2853 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2854 switch(sh->sh_type) {
2855 case SHT_DYNAMIC:
2856 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2857 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2858 break;
2859 case SHT_DYNSYM:
2860 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2861 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2862 sh1 = &shdr[sh->sh_link];
2863 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2864 break;
2865 default:
2866 break;
2870 /* compute the real library name */
2871 soname = tcc_basename(filename);
2873 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2874 if (dt->d_tag == DT_SONAME) {
2875 soname = dynstr + dt->d_un.d_val;
2879 /* if the dll is already loaded, do not load it */
2880 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2881 dllref = s1->loaded_dlls[i];
2882 if (!strcmp(soname, dllref->name)) {
2883 /* but update level if needed */
2884 if (level < dllref->level)
2885 dllref->level = level;
2886 ret = 0;
2887 goto the_end;
2891 /* add the dll and its level */
2892 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2893 dllref->level = level;
2894 strcpy(dllref->name, soname);
2895 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2897 /* add dynamic symbols in dynsym_section */
2898 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2899 sym_bind = ELFW(ST_BIND)(sym->st_info);
2900 if (sym_bind == STB_LOCAL)
2901 continue;
2902 name = dynstr + sym->st_name;
2903 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2904 sym->st_info, sym->st_other, sym->st_shndx, name);
2907 /* load all referenced DLLs */
2908 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2909 switch(dt->d_tag) {
2910 case DT_NEEDED:
2911 name = dynstr + dt->d_un.d_val;
2912 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2913 dllref = s1->loaded_dlls[j];
2914 if (!strcmp(name, dllref->name))
2915 goto already_loaded;
2917 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2918 tcc_error_noabort("referenced dll '%s' not found", name);
2919 ret = -1;
2920 goto the_end;
2922 already_loaded:
2923 break;
2926 ret = 0;
2927 the_end:
2928 tcc_free(dynstr);
2929 tcc_free(dynsym);
2930 tcc_free(dynamic);
2931 tcc_free(shdr);
2932 return ret;
2935 #define LD_TOK_NAME 256
2936 #define LD_TOK_EOF (-1)
2938 /* return next ld script token */
2939 static int ld_next(TCCState *s1, char *name, int name_size)
2941 int c;
2942 char *q;
2944 redo:
2945 switch(ch) {
2946 case ' ':
2947 case '\t':
2948 case '\f':
2949 case '\v':
2950 case '\r':
2951 case '\n':
2952 inp();
2953 goto redo;
2954 case '/':
2955 minp();
2956 if (ch == '*') {
2957 file->buf_ptr = parse_comment(file->buf_ptr);
2958 ch = file->buf_ptr[0];
2959 goto redo;
2960 } else {
2961 q = name;
2962 *q++ = '/';
2963 goto parse_name;
2965 break;
2966 /* case 'a' ... 'z': */
2967 case 'a':
2968 case 'b':
2969 case 'c':
2970 case 'd':
2971 case 'e':
2972 case 'f':
2973 case 'g':
2974 case 'h':
2975 case 'i':
2976 case 'j':
2977 case 'k':
2978 case 'l':
2979 case 'm':
2980 case 'n':
2981 case 'o':
2982 case 'p':
2983 case 'q':
2984 case 'r':
2985 case 's':
2986 case 't':
2987 case 'u':
2988 case 'v':
2989 case 'w':
2990 case 'x':
2991 case 'y':
2992 case 'z':
2993 /* case 'A' ... 'z': */
2994 case 'A':
2995 case 'B':
2996 case 'C':
2997 case 'D':
2998 case 'E':
2999 case 'F':
3000 case 'G':
3001 case 'H':
3002 case 'I':
3003 case 'J':
3004 case 'K':
3005 case 'L':
3006 case 'M':
3007 case 'N':
3008 case 'O':
3009 case 'P':
3010 case 'Q':
3011 case 'R':
3012 case 'S':
3013 case 'T':
3014 case 'U':
3015 case 'V':
3016 case 'W':
3017 case 'X':
3018 case 'Y':
3019 case 'Z':
3020 case '_':
3021 case '\\':
3022 case '.':
3023 case '$':
3024 case '~':
3025 q = name;
3026 parse_name:
3027 for(;;) {
3028 if (!((ch >= 'a' && ch <= 'z') ||
3029 (ch >= 'A' && ch <= 'Z') ||
3030 (ch >= '0' && ch <= '9') ||
3031 strchr("/.-_+=$:\\,~", ch)))
3032 break;
3033 if ((q - name) < name_size - 1) {
3034 *q++ = ch;
3036 minp();
3038 *q = '\0';
3039 c = LD_TOK_NAME;
3040 break;
3041 case CH_EOF:
3042 c = LD_TOK_EOF;
3043 break;
3044 default:
3045 c = ch;
3046 inp();
3047 break;
3049 return c;
3052 static int ld_add_file(TCCState *s1, const char filename[])
3054 int ret;
3056 ret = tcc_add_file_internal(s1, filename, 0);
3057 if (ret)
3058 ret = tcc_add_dll(s1, filename, 0);
3059 return ret;
3062 static inline int new_undef_syms(void)
3064 int ret = 0;
3065 ret = new_undef_sym;
3066 new_undef_sym = 0;
3067 return ret;
3070 static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
3072 char filename[1024], libname[1024];
3073 int t, group, nblibs = 0, ret = 0;
3074 char **libs = NULL;
3076 group = !strcmp(cmd, "GROUP");
3077 if (!as_needed)
3078 new_undef_syms();
3079 t = ld_next(s1, filename, sizeof(filename));
3080 if (t != '(')
3081 expect("(");
3082 t = ld_next(s1, filename, sizeof(filename));
3083 for(;;) {
3084 libname[0] = '\0';
3085 if (t == LD_TOK_EOF) {
3086 tcc_error_noabort("unexpected end of file");
3087 ret = -1;
3088 goto lib_parse_error;
3089 } else if (t == ')') {
3090 break;
3091 } else if (t == '-') {
3092 t = ld_next(s1, filename, sizeof(filename));
3093 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3094 tcc_error_noabort("library name expected");
3095 ret = -1;
3096 goto lib_parse_error;
3098 pstrcpy(libname, sizeof libname, &filename[1]);
3099 if (s1->static_link) {
3100 snprintf(filename, sizeof filename, "lib%s.a", libname);
3101 } else {
3102 snprintf(filename, sizeof filename, "lib%s.so", libname);
3104 } else if (t != LD_TOK_NAME) {
3105 tcc_error_noabort("filename expected");
3106 ret = -1;
3107 goto lib_parse_error;
3109 if (!strcmp(filename, "AS_NEEDED")) {
3110 ret = ld_add_file_list(s1, cmd, 1);
3111 if (ret)
3112 goto lib_parse_error;
3113 } else {
3114 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3115 if (!as_needed) {
3116 ret = ld_add_file(s1, filename);
3117 if (ret)
3118 goto lib_parse_error;
3119 if (group) {
3120 /* Add the filename *and* the libname to avoid future conversions */
3121 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(filename));
3122 if (libname[0] != '\0')
3123 dynarray_add((void ***) &libs, &nblibs, tcc_strdup(libname));
3127 t = ld_next(s1, filename, sizeof(filename));
3128 if (t == ',') {
3129 t = ld_next(s1, filename, sizeof(filename));
3132 if (group && !as_needed) {
3133 while (new_undef_syms()) {
3134 int i;
3136 for (i = 0; i < nblibs; i ++)
3137 ld_add_file(s1, libs[i]);
3140 lib_parse_error:
3141 dynarray_reset(&libs, &nblibs);
3142 return ret;
3145 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3146 files */
3147 ST_FUNC int tcc_load_ldscript(TCCState *s1)
3149 char cmd[64];
3150 char filename[1024];
3151 int t, ret;
3153 ch = file->buf_ptr[0];
3154 ch = handle_eob();
3155 for(;;) {
3156 t = ld_next(s1, cmd, sizeof(cmd));
3157 if (t == LD_TOK_EOF)
3158 return 0;
3159 else if (t != LD_TOK_NAME)
3160 return -1;
3161 if (!strcmp(cmd, "INPUT") ||
3162 !strcmp(cmd, "GROUP")) {
3163 ret = ld_add_file_list(s1, cmd, 0);
3164 if (ret)
3165 return ret;
3166 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
3167 !strcmp(cmd, "TARGET")) {
3168 /* ignore some commands */
3169 t = ld_next(s1, cmd, sizeof(cmd));
3170 if (t != '(')
3171 expect("(");
3172 for(;;) {
3173 t = ld_next(s1, filename, sizeof(filename));
3174 if (t == LD_TOK_EOF) {
3175 tcc_error_noabort("unexpected end of file");
3176 return -1;
3177 } else if (t == ')') {
3178 break;
3181 } else {
3182 return -1;
3185 return 0;
3187 #endif /* !TCC_TARGET_PE */