Introduce ElfW macro and ELFW to encapsulate the difference between Elf32_* and Elf64...
[tinycc/kirr.git] / tccelf.c
blob5d76b3141d82ef1b605bca05e2c66cdacc6acc10
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%s", 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 * sizeof(int));
728 /* keep space for _DYNAMIC pointer, if present */
729 put32(ptr, 0);
730 /* two dummy got entries */
731 put32(ptr + 4, 0);
732 put32(ptr + 8, 0);
735 /* put a got entry corresponding to a symbol in symtab_section. 'size'
736 and 'info' can be modifed if more precise info comes from the DLL */
737 static void put_got_entry(TCCState *s1,
738 int reloc_type, unsigned long size, int info,
739 int sym_index)
741 int index;
742 const char *name;
743 ElfW(Sym) *sym;
744 unsigned long offset;
745 int *ptr;
747 if (!s1->got)
748 build_got(s1);
750 /* if a got entry already exists for that symbol, no need to add one */
751 if (sym_index < s1->nb_got_offsets &&
752 s1->got_offsets[sym_index] != 0)
753 return;
755 put_got_offset(s1, sym_index, s1->got->data_offset);
757 if (s1->dynsym) {
758 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
759 name = symtab_section->link->data + sym->st_name;
760 offset = sym->st_value;
761 #ifdef TCC_TARGET_I386
762 if (reloc_type == R_386_JMP_SLOT) {
763 Section *plt;
764 uint8_t *p;
765 int modrm;
767 /* if we build a DLL, we add a %ebx offset */
768 if (s1->output_type == TCC_OUTPUT_DLL)
769 modrm = 0xa3;
770 else
771 modrm = 0x25;
773 /* add a PLT entry */
774 plt = s1->plt;
775 if (plt->data_offset == 0) {
776 /* first plt entry */
777 p = section_ptr_add(plt, 16);
778 p[0] = 0xff; /* pushl got + 4 */
779 p[1] = modrm + 0x10;
780 put32(p + 2, 4);
781 p[6] = 0xff; /* jmp *(got + 8) */
782 p[7] = modrm;
783 put32(p + 8, 8);
786 p = section_ptr_add(plt, 16);
787 p[0] = 0xff; /* jmp *(got + x) */
788 p[1] = modrm;
789 put32(p + 2, s1->got->data_offset);
790 p[6] = 0x68; /* push $xxx */
791 put32(p + 7, (plt->data_offset - 32) >> 1);
792 p[11] = 0xe9; /* jmp plt_start */
793 put32(p + 12, -(plt->data_offset));
795 /* the symbol is modified so that it will be relocated to
796 the PLT */
797 if (s1->output_type == TCC_OUTPUT_EXE)
798 offset = plt->data_offset - 16;
800 #elif defined(TCC_TARGET_ARM)
801 if (reloc_type == R_ARM_JUMP_SLOT) {
802 Section *plt;
803 uint8_t *p;
805 /* if we build a DLL, we add a %ebx offset */
806 if (s1->output_type == TCC_OUTPUT_DLL)
807 error("DLLs unimplemented!");
809 /* add a PLT entry */
810 plt = s1->plt;
811 if (plt->data_offset == 0) {
812 /* first plt entry */
813 p = section_ptr_add(plt, 16);
814 put32(p , 0xe52de004);
815 put32(p + 4, 0xe59fe010);
816 put32(p + 8, 0xe08fe00e);
817 put32(p + 12, 0xe5bef008);
820 p = section_ptr_add(plt, 16);
821 put32(p , 0xe59fc004);
822 put32(p+4, 0xe08fc00c);
823 put32(p+8, 0xe59cf000);
824 put32(p+12, s1->got->data_offset);
826 /* the symbol is modified so that it will be relocated to
827 the PLT */
828 if (s1->output_type == TCC_OUTPUT_EXE)
829 offset = plt->data_offset - 16;
831 #elif defined(TCC_TARGET_C67)
832 error("C67 got not implemented");
833 #else
834 #error unsupported CPU
835 #endif
836 index = put_elf_sym(s1->dynsym, offset,
837 size, info, 0, sym->st_shndx, name);
838 /* put a got entry */
839 put_elf_reloc(s1->dynsym, s1->got,
840 s1->got->data_offset,
841 reloc_type, index);
843 ptr = section_ptr_add(s1->got, sizeof(int));
844 *ptr = 0;
847 /* build GOT and PLT entries */
848 static void build_got_entries(TCCState *s1)
850 Section *s, *symtab;
851 ElfW_Rel *rel, *rel_end;
852 ElfW(Sym) *sym;
853 int i, type, reloc_type, sym_index;
855 for(i = 1; i < s1->nb_sections; i++) {
856 s = s1->sections[i];
857 if (s->sh_type != SHT_RELX)
858 continue;
859 /* no need to handle got relocations */
860 if (s->link != symtab_section)
861 continue;
862 symtab = s->link;
863 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
864 for(rel = (ElfW_Rel *)s->data;
865 rel < rel_end;
866 rel++) {
867 type = ELFW(R_TYPE)(rel->r_info);
868 switch(type) {
869 #if defined(TCC_TARGET_I386)
870 case R_386_GOT32:
871 case R_386_GOTOFF:
872 case R_386_GOTPC:
873 case R_386_PLT32:
874 if (!s1->got)
875 build_got(s1);
876 if (type == R_386_GOT32 || type == R_386_PLT32) {
877 sym_index = ELFW(R_SYM)(rel->r_info);
878 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
879 /* look at the symbol got offset. If none, then add one */
880 if (type == R_386_GOT32)
881 reloc_type = R_386_GLOB_DAT;
882 else
883 reloc_type = R_386_JMP_SLOT;
884 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
885 sym_index);
887 break;
888 #elif defined(TCC_TARGET_ARM)
889 case R_ARM_GOT_BREL:
890 case R_ARM_GOTOFF32:
891 case R_ARM_BASE_PREL:
892 case R_ARM_PLT32:
893 if (!s1->got)
894 build_got(s1);
895 if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) {
896 sym_index = ELFW(R_SYM)(rel->r_info);
897 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
898 /* look at the symbol got offset. If none, then add one */
899 if (type == R_ARM_GOT_BREL)
900 reloc_type = R_ARM_GLOB_DAT;
901 else
902 reloc_type = R_ARM_JUMP_SLOT;
903 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
904 sym_index);
906 break;
907 #elif defined(TCC_TARGET_C67)
908 case R_C60_GOT32:
909 case R_C60_GOTOFF:
910 case R_C60_GOTPC:
911 case R_C60_PLT32:
912 if (!s1->got)
913 build_got(s1);
914 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
915 sym_index = ELFW(R_SYM)(rel->r_info);
916 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
917 /* look at the symbol got offset. If none, then add one */
918 if (type == R_C60_GOT32)
919 reloc_type = R_C60_GLOB_DAT;
920 else
921 reloc_type = R_C60_JMP_SLOT;
922 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
923 sym_index);
925 break;
926 #else
927 #error unsupported CPU
928 #endif
929 default:
930 break;
936 static Section *new_symtab(TCCState *s1,
937 const char *symtab_name, int sh_type, int sh_flags,
938 const char *strtab_name,
939 const char *hash_name, int hash_sh_flags)
941 Section *symtab, *strtab, *hash;
942 int *ptr, nb_buckets;
944 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
945 symtab->sh_entsize = sizeof(ElfW(Sym));
946 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
947 put_elf_str(strtab, "");
948 symtab->link = strtab;
949 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
951 nb_buckets = 1;
953 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
954 hash->sh_entsize = sizeof(int);
955 symtab->hash = hash;
956 hash->link = symtab;
958 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
959 ptr[0] = nb_buckets;
960 ptr[1] = 1;
961 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
962 return symtab;
965 /* put dynamic tag */
966 static void put_dt(Section *dynamic, int dt, unsigned long val)
968 ElfW(Dyn) *dyn;
969 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
970 dyn->d_tag = dt;
971 dyn->d_un.d_val = val;
974 static void add_init_array_defines(TCCState *s1, const char *section_name)
976 Section *s;
977 long end_offset;
978 char sym_start[1024];
979 char sym_end[1024];
981 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
982 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
984 s = find_section(s1, section_name);
985 if (!s) {
986 end_offset = 0;
987 s = data_section;
988 } else {
989 end_offset = s->data_offset;
992 add_elf_sym(symtab_section,
993 0, 0,
994 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
995 s->sh_num, sym_start);
996 add_elf_sym(symtab_section,
997 end_offset, 0,
998 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
999 s->sh_num, sym_end);
1002 /* add tcc runtime libraries */
1003 static void tcc_add_runtime(TCCState *s1)
1005 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1006 char buf[1024];
1007 #endif
1009 #ifdef CONFIG_TCC_BCHECK
1010 if (do_bounds_check) {
1011 unsigned long *ptr;
1012 Section *init_section;
1013 unsigned char *pinit;
1014 int sym_index;
1016 /* XXX: add an object file to do that */
1017 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
1018 *ptr = 0;
1019 add_elf_sym(symtab_section, 0, 0,
1020 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1021 bounds_section->sh_num, "__bounds_start");
1022 /* add bound check code */
1023 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
1024 tcc_add_file(s1, buf);
1025 #ifdef TCC_TARGET_I386
1026 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1027 /* add 'call __bound_init()' in .init section */
1028 init_section = find_section(s1, ".init");
1029 pinit = section_ptr_add(init_section, 5);
1030 pinit[0] = 0xe8;
1031 put32(pinit + 1, -4);
1032 sym_index = find_elf_sym(symtab_section, "__bound_init");
1033 put_elf_reloc(symtab_section, init_section,
1034 init_section->data_offset - 4, R_386_PC32, sym_index);
1036 #endif
1038 #endif
1039 /* add libc */
1040 if (!s1->nostdlib) {
1041 tcc_add_library(s1, "c");
1043 #ifdef CONFIG_USE_LIBGCC
1044 tcc_add_file(s1, CONFIG_SYSROOT "/lib/libgcc_s.so.1");
1045 #else
1046 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
1047 tcc_add_file(s1, buf);
1048 #endif
1050 /* add crt end if not memory output */
1051 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
1052 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1056 /* add various standard linker symbols (must be done after the
1057 sections are filled (for example after allocating common
1058 symbols)) */
1059 static void tcc_add_linker_symbols(TCCState *s1)
1061 char buf[1024];
1062 int i;
1063 Section *s;
1065 add_elf_sym(symtab_section,
1066 text_section->data_offset, 0,
1067 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1068 text_section->sh_num, "_etext");
1069 add_elf_sym(symtab_section,
1070 data_section->data_offset, 0,
1071 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1072 data_section->sh_num, "_edata");
1073 add_elf_sym(symtab_section,
1074 bss_section->data_offset, 0,
1075 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1076 bss_section->sh_num, "_end");
1077 /* horrible new standard ldscript defines */
1078 add_init_array_defines(s1, ".preinit_array");
1079 add_init_array_defines(s1, ".init_array");
1080 add_init_array_defines(s1, ".fini_array");
1082 /* add start and stop symbols for sections whose name can be
1083 expressed in C */
1084 for(i = 1; i < s1->nb_sections; i++) {
1085 s = s1->sections[i];
1086 if (s->sh_type == SHT_PROGBITS &&
1087 (s->sh_flags & SHF_ALLOC)) {
1088 const char *p;
1089 int ch;
1091 /* check if section name can be expressed in C */
1092 p = s->name;
1093 for(;;) {
1094 ch = *p;
1095 if (!ch)
1096 break;
1097 if (!isid(ch) && !isnum(ch))
1098 goto next_sec;
1099 p++;
1101 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1102 add_elf_sym(symtab_section,
1103 0, 0,
1104 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1105 s->sh_num, buf);
1106 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1107 add_elf_sym(symtab_section,
1108 s->data_offset, 0,
1109 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1110 s->sh_num, buf);
1112 next_sec: ;
1116 /* name of ELF interpreter */
1117 #ifdef __FreeBSD__
1118 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1119 #else
1120 #ifdef TCC_ARM_EABI
1121 static char elf_interp[] = "/lib/ld-linux.so.3";
1122 #else
1123 static char elf_interp[] = "/lib/ld-linux.so.2";
1124 #endif
1125 #endif
1127 static void tcc_output_binary(TCCState *s1, FILE *f,
1128 const int *section_order)
1130 Section *s;
1131 int i, offset, size;
1133 offset = 0;
1134 for(i=1;i<s1->nb_sections;i++) {
1135 s = s1->sections[section_order[i]];
1136 if (s->sh_type != SHT_NOBITS &&
1137 (s->sh_flags & SHF_ALLOC)) {
1138 while (offset < s->sh_offset) {
1139 fputc(0, f);
1140 offset++;
1142 size = s->sh_size;
1143 fwrite(s->data, 1, size, f);
1144 offset += size;
1149 /* output an ELF file */
1150 /* XXX: suppress unneeded sections */
1151 int elf_output_file(TCCState *s1, const char *filename)
1153 ElfW(Ehdr) ehdr;
1154 FILE *f;
1155 int fd, mode, ret;
1156 int *section_order;
1157 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1158 unsigned long addr;
1159 Section *strsec, *s;
1160 ElfW(Shdr) shdr, *sh;
1161 ElfW(Phdr) *phdr, *ph;
1162 Section *interp, *dynamic, *dynstr;
1163 unsigned long saved_dynamic_data_offset;
1164 ElfW(Sym) *sym;
1165 int type, file_type;
1166 unsigned long rel_addr, rel_size;
1168 file_type = s1->output_type;
1169 s1->nb_errors = 0;
1171 if (file_type != TCC_OUTPUT_OBJ) {
1172 tcc_add_runtime(s1);
1175 phdr = NULL;
1176 section_order = NULL;
1177 interp = NULL;
1178 dynamic = NULL;
1179 dynstr = NULL; /* avoid warning */
1180 saved_dynamic_data_offset = 0; /* avoid warning */
1182 if (file_type != TCC_OUTPUT_OBJ) {
1183 relocate_common_syms();
1185 tcc_add_linker_symbols(s1);
1187 if (!s1->static_link) {
1188 const char *name;
1189 int sym_index, index;
1190 ElfW(Sym) *esym, *sym_end;
1192 if (file_type == TCC_OUTPUT_EXE) {
1193 char *ptr;
1194 /* add interpreter section only if executable */
1195 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1196 interp->sh_addralign = 1;
1197 ptr = section_ptr_add(interp, sizeof(elf_interp));
1198 strcpy(ptr, elf_interp);
1201 /* add dynamic symbol table */
1202 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1203 ".dynstr",
1204 ".hash", SHF_ALLOC);
1205 dynstr = s1->dynsym->link;
1207 /* add dynamic section */
1208 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1209 SHF_ALLOC | SHF_WRITE);
1210 dynamic->link = dynstr;
1211 dynamic->sh_entsize = sizeof(ElfW(Dyn));
1213 /* add PLT */
1214 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1215 SHF_ALLOC | SHF_EXECINSTR);
1216 s1->plt->sh_entsize = 4;
1218 build_got(s1);
1220 /* scan for undefined symbols and see if they are in the
1221 dynamic symbols. If a symbol STT_FUNC is found, then we
1222 add it in the PLT. If a symbol STT_OBJECT is found, we
1223 add it in the .bss section with a suitable relocation */
1224 sym_end = (ElfW(Sym) *)(symtab_section->data +
1225 symtab_section->data_offset);
1226 if (file_type == TCC_OUTPUT_EXE) {
1227 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1228 sym < sym_end;
1229 sym++) {
1230 if (sym->st_shndx == SHN_UNDEF) {
1231 name = symtab_section->link->data + sym->st_name;
1232 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1233 if (sym_index) {
1234 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1235 type = ELFW(ST_TYPE)(esym->st_info);
1236 if (type == STT_FUNC) {
1237 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1238 esym->st_info,
1239 sym - (ElfW(Sym) *)symtab_section->data);
1240 } else if (type == STT_OBJECT) {
1241 unsigned long offset;
1242 offset = bss_section->data_offset;
1243 /* XXX: which alignment ? */
1244 offset = (offset + 16 - 1) & -16;
1245 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1246 esym->st_info, 0,
1247 bss_section->sh_num, name);
1248 put_elf_reloc(s1->dynsym, bss_section,
1249 offset, R_COPY, index);
1250 offset += esym->st_size;
1251 bss_section->data_offset = offset;
1253 } else {
1254 /* STB_WEAK undefined symbols are accepted */
1255 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1256 it */
1257 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1258 !strcmp(name, "_fp_hw")) {
1259 } else {
1260 error_noabort("undefined symbol '%s'", name);
1263 } else if (s1->rdynamic &&
1264 ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1265 /* if -rdynamic option, then export all non
1266 local symbols */
1267 name = symtab_section->link->data + sym->st_name;
1268 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1269 sym->st_info, 0,
1270 sym->st_shndx, name);
1274 if (s1->nb_errors)
1275 goto fail;
1277 /* now look at unresolved dynamic symbols and export
1278 corresponding symbol */
1279 sym_end = (ElfW(Sym) *)(s1->dynsymtab_section->data +
1280 s1->dynsymtab_section->data_offset);
1281 for(esym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1;
1282 esym < sym_end;
1283 esym++) {
1284 if (esym->st_shndx == SHN_UNDEF) {
1285 name = s1->dynsymtab_section->link->data + esym->st_name;
1286 sym_index = find_elf_sym(symtab_section, name);
1287 if (sym_index) {
1288 /* XXX: avoid adding a symbol if already
1289 present because of -rdynamic ? */
1290 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1291 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1292 sym->st_info, 0,
1293 sym->st_shndx, name);
1294 } else {
1295 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1296 /* weak symbols can stay undefined */
1297 } else {
1298 warning("undefined dynamic symbol '%s'", name);
1303 } else {
1304 int nb_syms;
1305 /* shared library case : we simply export all the global symbols */
1306 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1307 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1308 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1309 sym < sym_end;
1310 sym++) {
1311 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1312 name = symtab_section->link->data + sym->st_name;
1313 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1314 sym->st_info, 0,
1315 sym->st_shndx, name);
1316 s1->symtab_to_dynsym[sym -
1317 (ElfW(Sym) *)symtab_section->data] =
1318 index;
1323 build_got_entries(s1);
1325 /* add a list of needed dlls */
1326 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1327 DLLReference *dllref = s1->loaded_dlls[i];
1328 if (dllref->level == 0)
1329 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1331 /* XXX: currently, since we do not handle PIC code, we
1332 must relocate the readonly segments */
1333 if (file_type == TCC_OUTPUT_DLL) {
1334 if (s1->soname)
1335 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
1336 put_dt(dynamic, DT_TEXTREL, 0);
1339 /* add necessary space for other entries */
1340 saved_dynamic_data_offset = dynamic->data_offset;
1341 dynamic->data_offset += 8 * 9;
1342 } else {
1343 /* still need to build got entries in case of static link */
1344 build_got_entries(s1);
1348 memset(&ehdr, 0, sizeof(ehdr));
1350 /* we add a section for symbols */
1351 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1352 put_elf_str(strsec, "");
1354 /* compute number of sections */
1355 shnum = s1->nb_sections;
1357 /* this array is used to reorder sections in the output file */
1358 section_order = tcc_malloc(sizeof(int) * shnum);
1359 section_order[0] = 0;
1360 sh_order_index = 1;
1362 /* compute number of program headers */
1363 switch(file_type) {
1364 default:
1365 case TCC_OUTPUT_OBJ:
1366 phnum = 0;
1367 break;
1368 case TCC_OUTPUT_EXE:
1369 if (!s1->static_link)
1370 phnum = 4;
1371 else
1372 phnum = 2;
1373 break;
1374 case TCC_OUTPUT_DLL:
1375 phnum = 3;
1376 break;
1379 /* allocate strings for section names and decide if an unallocated
1380 section should be output */
1381 /* NOTE: the strsec section comes last, so its size is also
1382 correct ! */
1383 for(i = 1; i < s1->nb_sections; i++) {
1384 s = s1->sections[i];
1385 s->sh_name = put_elf_str(strsec, s->name);
1386 #if 0 //gr
1387 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1388 s->sh_flags,
1389 s->sh_type,
1390 s->sh_info,
1391 s->name,
1392 s->reloc ? s->reloc->name : "n"
1394 #endif
1395 /* when generating a DLL, we include relocations but we may
1396 patch them */
1397 if (file_type == TCC_OUTPUT_DLL &&
1398 s->sh_type == SHT_RELX &&
1399 !(s->sh_flags & SHF_ALLOC)) {
1400 /* //gr: avoid bogus relocs for empty (debug) sections */
1401 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1402 prepare_dynamic_rel(s1, s);
1403 else if (do_debug)
1404 s->sh_size = s->data_offset;
1405 } else if (do_debug ||
1406 file_type == TCC_OUTPUT_OBJ ||
1407 (s->sh_flags & SHF_ALLOC) ||
1408 i == (s1->nb_sections - 1)) {
1409 /* we output all sections if debug or object file */
1410 s->sh_size = s->data_offset;
1414 /* allocate program segment headers */
1415 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
1417 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1418 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1419 } else {
1420 file_offset = 0;
1422 if (phnum > 0) {
1423 /* compute section to program header mapping */
1424 if (s1->has_text_addr) {
1425 int a_offset, p_offset;
1426 addr = s1->text_addr;
1427 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1428 ELF_PAGE_SIZE */
1429 a_offset = addr & (ELF_PAGE_SIZE - 1);
1430 p_offset = file_offset & (ELF_PAGE_SIZE - 1);
1431 if (a_offset < p_offset)
1432 a_offset += ELF_PAGE_SIZE;
1433 file_offset += (a_offset - p_offset);
1434 } else {
1435 if (file_type == TCC_OUTPUT_DLL)
1436 addr = 0;
1437 else
1438 addr = ELF_START_ADDR;
1439 /* compute address after headers */
1440 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1443 /* dynamic relocation table information, for .dynamic section */
1444 rel_size = 0;
1445 rel_addr = 0;
1447 /* leave one program header for the program interpreter */
1448 ph = &phdr[0];
1449 if (interp)
1450 ph++;
1452 for(j = 0; j < 2; j++) {
1453 ph->p_type = PT_LOAD;
1454 if (j == 0)
1455 ph->p_flags = PF_R | PF_X;
1456 else
1457 ph->p_flags = PF_R | PF_W;
1458 ph->p_align = ELF_PAGE_SIZE;
1460 /* we do the following ordering: interp, symbol tables,
1461 relocations, progbits, nobits */
1462 /* XXX: do faster and simpler sorting */
1463 for(k = 0; k < 5; k++) {
1464 for(i = 1; i < s1->nb_sections; i++) {
1465 s = s1->sections[i];
1466 /* compute if section should be included */
1467 if (j == 0) {
1468 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1469 SHF_ALLOC)
1470 continue;
1471 } else {
1472 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1473 (SHF_ALLOC | SHF_WRITE))
1474 continue;
1476 if (s == interp) {
1477 if (k != 0)
1478 continue;
1479 } else if (s->sh_type == SHT_DYNSYM ||
1480 s->sh_type == SHT_STRTAB ||
1481 s->sh_type == SHT_HASH) {
1482 if (k != 1)
1483 continue;
1484 } else if (s->sh_type == SHT_RELX) {
1485 if (k != 2)
1486 continue;
1487 } else if (s->sh_type == SHT_NOBITS) {
1488 if (k != 4)
1489 continue;
1490 } else {
1491 if (k != 3)
1492 continue;
1494 section_order[sh_order_index++] = i;
1496 /* section matches: we align it and add its size */
1497 tmp = addr;
1498 addr = (addr + s->sh_addralign - 1) &
1499 ~(s->sh_addralign - 1);
1500 file_offset += addr - tmp;
1501 s->sh_offset = file_offset;
1502 s->sh_addr = addr;
1504 /* update program header infos */
1505 if (ph->p_offset == 0) {
1506 ph->p_offset = file_offset;
1507 ph->p_vaddr = addr;
1508 ph->p_paddr = ph->p_vaddr;
1510 /* update dynamic relocation infos */
1511 if (s->sh_type == SHT_RELX) {
1512 if (rel_size == 0)
1513 rel_addr = addr;
1514 rel_size += s->sh_size;
1516 addr += s->sh_size;
1517 if (s->sh_type != SHT_NOBITS)
1518 file_offset += s->sh_size;
1521 ph->p_filesz = file_offset - ph->p_offset;
1522 ph->p_memsz = addr - ph->p_vaddr;
1523 ph++;
1524 if (j == 0) {
1525 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1526 /* if in the middle of a page, we duplicate the page in
1527 memory so that one copy is RX and the other is RW */
1528 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1529 addr += ELF_PAGE_SIZE;
1530 } else {
1531 addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
1532 file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
1533 ~(ELF_PAGE_SIZE - 1);
1538 /* if interpreter, then add corresponing program header */
1539 if (interp) {
1540 ph = &phdr[0];
1542 ph->p_type = PT_INTERP;
1543 ph->p_offset = interp->sh_offset;
1544 ph->p_vaddr = interp->sh_addr;
1545 ph->p_paddr = ph->p_vaddr;
1546 ph->p_filesz = interp->sh_size;
1547 ph->p_memsz = interp->sh_size;
1548 ph->p_flags = PF_R;
1549 ph->p_align = interp->sh_addralign;
1552 /* if dynamic section, then add corresponing program header */
1553 if (dynamic) {
1554 ElfW(Sym) *sym_end;
1556 ph = &phdr[phnum - 1];
1558 ph->p_type = PT_DYNAMIC;
1559 ph->p_offset = dynamic->sh_offset;
1560 ph->p_vaddr = dynamic->sh_addr;
1561 ph->p_paddr = ph->p_vaddr;
1562 ph->p_filesz = dynamic->sh_size;
1563 ph->p_memsz = dynamic->sh_size;
1564 ph->p_flags = PF_R | PF_W;
1565 ph->p_align = dynamic->sh_addralign;
1567 /* put GOT dynamic section address */
1568 put32(s1->got->data, dynamic->sh_addr);
1570 /* relocate the PLT */
1571 if (file_type == TCC_OUTPUT_EXE) {
1572 uint8_t *p, *p_end;
1574 p = s1->plt->data;
1575 p_end = p + s1->plt->data_offset;
1576 if (p < p_end) {
1577 #if defined(TCC_TARGET_I386)
1578 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1579 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1580 p += 16;
1581 while (p < p_end) {
1582 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1583 p += 16;
1585 #elif defined(TCC_TARGET_ARM)
1586 int x;
1587 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1588 p +=16;
1589 while (p < p_end) {
1590 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1591 p += 16;
1593 #elif defined(TCC_TARGET_C67)
1594 /* XXX: TODO */
1595 #else
1596 #error unsupported CPU
1597 #endif
1601 /* relocate symbols in .dynsym */
1602 sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset);
1603 for(sym = (ElfW(Sym) *)s1->dynsym->data + 1;
1604 sym < sym_end;
1605 sym++) {
1606 if (sym->st_shndx == SHN_UNDEF) {
1607 /* relocate to the PLT if the symbol corresponds
1608 to a PLT entry */
1609 if (sym->st_value)
1610 sym->st_value += s1->plt->sh_addr;
1611 } else if (sym->st_shndx < SHN_LORESERVE) {
1612 /* do symbol relocation */
1613 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1617 /* put dynamic section entries */
1618 dynamic->data_offset = saved_dynamic_data_offset;
1619 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1620 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1621 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1622 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1623 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1624 put_dt(dynamic, DT_REL, rel_addr);
1625 put_dt(dynamic, DT_RELSZ, rel_size);
1626 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1627 if (do_debug)
1628 put_dt(dynamic, DT_DEBUG, 0);
1629 put_dt(dynamic, DT_NULL, 0);
1632 ehdr.e_phentsize = sizeof(ElfW(Phdr));
1633 ehdr.e_phnum = phnum;
1634 ehdr.e_phoff = sizeof(ElfW(Ehdr));
1637 /* all other sections come after */
1638 for(i = 1; i < s1->nb_sections; i++) {
1639 s = s1->sections[i];
1640 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1641 continue;
1642 section_order[sh_order_index++] = i;
1644 file_offset = (file_offset + s->sh_addralign - 1) &
1645 ~(s->sh_addralign - 1);
1646 s->sh_offset = file_offset;
1647 if (s->sh_type != SHT_NOBITS)
1648 file_offset += s->sh_size;
1651 /* if building executable or DLL, then relocate each section
1652 except the GOT which is already relocated */
1653 if (file_type != TCC_OUTPUT_OBJ) {
1654 relocate_syms(s1, 0);
1656 if (s1->nb_errors != 0) {
1657 fail:
1658 ret = -1;
1659 goto the_end;
1662 /* relocate sections */
1663 /* XXX: ignore sections with allocated relocations ? */
1664 for(i = 1; i < s1->nb_sections; i++) {
1665 s = s1->sections[i];
1666 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
1667 relocate_section(s1, s);
1670 /* relocate relocation entries if the relocation tables are
1671 allocated in the executable */
1672 for(i = 1; i < s1->nb_sections; i++) {
1673 s = s1->sections[i];
1674 if ((s->sh_flags & SHF_ALLOC) &&
1675 s->sh_type == SHT_RELX) {
1676 relocate_rel(s1, s);
1680 /* get entry point address */
1681 if (file_type == TCC_OUTPUT_EXE)
1682 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
1683 else
1684 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1687 /* write elf file */
1688 if (file_type == TCC_OUTPUT_OBJ)
1689 mode = 0666;
1690 else
1691 mode = 0777;
1692 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1693 if (fd < 0) {
1694 error_noabort("could not write '%s'", filename);
1695 goto fail;
1697 f = fdopen(fd, "wb");
1698 if (verbose)
1699 printf("<- %s\n", filename);
1701 #ifdef TCC_TARGET_COFF
1702 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1703 tcc_output_coff(s1, f);
1704 } else
1705 #endif
1706 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1707 sort_syms(s1, symtab_section);
1709 /* align to 4 */
1710 file_offset = (file_offset + 3) & -4;
1712 /* fill header */
1713 ehdr.e_ident[0] = ELFMAG0;
1714 ehdr.e_ident[1] = ELFMAG1;
1715 ehdr.e_ident[2] = ELFMAG2;
1716 ehdr.e_ident[3] = ELFMAG3;
1717 ehdr.e_ident[4] = ELFCLASS32;
1718 ehdr.e_ident[5] = ELFDATA2LSB;
1719 ehdr.e_ident[6] = EV_CURRENT;
1720 #ifdef __FreeBSD__
1721 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1722 #endif
1723 #ifdef TCC_TARGET_ARM
1724 #ifdef TCC_ARM_EABI
1725 ehdr.e_ident[EI_OSABI] = 0;
1726 ehdr.e_flags = 4 << 24;
1727 #else
1728 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1729 #endif
1730 #endif
1731 switch(file_type) {
1732 default:
1733 case TCC_OUTPUT_EXE:
1734 ehdr.e_type = ET_EXEC;
1735 break;
1736 case TCC_OUTPUT_DLL:
1737 ehdr.e_type = ET_DYN;
1738 break;
1739 case TCC_OUTPUT_OBJ:
1740 ehdr.e_type = ET_REL;
1741 break;
1743 ehdr.e_machine = EM_TCC_TARGET;
1744 ehdr.e_version = EV_CURRENT;
1745 ehdr.e_shoff = file_offset;
1746 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
1747 ehdr.e_shentsize = sizeof(ElfW(Shdr));
1748 ehdr.e_shnum = shnum;
1749 ehdr.e_shstrndx = shnum - 1;
1751 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
1752 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
1753 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1755 for(i=1;i<s1->nb_sections;i++) {
1756 s = s1->sections[section_order[i]];
1757 if (s->sh_type != SHT_NOBITS) {
1758 while (offset < s->sh_offset) {
1759 fputc(0, f);
1760 offset++;
1762 size = s->sh_size;
1763 fwrite(s->data, 1, size, f);
1764 offset += size;
1768 /* output section headers */
1769 while (offset < ehdr.e_shoff) {
1770 fputc(0, f);
1771 offset++;
1774 for(i=0;i<s1->nb_sections;i++) {
1775 sh = &shdr;
1776 memset(sh, 0, sizeof(ElfW(Shdr)));
1777 s = s1->sections[i];
1778 if (s) {
1779 sh->sh_name = s->sh_name;
1780 sh->sh_type = s->sh_type;
1781 sh->sh_flags = s->sh_flags;
1782 sh->sh_entsize = s->sh_entsize;
1783 sh->sh_info = s->sh_info;
1784 if (s->link)
1785 sh->sh_link = s->link->sh_num;
1786 sh->sh_addralign = s->sh_addralign;
1787 sh->sh_addr = s->sh_addr;
1788 sh->sh_offset = s->sh_offset;
1789 sh->sh_size = s->sh_size;
1791 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
1793 } else {
1794 tcc_output_binary(s1, f, section_order);
1796 fclose(f);
1798 ret = 0;
1799 the_end:
1800 tcc_free(s1->symtab_to_dynsym);
1801 tcc_free(section_order);
1802 tcc_free(phdr);
1803 tcc_free(s1->got_offsets);
1804 return ret;
1807 int tcc_output_file(TCCState *s, const char *filename)
1809 int ret;
1810 #ifdef TCC_TARGET_PE
1811 if (s->output_type != TCC_OUTPUT_OBJ) {
1812 ret = pe_output_file(s, filename);
1813 } else
1814 #endif
1816 ret = elf_output_file(s, filename);
1818 return ret;
1821 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1823 void *data;
1825 data = tcc_malloc(size);
1826 lseek(fd, file_offset, SEEK_SET);
1827 read(fd, data, size);
1828 return data;
1831 typedef struct SectionMergeInfo {
1832 Section *s; /* corresponding existing section */
1833 unsigned long offset; /* offset of the new section in the existing section */
1834 uint8_t new_section; /* true if section 's' was added */
1835 uint8_t link_once; /* true if link once section */
1836 } SectionMergeInfo;
1838 /* load an object file and merge it with current files */
1839 /* XXX: handle correctly stab (debug) info */
1840 static int tcc_load_object_file(TCCState *s1,
1841 int fd, unsigned long file_offset)
1843 ElfW(Ehdr) ehdr;
1844 ElfW(Shdr) *shdr, *sh;
1845 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1846 unsigned char *strsec, *strtab;
1847 int *old_to_new_syms;
1848 char *sh_name, *name;
1849 SectionMergeInfo *sm_table, *sm;
1850 ElfW(Sym) *sym, *symtab;
1851 ElfW_Rel *rel, *rel_end;
1852 Section *s;
1854 int stab_index;
1855 int stabstr_index;
1857 stab_index = stabstr_index = 0;
1859 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1860 goto fail1;
1861 if (ehdr.e_ident[0] != ELFMAG0 ||
1862 ehdr.e_ident[1] != ELFMAG1 ||
1863 ehdr.e_ident[2] != ELFMAG2 ||
1864 ehdr.e_ident[3] != ELFMAG3)
1865 goto fail1;
1866 /* test if object file */
1867 if (ehdr.e_type != ET_REL)
1868 goto fail1;
1869 /* test CPU specific stuff */
1870 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1871 ehdr.e_machine != EM_TCC_TARGET) {
1872 fail1:
1873 error_noabort("invalid object file");
1874 return -1;
1876 /* read sections */
1877 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1878 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
1879 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1881 /* load section names */
1882 sh = &shdr[ehdr.e_shstrndx];
1883 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1885 /* load symtab and strtab */
1886 old_to_new_syms = NULL;
1887 symtab = NULL;
1888 strtab = NULL;
1889 nb_syms = 0;
1890 for(i = 1; i < ehdr.e_shnum; i++) {
1891 sh = &shdr[i];
1892 if (sh->sh_type == SHT_SYMTAB) {
1893 if (symtab) {
1894 error_noabort("object must contain only one symtab");
1895 fail:
1896 ret = -1;
1897 goto the_end;
1899 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
1900 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1901 sm_table[i].s = symtab_section;
1903 /* now load strtab */
1904 sh = &shdr[sh->sh_link];
1905 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1909 /* now examine each section and try to merge its content with the
1910 ones in memory */
1911 for(i = 1; i < ehdr.e_shnum; i++) {
1912 /* no need to examine section name strtab */
1913 if (i == ehdr.e_shstrndx)
1914 continue;
1915 sh = &shdr[i];
1916 sh_name = strsec + sh->sh_name;
1917 /* ignore sections types we do not handle */
1918 if (sh->sh_type != SHT_PROGBITS &&
1919 sh->sh_type != SHT_RELX &&
1920 #ifdef TCC_ARM_EABI
1921 sh->sh_type != SHT_ARM_EXIDX &&
1922 #endif
1923 sh->sh_type != SHT_NOBITS &&
1924 strcmp(sh_name, ".stabstr")
1926 continue;
1927 if (sh->sh_addralign < 1)
1928 sh->sh_addralign = 1;
1929 /* find corresponding section, if any */
1930 for(j = 1; j < s1->nb_sections;j++) {
1931 s = s1->sections[j];
1932 if (!strcmp(s->name, sh_name)) {
1933 if (!strncmp(sh_name, ".gnu.linkonce",
1934 sizeof(".gnu.linkonce") - 1)) {
1935 /* if a 'linkonce' section is already present, we
1936 do not add it again. It is a little tricky as
1937 symbols can still be defined in
1938 it. */
1939 sm_table[i].link_once = 1;
1940 goto next;
1941 } else {
1942 goto found;
1946 /* not found: create new section */
1947 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1948 /* take as much info as possible from the section. sh_link and
1949 sh_info will be updated later */
1950 s->sh_addralign = sh->sh_addralign;
1951 s->sh_entsize = sh->sh_entsize;
1952 sm_table[i].new_section = 1;
1953 found:
1954 if (sh->sh_type != s->sh_type) {
1955 error_noabort("invalid section type");
1956 goto fail;
1959 /* align start of section */
1960 offset = s->data_offset;
1962 if (0 == strcmp(sh_name, ".stab")) {
1963 stab_index = i;
1964 goto no_align;
1966 if (0 == strcmp(sh_name, ".stabstr")) {
1967 stabstr_index = i;
1968 goto no_align;
1971 size = sh->sh_addralign - 1;
1972 offset = (offset + size) & ~size;
1973 if (sh->sh_addralign > s->sh_addralign)
1974 s->sh_addralign = sh->sh_addralign;
1975 s->data_offset = offset;
1976 no_align:
1977 sm_table[i].offset = offset;
1978 sm_table[i].s = s;
1979 /* concatenate sections */
1980 size = sh->sh_size;
1981 if (sh->sh_type != SHT_NOBITS) {
1982 unsigned char *ptr;
1983 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1984 ptr = section_ptr_add(s, size);
1985 read(fd, ptr, size);
1986 } else {
1987 s->data_offset += size;
1989 next: ;
1992 /* //gr relocate stab strings */
1993 if (stab_index && stabstr_index) {
1994 Stab_Sym *a, *b;
1995 unsigned o;
1996 s = sm_table[stab_index].s;
1997 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
1998 b = (Stab_Sym *)(s->data + s->data_offset);
1999 o = sm_table[stabstr_index].offset;
2000 while (a < b)
2001 a->n_strx += o, a++;
2004 /* second short pass to update sh_link and sh_info fields of new
2005 sections */
2006 for(i = 1; i < ehdr.e_shnum; i++) {
2007 s = sm_table[i].s;
2008 if (!s || !sm_table[i].new_section)
2009 continue;
2010 sh = &shdr[i];
2011 if (sh->sh_link > 0)
2012 s->link = sm_table[sh->sh_link].s;
2013 if (sh->sh_type == SHT_RELX) {
2014 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2015 /* update backward link */
2016 s1->sections[s->sh_info]->reloc = s;
2019 sm = sm_table;
2021 /* resolve symbols */
2022 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2024 sym = symtab + 1;
2025 for(i = 1; i < nb_syms; i++, sym++) {
2026 if (sym->st_shndx != SHN_UNDEF &&
2027 sym->st_shndx < SHN_LORESERVE) {
2028 sm = &sm_table[sym->st_shndx];
2029 if (sm->link_once) {
2030 /* if a symbol is in a link once section, we use the
2031 already defined symbol. It is very important to get
2032 correct relocations */
2033 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2034 name = strtab + sym->st_name;
2035 sym_index = find_elf_sym(symtab_section, name);
2036 if (sym_index)
2037 old_to_new_syms[i] = sym_index;
2039 continue;
2041 /* if no corresponding section added, no need to add symbol */
2042 if (!sm->s)
2043 continue;
2044 /* convert section number */
2045 sym->st_shndx = sm->s->sh_num;
2046 /* offset value */
2047 sym->st_value += sm->offset;
2049 /* add symbol */
2050 name = strtab + sym->st_name;
2051 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
2052 sym->st_info, sym->st_other,
2053 sym->st_shndx, name);
2054 old_to_new_syms[i] = sym_index;
2057 /* third pass to patch relocation entries */
2058 for(i = 1; i < ehdr.e_shnum; i++) {
2059 s = sm_table[i].s;
2060 if (!s)
2061 continue;
2062 sh = &shdr[i];
2063 offset = sm_table[i].offset;
2064 switch(s->sh_type) {
2065 case SHT_RELX:
2066 /* take relocation offset information */
2067 offseti = sm_table[sh->sh_info].offset;
2068 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
2069 for(rel = (ElfW_Rel *)(s->data + offset);
2070 rel < rel_end;
2071 rel++) {
2072 int type;
2073 unsigned sym_index;
2074 /* convert symbol index */
2075 type = ELFW(R_TYPE)(rel->r_info);
2076 sym_index = ELFW(R_SYM)(rel->r_info);
2077 /* NOTE: only one symtab assumed */
2078 if (sym_index >= nb_syms)
2079 goto invalid_reloc;
2080 sym_index = old_to_new_syms[sym_index];
2081 /* ignore link_once in rel section. */
2082 if (!sym_index && !sm->link_once) {
2083 invalid_reloc:
2084 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2085 i, strsec + sh->sh_name, rel->r_offset);
2086 goto fail;
2088 rel->r_info = ELFW(R_INFO)(sym_index, type);
2089 /* offset the relocation offset */
2090 rel->r_offset += offseti;
2092 break;
2093 default:
2094 break;
2098 ret = 0;
2099 the_end:
2100 tcc_free(symtab);
2101 tcc_free(strtab);
2102 tcc_free(old_to_new_syms);
2103 tcc_free(sm_table);
2104 tcc_free(strsec);
2105 tcc_free(shdr);
2106 return ret;
2109 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2111 typedef struct ArchiveHeader {
2112 char ar_name[16]; /* name of this member */
2113 char ar_date[12]; /* file mtime */
2114 char ar_uid[6]; /* owner uid; printed as decimal */
2115 char ar_gid[6]; /* owner gid; printed as decimal */
2116 char ar_mode[8]; /* file mode, printed as octal */
2117 char ar_size[10]; /* file size, printed as decimal */
2118 char ar_fmag[2]; /* should contain ARFMAG */
2119 } ArchiveHeader;
2121 static int get_be32(const uint8_t *b)
2123 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2126 /* load only the objects which resolve undefined symbols */
2127 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
2129 int i, bound, nsyms, sym_index, off, ret;
2130 uint8_t *data;
2131 const char *ar_names, *p;
2132 const uint8_t *ar_index;
2133 ElfW(Sym) *sym;
2135 data = tcc_malloc(size);
2136 if (read(fd, data, size) != size)
2137 goto fail;
2138 nsyms = get_be32(data);
2139 ar_index = data + 4;
2140 ar_names = ar_index + nsyms * 4;
2142 do {
2143 bound = 0;
2144 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2145 sym_index = find_elf_sym(symtab_section, p);
2146 if(sym_index) {
2147 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2148 if(sym->st_shndx == SHN_UNDEF) {
2149 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2150 #if 0
2151 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2152 #endif
2153 ++bound;
2154 lseek(fd, off, SEEK_SET);
2155 if(tcc_load_object_file(s1, fd, off) < 0) {
2156 fail:
2157 ret = -1;
2158 goto the_end;
2163 } while(bound);
2164 ret = 0;
2165 the_end:
2166 tcc_free(data);
2167 return ret;
2170 /* load a '.a' file */
2171 static int tcc_load_archive(TCCState *s1, int fd)
2173 ArchiveHeader hdr;
2174 char ar_size[11];
2175 char ar_name[17];
2176 char magic[8];
2177 int size, len, i;
2178 unsigned long file_offset;
2180 /* skip magic which was already checked */
2181 read(fd, magic, sizeof(magic));
2183 for(;;) {
2184 len = read(fd, &hdr, sizeof(hdr));
2185 if (len == 0)
2186 break;
2187 if (len != sizeof(hdr)) {
2188 error_noabort("invalid archive");
2189 return -1;
2191 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2192 ar_size[sizeof(hdr.ar_size)] = '\0';
2193 size = strtol(ar_size, NULL, 0);
2194 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2195 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2196 if (ar_name[i] != ' ')
2197 break;
2199 ar_name[i + 1] = '\0';
2200 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2201 file_offset = lseek(fd, 0, SEEK_CUR);
2202 /* align to even */
2203 size = (size + 1) & ~1;
2204 if (!strcmp(ar_name, "/")) {
2205 /* coff symbol table : we handle it */
2206 if(s1->alacarte_link)
2207 return tcc_load_alacarte(s1, fd, size);
2208 } else if (!strcmp(ar_name, "//") ||
2209 !strcmp(ar_name, "__.SYMDEF") ||
2210 !strcmp(ar_name, "__.SYMDEF/") ||
2211 !strcmp(ar_name, "ARFILENAMES/")) {
2212 /* skip symbol table or archive names */
2213 } else {
2214 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2215 return -1;
2217 lseek(fd, file_offset + size, SEEK_SET);
2219 return 0;
2222 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2223 is referenced by the user (so it should be added as DT_NEEDED in
2224 the generated ELF file) */
2225 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2227 ElfW(Ehdr) ehdr;
2228 ElfW(Shdr) *shdr, *sh, *sh1;
2229 int i, j, nb_syms, nb_dts, sym_bind, ret;
2230 ElfW(Sym) *sym, *dynsym;
2231 ElfW(Dyn) *dt, *dynamic;
2232 unsigned char *dynstr;
2233 const char *name, *soname;
2234 DLLReference *dllref;
2236 read(fd, &ehdr, sizeof(ehdr));
2238 /* test CPU specific stuff */
2239 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2240 ehdr.e_machine != EM_TCC_TARGET) {
2241 error_noabort("bad architecture");
2242 return -1;
2245 /* read sections */
2246 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2248 /* load dynamic section and dynamic symbols */
2249 nb_syms = 0;
2250 nb_dts = 0;
2251 dynamic = NULL;
2252 dynsym = NULL; /* avoid warning */
2253 dynstr = NULL; /* avoid warning */
2254 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2255 switch(sh->sh_type) {
2256 case SHT_DYNAMIC:
2257 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2258 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2259 break;
2260 case SHT_DYNSYM:
2261 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2262 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2263 sh1 = &shdr[sh->sh_link];
2264 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2265 break;
2266 default:
2267 break;
2271 /* compute the real library name */
2272 soname = tcc_basename(filename);
2274 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2275 if (dt->d_tag == DT_SONAME) {
2276 soname = dynstr + dt->d_un.d_val;
2280 /* if the dll is already loaded, do not load it */
2281 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2282 dllref = s1->loaded_dlls[i];
2283 if (!strcmp(soname, dllref->name)) {
2284 /* but update level if needed */
2285 if (level < dllref->level)
2286 dllref->level = level;
2287 ret = 0;
2288 goto the_end;
2292 // printf("loading dll '%s'\n", soname);
2294 /* add the dll and its level */
2295 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2296 dllref->level = level;
2297 strcpy(dllref->name, soname);
2298 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2300 /* add dynamic symbols in dynsym_section */
2301 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2302 sym_bind = ELFW(ST_BIND)(sym->st_info);
2303 if (sym_bind == STB_LOCAL)
2304 continue;
2305 name = dynstr + sym->st_name;
2306 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2307 sym->st_info, sym->st_other, sym->st_shndx, name);
2310 /* load all referenced DLLs */
2311 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2312 switch(dt->d_tag) {
2313 case DT_NEEDED:
2314 name = dynstr + dt->d_un.d_val;
2315 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2316 dllref = s1->loaded_dlls[j];
2317 if (!strcmp(name, dllref->name))
2318 goto already_loaded;
2320 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2321 error_noabort("referenced dll '%s' not found", name);
2322 ret = -1;
2323 goto the_end;
2325 already_loaded:
2326 break;
2329 ret = 0;
2330 the_end:
2331 tcc_free(dynstr);
2332 tcc_free(dynsym);
2333 tcc_free(dynamic);
2334 tcc_free(shdr);
2335 return ret;
2338 #define LD_TOK_NAME 256
2339 #define LD_TOK_EOF (-1)
2341 /* return next ld script token */
2342 static int ld_next(TCCState *s1, char *name, int name_size)
2344 int c;
2345 char *q;
2347 redo:
2348 switch(ch) {
2349 case ' ':
2350 case '\t':
2351 case '\f':
2352 case '\v':
2353 case '\r':
2354 case '\n':
2355 inp();
2356 goto redo;
2357 case '/':
2358 minp();
2359 if (ch == '*') {
2360 file->buf_ptr = parse_comment(file->buf_ptr);
2361 ch = file->buf_ptr[0];
2362 goto redo;
2363 } else {
2364 q = name;
2365 *q++ = '/';
2366 goto parse_name;
2368 break;
2369 /* case 'a' ... 'z': */
2370 case 'a':
2371 case 'b':
2372 case 'c':
2373 case 'd':
2374 case 'e':
2375 case 'f':
2376 case 'g':
2377 case 'h':
2378 case 'i':
2379 case 'j':
2380 case 'k':
2381 case 'l':
2382 case 'm':
2383 case 'n':
2384 case 'o':
2385 case 'p':
2386 case 'q':
2387 case 'r':
2388 case 's':
2389 case 't':
2390 case 'u':
2391 case 'v':
2392 case 'w':
2393 case 'x':
2394 case 'y':
2395 case 'z':
2396 /* case 'A' ... 'z': */
2397 case 'A':
2398 case 'B':
2399 case 'C':
2400 case 'D':
2401 case 'E':
2402 case 'F':
2403 case 'G':
2404 case 'H':
2405 case 'I':
2406 case 'J':
2407 case 'K':
2408 case 'L':
2409 case 'M':
2410 case 'N':
2411 case 'O':
2412 case 'P':
2413 case 'Q':
2414 case 'R':
2415 case 'S':
2416 case 'T':
2417 case 'U':
2418 case 'V':
2419 case 'W':
2420 case 'X':
2421 case 'Y':
2422 case 'Z':
2423 case '_':
2424 case '\\':
2425 case '.':
2426 case '$':
2427 case '~':
2428 q = name;
2429 parse_name:
2430 for(;;) {
2431 if (!((ch >= 'a' && ch <= 'z') ||
2432 (ch >= 'A' && ch <= 'Z') ||
2433 (ch >= '0' && ch <= '9') ||
2434 strchr("/.-_+=$:\\,~", ch)))
2435 break;
2436 if ((q - name) < name_size - 1) {
2437 *q++ = ch;
2439 minp();
2441 *q = '\0';
2442 c = LD_TOK_NAME;
2443 break;
2444 case CH_EOF:
2445 c = LD_TOK_EOF;
2446 break;
2447 default:
2448 c = ch;
2449 inp();
2450 break;
2452 #if 0
2453 printf("tok=%c %d\n", c, c);
2454 if (c == LD_TOK_NAME)
2455 printf(" name=%s\n", name);
2456 #endif
2457 return c;
2460 static int ld_add_file_list(TCCState *s1, int as_needed)
2462 char filename[1024];
2463 int t, ret;
2465 t = ld_next(s1, filename, sizeof(filename));
2466 if (t != '(')
2467 expect("(");
2468 t = ld_next(s1, filename, sizeof(filename));
2469 for(;;) {
2470 if (t == LD_TOK_EOF) {
2471 error_noabort("unexpected end of file");
2472 return -1;
2473 } else if (t == ')') {
2474 break;
2475 } else if (t != LD_TOK_NAME) {
2476 error_noabort("filename expected");
2477 return -1;
2479 if (!strcmp(filename, "AS_NEEDED")) {
2480 ret = ld_add_file_list(s1, 1);
2481 if (ret)
2482 return ret;
2483 } else {
2484 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2485 if (!as_needed)
2486 tcc_add_file(s1, filename);
2488 t = ld_next(s1, filename, sizeof(filename));
2489 if (t == ',') {
2490 t = ld_next(s1, filename, sizeof(filename));
2493 return 0;
2496 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2497 files */
2498 static int tcc_load_ldscript(TCCState *s1)
2500 char cmd[64];
2501 char filename[1024];
2502 int t, ret;
2504 ch = file->buf_ptr[0];
2505 ch = handle_eob();
2506 for(;;) {
2507 t = ld_next(s1, cmd, sizeof(cmd));
2508 if (t == LD_TOK_EOF)
2509 return 0;
2510 else if (t != LD_TOK_NAME)
2511 return -1;
2512 if (!strcmp(cmd, "INPUT") ||
2513 !strcmp(cmd, "GROUP")) {
2514 ret = ld_add_file_list(s1, 0);
2515 if (ret)
2516 return ret;
2517 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2518 !strcmp(cmd, "TARGET")) {
2519 /* ignore some commands */
2520 t = ld_next(s1, cmd, sizeof(cmd));
2521 if (t != '(')
2522 expect("(");
2523 for(;;) {
2524 t = ld_next(s1, filename, sizeof(filename));
2525 if (t == LD_TOK_EOF) {
2526 error_noabort("unexpected end of file");
2527 return -1;
2528 } else if (t == ')') {
2529 break;
2532 } else {
2533 return -1;
2536 return 0;