Switch to newer tccpe.c (includes support for resources)
[tinycc.git] / tccelf.c
blob273d0b91e26917b813d9ebdd3417405654a1767a
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_CALL:
536 case R_ARM_JUMP24:
537 case R_ARM_PLT32:
539 int x;
540 x = (*(int *)ptr)&0xffffff;
541 (*(int *)ptr) &= 0xff000000;
542 if (x & 0x800000)
543 x -= 0x1000000;
544 x *= 4;
545 x += val - addr;
546 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
547 error("can't relocate value at %x",addr);
548 x >>= 2;
549 x &= 0xffffff;
550 (*(int *)ptr) |= x;
552 break;
553 case R_ARM_PREL31:
555 int x;
556 x = (*(int *)ptr) & 0x7fffffff;
557 (*(int *)ptr) &= 0x80000000;
558 x = (x * 2) / 2;
559 x += val - addr;
560 if((x^(x>>1))&0x40000000)
561 error("can't relocate value at %x",addr);
562 (*(int *)ptr) |= x & 0x7fffffff;
564 case R_ARM_ABS32:
565 *(int *)ptr += val;
566 break;
567 case R_ARM_BASE_PREL:
568 *(int *)ptr += s1->got->sh_addr - addr;
569 break;
570 case R_ARM_GOTOFF32:
571 *(int *)ptr += val - s1->got->sh_addr;
572 break;
573 case R_ARM_GOT_BREL:
574 /* we load the got offset */
575 *(int *)ptr += s1->got_offsets[sym_index];
576 break;
577 case R_ARM_COPY:
578 break;
579 default:
580 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
581 type,addr,(unsigned int )ptr,val);
582 break;
583 #elif defined(TCC_TARGET_C67)
584 case R_C60_32:
585 *(int *)ptr += val;
586 break;
587 case R_C60LO16:
589 uint32_t orig;
591 /* put the low 16 bits of the absolute address */
592 // add to what is already there
594 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
595 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
597 //patch both at once - assumes always in pairs Low - High
599 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
600 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
602 break;
603 case R_C60HI16:
604 break;
605 default:
606 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
607 type,addr,(unsigned int )ptr,val);
608 break;
609 #else
610 #error unsupported processor
611 #endif
614 /* if the relocation is allocated, we change its symbol table */
615 if (sr->sh_flags & SHF_ALLOC)
616 sr->link = s1->dynsym;
619 /* relocate relocation table in 'sr' */
620 static void relocate_rel(TCCState *s1, Section *sr)
622 Section *s;
623 Elf32_Rel *rel, *rel_end;
625 s = s1->sections[sr->sh_info];
626 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
627 for(rel = (Elf32_Rel *)sr->data;
628 rel < rel_end;
629 rel++) {
630 rel->r_offset += s->sh_addr;
634 /* count the number of dynamic relocations so that we can reserve
635 their space */
636 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
638 Elf32_Rel *rel, *rel_end;
639 int sym_index, esym_index, type, count;
641 count = 0;
642 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
643 for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) {
644 sym_index = ELF32_R_SYM(rel->r_info);
645 type = ELF32_R_TYPE(rel->r_info);
646 switch(type) {
647 case R_386_32:
648 count++;
649 break;
650 case R_386_PC32:
651 esym_index = s1->symtab_to_dynsym[sym_index];
652 if (esym_index)
653 count++;
654 break;
655 default:
656 break;
659 if (count) {
660 /* allocate the section */
661 sr->sh_flags |= SHF_ALLOC;
662 sr->sh_size = count * sizeof(Elf32_Rel);
664 return count;
667 static void put_got_offset(TCCState *s1, int index, unsigned long val)
669 int n;
670 unsigned long *tab;
672 if (index >= s1->nb_got_offsets) {
673 /* find immediately bigger power of 2 and reallocate array */
674 n = 1;
675 while (index >= n)
676 n *= 2;
677 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
678 if (!tab)
679 error("memory full");
680 s1->got_offsets = tab;
681 memset(s1->got_offsets + s1->nb_got_offsets, 0,
682 (n - s1->nb_got_offsets) * sizeof(unsigned long));
683 s1->nb_got_offsets = n;
685 s1->got_offsets[index] = val;
688 /* XXX: suppress that */
689 static void put32(unsigned char *p, uint32_t val)
691 p[0] = val;
692 p[1] = val >> 8;
693 p[2] = val >> 16;
694 p[3] = val >> 24;
697 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM)
698 static uint32_t get32(unsigned char *p)
700 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
702 #endif
704 static void build_got(TCCState *s1)
706 unsigned char *ptr;
708 /* if no got, then create it */
709 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
710 s1->got->sh_entsize = 4;
711 add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
712 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
713 ptr = section_ptr_add(s1->got, 3 * sizeof(int));
714 /* keep space for _DYNAMIC pointer, if present */
715 put32(ptr, 0);
716 /* two dummy got entries */
717 put32(ptr + 4, 0);
718 put32(ptr + 8, 0);
721 /* put a got entry corresponding to a symbol in symtab_section. 'size'
722 and 'info' can be modifed if more precise info comes from the DLL */
723 static void put_got_entry(TCCState *s1,
724 int reloc_type, unsigned long size, int info,
725 int sym_index)
727 int index;
728 const char *name;
729 Elf32_Sym *sym;
730 unsigned long offset;
731 int *ptr;
733 if (!s1->got)
734 build_got(s1);
736 /* if a got entry already exists for that symbol, no need to add one */
737 if (sym_index < s1->nb_got_offsets &&
738 s1->got_offsets[sym_index] != 0)
739 return;
741 put_got_offset(s1, sym_index, s1->got->data_offset);
743 if (s1->dynsym) {
744 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
745 name = symtab_section->link->data + sym->st_name;
746 offset = sym->st_value;
747 #ifdef TCC_TARGET_I386
748 if (reloc_type == R_386_JMP_SLOT) {
749 Section *plt;
750 uint8_t *p;
751 int modrm;
753 /* if we build a DLL, we add a %ebx offset */
754 if (s1->output_type == TCC_OUTPUT_DLL)
755 modrm = 0xa3;
756 else
757 modrm = 0x25;
759 /* add a PLT entry */
760 plt = s1->plt;
761 if (plt->data_offset == 0) {
762 /* first plt entry */
763 p = section_ptr_add(plt, 16);
764 p[0] = 0xff; /* pushl got + 4 */
765 p[1] = modrm + 0x10;
766 put32(p + 2, 4);
767 p[6] = 0xff; /* jmp *(got + 8) */
768 p[7] = modrm;
769 put32(p + 8, 8);
772 p = section_ptr_add(plt, 16);
773 p[0] = 0xff; /* jmp *(got + x) */
774 p[1] = modrm;
775 put32(p + 2, s1->got->data_offset);
776 p[6] = 0x68; /* push $xxx */
777 put32(p + 7, (plt->data_offset - 32) >> 1);
778 p[11] = 0xe9; /* jmp plt_start */
779 put32(p + 12, -(plt->data_offset));
781 /* the symbol is modified so that it will be relocated to
782 the PLT */
783 if (s1->output_type == TCC_OUTPUT_EXE)
784 offset = plt->data_offset - 16;
786 #elif defined(TCC_TARGET_ARM)
787 if (reloc_type == R_ARM_JUMP_SLOT) {
788 Section *plt;
789 uint8_t *p;
791 /* if we build a DLL, we add a %ebx offset */
792 if (s1->output_type == TCC_OUTPUT_DLL)
793 error("DLLs unimplemented!");
795 /* add a PLT entry */
796 plt = s1->plt;
797 if (plt->data_offset == 0) {
798 /* first plt entry */
799 p = section_ptr_add(plt, 16);
800 put32(p , 0xe52de004);
801 put32(p + 4, 0xe59fe010);
802 put32(p + 8, 0xe08fe00e);
803 put32(p + 12, 0xe5bef008);
806 p = section_ptr_add(plt, 16);
807 put32(p , 0xe59fc004);
808 put32(p+4, 0xe08fc00c);
809 put32(p+8, 0xe59cf000);
810 put32(p+12, s1->got->data_offset);
812 /* the symbol is modified so that it will be relocated to
813 the PLT */
814 if (s1->output_type == TCC_OUTPUT_EXE)
815 offset = plt->data_offset - 16;
817 #elif defined(TCC_TARGET_C67)
818 error("C67 got not implemented");
819 #else
820 #error unsupported CPU
821 #endif
822 index = put_elf_sym(s1->dynsym, offset,
823 size, info, 0, sym->st_shndx, name);
824 /* put a got entry */
825 put_elf_reloc(s1->dynsym, s1->got,
826 s1->got->data_offset,
827 reloc_type, index);
829 ptr = section_ptr_add(s1->got, sizeof(int));
830 *ptr = 0;
833 /* build GOT and PLT entries */
834 static void build_got_entries(TCCState *s1)
836 Section *s, *symtab;
837 Elf32_Rel *rel, *rel_end;
838 Elf32_Sym *sym;
839 int i, type, reloc_type, sym_index;
841 for(i = 1; i < s1->nb_sections; i++) {
842 s = s1->sections[i];
843 if (s->sh_type != SHT_REL)
844 continue;
845 /* no need to handle got relocations */
846 if (s->link != symtab_section)
847 continue;
848 symtab = s->link;
849 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
850 for(rel = (Elf32_Rel *)s->data;
851 rel < rel_end;
852 rel++) {
853 type = ELF32_R_TYPE(rel->r_info);
854 switch(type) {
855 #if defined(TCC_TARGET_I386)
856 case R_386_GOT32:
857 case R_386_GOTOFF:
858 case R_386_GOTPC:
859 case R_386_PLT32:
860 if (!s1->got)
861 build_got(s1);
862 if (type == R_386_GOT32 || type == R_386_PLT32) {
863 sym_index = ELF32_R_SYM(rel->r_info);
864 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
865 /* look at the symbol got offset. If none, then add one */
866 if (type == R_386_GOT32)
867 reloc_type = R_386_GLOB_DAT;
868 else
869 reloc_type = R_386_JMP_SLOT;
870 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
871 sym_index);
873 break;
874 #elif defined(TCC_TARGET_ARM)
875 case R_ARM_GOT_BREL:
876 case R_ARM_GOTOFF32:
877 case R_ARM_BASE_PREL:
878 case R_ARM_PLT32:
879 if (!s1->got)
880 build_got(s1);
881 if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) {
882 sym_index = ELF32_R_SYM(rel->r_info);
883 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
884 /* look at the symbol got offset. If none, then add one */
885 if (type == R_ARM_GOT_BREL)
886 reloc_type = R_ARM_GLOB_DAT;
887 else
888 reloc_type = R_ARM_JUMP_SLOT;
889 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
890 sym_index);
892 break;
893 #elif defined(TCC_TARGET_C67)
894 case R_C60_GOT32:
895 case R_C60_GOTOFF:
896 case R_C60_GOTPC:
897 case R_C60_PLT32:
898 if (!s1->got)
899 build_got(s1);
900 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
901 sym_index = ELF32_R_SYM(rel->r_info);
902 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
903 /* look at the symbol got offset. If none, then add one */
904 if (type == R_C60_GOT32)
905 reloc_type = R_C60_GLOB_DAT;
906 else
907 reloc_type = R_C60_JMP_SLOT;
908 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
909 sym_index);
911 break;
912 #else
913 #error unsupported CPU
914 #endif
915 default:
916 break;
922 static Section *new_symtab(TCCState *s1,
923 const char *symtab_name, int sh_type, int sh_flags,
924 const char *strtab_name,
925 const char *hash_name, int hash_sh_flags)
927 Section *symtab, *strtab, *hash;
928 int *ptr, nb_buckets;
930 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
931 symtab->sh_entsize = sizeof(Elf32_Sym);
932 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
933 put_elf_str(strtab, "");
934 symtab->link = strtab;
935 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
937 nb_buckets = 1;
939 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
940 hash->sh_entsize = sizeof(int);
941 symtab->hash = hash;
942 hash->link = symtab;
944 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
945 ptr[0] = nb_buckets;
946 ptr[1] = 1;
947 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
948 return symtab;
951 /* put dynamic tag */
952 static void put_dt(Section *dynamic, int dt, unsigned long val)
954 Elf32_Dyn *dyn;
955 dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
956 dyn->d_tag = dt;
957 dyn->d_un.d_val = val;
960 static void add_init_array_defines(TCCState *s1, const char *section_name)
962 Section *s;
963 long end_offset;
964 char sym_start[1024];
965 char sym_end[1024];
967 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
968 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
970 s = find_section(s1, section_name);
971 if (!s) {
972 end_offset = 0;
973 s = data_section;
974 } else {
975 end_offset = s->data_offset;
978 add_elf_sym(symtab_section,
979 0, 0,
980 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
981 s->sh_num, sym_start);
982 add_elf_sym(symtab_section,
983 end_offset, 0,
984 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
985 s->sh_num, sym_end);
988 /* add tcc runtime libraries */
989 static void tcc_add_runtime(TCCState *s1)
991 char buf[1024];
993 #ifdef CONFIG_TCC_BCHECK
994 if (do_bounds_check) {
995 unsigned long *ptr;
996 Section *init_section;
997 unsigned char *pinit;
998 int sym_index;
1000 /* XXX: add an object file to do that */
1001 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
1002 *ptr = 0;
1003 add_elf_sym(symtab_section, 0, 0,
1004 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1005 bounds_section->sh_num, "__bounds_start");
1006 /* add bound check code */
1007 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
1008 tcc_add_file(s1, buf);
1009 #ifdef TCC_TARGET_I386
1010 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1011 /* add 'call __bound_init()' in .init section */
1012 init_section = find_section(s1, ".init");
1013 pinit = section_ptr_add(init_section, 5);
1014 pinit[0] = 0xe8;
1015 put32(pinit + 1, -4);
1016 sym_index = find_elf_sym(symtab_section, "__bound_init");
1017 put_elf_reloc(symtab_section, init_section,
1018 init_section->data_offset - 4, R_386_PC32, sym_index);
1020 #endif
1022 #endif
1023 /* add libc */
1024 if (!s1->nostdlib) {
1025 tcc_add_library(s1, "c");
1027 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
1028 tcc_add_file(s1, buf);
1030 /* add crt end if not memory output */
1031 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
1032 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1036 /* add various standard linker symbols (must be done after the
1037 sections are filled (for example after allocating common
1038 symbols)) */
1039 static void tcc_add_linker_symbols(TCCState *s1)
1041 char buf[1024];
1042 int i;
1043 Section *s;
1045 add_elf_sym(symtab_section,
1046 text_section->data_offset, 0,
1047 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1048 text_section->sh_num, "_etext");
1049 add_elf_sym(symtab_section,
1050 data_section->data_offset, 0,
1051 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1052 data_section->sh_num, "_edata");
1053 add_elf_sym(symtab_section,
1054 bss_section->data_offset, 0,
1055 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1056 bss_section->sh_num, "_end");
1057 /* horrible new standard ldscript defines */
1058 add_init_array_defines(s1, ".preinit_array");
1059 add_init_array_defines(s1, ".init_array");
1060 add_init_array_defines(s1, ".fini_array");
1062 /* add start and stop symbols for sections whose name can be
1063 expressed in C */
1064 for(i = 1; i < s1->nb_sections; i++) {
1065 s = s1->sections[i];
1066 if (s->sh_type == SHT_PROGBITS &&
1067 (s->sh_flags & SHF_ALLOC)) {
1068 const char *p;
1069 int ch;
1071 /* check if section name can be expressed in C */
1072 p = s->name;
1073 for(;;) {
1074 ch = *p;
1075 if (!ch)
1076 break;
1077 if (!isid(ch) && !isnum(ch))
1078 goto next_sec;
1079 p++;
1081 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1082 add_elf_sym(symtab_section,
1083 0, 0,
1084 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1085 s->sh_num, buf);
1086 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1087 add_elf_sym(symtab_section,
1088 s->data_offset, 0,
1089 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1090 s->sh_num, buf);
1092 next_sec: ;
1096 /* name of ELF interpreter */
1097 #ifdef __FreeBSD__
1098 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1099 #else
1100 #ifdef TCC_ARM_EABI
1101 static char elf_interp[] = "/lib/ld-linux.so.3";
1102 #else
1103 static char elf_interp[] = "/lib/ld-linux.so.2";
1104 #endif
1105 #endif
1107 static void tcc_output_binary(TCCState *s1, FILE *f,
1108 const int *section_order)
1110 Section *s;
1111 int i, offset, size;
1113 offset = 0;
1114 for(i=1;i<s1->nb_sections;i++) {
1115 s = s1->sections[section_order[i]];
1116 if (s->sh_type != SHT_NOBITS &&
1117 (s->sh_flags & SHF_ALLOC)) {
1118 while (offset < s->sh_offset) {
1119 fputc(0, f);
1120 offset++;
1122 size = s->sh_size;
1123 fwrite(s->data, 1, size, f);
1124 offset += size;
1129 /* output an ELF file */
1130 /* XXX: suppress unneeded sections */
1131 int tcc_output_file(TCCState *s1, const char *filename)
1133 Elf32_Ehdr ehdr;
1134 FILE *f;
1135 int fd, mode, ret;
1136 int *section_order;
1137 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1138 unsigned long addr;
1139 Section *strsec, *s;
1140 Elf32_Shdr shdr, *sh;
1141 Elf32_Phdr *phdr, *ph;
1142 Section *interp, *dynamic, *dynstr;
1143 unsigned long saved_dynamic_data_offset;
1144 Elf32_Sym *sym;
1145 int type, file_type;
1146 unsigned long rel_addr, rel_size;
1148 file_type = s1->output_type;
1149 s1->nb_errors = 0;
1151 if (file_type != TCC_OUTPUT_OBJ) {
1152 tcc_add_runtime(s1);
1155 phdr = NULL;
1156 section_order = NULL;
1157 interp = NULL;
1158 dynamic = NULL;
1159 dynstr = NULL; /* avoid warning */
1160 saved_dynamic_data_offset = 0; /* avoid warning */
1162 if (file_type != TCC_OUTPUT_OBJ) {
1163 relocate_common_syms();
1165 tcc_add_linker_symbols(s1);
1167 if (!s1->static_link) {
1168 const char *name;
1169 int sym_index, index;
1170 Elf32_Sym *esym, *sym_end;
1172 if (file_type == TCC_OUTPUT_EXE) {
1173 char *ptr;
1174 /* add interpreter section only if executable */
1175 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1176 interp->sh_addralign = 1;
1177 ptr = section_ptr_add(interp, sizeof(elf_interp));
1178 strcpy(ptr, elf_interp);
1181 /* add dynamic symbol table */
1182 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1183 ".dynstr",
1184 ".hash", SHF_ALLOC);
1185 dynstr = s1->dynsym->link;
1187 /* add dynamic section */
1188 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1189 SHF_ALLOC | SHF_WRITE);
1190 dynamic->link = dynstr;
1191 dynamic->sh_entsize = sizeof(Elf32_Dyn);
1193 /* add PLT */
1194 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1195 SHF_ALLOC | SHF_EXECINSTR);
1196 s1->plt->sh_entsize = 4;
1198 build_got(s1);
1200 /* scan for undefined symbols and see if they are in the
1201 dynamic symbols. If a symbol STT_FUNC is found, then we
1202 add it in the PLT. If a symbol STT_OBJECT is found, we
1203 add it in the .bss section with a suitable relocation */
1204 sym_end = (Elf32_Sym *)(symtab_section->data +
1205 symtab_section->data_offset);
1206 if (file_type == TCC_OUTPUT_EXE) {
1207 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1208 sym < sym_end;
1209 sym++) {
1210 if (sym->st_shndx == SHN_UNDEF) {
1211 name = symtab_section->link->data + sym->st_name;
1212 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1213 if (sym_index) {
1214 esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
1215 type = ELF32_ST_TYPE(esym->st_info);
1216 if (type == STT_FUNC) {
1217 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1218 esym->st_info,
1219 sym - (Elf32_Sym *)symtab_section->data);
1220 } else if (type == STT_OBJECT) {
1221 unsigned long offset;
1222 offset = bss_section->data_offset;
1223 /* XXX: which alignment ? */
1224 offset = (offset + 16 - 1) & -16;
1225 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1226 esym->st_info, 0,
1227 bss_section->sh_num, name);
1228 put_elf_reloc(s1->dynsym, bss_section,
1229 offset, R_COPY, index);
1230 offset += esym->st_size;
1231 bss_section->data_offset = offset;
1233 } else {
1234 /* STB_WEAK undefined symbols are accepted */
1235 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1236 it */
1237 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
1238 !strcmp(name, "_fp_hw")) {
1239 } else {
1240 error_noabort("undefined symbol '%s'", name);
1243 } else if (s1->rdynamic &&
1244 ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1245 /* if -rdynamic option, then export all non
1246 local symbols */
1247 name = symtab_section->link->data + sym->st_name;
1248 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1249 sym->st_info, 0,
1250 sym->st_shndx, name);
1254 if (s1->nb_errors)
1255 goto fail;
1257 /* now look at unresolved dynamic symbols and export
1258 corresponding symbol */
1259 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
1260 s1->dynsymtab_section->data_offset);
1261 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
1262 esym < sym_end;
1263 esym++) {
1264 if (esym->st_shndx == SHN_UNDEF) {
1265 name = s1->dynsymtab_section->link->data + esym->st_name;
1266 sym_index = find_elf_sym(symtab_section, name);
1267 if (sym_index) {
1268 /* XXX: avoid adding a symbol if already
1269 present because of -rdynamic ? */
1270 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1271 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1272 sym->st_info, 0,
1273 sym->st_shndx, name);
1274 } else {
1275 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
1276 /* weak symbols can stay undefined */
1277 } else {
1278 warning("undefined dynamic symbol '%s'", name);
1283 } else {
1284 int nb_syms;
1285 /* shared library case : we simply export all the global symbols */
1286 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
1287 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1288 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1289 sym < sym_end;
1290 sym++) {
1291 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1292 name = symtab_section->link->data + sym->st_name;
1293 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1294 sym->st_info, 0,
1295 sym->st_shndx, name);
1296 s1->symtab_to_dynsym[sym -
1297 (Elf32_Sym *)symtab_section->data] =
1298 index;
1303 build_got_entries(s1);
1305 /* add a list of needed dlls */
1306 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1307 DLLReference *dllref = s1->loaded_dlls[i];
1308 if (dllref->level == 0)
1309 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1311 /* XXX: currently, since we do not handle PIC code, we
1312 must relocate the readonly segments */
1313 if (file_type == TCC_OUTPUT_DLL)
1314 put_dt(dynamic, DT_TEXTREL, 0);
1316 /* add necessary space for other entries */
1317 saved_dynamic_data_offset = dynamic->data_offset;
1318 dynamic->data_offset += 8 * 9;
1319 } else {
1320 /* still need to build got entries in case of static link */
1321 build_got_entries(s1);
1325 memset(&ehdr, 0, sizeof(ehdr));
1327 /* we add a section for symbols */
1328 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1329 put_elf_str(strsec, "");
1331 /* compute number of sections */
1332 shnum = s1->nb_sections;
1334 /* this array is used to reorder sections in the output file */
1335 section_order = tcc_malloc(sizeof(int) * shnum);
1336 section_order[0] = 0;
1337 sh_order_index = 1;
1339 /* compute number of program headers */
1340 switch(file_type) {
1341 default:
1342 case TCC_OUTPUT_OBJ:
1343 phnum = 0;
1344 break;
1345 case TCC_OUTPUT_EXE:
1346 if (!s1->static_link)
1347 phnum = 4;
1348 else
1349 phnum = 2;
1350 break;
1351 case TCC_OUTPUT_DLL:
1352 phnum = 3;
1353 break;
1356 /* allocate strings for section names and decide if an unallocated
1357 section should be output */
1358 /* NOTE: the strsec section comes last, so its size is also
1359 correct ! */
1360 for(i = 1; i < s1->nb_sections; i++) {
1361 s = s1->sections[i];
1362 s->sh_name = put_elf_str(strsec, s->name);
1363 /* when generating a DLL, we include relocations but we may
1364 patch them */
1365 if (file_type == TCC_OUTPUT_DLL &&
1366 s->sh_type == SHT_REL &&
1367 !(s->sh_flags & SHF_ALLOC)) {
1368 prepare_dynamic_rel(s1, s);
1369 } else if (do_debug ||
1370 file_type == TCC_OUTPUT_OBJ ||
1371 (s->sh_flags & SHF_ALLOC) ||
1372 i == (s1->nb_sections - 1)) {
1373 /* we output all sections if debug or object file */
1374 s->sh_size = s->data_offset;
1378 /* allocate program segment headers */
1379 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1381 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1382 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1383 } else {
1384 file_offset = 0;
1386 if (phnum > 0) {
1387 /* compute section to program header mapping */
1388 if (s1->has_text_addr) {
1389 int a_offset, p_offset;
1390 addr = s1->text_addr;
1391 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1392 ELF_PAGE_SIZE */
1393 a_offset = addr & (ELF_PAGE_SIZE - 1);
1394 p_offset = file_offset & (ELF_PAGE_SIZE - 1);
1395 if (a_offset < p_offset)
1396 a_offset += ELF_PAGE_SIZE;
1397 file_offset += (a_offset - p_offset);
1398 } else {
1399 if (file_type == TCC_OUTPUT_DLL)
1400 addr = 0;
1401 else
1402 addr = ELF_START_ADDR;
1403 /* compute address after headers */
1404 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1407 /* dynamic relocation table information, for .dynamic section */
1408 rel_size = 0;
1409 rel_addr = 0;
1411 /* leave one program header for the program interpreter */
1412 ph = &phdr[0];
1413 if (interp)
1414 ph++;
1416 for(j = 0; j < 2; j++) {
1417 ph->p_type = PT_LOAD;
1418 if (j == 0)
1419 ph->p_flags = PF_R | PF_X;
1420 else
1421 ph->p_flags = PF_R | PF_W;
1422 ph->p_align = ELF_PAGE_SIZE;
1424 /* we do the following ordering: interp, symbol tables,
1425 relocations, progbits, nobits */
1426 /* XXX: do faster and simpler sorting */
1427 for(k = 0; k < 5; k++) {
1428 for(i = 1; i < s1->nb_sections; i++) {
1429 s = s1->sections[i];
1430 /* compute if section should be included */
1431 if (j == 0) {
1432 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1433 SHF_ALLOC)
1434 continue;
1435 } else {
1436 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1437 (SHF_ALLOC | SHF_WRITE))
1438 continue;
1440 if (s == interp) {
1441 if (k != 0)
1442 continue;
1443 } else if (s->sh_type == SHT_DYNSYM ||
1444 s->sh_type == SHT_STRTAB ||
1445 s->sh_type == SHT_HASH) {
1446 if (k != 1)
1447 continue;
1448 } else if (s->sh_type == SHT_REL) {
1449 if (k != 2)
1450 continue;
1451 } else if (s->sh_type == SHT_NOBITS) {
1452 if (k != 4)
1453 continue;
1454 } else {
1455 if (k != 3)
1456 continue;
1458 section_order[sh_order_index++] = i;
1460 /* section matches: we align it and add its size */
1461 tmp = addr;
1462 addr = (addr + s->sh_addralign - 1) &
1463 ~(s->sh_addralign - 1);
1464 file_offset += addr - tmp;
1465 s->sh_offset = file_offset;
1466 s->sh_addr = addr;
1468 /* update program header infos */
1469 if (ph->p_offset == 0) {
1470 ph->p_offset = file_offset;
1471 ph->p_vaddr = addr;
1472 ph->p_paddr = ph->p_vaddr;
1474 /* update dynamic relocation infos */
1475 if (s->sh_type == SHT_REL) {
1476 if (rel_size == 0)
1477 rel_addr = addr;
1478 rel_size += s->sh_size;
1480 addr += s->sh_size;
1481 if (s->sh_type != SHT_NOBITS)
1482 file_offset += s->sh_size;
1485 ph->p_filesz = file_offset - ph->p_offset;
1486 ph->p_memsz = addr - ph->p_vaddr;
1487 ph++;
1488 if (j == 0) {
1489 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1490 /* if in the middle of a page, we duplicate the page in
1491 memory so that one copy is RX and the other is RW */
1492 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1493 addr += ELF_PAGE_SIZE;
1494 } else {
1495 addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
1496 file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
1497 ~(ELF_PAGE_SIZE - 1);
1502 /* if interpreter, then add corresponing program header */
1503 if (interp) {
1504 ph = &phdr[0];
1506 ph->p_type = PT_INTERP;
1507 ph->p_offset = interp->sh_offset;
1508 ph->p_vaddr = interp->sh_addr;
1509 ph->p_paddr = ph->p_vaddr;
1510 ph->p_filesz = interp->sh_size;
1511 ph->p_memsz = interp->sh_size;
1512 ph->p_flags = PF_R;
1513 ph->p_align = interp->sh_addralign;
1516 /* if dynamic section, then add corresponing program header */
1517 if (dynamic) {
1518 Elf32_Sym *sym_end;
1520 ph = &phdr[phnum - 1];
1522 ph->p_type = PT_DYNAMIC;
1523 ph->p_offset = dynamic->sh_offset;
1524 ph->p_vaddr = dynamic->sh_addr;
1525 ph->p_paddr = ph->p_vaddr;
1526 ph->p_filesz = dynamic->sh_size;
1527 ph->p_memsz = dynamic->sh_size;
1528 ph->p_flags = PF_R | PF_W;
1529 ph->p_align = dynamic->sh_addralign;
1531 /* put GOT dynamic section address */
1532 put32(s1->got->data, dynamic->sh_addr);
1534 /* relocate the PLT */
1535 if (file_type == TCC_OUTPUT_EXE) {
1536 uint8_t *p, *p_end;
1538 p = s1->plt->data;
1539 p_end = p + s1->plt->data_offset;
1540 if (p < p_end) {
1541 #if defined(TCC_TARGET_I386)
1542 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1543 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1544 p += 16;
1545 while (p < p_end) {
1546 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1547 p += 16;
1549 #elif defined(TCC_TARGET_ARM)
1550 int x;
1551 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1552 p +=16;
1553 while (p < p_end) {
1554 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1555 p += 16;
1557 #elif defined(TCC_TARGET_C67)
1558 /* XXX: TODO */
1559 #else
1560 #error unsupported CPU
1561 #endif
1565 /* relocate symbols in .dynsym */
1566 sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
1567 for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
1568 sym < sym_end;
1569 sym++) {
1570 if (sym->st_shndx == SHN_UNDEF) {
1571 /* relocate to the PLT if the symbol corresponds
1572 to a PLT entry */
1573 if (sym->st_value)
1574 sym->st_value += s1->plt->sh_addr;
1575 } else if (sym->st_shndx < SHN_LORESERVE) {
1576 /* do symbol relocation */
1577 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1581 /* put dynamic section entries */
1582 dynamic->data_offset = saved_dynamic_data_offset;
1583 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1584 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1585 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1586 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1587 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
1588 put_dt(dynamic, DT_REL, rel_addr);
1589 put_dt(dynamic, DT_RELSZ, rel_size);
1590 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
1591 put_dt(dynamic, DT_NULL, 0);
1594 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1595 ehdr.e_phnum = phnum;
1596 ehdr.e_phoff = sizeof(Elf32_Ehdr);
1599 /* all other sections come after */
1600 for(i = 1; i < s1->nb_sections; i++) {
1601 s = s1->sections[i];
1602 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1603 continue;
1604 section_order[sh_order_index++] = i;
1606 file_offset = (file_offset + s->sh_addralign - 1) &
1607 ~(s->sh_addralign - 1);
1608 s->sh_offset = file_offset;
1609 if (s->sh_type != SHT_NOBITS)
1610 file_offset += s->sh_size;
1613 /* if building executable or DLL, then relocate each section
1614 except the GOT which is already relocated */
1615 if (file_type != TCC_OUTPUT_OBJ) {
1616 relocate_syms(s1, 0);
1618 if (s1->nb_errors != 0) {
1619 fail:
1620 ret = -1;
1621 goto the_end;
1624 /* relocate sections */
1625 /* XXX: ignore sections with allocated relocations ? */
1626 for(i = 1; i < s1->nb_sections; i++) {
1627 s = s1->sections[i];
1628 if (s->reloc && s != s1->got)
1629 relocate_section(s1, s);
1632 /* relocate relocation entries if the relocation tables are
1633 allocated in the executable */
1634 for(i = 1; i < s1->nb_sections; i++) {
1635 s = s1->sections[i];
1636 if ((s->sh_flags & SHF_ALLOC) &&
1637 s->sh_type == SHT_REL) {
1638 relocate_rel(s1, s);
1642 /* get entry point address */
1643 if (file_type == TCC_OUTPUT_EXE)
1644 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
1645 else
1646 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1649 /* write elf file */
1650 if (file_type == TCC_OUTPUT_OBJ)
1651 mode = 0666;
1652 else
1653 mode = 0777;
1654 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1655 if (fd < 0) {
1656 error_noabort("could not write '%s'", filename);
1657 goto fail;
1659 f = fdopen(fd, "wb");
1661 #ifdef TCC_TARGET_COFF
1662 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1663 tcc_output_coff(s1, f);
1664 } else
1665 #endif
1666 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1667 sort_syms(s1, symtab_section);
1669 /* align to 4 */
1670 file_offset = (file_offset + 3) & -4;
1672 /* fill header */
1673 ehdr.e_ident[0] = ELFMAG0;
1674 ehdr.e_ident[1] = ELFMAG1;
1675 ehdr.e_ident[2] = ELFMAG2;
1676 ehdr.e_ident[3] = ELFMAG3;
1677 ehdr.e_ident[4] = ELFCLASS32;
1678 ehdr.e_ident[5] = ELFDATA2LSB;
1679 ehdr.e_ident[6] = EV_CURRENT;
1680 #ifdef __FreeBSD__
1681 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1682 #endif
1683 #ifdef TCC_TARGET_ARM
1684 #ifdef TCC_ARM_EABI
1685 ehdr.e_ident[EI_OSABI] = 0;
1686 ehdr.e_flags = 4 << 24;
1687 #else
1688 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1689 #endif
1690 #endif
1691 switch(file_type) {
1692 default:
1693 case TCC_OUTPUT_EXE:
1694 ehdr.e_type = ET_EXEC;
1695 break;
1696 case TCC_OUTPUT_DLL:
1697 ehdr.e_type = ET_DYN;
1698 break;
1699 case TCC_OUTPUT_OBJ:
1700 ehdr.e_type = ET_REL;
1701 break;
1703 ehdr.e_machine = EM_TCC_TARGET;
1704 ehdr.e_version = EV_CURRENT;
1705 ehdr.e_shoff = file_offset;
1706 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1707 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1708 ehdr.e_shnum = shnum;
1709 ehdr.e_shstrndx = shnum - 1;
1711 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1712 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1713 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1715 for(i=1;i<s1->nb_sections;i++) {
1716 s = s1->sections[section_order[i]];
1717 if (s->sh_type != SHT_NOBITS) {
1718 while (offset < s->sh_offset) {
1719 fputc(0, f);
1720 offset++;
1722 size = s->sh_size;
1723 fwrite(s->data, 1, size, f);
1724 offset += size;
1728 /* output section headers */
1729 while (offset < ehdr.e_shoff) {
1730 fputc(0, f);
1731 offset++;
1734 for(i=0;i<s1->nb_sections;i++) {
1735 sh = &shdr;
1736 memset(sh, 0, sizeof(Elf32_Shdr));
1737 s = s1->sections[i];
1738 if (s) {
1739 sh->sh_name = s->sh_name;
1740 sh->sh_type = s->sh_type;
1741 sh->sh_flags = s->sh_flags;
1742 sh->sh_entsize = s->sh_entsize;
1743 sh->sh_info = s->sh_info;
1744 if (s->link)
1745 sh->sh_link = s->link->sh_num;
1746 sh->sh_addralign = s->sh_addralign;
1747 sh->sh_addr = s->sh_addr;
1748 sh->sh_offset = s->sh_offset;
1749 sh->sh_size = s->sh_size;
1751 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1753 } else {
1754 tcc_output_binary(s1, f, section_order);
1756 fclose(f);
1758 ret = 0;
1759 the_end:
1760 tcc_free(s1->symtab_to_dynsym);
1761 tcc_free(section_order);
1762 tcc_free(phdr);
1763 tcc_free(s1->got_offsets);
1764 return ret;
1767 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1769 void *data;
1771 data = tcc_malloc(size);
1772 lseek(fd, file_offset, SEEK_SET);
1773 read(fd, data, size);
1774 return data;
1777 typedef struct SectionMergeInfo {
1778 Section *s; /* corresponding existing section */
1779 unsigned long offset; /* offset of the new section in the existing section */
1780 uint8_t new_section; /* true if section 's' was added */
1781 uint8_t link_once; /* true if link once section */
1782 } SectionMergeInfo;
1784 /* load an object file and merge it with current files */
1785 /* XXX: handle correctly stab (debug) info */
1786 static int tcc_load_object_file(TCCState *s1,
1787 int fd, unsigned long file_offset)
1789 Elf32_Ehdr ehdr;
1790 Elf32_Shdr *shdr, *sh;
1791 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1792 unsigned char *strsec, *strtab;
1793 int *old_to_new_syms;
1794 char *sh_name, *name;
1795 SectionMergeInfo *sm_table, *sm;
1796 Elf32_Sym *sym, *symtab;
1797 Elf32_Rel *rel, *rel_end;
1798 Section *s;
1800 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1801 goto fail1;
1802 if (ehdr.e_ident[0] != ELFMAG0 ||
1803 ehdr.e_ident[1] != ELFMAG1 ||
1804 ehdr.e_ident[2] != ELFMAG2 ||
1805 ehdr.e_ident[3] != ELFMAG3)
1806 goto fail1;
1807 /* test if object file */
1808 if (ehdr.e_type != ET_REL)
1809 goto fail1;
1810 /* test CPU specific stuff */
1811 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1812 ehdr.e_machine != EM_TCC_TARGET) {
1813 fail1:
1814 error_noabort("invalid object file");
1815 return -1;
1817 /* read sections */
1818 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1819 sizeof(Elf32_Shdr) * ehdr.e_shnum);
1820 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1822 /* load section names */
1823 sh = &shdr[ehdr.e_shstrndx];
1824 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1826 /* load symtab and strtab */
1827 old_to_new_syms = NULL;
1828 symtab = NULL;
1829 strtab = NULL;
1830 nb_syms = 0;
1831 for(i = 1; i < ehdr.e_shnum; i++) {
1832 sh = &shdr[i];
1833 if (sh->sh_type == SHT_SYMTAB) {
1834 if (symtab) {
1835 error_noabort("object must contain only one symtab");
1836 fail:
1837 ret = -1;
1838 goto the_end;
1840 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1841 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1842 sm_table[i].s = symtab_section;
1844 /* now load strtab */
1845 sh = &shdr[sh->sh_link];
1846 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1850 /* now examine each section and try to merge its content with the
1851 ones in memory */
1852 for(i = 1; i < ehdr.e_shnum; i++) {
1853 /* no need to examine section name strtab */
1854 if (i == ehdr.e_shstrndx)
1855 continue;
1856 sh = &shdr[i];
1857 sh_name = strsec + sh->sh_name;
1858 /* ignore sections types we do not handle */
1859 if (sh->sh_type != SHT_PROGBITS &&
1860 sh->sh_type != SHT_REL &&
1861 #ifdef TCC_ARM_EABI
1862 sh->sh_type != SHT_ARM_EXIDX &&
1863 #endif
1864 sh->sh_type != SHT_NOBITS)
1865 continue;
1866 if (sh->sh_addralign < 1)
1867 sh->sh_addralign = 1;
1868 /* find corresponding section, if any */
1869 for(j = 1; j < s1->nb_sections;j++) {
1870 s = s1->sections[j];
1871 if (!strcmp(s->name, sh_name)) {
1872 if (!strncmp(sh_name, ".gnu.linkonce",
1873 sizeof(".gnu.linkonce") - 1)) {
1874 /* if a 'linkonce' section is already present, we
1875 do not add it again. It is a little tricky as
1876 symbols can still be defined in
1877 it. */
1878 sm_table[i].link_once = 1;
1879 goto next;
1880 } else {
1881 goto found;
1885 /* not found: create new section */
1886 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1887 /* take as much info as possible from the section. sh_link and
1888 sh_info will be updated later */
1889 s->sh_addralign = sh->sh_addralign;
1890 s->sh_entsize = sh->sh_entsize;
1891 sm_table[i].new_section = 1;
1892 found:
1893 if (sh->sh_type != s->sh_type) {
1894 error_noabort("invalid section type");
1895 goto fail;
1898 /* align start of section */
1899 offset = s->data_offset;
1900 size = sh->sh_addralign - 1;
1901 offset = (offset + size) & ~size;
1902 if (sh->sh_addralign > s->sh_addralign)
1903 s->sh_addralign = sh->sh_addralign;
1904 s->data_offset = offset;
1905 sm_table[i].offset = offset;
1906 sm_table[i].s = s;
1907 /* concatenate sections */
1908 size = sh->sh_size;
1909 if (sh->sh_type != SHT_NOBITS) {
1910 unsigned char *ptr;
1911 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1912 ptr = section_ptr_add(s, size);
1913 read(fd, ptr, size);
1914 } else {
1915 s->data_offset += size;
1917 next: ;
1920 /* second short pass to update sh_link and sh_info fields of new
1921 sections */
1922 for(i = 1; i < ehdr.e_shnum; i++) {
1923 s = sm_table[i].s;
1924 if (!s || !sm_table[i].new_section)
1925 continue;
1926 sh = &shdr[i];
1927 if (sh->sh_link > 0)
1928 s->link = sm_table[sh->sh_link].s;
1929 if (sh->sh_type == SHT_REL) {
1930 s->sh_info = sm_table[sh->sh_info].s->sh_num;
1931 /* update backward link */
1932 s1->sections[s->sh_info]->reloc = s;
1935 sm = sm_table;
1937 /* resolve symbols */
1938 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
1940 sym = symtab + 1;
1941 for(i = 1; i < nb_syms; i++, sym++) {
1942 if (sym->st_shndx != SHN_UNDEF &&
1943 sym->st_shndx < SHN_LORESERVE) {
1944 sm = &sm_table[sym->st_shndx];
1945 if (sm->link_once) {
1946 /* if a symbol is in a link once section, we use the
1947 already defined symbol. It is very important to get
1948 correct relocations */
1949 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1950 name = strtab + sym->st_name;
1951 sym_index = find_elf_sym(symtab_section, name);
1952 if (sym_index)
1953 old_to_new_syms[i] = sym_index;
1955 continue;
1957 /* if no corresponding section added, no need to add symbol */
1958 if (!sm->s)
1959 continue;
1960 /* convert section number */
1961 sym->st_shndx = sm->s->sh_num;
1962 /* offset value */
1963 sym->st_value += sm->offset;
1965 /* add symbol */
1966 name = strtab + sym->st_name;
1967 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
1968 sym->st_info, sym->st_other,
1969 sym->st_shndx, name);
1970 old_to_new_syms[i] = sym_index;
1973 /* third pass to patch relocation entries */
1974 for(i = 1; i < ehdr.e_shnum; i++) {
1975 s = sm_table[i].s;
1976 if (!s)
1977 continue;
1978 sh = &shdr[i];
1979 offset = sm_table[i].offset;
1980 switch(s->sh_type) {
1981 case SHT_REL:
1982 /* take relocation offset information */
1983 offseti = sm_table[sh->sh_info].offset;
1984 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
1985 for(rel = (Elf32_Rel *)(s->data + offset);
1986 rel < rel_end;
1987 rel++) {
1988 int type;
1989 unsigned sym_index;
1990 /* convert symbol index */
1991 type = ELF32_R_TYPE(rel->r_info);
1992 sym_index = ELF32_R_SYM(rel->r_info);
1993 /* NOTE: only one symtab assumed */
1994 if (sym_index >= nb_syms)
1995 goto invalid_reloc;
1996 sym_index = old_to_new_syms[sym_index];
1997 /* ignore link_once in rel section. */
1998 if (!sym_index && !sm->link_once) {
1999 invalid_reloc:
2000 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2001 i, strsec + sh->sh_name, rel->r_offset);
2002 goto fail;
2004 rel->r_info = ELF32_R_INFO(sym_index, type);
2005 /* offset the relocation offset */
2006 rel->r_offset += offseti;
2008 break;
2009 default:
2010 break;
2014 ret = 0;
2015 the_end:
2016 tcc_free(symtab);
2017 tcc_free(strtab);
2018 tcc_free(old_to_new_syms);
2019 tcc_free(sm_table);
2020 tcc_free(strsec);
2021 tcc_free(shdr);
2022 return ret;
2025 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2027 typedef struct ArchiveHeader {
2028 char ar_name[16]; /* name of this member */
2029 char ar_date[12]; /* file mtime */
2030 char ar_uid[6]; /* owner uid; printed as decimal */
2031 char ar_gid[6]; /* owner gid; printed as decimal */
2032 char ar_mode[8]; /* file mode, printed as octal */
2033 char ar_size[10]; /* file size, printed as decimal */
2034 char ar_fmag[2]; /* should contain ARFMAG */
2035 } ArchiveHeader;
2037 static int get_be32(const uint8_t *b)
2039 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2042 /* load only the objects which resolve undefined symbols */
2043 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
2045 int i, bound, nsyms, sym_index, off, ret;
2046 uint8_t *data;
2047 const char *ar_names, *p;
2048 const uint8_t *ar_index;
2049 Elf32_Sym *sym;
2051 data = tcc_malloc(size);
2052 if (read(fd, data, size) != size)
2053 goto fail;
2054 nsyms = get_be32(data);
2055 ar_index = data + 4;
2056 ar_names = ar_index + nsyms * 4;
2058 do {
2059 bound = 0;
2060 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2061 sym_index = find_elf_sym(symtab_section, p);
2062 if(sym_index) {
2063 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
2064 if(sym->st_shndx == SHN_UNDEF) {
2065 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2066 #if 0
2067 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2068 #endif
2069 ++bound;
2070 lseek(fd, off, SEEK_SET);
2071 if(tcc_load_object_file(s1, fd, off) < 0) {
2072 fail:
2073 ret = -1;
2074 goto the_end;
2079 } while(bound);
2080 ret = 0;
2081 the_end:
2082 tcc_free(data);
2083 return ret;
2086 /* load a '.a' file */
2087 static int tcc_load_archive(TCCState *s1, int fd)
2089 ArchiveHeader hdr;
2090 char ar_size[11];
2091 char ar_name[17];
2092 char magic[8];
2093 int size, len, i;
2094 unsigned long file_offset;
2096 /* skip magic which was already checked */
2097 read(fd, magic, sizeof(magic));
2099 for(;;) {
2100 len = read(fd, &hdr, sizeof(hdr));
2101 if (len == 0)
2102 break;
2103 if (len != sizeof(hdr)) {
2104 error_noabort("invalid archive");
2105 return -1;
2107 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2108 ar_size[sizeof(hdr.ar_size)] = '\0';
2109 size = strtol(ar_size, NULL, 0);
2110 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2111 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2112 if (ar_name[i] != ' ')
2113 break;
2115 ar_name[i + 1] = '\0';
2116 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2117 file_offset = lseek(fd, 0, SEEK_CUR);
2118 /* align to even */
2119 size = (size + 1) & ~1;
2120 if (!strcmp(ar_name, "/")) {
2121 /* coff symbol table : we handle it */
2122 if(s1->alacarte_link)
2123 return tcc_load_alacarte(s1, fd, size);
2124 } else if (!strcmp(ar_name, "//") ||
2125 !strcmp(ar_name, "__.SYMDEF") ||
2126 !strcmp(ar_name, "__.SYMDEF/") ||
2127 !strcmp(ar_name, "ARFILENAMES/")) {
2128 /* skip symbol table or archive names */
2129 } else {
2130 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2131 return -1;
2133 lseek(fd, file_offset + size, SEEK_SET);
2135 return 0;
2138 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2139 is referenced by the user (so it should be added as DT_NEEDED in
2140 the generated ELF file) */
2141 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2143 Elf32_Ehdr ehdr;
2144 Elf32_Shdr *shdr, *sh, *sh1;
2145 int i, j, nb_syms, nb_dts, sym_bind, ret;
2146 Elf32_Sym *sym, *dynsym;
2147 Elf32_Dyn *dt, *dynamic;
2148 unsigned char *dynstr;
2149 const char *name, *soname;
2150 DLLReference *dllref;
2152 read(fd, &ehdr, sizeof(ehdr));
2154 /* test CPU specific stuff */
2155 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2156 ehdr.e_machine != EM_TCC_TARGET) {
2157 error_noabort("bad architecture");
2158 return -1;
2161 /* read sections */
2162 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
2164 /* load dynamic section and dynamic symbols */
2165 nb_syms = 0;
2166 nb_dts = 0;
2167 dynamic = NULL;
2168 dynsym = NULL; /* avoid warning */
2169 dynstr = NULL; /* avoid warning */
2170 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2171 switch(sh->sh_type) {
2172 case SHT_DYNAMIC:
2173 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
2174 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2175 break;
2176 case SHT_DYNSYM:
2177 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
2178 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2179 sh1 = &shdr[sh->sh_link];
2180 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2181 break;
2182 default:
2183 break;
2187 /* compute the real library name */
2188 soname = tcc_basename(filename);
2190 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2191 if (dt->d_tag == DT_SONAME) {
2192 soname = dynstr + dt->d_un.d_val;
2196 /* if the dll is already loaded, do not load it */
2197 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2198 dllref = s1->loaded_dlls[i];
2199 if (!strcmp(soname, dllref->name)) {
2200 /* but update level if needed */
2201 if (level < dllref->level)
2202 dllref->level = level;
2203 ret = 0;
2204 goto the_end;
2208 // printf("loading dll '%s'\n", soname);
2210 /* add the dll and its level */
2211 dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
2212 dllref->level = level;
2213 strcpy(dllref->name, soname);
2214 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2216 /* add dynamic symbols in dynsym_section */
2217 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2218 sym_bind = ELF32_ST_BIND(sym->st_info);
2219 if (sym_bind == STB_LOCAL)
2220 continue;
2221 name = dynstr + sym->st_name;
2222 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2223 sym->st_info, sym->st_other, sym->st_shndx, name);
2226 /* load all referenced DLLs */
2227 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2228 switch(dt->d_tag) {
2229 case DT_NEEDED:
2230 name = dynstr + dt->d_un.d_val;
2231 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2232 dllref = s1->loaded_dlls[j];
2233 if (!strcmp(name, dllref->name))
2234 goto already_loaded;
2236 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2237 error_noabort("referenced dll '%s' not found", name);
2238 ret = -1;
2239 goto the_end;
2241 already_loaded:
2242 break;
2245 ret = 0;
2246 the_end:
2247 tcc_free(dynstr);
2248 tcc_free(dynsym);
2249 tcc_free(dynamic);
2250 tcc_free(shdr);
2251 return ret;
2254 #define LD_TOK_NAME 256
2255 #define LD_TOK_EOF (-1)
2257 /* return next ld script token */
2258 static int ld_next(TCCState *s1, char *name, int name_size)
2260 int c;
2261 char *q;
2263 redo:
2264 switch(ch) {
2265 case ' ':
2266 case '\t':
2267 case '\f':
2268 case '\v':
2269 case '\r':
2270 case '\n':
2271 inp();
2272 goto redo;
2273 case '/':
2274 minp();
2275 if (ch == '*') {
2276 file->buf_ptr = parse_comment(file->buf_ptr);
2277 ch = file->buf_ptr[0];
2278 goto redo;
2279 } else {
2280 q = name;
2281 *q++ = '/';
2282 goto parse_name;
2284 break;
2285 case 'a' ... 'z':
2286 case 'A' ... 'Z':
2287 case '_':
2288 case '\\':
2289 case '.':
2290 case '$':
2291 case '~':
2292 q = name;
2293 parse_name:
2294 for(;;) {
2295 if (!((ch >= 'a' && ch <= 'z') ||
2296 (ch >= 'A' && ch <= 'Z') ||
2297 (ch >= '0' && ch <= '9') ||
2298 strchr("/.-_+=$:\\,~", ch)))
2299 break;
2300 if ((q - name) < name_size - 1) {
2301 *q++ = ch;
2303 minp();
2305 *q = '\0';
2306 c = LD_TOK_NAME;
2307 break;
2308 case CH_EOF:
2309 c = LD_TOK_EOF;
2310 break;
2311 default:
2312 c = ch;
2313 inp();
2314 break;
2316 #if 0
2317 printf("tok=%c %d\n", c, c);
2318 if (c == LD_TOK_NAME)
2319 printf(" name=%s\n", name);
2320 #endif
2321 return c;
2324 static int ld_add_file_list(TCCState *s1, int as_needed)
2326 char filename[1024];
2327 int t, ret;
2329 t = ld_next(s1, filename, sizeof(filename));
2330 if (t != '(')
2331 expect("(");
2332 t = ld_next(s1, filename, sizeof(filename));
2333 for(;;) {
2334 if (t == LD_TOK_EOF) {
2335 error_noabort("unexpected end of file");
2336 return -1;
2337 } else if (t == ')') {
2338 break;
2339 } else if (t != LD_TOK_NAME) {
2340 error_noabort("filename expected");
2341 return -1;
2343 if (!strcmp(filename, "AS_NEEDED")) {
2344 ret = ld_add_file_list(s1, 1);
2345 if (ret)
2346 return ret;
2347 } else {
2348 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2349 if (!as_needed)
2350 tcc_add_file(s1, filename);
2352 t = ld_next(s1, filename, sizeof(filename));
2353 if (t == ',') {
2354 t = ld_next(s1, filename, sizeof(filename));
2357 return 0;
2360 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2361 files */
2362 static int tcc_load_ldscript(TCCState *s1)
2364 char cmd[64];
2365 char filename[1024];
2366 int t, ret;
2368 ch = file->buf_ptr[0];
2369 ch = handle_eob();
2370 for(;;) {
2371 t = ld_next(s1, cmd, sizeof(cmd));
2372 if (t == LD_TOK_EOF)
2373 return 0;
2374 else if (t != LD_TOK_NAME)
2375 return -1;
2376 if (!strcmp(cmd, "INPUT") ||
2377 !strcmp(cmd, "GROUP")) {
2378 ret = ld_add_file_list(s1, 0);
2379 if (ret)
2380 return ret;
2381 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2382 !strcmp(cmd, "TARGET")) {
2383 /* ignore some commands */
2384 t = ld_next(s1, cmd, sizeof(cmd));
2385 if (t != '(')
2386 expect("(");
2387 for(;;) {
2388 t = ld_next(s1, filename, sizeof(filename));
2389 if (t == LD_TOK_EOF) {
2390 error_noabort("unexpected end of file");
2391 return -1;
2392 } else if (t == ')') {
2393 break;
2396 } else {
2397 return -1;
2400 return 0;