silly bug fix: s/#ifdef PTR_SIZE == 4/#if PTR_SIZE == 4/
[tinycc.git] / tccelf.c
blobd41d06cc5d58065581afa63e74c61893aab2bbb4
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 #else
26 #define ElfW_Rel ElfW(Rel)
27 #define SHT_RELX SHT_REL
28 #define REL_SECTION_FMT ".rel%s"
29 #endif
31 static int put_elf_str(Section *s, const char *sym)
33 int offset, len;
34 char *ptr;
36 len = strlen(sym) + 1;
37 offset = s->data_offset;
38 ptr = section_ptr_add(s, len);
39 memcpy(ptr, sym, len);
40 return offset;
43 /* elf symbol hashing function */
44 static unsigned long elf_hash(const unsigned char *name)
46 unsigned long h = 0, g;
48 while (*name) {
49 h = (h << 4) + *name++;
50 g = h & 0xf0000000;
51 if (g)
52 h ^= g >> 24;
53 h &= ~g;
55 return h;
58 /* rebuild hash table of section s */
59 /* NOTE: we do factorize the hash table code to go faster */
60 static void rebuild_hash(Section *s, unsigned int nb_buckets)
62 ElfW(Sym) *sym;
63 int *ptr, *hash, nb_syms, sym_index, h;
64 char *strtab;
66 strtab = s->link->data;
67 nb_syms = s->data_offset / sizeof(ElfW(Sym));
69 s->hash->data_offset = 0;
70 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
71 ptr[0] = nb_buckets;
72 ptr[1] = nb_syms;
73 ptr += 2;
74 hash = ptr;
75 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
76 ptr += nb_buckets + 1;
78 sym = (ElfW(Sym) *)s->data + 1;
79 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
80 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
81 h = elf_hash(strtab + sym->st_name) % nb_buckets;
82 *ptr = hash[h];
83 hash[h] = sym_index;
84 } else {
85 *ptr = 0;
87 ptr++;
88 sym++;
92 /* return the symbol number */
93 static int put_elf_sym(Section *s,
94 unsigned long value, unsigned long size,
95 int info, int other, int shndx, const char *name)
97 int name_offset, sym_index;
98 int nbuckets, h;
99 ElfW(Sym) *sym;
100 Section *hs;
102 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
103 if (name)
104 name_offset = put_elf_str(s->link, name);
105 else
106 name_offset = 0;
107 /* XXX: endianness */
108 sym->st_name = name_offset;
109 sym->st_value = value;
110 sym->st_size = size;
111 sym->st_info = info;
112 sym->st_other = other;
113 sym->st_shndx = shndx;
114 sym_index = sym - (ElfW(Sym) *)s->data;
115 hs = s->hash;
116 if (hs) {
117 int *ptr, *base;
118 ptr = section_ptr_add(hs, sizeof(int));
119 base = (int *)hs->data;
120 /* only add global or weak symbols */
121 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
122 /* add another hashing entry */
123 nbuckets = base[0];
124 h = elf_hash(name) % nbuckets;
125 *ptr = base[2 + h];
126 base[2 + h] = sym_index;
127 base[1]++;
128 /* we resize the hash table */
129 hs->nb_hashed_syms++;
130 if (hs->nb_hashed_syms > 2 * nbuckets) {
131 rebuild_hash(s, 2 * nbuckets);
133 } else {
134 *ptr = 0;
135 base[1]++;
138 return sym_index;
141 /* find global ELF symbol 'name' and return its index. Return 0 if not
142 found. */
143 static int find_elf_sym(Section *s, const char *name)
145 ElfW(Sym) *sym;
146 Section *hs;
147 int nbuckets, sym_index, h;
148 const char *name1;
150 hs = s->hash;
151 if (!hs)
152 return 0;
153 nbuckets = ((int *)hs->data)[0];
154 h = elf_hash(name) % nbuckets;
155 sym_index = ((int *)hs->data)[2 + h];
156 while (sym_index != 0) {
157 sym = &((ElfW(Sym) *)s->data)[sym_index];
158 name1 = s->link->data + sym->st_name;
159 if (!strcmp(name, name1))
160 return sym_index;
161 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
163 return 0;
166 /* return elf symbol value or error */
167 int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name)
169 int sym_index;
170 ElfW(Sym) *sym;
172 sym_index = find_elf_sym(symtab_section, name);
173 if (!sym_index)
174 return -1;
175 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
176 *pval = sym->st_value;
177 return 0;
180 void *tcc_get_symbol_err(TCCState *s, const char *name)
182 unsigned long val;
183 if (tcc_get_symbol(s, &val, name) < 0)
184 error("%s not defined", name);
185 return (void *)val;
188 /* add an elf symbol : check if it is already defined and patch
189 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
190 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
191 int info, int other, int sh_num, const char *name)
193 ElfW(Sym) *esym;
194 int sym_bind, sym_index, sym_type, esym_bind;
195 unsigned char sym_vis, esym_vis, new_vis;
197 sym_bind = ELFW(ST_BIND)(info);
198 sym_type = ELFW(ST_TYPE)(info);
199 sym_vis = ELFW(ST_VISIBILITY)(other);
201 if (sym_bind != STB_LOCAL) {
202 /* we search global or weak symbols */
203 sym_index = find_elf_sym(s, name);
204 if (!sym_index)
205 goto do_def;
206 esym = &((ElfW(Sym) *)s->data)[sym_index];
207 if (esym->st_shndx != SHN_UNDEF) {
208 esym_bind = ELFW(ST_BIND)(esym->st_info);
209 /* propagate the most constraining visibility */
210 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
211 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
212 if (esym_vis == STV_DEFAULT) {
213 new_vis = sym_vis;
214 } else if (sym_vis == STV_DEFAULT) {
215 new_vis = esym_vis;
216 } else {
217 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
219 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
220 | new_vis;
221 other = esym->st_other; /* in case we have to patch esym */
222 if (sh_num == SHN_UNDEF) {
223 /* ignore adding of undefined symbol if the
224 corresponding symbol is already defined */
225 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
226 /* global overrides weak, so patch */
227 goto do_patch;
228 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
229 /* weak is ignored if already global */
230 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
231 /* ignore hidden symbols after */
232 } else if (esym->st_shndx == SHN_COMMON && sh_num < SHN_LORESERVE) {
233 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
234 No idea if this is the correct solution ... */
235 goto do_patch;
236 } else if (s == tcc_state->dynsymtab_section) {
237 /* we accept that two DLL define the same symbol */
238 } else {
239 #if 1
240 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
241 sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
242 #endif
243 error_noabort("'%s' defined twice", name);
245 } else {
246 do_patch:
247 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
248 esym->st_shndx = sh_num;
249 esym->st_value = value;
250 esym->st_size = size;
251 esym->st_other = other;
253 } else {
254 do_def:
255 sym_index = put_elf_sym(s, value, size,
256 ELFW(ST_INFO)(sym_bind, sym_type), other,
257 sh_num, name);
259 return sym_index;
262 /* put relocation */
263 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
264 int type, int symbol)
266 char buf[256];
267 Section *sr;
268 ElfW_Rel *rel;
270 sr = s->reloc;
271 if (!sr) {
272 /* if no relocation section, create it */
273 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
274 /* if the symtab is allocated, then we consider the relocation
275 are also */
276 sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
277 sr->sh_entsize = sizeof(ElfW_Rel);
278 sr->link = symtab;
279 sr->sh_info = s->sh_num;
280 s->reloc = sr;
282 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
283 rel->r_offset = offset;
284 rel->r_info = ELFW(R_INFO)(symbol, type);
287 /* put stab debug information */
289 typedef struct {
290 unsigned long n_strx; /* index into string table of name */
291 unsigned char n_type; /* type of symbol */
292 unsigned char n_other; /* misc info (usually empty) */
293 unsigned short n_desc; /* description field */
294 unsigned long n_value; /* value of symbol */
295 } Stab_Sym;
297 static void put_stabs(const char *str, int type, int other, int desc,
298 unsigned long value)
300 Stab_Sym *sym;
302 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
303 if (str) {
304 sym->n_strx = put_elf_str(stabstr_section, str);
305 } else {
306 sym->n_strx = 0;
308 sym->n_type = type;
309 sym->n_other = other;
310 sym->n_desc = desc;
311 sym->n_value = value;
314 static void put_stabs_r(const char *str, int type, int other, int desc,
315 unsigned long value, Section *sec, int sym_index)
317 put_stabs(str, type, other, desc, value);
318 put_elf_reloc(symtab_section, stab_section,
319 stab_section->data_offset - sizeof(unsigned long),
320 R_DATA_32, sym_index);
323 static void put_stabn(int type, int other, int desc, int value)
325 put_stabs(NULL, type, other, desc, value);
328 static void put_stabd(int type, int other, int desc)
330 put_stabs(NULL, type, other, desc, 0);
333 /* In an ELF file symbol table, the local symbols must appear below
334 the global and weak ones. Since TCC cannot sort it while generating
335 the code, we must do it after. All the relocation tables are also
336 modified to take into account the symbol table sorting */
337 static void sort_syms(TCCState *s1, Section *s)
339 int *old_to_new_syms;
340 ElfW(Sym) *new_syms;
341 int nb_syms, i;
342 ElfW(Sym) *p, *q;
343 ElfW_Rel *rel, *rel_end;
344 Section *sr;
345 int type, sym_index;
347 nb_syms = s->data_offset / sizeof(ElfW(Sym));
348 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
349 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
351 /* first pass for local symbols */
352 p = (ElfW(Sym) *)s->data;
353 q = new_syms;
354 for(i = 0; i < nb_syms; i++) {
355 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
356 old_to_new_syms[i] = q - new_syms;
357 *q++ = *p;
359 p++;
361 /* save the number of local symbols in section header */
362 s->sh_info = q - new_syms;
364 /* then second pass for non local symbols */
365 p = (ElfW(Sym) *)s->data;
366 for(i = 0; i < nb_syms; i++) {
367 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
368 old_to_new_syms[i] = q - new_syms;
369 *q++ = *p;
371 p++;
374 /* we copy the new symbols to the old */
375 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
376 tcc_free(new_syms);
378 /* now we modify all the relocations */
379 for(i = 1; i < s1->nb_sections; i++) {
380 sr = s1->sections[i];
381 if (sr->sh_type == SHT_RELX && sr->link == s) {
382 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
383 for(rel = (ElfW_Rel *)sr->data;
384 rel < rel_end;
385 rel++) {
386 sym_index = ELFW(R_SYM)(rel->r_info);
387 type = ELFW(R_TYPE)(rel->r_info);
388 sym_index = old_to_new_syms[sym_index];
389 rel->r_info = ELFW(R_INFO)(sym_index, type);
394 tcc_free(old_to_new_syms);
397 /* relocate common symbols in the .bss section */
398 static void relocate_common_syms(void)
400 ElfW(Sym) *sym, *sym_end;
401 unsigned long offset, align;
403 sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
404 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
405 sym < sym_end;
406 sym++) {
407 if (sym->st_shndx == SHN_COMMON) {
408 /* align symbol */
409 align = sym->st_value;
410 offset = bss_section->data_offset;
411 offset = (offset + align - 1) & -align;
412 sym->st_value = offset;
413 sym->st_shndx = bss_section->sh_num;
414 offset += sym->st_size;
415 bss_section->data_offset = offset;
420 /* relocate symbol table, resolve undefined symbols if do_resolve is
421 true and output error if undefined symbol. */
422 static void relocate_syms(TCCState *s1, int do_resolve)
424 ElfW(Sym) *sym, *esym, *sym_end;
425 int sym_bind, sh_num, sym_index;
426 const char *name;
427 unsigned long addr;
429 sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
430 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
431 sym < sym_end;
432 sym++) {
433 sh_num = sym->st_shndx;
434 if (sh_num == SHN_UNDEF) {
435 name = strtab_section->data + sym->st_name;
436 if (do_resolve) {
437 name = symtab_section->link->data + sym->st_name;
438 addr = (unsigned long)resolve_sym(s1, name, ELFW(ST_TYPE)(sym->st_info));
439 if (addr) {
440 sym->st_value = addr;
441 goto found;
443 } else if (s1->dynsym) {
444 /* if dynamic symbol exist, then use it */
445 sym_index = find_elf_sym(s1->dynsym, name);
446 if (sym_index) {
447 esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
448 sym->st_value = esym->st_value;
449 goto found;
452 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
453 it */
454 if (!strcmp(name, "_fp_hw"))
455 goto found;
456 /* only weak symbols are accepted to be undefined. Their
457 value is zero */
458 sym_bind = ELFW(ST_BIND)(sym->st_info);
459 if (sym_bind == STB_WEAK) {
460 sym->st_value = 0;
461 } else {
462 error_noabort("undefined symbol '%s'", name);
464 } else if (sh_num < SHN_LORESERVE) {
465 /* add section base */
466 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
468 found: ;
472 /* relocate a given section (CPU dependent) */
473 static void relocate_section(TCCState *s1, Section *s)
475 Section *sr;
476 ElfW_Rel *rel, *rel_end, *qrel;
477 ElfW(Sym) *sym;
478 int type, sym_index;
479 unsigned char *ptr;
480 unsigned long val, addr;
481 #if defined(TCC_TARGET_I386)
482 int esym_index;
483 #endif
485 sr = s->reloc;
486 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
487 qrel = (ElfW_Rel *)sr->data;
488 for(rel = qrel;
489 rel < rel_end;
490 rel++) {
491 ptr = s->data + rel->r_offset;
493 sym_index = ELFW(R_SYM)(rel->r_info);
494 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
495 val = sym->st_value;
496 type = ELFW(R_TYPE)(rel->r_info);
497 addr = s->sh_addr + rel->r_offset;
499 /* CPU specific */
500 switch(type) {
501 #if defined(TCC_TARGET_I386)
502 case R_386_32:
503 if (s1->output_type == TCC_OUTPUT_DLL) {
504 esym_index = s1->symtab_to_dynsym[sym_index];
505 qrel->r_offset = rel->r_offset;
506 if (esym_index) {
507 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
508 qrel++;
509 break;
510 } else {
511 qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
512 qrel++;
515 *(int *)ptr += val;
516 break;
517 case R_386_PC32:
518 if (s1->output_type == TCC_OUTPUT_DLL) {
519 /* DLL relocation */
520 esym_index = s1->symtab_to_dynsym[sym_index];
521 if (esym_index) {
522 qrel->r_offset = rel->r_offset;
523 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
524 qrel++;
525 break;
528 *(int *)ptr += val - addr;
529 break;
530 case R_386_PLT32:
531 *(int *)ptr += val - addr;
532 break;
533 case R_386_GLOB_DAT:
534 case R_386_JMP_SLOT:
535 *(int *)ptr = val;
536 break;
537 case R_386_GOTPC:
538 *(int *)ptr += s1->got->sh_addr - addr;
539 break;
540 case R_386_GOTOFF:
541 *(int *)ptr += val - s1->got->sh_addr;
542 break;
543 case R_386_GOT32:
544 /* we load the got offset */
545 *(int *)ptr += s1->got_offsets[sym_index];
546 break;
547 #elif defined(TCC_TARGET_ARM)
548 case R_ARM_PC24:
549 case R_ARM_CALL:
550 case R_ARM_JUMP24:
551 case R_ARM_PLT32:
553 int x;
554 x = (*(int *)ptr)&0xffffff;
555 (*(int *)ptr) &= 0xff000000;
556 if (x & 0x800000)
557 x -= 0x1000000;
558 x *= 4;
559 x += val - addr;
560 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
561 error("can't relocate value at %x",addr);
562 x >>= 2;
563 x &= 0xffffff;
564 (*(int *)ptr) |= x;
566 break;
567 case R_ARM_PREL31:
569 int x;
570 x = (*(int *)ptr) & 0x7fffffff;
571 (*(int *)ptr) &= 0x80000000;
572 x = (x * 2) / 2;
573 x += val - addr;
574 if((x^(x>>1))&0x40000000)
575 error("can't relocate value at %x",addr);
576 (*(int *)ptr) |= x & 0x7fffffff;
578 case R_ARM_ABS32:
579 *(int *)ptr += val;
580 break;
581 case R_ARM_BASE_PREL:
582 *(int *)ptr += s1->got->sh_addr - addr;
583 break;
584 case R_ARM_GOTOFF32:
585 *(int *)ptr += val - s1->got->sh_addr;
586 break;
587 case R_ARM_GOT_BREL:
588 /* we load the got offset */
589 *(int *)ptr += s1->got_offsets[sym_index];
590 break;
591 case R_ARM_COPY:
592 break;
593 default:
594 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
595 type,addr,(unsigned int )ptr,val);
596 break;
597 #elif defined(TCC_TARGET_C67)
598 case R_C60_32:
599 *(int *)ptr += val;
600 break;
601 case R_C60LO16:
603 uint32_t orig;
605 /* put the low 16 bits of the absolute address */
606 // add to what is already there
608 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
609 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
611 //patch both at once - assumes always in pairs Low - High
613 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
614 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
616 break;
617 case R_C60HI16:
618 break;
619 default:
620 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
621 type,addr,(unsigned int )ptr,val);
622 break;
623 #else
624 #error unsupported processor
625 #endif
628 /* if the relocation is allocated, we change its symbol table */
629 if (sr->sh_flags & SHF_ALLOC)
630 sr->link = s1->dynsym;
633 /* relocate relocation table in 'sr' */
634 static void relocate_rel(TCCState *s1, Section *sr)
636 Section *s;
637 ElfW_Rel *rel, *rel_end;
639 s = s1->sections[sr->sh_info];
640 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
641 for(rel = (ElfW_Rel *)sr->data;
642 rel < rel_end;
643 rel++) {
644 rel->r_offset += s->sh_addr;
648 /* count the number of dynamic relocations so that we can reserve
649 their space */
650 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
652 ElfW_Rel *rel, *rel_end;
653 int sym_index, esym_index, type, count;
655 count = 0;
656 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
657 for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
658 sym_index = ELFW(R_SYM)(rel->r_info);
659 type = ELFW(R_TYPE)(rel->r_info);
660 switch(type) {
661 case R_386_32:
662 count++;
663 break;
664 case R_386_PC32:
665 esym_index = s1->symtab_to_dynsym[sym_index];
666 if (esym_index)
667 count++;
668 break;
669 default:
670 break;
673 if (count) {
674 /* allocate the section */
675 sr->sh_flags |= SHF_ALLOC;
676 sr->sh_size = count * sizeof(ElfW_Rel);
678 return count;
681 static void put_got_offset(TCCState *s1, int index, unsigned long val)
683 int n;
684 unsigned long *tab;
686 if (index >= s1->nb_got_offsets) {
687 /* find immediately bigger power of 2 and reallocate array */
688 n = 1;
689 while (index >= n)
690 n *= 2;
691 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
692 if (!tab)
693 error("memory full");
694 s1->got_offsets = tab;
695 memset(s1->got_offsets + s1->nb_got_offsets, 0,
696 (n - s1->nb_got_offsets) * sizeof(unsigned long));
697 s1->nb_got_offsets = n;
699 s1->got_offsets[index] = val;
702 /* XXX: suppress that */
703 static void put32(unsigned char *p, uint32_t val)
705 p[0] = val;
706 p[1] = val >> 8;
707 p[2] = val >> 16;
708 p[3] = val >> 24;
711 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM)
712 static uint32_t get32(unsigned char *p)
714 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
716 #endif
718 static void build_got(TCCState *s1)
720 unsigned char *ptr;
722 /* if no got, then create it */
723 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
724 s1->got->sh_entsize = 4;
725 add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
726 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
727 ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
728 #if PTR_SIZE == 4
729 /* keep space for _DYNAMIC pointer, if present */
730 put32(ptr, 0);
731 /* two dummy got entries */
732 put32(ptr + 4, 0);
733 put32(ptr + 8, 0);
734 #else
735 /* keep space for _DYNAMIC pointer, if present */
736 put32(ptr, 0);
737 put32(ptr + 4, 0);
738 /* two dummy got entries */
739 put32(ptr + 8, 0);
740 put32(ptr + 12, 0);
741 put32(ptr + 16, 0);
742 put32(ptr + 20, 0);
743 #endif
746 /* put a got entry corresponding to a symbol in symtab_section. 'size'
747 and 'info' can be modifed if more precise info comes from the DLL */
748 static void put_got_entry(TCCState *s1,
749 int reloc_type, unsigned long size, int info,
750 int sym_index)
752 int index;
753 const char *name;
754 ElfW(Sym) *sym;
755 unsigned long offset;
756 int *ptr;
758 if (!s1->got)
759 build_got(s1);
761 /* if a got entry already exists for that symbol, no need to add one */
762 if (sym_index < s1->nb_got_offsets &&
763 s1->got_offsets[sym_index] != 0)
764 return;
766 put_got_offset(s1, sym_index, s1->got->data_offset);
768 if (s1->dynsym) {
769 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
770 name = symtab_section->link->data + sym->st_name;
771 offset = sym->st_value;
772 #ifdef TCC_TARGET_I386
773 if (reloc_type == R_386_JMP_SLOT) {
774 Section *plt;
775 uint8_t *p;
776 int modrm;
778 /* if we build a DLL, we add a %ebx offset */
779 if (s1->output_type == TCC_OUTPUT_DLL)
780 modrm = 0xa3;
781 else
782 modrm = 0x25;
784 /* add a PLT entry */
785 plt = s1->plt;
786 if (plt->data_offset == 0) {
787 /* first plt entry */
788 p = section_ptr_add(plt, 16);
789 p[0] = 0xff; /* pushl got + PTR_SIZE */
790 p[1] = modrm + 0x10;
791 put32(p + 2, PTR_SIZE);
792 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
793 p[7] = modrm;
794 put32(p + 8, PTR_SIZE * 2);
797 p = section_ptr_add(plt, 16);
798 p[0] = 0xff; /* jmp *(got + x) */
799 p[1] = modrm;
800 put32(p + 2, s1->got->data_offset);
801 p[6] = 0x68; /* push $xxx */
802 put32(p + 7, (plt->data_offset - 32) >> 1);
803 p[11] = 0xe9; /* jmp plt_start */
804 put32(p + 12, -(plt->data_offset));
806 /* the symbol is modified so that it will be relocated to
807 the PLT */
808 if (s1->output_type == TCC_OUTPUT_EXE)
809 offset = plt->data_offset - 16;
811 #elif defined(TCC_TARGET_ARM)
812 if (reloc_type == R_ARM_JUMP_SLOT) {
813 Section *plt;
814 uint8_t *p;
816 /* if we build a DLL, we add a %ebx offset */
817 if (s1->output_type == TCC_OUTPUT_DLL)
818 error("DLLs unimplemented!");
820 /* add a PLT entry */
821 plt = s1->plt;
822 if (plt->data_offset == 0) {
823 /* first plt entry */
824 p = section_ptr_add(plt, 16);
825 put32(p , 0xe52de004);
826 put32(p + 4, 0xe59fe010);
827 put32(p + 8, 0xe08fe00e);
828 put32(p + 12, 0xe5bef008);
831 p = section_ptr_add(plt, 16);
832 put32(p , 0xe59fc004);
833 put32(p+4, 0xe08fc00c);
834 put32(p+8, 0xe59cf000);
835 put32(p+12, s1->got->data_offset);
837 /* the symbol is modified so that it will be relocated to
838 the PLT */
839 if (s1->output_type == TCC_OUTPUT_EXE)
840 offset = plt->data_offset - 16;
842 #elif defined(TCC_TARGET_C67)
843 error("C67 got not implemented");
844 #else
845 #error unsupported CPU
846 #endif
847 index = put_elf_sym(s1->dynsym, offset,
848 size, info, 0, sym->st_shndx, name);
849 /* put a got entry */
850 put_elf_reloc(s1->dynsym, s1->got,
851 s1->got->data_offset,
852 reloc_type, index);
854 ptr = section_ptr_add(s1->got, PTR_SIZE);
855 *ptr = 0;
858 /* build GOT and PLT entries */
859 static void build_got_entries(TCCState *s1)
861 Section *s, *symtab;
862 ElfW_Rel *rel, *rel_end;
863 ElfW(Sym) *sym;
864 int i, type, reloc_type, sym_index;
866 for(i = 1; i < s1->nb_sections; i++) {
867 s = s1->sections[i];
868 if (s->sh_type != SHT_RELX)
869 continue;
870 /* no need to handle got relocations */
871 if (s->link != symtab_section)
872 continue;
873 symtab = s->link;
874 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
875 for(rel = (ElfW_Rel *)s->data;
876 rel < rel_end;
877 rel++) {
878 type = ELFW(R_TYPE)(rel->r_info);
879 switch(type) {
880 #if defined(TCC_TARGET_I386)
881 case R_386_GOT32:
882 case R_386_GOTOFF:
883 case R_386_GOTPC:
884 case R_386_PLT32:
885 if (!s1->got)
886 build_got(s1);
887 if (type == R_386_GOT32 || type == R_386_PLT32) {
888 sym_index = ELFW(R_SYM)(rel->r_info);
889 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
890 /* look at the symbol got offset. If none, then add one */
891 if (type == R_386_GOT32)
892 reloc_type = R_386_GLOB_DAT;
893 else
894 reloc_type = R_386_JMP_SLOT;
895 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
896 sym_index);
898 break;
899 #elif defined(TCC_TARGET_ARM)
900 case R_ARM_GOT_BREL:
901 case R_ARM_GOTOFF32:
902 case R_ARM_BASE_PREL:
903 case R_ARM_PLT32:
904 if (!s1->got)
905 build_got(s1);
906 if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) {
907 sym_index = ELFW(R_SYM)(rel->r_info);
908 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
909 /* look at the symbol got offset. If none, then add one */
910 if (type == R_ARM_GOT_BREL)
911 reloc_type = R_ARM_GLOB_DAT;
912 else
913 reloc_type = R_ARM_JUMP_SLOT;
914 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
915 sym_index);
917 break;
918 #elif defined(TCC_TARGET_C67)
919 case R_C60_GOT32:
920 case R_C60_GOTOFF:
921 case R_C60_GOTPC:
922 case R_C60_PLT32:
923 if (!s1->got)
924 build_got(s1);
925 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
926 sym_index = ELFW(R_SYM)(rel->r_info);
927 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
928 /* look at the symbol got offset. If none, then add one */
929 if (type == R_C60_GOT32)
930 reloc_type = R_C60_GLOB_DAT;
931 else
932 reloc_type = R_C60_JMP_SLOT;
933 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
934 sym_index);
936 break;
937 #else
938 #error unsupported CPU
939 #endif
940 default:
941 break;
947 static Section *new_symtab(TCCState *s1,
948 const char *symtab_name, int sh_type, int sh_flags,
949 const char *strtab_name,
950 const char *hash_name, int hash_sh_flags)
952 Section *symtab, *strtab, *hash;
953 int *ptr, nb_buckets;
955 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
956 symtab->sh_entsize = sizeof(ElfW(Sym));
957 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
958 put_elf_str(strtab, "");
959 symtab->link = strtab;
960 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
962 nb_buckets = 1;
964 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
965 hash->sh_entsize = sizeof(int);
966 symtab->hash = hash;
967 hash->link = symtab;
969 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
970 ptr[0] = nb_buckets;
971 ptr[1] = 1;
972 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
973 return symtab;
976 /* put dynamic tag */
977 static void put_dt(Section *dynamic, int dt, unsigned long val)
979 ElfW(Dyn) *dyn;
980 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
981 dyn->d_tag = dt;
982 dyn->d_un.d_val = val;
985 static void add_init_array_defines(TCCState *s1, const char *section_name)
987 Section *s;
988 long end_offset;
989 char sym_start[1024];
990 char sym_end[1024];
992 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
993 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
995 s = find_section(s1, section_name);
996 if (!s) {
997 end_offset = 0;
998 s = data_section;
999 } else {
1000 end_offset = s->data_offset;
1003 add_elf_sym(symtab_section,
1004 0, 0,
1005 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1006 s->sh_num, sym_start);
1007 add_elf_sym(symtab_section,
1008 end_offset, 0,
1009 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1010 s->sh_num, sym_end);
1013 /* add tcc runtime libraries */
1014 static void tcc_add_runtime(TCCState *s1)
1016 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1017 char buf[1024];
1018 #endif
1020 #ifdef CONFIG_TCC_BCHECK
1021 if (do_bounds_check) {
1022 unsigned long *ptr;
1023 Section *init_section;
1024 unsigned char *pinit;
1025 int sym_index;
1027 /* XXX: add an object file to do that */
1028 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
1029 *ptr = 0;
1030 add_elf_sym(symtab_section, 0, 0,
1031 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1032 bounds_section->sh_num, "__bounds_start");
1033 /* add bound check code */
1034 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
1035 tcc_add_file(s1, buf);
1036 #ifdef TCC_TARGET_I386
1037 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1038 /* add 'call __bound_init()' in .init section */
1039 init_section = find_section(s1, ".init");
1040 pinit = section_ptr_add(init_section, 5);
1041 pinit[0] = 0xe8;
1042 put32(pinit + 1, -4);
1043 sym_index = find_elf_sym(symtab_section, "__bound_init");
1044 put_elf_reloc(symtab_section, init_section,
1045 init_section->data_offset - 4, R_386_PC32, sym_index);
1047 #endif
1049 #endif
1050 /* add libc */
1051 if (!s1->nostdlib) {
1052 tcc_add_library(s1, "c");
1054 #ifdef CONFIG_USE_LIBGCC
1055 tcc_add_file(s1, CONFIG_SYSROOT "/lib/libgcc_s.so.1");
1056 #else
1057 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
1058 tcc_add_file(s1, buf);
1059 #endif
1061 /* add crt end if not memory output */
1062 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
1063 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1067 /* add various standard linker symbols (must be done after the
1068 sections are filled (for example after allocating common
1069 symbols)) */
1070 static void tcc_add_linker_symbols(TCCState *s1)
1072 char buf[1024];
1073 int i;
1074 Section *s;
1076 add_elf_sym(symtab_section,
1077 text_section->data_offset, 0,
1078 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1079 text_section->sh_num, "_etext");
1080 add_elf_sym(symtab_section,
1081 data_section->data_offset, 0,
1082 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1083 data_section->sh_num, "_edata");
1084 add_elf_sym(symtab_section,
1085 bss_section->data_offset, 0,
1086 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1087 bss_section->sh_num, "_end");
1088 /* horrible new standard ldscript defines */
1089 add_init_array_defines(s1, ".preinit_array");
1090 add_init_array_defines(s1, ".init_array");
1091 add_init_array_defines(s1, ".fini_array");
1093 /* add start and stop symbols for sections whose name can be
1094 expressed in C */
1095 for(i = 1; i < s1->nb_sections; i++) {
1096 s = s1->sections[i];
1097 if (s->sh_type == SHT_PROGBITS &&
1098 (s->sh_flags & SHF_ALLOC)) {
1099 const char *p;
1100 int ch;
1102 /* check if section name can be expressed in C */
1103 p = s->name;
1104 for(;;) {
1105 ch = *p;
1106 if (!ch)
1107 break;
1108 if (!isid(ch) && !isnum(ch))
1109 goto next_sec;
1110 p++;
1112 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1113 add_elf_sym(symtab_section,
1114 0, 0,
1115 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1116 s->sh_num, buf);
1117 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1118 add_elf_sym(symtab_section,
1119 s->data_offset, 0,
1120 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1121 s->sh_num, buf);
1123 next_sec: ;
1127 /* name of ELF interpreter */
1128 #ifdef __FreeBSD__
1129 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1130 #else
1131 #ifdef TCC_ARM_EABI
1132 static char elf_interp[] = "/lib/ld-linux.so.3";
1133 #else
1134 static char elf_interp[] = "/lib/ld-linux.so.2";
1135 #endif
1136 #endif
1138 static void tcc_output_binary(TCCState *s1, FILE *f,
1139 const int *section_order)
1141 Section *s;
1142 int i, offset, size;
1144 offset = 0;
1145 for(i=1;i<s1->nb_sections;i++) {
1146 s = s1->sections[section_order[i]];
1147 if (s->sh_type != SHT_NOBITS &&
1148 (s->sh_flags & SHF_ALLOC)) {
1149 while (offset < s->sh_offset) {
1150 fputc(0, f);
1151 offset++;
1153 size = s->sh_size;
1154 fwrite(s->data, 1, size, f);
1155 offset += size;
1160 /* output an ELF file */
1161 /* XXX: suppress unneeded sections */
1162 int elf_output_file(TCCState *s1, const char *filename)
1164 ElfW(Ehdr) ehdr;
1165 FILE *f;
1166 int fd, mode, ret;
1167 int *section_order;
1168 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1169 unsigned long addr;
1170 Section *strsec, *s;
1171 ElfW(Shdr) shdr, *sh;
1172 ElfW(Phdr) *phdr, *ph;
1173 Section *interp, *dynamic, *dynstr;
1174 unsigned long saved_dynamic_data_offset;
1175 ElfW(Sym) *sym;
1176 int type, file_type;
1177 unsigned long rel_addr, rel_size;
1179 file_type = s1->output_type;
1180 s1->nb_errors = 0;
1182 if (file_type != TCC_OUTPUT_OBJ) {
1183 tcc_add_runtime(s1);
1186 phdr = NULL;
1187 section_order = NULL;
1188 interp = NULL;
1189 dynamic = NULL;
1190 dynstr = NULL; /* avoid warning */
1191 saved_dynamic_data_offset = 0; /* avoid warning */
1193 if (file_type != TCC_OUTPUT_OBJ) {
1194 relocate_common_syms();
1196 tcc_add_linker_symbols(s1);
1198 if (!s1->static_link) {
1199 const char *name;
1200 int sym_index, index;
1201 ElfW(Sym) *esym, *sym_end;
1203 if (file_type == TCC_OUTPUT_EXE) {
1204 char *ptr;
1205 /* add interpreter section only if executable */
1206 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1207 interp->sh_addralign = 1;
1208 ptr = section_ptr_add(interp, sizeof(elf_interp));
1209 strcpy(ptr, elf_interp);
1212 /* add dynamic symbol table */
1213 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1214 ".dynstr",
1215 ".hash", SHF_ALLOC);
1216 dynstr = s1->dynsym->link;
1218 /* add dynamic section */
1219 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1220 SHF_ALLOC | SHF_WRITE);
1221 dynamic->link = dynstr;
1222 dynamic->sh_entsize = sizeof(ElfW(Dyn));
1224 /* add PLT */
1225 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1226 SHF_ALLOC | SHF_EXECINSTR);
1227 s1->plt->sh_entsize = 4;
1229 build_got(s1);
1231 /* scan for undefined symbols and see if they are in the
1232 dynamic symbols. If a symbol STT_FUNC is found, then we
1233 add it in the PLT. If a symbol STT_OBJECT is found, we
1234 add it in the .bss section with a suitable relocation */
1235 sym_end = (ElfW(Sym) *)(symtab_section->data +
1236 symtab_section->data_offset);
1237 if (file_type == TCC_OUTPUT_EXE) {
1238 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1239 sym < sym_end;
1240 sym++) {
1241 if (sym->st_shndx == SHN_UNDEF) {
1242 name = symtab_section->link->data + sym->st_name;
1243 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1244 if (sym_index) {
1245 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1246 type = ELFW(ST_TYPE)(esym->st_info);
1247 if (type == STT_FUNC) {
1248 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1249 esym->st_info,
1250 sym - (ElfW(Sym) *)symtab_section->data);
1251 } else if (type == STT_OBJECT) {
1252 unsigned long offset;
1253 offset = bss_section->data_offset;
1254 /* XXX: which alignment ? */
1255 offset = (offset + 16 - 1) & -16;
1256 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1257 esym->st_info, 0,
1258 bss_section->sh_num, name);
1259 put_elf_reloc(s1->dynsym, bss_section,
1260 offset, R_COPY, index);
1261 offset += esym->st_size;
1262 bss_section->data_offset = offset;
1264 } else {
1265 /* STB_WEAK undefined symbols are accepted */
1266 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1267 it */
1268 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1269 !strcmp(name, "_fp_hw")) {
1270 } else {
1271 error_noabort("undefined symbol '%s'", name);
1274 } else if (s1->rdynamic &&
1275 ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1276 /* if -rdynamic option, then export all non
1277 local symbols */
1278 name = symtab_section->link->data + sym->st_name;
1279 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1280 sym->st_info, 0,
1281 sym->st_shndx, name);
1285 if (s1->nb_errors)
1286 goto fail;
1288 /* now look at unresolved dynamic symbols and export
1289 corresponding symbol */
1290 sym_end = (ElfW(Sym) *)(s1->dynsymtab_section->data +
1291 s1->dynsymtab_section->data_offset);
1292 for(esym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1;
1293 esym < sym_end;
1294 esym++) {
1295 if (esym->st_shndx == SHN_UNDEF) {
1296 name = s1->dynsymtab_section->link->data + esym->st_name;
1297 sym_index = find_elf_sym(symtab_section, name);
1298 if (sym_index) {
1299 /* XXX: avoid adding a symbol if already
1300 present because of -rdynamic ? */
1301 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1302 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1303 sym->st_info, 0,
1304 sym->st_shndx, name);
1305 } else {
1306 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1307 /* weak symbols can stay undefined */
1308 } else {
1309 warning("undefined dynamic symbol '%s'", name);
1314 } else {
1315 int nb_syms;
1316 /* shared library case : we simply export all the global symbols */
1317 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1318 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1319 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1320 sym < sym_end;
1321 sym++) {
1322 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1323 name = symtab_section->link->data + sym->st_name;
1324 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1325 sym->st_info, 0,
1326 sym->st_shndx, name);
1327 s1->symtab_to_dynsym[sym -
1328 (ElfW(Sym) *)symtab_section->data] =
1329 index;
1334 build_got_entries(s1);
1336 /* add a list of needed dlls */
1337 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1338 DLLReference *dllref = s1->loaded_dlls[i];
1339 if (dllref->level == 0)
1340 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1342 /* XXX: currently, since we do not handle PIC code, we
1343 must relocate the readonly segments */
1344 if (file_type == TCC_OUTPUT_DLL) {
1345 if (s1->soname)
1346 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
1347 put_dt(dynamic, DT_TEXTREL, 0);
1350 /* add necessary space for other entries */
1351 saved_dynamic_data_offset = dynamic->data_offset;
1352 dynamic->data_offset += sizeof(ElfW(Dyn)) * 9;
1353 } else {
1354 /* still need to build got entries in case of static link */
1355 build_got_entries(s1);
1359 memset(&ehdr, 0, sizeof(ehdr));
1361 /* we add a section for symbols */
1362 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1363 put_elf_str(strsec, "");
1365 /* compute number of sections */
1366 shnum = s1->nb_sections;
1368 /* this array is used to reorder sections in the output file */
1369 section_order = tcc_malloc(sizeof(int) * shnum);
1370 section_order[0] = 0;
1371 sh_order_index = 1;
1373 /* compute number of program headers */
1374 switch(file_type) {
1375 default:
1376 case TCC_OUTPUT_OBJ:
1377 phnum = 0;
1378 break;
1379 case TCC_OUTPUT_EXE:
1380 if (!s1->static_link)
1381 phnum = 4;
1382 else
1383 phnum = 2;
1384 break;
1385 case TCC_OUTPUT_DLL:
1386 phnum = 3;
1387 break;
1390 /* allocate strings for section names and decide if an unallocated
1391 section should be output */
1392 /* NOTE: the strsec section comes last, so its size is also
1393 correct ! */
1394 for(i = 1; i < s1->nb_sections; i++) {
1395 s = s1->sections[i];
1396 s->sh_name = put_elf_str(strsec, s->name);
1397 #if 0 //gr
1398 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1399 s->sh_flags,
1400 s->sh_type,
1401 s->sh_info,
1402 s->name,
1403 s->reloc ? s->reloc->name : "n"
1405 #endif
1406 /* when generating a DLL, we include relocations but we may
1407 patch them */
1408 if (file_type == TCC_OUTPUT_DLL &&
1409 s->sh_type == SHT_RELX &&
1410 !(s->sh_flags & SHF_ALLOC)) {
1411 /* //gr: avoid bogus relocs for empty (debug) sections */
1412 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1413 prepare_dynamic_rel(s1, s);
1414 else if (do_debug)
1415 s->sh_size = s->data_offset;
1416 } else if (do_debug ||
1417 file_type == TCC_OUTPUT_OBJ ||
1418 (s->sh_flags & SHF_ALLOC) ||
1419 i == (s1->nb_sections - 1)) {
1420 /* we output all sections if debug or object file */
1421 s->sh_size = s->data_offset;
1425 /* allocate program segment headers */
1426 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
1428 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1429 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1430 } else {
1431 file_offset = 0;
1433 if (phnum > 0) {
1434 /* compute section to program header mapping */
1435 if (s1->has_text_addr) {
1436 int a_offset, p_offset;
1437 addr = s1->text_addr;
1438 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1439 ELF_PAGE_SIZE */
1440 a_offset = addr & (ELF_PAGE_SIZE - 1);
1441 p_offset = file_offset & (ELF_PAGE_SIZE - 1);
1442 if (a_offset < p_offset)
1443 a_offset += ELF_PAGE_SIZE;
1444 file_offset += (a_offset - p_offset);
1445 } else {
1446 if (file_type == TCC_OUTPUT_DLL)
1447 addr = 0;
1448 else
1449 addr = ELF_START_ADDR;
1450 /* compute address after headers */
1451 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1454 /* dynamic relocation table information, for .dynamic section */
1455 rel_size = 0;
1456 rel_addr = 0;
1458 /* leave one program header for the program interpreter */
1459 ph = &phdr[0];
1460 if (interp)
1461 ph++;
1463 for(j = 0; j < 2; j++) {
1464 ph->p_type = PT_LOAD;
1465 if (j == 0)
1466 ph->p_flags = PF_R | PF_X;
1467 else
1468 ph->p_flags = PF_R | PF_W;
1469 ph->p_align = ELF_PAGE_SIZE;
1471 /* we do the following ordering: interp, symbol tables,
1472 relocations, progbits, nobits */
1473 /* XXX: do faster and simpler sorting */
1474 for(k = 0; k < 5; k++) {
1475 for(i = 1; i < s1->nb_sections; i++) {
1476 s = s1->sections[i];
1477 /* compute if section should be included */
1478 if (j == 0) {
1479 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1480 SHF_ALLOC)
1481 continue;
1482 } else {
1483 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1484 (SHF_ALLOC | SHF_WRITE))
1485 continue;
1487 if (s == interp) {
1488 if (k != 0)
1489 continue;
1490 } else if (s->sh_type == SHT_DYNSYM ||
1491 s->sh_type == SHT_STRTAB ||
1492 s->sh_type == SHT_HASH) {
1493 if (k != 1)
1494 continue;
1495 } else if (s->sh_type == SHT_RELX) {
1496 if (k != 2)
1497 continue;
1498 } else if (s->sh_type == SHT_NOBITS) {
1499 if (k != 4)
1500 continue;
1501 } else {
1502 if (k != 3)
1503 continue;
1505 section_order[sh_order_index++] = i;
1507 /* section matches: we align it and add its size */
1508 tmp = addr;
1509 addr = (addr + s->sh_addralign - 1) &
1510 ~(s->sh_addralign - 1);
1511 file_offset += addr - tmp;
1512 s->sh_offset = file_offset;
1513 s->sh_addr = addr;
1515 /* update program header infos */
1516 if (ph->p_offset == 0) {
1517 ph->p_offset = file_offset;
1518 ph->p_vaddr = addr;
1519 ph->p_paddr = ph->p_vaddr;
1521 /* update dynamic relocation infos */
1522 if (s->sh_type == SHT_RELX) {
1523 if (rel_size == 0)
1524 rel_addr = addr;
1525 rel_size += s->sh_size;
1527 addr += s->sh_size;
1528 if (s->sh_type != SHT_NOBITS)
1529 file_offset += s->sh_size;
1532 ph->p_filesz = file_offset - ph->p_offset;
1533 ph->p_memsz = addr - ph->p_vaddr;
1534 ph++;
1535 if (j == 0) {
1536 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1537 /* if in the middle of a page, we duplicate the page in
1538 memory so that one copy is RX and the other is RW */
1539 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1540 addr += ELF_PAGE_SIZE;
1541 } else {
1542 addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
1543 file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
1544 ~(ELF_PAGE_SIZE - 1);
1549 /* if interpreter, then add corresponing program header */
1550 if (interp) {
1551 ph = &phdr[0];
1553 ph->p_type = PT_INTERP;
1554 ph->p_offset = interp->sh_offset;
1555 ph->p_vaddr = interp->sh_addr;
1556 ph->p_paddr = ph->p_vaddr;
1557 ph->p_filesz = interp->sh_size;
1558 ph->p_memsz = interp->sh_size;
1559 ph->p_flags = PF_R;
1560 ph->p_align = interp->sh_addralign;
1563 /* if dynamic section, then add corresponing program header */
1564 if (dynamic) {
1565 ElfW(Sym) *sym_end;
1567 ph = &phdr[phnum - 1];
1569 ph->p_type = PT_DYNAMIC;
1570 ph->p_offset = dynamic->sh_offset;
1571 ph->p_vaddr = dynamic->sh_addr;
1572 ph->p_paddr = ph->p_vaddr;
1573 ph->p_filesz = dynamic->sh_size;
1574 ph->p_memsz = dynamic->sh_size;
1575 ph->p_flags = PF_R | PF_W;
1576 ph->p_align = dynamic->sh_addralign;
1578 /* put GOT dynamic section address */
1579 put32(s1->got->data, dynamic->sh_addr);
1581 /* relocate the PLT */
1582 if (file_type == TCC_OUTPUT_EXE) {
1583 uint8_t *p, *p_end;
1585 p = s1->plt->data;
1586 p_end = p + s1->plt->data_offset;
1587 if (p < p_end) {
1588 #if defined(TCC_TARGET_I386)
1589 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1590 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1591 p += 16;
1592 while (p < p_end) {
1593 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1594 p += 16;
1596 #elif defined(TCC_TARGET_ARM)
1597 int x;
1598 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1599 p +=16;
1600 while (p < p_end) {
1601 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1602 p += 16;
1604 #elif defined(TCC_TARGET_C67)
1605 /* XXX: TODO */
1606 #else
1607 #error unsupported CPU
1608 #endif
1612 /* relocate symbols in .dynsym */
1613 sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset);
1614 for(sym = (ElfW(Sym) *)s1->dynsym->data + 1;
1615 sym < sym_end;
1616 sym++) {
1617 if (sym->st_shndx == SHN_UNDEF) {
1618 /* relocate to the PLT if the symbol corresponds
1619 to a PLT entry */
1620 if (sym->st_value)
1621 sym->st_value += s1->plt->sh_addr;
1622 } else if (sym->st_shndx < SHN_LORESERVE) {
1623 /* do symbol relocation */
1624 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1628 /* put dynamic section entries */
1629 dynamic->data_offset = saved_dynamic_data_offset;
1630 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1631 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1632 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1633 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1634 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1635 put_dt(dynamic, DT_REL, rel_addr);
1636 put_dt(dynamic, DT_RELSZ, rel_size);
1637 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1638 if (do_debug)
1639 put_dt(dynamic, DT_DEBUG, 0);
1640 put_dt(dynamic, DT_NULL, 0);
1643 ehdr.e_phentsize = sizeof(ElfW(Phdr));
1644 ehdr.e_phnum = phnum;
1645 ehdr.e_phoff = sizeof(ElfW(Ehdr));
1648 /* all other sections come after */
1649 for(i = 1; i < s1->nb_sections; i++) {
1650 s = s1->sections[i];
1651 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1652 continue;
1653 section_order[sh_order_index++] = i;
1655 file_offset = (file_offset + s->sh_addralign - 1) &
1656 ~(s->sh_addralign - 1);
1657 s->sh_offset = file_offset;
1658 if (s->sh_type != SHT_NOBITS)
1659 file_offset += s->sh_size;
1662 /* if building executable or DLL, then relocate each section
1663 except the GOT which is already relocated */
1664 if (file_type != TCC_OUTPUT_OBJ) {
1665 relocate_syms(s1, 0);
1667 if (s1->nb_errors != 0) {
1668 fail:
1669 ret = -1;
1670 goto the_end;
1673 /* relocate sections */
1674 /* XXX: ignore sections with allocated relocations ? */
1675 for(i = 1; i < s1->nb_sections; i++) {
1676 s = s1->sections[i];
1677 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
1678 relocate_section(s1, s);
1681 /* relocate relocation entries if the relocation tables are
1682 allocated in the executable */
1683 for(i = 1; i < s1->nb_sections; i++) {
1684 s = s1->sections[i];
1685 if ((s->sh_flags & SHF_ALLOC) &&
1686 s->sh_type == SHT_RELX) {
1687 relocate_rel(s1, s);
1691 /* get entry point address */
1692 if (file_type == TCC_OUTPUT_EXE)
1693 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
1694 else
1695 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1698 /* write elf file */
1699 if (file_type == TCC_OUTPUT_OBJ)
1700 mode = 0666;
1701 else
1702 mode = 0777;
1703 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1704 if (fd < 0) {
1705 error_noabort("could not write '%s'", filename);
1706 goto fail;
1708 f = fdopen(fd, "wb");
1709 if (verbose)
1710 printf("<- %s\n", filename);
1712 #ifdef TCC_TARGET_COFF
1713 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1714 tcc_output_coff(s1, f);
1715 } else
1716 #endif
1717 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1718 sort_syms(s1, symtab_section);
1720 /* align to 4 */
1721 file_offset = (file_offset + 3) & -4;
1723 /* fill header */
1724 ehdr.e_ident[0] = ELFMAG0;
1725 ehdr.e_ident[1] = ELFMAG1;
1726 ehdr.e_ident[2] = ELFMAG2;
1727 ehdr.e_ident[3] = ELFMAG3;
1728 ehdr.e_ident[4] = TCC_ELFCLASS;
1729 ehdr.e_ident[5] = ELFDATA2LSB;
1730 ehdr.e_ident[6] = EV_CURRENT;
1731 #ifdef __FreeBSD__
1732 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1733 #endif
1734 #ifdef TCC_TARGET_ARM
1735 #ifdef TCC_ARM_EABI
1736 ehdr.e_ident[EI_OSABI] = 0;
1737 ehdr.e_flags = 4 << 24;
1738 #else
1739 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1740 #endif
1741 #endif
1742 switch(file_type) {
1743 default:
1744 case TCC_OUTPUT_EXE:
1745 ehdr.e_type = ET_EXEC;
1746 break;
1747 case TCC_OUTPUT_DLL:
1748 ehdr.e_type = ET_DYN;
1749 break;
1750 case TCC_OUTPUT_OBJ:
1751 ehdr.e_type = ET_REL;
1752 break;
1754 ehdr.e_machine = EM_TCC_TARGET;
1755 ehdr.e_version = EV_CURRENT;
1756 ehdr.e_shoff = file_offset;
1757 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
1758 ehdr.e_shentsize = sizeof(ElfW(Shdr));
1759 ehdr.e_shnum = shnum;
1760 ehdr.e_shstrndx = shnum - 1;
1762 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
1763 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
1764 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1766 for(i=1;i<s1->nb_sections;i++) {
1767 s = s1->sections[section_order[i]];
1768 if (s->sh_type != SHT_NOBITS) {
1769 while (offset < s->sh_offset) {
1770 fputc(0, f);
1771 offset++;
1773 size = s->sh_size;
1774 fwrite(s->data, 1, size, f);
1775 offset += size;
1779 /* output section headers */
1780 while (offset < ehdr.e_shoff) {
1781 fputc(0, f);
1782 offset++;
1785 for(i=0;i<s1->nb_sections;i++) {
1786 sh = &shdr;
1787 memset(sh, 0, sizeof(ElfW(Shdr)));
1788 s = s1->sections[i];
1789 if (s) {
1790 sh->sh_name = s->sh_name;
1791 sh->sh_type = s->sh_type;
1792 sh->sh_flags = s->sh_flags;
1793 sh->sh_entsize = s->sh_entsize;
1794 sh->sh_info = s->sh_info;
1795 if (s->link)
1796 sh->sh_link = s->link->sh_num;
1797 sh->sh_addralign = s->sh_addralign;
1798 sh->sh_addr = s->sh_addr;
1799 sh->sh_offset = s->sh_offset;
1800 sh->sh_size = s->sh_size;
1802 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
1804 } else {
1805 tcc_output_binary(s1, f, section_order);
1807 fclose(f);
1809 ret = 0;
1810 the_end:
1811 tcc_free(s1->symtab_to_dynsym);
1812 tcc_free(section_order);
1813 tcc_free(phdr);
1814 tcc_free(s1->got_offsets);
1815 return ret;
1818 int tcc_output_file(TCCState *s, const char *filename)
1820 int ret;
1821 #ifdef TCC_TARGET_PE
1822 if (s->output_type != TCC_OUTPUT_OBJ) {
1823 ret = pe_output_file(s, filename);
1824 } else
1825 #endif
1827 ret = elf_output_file(s, filename);
1829 return ret;
1832 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1834 void *data;
1836 data = tcc_malloc(size);
1837 lseek(fd, file_offset, SEEK_SET);
1838 read(fd, data, size);
1839 return data;
1842 typedef struct SectionMergeInfo {
1843 Section *s; /* corresponding existing section */
1844 unsigned long offset; /* offset of the new section in the existing section */
1845 uint8_t new_section; /* true if section 's' was added */
1846 uint8_t link_once; /* true if link once section */
1847 } SectionMergeInfo;
1849 /* load an object file and merge it with current files */
1850 /* XXX: handle correctly stab (debug) info */
1851 static int tcc_load_object_file(TCCState *s1,
1852 int fd, unsigned long file_offset)
1854 ElfW(Ehdr) ehdr;
1855 ElfW(Shdr) *shdr, *sh;
1856 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1857 unsigned char *strsec, *strtab;
1858 int *old_to_new_syms;
1859 char *sh_name, *name;
1860 SectionMergeInfo *sm_table, *sm;
1861 ElfW(Sym) *sym, *symtab;
1862 ElfW_Rel *rel, *rel_end;
1863 Section *s;
1865 int stab_index;
1866 int stabstr_index;
1868 stab_index = stabstr_index = 0;
1870 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1871 goto fail1;
1872 if (ehdr.e_ident[0] != ELFMAG0 ||
1873 ehdr.e_ident[1] != ELFMAG1 ||
1874 ehdr.e_ident[2] != ELFMAG2 ||
1875 ehdr.e_ident[3] != ELFMAG3)
1876 goto fail1;
1877 /* test if object file */
1878 if (ehdr.e_type != ET_REL)
1879 goto fail1;
1880 /* test CPU specific stuff */
1881 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1882 ehdr.e_machine != EM_TCC_TARGET) {
1883 fail1:
1884 error_noabort("invalid object file");
1885 return -1;
1887 /* read sections */
1888 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1889 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
1890 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1892 /* load section names */
1893 sh = &shdr[ehdr.e_shstrndx];
1894 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1896 /* load symtab and strtab */
1897 old_to_new_syms = NULL;
1898 symtab = NULL;
1899 strtab = NULL;
1900 nb_syms = 0;
1901 for(i = 1; i < ehdr.e_shnum; i++) {
1902 sh = &shdr[i];
1903 if (sh->sh_type == SHT_SYMTAB) {
1904 if (symtab) {
1905 error_noabort("object must contain only one symtab");
1906 fail:
1907 ret = -1;
1908 goto the_end;
1910 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
1911 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1912 sm_table[i].s = symtab_section;
1914 /* now load strtab */
1915 sh = &shdr[sh->sh_link];
1916 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1920 /* now examine each section and try to merge its content with the
1921 ones in memory */
1922 for(i = 1; i < ehdr.e_shnum; i++) {
1923 /* no need to examine section name strtab */
1924 if (i == ehdr.e_shstrndx)
1925 continue;
1926 sh = &shdr[i];
1927 sh_name = strsec + sh->sh_name;
1928 /* ignore sections types we do not handle */
1929 if (sh->sh_type != SHT_PROGBITS &&
1930 sh->sh_type != SHT_RELX &&
1931 #ifdef TCC_ARM_EABI
1932 sh->sh_type != SHT_ARM_EXIDX &&
1933 #endif
1934 sh->sh_type != SHT_NOBITS &&
1935 strcmp(sh_name, ".stabstr")
1937 continue;
1938 if (sh->sh_addralign < 1)
1939 sh->sh_addralign = 1;
1940 /* find corresponding section, if any */
1941 for(j = 1; j < s1->nb_sections;j++) {
1942 s = s1->sections[j];
1943 if (!strcmp(s->name, sh_name)) {
1944 if (!strncmp(sh_name, ".gnu.linkonce",
1945 sizeof(".gnu.linkonce") - 1)) {
1946 /* if a 'linkonce' section is already present, we
1947 do not add it again. It is a little tricky as
1948 symbols can still be defined in
1949 it. */
1950 sm_table[i].link_once = 1;
1951 goto next;
1952 } else {
1953 goto found;
1957 /* not found: create new section */
1958 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1959 /* take as much info as possible from the section. sh_link and
1960 sh_info will be updated later */
1961 s->sh_addralign = sh->sh_addralign;
1962 s->sh_entsize = sh->sh_entsize;
1963 sm_table[i].new_section = 1;
1964 found:
1965 if (sh->sh_type != s->sh_type) {
1966 error_noabort("invalid section type");
1967 goto fail;
1970 /* align start of section */
1971 offset = s->data_offset;
1973 if (0 == strcmp(sh_name, ".stab")) {
1974 stab_index = i;
1975 goto no_align;
1977 if (0 == strcmp(sh_name, ".stabstr")) {
1978 stabstr_index = i;
1979 goto no_align;
1982 size = sh->sh_addralign - 1;
1983 offset = (offset + size) & ~size;
1984 if (sh->sh_addralign > s->sh_addralign)
1985 s->sh_addralign = sh->sh_addralign;
1986 s->data_offset = offset;
1987 no_align:
1988 sm_table[i].offset = offset;
1989 sm_table[i].s = s;
1990 /* concatenate sections */
1991 size = sh->sh_size;
1992 if (sh->sh_type != SHT_NOBITS) {
1993 unsigned char *ptr;
1994 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1995 ptr = section_ptr_add(s, size);
1996 read(fd, ptr, size);
1997 } else {
1998 s->data_offset += size;
2000 next: ;
2003 /* //gr relocate stab strings */
2004 if (stab_index && stabstr_index) {
2005 Stab_Sym *a, *b;
2006 unsigned o;
2007 s = sm_table[stab_index].s;
2008 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2009 b = (Stab_Sym *)(s->data + s->data_offset);
2010 o = sm_table[stabstr_index].offset;
2011 while (a < b)
2012 a->n_strx += o, a++;
2015 /* second short pass to update sh_link and sh_info fields of new
2016 sections */
2017 for(i = 1; i < ehdr.e_shnum; i++) {
2018 s = sm_table[i].s;
2019 if (!s || !sm_table[i].new_section)
2020 continue;
2021 sh = &shdr[i];
2022 if (sh->sh_link > 0)
2023 s->link = sm_table[sh->sh_link].s;
2024 if (sh->sh_type == SHT_RELX) {
2025 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2026 /* update backward link */
2027 s1->sections[s->sh_info]->reloc = s;
2030 sm = sm_table;
2032 /* resolve symbols */
2033 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2035 sym = symtab + 1;
2036 for(i = 1; i < nb_syms; i++, sym++) {
2037 if (sym->st_shndx != SHN_UNDEF &&
2038 sym->st_shndx < SHN_LORESERVE) {
2039 sm = &sm_table[sym->st_shndx];
2040 if (sm->link_once) {
2041 /* if a symbol is in a link once section, we use the
2042 already defined symbol. It is very important to get
2043 correct relocations */
2044 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2045 name = strtab + sym->st_name;
2046 sym_index = find_elf_sym(symtab_section, name);
2047 if (sym_index)
2048 old_to_new_syms[i] = sym_index;
2050 continue;
2052 /* if no corresponding section added, no need to add symbol */
2053 if (!sm->s)
2054 continue;
2055 /* convert section number */
2056 sym->st_shndx = sm->s->sh_num;
2057 /* offset value */
2058 sym->st_value += sm->offset;
2060 /* add symbol */
2061 name = strtab + sym->st_name;
2062 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
2063 sym->st_info, sym->st_other,
2064 sym->st_shndx, name);
2065 old_to_new_syms[i] = sym_index;
2068 /* third pass to patch relocation entries */
2069 for(i = 1; i < ehdr.e_shnum; i++) {
2070 s = sm_table[i].s;
2071 if (!s)
2072 continue;
2073 sh = &shdr[i];
2074 offset = sm_table[i].offset;
2075 switch(s->sh_type) {
2076 case SHT_RELX:
2077 /* take relocation offset information */
2078 offseti = sm_table[sh->sh_info].offset;
2079 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
2080 for(rel = (ElfW_Rel *)(s->data + offset);
2081 rel < rel_end;
2082 rel++) {
2083 int type;
2084 unsigned sym_index;
2085 /* convert symbol index */
2086 type = ELFW(R_TYPE)(rel->r_info);
2087 sym_index = ELFW(R_SYM)(rel->r_info);
2088 /* NOTE: only one symtab assumed */
2089 if (sym_index >= nb_syms)
2090 goto invalid_reloc;
2091 sym_index = old_to_new_syms[sym_index];
2092 /* ignore link_once in rel section. */
2093 if (!sym_index && !sm->link_once) {
2094 invalid_reloc:
2095 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2096 i, strsec + sh->sh_name, rel->r_offset);
2097 goto fail;
2099 rel->r_info = ELFW(R_INFO)(sym_index, type);
2100 /* offset the relocation offset */
2101 rel->r_offset += offseti;
2103 break;
2104 default:
2105 break;
2109 ret = 0;
2110 the_end:
2111 tcc_free(symtab);
2112 tcc_free(strtab);
2113 tcc_free(old_to_new_syms);
2114 tcc_free(sm_table);
2115 tcc_free(strsec);
2116 tcc_free(shdr);
2117 return ret;
2120 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2122 typedef struct ArchiveHeader {
2123 char ar_name[16]; /* name of this member */
2124 char ar_date[12]; /* file mtime */
2125 char ar_uid[6]; /* owner uid; printed as decimal */
2126 char ar_gid[6]; /* owner gid; printed as decimal */
2127 char ar_mode[8]; /* file mode, printed as octal */
2128 char ar_size[10]; /* file size, printed as decimal */
2129 char ar_fmag[2]; /* should contain ARFMAG */
2130 } ArchiveHeader;
2132 static int get_be32(const uint8_t *b)
2134 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2137 /* load only the objects which resolve undefined symbols */
2138 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
2140 int i, bound, nsyms, sym_index, off, ret;
2141 uint8_t *data;
2142 const char *ar_names, *p;
2143 const uint8_t *ar_index;
2144 ElfW(Sym) *sym;
2146 data = tcc_malloc(size);
2147 if (read(fd, data, size) != size)
2148 goto fail;
2149 nsyms = get_be32(data);
2150 ar_index = data + 4;
2151 ar_names = ar_index + nsyms * 4;
2153 do {
2154 bound = 0;
2155 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2156 sym_index = find_elf_sym(symtab_section, p);
2157 if(sym_index) {
2158 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2159 if(sym->st_shndx == SHN_UNDEF) {
2160 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2161 #if 0
2162 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2163 #endif
2164 ++bound;
2165 lseek(fd, off, SEEK_SET);
2166 if(tcc_load_object_file(s1, fd, off) < 0) {
2167 fail:
2168 ret = -1;
2169 goto the_end;
2174 } while(bound);
2175 ret = 0;
2176 the_end:
2177 tcc_free(data);
2178 return ret;
2181 /* load a '.a' file */
2182 static int tcc_load_archive(TCCState *s1, int fd)
2184 ArchiveHeader hdr;
2185 char ar_size[11];
2186 char ar_name[17];
2187 char magic[8];
2188 int size, len, i;
2189 unsigned long file_offset;
2191 /* skip magic which was already checked */
2192 read(fd, magic, sizeof(magic));
2194 for(;;) {
2195 len = read(fd, &hdr, sizeof(hdr));
2196 if (len == 0)
2197 break;
2198 if (len != sizeof(hdr)) {
2199 error_noabort("invalid archive");
2200 return -1;
2202 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2203 ar_size[sizeof(hdr.ar_size)] = '\0';
2204 size = strtol(ar_size, NULL, 0);
2205 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2206 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2207 if (ar_name[i] != ' ')
2208 break;
2210 ar_name[i + 1] = '\0';
2211 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2212 file_offset = lseek(fd, 0, SEEK_CUR);
2213 /* align to even */
2214 size = (size + 1) & ~1;
2215 if (!strcmp(ar_name, "/")) {
2216 /* coff symbol table : we handle it */
2217 if(s1->alacarte_link)
2218 return tcc_load_alacarte(s1, fd, size);
2219 } else if (!strcmp(ar_name, "//") ||
2220 !strcmp(ar_name, "__.SYMDEF") ||
2221 !strcmp(ar_name, "__.SYMDEF/") ||
2222 !strcmp(ar_name, "ARFILENAMES/")) {
2223 /* skip symbol table or archive names */
2224 } else {
2225 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2226 return -1;
2228 lseek(fd, file_offset + size, SEEK_SET);
2230 return 0;
2233 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2234 is referenced by the user (so it should be added as DT_NEEDED in
2235 the generated ELF file) */
2236 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2238 ElfW(Ehdr) ehdr;
2239 ElfW(Shdr) *shdr, *sh, *sh1;
2240 int i, j, nb_syms, nb_dts, sym_bind, ret;
2241 ElfW(Sym) *sym, *dynsym;
2242 ElfW(Dyn) *dt, *dynamic;
2243 unsigned char *dynstr;
2244 const char *name, *soname;
2245 DLLReference *dllref;
2247 read(fd, &ehdr, sizeof(ehdr));
2249 /* test CPU specific stuff */
2250 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2251 ehdr.e_machine != EM_TCC_TARGET) {
2252 error_noabort("bad architecture");
2253 return -1;
2256 /* read sections */
2257 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2259 /* load dynamic section and dynamic symbols */
2260 nb_syms = 0;
2261 nb_dts = 0;
2262 dynamic = NULL;
2263 dynsym = NULL; /* avoid warning */
2264 dynstr = NULL; /* avoid warning */
2265 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2266 switch(sh->sh_type) {
2267 case SHT_DYNAMIC:
2268 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2269 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2270 break;
2271 case SHT_DYNSYM:
2272 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2273 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2274 sh1 = &shdr[sh->sh_link];
2275 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2276 break;
2277 default:
2278 break;
2282 /* compute the real library name */
2283 soname = tcc_basename(filename);
2285 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2286 if (dt->d_tag == DT_SONAME) {
2287 soname = dynstr + dt->d_un.d_val;
2291 /* if the dll is already loaded, do not load it */
2292 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2293 dllref = s1->loaded_dlls[i];
2294 if (!strcmp(soname, dllref->name)) {
2295 /* but update level if needed */
2296 if (level < dllref->level)
2297 dllref->level = level;
2298 ret = 0;
2299 goto the_end;
2303 // printf("loading dll '%s'\n", soname);
2305 /* add the dll and its level */
2306 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2307 dllref->level = level;
2308 strcpy(dllref->name, soname);
2309 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2311 /* add dynamic symbols in dynsym_section */
2312 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2313 sym_bind = ELFW(ST_BIND)(sym->st_info);
2314 if (sym_bind == STB_LOCAL)
2315 continue;
2316 name = dynstr + sym->st_name;
2317 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2318 sym->st_info, sym->st_other, sym->st_shndx, name);
2321 /* load all referenced DLLs */
2322 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2323 switch(dt->d_tag) {
2324 case DT_NEEDED:
2325 name = dynstr + dt->d_un.d_val;
2326 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2327 dllref = s1->loaded_dlls[j];
2328 if (!strcmp(name, dllref->name))
2329 goto already_loaded;
2331 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2332 error_noabort("referenced dll '%s' not found", name);
2333 ret = -1;
2334 goto the_end;
2336 already_loaded:
2337 break;
2340 ret = 0;
2341 the_end:
2342 tcc_free(dynstr);
2343 tcc_free(dynsym);
2344 tcc_free(dynamic);
2345 tcc_free(shdr);
2346 return ret;
2349 #define LD_TOK_NAME 256
2350 #define LD_TOK_EOF (-1)
2352 /* return next ld script token */
2353 static int ld_next(TCCState *s1, char *name, int name_size)
2355 int c;
2356 char *q;
2358 redo:
2359 switch(ch) {
2360 case ' ':
2361 case '\t':
2362 case '\f':
2363 case '\v':
2364 case '\r':
2365 case '\n':
2366 inp();
2367 goto redo;
2368 case '/':
2369 minp();
2370 if (ch == '*') {
2371 file->buf_ptr = parse_comment(file->buf_ptr);
2372 ch = file->buf_ptr[0];
2373 goto redo;
2374 } else {
2375 q = name;
2376 *q++ = '/';
2377 goto parse_name;
2379 break;
2380 /* case 'a' ... 'z': */
2381 case 'a':
2382 case 'b':
2383 case 'c':
2384 case 'd':
2385 case 'e':
2386 case 'f':
2387 case 'g':
2388 case 'h':
2389 case 'i':
2390 case 'j':
2391 case 'k':
2392 case 'l':
2393 case 'm':
2394 case 'n':
2395 case 'o':
2396 case 'p':
2397 case 'q':
2398 case 'r':
2399 case 's':
2400 case 't':
2401 case 'u':
2402 case 'v':
2403 case 'w':
2404 case 'x':
2405 case 'y':
2406 case 'z':
2407 /* case 'A' ... 'z': */
2408 case 'A':
2409 case 'B':
2410 case 'C':
2411 case 'D':
2412 case 'E':
2413 case 'F':
2414 case 'G':
2415 case 'H':
2416 case 'I':
2417 case 'J':
2418 case 'K':
2419 case 'L':
2420 case 'M':
2421 case 'N':
2422 case 'O':
2423 case 'P':
2424 case 'Q':
2425 case 'R':
2426 case 'S':
2427 case 'T':
2428 case 'U':
2429 case 'V':
2430 case 'W':
2431 case 'X':
2432 case 'Y':
2433 case 'Z':
2434 case '_':
2435 case '\\':
2436 case '.':
2437 case '$':
2438 case '~':
2439 q = name;
2440 parse_name:
2441 for(;;) {
2442 if (!((ch >= 'a' && ch <= 'z') ||
2443 (ch >= 'A' && ch <= 'Z') ||
2444 (ch >= '0' && ch <= '9') ||
2445 strchr("/.-_+=$:\\,~", ch)))
2446 break;
2447 if ((q - name) < name_size - 1) {
2448 *q++ = ch;
2450 minp();
2452 *q = '\0';
2453 c = LD_TOK_NAME;
2454 break;
2455 case CH_EOF:
2456 c = LD_TOK_EOF;
2457 break;
2458 default:
2459 c = ch;
2460 inp();
2461 break;
2463 #if 0
2464 printf("tok=%c %d\n", c, c);
2465 if (c == LD_TOK_NAME)
2466 printf(" name=%s\n", name);
2467 #endif
2468 return c;
2471 static int ld_add_file_list(TCCState *s1, int as_needed)
2473 char filename[1024];
2474 int t, ret;
2476 t = ld_next(s1, filename, sizeof(filename));
2477 if (t != '(')
2478 expect("(");
2479 t = ld_next(s1, filename, sizeof(filename));
2480 for(;;) {
2481 if (t == LD_TOK_EOF) {
2482 error_noabort("unexpected end of file");
2483 return -1;
2484 } else if (t == ')') {
2485 break;
2486 } else if (t != LD_TOK_NAME) {
2487 error_noabort("filename expected");
2488 return -1;
2490 if (!strcmp(filename, "AS_NEEDED")) {
2491 ret = ld_add_file_list(s1, 1);
2492 if (ret)
2493 return ret;
2494 } else {
2495 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2496 if (!as_needed)
2497 tcc_add_file(s1, filename);
2499 t = ld_next(s1, filename, sizeof(filename));
2500 if (t == ',') {
2501 t = ld_next(s1, filename, sizeof(filename));
2504 return 0;
2507 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2508 files */
2509 static int tcc_load_ldscript(TCCState *s1)
2511 char cmd[64];
2512 char filename[1024];
2513 int t, ret;
2515 ch = file->buf_ptr[0];
2516 ch = handle_eob();
2517 for(;;) {
2518 t = ld_next(s1, cmd, sizeof(cmd));
2519 if (t == LD_TOK_EOF)
2520 return 0;
2521 else if (t != LD_TOK_NAME)
2522 return -1;
2523 if (!strcmp(cmd, "INPUT") ||
2524 !strcmp(cmd, "GROUP")) {
2525 ret = ld_add_file_list(s1, 0);
2526 if (ret)
2527 return ret;
2528 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2529 !strcmp(cmd, "TARGET")) {
2530 /* ignore some commands */
2531 t = ld_next(s1, cmd, sizeof(cmd));
2532 if (t != '(')
2533 expect("(");
2534 for(;;) {
2535 t = ld_next(s1, filename, sizeof(filename));
2536 if (t == LD_TOK_EOF) {
2537 error_noabort("unexpected end of file");
2538 return -1;
2539 } else if (t == ')') {
2540 break;
2543 } else {
2544 return -1;
2547 return 0;