Set VT_LVAL_xxx flags for function arguments in gfunc_prolog (Daniel Glöckner)
[tinycc.git] / tccelf.c
blob7de8a4866a0b2f912ff9c2d8a2224bacfef1d489
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 char buf[1024];
997 #ifdef CONFIG_TCC_BCHECK
998 if (do_bounds_check) {
999 unsigned long *ptr;
1000 Section *init_section;
1001 unsigned char *pinit;
1002 int sym_index;
1004 /* XXX: add an object file to do that */
1005 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
1006 *ptr = 0;
1007 add_elf_sym(symtab_section, 0, 0,
1008 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1009 bounds_section->sh_num, "__bounds_start");
1010 /* add bound check code */
1011 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
1012 tcc_add_file(s1, buf);
1013 #ifdef TCC_TARGET_I386
1014 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1015 /* add 'call __bound_init()' in .init section */
1016 init_section = find_section(s1, ".init");
1017 pinit = section_ptr_add(init_section, 5);
1018 pinit[0] = 0xe8;
1019 put32(pinit + 1, -4);
1020 sym_index = find_elf_sym(symtab_section, "__bound_init");
1021 put_elf_reloc(symtab_section, init_section,
1022 init_section->data_offset - 4, R_386_PC32, sym_index);
1024 #endif
1026 #endif
1027 /* add libc */
1028 if (!s1->nostdlib) {
1029 tcc_add_library(s1, "c");
1031 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
1032 tcc_add_file(s1, buf);
1034 /* add crt end if not memory output */
1035 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
1036 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1040 /* add various standard linker symbols (must be done after the
1041 sections are filled (for example after allocating common
1042 symbols)) */
1043 static void tcc_add_linker_symbols(TCCState *s1)
1045 char buf[1024];
1046 int i;
1047 Section *s;
1049 add_elf_sym(symtab_section,
1050 text_section->data_offset, 0,
1051 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1052 text_section->sh_num, "_etext");
1053 add_elf_sym(symtab_section,
1054 data_section->data_offset, 0,
1055 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1056 data_section->sh_num, "_edata");
1057 add_elf_sym(symtab_section,
1058 bss_section->data_offset, 0,
1059 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1060 bss_section->sh_num, "_end");
1061 /* horrible new standard ldscript defines */
1062 add_init_array_defines(s1, ".preinit_array");
1063 add_init_array_defines(s1, ".init_array");
1064 add_init_array_defines(s1, ".fini_array");
1066 /* add start and stop symbols for sections whose name can be
1067 expressed in C */
1068 for(i = 1; i < s1->nb_sections; i++) {
1069 s = s1->sections[i];
1070 if (s->sh_type == SHT_PROGBITS &&
1071 (s->sh_flags & SHF_ALLOC)) {
1072 const char *p;
1073 int ch;
1075 /* check if section name can be expressed in C */
1076 p = s->name;
1077 for(;;) {
1078 ch = *p;
1079 if (!ch)
1080 break;
1081 if (!isid(ch) && !isnum(ch))
1082 goto next_sec;
1083 p++;
1085 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1086 add_elf_sym(symtab_section,
1087 0, 0,
1088 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1089 s->sh_num, buf);
1090 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1091 add_elf_sym(symtab_section,
1092 s->data_offset, 0,
1093 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1094 s->sh_num, buf);
1096 next_sec: ;
1100 /* name of ELF interpreter */
1101 #ifdef __FreeBSD__
1102 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1103 #else
1104 #ifdef TCC_ARM_EABI
1105 static char elf_interp[] = "/lib/ld-linux.so.3";
1106 #else
1107 static char elf_interp[] = "/lib/ld-linux.so.2";
1108 #endif
1109 #endif
1111 static void tcc_output_binary(TCCState *s1, FILE *f,
1112 const int *section_order)
1114 Section *s;
1115 int i, offset, size;
1117 offset = 0;
1118 for(i=1;i<s1->nb_sections;i++) {
1119 s = s1->sections[section_order[i]];
1120 if (s->sh_type != SHT_NOBITS &&
1121 (s->sh_flags & SHF_ALLOC)) {
1122 while (offset < s->sh_offset) {
1123 fputc(0, f);
1124 offset++;
1126 size = s->sh_size;
1127 fwrite(s->data, 1, size, f);
1128 offset += size;
1133 /* output an ELF file */
1134 /* XXX: suppress unneeded sections */
1135 int elf_output_file(TCCState *s1, const char *filename)
1137 Elf32_Ehdr ehdr;
1138 FILE *f;
1139 int fd, mode, ret;
1140 int *section_order;
1141 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1142 unsigned long addr;
1143 Section *strsec, *s;
1144 Elf32_Shdr shdr, *sh;
1145 Elf32_Phdr *phdr, *ph;
1146 Section *interp, *dynamic, *dynstr;
1147 unsigned long saved_dynamic_data_offset;
1148 Elf32_Sym *sym;
1149 int type, file_type;
1150 unsigned long rel_addr, rel_size;
1152 file_type = s1->output_type;
1153 s1->nb_errors = 0;
1155 if (file_type != TCC_OUTPUT_OBJ) {
1156 tcc_add_runtime(s1);
1159 phdr = NULL;
1160 section_order = NULL;
1161 interp = NULL;
1162 dynamic = NULL;
1163 dynstr = NULL; /* avoid warning */
1164 saved_dynamic_data_offset = 0; /* avoid warning */
1166 if (file_type != TCC_OUTPUT_OBJ) {
1167 relocate_common_syms();
1169 tcc_add_linker_symbols(s1);
1171 if (!s1->static_link) {
1172 const char *name;
1173 int sym_index, index;
1174 Elf32_Sym *esym, *sym_end;
1176 if (file_type == TCC_OUTPUT_EXE) {
1177 char *ptr;
1178 /* add interpreter section only if executable */
1179 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1180 interp->sh_addralign = 1;
1181 ptr = section_ptr_add(interp, sizeof(elf_interp));
1182 strcpy(ptr, elf_interp);
1185 /* add dynamic symbol table */
1186 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1187 ".dynstr",
1188 ".hash", SHF_ALLOC);
1189 dynstr = s1->dynsym->link;
1191 /* add dynamic section */
1192 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1193 SHF_ALLOC | SHF_WRITE);
1194 dynamic->link = dynstr;
1195 dynamic->sh_entsize = sizeof(Elf32_Dyn);
1197 /* add PLT */
1198 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1199 SHF_ALLOC | SHF_EXECINSTR);
1200 s1->plt->sh_entsize = 4;
1202 build_got(s1);
1204 /* scan for undefined symbols and see if they are in the
1205 dynamic symbols. If a symbol STT_FUNC is found, then we
1206 add it in the PLT. If a symbol STT_OBJECT is found, we
1207 add it in the .bss section with a suitable relocation */
1208 sym_end = (Elf32_Sym *)(symtab_section->data +
1209 symtab_section->data_offset);
1210 if (file_type == TCC_OUTPUT_EXE) {
1211 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1212 sym < sym_end;
1213 sym++) {
1214 if (sym->st_shndx == SHN_UNDEF) {
1215 name = symtab_section->link->data + sym->st_name;
1216 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1217 if (sym_index) {
1218 esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
1219 type = ELF32_ST_TYPE(esym->st_info);
1220 if (type == STT_FUNC) {
1221 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1222 esym->st_info,
1223 sym - (Elf32_Sym *)symtab_section->data);
1224 } else if (type == STT_OBJECT) {
1225 unsigned long offset;
1226 offset = bss_section->data_offset;
1227 /* XXX: which alignment ? */
1228 offset = (offset + 16 - 1) & -16;
1229 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1230 esym->st_info, 0,
1231 bss_section->sh_num, name);
1232 put_elf_reloc(s1->dynsym, bss_section,
1233 offset, R_COPY, index);
1234 offset += esym->st_size;
1235 bss_section->data_offset = offset;
1237 } else {
1238 /* STB_WEAK undefined symbols are accepted */
1239 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1240 it */
1241 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
1242 !strcmp(name, "_fp_hw")) {
1243 } else {
1244 error_noabort("undefined symbol '%s'", name);
1247 } else if (s1->rdynamic &&
1248 ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1249 /* if -rdynamic option, then export all non
1250 local symbols */
1251 name = symtab_section->link->data + sym->st_name;
1252 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1253 sym->st_info, 0,
1254 sym->st_shndx, name);
1258 if (s1->nb_errors)
1259 goto fail;
1261 /* now look at unresolved dynamic symbols and export
1262 corresponding symbol */
1263 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
1264 s1->dynsymtab_section->data_offset);
1265 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
1266 esym < sym_end;
1267 esym++) {
1268 if (esym->st_shndx == SHN_UNDEF) {
1269 name = s1->dynsymtab_section->link->data + esym->st_name;
1270 sym_index = find_elf_sym(symtab_section, name);
1271 if (sym_index) {
1272 /* XXX: avoid adding a symbol if already
1273 present because of -rdynamic ? */
1274 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1275 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1276 sym->st_info, 0,
1277 sym->st_shndx, name);
1278 } else {
1279 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
1280 /* weak symbols can stay undefined */
1281 } else {
1282 warning("undefined dynamic symbol '%s'", name);
1287 } else {
1288 int nb_syms;
1289 /* shared library case : we simply export all the global symbols */
1290 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
1291 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1292 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1293 sym < sym_end;
1294 sym++) {
1295 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1296 name = symtab_section->link->data + sym->st_name;
1297 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1298 sym->st_info, 0,
1299 sym->st_shndx, name);
1300 s1->symtab_to_dynsym[sym -
1301 (Elf32_Sym *)symtab_section->data] =
1302 index;
1307 build_got_entries(s1);
1309 /* add a list of needed dlls */
1310 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1311 DLLReference *dllref = s1->loaded_dlls[i];
1312 if (dllref->level == 0)
1313 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1315 /* XXX: currently, since we do not handle PIC code, we
1316 must relocate the readonly segments */
1317 if (file_type == TCC_OUTPUT_DLL) {
1318 if (s1->soname)
1319 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
1320 put_dt(dynamic, DT_TEXTREL, 0);
1323 /* add necessary space for other entries */
1324 saved_dynamic_data_offset = dynamic->data_offset;
1325 dynamic->data_offset += 8 * 9;
1326 } else {
1327 /* still need to build got entries in case of static link */
1328 build_got_entries(s1);
1332 memset(&ehdr, 0, sizeof(ehdr));
1334 /* we add a section for symbols */
1335 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1336 put_elf_str(strsec, "");
1338 /* compute number of sections */
1339 shnum = s1->nb_sections;
1341 /* this array is used to reorder sections in the output file */
1342 section_order = tcc_malloc(sizeof(int) * shnum);
1343 section_order[0] = 0;
1344 sh_order_index = 1;
1346 /* compute number of program headers */
1347 switch(file_type) {
1348 default:
1349 case TCC_OUTPUT_OBJ:
1350 phnum = 0;
1351 break;
1352 case TCC_OUTPUT_EXE:
1353 if (!s1->static_link)
1354 phnum = 4;
1355 else
1356 phnum = 2;
1357 break;
1358 case TCC_OUTPUT_DLL:
1359 phnum = 3;
1360 break;
1363 /* allocate strings for section names and decide if an unallocated
1364 section should be output */
1365 /* NOTE: the strsec section comes last, so its size is also
1366 correct ! */
1367 for(i = 1; i < s1->nb_sections; i++) {
1368 s = s1->sections[i];
1369 s->sh_name = put_elf_str(strsec, s->name);
1370 #if 0 //gr
1371 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1372 s->sh_flags,
1373 s->sh_type,
1374 s->sh_info,
1375 s->name,
1376 s->reloc ? s->reloc->name : "n"
1378 #endif
1379 /* when generating a DLL, we include relocations but we may
1380 patch them */
1381 if (file_type == TCC_OUTPUT_DLL &&
1382 s->sh_type == SHT_REL &&
1383 !(s->sh_flags & SHF_ALLOC)) {
1384 /* //gr: avoid bogus relocs for empty (debug) sections */
1385 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1386 prepare_dynamic_rel(s1, s);
1387 else if (do_debug)
1388 s->sh_size = s->data_offset;
1389 } else if (do_debug ||
1390 file_type == TCC_OUTPUT_OBJ ||
1391 (s->sh_flags & SHF_ALLOC) ||
1392 i == (s1->nb_sections - 1)) {
1393 /* we output all sections if debug or object file */
1394 s->sh_size = s->data_offset;
1398 /* allocate program segment headers */
1399 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1401 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1402 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1403 } else {
1404 file_offset = 0;
1406 if (phnum > 0) {
1407 /* compute section to program header mapping */
1408 if (s1->has_text_addr) {
1409 int a_offset, p_offset;
1410 addr = s1->text_addr;
1411 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1412 ELF_PAGE_SIZE */
1413 a_offset = addr & (ELF_PAGE_SIZE - 1);
1414 p_offset = file_offset & (ELF_PAGE_SIZE - 1);
1415 if (a_offset < p_offset)
1416 a_offset += ELF_PAGE_SIZE;
1417 file_offset += (a_offset - p_offset);
1418 } else {
1419 if (file_type == TCC_OUTPUT_DLL)
1420 addr = 0;
1421 else
1422 addr = ELF_START_ADDR;
1423 /* compute address after headers */
1424 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1427 /* dynamic relocation table information, for .dynamic section */
1428 rel_size = 0;
1429 rel_addr = 0;
1431 /* leave one program header for the program interpreter */
1432 ph = &phdr[0];
1433 if (interp)
1434 ph++;
1436 for(j = 0; j < 2; j++) {
1437 ph->p_type = PT_LOAD;
1438 if (j == 0)
1439 ph->p_flags = PF_R | PF_X;
1440 else
1441 ph->p_flags = PF_R | PF_W;
1442 ph->p_align = ELF_PAGE_SIZE;
1444 /* we do the following ordering: interp, symbol tables,
1445 relocations, progbits, nobits */
1446 /* XXX: do faster and simpler sorting */
1447 for(k = 0; k < 5; k++) {
1448 for(i = 1; i < s1->nb_sections; i++) {
1449 s = s1->sections[i];
1450 /* compute if section should be included */
1451 if (j == 0) {
1452 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1453 SHF_ALLOC)
1454 continue;
1455 } else {
1456 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1457 (SHF_ALLOC | SHF_WRITE))
1458 continue;
1460 if (s == interp) {
1461 if (k != 0)
1462 continue;
1463 } else if (s->sh_type == SHT_DYNSYM ||
1464 s->sh_type == SHT_STRTAB ||
1465 s->sh_type == SHT_HASH) {
1466 if (k != 1)
1467 continue;
1468 } else if (s->sh_type == SHT_REL) {
1469 if (k != 2)
1470 continue;
1471 } else if (s->sh_type == SHT_NOBITS) {
1472 if (k != 4)
1473 continue;
1474 } else {
1475 if (k != 3)
1476 continue;
1478 section_order[sh_order_index++] = i;
1480 /* section matches: we align it and add its size */
1481 tmp = addr;
1482 addr = (addr + s->sh_addralign - 1) &
1483 ~(s->sh_addralign - 1);
1484 file_offset += addr - tmp;
1485 s->sh_offset = file_offset;
1486 s->sh_addr = addr;
1488 /* update program header infos */
1489 if (ph->p_offset == 0) {
1490 ph->p_offset = file_offset;
1491 ph->p_vaddr = addr;
1492 ph->p_paddr = ph->p_vaddr;
1494 /* update dynamic relocation infos */
1495 if (s->sh_type == SHT_REL) {
1496 if (rel_size == 0)
1497 rel_addr = addr;
1498 rel_size += s->sh_size;
1500 addr += s->sh_size;
1501 if (s->sh_type != SHT_NOBITS)
1502 file_offset += s->sh_size;
1505 ph->p_filesz = file_offset - ph->p_offset;
1506 ph->p_memsz = addr - ph->p_vaddr;
1507 ph++;
1508 if (j == 0) {
1509 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1510 /* if in the middle of a page, we duplicate the page in
1511 memory so that one copy is RX and the other is RW */
1512 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1513 addr += ELF_PAGE_SIZE;
1514 } else {
1515 addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
1516 file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
1517 ~(ELF_PAGE_SIZE - 1);
1522 /* if interpreter, then add corresponing program header */
1523 if (interp) {
1524 ph = &phdr[0];
1526 ph->p_type = PT_INTERP;
1527 ph->p_offset = interp->sh_offset;
1528 ph->p_vaddr = interp->sh_addr;
1529 ph->p_paddr = ph->p_vaddr;
1530 ph->p_filesz = interp->sh_size;
1531 ph->p_memsz = interp->sh_size;
1532 ph->p_flags = PF_R;
1533 ph->p_align = interp->sh_addralign;
1536 /* if dynamic section, then add corresponing program header */
1537 if (dynamic) {
1538 Elf32_Sym *sym_end;
1540 ph = &phdr[phnum - 1];
1542 ph->p_type = PT_DYNAMIC;
1543 ph->p_offset = dynamic->sh_offset;
1544 ph->p_vaddr = dynamic->sh_addr;
1545 ph->p_paddr = ph->p_vaddr;
1546 ph->p_filesz = dynamic->sh_size;
1547 ph->p_memsz = dynamic->sh_size;
1548 ph->p_flags = PF_R | PF_W;
1549 ph->p_align = dynamic->sh_addralign;
1551 /* put GOT dynamic section address */
1552 put32(s1->got->data, dynamic->sh_addr);
1554 /* relocate the PLT */
1555 if (file_type == TCC_OUTPUT_EXE) {
1556 uint8_t *p, *p_end;
1558 p = s1->plt->data;
1559 p_end = p + s1->plt->data_offset;
1560 if (p < p_end) {
1561 #if defined(TCC_TARGET_I386)
1562 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1563 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1564 p += 16;
1565 while (p < p_end) {
1566 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1567 p += 16;
1569 #elif defined(TCC_TARGET_ARM)
1570 int x;
1571 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1572 p +=16;
1573 while (p < p_end) {
1574 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1575 p += 16;
1577 #elif defined(TCC_TARGET_C67)
1578 /* XXX: TODO */
1579 #else
1580 #error unsupported CPU
1581 #endif
1585 /* relocate symbols in .dynsym */
1586 sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
1587 for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
1588 sym < sym_end;
1589 sym++) {
1590 if (sym->st_shndx == SHN_UNDEF) {
1591 /* relocate to the PLT if the symbol corresponds
1592 to a PLT entry */
1593 if (sym->st_value)
1594 sym->st_value += s1->plt->sh_addr;
1595 } else if (sym->st_shndx < SHN_LORESERVE) {
1596 /* do symbol relocation */
1597 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1601 /* put dynamic section entries */
1602 dynamic->data_offset = saved_dynamic_data_offset;
1603 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1604 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1605 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1606 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1607 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
1608 put_dt(dynamic, DT_REL, rel_addr);
1609 put_dt(dynamic, DT_RELSZ, rel_size);
1610 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
1611 if (do_debug)
1612 put_dt(dynamic, DT_DEBUG, 0);
1613 put_dt(dynamic, DT_NULL, 0);
1616 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1617 ehdr.e_phnum = phnum;
1618 ehdr.e_phoff = sizeof(Elf32_Ehdr);
1621 /* all other sections come after */
1622 for(i = 1; i < s1->nb_sections; i++) {
1623 s = s1->sections[i];
1624 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1625 continue;
1626 section_order[sh_order_index++] = i;
1628 file_offset = (file_offset + s->sh_addralign - 1) &
1629 ~(s->sh_addralign - 1);
1630 s->sh_offset = file_offset;
1631 if (s->sh_type != SHT_NOBITS)
1632 file_offset += s->sh_size;
1635 /* if building executable or DLL, then relocate each section
1636 except the GOT which is already relocated */
1637 if (file_type != TCC_OUTPUT_OBJ) {
1638 relocate_syms(s1, 0);
1640 if (s1->nb_errors != 0) {
1641 fail:
1642 ret = -1;
1643 goto the_end;
1646 /* relocate sections */
1647 /* XXX: ignore sections with allocated relocations ? */
1648 for(i = 1; i < s1->nb_sections; i++) {
1649 s = s1->sections[i];
1650 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
1651 relocate_section(s1, s);
1654 /* relocate relocation entries if the relocation tables are
1655 allocated in the executable */
1656 for(i = 1; i < s1->nb_sections; i++) {
1657 s = s1->sections[i];
1658 if ((s->sh_flags & SHF_ALLOC) &&
1659 s->sh_type == SHT_REL) {
1660 relocate_rel(s1, s);
1664 /* get entry point address */
1665 if (file_type == TCC_OUTPUT_EXE)
1666 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
1667 else
1668 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1671 /* write elf file */
1672 if (file_type == TCC_OUTPUT_OBJ)
1673 mode = 0666;
1674 else
1675 mode = 0777;
1676 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1677 if (fd < 0) {
1678 error_noabort("could not write '%s'", filename);
1679 goto fail;
1681 f = fdopen(fd, "wb");
1682 if (verbose)
1683 printf("<- %s\n", filename);
1685 #ifdef TCC_TARGET_COFF
1686 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1687 tcc_output_coff(s1, f);
1688 } else
1689 #endif
1690 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1691 sort_syms(s1, symtab_section);
1693 /* align to 4 */
1694 file_offset = (file_offset + 3) & -4;
1696 /* fill header */
1697 ehdr.e_ident[0] = ELFMAG0;
1698 ehdr.e_ident[1] = ELFMAG1;
1699 ehdr.e_ident[2] = ELFMAG2;
1700 ehdr.e_ident[3] = ELFMAG3;
1701 ehdr.e_ident[4] = ELFCLASS32;
1702 ehdr.e_ident[5] = ELFDATA2LSB;
1703 ehdr.e_ident[6] = EV_CURRENT;
1704 #ifdef __FreeBSD__
1705 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1706 #endif
1707 #ifdef TCC_TARGET_ARM
1708 #ifdef TCC_ARM_EABI
1709 ehdr.e_ident[EI_OSABI] = 0;
1710 ehdr.e_flags = 4 << 24;
1711 #else
1712 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1713 #endif
1714 #endif
1715 switch(file_type) {
1716 default:
1717 case TCC_OUTPUT_EXE:
1718 ehdr.e_type = ET_EXEC;
1719 break;
1720 case TCC_OUTPUT_DLL:
1721 ehdr.e_type = ET_DYN;
1722 break;
1723 case TCC_OUTPUT_OBJ:
1724 ehdr.e_type = ET_REL;
1725 break;
1727 ehdr.e_machine = EM_TCC_TARGET;
1728 ehdr.e_version = EV_CURRENT;
1729 ehdr.e_shoff = file_offset;
1730 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1731 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1732 ehdr.e_shnum = shnum;
1733 ehdr.e_shstrndx = shnum - 1;
1735 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1736 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1737 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1739 for(i=1;i<s1->nb_sections;i++) {
1740 s = s1->sections[section_order[i]];
1741 if (s->sh_type != SHT_NOBITS) {
1742 while (offset < s->sh_offset) {
1743 fputc(0, f);
1744 offset++;
1746 size = s->sh_size;
1747 fwrite(s->data, 1, size, f);
1748 offset += size;
1752 /* output section headers */
1753 while (offset < ehdr.e_shoff) {
1754 fputc(0, f);
1755 offset++;
1758 for(i=0;i<s1->nb_sections;i++) {
1759 sh = &shdr;
1760 memset(sh, 0, sizeof(Elf32_Shdr));
1761 s = s1->sections[i];
1762 if (s) {
1763 sh->sh_name = s->sh_name;
1764 sh->sh_type = s->sh_type;
1765 sh->sh_flags = s->sh_flags;
1766 sh->sh_entsize = s->sh_entsize;
1767 sh->sh_info = s->sh_info;
1768 if (s->link)
1769 sh->sh_link = s->link->sh_num;
1770 sh->sh_addralign = s->sh_addralign;
1771 sh->sh_addr = s->sh_addr;
1772 sh->sh_offset = s->sh_offset;
1773 sh->sh_size = s->sh_size;
1775 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1777 } else {
1778 tcc_output_binary(s1, f, section_order);
1780 fclose(f);
1782 ret = 0;
1783 the_end:
1784 tcc_free(s1->symtab_to_dynsym);
1785 tcc_free(section_order);
1786 tcc_free(phdr);
1787 tcc_free(s1->got_offsets);
1788 return ret;
1791 int tcc_output_file(TCCState *s, const char *filename)
1793 int ret;
1794 #ifdef TCC_TARGET_PE
1795 if (s->output_type != TCC_OUTPUT_OBJ) {
1796 ret = pe_output_file(s, filename);
1797 } else
1798 #endif
1800 ret = elf_output_file(s, filename);
1802 return ret;
1805 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1807 void *data;
1809 data = tcc_malloc(size);
1810 lseek(fd, file_offset, SEEK_SET);
1811 read(fd, data, size);
1812 return data;
1815 typedef struct SectionMergeInfo {
1816 Section *s; /* corresponding existing section */
1817 unsigned long offset; /* offset of the new section in the existing section */
1818 uint8_t new_section; /* true if section 's' was added */
1819 uint8_t link_once; /* true if link once section */
1820 } SectionMergeInfo;
1822 /* load an object file and merge it with current files */
1823 /* XXX: handle correctly stab (debug) info */
1824 static int tcc_load_object_file(TCCState *s1,
1825 int fd, unsigned long file_offset)
1827 Elf32_Ehdr ehdr;
1828 Elf32_Shdr *shdr, *sh;
1829 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1830 unsigned char *strsec, *strtab;
1831 int *old_to_new_syms;
1832 char *sh_name, *name;
1833 SectionMergeInfo *sm_table, *sm;
1834 Elf32_Sym *sym, *symtab;
1835 Elf32_Rel *rel, *rel_end;
1836 Section *s;
1838 int stab_index;
1839 int stabstr_index;
1841 stab_index = stabstr_index = 0;
1843 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1844 goto fail1;
1845 if (ehdr.e_ident[0] != ELFMAG0 ||
1846 ehdr.e_ident[1] != ELFMAG1 ||
1847 ehdr.e_ident[2] != ELFMAG2 ||
1848 ehdr.e_ident[3] != ELFMAG3)
1849 goto fail1;
1850 /* test if object file */
1851 if (ehdr.e_type != ET_REL)
1852 goto fail1;
1853 /* test CPU specific stuff */
1854 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1855 ehdr.e_machine != EM_TCC_TARGET) {
1856 fail1:
1857 error_noabort("invalid object file");
1858 return -1;
1860 /* read sections */
1861 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1862 sizeof(Elf32_Shdr) * ehdr.e_shnum);
1863 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1865 /* load section names */
1866 sh = &shdr[ehdr.e_shstrndx];
1867 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1869 /* load symtab and strtab */
1870 old_to_new_syms = NULL;
1871 symtab = NULL;
1872 strtab = NULL;
1873 nb_syms = 0;
1874 for(i = 1; i < ehdr.e_shnum; i++) {
1875 sh = &shdr[i];
1876 if (sh->sh_type == SHT_SYMTAB) {
1877 if (symtab) {
1878 error_noabort("object must contain only one symtab");
1879 fail:
1880 ret = -1;
1881 goto the_end;
1883 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1884 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1885 sm_table[i].s = symtab_section;
1887 /* now load strtab */
1888 sh = &shdr[sh->sh_link];
1889 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1893 /* now examine each section and try to merge its content with the
1894 ones in memory */
1895 for(i = 1; i < ehdr.e_shnum; i++) {
1896 /* no need to examine section name strtab */
1897 if (i == ehdr.e_shstrndx)
1898 continue;
1899 sh = &shdr[i];
1900 sh_name = strsec + sh->sh_name;
1901 /* ignore sections types we do not handle */
1902 if (sh->sh_type != SHT_PROGBITS &&
1903 sh->sh_type != SHT_REL &&
1904 #ifdef TCC_ARM_EABI
1905 sh->sh_type != SHT_ARM_EXIDX &&
1906 #endif
1907 sh->sh_type != SHT_NOBITS &&
1908 strcmp(sh_name, ".stabstr")
1910 continue;
1911 if (sh->sh_addralign < 1)
1912 sh->sh_addralign = 1;
1913 /* find corresponding section, if any */
1914 for(j = 1; j < s1->nb_sections;j++) {
1915 s = s1->sections[j];
1916 if (!strcmp(s->name, sh_name)) {
1917 if (!strncmp(sh_name, ".gnu.linkonce",
1918 sizeof(".gnu.linkonce") - 1)) {
1919 /* if a 'linkonce' section is already present, we
1920 do not add it again. It is a little tricky as
1921 symbols can still be defined in
1922 it. */
1923 sm_table[i].link_once = 1;
1924 goto next;
1925 } else {
1926 goto found;
1930 /* not found: create new section */
1931 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1932 /* take as much info as possible from the section. sh_link and
1933 sh_info will be updated later */
1934 s->sh_addralign = sh->sh_addralign;
1935 s->sh_entsize = sh->sh_entsize;
1936 sm_table[i].new_section = 1;
1937 found:
1938 if (sh->sh_type != s->sh_type) {
1939 error_noabort("invalid section type");
1940 goto fail;
1943 /* align start of section */
1944 offset = s->data_offset;
1946 if (0 == strcmp(sh_name, ".stab")) {
1947 stab_index = i;
1948 goto no_align;
1950 if (0 == strcmp(sh_name, ".stabstr")) {
1951 stabstr_index = i;
1952 goto no_align;
1955 size = sh->sh_addralign - 1;
1956 offset = (offset + size) & ~size;
1957 if (sh->sh_addralign > s->sh_addralign)
1958 s->sh_addralign = sh->sh_addralign;
1959 s->data_offset = offset;
1960 no_align:
1961 sm_table[i].offset = offset;
1962 sm_table[i].s = s;
1963 /* concatenate sections */
1964 size = sh->sh_size;
1965 if (sh->sh_type != SHT_NOBITS) {
1966 unsigned char *ptr;
1967 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1968 ptr = section_ptr_add(s, size);
1969 read(fd, ptr, size);
1970 } else {
1971 s->data_offset += size;
1973 next: ;
1976 /* //gr relocate stab strings */
1977 if (stab_index && stabstr_index) {
1978 Stab_Sym *a, *b;
1979 unsigned o;
1980 s = sm_table[stab_index].s;
1981 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
1982 b = (Stab_Sym *)(s->data + s->data_offset);
1983 o = sm_table[stabstr_index].offset;
1984 while (a < b)
1985 a->n_strx += o, a++;
1988 /* second short pass to update sh_link and sh_info fields of new
1989 sections */
1990 for(i = 1; i < ehdr.e_shnum; i++) {
1991 s = sm_table[i].s;
1992 if (!s || !sm_table[i].new_section)
1993 continue;
1994 sh = &shdr[i];
1995 if (sh->sh_link > 0)
1996 s->link = sm_table[sh->sh_link].s;
1997 if (sh->sh_type == SHT_REL) {
1998 s->sh_info = sm_table[sh->sh_info].s->sh_num;
1999 /* update backward link */
2000 s1->sections[s->sh_info]->reloc = s;
2003 sm = sm_table;
2005 /* resolve symbols */
2006 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2008 sym = symtab + 1;
2009 for(i = 1; i < nb_syms; i++, sym++) {
2010 if (sym->st_shndx != SHN_UNDEF &&
2011 sym->st_shndx < SHN_LORESERVE) {
2012 sm = &sm_table[sym->st_shndx];
2013 if (sm->link_once) {
2014 /* if a symbol is in a link once section, we use the
2015 already defined symbol. It is very important to get
2016 correct relocations */
2017 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
2018 name = strtab + sym->st_name;
2019 sym_index = find_elf_sym(symtab_section, name);
2020 if (sym_index)
2021 old_to_new_syms[i] = sym_index;
2023 continue;
2025 /* if no corresponding section added, no need to add symbol */
2026 if (!sm->s)
2027 continue;
2028 /* convert section number */
2029 sym->st_shndx = sm->s->sh_num;
2030 /* offset value */
2031 sym->st_value += sm->offset;
2033 /* add symbol */
2034 name = strtab + sym->st_name;
2035 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
2036 sym->st_info, sym->st_other,
2037 sym->st_shndx, name);
2038 old_to_new_syms[i] = sym_index;
2041 /* third pass to patch relocation entries */
2042 for(i = 1; i < ehdr.e_shnum; i++) {
2043 s = sm_table[i].s;
2044 if (!s)
2045 continue;
2046 sh = &shdr[i];
2047 offset = sm_table[i].offset;
2048 switch(s->sh_type) {
2049 case SHT_REL:
2050 /* take relocation offset information */
2051 offseti = sm_table[sh->sh_info].offset;
2052 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
2053 for(rel = (Elf32_Rel *)(s->data + offset);
2054 rel < rel_end;
2055 rel++) {
2056 int type;
2057 unsigned sym_index;
2058 /* convert symbol index */
2059 type = ELF32_R_TYPE(rel->r_info);
2060 sym_index = ELF32_R_SYM(rel->r_info);
2061 /* NOTE: only one symtab assumed */
2062 if (sym_index >= nb_syms)
2063 goto invalid_reloc;
2064 sym_index = old_to_new_syms[sym_index];
2065 /* ignore link_once in rel section. */
2066 if (!sym_index && !sm->link_once) {
2067 invalid_reloc:
2068 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2069 i, strsec + sh->sh_name, rel->r_offset);
2070 goto fail;
2072 rel->r_info = ELF32_R_INFO(sym_index, type);
2073 /* offset the relocation offset */
2074 rel->r_offset += offseti;
2076 break;
2077 default:
2078 break;
2082 ret = 0;
2083 the_end:
2084 tcc_free(symtab);
2085 tcc_free(strtab);
2086 tcc_free(old_to_new_syms);
2087 tcc_free(sm_table);
2088 tcc_free(strsec);
2089 tcc_free(shdr);
2090 return ret;
2093 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2095 typedef struct ArchiveHeader {
2096 char ar_name[16]; /* name of this member */
2097 char ar_date[12]; /* file mtime */
2098 char ar_uid[6]; /* owner uid; printed as decimal */
2099 char ar_gid[6]; /* owner gid; printed as decimal */
2100 char ar_mode[8]; /* file mode, printed as octal */
2101 char ar_size[10]; /* file size, printed as decimal */
2102 char ar_fmag[2]; /* should contain ARFMAG */
2103 } ArchiveHeader;
2105 static int get_be32(const uint8_t *b)
2107 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2110 /* load only the objects which resolve undefined symbols */
2111 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
2113 int i, bound, nsyms, sym_index, off, ret;
2114 uint8_t *data;
2115 const char *ar_names, *p;
2116 const uint8_t *ar_index;
2117 Elf32_Sym *sym;
2119 data = tcc_malloc(size);
2120 if (read(fd, data, size) != size)
2121 goto fail;
2122 nsyms = get_be32(data);
2123 ar_index = data + 4;
2124 ar_names = ar_index + nsyms * 4;
2126 do {
2127 bound = 0;
2128 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2129 sym_index = find_elf_sym(symtab_section, p);
2130 if(sym_index) {
2131 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
2132 if(sym->st_shndx == SHN_UNDEF) {
2133 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2134 #if 0
2135 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2136 #endif
2137 ++bound;
2138 lseek(fd, off, SEEK_SET);
2139 if(tcc_load_object_file(s1, fd, off) < 0) {
2140 fail:
2141 ret = -1;
2142 goto the_end;
2147 } while(bound);
2148 ret = 0;
2149 the_end:
2150 tcc_free(data);
2151 return ret;
2154 /* load a '.a' file */
2155 static int tcc_load_archive(TCCState *s1, int fd)
2157 ArchiveHeader hdr;
2158 char ar_size[11];
2159 char ar_name[17];
2160 char magic[8];
2161 int size, len, i;
2162 unsigned long file_offset;
2164 /* skip magic which was already checked */
2165 read(fd, magic, sizeof(magic));
2167 for(;;) {
2168 len = read(fd, &hdr, sizeof(hdr));
2169 if (len == 0)
2170 break;
2171 if (len != sizeof(hdr)) {
2172 error_noabort("invalid archive");
2173 return -1;
2175 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2176 ar_size[sizeof(hdr.ar_size)] = '\0';
2177 size = strtol(ar_size, NULL, 0);
2178 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2179 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2180 if (ar_name[i] != ' ')
2181 break;
2183 ar_name[i + 1] = '\0';
2184 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2185 file_offset = lseek(fd, 0, SEEK_CUR);
2186 /* align to even */
2187 size = (size + 1) & ~1;
2188 if (!strcmp(ar_name, "/")) {
2189 /* coff symbol table : we handle it */
2190 if(s1->alacarte_link)
2191 return tcc_load_alacarte(s1, fd, size);
2192 } else if (!strcmp(ar_name, "//") ||
2193 !strcmp(ar_name, "__.SYMDEF") ||
2194 !strcmp(ar_name, "__.SYMDEF/") ||
2195 !strcmp(ar_name, "ARFILENAMES/")) {
2196 /* skip symbol table or archive names */
2197 } else {
2198 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2199 return -1;
2201 lseek(fd, file_offset + size, SEEK_SET);
2203 return 0;
2206 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2207 is referenced by the user (so it should be added as DT_NEEDED in
2208 the generated ELF file) */
2209 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2211 Elf32_Ehdr ehdr;
2212 Elf32_Shdr *shdr, *sh, *sh1;
2213 int i, j, nb_syms, nb_dts, sym_bind, ret;
2214 Elf32_Sym *sym, *dynsym;
2215 Elf32_Dyn *dt, *dynamic;
2216 unsigned char *dynstr;
2217 const char *name, *soname;
2218 DLLReference *dllref;
2220 read(fd, &ehdr, sizeof(ehdr));
2222 /* test CPU specific stuff */
2223 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2224 ehdr.e_machine != EM_TCC_TARGET) {
2225 error_noabort("bad architecture");
2226 return -1;
2229 /* read sections */
2230 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
2232 /* load dynamic section and dynamic symbols */
2233 nb_syms = 0;
2234 nb_dts = 0;
2235 dynamic = NULL;
2236 dynsym = NULL; /* avoid warning */
2237 dynstr = NULL; /* avoid warning */
2238 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2239 switch(sh->sh_type) {
2240 case SHT_DYNAMIC:
2241 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
2242 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2243 break;
2244 case SHT_DYNSYM:
2245 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
2246 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2247 sh1 = &shdr[sh->sh_link];
2248 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2249 break;
2250 default:
2251 break;
2255 /* compute the real library name */
2256 soname = tcc_basename(filename);
2258 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2259 if (dt->d_tag == DT_SONAME) {
2260 soname = dynstr + dt->d_un.d_val;
2264 /* if the dll is already loaded, do not load it */
2265 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2266 dllref = s1->loaded_dlls[i];
2267 if (!strcmp(soname, dllref->name)) {
2268 /* but update level if needed */
2269 if (level < dllref->level)
2270 dllref->level = level;
2271 ret = 0;
2272 goto the_end;
2276 // printf("loading dll '%s'\n", soname);
2278 /* add the dll and its level */
2279 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2280 dllref->level = level;
2281 strcpy(dllref->name, soname);
2282 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2284 /* add dynamic symbols in dynsym_section */
2285 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2286 sym_bind = ELF32_ST_BIND(sym->st_info);
2287 if (sym_bind == STB_LOCAL)
2288 continue;
2289 name = dynstr + sym->st_name;
2290 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2291 sym->st_info, sym->st_other, sym->st_shndx, name);
2294 /* load all referenced DLLs */
2295 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2296 switch(dt->d_tag) {
2297 case DT_NEEDED:
2298 name = dynstr + dt->d_un.d_val;
2299 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2300 dllref = s1->loaded_dlls[j];
2301 if (!strcmp(name, dllref->name))
2302 goto already_loaded;
2304 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2305 error_noabort("referenced dll '%s' not found", name);
2306 ret = -1;
2307 goto the_end;
2309 already_loaded:
2310 break;
2313 ret = 0;
2314 the_end:
2315 tcc_free(dynstr);
2316 tcc_free(dynsym);
2317 tcc_free(dynamic);
2318 tcc_free(shdr);
2319 return ret;
2322 #define LD_TOK_NAME 256
2323 #define LD_TOK_EOF (-1)
2325 /* return next ld script token */
2326 static int ld_next(TCCState *s1, char *name, int name_size)
2328 int c;
2329 char *q;
2331 redo:
2332 switch(ch) {
2333 case ' ':
2334 case '\t':
2335 case '\f':
2336 case '\v':
2337 case '\r':
2338 case '\n':
2339 inp();
2340 goto redo;
2341 case '/':
2342 minp();
2343 if (ch == '*') {
2344 file->buf_ptr = parse_comment(file->buf_ptr);
2345 ch = file->buf_ptr[0];
2346 goto redo;
2347 } else {
2348 q = name;
2349 *q++ = '/';
2350 goto parse_name;
2352 break;
2353 /* case 'a' ... 'z': */
2354 case 'a':
2355 case 'b':
2356 case 'c':
2357 case 'd':
2358 case 'e':
2359 case 'f':
2360 case 'g':
2361 case 'h':
2362 case 'i':
2363 case 'j':
2364 case 'k':
2365 case 'l':
2366 case 'm':
2367 case 'n':
2368 case 'o':
2369 case 'p':
2370 case 'q':
2371 case 'r':
2372 case 's':
2373 case 't':
2374 case 'u':
2375 case 'v':
2376 case 'w':
2377 case 'x':
2378 case 'y':
2379 case 'z':
2380 /* case 'A' ... 'z': */
2381 case 'A':
2382 case 'B':
2383 case 'C':
2384 case 'D':
2385 case 'E':
2386 case 'F':
2387 case 'G':
2388 case 'H':
2389 case 'I':
2390 case 'J':
2391 case 'K':
2392 case 'L':
2393 case 'M':
2394 case 'N':
2395 case 'O':
2396 case 'P':
2397 case 'Q':
2398 case 'R':
2399 case 'S':
2400 case 'T':
2401 case 'U':
2402 case 'V':
2403 case 'W':
2404 case 'X':
2405 case 'Y':
2406 case 'Z':
2407 case '_':
2408 case '\\':
2409 case '.':
2410 case '$':
2411 case '~':
2412 q = name;
2413 parse_name:
2414 for(;;) {
2415 if (!((ch >= 'a' && ch <= 'z') ||
2416 (ch >= 'A' && ch <= 'Z') ||
2417 (ch >= '0' && ch <= '9') ||
2418 strchr("/.-_+=$:\\,~", ch)))
2419 break;
2420 if ((q - name) < name_size - 1) {
2421 *q++ = ch;
2423 minp();
2425 *q = '\0';
2426 c = LD_TOK_NAME;
2427 break;
2428 case CH_EOF:
2429 c = LD_TOK_EOF;
2430 break;
2431 default:
2432 c = ch;
2433 inp();
2434 break;
2436 #if 0
2437 printf("tok=%c %d\n", c, c);
2438 if (c == LD_TOK_NAME)
2439 printf(" name=%s\n", name);
2440 #endif
2441 return c;
2444 static int ld_add_file_list(TCCState *s1, int as_needed)
2446 char filename[1024];
2447 int t, ret;
2449 t = ld_next(s1, filename, sizeof(filename));
2450 if (t != '(')
2451 expect("(");
2452 t = ld_next(s1, filename, sizeof(filename));
2453 for(;;) {
2454 if (t == LD_TOK_EOF) {
2455 error_noabort("unexpected end of file");
2456 return -1;
2457 } else if (t == ')') {
2458 break;
2459 } else if (t != LD_TOK_NAME) {
2460 error_noabort("filename expected");
2461 return -1;
2463 if (!strcmp(filename, "AS_NEEDED")) {
2464 ret = ld_add_file_list(s1, 1);
2465 if (ret)
2466 return ret;
2467 } else {
2468 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2469 if (!as_needed)
2470 tcc_add_file(s1, filename);
2472 t = ld_next(s1, filename, sizeof(filename));
2473 if (t == ',') {
2474 t = ld_next(s1, filename, sizeof(filename));
2477 return 0;
2480 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2481 files */
2482 static int tcc_load_ldscript(TCCState *s1)
2484 char cmd[64];
2485 char filename[1024];
2486 int t, ret;
2488 ch = file->buf_ptr[0];
2489 ch = handle_eob();
2490 for(;;) {
2491 t = ld_next(s1, cmd, sizeof(cmd));
2492 if (t == LD_TOK_EOF)
2493 return 0;
2494 else if (t != LD_TOK_NAME)
2495 return -1;
2496 if (!strcmp(cmd, "INPUT") ||
2497 !strcmp(cmd, "GROUP")) {
2498 ret = ld_add_file_list(s1, 0);
2499 if (ret)
2500 return ret;
2501 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2502 !strcmp(cmd, "TARGET")) {
2503 /* ignore some commands */
2504 t = ld_next(s1, cmd, sizeof(cmd));
2505 if (t != '(')
2506 expect("(");
2507 for(;;) {
2508 t = ld_next(s1, filename, sizeof(filename));
2509 if (t == LD_TOK_EOF) {
2510 error_noabort("unexpected end of file");
2511 return -1;
2512 } else if (t == ')') {
2513 break;
2516 } else {
2517 return -1;
2520 return 0;