get rid of 8 bytes memory leak
[tinycc.git] / tccelf.c
blob6a26831ba1ce651612d8d77590b5837bf7216be3
1 /*
2 * ELF file handling for TCC
3 *
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 #ifdef TCC_TARGET_X86_64
22 #define ElfW_Rel ElfW(Rela)
23 #define SHT_RELX SHT_RELA
24 #define REL_SECTION_FMT ".rela%s"
25 /* x86-64 requires PLT for DLLs */
26 #define TCC_OUTPUT_DLL_WITH_PLT
27 #else
28 #define ElfW_Rel ElfW(Rel)
29 #define SHT_RELX SHT_REL
30 #define REL_SECTION_FMT ".rel%s"
31 #endif
33 /* XXX: DLL with PLT would only work with x86-64 for now */
34 //#define TCC_OUTPUT_DLL_WITH_PLT
36 static int put_elf_str(Section *s, const char *sym)
38 int offset, len;
39 char *ptr;
41 len = strlen(sym) + 1;
42 offset = s->data_offset;
43 ptr = section_ptr_add(s, len);
44 memcpy(ptr, sym, len);
45 return offset;
48 /* elf symbol hashing function */
49 static unsigned long elf_hash(const unsigned char *name)
51 unsigned long h = 0, g;
53 while (*name) {
54 h = (h << 4) + *name++;
55 g = h & 0xf0000000;
56 if (g)
57 h ^= g >> 24;
58 h &= ~g;
60 return h;
63 /* rebuild hash table of section s */
64 /* NOTE: we do factorize the hash table code to go faster */
65 static void rebuild_hash(Section *s, unsigned int nb_buckets)
67 ElfW(Sym) *sym;
68 int *ptr, *hash, nb_syms, sym_index, h;
69 char *strtab;
71 strtab = s->link->data;
72 nb_syms = s->data_offset / sizeof(ElfW(Sym));
74 s->hash->data_offset = 0;
75 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
76 ptr[0] = nb_buckets;
77 ptr[1] = nb_syms;
78 ptr += 2;
79 hash = ptr;
80 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
81 ptr += nb_buckets + 1;
83 sym = (ElfW(Sym) *)s->data + 1;
84 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
85 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
86 h = elf_hash(strtab + sym->st_name) % nb_buckets;
87 *ptr = hash[h];
88 hash[h] = sym_index;
89 } else {
90 *ptr = 0;
92 ptr++;
93 sym++;
97 /* return the symbol number */
98 static int put_elf_sym(Section *s,
99 unsigned long value, unsigned long size,
100 int info, int other, int shndx, const char *name)
102 int name_offset, sym_index;
103 int nbuckets, h;
104 ElfW(Sym) *sym;
105 Section *hs;
107 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
108 if (name)
109 name_offset = put_elf_str(s->link, name);
110 else
111 name_offset = 0;
112 /* XXX: endianness */
113 sym->st_name = name_offset;
114 sym->st_value = value;
115 sym->st_size = size;
116 sym->st_info = info;
117 sym->st_other = other;
118 sym->st_shndx = shndx;
119 sym_index = sym - (ElfW(Sym) *)s->data;
120 hs = s->hash;
121 if (hs) {
122 int *ptr, *base;
123 ptr = section_ptr_add(hs, sizeof(int));
124 base = (int *)hs->data;
125 /* only add global or weak symbols */
126 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
127 /* add another hashing entry */
128 nbuckets = base[0];
129 h = elf_hash(name) % nbuckets;
130 *ptr = base[2 + h];
131 base[2 + h] = sym_index;
132 base[1]++;
133 /* we resize the hash table */
134 hs->nb_hashed_syms++;
135 if (hs->nb_hashed_syms > 2 * nbuckets) {
136 rebuild_hash(s, 2 * nbuckets);
138 } else {
139 *ptr = 0;
140 base[1]++;
143 return sym_index;
146 /* find global ELF symbol 'name' and return its index. Return 0 if not
147 found. */
148 static int find_elf_sym(Section *s, const char *name)
150 ElfW(Sym) *sym;
151 Section *hs;
152 int nbuckets, sym_index, h;
153 const char *name1;
155 hs = s->hash;
156 if (!hs)
157 return 0;
158 nbuckets = ((int *)hs->data)[0];
159 h = elf_hash(name) % nbuckets;
160 sym_index = ((int *)hs->data)[2 + h];
161 while (sym_index != 0) {
162 sym = &((ElfW(Sym) *)s->data)[sym_index];
163 name1 = s->link->data + sym->st_name;
164 if (!strcmp(name, name1))
165 return sym_index;
166 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
168 return 0;
171 /* return elf symbol value or error */
172 void *tcc_get_symbol(TCCState *s, const char *name)
174 int sym_index;
175 ElfW(Sym) *sym;
176 sym_index = find_elf_sym(symtab_section, name);
177 if (!sym_index)
178 return NULL;
179 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
180 return (void*)sym->st_value;
183 void *tcc_get_symbol_err(TCCState *s, const char *name)
185 void *sym;
186 sym = tcc_get_symbol(s, name);
187 if (!sym)
188 error("%s not defined", name);
189 return sym;
192 /* add an elf symbol : check if it is already defined and patch
193 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
194 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
195 int info, int other, int sh_num, const char *name)
197 ElfW(Sym) *esym;
198 int sym_bind, sym_index, sym_type, esym_bind;
199 unsigned char sym_vis, esym_vis, new_vis;
201 sym_bind = ELFW(ST_BIND)(info);
202 sym_type = ELFW(ST_TYPE)(info);
203 sym_vis = ELFW(ST_VISIBILITY)(other);
205 if (sym_bind != STB_LOCAL) {
206 /* we search global or weak symbols */
207 sym_index = find_elf_sym(s, name);
208 if (!sym_index)
209 goto do_def;
210 esym = &((ElfW(Sym) *)s->data)[sym_index];
211 if (esym->st_shndx != SHN_UNDEF) {
212 esym_bind = ELFW(ST_BIND)(esym->st_info);
213 /* propagate the most constraining visibility */
214 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
215 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
216 if (esym_vis == STV_DEFAULT) {
217 new_vis = sym_vis;
218 } else if (sym_vis == STV_DEFAULT) {
219 new_vis = esym_vis;
220 } else {
221 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
223 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
224 | new_vis;
225 other = esym->st_other; /* in case we have to patch esym */
226 if (sh_num == SHN_UNDEF) {
227 /* ignore adding of undefined symbol if the
228 corresponding symbol is already defined */
229 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
230 /* global overrides weak, so patch */
231 goto do_patch;
232 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
233 /* weak is ignored if already global */
234 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
235 /* ignore hidden symbols after */
236 } else if (esym->st_shndx == SHN_COMMON && sh_num < SHN_LORESERVE) {
237 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
238 No idea if this is the correct solution ... */
239 goto do_patch;
240 } else if (s == tcc_state->dynsymtab_section) {
241 /* we accept that two DLL define the same symbol */
242 } else {
243 #if 1
244 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
245 sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
246 #endif
247 error_noabort("'%s' defined twice", name);
249 } else {
250 do_patch:
251 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
252 esym->st_shndx = sh_num;
253 esym->st_value = value;
254 esym->st_size = size;
255 esym->st_other = other;
257 } else {
258 do_def:
259 sym_index = put_elf_sym(s, value, size,
260 ELFW(ST_INFO)(sym_bind, sym_type), other,
261 sh_num, name);
263 return sym_index;
266 /* put relocation */
267 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
268 int type, int symbol)
270 char buf[256];
271 Section *sr;
272 ElfW_Rel *rel;
274 sr = s->reloc;
275 if (!sr) {
276 /* if no relocation section, create it */
277 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
278 /* if the symtab is allocated, then we consider the relocation
279 are also */
280 sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
281 sr->sh_entsize = sizeof(ElfW_Rel);
282 sr->link = symtab;
283 sr->sh_info = s->sh_num;
284 s->reloc = sr;
286 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
287 rel->r_offset = offset;
288 rel->r_info = ELFW(R_INFO)(symbol, type);
289 #ifdef TCC_TARGET_X86_64
290 rel->r_addend = 0;
291 #endif
294 /* put stab debug information */
296 typedef struct {
297 unsigned int n_strx; /* index into string table of name */
298 unsigned char n_type; /* type of symbol */
299 unsigned char n_other; /* misc info (usually empty) */
300 unsigned short n_desc; /* description field */
301 unsigned int n_value; /* value of symbol */
302 } Stab_Sym;
304 static void put_stabs(const char *str, int type, int other, int desc,
305 unsigned long value)
307 Stab_Sym *sym;
309 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
310 if (str) {
311 sym->n_strx = put_elf_str(stabstr_section, str);
312 } else {
313 sym->n_strx = 0;
315 sym->n_type = type;
316 sym->n_other = other;
317 sym->n_desc = desc;
318 sym->n_value = value;
321 static void put_stabs_r(const char *str, int type, int other, int desc,
322 unsigned long value, Section *sec, int sym_index)
324 put_stabs(str, type, other, desc, value);
325 put_elf_reloc(symtab_section, stab_section,
326 stab_section->data_offset - sizeof(unsigned int),
327 R_DATA_32, sym_index);
330 static void put_stabn(int type, int other, int desc, int value)
332 put_stabs(NULL, type, other, desc, value);
335 static void put_stabd(int type, int other, int desc)
337 put_stabs(NULL, type, other, desc, 0);
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, *rel_end;
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 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
390 for(rel = (ElfW_Rel *)sr->data;
391 rel < rel_end;
392 rel++) {
393 sym_index = ELFW(R_SYM)(rel->r_info);
394 type = ELFW(R_TYPE)(rel->r_info);
395 sym_index = old_to_new_syms[sym_index];
396 rel->r_info = ELFW(R_INFO)(sym_index, type);
401 tcc_free(old_to_new_syms);
404 /* relocate common symbols in the .bss section */
405 static void relocate_common_syms(void)
407 ElfW(Sym) *sym, *sym_end;
408 unsigned long offset, align;
410 sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
411 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
412 sym < sym_end;
413 sym++) {
414 if (sym->st_shndx == SHN_COMMON) {
415 /* align symbol */
416 align = sym->st_value;
417 offset = bss_section->data_offset;
418 offset = (offset + align - 1) & -align;
419 sym->st_value = offset;
420 sym->st_shndx = bss_section->sh_num;
421 offset += sym->st_size;
422 bss_section->data_offset = offset;
427 /* relocate symbol table, resolve undefined symbols if do_resolve is
428 true and output error if undefined symbol. */
429 static void relocate_syms(TCCState *s1, int do_resolve)
431 ElfW(Sym) *sym, *esym, *sym_end;
432 int sym_bind, sh_num, sym_index;
433 const char *name;
434 unsigned long addr;
436 sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
437 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
438 sym < sym_end;
439 sym++) {
440 sh_num = sym->st_shndx;
441 if (sh_num == SHN_UNDEF) {
442 name = strtab_section->data + sym->st_name;
443 if (do_resolve) {
444 name = symtab_section->link->data + sym->st_name;
445 addr = (unsigned long)resolve_sym(s1, name, ELFW(ST_TYPE)(sym->st_info));
446 if (addr) {
447 sym->st_value = addr;
448 goto found;
450 } else if (s1->dynsym) {
451 /* if dynamic symbol exist, then use it */
452 sym_index = find_elf_sym(s1->dynsym, name);
453 if (sym_index) {
454 esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
455 sym->st_value = esym->st_value;
456 goto found;
459 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
460 it */
461 if (!strcmp(name, "_fp_hw"))
462 goto found;
463 /* only weak symbols are accepted to be undefined. Their
464 value is zero */
465 sym_bind = ELFW(ST_BIND)(sym->st_info);
466 if (sym_bind == STB_WEAK) {
467 sym->st_value = 0;
468 } else {
469 error_noabort("undefined symbol '%s'", name);
471 } else if (sh_num < SHN_LORESERVE) {
472 /* add section base */
473 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
475 found: ;
479 #ifdef TCC_TARGET_X86_64
480 #define JMP_TABLE_ENTRY_SIZE 14
481 static unsigned long add_jmp_table(TCCState *s1, unsigned long val)
483 char *p = (char *)section_ptr_add(text_section, JMP_TABLE_ENTRY_SIZE);
484 /* jmp *0x0(%rip) */
485 p[0] = 0xff;
486 p[1] = 0x25;
487 *(int *)(p + 2) = 0;
488 *(unsigned long *)(p + 6) = val;
489 return (unsigned long)p;
492 static unsigned long add_got_table(TCCState *s1, unsigned long val)
494 unsigned long *p =
495 (unsigned long *)section_ptr_add(text_section, sizeof(void *));
496 *p = val;
497 return (unsigned long)p;
499 #endif
501 /* relocate a given section (CPU dependent) */
502 static void relocate_section(TCCState *s1, Section *s)
504 Section *sr;
505 ElfW_Rel *rel, *rel_end, *qrel;
506 ElfW(Sym) *sym;
507 int type, sym_index;
508 unsigned char *ptr;
509 unsigned long val, addr;
510 int esym_index;
512 sr = s->reloc;
513 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
514 qrel = (ElfW_Rel *)sr->data;
515 for(rel = qrel;
516 rel < rel_end;
517 rel++) {
518 ptr = s->data + rel->r_offset;
520 sym_index = ELFW(R_SYM)(rel->r_info);
521 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
522 val = sym->st_value;
523 #ifdef TCC_TARGET_X86_64
524 /* XXX: not tested */
525 val += rel->r_addend;
526 #endif
527 type = ELFW(R_TYPE)(rel->r_info);
528 addr = s->sh_addr + rel->r_offset;
530 /* CPU specific */
531 switch(type) {
532 #if defined(TCC_TARGET_I386)
533 case R_386_32:
534 if (s1->output_type == TCC_OUTPUT_DLL) {
535 esym_index = s1->symtab_to_dynsym[sym_index];
536 qrel->r_offset = rel->r_offset;
537 if (esym_index) {
538 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
539 qrel++;
540 break;
541 } else {
542 qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
543 qrel++;
546 *(int *)ptr += val;
547 break;
548 case R_386_PC32:
549 if (s1->output_type == TCC_OUTPUT_DLL) {
550 /* DLL relocation */
551 esym_index = s1->symtab_to_dynsym[sym_index];
552 if (esym_index) {
553 qrel->r_offset = rel->r_offset;
554 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
555 qrel++;
556 break;
559 *(int *)ptr += val - addr;
560 break;
561 case R_386_PLT32:
562 *(int *)ptr += val - addr;
563 break;
564 case R_386_GLOB_DAT:
565 case R_386_JMP_SLOT:
566 *(int *)ptr = val;
567 break;
568 case R_386_GOTPC:
569 *(int *)ptr += s1->got->sh_addr - addr;
570 break;
571 case R_386_GOTOFF:
572 *(int *)ptr += val - s1->got->sh_addr;
573 break;
574 case R_386_GOT32:
575 /* we load the got offset */
576 *(int *)ptr += s1->got_offsets[sym_index];
577 break;
578 #elif defined(TCC_TARGET_ARM)
579 case R_ARM_PC24:
580 case R_ARM_CALL:
581 case R_ARM_JUMP24:
582 case R_ARM_PLT32:
584 int x;
585 x = (*(int *)ptr)&0xffffff;
586 (*(int *)ptr) &= 0xff000000;
587 if (x & 0x800000)
588 x -= 0x1000000;
589 x *= 4;
590 x += val - addr;
591 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
592 error("can't relocate value at %x",addr);
593 x >>= 2;
594 x &= 0xffffff;
595 (*(int *)ptr) |= x;
597 break;
598 case R_ARM_PREL31:
600 int x;
601 x = (*(int *)ptr) & 0x7fffffff;
602 (*(int *)ptr) &= 0x80000000;
603 x = (x * 2) / 2;
604 x += val - addr;
605 if((x^(x>>1))&0x40000000)
606 error("can't relocate value at %x",addr);
607 (*(int *)ptr) |= x & 0x7fffffff;
609 case R_ARM_ABS32:
610 *(int *)ptr += val;
611 break;
612 case R_ARM_BASE_PREL:
613 *(int *)ptr += s1->got->sh_addr - addr;
614 break;
615 case R_ARM_GOTOFF32:
616 *(int *)ptr += val - s1->got->sh_addr;
617 break;
618 case R_ARM_GOT_BREL:
619 /* we load the got offset */
620 *(int *)ptr += s1->got_offsets[sym_index];
621 break;
622 case R_ARM_COPY:
623 break;
624 default:
625 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
626 type,addr,(unsigned int )ptr,val);
627 break;
628 #elif defined(TCC_TARGET_C67)
629 case R_C60_32:
630 *(int *)ptr += val;
631 break;
632 case R_C60LO16:
634 uint32_t orig;
636 /* put the low 16 bits of the absolute address */
637 // add to what is already there
639 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
640 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
642 //patch both at once - assumes always in pairs Low - High
644 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
645 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
647 break;
648 case R_C60HI16:
649 break;
650 default:
651 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
652 type,addr,(unsigned int )ptr,val);
653 break;
654 #elif defined(TCC_TARGET_X86_64)
655 case R_X86_64_64:
656 if (s1->output_type == TCC_OUTPUT_DLL) {
657 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
658 qrel->r_addend = *(long long *)ptr + val;
659 qrel++;
661 *(long long *)ptr += val;
662 break;
663 case R_X86_64_32:
664 case R_X86_64_32S:
665 if (s1->output_type == TCC_OUTPUT_DLL) {
666 /* XXX: this logic may depend on TCC's codegen
667 now TCC uses R_X86_64_32 even for a 64bit pointer */
668 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
669 qrel->r_addend = *(int *)ptr + val;
670 qrel++;
672 *(int *)ptr += val;
673 break;
674 case R_X86_64_PC32: {
675 if (s1->output_type == TCC_OUTPUT_DLL) {
676 /* DLL relocation */
677 esym_index = s1->symtab_to_dynsym[sym_index];
678 if (esym_index) {
679 qrel->r_offset = rel->r_offset;
680 qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
681 qrel->r_addend = *(int *)ptr;
682 qrel++;
683 break;
686 long diff = val - addr;
687 if (diff <= -2147483647 || diff > 2147483647) {
688 /* XXX: naive support for over 32bit jump */
689 if (s1->output_type == TCC_OUTPUT_MEMORY) {
690 val = add_jmp_table(s1, val);
691 diff = val - addr;
693 if (diff <= -2147483647 || diff > 2147483647) {
694 error("internal error: relocation failed");
697 *(int *)ptr += diff;
699 break;
700 case R_X86_64_PLT32:
701 *(int *)ptr += val - addr;
702 break;
703 case R_X86_64_GLOB_DAT:
704 case R_X86_64_JUMP_SLOT:
705 *(int *)ptr = val;
706 break;
707 case R_X86_64_GOTPCREL:
708 if (s1->output_type == TCC_OUTPUT_MEMORY) {
709 val = add_got_table(s1, val - rel->r_addend) + rel->r_addend;
710 *(int *)ptr += val - addr;
711 break;
713 *(int *)ptr += (s1->got->sh_addr - addr +
714 s1->got_offsets[sym_index] - 4);
715 break;
716 case R_X86_64_GOTTPOFF:
717 *(int *)ptr += val - s1->got->sh_addr;
718 break;
719 case R_X86_64_GOT32:
720 /* we load the got offset */
721 *(int *)ptr += s1->got_offsets[sym_index];
722 break;
723 #else
724 #error unsupported processor
725 #endif
728 /* if the relocation is allocated, we change its symbol table */
729 if (sr->sh_flags & SHF_ALLOC)
730 sr->link = s1->dynsym;
733 /* relocate relocation table in 'sr' */
734 static void relocate_rel(TCCState *s1, Section *sr)
736 Section *s;
737 ElfW_Rel *rel, *rel_end;
739 s = s1->sections[sr->sh_info];
740 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
741 for(rel = (ElfW_Rel *)sr->data;
742 rel < rel_end;
743 rel++) {
744 rel->r_offset += s->sh_addr;
748 /* count the number of dynamic relocations so that we can reserve
749 their space */
750 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
752 ElfW_Rel *rel, *rel_end;
753 int sym_index, esym_index, type, count;
755 count = 0;
756 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
757 for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
758 sym_index = ELFW(R_SYM)(rel->r_info);
759 type = ELFW(R_TYPE)(rel->r_info);
760 switch(type) {
761 #if defined(TCC_TARGET_I386)
762 case R_386_32:
763 #elif defined(TCC_TARGET_X86_64)
764 case R_X86_64_32:
765 case R_X86_64_32S:
766 case R_X86_64_64:
767 #endif
768 count++;
769 break;
770 #if defined(TCC_TARGET_I386)
771 case R_386_PC32:
772 #elif defined(TCC_TARGET_X86_64)
773 case R_X86_64_PC32:
774 #endif
775 esym_index = s1->symtab_to_dynsym[sym_index];
776 if (esym_index)
777 count++;
778 break;
779 default:
780 break;
783 if (count) {
784 /* allocate the section */
785 sr->sh_flags |= SHF_ALLOC;
786 sr->sh_size = count * sizeof(ElfW_Rel);
788 return count;
791 static void put_got_offset(TCCState *s1, int index, unsigned long val)
793 int n;
794 unsigned long *tab;
796 if (index >= s1->nb_got_offsets) {
797 /* find immediately bigger power of 2 and reallocate array */
798 n = 1;
799 while (index >= n)
800 n *= 2;
801 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
802 if (!tab)
803 error("memory full");
804 s1->got_offsets = tab;
805 memset(s1->got_offsets + s1->nb_got_offsets, 0,
806 (n - s1->nb_got_offsets) * sizeof(unsigned long));
807 s1->nb_got_offsets = n;
809 s1->got_offsets[index] = val;
812 /* XXX: suppress that */
813 static void put32(unsigned char *p, uint32_t val)
815 p[0] = val;
816 p[1] = val >> 8;
817 p[2] = val >> 16;
818 p[3] = val >> 24;
821 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
822 defined(TCC_TARGET_X86_64)
823 static uint32_t get32(unsigned char *p)
825 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
827 #endif
829 static void build_got(TCCState *s1)
831 unsigned char *ptr;
833 /* if no got, then create it */
834 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
835 s1->got->sh_entsize = 4;
836 add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
837 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
838 ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
839 #if PTR_SIZE == 4
840 /* keep space for _DYNAMIC pointer, if present */
841 put32(ptr, 0);
842 /* two dummy got entries */
843 put32(ptr + 4, 0);
844 put32(ptr + 8, 0);
845 #else
846 /* keep space for _DYNAMIC pointer, if present */
847 put32(ptr, 0);
848 put32(ptr + 4, 0);
849 /* two dummy got entries */
850 put32(ptr + 8, 0);
851 put32(ptr + 12, 0);
852 put32(ptr + 16, 0);
853 put32(ptr + 20, 0);
854 #endif
857 /* put a got entry corresponding to a symbol in symtab_section. 'size'
858 and 'info' can be modifed if more precise info comes from the DLL */
859 static void put_got_entry(TCCState *s1,
860 int reloc_type, unsigned long size, int info,
861 int sym_index)
863 int index;
864 const char *name;
865 ElfW(Sym) *sym;
866 unsigned long offset;
867 int *ptr;
869 if (!s1->got)
870 build_got(s1);
872 /* if a got entry already exists for that symbol, no need to add one */
873 if (sym_index < s1->nb_got_offsets &&
874 s1->got_offsets[sym_index] != 0)
875 return;
877 put_got_offset(s1, sym_index, s1->got->data_offset);
879 if (s1->dynsym) {
880 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
881 name = symtab_section->link->data + sym->st_name;
882 offset = sym->st_value;
883 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
884 if (reloc_type ==
885 #ifdef TCC_TARGET_X86_64
886 R_X86_64_JUMP_SLOT
887 #else
888 R_386_JMP_SLOT
889 #endif
891 Section *plt;
892 uint8_t *p;
893 int modrm;
895 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
896 modrm = 0x25;
897 #else
898 /* if we build a DLL, we add a %ebx offset */
899 if (s1->output_type == TCC_OUTPUT_DLL)
900 modrm = 0xa3;
901 else
902 modrm = 0x25;
903 #endif
905 /* add a PLT entry */
906 plt = s1->plt;
907 if (plt->data_offset == 0) {
908 /* first plt entry */
909 p = section_ptr_add(plt, 16);
910 p[0] = 0xff; /* pushl got + PTR_SIZE */
911 p[1] = modrm + 0x10;
912 put32(p + 2, PTR_SIZE);
913 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
914 p[7] = modrm;
915 put32(p + 8, PTR_SIZE * 2);
918 p = section_ptr_add(plt, 16);
919 p[0] = 0xff; /* jmp *(got + x) */
920 p[1] = modrm;
921 put32(p + 2, s1->got->data_offset);
922 p[6] = 0x68; /* push $xxx */
923 put32(p + 7, (plt->data_offset - 32) >> 1);
924 p[11] = 0xe9; /* jmp plt_start */
925 put32(p + 12, -(plt->data_offset));
927 /* the symbol is modified so that it will be relocated to
928 the PLT */
929 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
930 if (s1->output_type == TCC_OUTPUT_EXE)
931 #endif
932 offset = plt->data_offset - 16;
934 #elif defined(TCC_TARGET_ARM)
935 if (reloc_type == R_ARM_JUMP_SLOT) {
936 Section *plt;
937 uint8_t *p;
939 /* if we build a DLL, we add a %ebx offset */
940 if (s1->output_type == TCC_OUTPUT_DLL)
941 error("DLLs unimplemented!");
943 /* add a PLT entry */
944 plt = s1->plt;
945 if (plt->data_offset == 0) {
946 /* first plt entry */
947 p = section_ptr_add(plt, 16);
948 put32(p , 0xe52de004);
949 put32(p + 4, 0xe59fe010);
950 put32(p + 8, 0xe08fe00e);
951 put32(p + 12, 0xe5bef008);
954 p = section_ptr_add(plt, 16);
955 put32(p , 0xe59fc004);
956 put32(p+4, 0xe08fc00c);
957 put32(p+8, 0xe59cf000);
958 put32(p+12, s1->got->data_offset);
960 /* the symbol is modified so that it will be relocated to
961 the PLT */
962 if (s1->output_type == TCC_OUTPUT_EXE)
963 offset = plt->data_offset - 16;
965 #elif defined(TCC_TARGET_C67)
966 error("C67 got not implemented");
967 #else
968 #error unsupported CPU
969 #endif
970 index = put_elf_sym(s1->dynsym, offset,
971 size, info, 0, sym->st_shndx, name);
972 /* put a got entry */
973 put_elf_reloc(s1->dynsym, s1->got,
974 s1->got->data_offset,
975 reloc_type, index);
977 ptr = section_ptr_add(s1->got, PTR_SIZE);
978 *ptr = 0;
981 /* build GOT and PLT entries */
982 static void build_got_entries(TCCState *s1)
984 Section *s, *symtab;
985 ElfW_Rel *rel, *rel_end;
986 ElfW(Sym) *sym;
987 int i, type, reloc_type, sym_index;
989 for(i = 1; i < s1->nb_sections; i++) {
990 s = s1->sections[i];
991 if (s->sh_type != SHT_RELX)
992 continue;
993 /* no need to handle got relocations */
994 if (s->link != symtab_section)
995 continue;
996 symtab = s->link;
997 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
998 for(rel = (ElfW_Rel *)s->data;
999 rel < rel_end;
1000 rel++) {
1001 type = ELFW(R_TYPE)(rel->r_info);
1002 switch(type) {
1003 #if defined(TCC_TARGET_I386)
1004 case R_386_GOT32:
1005 case R_386_GOTOFF:
1006 case R_386_GOTPC:
1007 case R_386_PLT32:
1008 if (!s1->got)
1009 build_got(s1);
1010 if (type == R_386_GOT32 || type == R_386_PLT32) {
1011 sym_index = ELFW(R_SYM)(rel->r_info);
1012 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1013 /* look at the symbol got offset. If none, then add one */
1014 if (type == R_386_GOT32)
1015 reloc_type = R_386_GLOB_DAT;
1016 else
1017 reloc_type = R_386_JMP_SLOT;
1018 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1019 sym_index);
1021 break;
1022 #elif defined(TCC_TARGET_ARM)
1023 case R_ARM_GOT_BREL:
1024 case R_ARM_GOTOFF32:
1025 case R_ARM_BASE_PREL:
1026 case R_ARM_PLT32:
1027 if (!s1->got)
1028 build_got(s1);
1029 if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) {
1030 sym_index = ELFW(R_SYM)(rel->r_info);
1031 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1032 /* look at the symbol got offset. If none, then add one */
1033 if (type == R_ARM_GOT_BREL)
1034 reloc_type = R_ARM_GLOB_DAT;
1035 else
1036 reloc_type = R_ARM_JUMP_SLOT;
1037 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1038 sym_index);
1040 break;
1041 #elif defined(TCC_TARGET_C67)
1042 case R_C60_GOT32:
1043 case R_C60_GOTOFF:
1044 case R_C60_GOTPC:
1045 case R_C60_PLT32:
1046 if (!s1->got)
1047 build_got(s1);
1048 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
1049 sym_index = ELFW(R_SYM)(rel->r_info);
1050 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1051 /* look at the symbol got offset. If none, then add one */
1052 if (type == R_C60_GOT32)
1053 reloc_type = R_C60_GLOB_DAT;
1054 else
1055 reloc_type = R_C60_JMP_SLOT;
1056 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1057 sym_index);
1059 break;
1060 #elif defined(TCC_TARGET_X86_64)
1061 case R_X86_64_GOT32:
1062 case R_X86_64_GOTTPOFF:
1063 case R_X86_64_GOTPCREL:
1064 case R_X86_64_PLT32:
1065 if (!s1->got)
1066 build_got(s1);
1067 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
1068 type == R_X86_64_PLT32) {
1069 sym_index = ELFW(R_SYM)(rel->r_info);
1070 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1071 /* look at the symbol got offset. If none, then add one */
1072 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL)
1073 reloc_type = R_X86_64_GLOB_DAT;
1074 else
1075 reloc_type = R_X86_64_JUMP_SLOT;
1076 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1077 sym_index);
1079 break;
1080 #else
1081 #error unsupported CPU
1082 #endif
1083 default:
1084 break;
1090 static Section *new_symtab(TCCState *s1,
1091 const char *symtab_name, int sh_type, int sh_flags,
1092 const char *strtab_name,
1093 const char *hash_name, int hash_sh_flags)
1095 Section *symtab, *strtab, *hash;
1096 int *ptr, nb_buckets;
1098 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1099 symtab->sh_entsize = sizeof(ElfW(Sym));
1100 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1101 put_elf_str(strtab, "");
1102 symtab->link = strtab;
1103 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1105 nb_buckets = 1;
1107 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1108 hash->sh_entsize = sizeof(int);
1109 symtab->hash = hash;
1110 hash->link = symtab;
1112 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1113 ptr[0] = nb_buckets;
1114 ptr[1] = 1;
1115 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1116 return symtab;
1119 /* put dynamic tag */
1120 static void put_dt(Section *dynamic, int dt, unsigned long val)
1122 ElfW(Dyn) *dyn;
1123 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1124 dyn->d_tag = dt;
1125 dyn->d_un.d_val = val;
1128 static void add_init_array_defines(TCCState *s1, const char *section_name)
1130 Section *s;
1131 long end_offset;
1132 char sym_start[1024];
1133 char sym_end[1024];
1135 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1136 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1138 s = find_section(s1, section_name);
1139 if (!s) {
1140 end_offset = 0;
1141 s = data_section;
1142 } else {
1143 end_offset = s->data_offset;
1146 add_elf_sym(symtab_section,
1147 0, 0,
1148 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1149 s->sh_num, sym_start);
1150 add_elf_sym(symtab_section,
1151 end_offset, 0,
1152 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1153 s->sh_num, sym_end);
1156 /* add tcc runtime libraries */
1157 static void tcc_add_runtime(TCCState *s1)
1159 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1160 char buf[1024];
1161 #endif
1163 #ifdef CONFIG_TCC_BCHECK
1164 if (do_bounds_check) {
1165 unsigned long *ptr;
1166 Section *init_section;
1167 unsigned char *pinit;
1168 int sym_index;
1170 /* XXX: add an object file to do that */
1171 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
1172 *ptr = 0;
1173 add_elf_sym(symtab_section, 0, 0,
1174 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1175 bounds_section->sh_num, "__bounds_start");
1176 /* add bound check code */
1177 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
1178 tcc_add_file(s1, buf);
1179 #ifdef TCC_TARGET_I386
1180 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1181 /* add 'call __bound_init()' in .init section */
1182 init_section = find_section(s1, ".init");
1183 pinit = section_ptr_add(init_section, 5);
1184 pinit[0] = 0xe8;
1185 put32(pinit + 1, -4);
1186 sym_index = find_elf_sym(symtab_section, "__bound_init");
1187 put_elf_reloc(symtab_section, init_section,
1188 init_section->data_offset - 4, R_386_PC32, sym_index);
1190 #endif
1192 #endif
1193 /* add libc */
1194 if (!s1->nostdlib) {
1195 tcc_add_library(s1, "c");
1197 #ifdef CONFIG_USE_LIBGCC
1198 tcc_add_file(s1, CONFIG_SYSROOT "/lib/libgcc_s.so.1");
1199 #else
1200 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
1201 tcc_add_file(s1, buf);
1202 #endif
1204 /* add crt end if not memory output */
1205 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
1206 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1210 /* add various standard linker symbols (must be done after the
1211 sections are filled (for example after allocating common
1212 symbols)) */
1213 static void tcc_add_linker_symbols(TCCState *s1)
1215 char buf[1024];
1216 int i;
1217 Section *s;
1219 add_elf_sym(symtab_section,
1220 text_section->data_offset, 0,
1221 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1222 text_section->sh_num, "_etext");
1223 add_elf_sym(symtab_section,
1224 data_section->data_offset, 0,
1225 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1226 data_section->sh_num, "_edata");
1227 add_elf_sym(symtab_section,
1228 bss_section->data_offset, 0,
1229 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1230 bss_section->sh_num, "_end");
1231 /* horrible new standard ldscript defines */
1232 add_init_array_defines(s1, ".preinit_array");
1233 add_init_array_defines(s1, ".init_array");
1234 add_init_array_defines(s1, ".fini_array");
1236 /* add start and stop symbols for sections whose name can be
1237 expressed in C */
1238 for(i = 1; i < s1->nb_sections; i++) {
1239 s = s1->sections[i];
1240 if (s->sh_type == SHT_PROGBITS &&
1241 (s->sh_flags & SHF_ALLOC)) {
1242 const char *p;
1243 int ch;
1245 /* check if section name can be expressed in C */
1246 p = s->name;
1247 for(;;) {
1248 ch = *p;
1249 if (!ch)
1250 break;
1251 if (!isid(ch) && !isnum(ch))
1252 goto next_sec;
1253 p++;
1255 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1256 add_elf_sym(symtab_section,
1257 0, 0,
1258 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1259 s->sh_num, buf);
1260 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1261 add_elf_sym(symtab_section,
1262 s->data_offset, 0,
1263 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1264 s->sh_num, buf);
1266 next_sec: ;
1270 /* name of ELF interpreter */
1271 #ifdef __FreeBSD__
1272 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1273 #else
1274 #ifdef TCC_ARM_EABI
1275 static char elf_interp[] = "/lib/ld-linux.so.3";
1276 #elif defined(TCC_TARGET_X86_64)
1277 static char elf_interp[] = "/lib/ld-linux-x86-64.so.2";
1278 #else
1279 static char elf_interp[] = "/lib/ld-linux.so.2";
1280 #endif
1281 #endif
1283 static void tcc_output_binary(TCCState *s1, FILE *f,
1284 const int *section_order)
1286 Section *s;
1287 int i, offset, size;
1289 offset = 0;
1290 for(i=1;i<s1->nb_sections;i++) {
1291 s = s1->sections[section_order[i]];
1292 if (s->sh_type != SHT_NOBITS &&
1293 (s->sh_flags & SHF_ALLOC)) {
1294 while (offset < s->sh_offset) {
1295 fputc(0, f);
1296 offset++;
1298 size = s->sh_size;
1299 fwrite(s->data, 1, size, f);
1300 offset += size;
1305 /* output an ELF file */
1306 /* XXX: suppress unneeded sections */
1307 int elf_output_file(TCCState *s1, const char *filename)
1309 ElfW(Ehdr) ehdr;
1310 FILE *f;
1311 int fd, mode, ret;
1312 int *section_order;
1313 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1314 unsigned long addr;
1315 Section *strsec, *s;
1316 ElfW(Shdr) shdr, *sh;
1317 ElfW(Phdr) *phdr, *ph;
1318 Section *interp, *dynamic, *dynstr;
1319 unsigned long saved_dynamic_data_offset;
1320 ElfW(Sym) *sym;
1321 int type, file_type;
1322 unsigned long rel_addr, rel_size;
1324 file_type = s1->output_type;
1325 s1->nb_errors = 0;
1327 if (file_type != TCC_OUTPUT_OBJ) {
1328 tcc_add_runtime(s1);
1331 phdr = NULL;
1332 section_order = NULL;
1333 interp = NULL;
1334 dynamic = NULL;
1335 dynstr = NULL; /* avoid warning */
1336 saved_dynamic_data_offset = 0; /* avoid warning */
1338 if (file_type != TCC_OUTPUT_OBJ) {
1339 relocate_common_syms();
1341 tcc_add_linker_symbols(s1);
1343 if (!s1->static_link) {
1344 const char *name;
1345 int sym_index, index;
1346 ElfW(Sym) *esym, *sym_end;
1348 if (file_type == TCC_OUTPUT_EXE) {
1349 char *ptr;
1350 /* add interpreter section only if executable */
1351 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1352 interp->sh_addralign = 1;
1353 ptr = section_ptr_add(interp, sizeof(elf_interp));
1354 strcpy(ptr, elf_interp);
1357 /* add dynamic symbol table */
1358 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1359 ".dynstr",
1360 ".hash", SHF_ALLOC);
1361 dynstr = s1->dynsym->link;
1363 /* add dynamic section */
1364 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1365 SHF_ALLOC | SHF_WRITE);
1366 dynamic->link = dynstr;
1367 dynamic->sh_entsize = sizeof(ElfW(Dyn));
1369 /* add PLT */
1370 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1371 SHF_ALLOC | SHF_EXECINSTR);
1372 s1->plt->sh_entsize = 4;
1374 build_got(s1);
1376 /* scan for undefined symbols and see if they are in the
1377 dynamic symbols. If a symbol STT_FUNC is found, then we
1378 add it in the PLT. If a symbol STT_OBJECT is found, we
1379 add it in the .bss section with a suitable relocation */
1380 sym_end = (ElfW(Sym) *)(symtab_section->data +
1381 symtab_section->data_offset);
1382 if (file_type == TCC_OUTPUT_EXE) {
1383 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1384 sym < sym_end;
1385 sym++) {
1386 if (sym->st_shndx == SHN_UNDEF) {
1387 name = symtab_section->link->data + sym->st_name;
1388 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1389 if (sym_index) {
1390 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1391 type = ELFW(ST_TYPE)(esym->st_info);
1392 if (type == STT_FUNC) {
1393 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1394 esym->st_info,
1395 sym - (ElfW(Sym) *)symtab_section->data);
1396 } else if (type == STT_OBJECT) {
1397 unsigned long offset;
1398 offset = bss_section->data_offset;
1399 /* XXX: which alignment ? */
1400 offset = (offset + 16 - 1) & -16;
1401 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1402 esym->st_info, 0,
1403 bss_section->sh_num, name);
1404 put_elf_reloc(s1->dynsym, bss_section,
1405 offset, R_COPY, index);
1406 offset += esym->st_size;
1407 bss_section->data_offset = offset;
1409 } else {
1410 /* STB_WEAK undefined symbols are accepted */
1411 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1412 it */
1413 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1414 !strcmp(name, "_fp_hw")) {
1415 } else {
1416 error_noabort("undefined symbol '%s'", name);
1419 } else if (s1->rdynamic &&
1420 ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1421 /* if -rdynamic option, then export all non
1422 local symbols */
1423 name = symtab_section->link->data + sym->st_name;
1424 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1425 sym->st_info, 0,
1426 sym->st_shndx, name);
1430 if (s1->nb_errors)
1431 goto fail;
1433 /* now look at unresolved dynamic symbols and export
1434 corresponding symbol */
1435 sym_end = (ElfW(Sym) *)(s1->dynsymtab_section->data +
1436 s1->dynsymtab_section->data_offset);
1437 for(esym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1;
1438 esym < sym_end;
1439 esym++) {
1440 if (esym->st_shndx == SHN_UNDEF) {
1441 name = s1->dynsymtab_section->link->data + esym->st_name;
1442 sym_index = find_elf_sym(symtab_section, name);
1443 if (sym_index) {
1444 /* XXX: avoid adding a symbol if already
1445 present because of -rdynamic ? */
1446 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1447 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1448 sym->st_info, 0,
1449 sym->st_shndx, name);
1450 } else {
1451 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1452 /* weak symbols can stay undefined */
1453 } else {
1454 warning("undefined dynamic symbol '%s'", name);
1459 } else {
1460 int nb_syms;
1461 /* shared library case : we simply export all the global symbols */
1462 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1463 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1464 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1465 sym < sym_end;
1466 sym++) {
1467 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1468 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1469 if (ELFW(ST_TYPE)(sym->st_info) == STT_FUNC &&
1470 sym->st_shndx == SHN_UNDEF) {
1471 put_got_entry(s1, R_JMP_SLOT, sym->st_size,
1472 sym->st_info,
1473 sym - (ElfW(Sym) *)symtab_section->data);
1475 else if (ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT) {
1476 put_got_entry(s1, R_X86_64_GLOB_DAT, sym->st_size,
1477 sym->st_info,
1478 sym - (ElfW(Sym) *)symtab_section->data);
1480 else
1481 #endif
1483 name = symtab_section->link->data + sym->st_name;
1484 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1485 sym->st_info, 0,
1486 sym->st_shndx, name);
1487 s1->symtab_to_dynsym[sym -
1488 (ElfW(Sym) *)symtab_section->data] =
1489 index;
1495 build_got_entries(s1);
1497 /* add a list of needed dlls */
1498 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1499 DLLReference *dllref = s1->loaded_dlls[i];
1500 if (dllref->level == 0)
1501 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1503 /* XXX: currently, since we do not handle PIC code, we
1504 must relocate the readonly segments */
1505 if (file_type == TCC_OUTPUT_DLL) {
1506 if (s1->soname)
1507 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
1508 put_dt(dynamic, DT_TEXTREL, 0);
1511 /* add necessary space for other entries */
1512 saved_dynamic_data_offset = dynamic->data_offset;
1513 dynamic->data_offset += sizeof(ElfW(Dyn)) * 9;
1514 } else {
1515 /* still need to build got entries in case of static link */
1516 build_got_entries(s1);
1520 memset(&ehdr, 0, sizeof(ehdr));
1522 /* we add a section for symbols */
1523 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1524 put_elf_str(strsec, "");
1526 /* compute number of sections */
1527 shnum = s1->nb_sections;
1529 /* this array is used to reorder sections in the output file */
1530 section_order = tcc_malloc(sizeof(int) * shnum);
1531 section_order[0] = 0;
1532 sh_order_index = 1;
1534 /* compute number of program headers */
1535 switch(file_type) {
1536 default:
1537 case TCC_OUTPUT_OBJ:
1538 phnum = 0;
1539 break;
1540 case TCC_OUTPUT_EXE:
1541 if (!s1->static_link)
1542 phnum = 4;
1543 else
1544 phnum = 2;
1545 break;
1546 case TCC_OUTPUT_DLL:
1547 phnum = 3;
1548 break;
1551 /* allocate strings for section names and decide if an unallocated
1552 section should be output */
1553 /* NOTE: the strsec section comes last, so its size is also
1554 correct ! */
1555 for(i = 1; i < s1->nb_sections; i++) {
1556 s = s1->sections[i];
1557 s->sh_name = put_elf_str(strsec, s->name);
1558 #if 0 //gr
1559 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1560 s->sh_flags,
1561 s->sh_type,
1562 s->sh_info,
1563 s->name,
1564 s->reloc ? s->reloc->name : "n"
1566 #endif
1567 /* when generating a DLL, we include relocations but we may
1568 patch them */
1569 if (file_type == TCC_OUTPUT_DLL &&
1570 s->sh_type == SHT_RELX &&
1571 !(s->sh_flags & SHF_ALLOC)) {
1572 /* //gr: avoid bogus relocs for empty (debug) sections */
1573 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1574 prepare_dynamic_rel(s1, s);
1575 else if (do_debug)
1576 s->sh_size = s->data_offset;
1577 } else if (do_debug ||
1578 file_type == TCC_OUTPUT_OBJ ||
1579 (s->sh_flags & SHF_ALLOC) ||
1580 i == (s1->nb_sections - 1)) {
1581 /* we output all sections if debug or object file */
1582 s->sh_size = s->data_offset;
1586 /* allocate program segment headers */
1587 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
1589 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1590 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1591 } else {
1592 file_offset = 0;
1594 if (phnum > 0) {
1595 /* compute section to program header mapping */
1596 if (s1->has_text_addr) {
1597 int a_offset, p_offset;
1598 addr = s1->text_addr;
1599 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1600 ELF_PAGE_SIZE */
1601 a_offset = addr & (ELF_PAGE_SIZE - 1);
1602 p_offset = file_offset & (ELF_PAGE_SIZE - 1);
1603 if (a_offset < p_offset)
1604 a_offset += ELF_PAGE_SIZE;
1605 file_offset += (a_offset - p_offset);
1606 } else {
1607 if (file_type == TCC_OUTPUT_DLL)
1608 addr = 0;
1609 else
1610 addr = ELF_START_ADDR;
1611 /* compute address after headers */
1612 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1615 /* dynamic relocation table information, for .dynamic section */
1616 rel_size = 0;
1617 rel_addr = 0;
1619 /* leave one program header for the program interpreter */
1620 ph = &phdr[0];
1621 if (interp)
1622 ph++;
1624 for(j = 0; j < 2; j++) {
1625 ph->p_type = PT_LOAD;
1626 if (j == 0)
1627 ph->p_flags = PF_R | PF_X;
1628 else
1629 ph->p_flags = PF_R | PF_W;
1630 ph->p_align = ELF_PAGE_SIZE;
1632 /* we do the following ordering: interp, symbol tables,
1633 relocations, progbits, nobits */
1634 /* XXX: do faster and simpler sorting */
1635 for(k = 0; k < 5; k++) {
1636 for(i = 1; i < s1->nb_sections; i++) {
1637 s = s1->sections[i];
1638 /* compute if section should be included */
1639 if (j == 0) {
1640 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1641 SHF_ALLOC)
1642 continue;
1643 } else {
1644 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1645 (SHF_ALLOC | SHF_WRITE))
1646 continue;
1648 if (s == interp) {
1649 if (k != 0)
1650 continue;
1651 } else if (s->sh_type == SHT_DYNSYM ||
1652 s->sh_type == SHT_STRTAB ||
1653 s->sh_type == SHT_HASH) {
1654 if (k != 1)
1655 continue;
1656 } else if (s->sh_type == SHT_RELX) {
1657 if (k != 2)
1658 continue;
1659 } else if (s->sh_type == SHT_NOBITS) {
1660 if (k != 4)
1661 continue;
1662 } else {
1663 if (k != 3)
1664 continue;
1666 section_order[sh_order_index++] = i;
1668 /* section matches: we align it and add its size */
1669 tmp = addr;
1670 addr = (addr + s->sh_addralign - 1) &
1671 ~(s->sh_addralign - 1);
1672 file_offset += addr - tmp;
1673 s->sh_offset = file_offset;
1674 s->sh_addr = addr;
1676 /* update program header infos */
1677 if (ph->p_offset == 0) {
1678 ph->p_offset = file_offset;
1679 ph->p_vaddr = addr;
1680 ph->p_paddr = ph->p_vaddr;
1682 /* update dynamic relocation infos */
1683 if (s->sh_type == SHT_RELX) {
1684 if (rel_size == 0)
1685 rel_addr = addr;
1686 rel_size += s->sh_size;
1688 addr += s->sh_size;
1689 if (s->sh_type != SHT_NOBITS)
1690 file_offset += s->sh_size;
1693 ph->p_filesz = file_offset - ph->p_offset;
1694 ph->p_memsz = addr - ph->p_vaddr;
1695 ph++;
1696 if (j == 0) {
1697 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1698 /* if in the middle of a page, we duplicate the page in
1699 memory so that one copy is RX and the other is RW */
1700 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1701 addr += ELF_PAGE_SIZE;
1702 } else {
1703 addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
1704 file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
1705 ~(ELF_PAGE_SIZE - 1);
1710 /* if interpreter, then add corresponing program header */
1711 if (interp) {
1712 ph = &phdr[0];
1714 ph->p_type = PT_INTERP;
1715 ph->p_offset = interp->sh_offset;
1716 ph->p_vaddr = interp->sh_addr;
1717 ph->p_paddr = ph->p_vaddr;
1718 ph->p_filesz = interp->sh_size;
1719 ph->p_memsz = interp->sh_size;
1720 ph->p_flags = PF_R;
1721 ph->p_align = interp->sh_addralign;
1724 /* if dynamic section, then add corresponing program header */
1725 if (dynamic) {
1726 ElfW(Sym) *sym_end;
1728 ph = &phdr[phnum - 1];
1730 ph->p_type = PT_DYNAMIC;
1731 ph->p_offset = dynamic->sh_offset;
1732 ph->p_vaddr = dynamic->sh_addr;
1733 ph->p_paddr = ph->p_vaddr;
1734 ph->p_filesz = dynamic->sh_size;
1735 ph->p_memsz = dynamic->sh_size;
1736 ph->p_flags = PF_R | PF_W;
1737 ph->p_align = dynamic->sh_addralign;
1739 /* put GOT dynamic section address */
1740 put32(s1->got->data, dynamic->sh_addr);
1742 /* relocate the PLT */
1743 if (file_type == TCC_OUTPUT_EXE
1744 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1745 || file_type == TCC_OUTPUT_DLL
1746 #endif
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 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1776 p += 16;
1778 #elif defined(TCC_TARGET_C67)
1779 /* XXX: TODO */
1780 #else
1781 #error unsupported CPU
1782 #endif
1786 /* relocate symbols in .dynsym */
1787 sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset);
1788 for(sym = (ElfW(Sym) *)s1->dynsym->data + 1;
1789 sym < sym_end;
1790 sym++) {
1791 if (sym->st_shndx == SHN_UNDEF) {
1792 /* relocate to the PLT if the symbol corresponds
1793 to a PLT entry */
1794 if (sym->st_value)
1795 sym->st_value += s1->plt->sh_addr;
1796 } else if (sym->st_shndx < SHN_LORESERVE) {
1797 /* do symbol relocation */
1798 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1802 /* put dynamic section entries */
1803 dynamic->data_offset = saved_dynamic_data_offset;
1804 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1805 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1806 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1807 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1808 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1809 #ifdef TCC_TARGET_X86_64
1810 put_dt(dynamic, DT_RELA, rel_addr);
1811 put_dt(dynamic, DT_RELASZ, rel_size);
1812 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
1813 #else
1814 put_dt(dynamic, DT_REL, rel_addr);
1815 put_dt(dynamic, DT_RELSZ, rel_size);
1816 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1817 #endif
1818 if (do_debug)
1819 put_dt(dynamic, DT_DEBUG, 0);
1820 put_dt(dynamic, DT_NULL, 0);
1823 ehdr.e_phentsize = sizeof(ElfW(Phdr));
1824 ehdr.e_phnum = phnum;
1825 ehdr.e_phoff = sizeof(ElfW(Ehdr));
1828 /* all other sections come after */
1829 for(i = 1; i < s1->nb_sections; i++) {
1830 s = s1->sections[i];
1831 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1832 continue;
1833 section_order[sh_order_index++] = i;
1835 file_offset = (file_offset + s->sh_addralign - 1) &
1836 ~(s->sh_addralign - 1);
1837 s->sh_offset = file_offset;
1838 if (s->sh_type != SHT_NOBITS)
1839 file_offset += s->sh_size;
1842 /* if building executable or DLL, then relocate each section
1843 except the GOT which is already relocated */
1844 if (file_type != TCC_OUTPUT_OBJ) {
1845 relocate_syms(s1, 0);
1847 if (s1->nb_errors != 0) {
1848 fail:
1849 ret = -1;
1850 goto the_end;
1853 /* relocate sections */
1854 /* XXX: ignore sections with allocated relocations ? */
1855 for(i = 1; i < s1->nb_sections; i++) {
1856 s = s1->sections[i];
1857 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
1858 relocate_section(s1, s);
1861 /* relocate relocation entries if the relocation tables are
1862 allocated in the executable */
1863 for(i = 1; i < s1->nb_sections; i++) {
1864 s = s1->sections[i];
1865 if ((s->sh_flags & SHF_ALLOC) &&
1866 s->sh_type == SHT_RELX) {
1867 relocate_rel(s1, s);
1871 /* get entry point address */
1872 if (file_type == TCC_OUTPUT_EXE)
1873 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
1874 else
1875 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1878 /* write elf file */
1879 if (file_type == TCC_OUTPUT_OBJ)
1880 mode = 0666;
1881 else
1882 mode = 0777;
1883 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1884 if (fd < 0) {
1885 error_noabort("could not write '%s'", filename);
1886 goto fail;
1888 f = fdopen(fd, "wb");
1889 if (verbose)
1890 printf("<- %s\n", filename);
1892 #ifdef TCC_TARGET_COFF
1893 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1894 tcc_output_coff(s1, f);
1895 } else
1896 #endif
1897 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1898 sort_syms(s1, symtab_section);
1900 /* align to 4 */
1901 file_offset = (file_offset + 3) & -4;
1903 /* fill header */
1904 ehdr.e_ident[0] = ELFMAG0;
1905 ehdr.e_ident[1] = ELFMAG1;
1906 ehdr.e_ident[2] = ELFMAG2;
1907 ehdr.e_ident[3] = ELFMAG3;
1908 ehdr.e_ident[4] = TCC_ELFCLASS;
1909 ehdr.e_ident[5] = ELFDATA2LSB;
1910 ehdr.e_ident[6] = EV_CURRENT;
1911 #ifdef __FreeBSD__
1912 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1913 #endif
1914 #ifdef TCC_TARGET_ARM
1915 #ifdef TCC_ARM_EABI
1916 ehdr.e_ident[EI_OSABI] = 0;
1917 ehdr.e_flags = 4 << 24;
1918 #else
1919 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1920 #endif
1921 #endif
1922 switch(file_type) {
1923 default:
1924 case TCC_OUTPUT_EXE:
1925 ehdr.e_type = ET_EXEC;
1926 break;
1927 case TCC_OUTPUT_DLL:
1928 ehdr.e_type = ET_DYN;
1929 break;
1930 case TCC_OUTPUT_OBJ:
1931 ehdr.e_type = ET_REL;
1932 break;
1934 ehdr.e_machine = EM_TCC_TARGET;
1935 ehdr.e_version = EV_CURRENT;
1936 ehdr.e_shoff = file_offset;
1937 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
1938 ehdr.e_shentsize = sizeof(ElfW(Shdr));
1939 ehdr.e_shnum = shnum;
1940 ehdr.e_shstrndx = shnum - 1;
1942 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
1943 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
1944 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1946 for(i=1;i<s1->nb_sections;i++) {
1947 s = s1->sections[section_order[i]];
1948 if (s->sh_type != SHT_NOBITS) {
1949 while (offset < s->sh_offset) {
1950 fputc(0, f);
1951 offset++;
1953 size = s->sh_size;
1954 fwrite(s->data, 1, size, f);
1955 offset += size;
1959 /* output section headers */
1960 while (offset < ehdr.e_shoff) {
1961 fputc(0, f);
1962 offset++;
1965 for(i=0;i<s1->nb_sections;i++) {
1966 sh = &shdr;
1967 memset(sh, 0, sizeof(ElfW(Shdr)));
1968 s = s1->sections[i];
1969 if (s) {
1970 sh->sh_name = s->sh_name;
1971 sh->sh_type = s->sh_type;
1972 sh->sh_flags = s->sh_flags;
1973 sh->sh_entsize = s->sh_entsize;
1974 sh->sh_info = s->sh_info;
1975 if (s->link)
1976 sh->sh_link = s->link->sh_num;
1977 sh->sh_addralign = s->sh_addralign;
1978 sh->sh_addr = s->sh_addr;
1979 sh->sh_offset = s->sh_offset;
1980 sh->sh_size = s->sh_size;
1982 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
1984 } else {
1985 tcc_output_binary(s1, f, section_order);
1987 fclose(f);
1989 ret = 0;
1990 the_end:
1991 tcc_free(s1->symtab_to_dynsym);
1992 tcc_free(section_order);
1993 tcc_free(phdr);
1994 tcc_free(s1->got_offsets);
1995 return ret;
1998 int tcc_output_file(TCCState *s, const char *filename)
2000 int ret;
2001 #ifdef TCC_TARGET_PE
2002 if (s->output_type != TCC_OUTPUT_OBJ) {
2003 ret = pe_output_file(s, filename);
2004 } else
2005 #endif
2007 ret = elf_output_file(s, filename);
2009 return ret;
2012 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2014 void *data;
2016 data = tcc_malloc(size);
2017 lseek(fd, file_offset, SEEK_SET);
2018 read(fd, data, size);
2019 return data;
2022 typedef struct SectionMergeInfo {
2023 Section *s; /* corresponding existing section */
2024 unsigned long offset; /* offset of the new section in the existing section */
2025 uint8_t new_section; /* true if section 's' was added */
2026 uint8_t link_once; /* true if link once section */
2027 } SectionMergeInfo;
2029 /* load an object file and merge it with current files */
2030 /* XXX: handle correctly stab (debug) info */
2031 static int tcc_load_object_file(TCCState *s1,
2032 int fd, unsigned long file_offset)
2034 ElfW(Ehdr) ehdr;
2035 ElfW(Shdr) *shdr, *sh;
2036 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2037 unsigned char *strsec, *strtab;
2038 int *old_to_new_syms;
2039 char *sh_name, *name;
2040 SectionMergeInfo *sm_table, *sm;
2041 ElfW(Sym) *sym, *symtab;
2042 ElfW_Rel *rel, *rel_end;
2043 Section *s;
2045 int stab_index;
2046 int stabstr_index;
2048 stab_index = stabstr_index = 0;
2050 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
2051 goto fail1;
2052 if (ehdr.e_ident[0] != ELFMAG0 ||
2053 ehdr.e_ident[1] != ELFMAG1 ||
2054 ehdr.e_ident[2] != ELFMAG2 ||
2055 ehdr.e_ident[3] != ELFMAG3)
2056 goto fail1;
2057 /* test if object file */
2058 if (ehdr.e_type != ET_REL)
2059 goto fail1;
2060 /* test CPU specific stuff */
2061 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2062 ehdr.e_machine != EM_TCC_TARGET) {
2063 fail1:
2064 error_noabort("invalid object file");
2065 return -1;
2067 /* read sections */
2068 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2069 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2070 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2072 /* load section names */
2073 sh = &shdr[ehdr.e_shstrndx];
2074 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2076 /* load symtab and strtab */
2077 old_to_new_syms = NULL;
2078 symtab = NULL;
2079 strtab = NULL;
2080 nb_syms = 0;
2081 for(i = 1; i < ehdr.e_shnum; i++) {
2082 sh = &shdr[i];
2083 if (sh->sh_type == SHT_SYMTAB) {
2084 if (symtab) {
2085 error_noabort("object must contain only one symtab");
2086 fail:
2087 ret = -1;
2088 goto the_end;
2090 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2091 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2092 sm_table[i].s = symtab_section;
2094 /* now load strtab */
2095 sh = &shdr[sh->sh_link];
2096 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2100 /* now examine each section and try to merge its content with the
2101 ones in memory */
2102 for(i = 1; i < ehdr.e_shnum; i++) {
2103 /* no need to examine section name strtab */
2104 if (i == ehdr.e_shstrndx)
2105 continue;
2106 sh = &shdr[i];
2107 sh_name = strsec + sh->sh_name;
2108 /* ignore sections types we do not handle */
2109 if (sh->sh_type != SHT_PROGBITS &&
2110 sh->sh_type != SHT_RELX &&
2111 #ifdef TCC_ARM_EABI
2112 sh->sh_type != SHT_ARM_EXIDX &&
2113 #endif
2114 sh->sh_type != SHT_NOBITS &&
2115 strcmp(sh_name, ".stabstr")
2117 continue;
2118 if (sh->sh_addralign < 1)
2119 sh->sh_addralign = 1;
2120 /* find corresponding section, if any */
2121 for(j = 1; j < s1->nb_sections;j++) {
2122 s = s1->sections[j];
2123 if (!strcmp(s->name, sh_name)) {
2124 if (!strncmp(sh_name, ".gnu.linkonce",
2125 sizeof(".gnu.linkonce") - 1)) {
2126 /* if a 'linkonce' section is already present, we
2127 do not add it again. It is a little tricky as
2128 symbols can still be defined in
2129 it. */
2130 sm_table[i].link_once = 1;
2131 goto next;
2132 } else {
2133 goto found;
2137 /* not found: create new section */
2138 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
2139 /* take as much info as possible from the section. sh_link and
2140 sh_info will be updated later */
2141 s->sh_addralign = sh->sh_addralign;
2142 s->sh_entsize = sh->sh_entsize;
2143 sm_table[i].new_section = 1;
2144 found:
2145 if (sh->sh_type != s->sh_type) {
2146 error_noabort("invalid section type");
2147 goto fail;
2150 /* align start of section */
2151 offset = s->data_offset;
2153 if (0 == strcmp(sh_name, ".stab")) {
2154 stab_index = i;
2155 goto no_align;
2157 if (0 == strcmp(sh_name, ".stabstr")) {
2158 stabstr_index = i;
2159 goto no_align;
2162 size = sh->sh_addralign - 1;
2163 offset = (offset + size) & ~size;
2164 if (sh->sh_addralign > s->sh_addralign)
2165 s->sh_addralign = sh->sh_addralign;
2166 s->data_offset = offset;
2167 no_align:
2168 sm_table[i].offset = offset;
2169 sm_table[i].s = s;
2170 /* concatenate sections */
2171 size = sh->sh_size;
2172 if (sh->sh_type != SHT_NOBITS) {
2173 unsigned char *ptr;
2174 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2175 ptr = section_ptr_add(s, size);
2176 read(fd, ptr, size);
2177 } else {
2178 s->data_offset += size;
2180 next: ;
2183 /* //gr relocate stab strings */
2184 if (stab_index && stabstr_index) {
2185 Stab_Sym *a, *b;
2186 unsigned o;
2187 s = sm_table[stab_index].s;
2188 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2189 b = (Stab_Sym *)(s->data + s->data_offset);
2190 o = sm_table[stabstr_index].offset;
2191 while (a < b)
2192 a->n_strx += o, a++;
2195 /* second short pass to update sh_link and sh_info fields of new
2196 sections */
2197 for(i = 1; i < ehdr.e_shnum; i++) {
2198 s = sm_table[i].s;
2199 if (!s || !sm_table[i].new_section)
2200 continue;
2201 sh = &shdr[i];
2202 if (sh->sh_link > 0)
2203 s->link = sm_table[sh->sh_link].s;
2204 if (sh->sh_type == SHT_RELX) {
2205 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2206 /* update backward link */
2207 s1->sections[s->sh_info]->reloc = s;
2210 sm = sm_table;
2212 /* resolve symbols */
2213 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2215 sym = symtab + 1;
2216 for(i = 1; i < nb_syms; i++, sym++) {
2217 if (sym->st_shndx != SHN_UNDEF &&
2218 sym->st_shndx < SHN_LORESERVE) {
2219 sm = &sm_table[sym->st_shndx];
2220 if (sm->link_once) {
2221 /* if a symbol is in a link once section, we use the
2222 already defined symbol. It is very important to get
2223 correct relocations */
2224 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2225 name = strtab + sym->st_name;
2226 sym_index = find_elf_sym(symtab_section, name);
2227 if (sym_index)
2228 old_to_new_syms[i] = sym_index;
2230 continue;
2232 /* if no corresponding section added, no need to add symbol */
2233 if (!sm->s)
2234 continue;
2235 /* convert section number */
2236 sym->st_shndx = sm->s->sh_num;
2237 /* offset value */
2238 sym->st_value += sm->offset;
2240 /* add symbol */
2241 name = strtab + sym->st_name;
2242 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
2243 sym->st_info, sym->st_other,
2244 sym->st_shndx, name);
2245 old_to_new_syms[i] = sym_index;
2248 /* third pass to patch relocation entries */
2249 for(i = 1; i < ehdr.e_shnum; i++) {
2250 s = sm_table[i].s;
2251 if (!s)
2252 continue;
2253 sh = &shdr[i];
2254 offset = sm_table[i].offset;
2255 switch(s->sh_type) {
2256 case SHT_RELX:
2257 /* take relocation offset information */
2258 offseti = sm_table[sh->sh_info].offset;
2259 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
2260 for(rel = (ElfW_Rel *)(s->data + offset);
2261 rel < rel_end;
2262 rel++) {
2263 int type;
2264 unsigned sym_index;
2265 /* convert symbol index */
2266 type = ELFW(R_TYPE)(rel->r_info);
2267 sym_index = ELFW(R_SYM)(rel->r_info);
2268 /* NOTE: only one symtab assumed */
2269 if (sym_index >= nb_syms)
2270 goto invalid_reloc;
2271 sym_index = old_to_new_syms[sym_index];
2272 /* ignore link_once in rel section. */
2273 if (!sym_index && !sm->link_once) {
2274 invalid_reloc:
2275 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2276 i, strsec + sh->sh_name, rel->r_offset);
2277 goto fail;
2279 rel->r_info = ELFW(R_INFO)(sym_index, type);
2280 /* offset the relocation offset */
2281 rel->r_offset += offseti;
2283 break;
2284 default:
2285 break;
2289 ret = 0;
2290 the_end:
2291 tcc_free(symtab);
2292 tcc_free(strtab);
2293 tcc_free(old_to_new_syms);
2294 tcc_free(sm_table);
2295 tcc_free(strsec);
2296 tcc_free(shdr);
2297 return ret;
2300 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2302 typedef struct ArchiveHeader {
2303 char ar_name[16]; /* name of this member */
2304 char ar_date[12]; /* file mtime */
2305 char ar_uid[6]; /* owner uid; printed as decimal */
2306 char ar_gid[6]; /* owner gid; printed as decimal */
2307 char ar_mode[8]; /* file mode, printed as octal */
2308 char ar_size[10]; /* file size, printed as decimal */
2309 char ar_fmag[2]; /* should contain ARFMAG */
2310 } ArchiveHeader;
2312 static int get_be32(const uint8_t *b)
2314 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2317 /* load only the objects which resolve undefined symbols */
2318 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
2320 int i, bound, nsyms, sym_index, off, ret;
2321 uint8_t *data;
2322 const char *ar_names, *p;
2323 const uint8_t *ar_index;
2324 ElfW(Sym) *sym;
2326 data = tcc_malloc(size);
2327 if (read(fd, data, size) != size)
2328 goto fail;
2329 nsyms = get_be32(data);
2330 ar_index = data + 4;
2331 ar_names = ar_index + nsyms * 4;
2333 do {
2334 bound = 0;
2335 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2336 sym_index = find_elf_sym(symtab_section, p);
2337 if(sym_index) {
2338 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2339 if(sym->st_shndx == SHN_UNDEF) {
2340 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2341 #if 0
2342 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2343 #endif
2344 ++bound;
2345 lseek(fd, off, SEEK_SET);
2346 if(tcc_load_object_file(s1, fd, off) < 0) {
2347 fail:
2348 ret = -1;
2349 goto the_end;
2354 } while(bound);
2355 ret = 0;
2356 the_end:
2357 tcc_free(data);
2358 return ret;
2361 /* load a '.a' file */
2362 static int tcc_load_archive(TCCState *s1, int fd)
2364 ArchiveHeader hdr;
2365 char ar_size[11];
2366 char ar_name[17];
2367 char magic[8];
2368 int size, len, i;
2369 unsigned long file_offset;
2371 /* skip magic which was already checked */
2372 read(fd, magic, sizeof(magic));
2374 for(;;) {
2375 len = read(fd, &hdr, sizeof(hdr));
2376 if (len == 0)
2377 break;
2378 if (len != sizeof(hdr)) {
2379 error_noabort("invalid archive");
2380 return -1;
2382 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2383 ar_size[sizeof(hdr.ar_size)] = '\0';
2384 size = strtol(ar_size, NULL, 0);
2385 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2386 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2387 if (ar_name[i] != ' ')
2388 break;
2390 ar_name[i + 1] = '\0';
2391 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2392 file_offset = lseek(fd, 0, SEEK_CUR);
2393 /* align to even */
2394 size = (size + 1) & ~1;
2395 if (!strcmp(ar_name, "/")) {
2396 /* coff symbol table : we handle it */
2397 if(s1->alacarte_link)
2398 return tcc_load_alacarte(s1, fd, size);
2399 } else if (!strcmp(ar_name, "//") ||
2400 !strcmp(ar_name, "__.SYMDEF") ||
2401 !strcmp(ar_name, "__.SYMDEF/") ||
2402 !strcmp(ar_name, "ARFILENAMES/")) {
2403 /* skip symbol table or archive names */
2404 } else {
2405 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2406 return -1;
2408 lseek(fd, file_offset + size, SEEK_SET);
2410 return 0;
2413 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2414 is referenced by the user (so it should be added as DT_NEEDED in
2415 the generated ELF file) */
2416 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2418 ElfW(Ehdr) ehdr;
2419 ElfW(Shdr) *shdr, *sh, *sh1;
2420 int i, j, nb_syms, nb_dts, sym_bind, ret;
2421 ElfW(Sym) *sym, *dynsym;
2422 ElfW(Dyn) *dt, *dynamic;
2423 unsigned char *dynstr;
2424 const char *name, *soname;
2425 DLLReference *dllref;
2427 read(fd, &ehdr, sizeof(ehdr));
2429 /* test CPU specific stuff */
2430 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2431 ehdr.e_machine != EM_TCC_TARGET) {
2432 error_noabort("bad architecture");
2433 return -1;
2436 /* read sections */
2437 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2439 /* load dynamic section and dynamic symbols */
2440 nb_syms = 0;
2441 nb_dts = 0;
2442 dynamic = NULL;
2443 dynsym = NULL; /* avoid warning */
2444 dynstr = NULL; /* avoid warning */
2445 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2446 switch(sh->sh_type) {
2447 case SHT_DYNAMIC:
2448 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2449 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2450 break;
2451 case SHT_DYNSYM:
2452 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2453 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2454 sh1 = &shdr[sh->sh_link];
2455 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2456 break;
2457 default:
2458 break;
2462 /* compute the real library name */
2463 soname = tcc_basename(filename);
2465 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2466 if (dt->d_tag == DT_SONAME) {
2467 soname = dynstr + dt->d_un.d_val;
2471 /* if the dll is already loaded, do not load it */
2472 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2473 dllref = s1->loaded_dlls[i];
2474 if (!strcmp(soname, dllref->name)) {
2475 /* but update level if needed */
2476 if (level < dllref->level)
2477 dllref->level = level;
2478 ret = 0;
2479 goto the_end;
2483 // printf("loading dll '%s'\n", soname);
2485 /* add the dll and its level */
2486 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2487 dllref->level = level;
2488 strcpy(dllref->name, soname);
2489 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2491 /* add dynamic symbols in dynsym_section */
2492 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2493 sym_bind = ELFW(ST_BIND)(sym->st_info);
2494 if (sym_bind == STB_LOCAL)
2495 continue;
2496 name = dynstr + sym->st_name;
2497 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2498 sym->st_info, sym->st_other, sym->st_shndx, name);
2501 /* load all referenced DLLs */
2502 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2503 switch(dt->d_tag) {
2504 case DT_NEEDED:
2505 name = dynstr + dt->d_un.d_val;
2506 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2507 dllref = s1->loaded_dlls[j];
2508 if (!strcmp(name, dllref->name))
2509 goto already_loaded;
2511 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2512 error_noabort("referenced dll '%s' not found", name);
2513 ret = -1;
2514 goto the_end;
2516 already_loaded:
2517 break;
2520 ret = 0;
2521 the_end:
2522 tcc_free(dynstr);
2523 tcc_free(dynsym);
2524 tcc_free(dynamic);
2525 tcc_free(shdr);
2526 return ret;
2529 #define LD_TOK_NAME 256
2530 #define LD_TOK_EOF (-1)
2532 /* return next ld script token */
2533 static int ld_next(TCCState *s1, char *name, int name_size)
2535 int c;
2536 char *q;
2538 redo:
2539 switch(ch) {
2540 case ' ':
2541 case '\t':
2542 case '\f':
2543 case '\v':
2544 case '\r':
2545 case '\n':
2546 inp();
2547 goto redo;
2548 case '/':
2549 minp();
2550 if (ch == '*') {
2551 file->buf_ptr = parse_comment(file->buf_ptr);
2552 ch = file->buf_ptr[0];
2553 goto redo;
2554 } else {
2555 q = name;
2556 *q++ = '/';
2557 goto parse_name;
2559 break;
2560 /* case 'a' ... 'z': */
2561 case 'a':
2562 case 'b':
2563 case 'c':
2564 case 'd':
2565 case 'e':
2566 case 'f':
2567 case 'g':
2568 case 'h':
2569 case 'i':
2570 case 'j':
2571 case 'k':
2572 case 'l':
2573 case 'm':
2574 case 'n':
2575 case 'o':
2576 case 'p':
2577 case 'q':
2578 case 'r':
2579 case 's':
2580 case 't':
2581 case 'u':
2582 case 'v':
2583 case 'w':
2584 case 'x':
2585 case 'y':
2586 case 'z':
2587 /* case 'A' ... 'z': */
2588 case 'A':
2589 case 'B':
2590 case 'C':
2591 case 'D':
2592 case 'E':
2593 case 'F':
2594 case 'G':
2595 case 'H':
2596 case 'I':
2597 case 'J':
2598 case 'K':
2599 case 'L':
2600 case 'M':
2601 case 'N':
2602 case 'O':
2603 case 'P':
2604 case 'Q':
2605 case 'R':
2606 case 'S':
2607 case 'T':
2608 case 'U':
2609 case 'V':
2610 case 'W':
2611 case 'X':
2612 case 'Y':
2613 case 'Z':
2614 case '_':
2615 case '\\':
2616 case '.':
2617 case '$':
2618 case '~':
2619 q = name;
2620 parse_name:
2621 for(;;) {
2622 if (!((ch >= 'a' && ch <= 'z') ||
2623 (ch >= 'A' && ch <= 'Z') ||
2624 (ch >= '0' && ch <= '9') ||
2625 strchr("/.-_+=$:\\,~", ch)))
2626 break;
2627 if ((q - name) < name_size - 1) {
2628 *q++ = ch;
2630 minp();
2632 *q = '\0';
2633 c = LD_TOK_NAME;
2634 break;
2635 case CH_EOF:
2636 c = LD_TOK_EOF;
2637 break;
2638 default:
2639 c = ch;
2640 inp();
2641 break;
2643 #if 0
2644 printf("tok=%c %d\n", c, c);
2645 if (c == LD_TOK_NAME)
2646 printf(" name=%s\n", name);
2647 #endif
2648 return c;
2651 static int ld_add_file_list(TCCState *s1, int as_needed)
2653 char filename[1024];
2654 int t, ret;
2656 t = ld_next(s1, filename, sizeof(filename));
2657 if (t != '(')
2658 expect("(");
2659 t = ld_next(s1, filename, sizeof(filename));
2660 for(;;) {
2661 if (t == LD_TOK_EOF) {
2662 error_noabort("unexpected end of file");
2663 return -1;
2664 } else if (t == ')') {
2665 break;
2666 } else if (t != LD_TOK_NAME) {
2667 error_noabort("filename expected");
2668 return -1;
2670 if (!strcmp(filename, "AS_NEEDED")) {
2671 ret = ld_add_file_list(s1, 1);
2672 if (ret)
2673 return ret;
2674 } else {
2675 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2676 if (!as_needed)
2677 tcc_add_file(s1, filename);
2679 t = ld_next(s1, filename, sizeof(filename));
2680 if (t == ',') {
2681 t = ld_next(s1, filename, sizeof(filename));
2684 return 0;
2687 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2688 files */
2689 static int tcc_load_ldscript(TCCState *s1)
2691 char cmd[64];
2692 char filename[1024];
2693 int t, ret;
2695 ch = file->buf_ptr[0];
2696 ch = handle_eob();
2697 for(;;) {
2698 t = ld_next(s1, cmd, sizeof(cmd));
2699 if (t == LD_TOK_EOF)
2700 return 0;
2701 else if (t != LD_TOK_NAME)
2702 return -1;
2703 if (!strcmp(cmd, "INPUT") ||
2704 !strcmp(cmd, "GROUP")) {
2705 ret = ld_add_file_list(s1, 0);
2706 if (ret)
2707 return ret;
2708 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2709 !strcmp(cmd, "TARGET")) {
2710 /* ignore some commands */
2711 t = ld_next(s1, cmd, sizeof(cmd));
2712 if (t != '(')
2713 expect("(");
2714 for(;;) {
2715 t = ld_next(s1, filename, sizeof(filename));
2716 if (t == LD_TOK_EOF) {
2717 error_noabort("unexpected end of file");
2718 return -1;
2719 } else if (t == ')') {
2720 break;
2723 } else {
2724 return -1;
2727 return 0;