Some in-between fixes (See Changelog for details).
[tinycc/miki.git] / tccelf.c
blob73f84cc5cd8946891858c1951b1c775291adb637
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 static int put_elf_str(Section *s, const char *sym)
23 int offset, len;
24 char *ptr;
26 len = strlen(sym) + 1;
27 offset = s->data_offset;
28 ptr = section_ptr_add(s, len);
29 memcpy(ptr, sym, len);
30 return offset;
33 /* elf symbol hashing function */
34 static unsigned long elf_hash(const unsigned char *name)
36 unsigned long h = 0, g;
38 while (*name) {
39 h = (h << 4) + *name++;
40 g = h & 0xf0000000;
41 if (g)
42 h ^= g >> 24;
43 h &= ~g;
45 return h;
48 /* rebuild hash table of section s */
49 /* NOTE: we do factorize the hash table code to go faster */
50 static void rebuild_hash(Section *s, unsigned int nb_buckets)
52 Elf32_Sym *sym;
53 int *ptr, *hash, nb_syms, sym_index, h;
54 char *strtab;
56 strtab = s->link->data;
57 nb_syms = s->data_offset / sizeof(Elf32_Sym);
59 s->hash->data_offset = 0;
60 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
61 ptr[0] = nb_buckets;
62 ptr[1] = nb_syms;
63 ptr += 2;
64 hash = ptr;
65 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
66 ptr += nb_buckets + 1;
68 sym = (Elf32_Sym *)s->data + 1;
69 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
70 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
71 h = elf_hash(strtab + sym->st_name) % nb_buckets;
72 *ptr = hash[h];
73 hash[h] = sym_index;
74 } else {
75 *ptr = 0;
77 ptr++;
78 sym++;
82 /* return the symbol number */
83 static int put_elf_sym(Section *s,
84 unsigned long value, unsigned long size,
85 int info, int other, int shndx, const char *name)
87 int name_offset, sym_index;
88 int nbuckets, h;
89 Elf32_Sym *sym;
90 Section *hs;
92 sym = section_ptr_add(s, sizeof(Elf32_Sym));
93 if (name)
94 name_offset = put_elf_str(s->link, name);
95 else
96 name_offset = 0;
97 /* XXX: endianness */
98 sym->st_name = name_offset;
99 sym->st_value = value;
100 sym->st_size = size;
101 sym->st_info = info;
102 sym->st_other = other;
103 sym->st_shndx = shndx;
104 sym_index = sym - (Elf32_Sym *)s->data;
105 hs = s->hash;
106 if (hs) {
107 int *ptr, *base;
108 ptr = section_ptr_add(hs, sizeof(int));
109 base = (int *)hs->data;
110 /* only add global or weak symbols */
111 if (ELF32_ST_BIND(info) != STB_LOCAL) {
112 /* add another hashing entry */
113 nbuckets = base[0];
114 h = elf_hash(name) % nbuckets;
115 *ptr = base[2 + h];
116 base[2 + h] = sym_index;
117 base[1]++;
118 /* we resize the hash table */
119 hs->nb_hashed_syms++;
120 if (hs->nb_hashed_syms > 2 * nbuckets) {
121 rebuild_hash(s, 2 * nbuckets);
123 } else {
124 *ptr = 0;
125 base[1]++;
128 return sym_index;
131 /* find global ELF symbol 'name' and return its index. Return 0 if not
132 found. */
133 static int find_elf_sym(Section *s, const char *name)
135 Elf32_Sym *sym;
136 Section *hs;
137 int nbuckets, sym_index, h;
138 const char *name1;
140 hs = s->hash;
141 if (!hs)
142 return 0;
143 nbuckets = ((int *)hs->data)[0];
144 h = elf_hash(name) % nbuckets;
145 sym_index = ((int *)hs->data)[2 + h];
146 while (sym_index != 0) {
147 sym = &((Elf32_Sym *)s->data)[sym_index];
148 name1 = s->link->data + sym->st_name;
149 if (!strcmp(name, name1))
150 return sym_index;
151 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
153 return 0;
156 /* return elf symbol value or error */
157 int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name)
159 int sym_index;
160 Elf32_Sym *sym;
162 sym_index = find_elf_sym(symtab_section, name);
163 if (!sym_index)
164 return -1;
165 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
166 *pval = sym->st_value;
167 return 0;
170 void *tcc_get_symbol_err(TCCState *s, const char *name)
172 unsigned long val;
173 if (tcc_get_symbol(s, &val, name) < 0)
174 error("%s not defined", name);
175 return (void *)val;
178 /* add an elf symbol : check if it is already defined and patch
179 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
180 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
181 int info, int other, int sh_num, const char *name)
183 Elf32_Sym *esym;
184 int sym_bind, sym_index, sym_type, esym_bind;
185 unsigned char sym_vis, esym_vis, new_vis;
187 sym_bind = ELF32_ST_BIND(info);
188 sym_type = ELF32_ST_TYPE(info);
189 sym_vis = ELF32_ST_VISIBILITY(other);
191 if (sym_bind != STB_LOCAL) {
192 /* we search global or weak symbols */
193 sym_index = find_elf_sym(s, name);
194 if (!sym_index)
195 goto do_def;
196 esym = &((Elf32_Sym *)s->data)[sym_index];
197 if (esym->st_shndx != SHN_UNDEF) {
198 esym_bind = ELF32_ST_BIND(esym->st_info);
199 /* propagate the most constraining visibility */
200 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
201 esym_vis = ELF32_ST_VISIBILITY(esym->st_other);
202 if (esym_vis == STV_DEFAULT) {
203 new_vis = sym_vis;
204 } else if (sym_vis == STV_DEFAULT) {
205 new_vis = esym_vis;
206 } else {
207 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
209 esym->st_other = (esym->st_other & ~ELF32_ST_VISIBILITY(-1))
210 | new_vis;
211 other = esym->st_other; /* in case we have to patch esym */
212 if (sh_num == SHN_UNDEF) {
213 /* ignore adding of undefined symbol if the
214 corresponding symbol is already defined */
215 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
216 /* global overrides weak, so patch */
217 goto do_patch;
218 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
219 /* weak is ignored if already global */
220 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
221 /* ignore hidden symbols after */
222 } else {
223 #if 0
224 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
225 sym_bind, sh_num, esym_bind, esym->st_shndx);
226 #endif
227 /* NOTE: we accept that two DLL define the same symbol */
228 if (s != tcc_state->dynsymtab_section)
229 error_noabort("'%s' defined twice", name);
231 } else {
232 do_patch:
233 esym->st_info = ELF32_ST_INFO(sym_bind, sym_type);
234 esym->st_shndx = sh_num;
235 esym->st_value = value;
236 esym->st_size = size;
237 esym->st_other = other;
239 } else {
240 do_def:
241 sym_index = put_elf_sym(s, value, size,
242 ELF32_ST_INFO(sym_bind, sym_type), other,
243 sh_num, name);
245 return sym_index;
248 /* put relocation */
249 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
250 int type, int symbol)
252 char buf[256];
253 Section *sr;
254 Elf32_Rel *rel;
256 sr = s->reloc;
257 if (!sr) {
258 /* if no relocation section, create it */
259 snprintf(buf, sizeof(buf), ".rel%s", s->name);
260 /* if the symtab is allocated, then we consider the relocation
261 are also */
262 sr = new_section(tcc_state, buf, SHT_REL, symtab->sh_flags);
263 sr->sh_entsize = sizeof(Elf32_Rel);
264 sr->link = symtab;
265 sr->sh_info = s->sh_num;
266 s->reloc = sr;
268 rel = section_ptr_add(sr, sizeof(Elf32_Rel));
269 rel->r_offset = offset;
270 rel->r_info = ELF32_R_INFO(symbol, type);
273 /* put stab debug information */
275 typedef struct {
276 unsigned long n_strx; /* index into string table of name */
277 unsigned char n_type; /* type of symbol */
278 unsigned char n_other; /* misc info (usually empty) */
279 unsigned short n_desc; /* description field */
280 unsigned long n_value; /* value of symbol */
281 } Stab_Sym;
283 static void put_stabs(const char *str, int type, int other, int desc,
284 unsigned long value)
286 Stab_Sym *sym;
288 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
289 if (str) {
290 sym->n_strx = put_elf_str(stabstr_section, str);
291 } else {
292 sym->n_strx = 0;
294 sym->n_type = type;
295 sym->n_other = other;
296 sym->n_desc = desc;
297 sym->n_value = value;
300 static void put_stabs_r(const char *str, int type, int other, int desc,
301 unsigned long value, Section *sec, int sym_index)
303 put_stabs(str, type, other, desc, value);
304 put_elf_reloc(symtab_section, stab_section,
305 stab_section->data_offset - sizeof(unsigned long),
306 R_DATA_32, sym_index);
309 static void put_stabn(int type, int other, int desc, int value)
311 put_stabs(NULL, type, other, desc, value);
314 static void put_stabd(int type, int other, int desc)
316 put_stabs(NULL, type, other, desc, 0);
319 /* In an ELF file symbol table, the local symbols must appear below
320 the global and weak ones. Since TCC cannot sort it while generating
321 the code, we must do it after. All the relocation tables are also
322 modified to take into account the symbol table sorting */
323 static void sort_syms(TCCState *s1, Section *s)
325 int *old_to_new_syms;
326 Elf32_Sym *new_syms;
327 int nb_syms, i;
328 Elf32_Sym *p, *q;
329 Elf32_Rel *rel, *rel_end;
330 Section *sr;
331 int type, sym_index;
333 nb_syms = s->data_offset / sizeof(Elf32_Sym);
334 new_syms = tcc_malloc(nb_syms * sizeof(Elf32_Sym));
335 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
337 /* first pass for local symbols */
338 p = (Elf32_Sym *)s->data;
339 q = new_syms;
340 for(i = 0; i < nb_syms; i++) {
341 if (ELF32_ST_BIND(p->st_info) == STB_LOCAL) {
342 old_to_new_syms[i] = q - new_syms;
343 *q++ = *p;
345 p++;
347 /* save the number of local symbols in section header */
348 s->sh_info = q - new_syms;
350 /* then second pass for non local symbols */
351 p = (Elf32_Sym *)s->data;
352 for(i = 0; i < nb_syms; i++) {
353 if (ELF32_ST_BIND(p->st_info) != STB_LOCAL) {
354 old_to_new_syms[i] = q - new_syms;
355 *q++ = *p;
357 p++;
360 /* we copy the new symbols to the old */
361 memcpy(s->data, new_syms, nb_syms * sizeof(Elf32_Sym));
362 tcc_free(new_syms);
364 /* now we modify all the relocations */
365 for(i = 1; i < s1->nb_sections; i++) {
366 sr = s1->sections[i];
367 if (sr->sh_type == SHT_REL && sr->link == s) {
368 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
369 for(rel = (Elf32_Rel *)sr->data;
370 rel < rel_end;
371 rel++) {
372 sym_index = ELF32_R_SYM(rel->r_info);
373 type = ELF32_R_TYPE(rel->r_info);
374 sym_index = old_to_new_syms[sym_index];
375 rel->r_info = ELF32_R_INFO(sym_index, type);
380 tcc_free(old_to_new_syms);
383 /* relocate common symbols in the .bss section */
384 static void relocate_common_syms(void)
386 Elf32_Sym *sym, *sym_end;
387 unsigned long offset, align;
389 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
390 for(sym = (Elf32_Sym *)symtab_section->data + 1;
391 sym < sym_end;
392 sym++) {
393 if (sym->st_shndx == SHN_COMMON) {
394 /* align symbol */
395 align = sym->st_value;
396 offset = bss_section->data_offset;
397 offset = (offset + align - 1) & -align;
398 sym->st_value = offset;
399 sym->st_shndx = bss_section->sh_num;
400 offset += sym->st_size;
401 bss_section->data_offset = offset;
406 /* relocate symbol table, resolve undefined symbols if do_resolve is
407 true and output error if undefined symbol. */
408 static void relocate_syms(TCCState *s1, int do_resolve)
410 Elf32_Sym *sym, *esym, *sym_end;
411 int sym_bind, sh_num, sym_index;
412 const char *name;
413 unsigned long addr;
415 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
416 for(sym = (Elf32_Sym *)symtab_section->data + 1;
417 sym < sym_end;
418 sym++) {
419 sh_num = sym->st_shndx;
420 if (sh_num == SHN_UNDEF) {
421 name = strtab_section->data + sym->st_name;
422 if (do_resolve) {
423 name = symtab_section->link->data + sym->st_name;
424 addr = (unsigned long)resolve_sym(s1, name, ELF32_ST_TYPE(sym->st_info));
425 if (addr) {
426 sym->st_value = addr;
427 goto found;
429 } else if (s1->dynsym) {
430 /* if dynamic symbol exist, then use it */
431 sym_index = find_elf_sym(s1->dynsym, name);
432 if (sym_index) {
433 esym = &((Elf32_Sym *)s1->dynsym->data)[sym_index];
434 sym->st_value = esym->st_value;
435 goto found;
438 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
439 it */
440 if (!strcmp(name, "_fp_hw"))
441 goto found;
442 /* only weak symbols are accepted to be undefined. Their
443 value is zero */
444 sym_bind = ELF32_ST_BIND(sym->st_info);
445 if (sym_bind == STB_WEAK) {
446 sym->st_value = 0;
447 } else {
448 error_noabort("undefined symbol '%s'", name);
450 } else if (sh_num < SHN_LORESERVE) {
451 /* add section base */
452 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
454 found: ;
458 /* relocate a given section (CPU dependent) */
459 static void relocate_section(TCCState *s1, Section *s)
461 Section *sr;
462 Elf32_Rel *rel, *rel_end, *qrel;
463 Elf32_Sym *sym;
464 int type, sym_index;
465 unsigned char *ptr;
466 unsigned long val, addr;
467 #if defined(TCC_TARGET_I386)
468 int esym_index;
469 #endif
471 sr = s->reloc;
472 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
473 qrel = (Elf32_Rel *)sr->data;
474 for(rel = qrel;
475 rel < rel_end;
476 rel++) {
477 ptr = s->data + rel->r_offset;
479 sym_index = ELF32_R_SYM(rel->r_info);
480 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
481 val = sym->st_value;
482 type = ELF32_R_TYPE(rel->r_info);
483 addr = s->sh_addr + rel->r_offset;
485 /* CPU specific */
486 switch(type) {
487 #if defined(TCC_TARGET_I386)
488 case R_386_32:
489 if (s1->output_type == TCC_OUTPUT_DLL) {
490 esym_index = s1->symtab_to_dynsym[sym_index];
491 qrel->r_offset = rel->r_offset;
492 if (esym_index) {
493 qrel->r_info = ELF32_R_INFO(esym_index, R_386_32);
494 qrel++;
495 break;
496 } else {
497 qrel->r_info = ELF32_R_INFO(0, R_386_RELATIVE);
498 qrel++;
501 *(int *)ptr += val;
502 break;
503 case R_386_PC32:
504 if (s1->output_type == TCC_OUTPUT_DLL) {
505 /* DLL relocation */
506 esym_index = s1->symtab_to_dynsym[sym_index];
507 if (esym_index) {
508 qrel->r_offset = rel->r_offset;
509 qrel->r_info = ELF32_R_INFO(esym_index, R_386_PC32);
510 qrel++;
511 break;
514 *(int *)ptr += val - addr;
515 break;
516 case R_386_PLT32:
517 *(int *)ptr += val - addr;
518 break;
519 case R_386_GLOB_DAT:
520 case R_386_JMP_SLOT:
521 *(int *)ptr = val;
522 break;
523 case R_386_GOTPC:
524 *(int *)ptr += s1->got->sh_addr - addr;
525 break;
526 case R_386_GOTOFF:
527 *(int *)ptr += val - s1->got->sh_addr;
528 break;
529 case R_386_GOT32:
530 /* we load the got offset */
531 *(int *)ptr += s1->got_offsets[sym_index];
532 break;
533 #elif defined(TCC_TARGET_ARM)
534 case R_ARM_PC24:
535 case R_ARM_PLT32:
537 int x;
538 x = (*(int *)ptr)&0xffffff;
539 (*(int *)ptr) &= 0xff000000;
540 if (x & 0x800000)
541 x -= 0x1000000;
542 x *= 4;
543 x += val - addr;
544 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
545 error("can't relocate value at %x",addr);
546 x >>= 2;
547 x &= 0xffffff;
548 (*(int *)ptr) |= x;
550 break;
551 case R_ARM_ABS32:
552 *(int *)ptr += val;
553 break;
554 case R_ARM_GOTPC:
555 *(int *)ptr += s1->got->sh_addr - addr;
556 break;
557 case R_ARM_GOT32:
558 /* we load the got offset */
559 *(int *)ptr += s1->got_offsets[sym_index];
560 break;
561 case R_ARM_COPY:
562 break;
563 default:
564 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
565 type,addr,(unsigned int )ptr,val);
566 break;
567 #elif defined(TCC_TARGET_C67)
568 case R_C60_32:
569 *(int *)ptr += val;
570 break;
571 case R_C60LO16:
573 uint32_t orig;
575 /* put the low 16 bits of the absolute address */
576 // add to what is already there
578 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
579 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
581 //patch both at once - assumes always in pairs Low - High
583 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
584 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
586 break;
587 case R_C60HI16:
588 break;
589 default:
590 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
591 type,addr,(unsigned int )ptr,val);
592 break;
593 #else
594 #error unsupported processor
595 #endif
598 /* if the relocation is allocated, we change its symbol table */
599 if (sr->sh_flags & SHF_ALLOC)
600 sr->link = s1->dynsym;
603 /* relocate relocation table in 'sr' */
604 static void relocate_rel(TCCState *s1, Section *sr)
606 Section *s;
607 Elf32_Rel *rel, *rel_end;
609 s = s1->sections[sr->sh_info];
610 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
611 for(rel = (Elf32_Rel *)sr->data;
612 rel < rel_end;
613 rel++) {
614 rel->r_offset += s->sh_addr;
618 /* count the number of dynamic relocations so that we can reserve
619 their space */
620 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
622 Elf32_Rel *rel, *rel_end;
623 int sym_index, esym_index, type, count;
625 count = 0;
626 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
627 for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) {
628 sym_index = ELF32_R_SYM(rel->r_info);
629 type = ELF32_R_TYPE(rel->r_info);
630 switch(type) {
631 case R_386_32:
632 count++;
633 break;
634 case R_386_PC32:
635 esym_index = s1->symtab_to_dynsym[sym_index];
636 if (esym_index)
637 count++;
638 break;
639 default:
640 break;
643 if (count) {
644 /* allocate the section */
645 sr->sh_flags |= SHF_ALLOC;
646 sr->sh_size = count * sizeof(Elf32_Rel);
648 return count;
651 static void put_got_offset(TCCState *s1, int index, unsigned long val)
653 int n;
654 unsigned long *tab;
656 if (index >= s1->nb_got_offsets) {
657 /* find immediately bigger power of 2 and reallocate array */
658 n = 1;
659 while (index >= n)
660 n *= 2;
661 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
662 if (!tab)
663 error("memory full");
664 s1->got_offsets = tab;
665 memset(s1->got_offsets + s1->nb_got_offsets, 0,
666 (n - s1->nb_got_offsets) * sizeof(unsigned long));
667 s1->nb_got_offsets = n;
669 s1->got_offsets[index] = val;
672 /* XXX: suppress that */
673 static void put32(unsigned char *p, uint32_t val)
675 p[0] = val;
676 p[1] = val >> 8;
677 p[2] = val >> 16;
678 p[3] = val >> 24;
681 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM)
682 static uint32_t get32(unsigned char *p)
684 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
686 #endif
688 static void build_got(TCCState *s1)
690 unsigned char *ptr;
692 /* if no got, then create it */
693 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
694 s1->got->sh_entsize = 4;
695 add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
696 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
697 ptr = section_ptr_add(s1->got, 3 * sizeof(int));
698 /* keep space for _DYNAMIC pointer, if present */
699 put32(ptr, 0);
700 /* two dummy got entries */
701 put32(ptr + 4, 0);
702 put32(ptr + 8, 0);
705 /* put a got entry corresponding to a symbol in symtab_section. 'size'
706 and 'info' can be modifed if more precise info comes from the DLL */
707 static void put_got_entry(TCCState *s1,
708 int reloc_type, unsigned long size, int info,
709 int sym_index)
711 int index;
712 const char *name;
713 Elf32_Sym *sym;
714 unsigned long offset;
715 int *ptr;
717 if (!s1->got)
718 build_got(s1);
720 /* if a got entry already exists for that symbol, no need to add one */
721 if (sym_index < s1->nb_got_offsets &&
722 s1->got_offsets[sym_index] != 0)
723 return;
725 put_got_offset(s1, sym_index, s1->got->data_offset);
727 if (s1->dynsym) {
728 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
729 name = symtab_section->link->data + sym->st_name;
730 offset = sym->st_value;
731 #ifdef TCC_TARGET_I386
732 if (reloc_type == R_386_JMP_SLOT) {
733 Section *plt;
734 uint8_t *p;
735 int modrm;
737 /* if we build a DLL, we add a %ebx offset */
738 if (s1->output_type == TCC_OUTPUT_DLL)
739 modrm = 0xa3;
740 else
741 modrm = 0x25;
743 /* add a PLT entry */
744 plt = s1->plt;
745 if (plt->data_offset == 0) {
746 /* first plt entry */
747 p = section_ptr_add(plt, 16);
748 p[0] = 0xff; /* pushl got + 4 */
749 p[1] = modrm + 0x10;
750 put32(p + 2, 4);
751 p[6] = 0xff; /* jmp *(got + 8) */
752 p[7] = modrm;
753 put32(p + 8, 8);
756 p = section_ptr_add(plt, 16);
757 p[0] = 0xff; /* jmp *(got + x) */
758 p[1] = modrm;
759 put32(p + 2, s1->got->data_offset);
760 p[6] = 0x68; /* push $xxx */
761 put32(p + 7, (plt->data_offset - 32) >> 1);
762 p[11] = 0xe9; /* jmp plt_start */
763 put32(p + 12, -(plt->data_offset));
765 /* the symbol is modified so that it will be relocated to
766 the PLT */
767 if (s1->output_type == TCC_OUTPUT_EXE)
768 offset = plt->data_offset - 16;
770 #elif defined(TCC_TARGET_ARM)
771 if (reloc_type == R_ARM_JUMP_SLOT) {
772 Section *plt;
773 uint8_t *p;
775 /* if we build a DLL, we add a %ebx offset */
776 if (s1->output_type == TCC_OUTPUT_DLL)
777 error("DLLs unimplemented!");
779 /* add a PLT entry */
780 plt = s1->plt;
781 if (plt->data_offset == 0) {
782 /* first plt entry */
783 p = section_ptr_add(plt, 16);
784 put32(p , 0xe52de004);
785 put32(p + 4, 0xe59fe010);
786 put32(p + 8, 0xe08fe00e);
787 put32(p + 12, 0xe5bef008);
790 p = section_ptr_add(plt, 16);
791 put32(p , 0xe59fc004);
792 put32(p+4, 0xe08fc00c);
793 put32(p+8, 0xe59cf000);
794 put32(p+12, s1->got->data_offset);
796 /* the symbol is modified so that it will be relocated to
797 the PLT */
798 if (s1->output_type == TCC_OUTPUT_EXE)
799 offset = plt->data_offset - 16;
801 #elif defined(TCC_TARGET_C67)
802 error("C67 got not implemented");
803 #else
804 #error unsupported CPU
805 #endif
806 index = put_elf_sym(s1->dynsym, offset,
807 size, info, 0, sym->st_shndx, name);
808 /* put a got entry */
809 put_elf_reloc(s1->dynsym, s1->got,
810 s1->got->data_offset,
811 reloc_type, index);
813 ptr = section_ptr_add(s1->got, sizeof(int));
814 *ptr = 0;
817 /* build GOT and PLT entries */
818 static void build_got_entries(TCCState *s1)
820 Section *s, *symtab;
821 Elf32_Rel *rel, *rel_end;
822 Elf32_Sym *sym;
823 int i, type, reloc_type, sym_index;
825 for(i = 1; i < s1->nb_sections; i++) {
826 s = s1->sections[i];
827 if (s->sh_type != SHT_REL)
828 continue;
829 /* no need to handle got relocations */
830 if (s->link != symtab_section)
831 continue;
832 symtab = s->link;
833 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
834 for(rel = (Elf32_Rel *)s->data;
835 rel < rel_end;
836 rel++) {
837 type = ELF32_R_TYPE(rel->r_info);
838 switch(type) {
839 #if defined(TCC_TARGET_I386)
840 case R_386_GOT32:
841 case R_386_GOTOFF:
842 case R_386_GOTPC:
843 case R_386_PLT32:
844 if (!s1->got)
845 build_got(s1);
846 if (type == R_386_GOT32 || type == R_386_PLT32) {
847 sym_index = ELF32_R_SYM(rel->r_info);
848 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
849 /* look at the symbol got offset. If none, then add one */
850 if (type == R_386_GOT32)
851 reloc_type = R_386_GLOB_DAT;
852 else
853 reloc_type = R_386_JMP_SLOT;
854 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
855 sym_index);
857 break;
858 #elif defined(TCC_TARGET_ARM)
859 case R_ARM_GOT32:
860 case R_ARM_GOTOFF:
861 case R_ARM_GOTPC:
862 case R_ARM_PLT32:
863 if (!s1->got)
864 build_got(s1);
865 if (type == R_ARM_GOT32 || type == R_ARM_PLT32) {
866 sym_index = ELF32_R_SYM(rel->r_info);
867 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
868 /* look at the symbol got offset. If none, then add one */
869 if (type == R_ARM_GOT32)
870 reloc_type = R_ARM_GLOB_DAT;
871 else
872 reloc_type = R_ARM_JUMP_SLOT;
873 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
874 sym_index);
876 break;
877 #elif defined(TCC_TARGET_C67)
878 case R_C60_GOT32:
879 case R_C60_GOTOFF:
880 case R_C60_GOTPC:
881 case R_C60_PLT32:
882 if (!s1->got)
883 build_got(s1);
884 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
885 sym_index = ELF32_R_SYM(rel->r_info);
886 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
887 /* look at the symbol got offset. If none, then add one */
888 if (type == R_C60_GOT32)
889 reloc_type = R_C60_GLOB_DAT;
890 else
891 reloc_type = R_C60_JMP_SLOT;
892 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
893 sym_index);
895 break;
896 #else
897 #error unsupported CPU
898 #endif
899 default:
900 break;
906 static Section *new_symtab(TCCState *s1,
907 const char *symtab_name, int sh_type, int sh_flags,
908 const char *strtab_name,
909 const char *hash_name, int hash_sh_flags)
911 Section *symtab, *strtab, *hash;
912 int *ptr, nb_buckets;
914 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
915 symtab->sh_entsize = sizeof(Elf32_Sym);
916 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
917 put_elf_str(strtab, "");
918 symtab->link = strtab;
919 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
921 nb_buckets = 1;
923 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
924 hash->sh_entsize = sizeof(int);
925 symtab->hash = hash;
926 hash->link = symtab;
928 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
929 ptr[0] = nb_buckets;
930 ptr[1] = 1;
931 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
932 return symtab;
935 /* put dynamic tag */
936 static void put_dt(Section *dynamic, int dt, unsigned long val)
938 Elf32_Dyn *dyn;
939 dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
940 dyn->d_tag = dt;
941 dyn->d_un.d_val = val;
944 static void add_init_array_defines(TCCState *s1, const char *section_name)
946 Section *s;
947 long end_offset;
948 char sym_start[1024];
949 char sym_end[1024];
951 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
952 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
954 s = find_section(s1, section_name);
955 if (!s) {
956 end_offset = 0;
957 s = data_section;
958 } else {
959 end_offset = s->data_offset;
962 add_elf_sym(symtab_section,
963 0, 0,
964 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
965 s->sh_num, sym_start);
966 add_elf_sym(symtab_section,
967 end_offset, 0,
968 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
969 s->sh_num, sym_end);
972 /* add tcc runtime libraries */
973 static void tcc_add_runtime(TCCState *s1)
975 char buf[1024];
977 #ifdef CONFIG_TCC_BCHECK
978 if (do_bounds_check) {
979 unsigned long *ptr;
980 Section *init_section;
981 unsigned char *pinit;
982 int sym_index;
984 /* XXX: add an object file to do that */
985 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
986 *ptr = 0;
987 add_elf_sym(symtab_section, 0, 0,
988 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
989 bounds_section->sh_num, "__bounds_start");
990 /* add bound check code */
991 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
992 tcc_add_file(s1, buf);
993 #ifdef TCC_TARGET_I386
994 if (s1->output_type != TCC_OUTPUT_MEMORY) {
995 /* add 'call __bound_init()' in .init section */
996 init_section = find_section(s1, ".init");
997 pinit = section_ptr_add(init_section, 5);
998 pinit[0] = 0xe8;
999 put32(pinit + 1, -4);
1000 sym_index = find_elf_sym(symtab_section, "__bound_init");
1001 put_elf_reloc(symtab_section, init_section,
1002 init_section->data_offset - 4, R_386_PC32, sym_index);
1004 #endif
1006 #endif
1007 /* add libc */
1008 if (!s1->nostdlib) {
1009 tcc_add_library(s1, "c");
1011 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
1012 tcc_add_file(s1, buf);
1014 /* add crt end if not memory output */
1015 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
1016 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1020 /* add various standard linker symbols (must be done after the
1021 sections are filled (for example after allocating common
1022 symbols)) */
1023 static void tcc_add_linker_symbols(TCCState *s1)
1025 char buf[1024];
1026 int i;
1027 Section *s;
1029 add_elf_sym(symtab_section,
1030 text_section->data_offset, 0,
1031 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1032 text_section->sh_num, "_etext");
1033 add_elf_sym(symtab_section,
1034 data_section->data_offset, 0,
1035 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1036 data_section->sh_num, "_edata");
1037 add_elf_sym(symtab_section,
1038 bss_section->data_offset, 0,
1039 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1040 bss_section->sh_num, "_end");
1041 /* horrible new standard ldscript defines */
1042 add_init_array_defines(s1, ".preinit_array");
1043 add_init_array_defines(s1, ".init_array");
1044 add_init_array_defines(s1, ".fini_array");
1046 /* add start and stop symbols for sections whose name can be
1047 expressed in C */
1048 for(i = 1; i < s1->nb_sections; i++) {
1049 s = s1->sections[i];
1050 if (s->sh_type == SHT_PROGBITS &&
1051 (s->sh_flags & SHF_ALLOC)) {
1052 const char *p;
1053 int ch;
1055 /* check if section name can be expressed in C */
1056 p = s->name;
1057 for(;;) {
1058 ch = *p;
1059 if (!ch)
1060 break;
1061 if (!isid(ch) && !isnum(ch))
1062 goto next_sec;
1063 p++;
1065 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1066 add_elf_sym(symtab_section,
1067 0, 0,
1068 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1069 s->sh_num, buf);
1070 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1071 add_elf_sym(symtab_section,
1072 s->data_offset, 0,
1073 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1074 s->sh_num, buf);
1076 next_sec: ;
1080 /* name of ELF interpreter */
1081 #ifdef __FreeBSD__
1082 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1083 #else
1084 static char elf_interp[] = "/lib/ld-linux.so.2";
1085 #endif
1087 static void tcc_output_binary(TCCState *s1, FILE *f,
1088 const int *section_order)
1090 Section *s;
1091 int i, offset, size;
1093 offset = 0;
1094 for(i=1;i<s1->nb_sections;i++) {
1095 s = s1->sections[section_order[i]];
1096 if (s->sh_type != SHT_NOBITS &&
1097 (s->sh_flags & SHF_ALLOC)) {
1098 while (offset < s->sh_offset) {
1099 fputc(0, f);
1100 offset++;
1102 size = s->sh_size;
1103 fwrite(s->data, 1, size, f);
1104 offset += size;
1109 /* output an ELF file */
1110 /* XXX: suppress unneeded sections */
1111 int tcc_output_file(TCCState *s1, const char *filename)
1113 Elf32_Ehdr ehdr;
1114 FILE *f;
1115 int fd, mode, ret;
1116 int *section_order;
1117 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1118 unsigned long addr;
1119 Section *strsec, *s;
1120 Elf32_Shdr shdr, *sh;
1121 Elf32_Phdr *phdr, *ph;
1122 Section *interp, *dynamic, *dynstr;
1123 unsigned long saved_dynamic_data_offset;
1124 Elf32_Sym *sym;
1125 int type, file_type;
1126 unsigned long rel_addr, rel_size;
1128 file_type = s1->output_type;
1129 s1->nb_errors = 0;
1131 if (file_type != TCC_OUTPUT_OBJ) {
1132 tcc_add_runtime(s1);
1135 phdr = NULL;
1136 section_order = NULL;
1137 interp = NULL;
1138 dynamic = NULL;
1139 dynstr = NULL; /* avoid warning */
1140 saved_dynamic_data_offset = 0; /* avoid warning */
1142 if (file_type != TCC_OUTPUT_OBJ) {
1143 relocate_common_syms();
1145 tcc_add_linker_symbols(s1);
1147 if (!s1->static_link) {
1148 const char *name;
1149 int sym_index, index;
1150 Elf32_Sym *esym, *sym_end;
1152 if (file_type == TCC_OUTPUT_EXE) {
1153 char *ptr;
1154 /* add interpreter section only if executable */
1155 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1156 interp->sh_addralign = 1;
1157 ptr = section_ptr_add(interp, sizeof(elf_interp));
1158 strcpy(ptr, elf_interp);
1161 /* add dynamic symbol table */
1162 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1163 ".dynstr",
1164 ".hash", SHF_ALLOC);
1165 dynstr = s1->dynsym->link;
1167 /* add dynamic section */
1168 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1169 SHF_ALLOC | SHF_WRITE);
1170 dynamic->link = dynstr;
1171 dynamic->sh_entsize = sizeof(Elf32_Dyn);
1173 /* add PLT */
1174 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1175 SHF_ALLOC | SHF_EXECINSTR);
1176 s1->plt->sh_entsize = 4;
1178 build_got(s1);
1180 /* scan for undefined symbols and see if they are in the
1181 dynamic symbols. If a symbol STT_FUNC is found, then we
1182 add it in the PLT. If a symbol STT_OBJECT is found, we
1183 add it in the .bss section with a suitable relocation */
1184 sym_end = (Elf32_Sym *)(symtab_section->data +
1185 symtab_section->data_offset);
1186 if (file_type == TCC_OUTPUT_EXE) {
1187 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1188 sym < sym_end;
1189 sym++) {
1190 if (sym->st_shndx == SHN_UNDEF) {
1191 name = symtab_section->link->data + sym->st_name;
1192 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1193 if (sym_index) {
1194 esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
1195 type = ELF32_ST_TYPE(esym->st_info);
1196 if (type == STT_FUNC) {
1197 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1198 esym->st_info,
1199 sym - (Elf32_Sym *)symtab_section->data);
1200 } else if (type == STT_OBJECT) {
1201 unsigned long offset;
1202 offset = bss_section->data_offset;
1203 /* XXX: which alignment ? */
1204 offset = (offset + 16 - 1) & -16;
1205 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1206 esym->st_info, 0,
1207 bss_section->sh_num, name);
1208 put_elf_reloc(s1->dynsym, bss_section,
1209 offset, R_COPY, index);
1210 offset += esym->st_size;
1211 bss_section->data_offset = offset;
1213 } else {
1214 /* STB_WEAK undefined symbols are accepted */
1215 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1216 it */
1217 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
1218 !strcmp(name, "_fp_hw")) {
1219 } else {
1220 error_noabort("undefined symbol '%s'", name);
1223 } else if (s1->rdynamic &&
1224 ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1225 /* if -rdynamic option, then export all non
1226 local symbols */
1227 name = symtab_section->link->data + sym->st_name;
1228 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1229 sym->st_info, 0,
1230 sym->st_shndx, name);
1234 if (s1->nb_errors)
1235 goto fail;
1237 /* now look at unresolved dynamic symbols and export
1238 corresponding symbol */
1239 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
1240 s1->dynsymtab_section->data_offset);
1241 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
1242 esym < sym_end;
1243 esym++) {
1244 if (esym->st_shndx == SHN_UNDEF) {
1245 name = s1->dynsymtab_section->link->data + esym->st_name;
1246 sym_index = find_elf_sym(symtab_section, name);
1247 if (sym_index) {
1248 /* XXX: avoid adding a symbol if already
1249 present because of -rdynamic ? */
1250 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1251 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1252 sym->st_info, 0,
1253 sym->st_shndx, name);
1254 } else {
1255 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
1256 /* weak symbols can stay undefined */
1257 } else {
1258 warning("undefined dynamic symbol '%s'", name);
1263 } else {
1264 int nb_syms;
1265 /* shared library case : we simply export all the global symbols */
1266 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
1267 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1268 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1269 sym < sym_end;
1270 sym++) {
1271 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1272 name = symtab_section->link->data + sym->st_name;
1273 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1274 sym->st_info, 0,
1275 sym->st_shndx, name);
1276 s1->symtab_to_dynsym[sym -
1277 (Elf32_Sym *)symtab_section->data] =
1278 index;
1283 build_got_entries(s1);
1285 /* add a list of needed dlls */
1286 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1287 DLLReference *dllref = s1->loaded_dlls[i];
1288 if (dllref->level == 0)
1289 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1291 /* XXX: currently, since we do not handle PIC code, we
1292 must relocate the readonly segments */
1293 if (file_type == TCC_OUTPUT_DLL)
1294 put_dt(dynamic, DT_TEXTREL, 0);
1296 /* add necessary space for other entries */
1297 saved_dynamic_data_offset = dynamic->data_offset;
1298 dynamic->data_offset += 8 * 9;
1299 } else {
1300 /* still need to build got entries in case of static link */
1301 build_got_entries(s1);
1305 memset(&ehdr, 0, sizeof(ehdr));
1307 /* we add a section for symbols */
1308 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1309 put_elf_str(strsec, "");
1311 /* compute number of sections */
1312 shnum = s1->nb_sections;
1314 /* this array is used to reorder sections in the output file */
1315 section_order = tcc_malloc(sizeof(int) * shnum);
1316 section_order[0] = 0;
1317 sh_order_index = 1;
1319 /* compute number of program headers */
1320 switch(file_type) {
1321 default:
1322 case TCC_OUTPUT_OBJ:
1323 phnum = 0;
1324 break;
1325 case TCC_OUTPUT_EXE:
1326 if (!s1->static_link)
1327 phnum = 4;
1328 else
1329 phnum = 2;
1330 break;
1331 case TCC_OUTPUT_DLL:
1332 phnum = 3;
1333 break;
1336 /* allocate strings for section names and decide if an unallocated
1337 section should be output */
1338 /* NOTE: the strsec section comes last, so its size is also
1339 correct ! */
1340 for(i = 1; i < s1->nb_sections; i++) {
1341 s = s1->sections[i];
1342 s->sh_name = put_elf_str(strsec, s->name);
1343 /* when generating a DLL, we include relocations but we may
1344 patch them */
1345 if (file_type == TCC_OUTPUT_DLL &&
1346 s->sh_type == SHT_REL &&
1347 !(s->sh_flags & SHF_ALLOC)) {
1348 prepare_dynamic_rel(s1, s);
1349 } else if (do_debug ||
1350 file_type == TCC_OUTPUT_OBJ ||
1351 (s->sh_flags & SHF_ALLOC) ||
1352 i == (s1->nb_sections - 1)) {
1353 /* we output all sections if debug or object file */
1354 s->sh_size = s->data_offset;
1358 /* allocate program segment headers */
1359 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1361 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1362 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1363 } else {
1364 file_offset = 0;
1366 if (phnum > 0) {
1367 /* compute section to program header mapping */
1368 if (s1->has_text_addr) {
1369 int a_offset, p_offset;
1370 addr = s1->text_addr;
1371 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1372 ELF_PAGE_SIZE */
1373 a_offset = addr & (ELF_PAGE_SIZE - 1);
1374 p_offset = file_offset & (ELF_PAGE_SIZE - 1);
1375 if (a_offset < p_offset)
1376 a_offset += ELF_PAGE_SIZE;
1377 file_offset += (a_offset - p_offset);
1378 } else {
1379 if (file_type == TCC_OUTPUT_DLL)
1380 addr = 0;
1381 else
1382 addr = ELF_START_ADDR;
1383 /* compute address after headers */
1384 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1387 /* dynamic relocation table information, for .dynamic section */
1388 rel_size = 0;
1389 rel_addr = 0;
1391 /* leave one program header for the program interpreter */
1392 ph = &phdr[0];
1393 if (interp)
1394 ph++;
1396 for(j = 0; j < 2; j++) {
1397 ph->p_type = PT_LOAD;
1398 if (j == 0)
1399 ph->p_flags = PF_R | PF_X;
1400 else
1401 ph->p_flags = PF_R | PF_W;
1402 ph->p_align = ELF_PAGE_SIZE;
1404 /* we do the following ordering: interp, symbol tables,
1405 relocations, progbits, nobits */
1406 /* XXX: do faster and simpler sorting */
1407 for(k = 0; k < 5; k++) {
1408 for(i = 1; i < s1->nb_sections; i++) {
1409 s = s1->sections[i];
1410 /* compute if section should be included */
1411 if (j == 0) {
1412 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1413 SHF_ALLOC)
1414 continue;
1415 } else {
1416 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1417 (SHF_ALLOC | SHF_WRITE))
1418 continue;
1420 if (s == interp) {
1421 if (k != 0)
1422 continue;
1423 } else if (s->sh_type == SHT_DYNSYM ||
1424 s->sh_type == SHT_STRTAB ||
1425 s->sh_type == SHT_HASH) {
1426 if (k != 1)
1427 continue;
1428 } else if (s->sh_type == SHT_REL) {
1429 if (k != 2)
1430 continue;
1431 } else if (s->sh_type == SHT_NOBITS) {
1432 if (k != 4)
1433 continue;
1434 } else {
1435 if (k != 3)
1436 continue;
1438 section_order[sh_order_index++] = i;
1440 /* section matches: we align it and add its size */
1441 tmp = addr;
1442 addr = (addr + s->sh_addralign - 1) &
1443 ~(s->sh_addralign - 1);
1444 file_offset += addr - tmp;
1445 s->sh_offset = file_offset;
1446 s->sh_addr = addr;
1448 /* update program header infos */
1449 if (ph->p_offset == 0) {
1450 ph->p_offset = file_offset;
1451 ph->p_vaddr = addr;
1452 ph->p_paddr = ph->p_vaddr;
1454 /* update dynamic relocation infos */
1455 if (s->sh_type == SHT_REL) {
1456 if (rel_size == 0)
1457 rel_addr = addr;
1458 rel_size += s->sh_size;
1460 addr += s->sh_size;
1461 if (s->sh_type != SHT_NOBITS)
1462 file_offset += s->sh_size;
1465 ph->p_filesz = file_offset - ph->p_offset;
1466 ph->p_memsz = addr - ph->p_vaddr;
1467 ph++;
1468 if (j == 0) {
1469 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1470 /* if in the middle of a page, we duplicate the page in
1471 memory so that one copy is RX and the other is RW */
1472 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1473 addr += ELF_PAGE_SIZE;
1474 } else {
1475 addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
1476 file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
1477 ~(ELF_PAGE_SIZE - 1);
1482 /* if interpreter, then add corresponing program header */
1483 if (interp) {
1484 ph = &phdr[0];
1486 ph->p_type = PT_INTERP;
1487 ph->p_offset = interp->sh_offset;
1488 ph->p_vaddr = interp->sh_addr;
1489 ph->p_paddr = ph->p_vaddr;
1490 ph->p_filesz = interp->sh_size;
1491 ph->p_memsz = interp->sh_size;
1492 ph->p_flags = PF_R;
1493 ph->p_align = interp->sh_addralign;
1496 /* if dynamic section, then add corresponing program header */
1497 if (dynamic) {
1498 Elf32_Sym *sym_end;
1500 ph = &phdr[phnum - 1];
1502 ph->p_type = PT_DYNAMIC;
1503 ph->p_offset = dynamic->sh_offset;
1504 ph->p_vaddr = dynamic->sh_addr;
1505 ph->p_paddr = ph->p_vaddr;
1506 ph->p_filesz = dynamic->sh_size;
1507 ph->p_memsz = dynamic->sh_size;
1508 ph->p_flags = PF_R | PF_W;
1509 ph->p_align = dynamic->sh_addralign;
1511 /* put GOT dynamic section address */
1512 put32(s1->got->data, dynamic->sh_addr);
1514 /* relocate the PLT */
1515 if (file_type == TCC_OUTPUT_EXE) {
1516 uint8_t *p, *p_end;
1518 p = s1->plt->data;
1519 p_end = p + s1->plt->data_offset;
1520 if (p < p_end) {
1521 #if defined(TCC_TARGET_I386)
1522 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1523 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1524 p += 16;
1525 while (p < p_end) {
1526 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1527 p += 16;
1529 #elif defined(TCC_TARGET_ARM)
1530 int x;
1531 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1532 p +=16;
1533 while (p < p_end) {
1534 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1535 p += 16;
1537 #elif defined(TCC_TARGET_C67)
1538 /* XXX: TODO */
1539 #else
1540 #error unsupported CPU
1541 #endif
1545 /* relocate symbols in .dynsym */
1546 sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
1547 for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
1548 sym < sym_end;
1549 sym++) {
1550 if (sym->st_shndx == SHN_UNDEF) {
1551 /* relocate to the PLT if the symbol corresponds
1552 to a PLT entry */
1553 if (sym->st_value)
1554 sym->st_value += s1->plt->sh_addr;
1555 } else if (sym->st_shndx < SHN_LORESERVE) {
1556 /* do symbol relocation */
1557 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1561 /* put dynamic section entries */
1562 dynamic->data_offset = saved_dynamic_data_offset;
1563 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1564 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1565 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1566 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1567 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
1568 put_dt(dynamic, DT_REL, rel_addr);
1569 put_dt(dynamic, DT_RELSZ, rel_size);
1570 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
1571 put_dt(dynamic, DT_NULL, 0);
1574 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1575 ehdr.e_phnum = phnum;
1576 ehdr.e_phoff = sizeof(Elf32_Ehdr);
1579 /* all other sections come after */
1580 for(i = 1; i < s1->nb_sections; i++) {
1581 s = s1->sections[i];
1582 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1583 continue;
1584 section_order[sh_order_index++] = i;
1586 file_offset = (file_offset + s->sh_addralign - 1) &
1587 ~(s->sh_addralign - 1);
1588 s->sh_offset = file_offset;
1589 if (s->sh_type != SHT_NOBITS)
1590 file_offset += s->sh_size;
1593 /* if building executable or DLL, then relocate each section
1594 except the GOT which is already relocated */
1595 if (file_type != TCC_OUTPUT_OBJ) {
1596 relocate_syms(s1, 0);
1598 if (s1->nb_errors != 0) {
1599 fail:
1600 ret = -1;
1601 goto the_end;
1604 /* relocate sections */
1605 /* XXX: ignore sections with allocated relocations ? */
1606 for(i = 1; i < s1->nb_sections; i++) {
1607 s = s1->sections[i];
1608 if (s->reloc && s != s1->got)
1609 relocate_section(s1, s);
1612 /* relocate relocation entries if the relocation tables are
1613 allocated in the executable */
1614 for(i = 1; i < s1->nb_sections; i++) {
1615 s = s1->sections[i];
1616 if ((s->sh_flags & SHF_ALLOC) &&
1617 s->sh_type == SHT_REL) {
1618 relocate_rel(s1, s);
1622 /* get entry point address */
1623 if (file_type == TCC_OUTPUT_EXE)
1624 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
1625 else
1626 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1629 /* write elf file */
1630 if (file_type == TCC_OUTPUT_OBJ)
1631 mode = 0666;
1632 else
1633 mode = 0777;
1634 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1635 if (fd < 0) {
1636 error_noabort("could not write '%s'", filename);
1637 goto fail;
1639 f = fdopen(fd, "wb");
1641 #ifdef TCC_TARGET_COFF
1642 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1643 tcc_output_coff(s1, f);
1644 } else
1645 #endif
1646 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1647 sort_syms(s1, symtab_section);
1649 /* align to 4 */
1650 file_offset = (file_offset + 3) & -4;
1652 /* fill header */
1653 ehdr.e_ident[0] = ELFMAG0;
1654 ehdr.e_ident[1] = ELFMAG1;
1655 ehdr.e_ident[2] = ELFMAG2;
1656 ehdr.e_ident[3] = ELFMAG3;
1657 ehdr.e_ident[4] = ELFCLASS32;
1658 ehdr.e_ident[5] = ELFDATA2LSB;
1659 ehdr.e_ident[6] = EV_CURRENT;
1660 #ifdef __FreeBSD__
1661 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1662 #endif
1663 #ifdef TCC_TARGET_ARM
1664 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1665 #endif
1666 switch(file_type) {
1667 default:
1668 case TCC_OUTPUT_EXE:
1669 ehdr.e_type = ET_EXEC;
1670 break;
1671 case TCC_OUTPUT_DLL:
1672 ehdr.e_type = ET_DYN;
1673 break;
1674 case TCC_OUTPUT_OBJ:
1675 ehdr.e_type = ET_REL;
1676 break;
1678 ehdr.e_machine = EM_TCC_TARGET;
1679 ehdr.e_version = EV_CURRENT;
1680 ehdr.e_shoff = file_offset;
1681 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1682 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1683 ehdr.e_shnum = shnum;
1684 ehdr.e_shstrndx = shnum - 1;
1686 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1687 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1688 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1690 for(i=1;i<s1->nb_sections;i++) {
1691 s = s1->sections[section_order[i]];
1692 if (s->sh_type != SHT_NOBITS) {
1693 while (offset < s->sh_offset) {
1694 fputc(0, f);
1695 offset++;
1697 size = s->sh_size;
1698 fwrite(s->data, 1, size, f);
1699 offset += size;
1703 /* output section headers */
1704 while (offset < ehdr.e_shoff) {
1705 fputc(0, f);
1706 offset++;
1709 for(i=0;i<s1->nb_sections;i++) {
1710 sh = &shdr;
1711 memset(sh, 0, sizeof(Elf32_Shdr));
1712 s = s1->sections[i];
1713 if (s) {
1714 sh->sh_name = s->sh_name;
1715 sh->sh_type = s->sh_type;
1716 sh->sh_flags = s->sh_flags;
1717 sh->sh_entsize = s->sh_entsize;
1718 sh->sh_info = s->sh_info;
1719 if (s->link)
1720 sh->sh_link = s->link->sh_num;
1721 sh->sh_addralign = s->sh_addralign;
1722 sh->sh_addr = s->sh_addr;
1723 sh->sh_offset = s->sh_offset;
1724 sh->sh_size = s->sh_size;
1726 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1728 } else {
1729 tcc_output_binary(s1, f, section_order);
1731 fclose(f);
1733 ret = 0;
1734 the_end:
1735 tcc_free(s1->symtab_to_dynsym);
1736 tcc_free(section_order);
1737 tcc_free(phdr);
1738 tcc_free(s1->got_offsets);
1739 return ret;
1742 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1744 void *data;
1746 data = tcc_malloc(size);
1747 lseek(fd, file_offset, SEEK_SET);
1748 read(fd, data, size);
1749 return data;
1752 typedef struct SectionMergeInfo {
1753 Section *s; /* corresponding existing section */
1754 unsigned long offset; /* offset of the new section in the existing section */
1755 uint8_t new_section; /* true if section 's' was added */
1756 uint8_t link_once; /* true if link once section */
1757 } SectionMergeInfo;
1759 /* load an object file and merge it with current files */
1760 /* XXX: handle correctly stab (debug) info */
1761 static int tcc_load_object_file(TCCState *s1,
1762 int fd, unsigned long file_offset)
1764 Elf32_Ehdr ehdr;
1765 Elf32_Shdr *shdr, *sh;
1766 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1767 unsigned char *strsec, *strtab;
1768 int *old_to_new_syms;
1769 char *sh_name, *name;
1770 SectionMergeInfo *sm_table, *sm;
1771 Elf32_Sym *sym, *symtab;
1772 Elf32_Rel *rel, *rel_end;
1773 Section *s;
1775 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1776 goto fail1;
1777 if (ehdr.e_ident[0] != ELFMAG0 ||
1778 ehdr.e_ident[1] != ELFMAG1 ||
1779 ehdr.e_ident[2] != ELFMAG2 ||
1780 ehdr.e_ident[3] != ELFMAG3)
1781 goto fail1;
1782 /* test if object file */
1783 if (ehdr.e_type != ET_REL)
1784 goto fail1;
1785 /* test CPU specific stuff */
1786 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1787 ehdr.e_machine != EM_TCC_TARGET) {
1788 fail1:
1789 error_noabort("invalid object file");
1790 return -1;
1792 /* read sections */
1793 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1794 sizeof(Elf32_Shdr) * ehdr.e_shnum);
1795 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1797 /* load section names */
1798 sh = &shdr[ehdr.e_shstrndx];
1799 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1801 /* load symtab and strtab */
1802 old_to_new_syms = NULL;
1803 symtab = NULL;
1804 strtab = NULL;
1805 nb_syms = 0;
1806 for(i = 1; i < ehdr.e_shnum; i++) {
1807 sh = &shdr[i];
1808 if (sh->sh_type == SHT_SYMTAB) {
1809 if (symtab) {
1810 error_noabort("object must contain only one symtab");
1811 fail:
1812 ret = -1;
1813 goto the_end;
1815 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1816 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1817 sm_table[i].s = symtab_section;
1819 /* now load strtab */
1820 sh = &shdr[sh->sh_link];
1821 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1825 /* now examine each section and try to merge its content with the
1826 ones in memory */
1827 for(i = 1; i < ehdr.e_shnum; i++) {
1828 /* no need to examine section name strtab */
1829 if (i == ehdr.e_shstrndx)
1830 continue;
1831 sh = &shdr[i];
1832 sh_name = strsec + sh->sh_name;
1833 /* ignore sections types we do not handle */
1834 if (sh->sh_type != SHT_PROGBITS &&
1835 sh->sh_type != SHT_REL &&
1836 sh->sh_type != SHT_NOBITS)
1837 continue;
1838 if (sh->sh_addralign < 1)
1839 sh->sh_addralign = 1;
1840 /* find corresponding section, if any */
1841 for(j = 1; j < s1->nb_sections;j++) {
1842 s = s1->sections[j];
1843 if (!strcmp(s->name, sh_name)) {
1844 if (!strncmp(sh_name, ".gnu.linkonce",
1845 sizeof(".gnu.linkonce") - 1)) {
1846 /* if a 'linkonce' section is already present, we
1847 do not add it again. It is a little tricky as
1848 symbols can still be defined in
1849 it. */
1850 sm_table[i].link_once = 1;
1851 goto next;
1852 } else {
1853 goto found;
1857 /* not found: create new section */
1858 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1859 /* take as much info as possible from the section. sh_link and
1860 sh_info will be updated later */
1861 s->sh_addralign = sh->sh_addralign;
1862 s->sh_entsize = sh->sh_entsize;
1863 sm_table[i].new_section = 1;
1864 found:
1865 if (sh->sh_type != s->sh_type) {
1866 error_noabort("invalid section type");
1867 goto fail;
1870 /* align start of section */
1871 offset = s->data_offset;
1872 size = sh->sh_addralign - 1;
1873 offset = (offset + size) & ~size;
1874 if (sh->sh_addralign > s->sh_addralign)
1875 s->sh_addralign = sh->sh_addralign;
1876 s->data_offset = offset;
1877 sm_table[i].offset = offset;
1878 sm_table[i].s = s;
1879 /* concatenate sections */
1880 size = sh->sh_size;
1881 if (sh->sh_type != SHT_NOBITS) {
1882 unsigned char *ptr;
1883 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1884 ptr = section_ptr_add(s, size);
1885 read(fd, ptr, size);
1886 } else {
1887 s->data_offset += size;
1889 next: ;
1892 /* second short pass to update sh_link and sh_info fields of new
1893 sections */
1894 for(i = 1; i < ehdr.e_shnum; i++) {
1895 s = sm_table[i].s;
1896 if (!s || !sm_table[i].new_section)
1897 continue;
1898 sh = &shdr[i];
1899 if (sh->sh_link > 0)
1900 s->link = sm_table[sh->sh_link].s;
1901 if (sh->sh_type == SHT_REL) {
1902 s->sh_info = sm_table[sh->sh_info].s->sh_num;
1903 /* update backward link */
1904 s1->sections[s->sh_info]->reloc = s;
1907 sm = sm_table;
1909 /* resolve symbols */
1910 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
1912 sym = symtab + 1;
1913 for(i = 1; i < nb_syms; i++, sym++) {
1914 if (sym->st_shndx != SHN_UNDEF &&
1915 sym->st_shndx < SHN_LORESERVE) {
1916 sm = &sm_table[sym->st_shndx];
1917 if (sm->link_once) {
1918 /* if a symbol is in a link once section, we use the
1919 already defined symbol. It is very important to get
1920 correct relocations */
1921 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1922 name = strtab + sym->st_name;
1923 sym_index = find_elf_sym(symtab_section, name);
1924 if (sym_index)
1925 old_to_new_syms[i] = sym_index;
1927 continue;
1929 /* if no corresponding section added, no need to add symbol */
1930 if (!sm->s)
1931 continue;
1932 /* convert section number */
1933 sym->st_shndx = sm->s->sh_num;
1934 /* offset value */
1935 sym->st_value += sm->offset;
1937 /* add symbol */
1938 name = strtab + sym->st_name;
1939 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
1940 sym->st_info, sym->st_other,
1941 sym->st_shndx, name);
1942 old_to_new_syms[i] = sym_index;
1945 /* third pass to patch relocation entries */
1946 for(i = 1; i < ehdr.e_shnum; i++) {
1947 s = sm_table[i].s;
1948 if (!s)
1949 continue;
1950 sh = &shdr[i];
1951 offset = sm_table[i].offset;
1952 switch(s->sh_type) {
1953 case SHT_REL:
1954 /* take relocation offset information */
1955 offseti = sm_table[sh->sh_info].offset;
1956 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
1957 for(rel = (Elf32_Rel *)(s->data + offset);
1958 rel < rel_end;
1959 rel++) {
1960 int type;
1961 unsigned sym_index;
1962 /* convert symbol index */
1963 type = ELF32_R_TYPE(rel->r_info);
1964 sym_index = ELF32_R_SYM(rel->r_info);
1965 /* NOTE: only one symtab assumed */
1966 if (sym_index >= nb_syms)
1967 goto invalid_reloc;
1968 sym_index = old_to_new_syms[sym_index];
1969 /* ignore link_once in rel section. */
1970 if (!sym_index && !sm->link_once) {
1971 invalid_reloc:
1972 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
1973 i, strsec + sh->sh_name, rel->r_offset);
1974 goto fail;
1976 rel->r_info = ELF32_R_INFO(sym_index, type);
1977 /* offset the relocation offset */
1978 rel->r_offset += offseti;
1980 break;
1981 default:
1982 break;
1986 ret = 0;
1987 the_end:
1988 tcc_free(symtab);
1989 tcc_free(strtab);
1990 tcc_free(old_to_new_syms);
1991 tcc_free(sm_table);
1992 tcc_free(strsec);
1993 tcc_free(shdr);
1994 return ret;
1997 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1999 typedef struct ArchiveHeader {
2000 char ar_name[16]; /* name of this member */
2001 char ar_date[12]; /* file mtime */
2002 char ar_uid[6]; /* owner uid; printed as decimal */
2003 char ar_gid[6]; /* owner gid; printed as decimal */
2004 char ar_mode[8]; /* file mode, printed as octal */
2005 char ar_size[10]; /* file size, printed as decimal */
2006 char ar_fmag[2]; /* should contain ARFMAG */
2007 } ArchiveHeader;
2009 static int get_be32(const uint8_t *b)
2011 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2014 /* load only the objects which resolve undefined symbols */
2015 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
2017 int i, bound, nsyms, sym_index, off, ret;
2018 uint8_t *data;
2019 const char *ar_names, *p;
2020 const uint8_t *ar_index;
2021 Elf32_Sym *sym;
2023 data = tcc_malloc(size);
2024 if (read(fd, data, size) != size)
2025 goto fail;
2026 nsyms = get_be32(data);
2027 ar_index = data + 4;
2028 ar_names = ar_index + nsyms * 4;
2030 do {
2031 bound = 0;
2032 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2033 sym_index = find_elf_sym(symtab_section, p);
2034 if(sym_index) {
2035 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
2036 if(sym->st_shndx == SHN_UNDEF) {
2037 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2038 #if 0
2039 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2040 #endif
2041 ++bound;
2042 lseek(fd, off, SEEK_SET);
2043 if(tcc_load_object_file(s1, fd, off) < 0) {
2044 fail:
2045 ret = -1;
2046 goto the_end;
2051 } while(bound);
2052 ret = 0;
2053 the_end:
2054 tcc_free(data);
2055 return ret;
2058 /* load a '.a' file */
2059 static int tcc_load_archive(TCCState *s1, int fd)
2061 ArchiveHeader hdr;
2062 char ar_size[11];
2063 char ar_name[17];
2064 char magic[8];
2065 int size, len, i;
2066 unsigned long file_offset;
2068 /* skip magic which was already checked */
2069 read(fd, magic, sizeof(magic));
2071 for(;;) {
2072 len = read(fd, &hdr, sizeof(hdr));
2073 if (len == 0)
2074 break;
2075 if (len != sizeof(hdr)) {
2076 error_noabort("invalid archive");
2077 return -1;
2079 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2080 ar_size[sizeof(hdr.ar_size)] = '\0';
2081 size = strtol(ar_size, NULL, 0);
2082 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2083 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2084 if (ar_name[i] != ' ')
2085 break;
2087 ar_name[i + 1] = '\0';
2088 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2089 file_offset = lseek(fd, 0, SEEK_CUR);
2090 /* align to even */
2091 size = (size + 1) & ~1;
2092 if (!strcmp(ar_name, "/")) {
2093 /* coff symbol table : we handle it */
2094 if(s1->alacarte_link)
2095 return tcc_load_alacarte(s1, fd, size);
2096 } else if (!strcmp(ar_name, "//") ||
2097 !strcmp(ar_name, "__.SYMDEF") ||
2098 !strcmp(ar_name, "__.SYMDEF/") ||
2099 !strcmp(ar_name, "ARFILENAMES/")) {
2100 /* skip symbol table or archive names */
2101 } else {
2102 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2103 return -1;
2105 lseek(fd, file_offset + size, SEEK_SET);
2107 return 0;
2110 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2111 is referenced by the user (so it should be added as DT_NEEDED in
2112 the generated ELF file) */
2113 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2115 Elf32_Ehdr ehdr;
2116 Elf32_Shdr *shdr, *sh, *sh1;
2117 int i, j, nb_syms, nb_dts, sym_bind, ret;
2118 Elf32_Sym *sym, *dynsym;
2119 Elf32_Dyn *dt, *dynamic;
2120 unsigned char *dynstr;
2121 const char *name, *soname, *p;
2122 DLLReference *dllref;
2124 read(fd, &ehdr, sizeof(ehdr));
2126 /* test CPU specific stuff */
2127 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2128 ehdr.e_machine != EM_TCC_TARGET) {
2129 error_noabort("bad architecture");
2130 return -1;
2133 /* read sections */
2134 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
2136 /* load dynamic section and dynamic symbols */
2137 nb_syms = 0;
2138 nb_dts = 0;
2139 dynamic = NULL;
2140 dynsym = NULL; /* avoid warning */
2141 dynstr = NULL; /* avoid warning */
2142 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2143 switch(sh->sh_type) {
2144 case SHT_DYNAMIC:
2145 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
2146 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2147 break;
2148 case SHT_DYNSYM:
2149 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
2150 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2151 sh1 = &shdr[sh->sh_link];
2152 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2153 break;
2154 default:
2155 break;
2159 /* compute the real library name */
2160 soname = filename;
2161 p = strrchr(soname, '/');
2162 if (p)
2163 soname = p + 1;
2165 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2166 if (dt->d_tag == DT_SONAME) {
2167 soname = dynstr + dt->d_un.d_val;
2171 /* if the dll is already loaded, do not load it */
2172 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2173 dllref = s1->loaded_dlls[i];
2174 if (!strcmp(soname, dllref->name)) {
2175 /* but update level if needed */
2176 if (level < dllref->level)
2177 dllref->level = level;
2178 ret = 0;
2179 goto the_end;
2183 // printf("loading dll '%s'\n", soname);
2185 /* add the dll and its level */
2186 dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
2187 dllref->level = level;
2188 strcpy(dllref->name, soname);
2189 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2191 /* add dynamic symbols in dynsym_section */
2192 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2193 sym_bind = ELF32_ST_BIND(sym->st_info);
2194 if (sym_bind == STB_LOCAL)
2195 continue;
2196 name = dynstr + sym->st_name;
2197 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2198 sym->st_info, sym->st_other, sym->st_shndx, name);
2201 /* load all referenced DLLs */
2202 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2203 switch(dt->d_tag) {
2204 case DT_NEEDED:
2205 name = dynstr + dt->d_un.d_val;
2206 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2207 dllref = s1->loaded_dlls[j];
2208 if (!strcmp(name, dllref->name))
2209 goto already_loaded;
2211 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2212 error_noabort("referenced dll '%s' not found", name);
2213 ret = -1;
2214 goto the_end;
2216 already_loaded:
2217 break;
2220 ret = 0;
2221 the_end:
2222 tcc_free(dynstr);
2223 tcc_free(dynsym);
2224 tcc_free(dynamic);
2225 tcc_free(shdr);
2226 return ret;
2229 #define LD_TOK_NAME 256
2230 #define LD_TOK_EOF (-1)
2232 /* return next ld script token */
2233 static int ld_next(TCCState *s1, char *name, int name_size)
2235 int c;
2236 char *q;
2238 redo:
2239 switch(ch) {
2240 case ' ':
2241 case '\t':
2242 case '\f':
2243 case '\v':
2244 case '\r':
2245 case '\n':
2246 inp();
2247 goto redo;
2248 case '/':
2249 minp();
2250 if (ch == '*') {
2251 file->buf_ptr = parse_comment(file->buf_ptr);
2252 ch = file->buf_ptr[0];
2253 goto redo;
2254 } else {
2255 q = name;
2256 *q++ = '/';
2257 goto parse_name;
2259 break;
2260 case 'a' ... 'z':
2261 case 'A' ... 'Z':
2262 case '_':
2263 case '\\':
2264 case '.':
2265 case '$':
2266 case '~':
2267 q = name;
2268 parse_name:
2269 for(;;) {
2270 if (!((ch >= 'a' && ch <= 'z') ||
2271 (ch >= 'A' && ch <= 'Z') ||
2272 (ch >= '0' && ch <= '9') ||
2273 strchr("/.-_+=$:\\,~", ch)))
2274 break;
2275 if ((q - name) < name_size - 1) {
2276 *q++ = ch;
2278 minp();
2280 *q = '\0';
2281 c = LD_TOK_NAME;
2282 break;
2283 case CH_EOF:
2284 c = LD_TOK_EOF;
2285 break;
2286 default:
2287 c = ch;
2288 inp();
2289 break;
2291 #if 0
2292 printf("tok=%c %d\n", c, c);
2293 if (c == LD_TOK_NAME)
2294 printf(" name=%s\n", name);
2295 #endif
2296 return c;
2299 static int ld_add_file_list(TCCState *s1, int as_needed)
2301 char filename[1024];
2302 int t, ret;
2304 t = ld_next(s1, filename, sizeof(filename));
2305 if (t != '(')
2306 expect("(");
2307 t = ld_next(s1, filename, sizeof(filename));
2308 for(;;) {
2309 if (t == LD_TOK_EOF) {
2310 error_noabort("unexpected end of file");
2311 return -1;
2312 } else if (t == ')') {
2313 break;
2314 } else if (t != LD_TOK_NAME) {
2315 error_noabort("filename expected");
2316 return -1;
2318 if (!strcmp(filename, "AS_NEEDED")) {
2319 ret = ld_add_file_list(s1, 1);
2320 if (ret)
2321 return ret;
2322 } else {
2323 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2324 if (!as_needed)
2325 tcc_add_file(s1, filename);
2327 t = ld_next(s1, filename, sizeof(filename));
2328 if (t == ',') {
2329 t = ld_next(s1, filename, sizeof(filename));
2332 return 0;
2335 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2336 files */
2337 static int tcc_load_ldscript(TCCState *s1)
2339 char cmd[64];
2340 char filename[1024];
2341 int t, ret;
2343 ch = file->buf_ptr[0];
2344 ch = handle_eob();
2345 for(;;) {
2346 t = ld_next(s1, cmd, sizeof(cmd));
2347 if (t == LD_TOK_EOF)
2348 return 0;
2349 else if (t != LD_TOK_NAME)
2350 return -1;
2351 if (!strcmp(cmd, "INPUT") ||
2352 !strcmp(cmd, "GROUP")) {
2353 ret = ld_add_file_list(s1, 0);
2354 if (ret)
2355 return ret;
2356 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2357 !strcmp(cmd, "TARGET")) {
2358 /* ignore some commands */
2359 t = ld_next(s1, cmd, sizeof(cmd));
2360 if (t != '(')
2361 expect("(");
2362 for(;;) {
2363 t = ld_next(s1, filename, sizeof(filename));
2364 if (t == LD_TOK_EOF) {
2365 error_noabort("unexpected end of file");
2366 return -1;
2367 } else if (t == ')') {
2368 break;
2371 } else {
2372 return -1;
2375 return 0;