Optimize arithmetic with pointer to value on stack + constant
[tinycc/miki.git] / tccelf.c
blobaa2df9bb8ff976ce50cf53e627c45f60854f9ffb
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 if (esym->st_shndx == SHN_COMMON && sh_num < SHN_LORESERVE) {
223 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
224 No idea if this is the correct solution ... */
225 goto do_patch;
226 } else if (s == tcc_state->dynsymtab_section) {
227 /* we accept that two DLL define the same symbol */
228 } else {
229 #if 1
230 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
231 sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
232 #endif
233 error_noabort("'%s' defined twice", name);
235 } else {
236 do_patch:
237 esym->st_info = ELF32_ST_INFO(sym_bind, sym_type);
238 esym->st_shndx = sh_num;
239 esym->st_value = value;
240 esym->st_size = size;
241 esym->st_other = other;
243 } else {
244 do_def:
245 sym_index = put_elf_sym(s, value, size,
246 ELF32_ST_INFO(sym_bind, sym_type), other,
247 sh_num, name);
249 return sym_index;
252 /* put relocation */
253 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
254 int type, int symbol)
256 char buf[256];
257 Section *sr;
258 Elf32_Rel *rel;
260 sr = s->reloc;
261 if (!sr) {
262 /* if no relocation section, create it */
263 snprintf(buf, sizeof(buf), ".rel%s", s->name);
264 /* if the symtab is allocated, then we consider the relocation
265 are also */
266 sr = new_section(tcc_state, buf, SHT_REL, symtab->sh_flags);
267 sr->sh_entsize = sizeof(Elf32_Rel);
268 sr->link = symtab;
269 sr->sh_info = s->sh_num;
270 s->reloc = sr;
272 rel = section_ptr_add(sr, sizeof(Elf32_Rel));
273 rel->r_offset = offset;
274 rel->r_info = ELF32_R_INFO(symbol, type);
277 /* put stab debug information */
279 typedef struct {
280 unsigned long n_strx; /* index into string table of name */
281 unsigned char n_type; /* type of symbol */
282 unsigned char n_other; /* misc info (usually empty) */
283 unsigned short n_desc; /* description field */
284 unsigned long n_value; /* value of symbol */
285 } Stab_Sym;
287 static void put_stabs(const char *str, int type, int other, int desc,
288 unsigned long value)
290 Stab_Sym *sym;
292 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
293 if (str) {
294 sym->n_strx = put_elf_str(stabstr_section, str);
295 } else {
296 sym->n_strx = 0;
298 sym->n_type = type;
299 sym->n_other = other;
300 sym->n_desc = desc;
301 sym->n_value = value;
304 static void put_stabs_r(const char *str, int type, int other, int desc,
305 unsigned long value, Section *sec, int sym_index)
307 put_stabs(str, type, other, desc, value);
308 put_elf_reloc(symtab_section, stab_section,
309 stab_section->data_offset - sizeof(unsigned long),
310 R_DATA_32, sym_index);
313 static void put_stabn(int type, int other, int desc, int value)
315 put_stabs(NULL, type, other, desc, value);
318 static void put_stabd(int type, int other, int desc)
320 put_stabs(NULL, type, other, desc, 0);
323 /* In an ELF file symbol table, the local symbols must appear below
324 the global and weak ones. Since TCC cannot sort it while generating
325 the code, we must do it after. All the relocation tables are also
326 modified to take into account the symbol table sorting */
327 static void sort_syms(TCCState *s1, Section *s)
329 int *old_to_new_syms;
330 Elf32_Sym *new_syms;
331 int nb_syms, i;
332 Elf32_Sym *p, *q;
333 Elf32_Rel *rel, *rel_end;
334 Section *sr;
335 int type, sym_index;
337 nb_syms = s->data_offset / sizeof(Elf32_Sym);
338 new_syms = tcc_malloc(nb_syms * sizeof(Elf32_Sym));
339 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
341 /* first pass for local symbols */
342 p = (Elf32_Sym *)s->data;
343 q = new_syms;
344 for(i = 0; i < nb_syms; i++) {
345 if (ELF32_ST_BIND(p->st_info) == STB_LOCAL) {
346 old_to_new_syms[i] = q - new_syms;
347 *q++ = *p;
349 p++;
351 /* save the number of local symbols in section header */
352 s->sh_info = q - new_syms;
354 /* then second pass for non local symbols */
355 p = (Elf32_Sym *)s->data;
356 for(i = 0; i < nb_syms; i++) {
357 if (ELF32_ST_BIND(p->st_info) != STB_LOCAL) {
358 old_to_new_syms[i] = q - new_syms;
359 *q++ = *p;
361 p++;
364 /* we copy the new symbols to the old */
365 memcpy(s->data, new_syms, nb_syms * sizeof(Elf32_Sym));
366 tcc_free(new_syms);
368 /* now we modify all the relocations */
369 for(i = 1; i < s1->nb_sections; i++) {
370 sr = s1->sections[i];
371 if (sr->sh_type == SHT_REL && sr->link == s) {
372 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
373 for(rel = (Elf32_Rel *)sr->data;
374 rel < rel_end;
375 rel++) {
376 sym_index = ELF32_R_SYM(rel->r_info);
377 type = ELF32_R_TYPE(rel->r_info);
378 sym_index = old_to_new_syms[sym_index];
379 rel->r_info = ELF32_R_INFO(sym_index, type);
384 tcc_free(old_to_new_syms);
387 /* relocate common symbols in the .bss section */
388 static void relocate_common_syms(void)
390 Elf32_Sym *sym, *sym_end;
391 unsigned long offset, align;
393 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
394 for(sym = (Elf32_Sym *)symtab_section->data + 1;
395 sym < sym_end;
396 sym++) {
397 if (sym->st_shndx == SHN_COMMON) {
398 /* align symbol */
399 align = sym->st_value;
400 offset = bss_section->data_offset;
401 offset = (offset + align - 1) & -align;
402 sym->st_value = offset;
403 sym->st_shndx = bss_section->sh_num;
404 offset += sym->st_size;
405 bss_section->data_offset = offset;
410 /* relocate symbol table, resolve undefined symbols if do_resolve is
411 true and output error if undefined symbol. */
412 static void relocate_syms(TCCState *s1, int do_resolve)
414 Elf32_Sym *sym, *esym, *sym_end;
415 int sym_bind, sh_num, sym_index;
416 const char *name;
417 unsigned long addr;
419 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
420 for(sym = (Elf32_Sym *)symtab_section->data + 1;
421 sym < sym_end;
422 sym++) {
423 sh_num = sym->st_shndx;
424 if (sh_num == SHN_UNDEF) {
425 name = strtab_section->data + sym->st_name;
426 if (do_resolve) {
427 name = symtab_section->link->data + sym->st_name;
428 addr = (unsigned long)resolve_sym(s1, name, ELF32_ST_TYPE(sym->st_info));
429 if (addr) {
430 sym->st_value = addr;
431 goto found;
433 } else if (s1->dynsym) {
434 /* if dynamic symbol exist, then use it */
435 sym_index = find_elf_sym(s1->dynsym, name);
436 if (sym_index) {
437 esym = &((Elf32_Sym *)s1->dynsym->data)[sym_index];
438 sym->st_value = esym->st_value;
439 goto found;
442 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
443 it */
444 if (!strcmp(name, "_fp_hw"))
445 goto found;
446 /* only weak symbols are accepted to be undefined. Their
447 value is zero */
448 sym_bind = ELF32_ST_BIND(sym->st_info);
449 if (sym_bind == STB_WEAK) {
450 sym->st_value = 0;
451 } else {
452 error_noabort("undefined symbol '%s'", name);
454 } else if (sh_num < SHN_LORESERVE) {
455 /* add section base */
456 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
458 found: ;
462 /* relocate a given section (CPU dependent) */
463 static void relocate_section(TCCState *s1, Section *s)
465 Section *sr;
466 Elf32_Rel *rel, *rel_end, *qrel;
467 Elf32_Sym *sym;
468 int type, sym_index;
469 unsigned char *ptr;
470 unsigned long val, addr;
471 #if defined(TCC_TARGET_I386)
472 int esym_index;
473 #endif
475 sr = s->reloc;
476 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
477 qrel = (Elf32_Rel *)sr->data;
478 for(rel = qrel;
479 rel < rel_end;
480 rel++) {
481 ptr = s->data + rel->r_offset;
483 sym_index = ELF32_R_SYM(rel->r_info);
484 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
485 val = sym->st_value;
486 type = ELF32_R_TYPE(rel->r_info);
487 addr = s->sh_addr + rel->r_offset;
489 /* CPU specific */
490 switch(type) {
491 #if defined(TCC_TARGET_I386)
492 case R_386_32:
493 if (s1->output_type == TCC_OUTPUT_DLL) {
494 esym_index = s1->symtab_to_dynsym[sym_index];
495 qrel->r_offset = rel->r_offset;
496 if (esym_index) {
497 qrel->r_info = ELF32_R_INFO(esym_index, R_386_32);
498 qrel++;
499 break;
500 } else {
501 qrel->r_info = ELF32_R_INFO(0, R_386_RELATIVE);
502 qrel++;
505 *(int *)ptr += val;
506 break;
507 case R_386_PC32:
508 if (s1->output_type == TCC_OUTPUT_DLL) {
509 /* DLL relocation */
510 esym_index = s1->symtab_to_dynsym[sym_index];
511 if (esym_index) {
512 qrel->r_offset = rel->r_offset;
513 qrel->r_info = ELF32_R_INFO(esym_index, R_386_PC32);
514 qrel++;
515 break;
518 *(int *)ptr += val - addr;
519 break;
520 case R_386_PLT32:
521 *(int *)ptr += val - addr;
522 break;
523 case R_386_GLOB_DAT:
524 case R_386_JMP_SLOT:
525 *(int *)ptr = val;
526 break;
527 case R_386_GOTPC:
528 *(int *)ptr += s1->got->sh_addr - addr;
529 break;
530 case R_386_GOTOFF:
531 *(int *)ptr += val - s1->got->sh_addr;
532 break;
533 case R_386_GOT32:
534 /* we load the got offset */
535 *(int *)ptr += s1->got_offsets[sym_index];
536 break;
537 #elif defined(TCC_TARGET_ARM)
538 case R_ARM_PC24:
539 case R_ARM_CALL:
540 case R_ARM_JUMP24:
541 case R_ARM_PLT32:
543 int x;
544 x = (*(int *)ptr)&0xffffff;
545 (*(int *)ptr) &= 0xff000000;
546 if (x & 0x800000)
547 x -= 0x1000000;
548 x *= 4;
549 x += val - addr;
550 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
551 error("can't relocate value at %x",addr);
552 x >>= 2;
553 x &= 0xffffff;
554 (*(int *)ptr) |= x;
556 break;
557 case R_ARM_PREL31:
559 int x;
560 x = (*(int *)ptr) & 0x7fffffff;
561 (*(int *)ptr) &= 0x80000000;
562 x = (x * 2) / 2;
563 x += val - addr;
564 if((x^(x>>1))&0x40000000)
565 error("can't relocate value at %x",addr);
566 (*(int *)ptr) |= x & 0x7fffffff;
568 case R_ARM_ABS32:
569 *(int *)ptr += val;
570 break;
571 case R_ARM_BASE_PREL:
572 *(int *)ptr += s1->got->sh_addr - addr;
573 break;
574 case R_ARM_GOTOFF32:
575 *(int *)ptr += val - s1->got->sh_addr;
576 break;
577 case R_ARM_GOT_BREL:
578 /* we load the got offset */
579 *(int *)ptr += s1->got_offsets[sym_index];
580 break;
581 case R_ARM_COPY:
582 break;
583 default:
584 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
585 type,addr,(unsigned int )ptr,val);
586 break;
587 #elif defined(TCC_TARGET_C67)
588 case R_C60_32:
589 *(int *)ptr += val;
590 break;
591 case R_C60LO16:
593 uint32_t orig;
595 /* put the low 16 bits of the absolute address */
596 // add to what is already there
598 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
599 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
601 //patch both at once - assumes always in pairs Low - High
603 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
604 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
606 break;
607 case R_C60HI16:
608 break;
609 default:
610 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
611 type,addr,(unsigned int )ptr,val);
612 break;
613 #else
614 #error unsupported processor
615 #endif
618 /* if the relocation is allocated, we change its symbol table */
619 if (sr->sh_flags & SHF_ALLOC)
620 sr->link = s1->dynsym;
623 /* relocate relocation table in 'sr' */
624 static void relocate_rel(TCCState *s1, Section *sr)
626 Section *s;
627 Elf32_Rel *rel, *rel_end;
629 s = s1->sections[sr->sh_info];
630 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
631 for(rel = (Elf32_Rel *)sr->data;
632 rel < rel_end;
633 rel++) {
634 rel->r_offset += s->sh_addr;
638 /* count the number of dynamic relocations so that we can reserve
639 their space */
640 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
642 Elf32_Rel *rel, *rel_end;
643 int sym_index, esym_index, type, count;
645 count = 0;
646 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
647 for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) {
648 sym_index = ELF32_R_SYM(rel->r_info);
649 type = ELF32_R_TYPE(rel->r_info);
650 switch(type) {
651 case R_386_32:
652 count++;
653 break;
654 case R_386_PC32:
655 esym_index = s1->symtab_to_dynsym[sym_index];
656 if (esym_index)
657 count++;
658 break;
659 default:
660 break;
663 if (count) {
664 /* allocate the section */
665 sr->sh_flags |= SHF_ALLOC;
666 sr->sh_size = count * sizeof(Elf32_Rel);
668 return count;
671 static void put_got_offset(TCCState *s1, int index, unsigned long val)
673 int n;
674 unsigned long *tab;
676 if (index >= s1->nb_got_offsets) {
677 /* find immediately bigger power of 2 and reallocate array */
678 n = 1;
679 while (index >= n)
680 n *= 2;
681 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
682 if (!tab)
683 error("memory full");
684 s1->got_offsets = tab;
685 memset(s1->got_offsets + s1->nb_got_offsets, 0,
686 (n - s1->nb_got_offsets) * sizeof(unsigned long));
687 s1->nb_got_offsets = n;
689 s1->got_offsets[index] = val;
692 /* XXX: suppress that */
693 static void put32(unsigned char *p, uint32_t val)
695 p[0] = val;
696 p[1] = val >> 8;
697 p[2] = val >> 16;
698 p[3] = val >> 24;
701 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM)
702 static uint32_t get32(unsigned char *p)
704 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
706 #endif
708 static void build_got(TCCState *s1)
710 unsigned char *ptr;
712 /* if no got, then create it */
713 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
714 s1->got->sh_entsize = 4;
715 add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
716 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
717 ptr = section_ptr_add(s1->got, 3 * sizeof(int));
718 /* keep space for _DYNAMIC pointer, if present */
719 put32(ptr, 0);
720 /* two dummy got entries */
721 put32(ptr + 4, 0);
722 put32(ptr + 8, 0);
725 /* put a got entry corresponding to a symbol in symtab_section. 'size'
726 and 'info' can be modifed if more precise info comes from the DLL */
727 static void put_got_entry(TCCState *s1,
728 int reloc_type, unsigned long size, int info,
729 int sym_index)
731 int index;
732 const char *name;
733 Elf32_Sym *sym;
734 unsigned long offset;
735 int *ptr;
737 if (!s1->got)
738 build_got(s1);
740 /* if a got entry already exists for that symbol, no need to add one */
741 if (sym_index < s1->nb_got_offsets &&
742 s1->got_offsets[sym_index] != 0)
743 return;
745 put_got_offset(s1, sym_index, s1->got->data_offset);
747 if (s1->dynsym) {
748 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
749 name = symtab_section->link->data + sym->st_name;
750 offset = sym->st_value;
751 #ifdef TCC_TARGET_I386
752 if (reloc_type == R_386_JMP_SLOT) {
753 Section *plt;
754 uint8_t *p;
755 int modrm;
757 /* if we build a DLL, we add a %ebx offset */
758 if (s1->output_type == TCC_OUTPUT_DLL)
759 modrm = 0xa3;
760 else
761 modrm = 0x25;
763 /* add a PLT entry */
764 plt = s1->plt;
765 if (plt->data_offset == 0) {
766 /* first plt entry */
767 p = section_ptr_add(plt, 16);
768 p[0] = 0xff; /* pushl got + 4 */
769 p[1] = modrm + 0x10;
770 put32(p + 2, 4);
771 p[6] = 0xff; /* jmp *(got + 8) */
772 p[7] = modrm;
773 put32(p + 8, 8);
776 p = section_ptr_add(plt, 16);
777 p[0] = 0xff; /* jmp *(got + x) */
778 p[1] = modrm;
779 put32(p + 2, s1->got->data_offset);
780 p[6] = 0x68; /* push $xxx */
781 put32(p + 7, (plt->data_offset - 32) >> 1);
782 p[11] = 0xe9; /* jmp plt_start */
783 put32(p + 12, -(plt->data_offset));
785 /* the symbol is modified so that it will be relocated to
786 the PLT */
787 if (s1->output_type == TCC_OUTPUT_EXE)
788 offset = plt->data_offset - 16;
790 #elif defined(TCC_TARGET_ARM)
791 if (reloc_type == R_ARM_JUMP_SLOT) {
792 Section *plt;
793 uint8_t *p;
795 /* if we build a DLL, we add a %ebx offset */
796 if (s1->output_type == TCC_OUTPUT_DLL)
797 error("DLLs unimplemented!");
799 /* add a PLT entry */
800 plt = s1->plt;
801 if (plt->data_offset == 0) {
802 /* first plt entry */
803 p = section_ptr_add(plt, 16);
804 put32(p , 0xe52de004);
805 put32(p + 4, 0xe59fe010);
806 put32(p + 8, 0xe08fe00e);
807 put32(p + 12, 0xe5bef008);
810 p = section_ptr_add(plt, 16);
811 put32(p , 0xe59fc004);
812 put32(p+4, 0xe08fc00c);
813 put32(p+8, 0xe59cf000);
814 put32(p+12, s1->got->data_offset);
816 /* the symbol is modified so that it will be relocated to
817 the PLT */
818 if (s1->output_type == TCC_OUTPUT_EXE)
819 offset = plt->data_offset - 16;
821 #elif defined(TCC_TARGET_C67)
822 error("C67 got not implemented");
823 #else
824 #error unsupported CPU
825 #endif
826 index = put_elf_sym(s1->dynsym, offset,
827 size, info, 0, sym->st_shndx, name);
828 /* put a got entry */
829 put_elf_reloc(s1->dynsym, s1->got,
830 s1->got->data_offset,
831 reloc_type, index);
833 ptr = section_ptr_add(s1->got, sizeof(int));
834 *ptr = 0;
837 /* build GOT and PLT entries */
838 static void build_got_entries(TCCState *s1)
840 Section *s, *symtab;
841 Elf32_Rel *rel, *rel_end;
842 Elf32_Sym *sym;
843 int i, type, reloc_type, sym_index;
845 for(i = 1; i < s1->nb_sections; i++) {
846 s = s1->sections[i];
847 if (s->sh_type != SHT_REL)
848 continue;
849 /* no need to handle got relocations */
850 if (s->link != symtab_section)
851 continue;
852 symtab = s->link;
853 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
854 for(rel = (Elf32_Rel *)s->data;
855 rel < rel_end;
856 rel++) {
857 type = ELF32_R_TYPE(rel->r_info);
858 switch(type) {
859 #if defined(TCC_TARGET_I386)
860 case R_386_GOT32:
861 case R_386_GOTOFF:
862 case R_386_GOTPC:
863 case R_386_PLT32:
864 if (!s1->got)
865 build_got(s1);
866 if (type == R_386_GOT32 || type == R_386_PLT32) {
867 sym_index = ELF32_R_SYM(rel->r_info);
868 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
869 /* look at the symbol got offset. If none, then add one */
870 if (type == R_386_GOT32)
871 reloc_type = R_386_GLOB_DAT;
872 else
873 reloc_type = R_386_JMP_SLOT;
874 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
875 sym_index);
877 break;
878 #elif defined(TCC_TARGET_ARM)
879 case R_ARM_GOT_BREL:
880 case R_ARM_GOTOFF32:
881 case R_ARM_BASE_PREL:
882 case R_ARM_PLT32:
883 if (!s1->got)
884 build_got(s1);
885 if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) {
886 sym_index = ELF32_R_SYM(rel->r_info);
887 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
888 /* look at the symbol got offset. If none, then add one */
889 if (type == R_ARM_GOT_BREL)
890 reloc_type = R_ARM_GLOB_DAT;
891 else
892 reloc_type = R_ARM_JUMP_SLOT;
893 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
894 sym_index);
896 break;
897 #elif defined(TCC_TARGET_C67)
898 case R_C60_GOT32:
899 case R_C60_GOTOFF:
900 case R_C60_GOTPC:
901 case R_C60_PLT32:
902 if (!s1->got)
903 build_got(s1);
904 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
905 sym_index = ELF32_R_SYM(rel->r_info);
906 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
907 /* look at the symbol got offset. If none, then add one */
908 if (type == R_C60_GOT32)
909 reloc_type = R_C60_GLOB_DAT;
910 else
911 reloc_type = R_C60_JMP_SLOT;
912 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
913 sym_index);
915 break;
916 #else
917 #error unsupported CPU
918 #endif
919 default:
920 break;
926 static Section *new_symtab(TCCState *s1,
927 const char *symtab_name, int sh_type, int sh_flags,
928 const char *strtab_name,
929 const char *hash_name, int hash_sh_flags)
931 Section *symtab, *strtab, *hash;
932 int *ptr, nb_buckets;
934 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
935 symtab->sh_entsize = sizeof(Elf32_Sym);
936 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
937 put_elf_str(strtab, "");
938 symtab->link = strtab;
939 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
941 nb_buckets = 1;
943 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
944 hash->sh_entsize = sizeof(int);
945 symtab->hash = hash;
946 hash->link = symtab;
948 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
949 ptr[0] = nb_buckets;
950 ptr[1] = 1;
951 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
952 return symtab;
955 /* put dynamic tag */
956 static void put_dt(Section *dynamic, int dt, unsigned long val)
958 Elf32_Dyn *dyn;
959 dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
960 dyn->d_tag = dt;
961 dyn->d_un.d_val = val;
964 static void add_init_array_defines(TCCState *s1, const char *section_name)
966 Section *s;
967 long end_offset;
968 char sym_start[1024];
969 char sym_end[1024];
971 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
972 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
974 s = find_section(s1, section_name);
975 if (!s) {
976 end_offset = 0;
977 s = data_section;
978 } else {
979 end_offset = s->data_offset;
982 add_elf_sym(symtab_section,
983 0, 0,
984 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
985 s->sh_num, sym_start);
986 add_elf_sym(symtab_section,
987 end_offset, 0,
988 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
989 s->sh_num, sym_end);
992 /* add tcc runtime libraries */
993 static void tcc_add_runtime(TCCState *s1)
995 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
996 char buf[1024];
997 #endif
999 #ifdef CONFIG_TCC_BCHECK
1000 if (do_bounds_check) {
1001 unsigned long *ptr;
1002 Section *init_section;
1003 unsigned char *pinit;
1004 int sym_index;
1006 /* XXX: add an object file to do that */
1007 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
1008 *ptr = 0;
1009 add_elf_sym(symtab_section, 0, 0,
1010 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1011 bounds_section->sh_num, "__bounds_start");
1012 /* add bound check code */
1013 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
1014 tcc_add_file(s1, buf);
1015 #ifdef TCC_TARGET_I386
1016 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1017 /* add 'call __bound_init()' in .init section */
1018 init_section = find_section(s1, ".init");
1019 pinit = section_ptr_add(init_section, 5);
1020 pinit[0] = 0xe8;
1021 put32(pinit + 1, -4);
1022 sym_index = find_elf_sym(symtab_section, "__bound_init");
1023 put_elf_reloc(symtab_section, init_section,
1024 init_section->data_offset - 4, R_386_PC32, sym_index);
1026 #endif
1028 #endif
1029 /* add libc */
1030 if (!s1->nostdlib) {
1031 tcc_add_library(s1, "c");
1033 #ifdef CONFIG_USE_LIBGCC
1034 tcc_add_file(s1, CONFIG_SYSROOT "/lib/libgcc_s.so.1");
1035 #else
1036 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
1037 tcc_add_file(s1, buf);
1038 #endif
1040 /* add crt end if not memory output */
1041 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
1042 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1046 /* add various standard linker symbols (must be done after the
1047 sections are filled (for example after allocating common
1048 symbols)) */
1049 static void tcc_add_linker_symbols(TCCState *s1)
1051 char buf[1024];
1052 int i;
1053 Section *s;
1055 add_elf_sym(symtab_section,
1056 text_section->data_offset, 0,
1057 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1058 text_section->sh_num, "_etext");
1059 add_elf_sym(symtab_section,
1060 data_section->data_offset, 0,
1061 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1062 data_section->sh_num, "_edata");
1063 add_elf_sym(symtab_section,
1064 bss_section->data_offset, 0,
1065 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1066 bss_section->sh_num, "_end");
1067 /* horrible new standard ldscript defines */
1068 add_init_array_defines(s1, ".preinit_array");
1069 add_init_array_defines(s1, ".init_array");
1070 add_init_array_defines(s1, ".fini_array");
1072 /* add start and stop symbols for sections whose name can be
1073 expressed in C */
1074 for(i = 1; i < s1->nb_sections; i++) {
1075 s = s1->sections[i];
1076 if (s->sh_type == SHT_PROGBITS &&
1077 (s->sh_flags & SHF_ALLOC)) {
1078 const char *p;
1079 int ch;
1081 /* check if section name can be expressed in C */
1082 p = s->name;
1083 for(;;) {
1084 ch = *p;
1085 if (!ch)
1086 break;
1087 if (!isid(ch) && !isnum(ch))
1088 goto next_sec;
1089 p++;
1091 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1092 add_elf_sym(symtab_section,
1093 0, 0,
1094 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1095 s->sh_num, buf);
1096 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1097 add_elf_sym(symtab_section,
1098 s->data_offset, 0,
1099 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1100 s->sh_num, buf);
1102 next_sec: ;
1106 /* name of ELF interpreter */
1107 #ifdef __FreeBSD__
1108 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1109 #else
1110 #ifdef TCC_ARM_EABI
1111 static char elf_interp[] = "/lib/ld-linux.so.3";
1112 #else
1113 static char elf_interp[] = "/lib/ld-linux.so.2";
1114 #endif
1115 #endif
1117 static void tcc_output_binary(TCCState *s1, FILE *f,
1118 const int *section_order)
1120 Section *s;
1121 int i, offset, size;
1123 offset = 0;
1124 for(i=1;i<s1->nb_sections;i++) {
1125 s = s1->sections[section_order[i]];
1126 if (s->sh_type != SHT_NOBITS &&
1127 (s->sh_flags & SHF_ALLOC)) {
1128 while (offset < s->sh_offset) {
1129 fputc(0, f);
1130 offset++;
1132 size = s->sh_size;
1133 fwrite(s->data, 1, size, f);
1134 offset += size;
1139 /* output an ELF file */
1140 /* XXX: suppress unneeded sections */
1141 int elf_output_file(TCCState *s1, const char *filename)
1143 Elf32_Ehdr ehdr;
1144 FILE *f;
1145 int fd, mode, ret;
1146 int *section_order;
1147 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1148 unsigned long addr;
1149 Section *strsec, *s;
1150 Elf32_Shdr shdr, *sh;
1151 Elf32_Phdr *phdr, *ph;
1152 Section *interp, *dynamic, *dynstr;
1153 unsigned long saved_dynamic_data_offset;
1154 Elf32_Sym *sym;
1155 int type, file_type;
1156 unsigned long rel_addr, rel_size;
1158 file_type = s1->output_type;
1159 s1->nb_errors = 0;
1161 if (file_type != TCC_OUTPUT_OBJ) {
1162 tcc_add_runtime(s1);
1165 phdr = NULL;
1166 section_order = NULL;
1167 interp = NULL;
1168 dynamic = NULL;
1169 dynstr = NULL; /* avoid warning */
1170 saved_dynamic_data_offset = 0; /* avoid warning */
1172 if (file_type != TCC_OUTPUT_OBJ) {
1173 relocate_common_syms();
1175 tcc_add_linker_symbols(s1);
1177 if (!s1->static_link) {
1178 const char *name;
1179 int sym_index, index;
1180 Elf32_Sym *esym, *sym_end;
1182 if (file_type == TCC_OUTPUT_EXE) {
1183 char *ptr;
1184 /* add interpreter section only if executable */
1185 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1186 interp->sh_addralign = 1;
1187 ptr = section_ptr_add(interp, sizeof(elf_interp));
1188 strcpy(ptr, elf_interp);
1191 /* add dynamic symbol table */
1192 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1193 ".dynstr",
1194 ".hash", SHF_ALLOC);
1195 dynstr = s1->dynsym->link;
1197 /* add dynamic section */
1198 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1199 SHF_ALLOC | SHF_WRITE);
1200 dynamic->link = dynstr;
1201 dynamic->sh_entsize = sizeof(Elf32_Dyn);
1203 /* add PLT */
1204 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1205 SHF_ALLOC | SHF_EXECINSTR);
1206 s1->plt->sh_entsize = 4;
1208 build_got(s1);
1210 /* scan for undefined symbols and see if they are in the
1211 dynamic symbols. If a symbol STT_FUNC is found, then we
1212 add it in the PLT. If a symbol STT_OBJECT is found, we
1213 add it in the .bss section with a suitable relocation */
1214 sym_end = (Elf32_Sym *)(symtab_section->data +
1215 symtab_section->data_offset);
1216 if (file_type == TCC_OUTPUT_EXE) {
1217 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1218 sym < sym_end;
1219 sym++) {
1220 if (sym->st_shndx == SHN_UNDEF) {
1221 name = symtab_section->link->data + sym->st_name;
1222 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1223 if (sym_index) {
1224 esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
1225 type = ELF32_ST_TYPE(esym->st_info);
1226 if (type == STT_FUNC) {
1227 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1228 esym->st_info,
1229 sym - (Elf32_Sym *)symtab_section->data);
1230 } else if (type == STT_OBJECT) {
1231 unsigned long offset;
1232 offset = bss_section->data_offset;
1233 /* XXX: which alignment ? */
1234 offset = (offset + 16 - 1) & -16;
1235 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1236 esym->st_info, 0,
1237 bss_section->sh_num, name);
1238 put_elf_reloc(s1->dynsym, bss_section,
1239 offset, R_COPY, index);
1240 offset += esym->st_size;
1241 bss_section->data_offset = offset;
1243 } else {
1244 /* STB_WEAK undefined symbols are accepted */
1245 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1246 it */
1247 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
1248 !strcmp(name, "_fp_hw")) {
1249 } else {
1250 error_noabort("undefined symbol '%s'", name);
1253 } else if (s1->rdynamic &&
1254 ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1255 /* if -rdynamic option, then export all non
1256 local symbols */
1257 name = symtab_section->link->data + sym->st_name;
1258 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1259 sym->st_info, 0,
1260 sym->st_shndx, name);
1264 if (s1->nb_errors)
1265 goto fail;
1267 /* now look at unresolved dynamic symbols and export
1268 corresponding symbol */
1269 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
1270 s1->dynsymtab_section->data_offset);
1271 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
1272 esym < sym_end;
1273 esym++) {
1274 if (esym->st_shndx == SHN_UNDEF) {
1275 name = s1->dynsymtab_section->link->data + esym->st_name;
1276 sym_index = find_elf_sym(symtab_section, name);
1277 if (sym_index) {
1278 /* XXX: avoid adding a symbol if already
1279 present because of -rdynamic ? */
1280 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1281 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1282 sym->st_info, 0,
1283 sym->st_shndx, name);
1284 } else {
1285 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
1286 /* weak symbols can stay undefined */
1287 } else {
1288 warning("undefined dynamic symbol '%s'", name);
1293 } else {
1294 int nb_syms;
1295 /* shared library case : we simply export all the global symbols */
1296 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
1297 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1298 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1299 sym < sym_end;
1300 sym++) {
1301 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1302 name = symtab_section->link->data + sym->st_name;
1303 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1304 sym->st_info, 0,
1305 sym->st_shndx, name);
1306 s1->symtab_to_dynsym[sym -
1307 (Elf32_Sym *)symtab_section->data] =
1308 index;
1313 build_got_entries(s1);
1315 /* add a list of needed dlls */
1316 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1317 DLLReference *dllref = s1->loaded_dlls[i];
1318 if (dllref->level == 0)
1319 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1321 /* XXX: currently, since we do not handle PIC code, we
1322 must relocate the readonly segments */
1323 if (file_type == TCC_OUTPUT_DLL) {
1324 if (s1->soname)
1325 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
1326 put_dt(dynamic, DT_TEXTREL, 0);
1329 /* add necessary space for other entries */
1330 saved_dynamic_data_offset = dynamic->data_offset;
1331 dynamic->data_offset += 8 * 9;
1332 } else {
1333 /* still need to build got entries in case of static link */
1334 build_got_entries(s1);
1338 memset(&ehdr, 0, sizeof(ehdr));
1340 /* we add a section for symbols */
1341 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1342 put_elf_str(strsec, "");
1344 /* compute number of sections */
1345 shnum = s1->nb_sections;
1347 /* this array is used to reorder sections in the output file */
1348 section_order = tcc_malloc(sizeof(int) * shnum);
1349 section_order[0] = 0;
1350 sh_order_index = 1;
1352 /* compute number of program headers */
1353 switch(file_type) {
1354 default:
1355 case TCC_OUTPUT_OBJ:
1356 phnum = 0;
1357 break;
1358 case TCC_OUTPUT_EXE:
1359 if (!s1->static_link)
1360 phnum = 4;
1361 else
1362 phnum = 2;
1363 break;
1364 case TCC_OUTPUT_DLL:
1365 phnum = 3;
1366 break;
1369 /* allocate strings for section names and decide if an unallocated
1370 section should be output */
1371 /* NOTE: the strsec section comes last, so its size is also
1372 correct ! */
1373 for(i = 1; i < s1->nb_sections; i++) {
1374 s = s1->sections[i];
1375 s->sh_name = put_elf_str(strsec, s->name);
1376 #if 0 //gr
1377 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1378 s->sh_flags,
1379 s->sh_type,
1380 s->sh_info,
1381 s->name,
1382 s->reloc ? s->reloc->name : "n"
1384 #endif
1385 /* when generating a DLL, we include relocations but we may
1386 patch them */
1387 if (file_type == TCC_OUTPUT_DLL &&
1388 s->sh_type == SHT_REL &&
1389 !(s->sh_flags & SHF_ALLOC)) {
1390 /* //gr: avoid bogus relocs for empty (debug) sections */
1391 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1392 prepare_dynamic_rel(s1, s);
1393 else if (do_debug)
1394 s->sh_size = s->data_offset;
1395 } else if (do_debug ||
1396 file_type == TCC_OUTPUT_OBJ ||
1397 (s->sh_flags & SHF_ALLOC) ||
1398 i == (s1->nb_sections - 1)) {
1399 /* we output all sections if debug or object file */
1400 s->sh_size = s->data_offset;
1404 /* allocate program segment headers */
1405 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1407 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1408 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1409 } else {
1410 file_offset = 0;
1412 if (phnum > 0) {
1413 /* compute section to program header mapping */
1414 if (s1->has_text_addr) {
1415 int a_offset, p_offset;
1416 addr = s1->text_addr;
1417 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1418 ELF_PAGE_SIZE */
1419 a_offset = addr & (ELF_PAGE_SIZE - 1);
1420 p_offset = file_offset & (ELF_PAGE_SIZE - 1);
1421 if (a_offset < p_offset)
1422 a_offset += ELF_PAGE_SIZE;
1423 file_offset += (a_offset - p_offset);
1424 } else {
1425 if (file_type == TCC_OUTPUT_DLL)
1426 addr = 0;
1427 else
1428 addr = ELF_START_ADDR;
1429 /* compute address after headers */
1430 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1433 /* dynamic relocation table information, for .dynamic section */
1434 rel_size = 0;
1435 rel_addr = 0;
1437 /* leave one program header for the program interpreter */
1438 ph = &phdr[0];
1439 if (interp)
1440 ph++;
1442 for(j = 0; j < 2; j++) {
1443 ph->p_type = PT_LOAD;
1444 if (j == 0)
1445 ph->p_flags = PF_R | PF_X;
1446 else
1447 ph->p_flags = PF_R | PF_W;
1448 ph->p_align = ELF_PAGE_SIZE;
1450 /* we do the following ordering: interp, symbol tables,
1451 relocations, progbits, nobits */
1452 /* XXX: do faster and simpler sorting */
1453 for(k = 0; k < 5; k++) {
1454 for(i = 1; i < s1->nb_sections; i++) {
1455 s = s1->sections[i];
1456 /* compute if section should be included */
1457 if (j == 0) {
1458 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1459 SHF_ALLOC)
1460 continue;
1461 } else {
1462 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1463 (SHF_ALLOC | SHF_WRITE))
1464 continue;
1466 if (s == interp) {
1467 if (k != 0)
1468 continue;
1469 } else if (s->sh_type == SHT_DYNSYM ||
1470 s->sh_type == SHT_STRTAB ||
1471 s->sh_type == SHT_HASH) {
1472 if (k != 1)
1473 continue;
1474 } else if (s->sh_type == SHT_REL) {
1475 if (k != 2)
1476 continue;
1477 } else if (s->sh_type == SHT_NOBITS) {
1478 if (k != 4)
1479 continue;
1480 } else {
1481 if (k != 3)
1482 continue;
1484 section_order[sh_order_index++] = i;
1486 /* section matches: we align it and add its size */
1487 tmp = addr;
1488 addr = (addr + s->sh_addralign - 1) &
1489 ~(s->sh_addralign - 1);
1490 file_offset += addr - tmp;
1491 s->sh_offset = file_offset;
1492 s->sh_addr = addr;
1494 /* update program header infos */
1495 if (ph->p_offset == 0) {
1496 ph->p_offset = file_offset;
1497 ph->p_vaddr = addr;
1498 ph->p_paddr = ph->p_vaddr;
1500 /* update dynamic relocation infos */
1501 if (s->sh_type == SHT_REL) {
1502 if (rel_size == 0)
1503 rel_addr = addr;
1504 rel_size += s->sh_size;
1506 addr += s->sh_size;
1507 if (s->sh_type != SHT_NOBITS)
1508 file_offset += s->sh_size;
1511 ph->p_filesz = file_offset - ph->p_offset;
1512 ph->p_memsz = addr - ph->p_vaddr;
1513 ph++;
1514 if (j == 0) {
1515 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1516 /* if in the middle of a page, we duplicate the page in
1517 memory so that one copy is RX and the other is RW */
1518 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1519 addr += ELF_PAGE_SIZE;
1520 } else {
1521 addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
1522 file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
1523 ~(ELF_PAGE_SIZE - 1);
1528 /* if interpreter, then add corresponing program header */
1529 if (interp) {
1530 ph = &phdr[0];
1532 ph->p_type = PT_INTERP;
1533 ph->p_offset = interp->sh_offset;
1534 ph->p_vaddr = interp->sh_addr;
1535 ph->p_paddr = ph->p_vaddr;
1536 ph->p_filesz = interp->sh_size;
1537 ph->p_memsz = interp->sh_size;
1538 ph->p_flags = PF_R;
1539 ph->p_align = interp->sh_addralign;
1542 /* if dynamic section, then add corresponing program header */
1543 if (dynamic) {
1544 Elf32_Sym *sym_end;
1546 ph = &phdr[phnum - 1];
1548 ph->p_type = PT_DYNAMIC;
1549 ph->p_offset = dynamic->sh_offset;
1550 ph->p_vaddr = dynamic->sh_addr;
1551 ph->p_paddr = ph->p_vaddr;
1552 ph->p_filesz = dynamic->sh_size;
1553 ph->p_memsz = dynamic->sh_size;
1554 ph->p_flags = PF_R | PF_W;
1555 ph->p_align = dynamic->sh_addralign;
1557 /* put GOT dynamic section address */
1558 put32(s1->got->data, dynamic->sh_addr);
1560 /* relocate the PLT */
1561 if (file_type == TCC_OUTPUT_EXE) {
1562 uint8_t *p, *p_end;
1564 p = s1->plt->data;
1565 p_end = p + s1->plt->data_offset;
1566 if (p < p_end) {
1567 #if defined(TCC_TARGET_I386)
1568 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1569 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1570 p += 16;
1571 while (p < p_end) {
1572 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1573 p += 16;
1575 #elif defined(TCC_TARGET_ARM)
1576 int x;
1577 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1578 p +=16;
1579 while (p < p_end) {
1580 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1581 p += 16;
1583 #elif defined(TCC_TARGET_C67)
1584 /* XXX: TODO */
1585 #else
1586 #error unsupported CPU
1587 #endif
1591 /* relocate symbols in .dynsym */
1592 sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
1593 for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
1594 sym < sym_end;
1595 sym++) {
1596 if (sym->st_shndx == SHN_UNDEF) {
1597 /* relocate to the PLT if the symbol corresponds
1598 to a PLT entry */
1599 if (sym->st_value)
1600 sym->st_value += s1->plt->sh_addr;
1601 } else if (sym->st_shndx < SHN_LORESERVE) {
1602 /* do symbol relocation */
1603 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1607 /* put dynamic section entries */
1608 dynamic->data_offset = saved_dynamic_data_offset;
1609 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1610 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1611 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1612 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1613 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
1614 put_dt(dynamic, DT_REL, rel_addr);
1615 put_dt(dynamic, DT_RELSZ, rel_size);
1616 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
1617 if (do_debug)
1618 put_dt(dynamic, DT_DEBUG, 0);
1619 put_dt(dynamic, DT_NULL, 0);
1622 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1623 ehdr.e_phnum = phnum;
1624 ehdr.e_phoff = sizeof(Elf32_Ehdr);
1627 /* all other sections come after */
1628 for(i = 1; i < s1->nb_sections; i++) {
1629 s = s1->sections[i];
1630 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1631 continue;
1632 section_order[sh_order_index++] = i;
1634 file_offset = (file_offset + s->sh_addralign - 1) &
1635 ~(s->sh_addralign - 1);
1636 s->sh_offset = file_offset;
1637 if (s->sh_type != SHT_NOBITS)
1638 file_offset += s->sh_size;
1641 /* if building executable or DLL, then relocate each section
1642 except the GOT which is already relocated */
1643 if (file_type != TCC_OUTPUT_OBJ) {
1644 relocate_syms(s1, 0);
1646 if (s1->nb_errors != 0) {
1647 fail:
1648 ret = -1;
1649 goto the_end;
1652 /* relocate sections */
1653 /* XXX: ignore sections with allocated relocations ? */
1654 for(i = 1; i < s1->nb_sections; i++) {
1655 s = s1->sections[i];
1656 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
1657 relocate_section(s1, s);
1660 /* relocate relocation entries if the relocation tables are
1661 allocated in the executable */
1662 for(i = 1; i < s1->nb_sections; i++) {
1663 s = s1->sections[i];
1664 if ((s->sh_flags & SHF_ALLOC) &&
1665 s->sh_type == SHT_REL) {
1666 relocate_rel(s1, s);
1670 /* get entry point address */
1671 if (file_type == TCC_OUTPUT_EXE)
1672 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
1673 else
1674 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1677 /* write elf file */
1678 if (file_type == TCC_OUTPUT_OBJ)
1679 mode = 0666;
1680 else
1681 mode = 0777;
1682 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1683 if (fd < 0) {
1684 error_noabort("could not write '%s'", filename);
1685 goto fail;
1687 f = fdopen(fd, "wb");
1688 if (verbose)
1689 printf("<- %s\n", filename);
1691 #ifdef TCC_TARGET_COFF
1692 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1693 tcc_output_coff(s1, f);
1694 } else
1695 #endif
1696 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1697 sort_syms(s1, symtab_section);
1699 /* align to 4 */
1700 file_offset = (file_offset + 3) & -4;
1702 /* fill header */
1703 ehdr.e_ident[0] = ELFMAG0;
1704 ehdr.e_ident[1] = ELFMAG1;
1705 ehdr.e_ident[2] = ELFMAG2;
1706 ehdr.e_ident[3] = ELFMAG3;
1707 ehdr.e_ident[4] = ELFCLASS32;
1708 ehdr.e_ident[5] = ELFDATA2LSB;
1709 ehdr.e_ident[6] = EV_CURRENT;
1710 #ifdef __FreeBSD__
1711 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1712 #endif
1713 #ifdef TCC_TARGET_ARM
1714 #ifdef TCC_ARM_EABI
1715 ehdr.e_ident[EI_OSABI] = 0;
1716 ehdr.e_flags = 4 << 24;
1717 #else
1718 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1719 #endif
1720 #endif
1721 switch(file_type) {
1722 default:
1723 case TCC_OUTPUT_EXE:
1724 ehdr.e_type = ET_EXEC;
1725 break;
1726 case TCC_OUTPUT_DLL:
1727 ehdr.e_type = ET_DYN;
1728 break;
1729 case TCC_OUTPUT_OBJ:
1730 ehdr.e_type = ET_REL;
1731 break;
1733 ehdr.e_machine = EM_TCC_TARGET;
1734 ehdr.e_version = EV_CURRENT;
1735 ehdr.e_shoff = file_offset;
1736 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1737 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1738 ehdr.e_shnum = shnum;
1739 ehdr.e_shstrndx = shnum - 1;
1741 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1742 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1743 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1745 for(i=1;i<s1->nb_sections;i++) {
1746 s = s1->sections[section_order[i]];
1747 if (s->sh_type != SHT_NOBITS) {
1748 while (offset < s->sh_offset) {
1749 fputc(0, f);
1750 offset++;
1752 size = s->sh_size;
1753 fwrite(s->data, 1, size, f);
1754 offset += size;
1758 /* output section headers */
1759 while (offset < ehdr.e_shoff) {
1760 fputc(0, f);
1761 offset++;
1764 for(i=0;i<s1->nb_sections;i++) {
1765 sh = &shdr;
1766 memset(sh, 0, sizeof(Elf32_Shdr));
1767 s = s1->sections[i];
1768 if (s) {
1769 sh->sh_name = s->sh_name;
1770 sh->sh_type = s->sh_type;
1771 sh->sh_flags = s->sh_flags;
1772 sh->sh_entsize = s->sh_entsize;
1773 sh->sh_info = s->sh_info;
1774 if (s->link)
1775 sh->sh_link = s->link->sh_num;
1776 sh->sh_addralign = s->sh_addralign;
1777 sh->sh_addr = s->sh_addr;
1778 sh->sh_offset = s->sh_offset;
1779 sh->sh_size = s->sh_size;
1781 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1783 } else {
1784 tcc_output_binary(s1, f, section_order);
1786 fclose(f);
1788 ret = 0;
1789 the_end:
1790 tcc_free(s1->symtab_to_dynsym);
1791 tcc_free(section_order);
1792 tcc_free(phdr);
1793 tcc_free(s1->got_offsets);
1794 return ret;
1797 int tcc_output_file(TCCState *s, const char *filename)
1799 int ret;
1800 #ifdef TCC_TARGET_PE
1801 if (s->output_type != TCC_OUTPUT_OBJ) {
1802 ret = pe_output_file(s, filename);
1803 } else
1804 #endif
1806 ret = elf_output_file(s, filename);
1808 return ret;
1811 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1813 void *data;
1815 data = tcc_malloc(size);
1816 lseek(fd, file_offset, SEEK_SET);
1817 read(fd, data, size);
1818 return data;
1821 typedef struct SectionMergeInfo {
1822 Section *s; /* corresponding existing section */
1823 unsigned long offset; /* offset of the new section in the existing section */
1824 uint8_t new_section; /* true if section 's' was added */
1825 uint8_t link_once; /* true if link once section */
1826 } SectionMergeInfo;
1828 /* load an object file and merge it with current files */
1829 /* XXX: handle correctly stab (debug) info */
1830 static int tcc_load_object_file(TCCState *s1,
1831 int fd, unsigned long file_offset)
1833 Elf32_Ehdr ehdr;
1834 Elf32_Shdr *shdr, *sh;
1835 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1836 unsigned char *strsec, *strtab;
1837 int *old_to_new_syms;
1838 char *sh_name, *name;
1839 SectionMergeInfo *sm_table, *sm;
1840 Elf32_Sym *sym, *symtab;
1841 Elf32_Rel *rel, *rel_end;
1842 Section *s;
1844 int stab_index;
1845 int stabstr_index;
1847 stab_index = stabstr_index = 0;
1849 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1850 goto fail1;
1851 if (ehdr.e_ident[0] != ELFMAG0 ||
1852 ehdr.e_ident[1] != ELFMAG1 ||
1853 ehdr.e_ident[2] != ELFMAG2 ||
1854 ehdr.e_ident[3] != ELFMAG3)
1855 goto fail1;
1856 /* test if object file */
1857 if (ehdr.e_type != ET_REL)
1858 goto fail1;
1859 /* test CPU specific stuff */
1860 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1861 ehdr.e_machine != EM_TCC_TARGET) {
1862 fail1:
1863 error_noabort("invalid object file");
1864 return -1;
1866 /* read sections */
1867 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1868 sizeof(Elf32_Shdr) * ehdr.e_shnum);
1869 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1871 /* load section names */
1872 sh = &shdr[ehdr.e_shstrndx];
1873 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1875 /* load symtab and strtab */
1876 old_to_new_syms = NULL;
1877 symtab = NULL;
1878 strtab = NULL;
1879 nb_syms = 0;
1880 for(i = 1; i < ehdr.e_shnum; i++) {
1881 sh = &shdr[i];
1882 if (sh->sh_type == SHT_SYMTAB) {
1883 if (symtab) {
1884 error_noabort("object must contain only one symtab");
1885 fail:
1886 ret = -1;
1887 goto the_end;
1889 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1890 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1891 sm_table[i].s = symtab_section;
1893 /* now load strtab */
1894 sh = &shdr[sh->sh_link];
1895 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1899 /* now examine each section and try to merge its content with the
1900 ones in memory */
1901 for(i = 1; i < ehdr.e_shnum; i++) {
1902 /* no need to examine section name strtab */
1903 if (i == ehdr.e_shstrndx)
1904 continue;
1905 sh = &shdr[i];
1906 sh_name = strsec + sh->sh_name;
1907 /* ignore sections types we do not handle */
1908 if (sh->sh_type != SHT_PROGBITS &&
1909 sh->sh_type != SHT_REL &&
1910 #ifdef TCC_ARM_EABI
1911 sh->sh_type != SHT_ARM_EXIDX &&
1912 #endif
1913 sh->sh_type != SHT_NOBITS &&
1914 strcmp(sh_name, ".stabstr")
1916 continue;
1917 if (sh->sh_addralign < 1)
1918 sh->sh_addralign = 1;
1919 /* find corresponding section, if any */
1920 for(j = 1; j < s1->nb_sections;j++) {
1921 s = s1->sections[j];
1922 if (!strcmp(s->name, sh_name)) {
1923 if (!strncmp(sh_name, ".gnu.linkonce",
1924 sizeof(".gnu.linkonce") - 1)) {
1925 /* if a 'linkonce' section is already present, we
1926 do not add it again. It is a little tricky as
1927 symbols can still be defined in
1928 it. */
1929 sm_table[i].link_once = 1;
1930 goto next;
1931 } else {
1932 goto found;
1936 /* not found: create new section */
1937 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1938 /* take as much info as possible from the section. sh_link and
1939 sh_info will be updated later */
1940 s->sh_addralign = sh->sh_addralign;
1941 s->sh_entsize = sh->sh_entsize;
1942 sm_table[i].new_section = 1;
1943 found:
1944 if (sh->sh_type != s->sh_type) {
1945 error_noabort("invalid section type");
1946 goto fail;
1949 /* align start of section */
1950 offset = s->data_offset;
1952 if (0 == strcmp(sh_name, ".stab")) {
1953 stab_index = i;
1954 goto no_align;
1956 if (0 == strcmp(sh_name, ".stabstr")) {
1957 stabstr_index = i;
1958 goto no_align;
1961 size = sh->sh_addralign - 1;
1962 offset = (offset + size) & ~size;
1963 if (sh->sh_addralign > s->sh_addralign)
1964 s->sh_addralign = sh->sh_addralign;
1965 s->data_offset = offset;
1966 no_align:
1967 sm_table[i].offset = offset;
1968 sm_table[i].s = s;
1969 /* concatenate sections */
1970 size = sh->sh_size;
1971 if (sh->sh_type != SHT_NOBITS) {
1972 unsigned char *ptr;
1973 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1974 ptr = section_ptr_add(s, size);
1975 read(fd, ptr, size);
1976 } else {
1977 s->data_offset += size;
1979 next: ;
1982 /* //gr relocate stab strings */
1983 if (stab_index && stabstr_index) {
1984 Stab_Sym *a, *b;
1985 unsigned o;
1986 s = sm_table[stab_index].s;
1987 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
1988 b = (Stab_Sym *)(s->data + s->data_offset);
1989 o = sm_table[stabstr_index].offset;
1990 while (a < b)
1991 a->n_strx += o, a++;
1994 /* second short pass to update sh_link and sh_info fields of new
1995 sections */
1996 for(i = 1; i < ehdr.e_shnum; i++) {
1997 s = sm_table[i].s;
1998 if (!s || !sm_table[i].new_section)
1999 continue;
2000 sh = &shdr[i];
2001 if (sh->sh_link > 0)
2002 s->link = sm_table[sh->sh_link].s;
2003 if (sh->sh_type == SHT_REL) {
2004 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2005 /* update backward link */
2006 s1->sections[s->sh_info]->reloc = s;
2009 sm = sm_table;
2011 /* resolve symbols */
2012 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2014 sym = symtab + 1;
2015 for(i = 1; i < nb_syms; i++, sym++) {
2016 if (sym->st_shndx != SHN_UNDEF &&
2017 sym->st_shndx < SHN_LORESERVE) {
2018 sm = &sm_table[sym->st_shndx];
2019 if (sm->link_once) {
2020 /* if a symbol is in a link once section, we use the
2021 already defined symbol. It is very important to get
2022 correct relocations */
2023 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
2024 name = strtab + sym->st_name;
2025 sym_index = find_elf_sym(symtab_section, name);
2026 if (sym_index)
2027 old_to_new_syms[i] = sym_index;
2029 continue;
2031 /* if no corresponding section added, no need to add symbol */
2032 if (!sm->s)
2033 continue;
2034 /* convert section number */
2035 sym->st_shndx = sm->s->sh_num;
2036 /* offset value */
2037 sym->st_value += sm->offset;
2039 /* add symbol */
2040 name = strtab + sym->st_name;
2041 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
2042 sym->st_info, sym->st_other,
2043 sym->st_shndx, name);
2044 old_to_new_syms[i] = sym_index;
2047 /* third pass to patch relocation entries */
2048 for(i = 1; i < ehdr.e_shnum; i++) {
2049 s = sm_table[i].s;
2050 if (!s)
2051 continue;
2052 sh = &shdr[i];
2053 offset = sm_table[i].offset;
2054 switch(s->sh_type) {
2055 case SHT_REL:
2056 /* take relocation offset information */
2057 offseti = sm_table[sh->sh_info].offset;
2058 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
2059 for(rel = (Elf32_Rel *)(s->data + offset);
2060 rel < rel_end;
2061 rel++) {
2062 int type;
2063 unsigned sym_index;
2064 /* convert symbol index */
2065 type = ELF32_R_TYPE(rel->r_info);
2066 sym_index = ELF32_R_SYM(rel->r_info);
2067 /* NOTE: only one symtab assumed */
2068 if (sym_index >= nb_syms)
2069 goto invalid_reloc;
2070 sym_index = old_to_new_syms[sym_index];
2071 /* ignore link_once in rel section. */
2072 if (!sym_index && !sm->link_once) {
2073 invalid_reloc:
2074 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2075 i, strsec + sh->sh_name, rel->r_offset);
2076 goto fail;
2078 rel->r_info = ELF32_R_INFO(sym_index, type);
2079 /* offset the relocation offset */
2080 rel->r_offset += offseti;
2082 break;
2083 default:
2084 break;
2088 ret = 0;
2089 the_end:
2090 tcc_free(symtab);
2091 tcc_free(strtab);
2092 tcc_free(old_to_new_syms);
2093 tcc_free(sm_table);
2094 tcc_free(strsec);
2095 tcc_free(shdr);
2096 return ret;
2099 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2101 typedef struct ArchiveHeader {
2102 char ar_name[16]; /* name of this member */
2103 char ar_date[12]; /* file mtime */
2104 char ar_uid[6]; /* owner uid; printed as decimal */
2105 char ar_gid[6]; /* owner gid; printed as decimal */
2106 char ar_mode[8]; /* file mode, printed as octal */
2107 char ar_size[10]; /* file size, printed as decimal */
2108 char ar_fmag[2]; /* should contain ARFMAG */
2109 } ArchiveHeader;
2111 static int get_be32(const uint8_t *b)
2113 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2116 /* load only the objects which resolve undefined symbols */
2117 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
2119 int i, bound, nsyms, sym_index, off, ret;
2120 uint8_t *data;
2121 const char *ar_names, *p;
2122 const uint8_t *ar_index;
2123 Elf32_Sym *sym;
2125 data = tcc_malloc(size);
2126 if (read(fd, data, size) != size)
2127 goto fail;
2128 nsyms = get_be32(data);
2129 ar_index = data + 4;
2130 ar_names = ar_index + nsyms * 4;
2132 do {
2133 bound = 0;
2134 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2135 sym_index = find_elf_sym(symtab_section, p);
2136 if(sym_index) {
2137 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
2138 if(sym->st_shndx == SHN_UNDEF) {
2139 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2140 #if 0
2141 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2142 #endif
2143 ++bound;
2144 lseek(fd, off, SEEK_SET);
2145 if(tcc_load_object_file(s1, fd, off) < 0) {
2146 fail:
2147 ret = -1;
2148 goto the_end;
2153 } while(bound);
2154 ret = 0;
2155 the_end:
2156 tcc_free(data);
2157 return ret;
2160 /* load a '.a' file */
2161 static int tcc_load_archive(TCCState *s1, int fd)
2163 ArchiveHeader hdr;
2164 char ar_size[11];
2165 char ar_name[17];
2166 char magic[8];
2167 int size, len, i;
2168 unsigned long file_offset;
2170 /* skip magic which was already checked */
2171 read(fd, magic, sizeof(magic));
2173 for(;;) {
2174 len = read(fd, &hdr, sizeof(hdr));
2175 if (len == 0)
2176 break;
2177 if (len != sizeof(hdr)) {
2178 error_noabort("invalid archive");
2179 return -1;
2181 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2182 ar_size[sizeof(hdr.ar_size)] = '\0';
2183 size = strtol(ar_size, NULL, 0);
2184 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2185 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2186 if (ar_name[i] != ' ')
2187 break;
2189 ar_name[i + 1] = '\0';
2190 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2191 file_offset = lseek(fd, 0, SEEK_CUR);
2192 /* align to even */
2193 size = (size + 1) & ~1;
2194 if (!strcmp(ar_name, "/")) {
2195 /* coff symbol table : we handle it */
2196 if(s1->alacarte_link)
2197 return tcc_load_alacarte(s1, fd, size);
2198 } else if (!strcmp(ar_name, "//") ||
2199 !strcmp(ar_name, "__.SYMDEF") ||
2200 !strcmp(ar_name, "__.SYMDEF/") ||
2201 !strcmp(ar_name, "ARFILENAMES/")) {
2202 /* skip symbol table or archive names */
2203 } else {
2204 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2205 return -1;
2207 lseek(fd, file_offset + size, SEEK_SET);
2209 return 0;
2212 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2213 is referenced by the user (so it should be added as DT_NEEDED in
2214 the generated ELF file) */
2215 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2217 Elf32_Ehdr ehdr;
2218 Elf32_Shdr *shdr, *sh, *sh1;
2219 int i, j, nb_syms, nb_dts, sym_bind, ret;
2220 Elf32_Sym *sym, *dynsym;
2221 Elf32_Dyn *dt, *dynamic;
2222 unsigned char *dynstr;
2223 const char *name, *soname;
2224 DLLReference *dllref;
2226 read(fd, &ehdr, sizeof(ehdr));
2228 /* test CPU specific stuff */
2229 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2230 ehdr.e_machine != EM_TCC_TARGET) {
2231 error_noabort("bad architecture");
2232 return -1;
2235 /* read sections */
2236 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
2238 /* load dynamic section and dynamic symbols */
2239 nb_syms = 0;
2240 nb_dts = 0;
2241 dynamic = NULL;
2242 dynsym = NULL; /* avoid warning */
2243 dynstr = NULL; /* avoid warning */
2244 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2245 switch(sh->sh_type) {
2246 case SHT_DYNAMIC:
2247 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
2248 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2249 break;
2250 case SHT_DYNSYM:
2251 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
2252 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2253 sh1 = &shdr[sh->sh_link];
2254 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2255 break;
2256 default:
2257 break;
2261 /* compute the real library name */
2262 soname = tcc_basename(filename);
2264 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2265 if (dt->d_tag == DT_SONAME) {
2266 soname = dynstr + dt->d_un.d_val;
2270 /* if the dll is already loaded, do not load it */
2271 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2272 dllref = s1->loaded_dlls[i];
2273 if (!strcmp(soname, dllref->name)) {
2274 /* but update level if needed */
2275 if (level < dllref->level)
2276 dllref->level = level;
2277 ret = 0;
2278 goto the_end;
2282 // printf("loading dll '%s'\n", soname);
2284 /* add the dll and its level */
2285 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2286 dllref->level = level;
2287 strcpy(dllref->name, soname);
2288 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2290 /* add dynamic symbols in dynsym_section */
2291 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2292 sym_bind = ELF32_ST_BIND(sym->st_info);
2293 if (sym_bind == STB_LOCAL)
2294 continue;
2295 name = dynstr + sym->st_name;
2296 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2297 sym->st_info, sym->st_other, sym->st_shndx, name);
2300 /* load all referenced DLLs */
2301 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2302 switch(dt->d_tag) {
2303 case DT_NEEDED:
2304 name = dynstr + dt->d_un.d_val;
2305 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2306 dllref = s1->loaded_dlls[j];
2307 if (!strcmp(name, dllref->name))
2308 goto already_loaded;
2310 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2311 error_noabort("referenced dll '%s' not found", name);
2312 ret = -1;
2313 goto the_end;
2315 already_loaded:
2316 break;
2319 ret = 0;
2320 the_end:
2321 tcc_free(dynstr);
2322 tcc_free(dynsym);
2323 tcc_free(dynamic);
2324 tcc_free(shdr);
2325 return ret;
2328 #define LD_TOK_NAME 256
2329 #define LD_TOK_EOF (-1)
2331 /* return next ld script token */
2332 static int ld_next(TCCState *s1, char *name, int name_size)
2334 int c;
2335 char *q;
2337 redo:
2338 switch(ch) {
2339 case ' ':
2340 case '\t':
2341 case '\f':
2342 case '\v':
2343 case '\r':
2344 case '\n':
2345 inp();
2346 goto redo;
2347 case '/':
2348 minp();
2349 if (ch == '*') {
2350 file->buf_ptr = parse_comment(file->buf_ptr);
2351 ch = file->buf_ptr[0];
2352 goto redo;
2353 } else {
2354 q = name;
2355 *q++ = '/';
2356 goto parse_name;
2358 break;
2359 /* case 'a' ... 'z': */
2360 case 'a':
2361 case 'b':
2362 case 'c':
2363 case 'd':
2364 case 'e':
2365 case 'f':
2366 case 'g':
2367 case 'h':
2368 case 'i':
2369 case 'j':
2370 case 'k':
2371 case 'l':
2372 case 'm':
2373 case 'n':
2374 case 'o':
2375 case 'p':
2376 case 'q':
2377 case 'r':
2378 case 's':
2379 case 't':
2380 case 'u':
2381 case 'v':
2382 case 'w':
2383 case 'x':
2384 case 'y':
2385 case 'z':
2386 /* case 'A' ... 'z': */
2387 case 'A':
2388 case 'B':
2389 case 'C':
2390 case 'D':
2391 case 'E':
2392 case 'F':
2393 case 'G':
2394 case 'H':
2395 case 'I':
2396 case 'J':
2397 case 'K':
2398 case 'L':
2399 case 'M':
2400 case 'N':
2401 case 'O':
2402 case 'P':
2403 case 'Q':
2404 case 'R':
2405 case 'S':
2406 case 'T':
2407 case 'U':
2408 case 'V':
2409 case 'W':
2410 case 'X':
2411 case 'Y':
2412 case 'Z':
2413 case '_':
2414 case '\\':
2415 case '.':
2416 case '$':
2417 case '~':
2418 q = name;
2419 parse_name:
2420 for(;;) {
2421 if (!((ch >= 'a' && ch <= 'z') ||
2422 (ch >= 'A' && ch <= 'Z') ||
2423 (ch >= '0' && ch <= '9') ||
2424 strchr("/.-_+=$:\\,~", ch)))
2425 break;
2426 if ((q - name) < name_size - 1) {
2427 *q++ = ch;
2429 minp();
2431 *q = '\0';
2432 c = LD_TOK_NAME;
2433 break;
2434 case CH_EOF:
2435 c = LD_TOK_EOF;
2436 break;
2437 default:
2438 c = ch;
2439 inp();
2440 break;
2442 #if 0
2443 printf("tok=%c %d\n", c, c);
2444 if (c == LD_TOK_NAME)
2445 printf(" name=%s\n", name);
2446 #endif
2447 return c;
2450 static int ld_add_file_list(TCCState *s1, int as_needed)
2452 char filename[1024];
2453 int t, ret;
2455 t = ld_next(s1, filename, sizeof(filename));
2456 if (t != '(')
2457 expect("(");
2458 t = ld_next(s1, filename, sizeof(filename));
2459 for(;;) {
2460 if (t == LD_TOK_EOF) {
2461 error_noabort("unexpected end of file");
2462 return -1;
2463 } else if (t == ')') {
2464 break;
2465 } else if (t != LD_TOK_NAME) {
2466 error_noabort("filename expected");
2467 return -1;
2469 if (!strcmp(filename, "AS_NEEDED")) {
2470 ret = ld_add_file_list(s1, 1);
2471 if (ret)
2472 return ret;
2473 } else {
2474 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2475 if (!as_needed)
2476 tcc_add_file(s1, filename);
2478 t = ld_next(s1, filename, sizeof(filename));
2479 if (t == ',') {
2480 t = ld_next(s1, filename, sizeof(filename));
2483 return 0;
2486 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2487 files */
2488 static int tcc_load_ldscript(TCCState *s1)
2490 char cmd[64];
2491 char filename[1024];
2492 int t, ret;
2494 ch = file->buf_ptr[0];
2495 ch = handle_eob();
2496 for(;;) {
2497 t = ld_next(s1, cmd, sizeof(cmd));
2498 if (t == LD_TOK_EOF)
2499 return 0;
2500 else if (t != LD_TOK_NAME)
2501 return -1;
2502 if (!strcmp(cmd, "INPUT") ||
2503 !strcmp(cmd, "GROUP")) {
2504 ret = ld_add_file_list(s1, 0);
2505 if (ret)
2506 return ret;
2507 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2508 !strcmp(cmd, "TARGET")) {
2509 /* ignore some commands */
2510 t = ld_next(s1, cmd, sizeof(cmd));
2511 if (t != '(')
2512 expect("(");
2513 for(;;) {
2514 t = ld_next(s1, filename, sizeof(filename));
2515 if (t == LD_TOK_EOF) {
2516 error_noabort("unexpected end of file");
2517 return -1;
2518 } else if (t == ')') {
2519 break;
2522 } else {
2523 return -1;
2526 return 0;