computed goto test
[tinycc.git] / tccelf.c
bloba162e27a5ba6408661e92d12bcadc4243a8eeda1
1 /*
2 * ELF file handling for TCC
3 *
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program 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
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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 void *tcc_get_symbol(TCCState *s, 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 error("%s not defined", name);
165 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
166 return (void *)sym->st_value;
169 /* add an elf symbol : check if it is already defined and patch
170 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
171 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
172 int info, int sh_num, const char *name)
174 Elf32_Sym *esym;
175 int sym_bind, sym_index, sym_type, esym_bind;
177 sym_bind = ELF32_ST_BIND(info);
178 sym_type = ELF32_ST_TYPE(info);
180 if (sym_bind != STB_LOCAL) {
181 /* we search global or weak symbols */
182 sym_index = find_elf_sym(s, name);
183 if (!sym_index)
184 goto do_def;
185 esym = &((Elf32_Sym *)s->data)[sym_index];
186 if (esym->st_shndx != SHN_UNDEF) {
187 esym_bind = ELF32_ST_BIND(esym->st_info);
188 if (sh_num == SHN_UNDEF) {
189 /* ignore adding of undefined symbol if the
190 corresponding symbol is already defined */
191 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
192 /* global overrides weak, so patch */
193 goto do_patch;
194 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
195 /* weak is ignored if already global */
196 } else {
197 #if 0
198 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
199 sym_bind, sh_num, esym_bind, esym->st_shndx);
200 #endif
201 /* NOTE: we accept that two DLL define the same symbol */
202 if (s != tcc_state->dynsymtab_section)
203 error_noabort("'%s' defined twice", name);
205 } else {
206 do_patch:
207 esym->st_info = ELF32_ST_INFO(sym_bind, sym_type);
208 esym->st_shndx = sh_num;
209 esym->st_value = value;
210 esym->st_size = size;
212 } else {
213 do_def:
214 sym_index = put_elf_sym(s, value, size,
215 ELF32_ST_INFO(sym_bind, sym_type), 0,
216 sh_num, name);
218 return sym_index;
221 /* put relocation */
222 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
223 int type, int symbol)
225 char buf[256];
226 Section *sr;
227 Elf32_Rel *rel;
229 sr = s->reloc;
230 if (!sr) {
231 /* if no relocation section, create it */
232 snprintf(buf, sizeof(buf), ".rel%s", s->name);
233 /* if the symtab is allocated, then we consider the relocation
234 are also */
235 sr = new_section(tcc_state, buf, SHT_REL, symtab->sh_flags);
236 sr->sh_entsize = sizeof(Elf32_Rel);
237 sr->link = symtab;
238 sr->sh_info = s->sh_num;
239 s->reloc = sr;
241 rel = section_ptr_add(sr, sizeof(Elf32_Rel));
242 rel->r_offset = offset;
243 rel->r_info = ELF32_R_INFO(symbol, type);
246 /* put stab debug information */
248 typedef struct {
249 unsigned long n_strx; /* index into string table of name */
250 unsigned char n_type; /* type of symbol */
251 unsigned char n_other; /* misc info (usually empty) */
252 unsigned short n_desc; /* description field */
253 unsigned long n_value; /* value of symbol */
254 } Stab_Sym;
256 static void put_stabs(const char *str, int type, int other, int desc,
257 unsigned long value)
259 Stab_Sym *sym;
261 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
262 if (str) {
263 sym->n_strx = put_elf_str(stabstr_section, str);
264 } else {
265 sym->n_strx = 0;
267 sym->n_type = type;
268 sym->n_other = other;
269 sym->n_desc = desc;
270 sym->n_value = value;
273 static void put_stabs_r(const char *str, int type, int other, int desc,
274 unsigned long value, Section *sec, int sym_index)
276 put_stabs(str, type, other, desc, value);
277 put_elf_reloc(symtab_section, stab_section,
278 stab_section->data_offset - sizeof(unsigned long),
279 R_DATA_32, sym_index);
282 static void put_stabn(int type, int other, int desc, int value)
284 put_stabs(NULL, type, other, desc, value);
287 static void put_stabd(int type, int other, int desc)
289 put_stabs(NULL, type, other, desc, 0);
292 /* In an ELF file symbol table, the local symbols must appear below
293 the global and weak ones. Since TCC cannot sort it while generating
294 the code, we must do it after. All the relocation tables are also
295 modified to take into account the symbol table sorting */
296 static void sort_syms(TCCState *s1, Section *s)
298 int *old_to_new_syms;
299 Elf32_Sym *new_syms;
300 int nb_syms, i;
301 Elf32_Sym *p, *q;
302 Elf32_Rel *rel, *rel_end;
303 Section *sr;
304 int type, sym_index;
306 nb_syms = s->data_offset / sizeof(Elf32_Sym);
307 new_syms = tcc_malloc(nb_syms * sizeof(Elf32_Sym));
308 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
310 /* first pass for local symbols */
311 p = (Elf32_Sym *)s->data;
312 q = new_syms;
313 for(i = 0; i < nb_syms; i++) {
314 if (ELF32_ST_BIND(p->st_info) == STB_LOCAL) {
315 old_to_new_syms[i] = q - new_syms;
316 *q++ = *p;
318 p++;
320 /* save the number of local symbols in section header */
321 s->sh_info = q - new_syms;
323 /* then second pass for non local symbols */
324 p = (Elf32_Sym *)s->data;
325 for(i = 0; i < nb_syms; i++) {
326 if (ELF32_ST_BIND(p->st_info) != STB_LOCAL) {
327 old_to_new_syms[i] = q - new_syms;
328 *q++ = *p;
330 p++;
333 /* we copy the new symbols to the old */
334 memcpy(s->data, new_syms, nb_syms * sizeof(Elf32_Sym));
335 tcc_free(new_syms);
337 /* now we modify all the relocations */
338 for(i = 1; i < s1->nb_sections; i++) {
339 sr = s1->sections[i];
340 if (sr->sh_type == SHT_REL && sr->link == s) {
341 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
342 for(rel = (Elf32_Rel *)sr->data;
343 rel < rel_end;
344 rel++) {
345 sym_index = ELF32_R_SYM(rel->r_info);
346 type = ELF32_R_TYPE(rel->r_info);
347 sym_index = old_to_new_syms[sym_index];
348 rel->r_info = ELF32_R_INFO(sym_index, type);
353 tcc_free(old_to_new_syms);
356 /* relocate common symbols in the .bss section */
357 static void relocate_common_syms(void)
359 Elf32_Sym *sym, *sym_end;
360 unsigned long offset, align;
362 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
363 for(sym = (Elf32_Sym *)symtab_section->data + 1;
364 sym < sym_end;
365 sym++) {
366 if (sym->st_shndx == SHN_COMMON) {
367 /* align symbol */
368 align = sym->st_value;
369 offset = bss_section->data_offset;
370 offset = (offset + align - 1) & -align;
371 sym->st_value = offset;
372 sym->st_shndx = bss_section->sh_num;
373 offset += sym->st_size;
374 bss_section->data_offset = offset;
379 static void *resolve_sym(const char *sym)
381 return dlsym(NULL, sym);
384 /* relocate symbol table, resolve undefined symbols if do_resolve is
385 true and output error if undefined symbol. */
386 static void relocate_syms(TCCState *s1, int do_resolve)
388 Elf32_Sym *sym, *esym, *sym_end;
389 int sym_bind, sh_num, sym_index;
390 const char *name;
391 unsigned long addr;
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 sh_num = sym->st_shndx;
398 if (sh_num == SHN_UNDEF) {
399 name = strtab_section->data + sym->st_name;
400 if (do_resolve) {
401 name = symtab_section->link->data + sym->st_name;
402 addr = (unsigned long)resolve_sym(name);
403 if (addr) {
404 sym->st_value = addr;
405 goto found;
407 } else if (s1->dynsym) {
408 /* if dynamic symbol exist, then use it */
409 sym_index = find_elf_sym(s1->dynsym, name);
410 if (sym_index) {
411 esym = &((Elf32_Sym *)s1->dynsym->data)[sym_index];
412 sym->st_value = esym->st_value;
413 goto found;
416 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
417 it */
418 if (!strcmp(name, "_fp_hw"))
419 goto found;
420 /* only weak symbols are accepted to be undefined. Their
421 value is zero */
422 sym_bind = ELF32_ST_BIND(sym->st_info);
423 if (sym_bind == STB_WEAK) {
424 sym->st_value = 0;
425 } else {
426 error_noabort("undefined symbol '%s'", name);
428 } else if (sh_num < SHN_LORESERVE) {
429 /* add section base */
430 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
432 found: ;
436 /* relocate a given section (CPU dependant) */
437 static void relocate_section(TCCState *s1, Section *s)
439 Section *sr;
440 Elf32_Rel *rel, *rel_end, *qrel;
441 Elf32_Sym *sym;
442 int type, sym_index, esym_index;
443 unsigned char *ptr;
444 unsigned long val, addr;
446 sr = s->reloc;
447 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
448 qrel = (Elf32_Rel *)sr->data;
449 for(rel = qrel;
450 rel < rel_end;
451 rel++) {
452 ptr = s->data + rel->r_offset;
454 sym_index = ELF32_R_SYM(rel->r_info);
455 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
456 val = sym->st_value;
457 type = ELF32_R_TYPE(rel->r_info);
458 addr = s->sh_addr + rel->r_offset;
460 /* CPU specific */
461 switch(type) {
462 case R_386_32:
463 if (s1->output_type == TCC_OUTPUT_DLL) {
464 esym_index = s1->symtab_to_dynsym[sym_index];
465 qrel->r_offset = rel->r_offset;
466 if (esym_index) {
467 qrel->r_info = ELF32_R_INFO(esym_index, R_386_32);
468 qrel++;
469 break;
470 } else {
471 qrel->r_info = ELF32_R_INFO(0, R_386_RELATIVE);
472 qrel++;
475 *(int *)ptr += val;
476 break;
477 case R_386_PC32:
478 if (s1->output_type == TCC_OUTPUT_DLL) {
479 /* DLL relocation */
480 esym_index = s1->symtab_to_dynsym[sym_index];
481 if (esym_index) {
482 qrel->r_offset = rel->r_offset;
483 qrel->r_info = ELF32_R_INFO(esym_index, R_386_PC32);
484 qrel++;
485 break;
488 *(int *)ptr += val - addr;
489 break;
490 case R_386_PLT32:
491 *(int *)ptr += val - addr;
492 break;
493 case R_386_GLOB_DAT:
494 case R_386_JMP_SLOT:
495 *(int *)ptr = val;
496 break;
497 case R_386_GOTPC:
498 *(int *)ptr += s1->got->sh_addr - addr;
499 break;
500 case R_386_GOTOFF:
501 *(int *)ptr += val - s1->got->sh_addr;
502 break;
503 case R_386_GOT32:
504 /* we load the got offset */
505 *(int *)ptr += s1->got_offsets[sym_index];
506 break;
509 /* if the relocation is allocated, we change its symbol table */
510 if (sr->sh_flags & SHF_ALLOC)
511 sr->link = s1->dynsym;
514 /* relocate relocation table in 'sr' */
515 static void relocate_rel(TCCState *s1, Section *sr)
517 Section *s;
518 Elf32_Rel *rel, *rel_end;
520 s = s1->sections[sr->sh_info];
521 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
522 for(rel = (Elf32_Rel *)sr->data;
523 rel < rel_end;
524 rel++) {
525 rel->r_offset += s->sh_addr;
529 /* count the number of dynamic relocations so that we can reserve
530 their space */
531 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
533 Elf32_Rel *rel, *rel_end;
534 int sym_index, esym_index, type, count;
536 count = 0;
537 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
538 for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) {
539 sym_index = ELF32_R_SYM(rel->r_info);
540 type = ELF32_R_TYPE(rel->r_info);
541 switch(type) {
542 case R_386_32:
543 count++;
544 break;
545 case R_386_PC32:
546 esym_index = s1->symtab_to_dynsym[sym_index];
547 if (esym_index)
548 count++;
549 break;
550 default:
551 break;
554 if (count) {
555 /* allocate the section */
556 sr->sh_flags |= SHF_ALLOC;
557 sr->sh_size = count * sizeof(Elf32_Rel);
559 return count;
562 static void put_got_offset(TCCState *s1, int index, unsigned long val)
564 int n;
565 unsigned long *tab;
567 if (index >= s1->nb_got_offsets) {
568 /* find immediately bigger power of 2 and reallocate array */
569 n = 1;
570 while (index >= n)
571 n *= 2;
572 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
573 if (!tab)
574 error("memory full");
575 s1->got_offsets = tab;
576 memset(s1->got_offsets + s1->nb_got_offsets, 0,
577 (n - s1->nb_got_offsets) * sizeof(unsigned long));
578 s1->nb_got_offsets = n;
580 s1->got_offsets[index] = val;
583 /* XXX: suppress that */
584 static void put32(unsigned char *p, unsigned int val)
586 p[0] = val;
587 p[1] = val >> 8;
588 p[2] = val >> 16;
589 p[3] = val >> 24;
592 static void build_got(TCCState *s1)
594 unsigned char *ptr;
596 /* if no got, then create it */
597 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
598 s1->got->sh_entsize = 4;
599 add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
600 s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
601 ptr = section_ptr_add(s1->got, 3 * sizeof(int));
602 /* keep space for _DYNAMIC pointer, if present */
603 put32(ptr, 0);
604 /* two dummy got entries */
605 put32(ptr + 4, 0);
606 put32(ptr + 8, 0);
609 /* put a got entry corresponding to a symbol in symtab_section. 'size'
610 and 'info' can be modifed if more precise info comes from the DLL */
611 static void put_got_entry(TCCState *s1,
612 int reloc_type, unsigned long size, int info,
613 int sym_index)
615 int index;
616 const char *name;
617 Elf32_Sym *sym;
618 unsigned long offset;
619 int *ptr;
621 if (!s1->got)
622 build_got(s1);
624 /* if a got entry already exists for that symbol, no need to add one */
625 if (sym_index < s1->nb_got_offsets &&
626 s1->got_offsets[sym_index] != 0)
627 return;
629 put_got_offset(s1, sym_index, s1->got->data_offset);
631 if (s1->dynsym) {
632 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
633 name = symtab_section->link->data + sym->st_name;
634 offset = sym->st_value;
635 /* NOTE: we put temporarily the got offset */
636 if (reloc_type == R_386_JMP_SLOT) {
637 s1->nb_plt_entries++;
638 offset = s1->got->data_offset;
640 index = put_elf_sym(s1->dynsym, offset,
641 size, info, 0, sym->st_shndx, name);
642 /* put a got entry */
643 put_elf_reloc(s1->dynsym, s1->got,
644 s1->got->data_offset,
645 reloc_type, index);
647 ptr = section_ptr_add(s1->got, sizeof(int));
648 *ptr = 0;
651 /* build GOT and PLT entries */
652 static void build_got_entries(TCCState *s1)
654 Section *s, *symtab;
655 Elf32_Rel *rel, *rel_end;
656 Elf32_Sym *sym;
657 int i, type, reloc_type, sym_index;
659 for(i = 1; i < s1->nb_sections; i++) {
660 s = s1->sections[i];
661 if (s->sh_type != SHT_REL)
662 continue;
663 /* no need to handle got relocations */
664 if (s->link != symtab_section)
665 continue;
666 symtab = s->link;
667 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
668 for(rel = (Elf32_Rel *)s->data;
669 rel < rel_end;
670 rel++) {
671 type = ELF32_R_TYPE(rel->r_info);
672 switch(type) {
673 case R_386_GOT32:
674 case R_386_GOTOFF:
675 case R_386_GOTPC:
676 case R_386_PLT32:
677 if (!s1->got)
678 build_got(s1);
679 if (type == R_386_GOT32 || type == R_386_PLT32) {
680 sym_index = ELF32_R_SYM(rel->r_info);
681 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
682 /* look at the symbol got offset. If none, then add one */
683 if (type == R_386_GOT32)
684 reloc_type = R_386_GLOB_DAT;
685 else
686 reloc_type = R_386_JMP_SLOT;
687 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
688 sym_index);
690 break;
691 default:
692 break;
698 static Section *new_symtab(TCCState *s1,
699 const char *symtab_name, int sh_type, int sh_flags,
700 const char *strtab_name,
701 const char *hash_name, int hash_sh_flags)
703 Section *symtab, *strtab, *hash;
704 int *ptr, nb_buckets;
706 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
707 symtab->sh_entsize = sizeof(Elf32_Sym);
708 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
709 put_elf_str(strtab, "");
710 symtab->link = strtab;
711 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
713 nb_buckets = 1;
715 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
716 hash->sh_entsize = sizeof(int);
717 symtab->hash = hash;
718 hash->link = symtab;
720 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
721 ptr[0] = nb_buckets;
722 ptr[1] = 1;
723 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
724 return symtab;
727 /* put dynamic tag */
728 static void put_dt(Section *dynamic, int dt, unsigned long val)
730 Elf32_Dyn *dyn;
731 dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
732 dyn->d_tag = dt;
733 dyn->d_un.d_val = val;
736 /* add tcc runtime libraries */
737 static void tcc_add_runtime(TCCState *s1)
739 char buf[1024];
740 int i;
741 Section *s;
743 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.o");
744 tcc_add_file(s1, buf);
745 #ifdef CONFIG_TCC_BCHECK
746 if (do_bounds_check) {
747 unsigned long *ptr;
748 Section *init_section;
749 unsigned char *pinit;
750 int sym_index;
752 /* XXX: add an object file to do that */
753 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
754 *ptr = 0;
755 add_elf_sym(symtab_section, 0, 0,
756 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
757 bounds_section->sh_num, "__bounds_start");
758 /* add bound check code */
759 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
760 tcc_add_file(s1, buf);
761 #ifdef TCC_TARGET_I386
762 if (s1->output_type != TCC_OUTPUT_MEMORY) {
763 /* add 'call __bound_init()' in .init section */
764 init_section = find_section(s1, ".init");
765 pinit = section_ptr_add(init_section, 5);
766 pinit[0] = 0xe8;
767 put32(pinit + 1, -4);
768 sym_index = find_elf_sym(symtab_section, "__bound_init");
769 put_elf_reloc(symtab_section, init_section,
770 init_section->data_offset - 4, R_386_PC32, sym_index);
772 #endif
774 #endif
775 /* add libc if not memory output */
776 if (s1->output_type != TCC_OUTPUT_MEMORY) {
777 tcc_add_library(s1, "c");
778 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
780 /* add various standard linker symbols */
781 add_elf_sym(symtab_section,
782 text_section->data_offset, 0,
783 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
784 text_section->sh_num, "_etext");
785 add_elf_sym(symtab_section,
786 data_section->data_offset, 0,
787 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
788 data_section->sh_num, "_edata");
789 add_elf_sym(symtab_section,
790 bss_section->data_offset, 0,
791 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
792 bss_section->sh_num, "_end");
793 /* add start and stop symbols for sections whose name can be
794 expressed in C */
795 for(i = 1; i < s1->nb_sections; i++) {
796 s = s1->sections[i];
797 if (s->sh_type == SHT_PROGBITS &&
798 (s->sh_flags & SHF_ALLOC)) {
799 const char *p;
800 int ch;
802 /* check if section name can be expressed in C */
803 p = s->name;
804 for(;;) {
805 ch = *p;
806 if (!ch)
807 break;
808 if (!isid(ch) && !isnum(ch))
809 goto next_sec;
810 p++;
812 snprintf(buf, sizeof(buf), "__start_%s", s->name);
813 add_elf_sym(symtab_section,
814 0, 0,
815 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
816 s->sh_num, buf);
817 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
818 add_elf_sym(symtab_section,
819 s->data_offset, 0,
820 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
821 s->sh_num, buf);
823 next_sec: ;
827 /* name of ELF interpreter */
828 static char elf_interp[] = "/lib/ld-linux.so.2";
830 #define ELF_START_ADDR 0x08048000
831 #define ELF_PAGE_SIZE 0x1000
833 /* output an ELF file */
834 /* XXX: suppress unneeded sections */
835 int tcc_output_file(TCCState *s1, const char *filename)
837 Elf32_Ehdr ehdr;
838 FILE *f;
839 int fd, mode, ret;
840 int *section_order;
841 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
842 unsigned long addr;
843 Section *strsec, *s;
844 Elf32_Shdr shdr, *sh;
845 Elf32_Phdr *phdr, *ph;
846 Section *interp, *plt, *dynamic, *dynstr;
847 unsigned long saved_dynamic_data_offset;
848 Elf32_Sym *sym;
849 int type, file_type;
850 unsigned long rel_addr, rel_size;
852 file_type = s1->output_type;
853 s1->nb_errors = 0;
855 if (file_type != TCC_OUTPUT_OBJ)
856 tcc_add_runtime(s1);
858 phdr = NULL;
859 section_order = NULL;
860 interp = NULL;
861 dynamic = NULL;
862 plt = NULL; /* avoid warning */
863 dynstr = NULL; /* avoid warning */
864 saved_dynamic_data_offset = 0; /* avoid warning */
866 if (file_type != TCC_OUTPUT_OBJ) {
868 relocate_common_syms();
870 if (!s1->static_link) {
871 const char *name;
872 int sym_index, index;
873 Elf32_Sym *esym, *sym_end;
875 if (file_type == TCC_OUTPUT_EXE) {
876 char *ptr;
877 /* add interpreter section only if executable */
878 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
879 interp->sh_addralign = 1;
880 ptr = section_ptr_add(interp, sizeof(elf_interp));
881 strcpy(ptr, elf_interp);
884 /* add dynamic symbol table */
885 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
886 ".dynstr",
887 ".hash", SHF_ALLOC);
888 dynstr = s1->dynsym->link;
890 /* add dynamic section */
891 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
892 SHF_ALLOC | SHF_WRITE);
893 dynamic->link = dynstr;
894 dynamic->sh_entsize = sizeof(Elf32_Dyn);
896 /* add PLT */
897 plt = new_section(s1, ".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
898 plt->sh_entsize = 4;
900 build_got(s1);
902 /* scan for undefined symbols and see if they are in the
903 dynamic symbols. If a symbol STT_FUNC is found, then we
904 add it in the PLT. If a symbol STT_OBJECT is found, we
905 add it in the .bss section with a suitable relocation */
906 sym_end = (Elf32_Sym *)(symtab_section->data +
907 symtab_section->data_offset);
908 if (file_type == TCC_OUTPUT_EXE) {
909 for(sym = (Elf32_Sym *)symtab_section->data + 1;
910 sym < sym_end;
911 sym++) {
912 if (sym->st_shndx == SHN_UNDEF) {
913 name = symtab_section->link->data + sym->st_name;
914 sym_index = find_elf_sym(s1->dynsymtab_section, name);
915 if (sym_index) {
916 esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
917 type = ELF32_ST_TYPE(esym->st_info);
918 if (type == STT_FUNC) {
919 put_got_entry(s1, R_386_JMP_SLOT, esym->st_size,
920 esym->st_info,
921 sym - (Elf32_Sym *)symtab_section->data);
922 } else if (type == STT_OBJECT) {
923 unsigned long offset;
924 offset = bss_section->data_offset;
925 /* XXX: which alignment ? */
926 offset = (offset + 8 - 1) & -8;
927 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
928 esym->st_info, 0,
929 bss_section->sh_num, name);
930 put_elf_reloc(s1->dynsym, bss_section,
931 offset, R_386_COPY, index);
932 offset += esym->st_size;
933 bss_section->data_offset = offset;
935 } else {
936 /* STB_WEAK undefined symbols are accepted */
937 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
938 it */
939 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
940 !strcmp(name, "_fp_hw")) {
941 } else {
942 error_noabort("undefined symbol '%s'", name);
948 if (s1->nb_errors)
949 goto fail;
951 /* now look at unresolved dynamic symbols and export
952 corresponding symbol */
953 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
954 s1->dynsymtab_section->data_offset);
955 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
956 esym < sym_end;
957 esym++) {
958 if (esym->st_shndx == SHN_UNDEF) {
959 name = s1->dynsymtab_section->link->data + esym->st_name;
960 sym_index = find_elf_sym(symtab_section, name);
961 if (sym_index) {
962 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
963 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
964 sym->st_info, 0,
965 sym->st_shndx, name);
966 } else {
967 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
968 /* weak symbols can stay undefined */
969 } else {
970 warning("undefined dynamic symbol '%s'", name);
975 } else {
976 int nb_syms;
977 /* shared library case : we simply export all the global symbols */
978 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
979 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
980 for(sym = (Elf32_Sym *)symtab_section->data + 1;
981 sym < sym_end;
982 sym++) {
983 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
984 name = symtab_section->link->data + sym->st_name;
985 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
986 sym->st_info, 0,
987 sym->st_shndx, name);
988 s1->symtab_to_dynsym[sym -
989 (Elf32_Sym *)symtab_section->data] =
990 index;
995 build_got_entries(s1);
997 /* update PLT/GOT sizes so that we can allocate their space */
998 plt->data_offset += 16 * (s1->nb_plt_entries + 1);
1000 /* add a list of needed dlls */
1001 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1002 DLLReference *dllref = s1->loaded_dlls[i];
1003 if (dllref->level == 0)
1004 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1006 /* XXX: currently, since we do not handle PIC code, we
1007 must relocate the readonly segments */
1008 if (file_type == TCC_OUTPUT_DLL)
1009 put_dt(dynamic, DT_TEXTREL, 0);
1011 /* add necessary space for other entries */
1012 saved_dynamic_data_offset = dynamic->data_offset;
1013 dynamic->data_offset += 8 * 9;
1014 } else {
1015 /* still need to build got entries in case of static link */
1016 build_got_entries(s1);
1020 memset(&ehdr, 0, sizeof(ehdr));
1022 /* we add a section for symbols */
1023 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1024 put_elf_str(strsec, "");
1026 /* compute number of sections */
1027 shnum = s1->nb_sections;
1029 /* this array is used to reorder sections in the output file */
1030 section_order = tcc_malloc(sizeof(int) * shnum);
1031 section_order[0] = 0;
1032 sh_order_index = 1;
1034 /* compute number of program headers */
1035 switch(file_type) {
1036 default:
1037 case TCC_OUTPUT_OBJ:
1038 phnum = 0;
1039 break;
1040 case TCC_OUTPUT_EXE:
1041 if (!s1->static_link)
1042 phnum = 4;
1043 else
1044 phnum = 2;
1045 break;
1046 case TCC_OUTPUT_DLL:
1047 phnum = 3;
1048 break;
1051 /* allocate strings for section names and decide if an unallocated
1052 section should be output */
1053 /* NOTE: the strsec section comes last, so its size is also
1054 correct ! */
1055 for(i = 1; i < s1->nb_sections; i++) {
1056 s = s1->sections[i];
1057 s->sh_name = put_elf_str(strsec, s->name);
1058 /* when generating a DLL, we include relocations but we may
1059 patch them */
1060 if (file_type == TCC_OUTPUT_DLL &&
1061 s->sh_type == SHT_REL &&
1062 !(s->sh_flags & SHF_ALLOC)) {
1063 prepare_dynamic_rel(s1, s);
1064 } else if (do_debug ||
1065 file_type == TCC_OUTPUT_OBJ ||
1066 (s->sh_flags & SHF_ALLOC) ||
1067 i == (s1->nb_sections - 1)) {
1068 /* we output all sections if debug or object file */
1069 s->sh_size = s->data_offset;
1073 /* allocate program segment headers */
1074 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1076 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1077 if (phnum > 0) {
1078 /* compute section to program header mapping */
1079 if (file_type == TCC_OUTPUT_DLL)
1080 addr = 0;
1081 else
1082 addr = ELF_START_ADDR;
1084 /* dynamic relocation table information, for .dynamic section */
1085 rel_size = 0;
1086 rel_addr = 0;
1088 /* compute address after headers */
1089 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1091 /* leave one program header for the program interpreter */
1092 ph = &phdr[0];
1093 if (interp)
1094 ph++;
1096 for(j = 0; j < 2; j++) {
1097 ph->p_type = PT_LOAD;
1098 if (j == 0)
1099 ph->p_flags = PF_R | PF_X;
1100 else
1101 ph->p_flags = PF_R | PF_W;
1102 ph->p_align = ELF_PAGE_SIZE;
1104 /* we do the following ordering: interp, symbol tables,
1105 relocations, progbits, nobits */
1106 /* XXX: do faster and simpler sorting */
1107 for(k = 0; k < 5; k++) {
1108 for(i = 1; i < s1->nb_sections; i++) {
1109 s = s1->sections[i];
1110 /* compute if section should be included */
1111 if (j == 0) {
1112 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1113 SHF_ALLOC)
1114 continue;
1115 } else {
1116 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1117 (SHF_ALLOC | SHF_WRITE))
1118 continue;
1120 if (s == interp) {
1121 if (k != 0)
1122 continue;
1123 } else if (s->sh_type == SHT_DYNSYM ||
1124 s->sh_type == SHT_STRTAB ||
1125 s->sh_type == SHT_HASH) {
1126 if (k != 1)
1127 continue;
1128 } else if (s->sh_type == SHT_REL) {
1129 if (k != 2)
1130 continue;
1131 } else if (s->sh_type == SHT_NOBITS) {
1132 if (k != 4)
1133 continue;
1134 } else {
1135 if (k != 3)
1136 continue;
1138 section_order[sh_order_index++] = i;
1140 /* section matches: we align it and add its size */
1141 tmp = file_offset;
1142 file_offset = (file_offset + s->sh_addralign - 1) &
1143 ~(s->sh_addralign - 1);
1144 s->sh_offset = file_offset;
1145 addr += file_offset - tmp;
1146 s->sh_addr = addr;
1148 /* update program header infos */
1149 if (ph->p_offset == 0) {
1150 ph->p_offset = file_offset;
1151 ph->p_vaddr = addr;
1152 ph->p_paddr = ph->p_vaddr;
1154 /* update dynamic relocation infos */
1155 if (s->sh_type == SHT_REL) {
1156 if (rel_size == 0)
1157 rel_addr = addr;
1158 rel_size += s->sh_size;
1160 addr += s->sh_size;
1161 if (s->sh_type != SHT_NOBITS)
1162 file_offset += s->sh_size;
1165 ph->p_filesz = file_offset - ph->p_offset;
1166 ph->p_memsz = addr - ph->p_vaddr;
1167 ph++;
1170 /* if interpreter, then add corresponing program header */
1171 if (interp) {
1172 ph = &phdr[0];
1174 ph->p_type = PT_INTERP;
1175 ph->p_offset = interp->sh_offset;
1176 ph->p_vaddr = interp->sh_addr;
1177 ph->p_paddr = ph->p_vaddr;
1178 ph->p_filesz = interp->sh_size;
1179 ph->p_memsz = interp->sh_size;
1180 ph->p_flags = PF_R;
1181 ph->p_align = interp->sh_addralign;
1184 /* if dynamic section, then add corresponing program header */
1185 if (dynamic) {
1186 int plt_offset;
1187 unsigned char *p;
1188 Elf32_Sym *sym_end;
1190 ph = &phdr[phnum - 1];
1192 ph->p_type = PT_DYNAMIC;
1193 ph->p_offset = dynamic->sh_offset;
1194 ph->p_vaddr = dynamic->sh_addr;
1195 ph->p_paddr = ph->p_vaddr;
1196 ph->p_filesz = dynamic->sh_size;
1197 ph->p_memsz = dynamic->sh_size;
1198 ph->p_flags = PF_R | PF_W;
1199 ph->p_align = dynamic->sh_addralign;
1201 /* put GOT dynamic section address */
1202 put32(s1->got->data, dynamic->sh_addr);
1204 /* compute the PLT */
1205 plt->data_offset = 0;
1207 /* first plt entry */
1208 p = section_ptr_add(plt, 16);
1209 p[0] = 0xff; /* pushl got + 4 */
1210 p[1] = 0x35;
1211 put32(p + 2, s1->got->sh_addr + 4);
1212 p[6] = 0xff; /* jmp *(got + 8) */
1213 p[7] = 0x25;
1214 put32(p + 8, s1->got->sh_addr + 8);
1216 /* relocation symbols in .dynsym and build PLT. */
1217 plt_offset = 0;
1218 sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
1219 for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
1220 sym < sym_end;
1221 sym++) {
1222 type = ELF32_ST_TYPE(sym->st_info);
1223 if (sym->st_shndx == SHN_UNDEF) {
1224 if (type == STT_FUNC) {
1225 /* one more entry in PLT */
1226 p = section_ptr_add(plt, 16);
1227 p[0] = 0xff; /* jmp *(got + x) */
1228 p[1] = 0x25;
1229 put32(p + 2, s1->got->sh_addr + sym->st_value);
1230 p[6] = 0x68; /* push $xxx */
1231 put32(p + 7, plt_offset);
1232 p[11] = 0xe9; /* jmp plt_start */
1233 put32(p + 12, -(plt->data_offset));
1235 /* patch symbol value to point to plt */
1236 sym->st_value = plt->sh_addr + p - plt->data;
1238 plt_offset += 8;
1240 } else if (sym->st_shndx < SHN_LORESERVE) {
1241 /* do symbol relocation */
1242 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1245 /* put dynamic section entries */
1247 dynamic->data_offset = saved_dynamic_data_offset;
1248 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1249 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1250 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1251 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1252 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
1253 put_dt(dynamic, DT_REL, rel_addr);
1254 put_dt(dynamic, DT_RELSZ, rel_size);
1255 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
1256 put_dt(dynamic, DT_NULL, 0);
1259 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1260 ehdr.e_phnum = phnum;
1261 ehdr.e_phoff = sizeof(Elf32_Ehdr);
1264 /* all other sections come after */
1265 for(i = 1; i < s1->nb_sections; i++) {
1266 s = s1->sections[i];
1267 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1268 continue;
1269 section_order[sh_order_index++] = i;
1271 file_offset = (file_offset + s->sh_addralign - 1) &
1272 ~(s->sh_addralign - 1);
1273 s->sh_offset = file_offset;
1274 if (s->sh_type != SHT_NOBITS)
1275 file_offset += s->sh_size;
1278 /* if building executable or DLL, then relocate each section
1279 except the GOT which is already relocated */
1280 if (file_type != TCC_OUTPUT_OBJ) {
1281 relocate_syms(s1, 0);
1283 if (s1->nb_errors != 0) {
1284 fail:
1285 ret = -1;
1286 goto the_end;
1289 /* relocate sections */
1290 /* XXX: ignore sections with allocated relocations ? */
1291 for(i = 1; i < s1->nb_sections; i++) {
1292 s = s1->sections[i];
1293 if (s->reloc && s != s1->got)
1294 relocate_section(s1, s);
1297 /* relocate relocation entries if the relocation tables are
1298 allocated in the executable */
1299 for(i = 1; i < s1->nb_sections; i++) {
1300 s = s1->sections[i];
1301 if ((s->sh_flags & SHF_ALLOC) &&
1302 s->sh_type == SHT_REL) {
1303 relocate_rel(s1, s);
1307 /* get entry point address */
1308 if (file_type == TCC_OUTPUT_EXE)
1309 ehdr.e_entry = (unsigned long)tcc_get_symbol(s1, "_start");
1310 else
1311 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1314 sort_syms(s1, symtab_section);
1316 /* align to 4 */
1317 file_offset = (file_offset + 3) & -4;
1319 /* fill header */
1320 ehdr.e_ident[0] = ELFMAG0;
1321 ehdr.e_ident[1] = ELFMAG1;
1322 ehdr.e_ident[2] = ELFMAG2;
1323 ehdr.e_ident[3] = ELFMAG3;
1324 ehdr.e_ident[4] = ELFCLASS32;
1325 ehdr.e_ident[5] = ELFDATA2LSB;
1326 ehdr.e_ident[6] = EV_CURRENT;
1327 switch(file_type) {
1328 default:
1329 case TCC_OUTPUT_EXE:
1330 ehdr.e_type = ET_EXEC;
1331 break;
1332 case TCC_OUTPUT_DLL:
1333 ehdr.e_type = ET_DYN;
1334 break;
1335 case TCC_OUTPUT_OBJ:
1336 ehdr.e_type = ET_REL;
1337 break;
1339 ehdr.e_machine = EM_386;
1340 ehdr.e_version = EV_CURRENT;
1341 ehdr.e_shoff = file_offset;
1342 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1343 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1344 ehdr.e_shnum = shnum;
1345 ehdr.e_shstrndx = shnum - 1;
1347 /* write elf file */
1348 if (file_type == TCC_OUTPUT_OBJ)
1349 mode = 0666;
1350 else
1351 mode = 0777;
1352 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
1353 if (fd < 0) {
1354 error_noabort("could not write '%s'", filename);
1355 goto fail;
1357 f = fdopen(fd, "w");
1358 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1359 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1360 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1361 for(i=1;i<s1->nb_sections;i++) {
1362 s = s1->sections[section_order[i]];
1363 if (s->sh_type != SHT_NOBITS) {
1364 while (offset < s->sh_offset) {
1365 fputc(0, f);
1366 offset++;
1368 size = s->sh_size;
1369 fwrite(s->data, 1, size, f);
1370 offset += size;
1373 while (offset < ehdr.e_shoff) {
1374 fputc(0, f);
1375 offset++;
1378 /* output section headers */
1379 for(i=0;i<s1->nb_sections;i++) {
1380 sh = &shdr;
1381 memset(sh, 0, sizeof(Elf32_Shdr));
1382 s = s1->sections[i];
1383 if (s) {
1384 sh->sh_name = s->sh_name;
1385 sh->sh_type = s->sh_type;
1386 sh->sh_flags = s->sh_flags;
1387 sh->sh_entsize = s->sh_entsize;
1388 sh->sh_info = s->sh_info;
1389 if (s->link)
1390 sh->sh_link = s->link->sh_num;
1391 sh->sh_addralign = s->sh_addralign;
1392 sh->sh_addr = s->sh_addr;
1393 sh->sh_offset = s->sh_offset;
1394 sh->sh_size = s->sh_size;
1396 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1398 fclose(f);
1400 ret = 0;
1401 the_end:
1402 tcc_free(s1->symtab_to_dynsym);
1403 tcc_free(section_order);
1404 tcc_free(phdr);
1405 tcc_free(s1->got_offsets);
1406 return ret;
1409 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1411 void *data;
1413 data = tcc_malloc(size);
1414 lseek(fd, file_offset, SEEK_SET);
1415 read(fd, data, size);
1416 return data;
1419 typedef struct SectionMergeInfo {
1420 Section *s; /* corresponding existing section */
1421 unsigned long offset; /* offset of the new section in the existing section */
1422 int new_section; /* true if section 's' was added */
1423 } SectionMergeInfo;
1425 /* load an object file and merge it with current files */
1426 /* XXX: handle correctly stab (debug) info */
1427 static int tcc_load_object_file(TCCState *s1,
1428 int fd, unsigned long file_offset)
1430 Elf32_Ehdr ehdr;
1431 Elf32_Shdr *shdr, *sh;
1432 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1433 unsigned char *strsec, *strtab;
1434 int *old_to_new_syms;
1435 char *sh_name, *name;
1436 SectionMergeInfo *sm_table, *sm;
1437 Elf32_Sym *sym, *symtab;
1438 Elf32_Rel *rel, *rel_end;
1439 Section *s;
1441 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1442 goto fail1;
1443 if (ehdr.e_ident[0] != ELFMAG0 ||
1444 ehdr.e_ident[1] != ELFMAG1 ||
1445 ehdr.e_ident[2] != ELFMAG2 ||
1446 ehdr.e_ident[3] != ELFMAG3)
1447 goto fail1;
1448 /* test if object file */
1449 if (ehdr.e_type != ET_REL)
1450 goto fail1;
1451 /* test CPU specific stuff */
1452 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1453 ehdr.e_machine != EM_386) {
1454 fail1:
1455 error_noabort("invalid object file");
1456 return -1;
1458 /* read sections */
1459 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1460 sizeof(Elf32_Shdr) * ehdr.e_shnum);
1461 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1463 /* load section names */
1464 sh = &shdr[ehdr.e_shstrndx];
1465 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1467 /* load symtab and strtab */
1468 old_to_new_syms = NULL;
1469 symtab = NULL;
1470 strtab = NULL;
1471 nb_syms = 0;
1472 for(i = 1; i < ehdr.e_shnum; i++) {
1473 sh = &shdr[i];
1474 if (sh->sh_type == SHT_SYMTAB) {
1475 if (symtab) {
1476 error_noabort("object must contain only one symtab");
1477 fail:
1478 ret = -1;
1479 goto the_end;
1481 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1482 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1483 sm_table[i].s = symtab_section;
1485 /* now load strtab */
1486 sh = &shdr[sh->sh_link];
1487 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1491 /* now examine each section and try to merge its content with the
1492 ones in memory */
1493 for(i = 1; i < ehdr.e_shnum; i++) {
1494 /* no need to examine section name strtab */
1495 if (i == ehdr.e_shstrndx)
1496 continue;
1497 sh = &shdr[i];
1498 sh_name = strsec + sh->sh_name;
1499 /* ignore sections types we do not handle */
1500 if (sh->sh_type != SHT_PROGBITS &&
1501 sh->sh_type != SHT_REL &&
1502 sh->sh_type != SHT_NOBITS)
1503 continue;
1504 if (sh->sh_addralign < 1)
1505 sh->sh_addralign = 1;
1506 /* find corresponding section, if any */
1507 for(j = 1; j < s1->nb_sections;j++) {
1508 s = s1->sections[j];
1509 if (!strcmp(s->name, sh_name))
1510 goto found;
1512 /* not found: create new section */
1513 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1514 /* take as much info as possible from the section. sh_link and
1515 sh_info will be updated later */
1516 s->sh_addralign = sh->sh_addralign;
1517 s->sh_entsize = sh->sh_entsize;
1518 sm_table[i].new_section = 1;
1519 found:
1520 if (sh->sh_type != s->sh_type) {
1521 error_noabort("invalid section type");
1522 goto fail;
1525 /* align start of section */
1526 offset = s->data_offset;
1527 size = sh->sh_addralign - 1;
1528 offset = (offset + size) & ~size;
1529 if (sh->sh_addralign > s->sh_addralign)
1530 s->sh_addralign = sh->sh_addralign;
1531 s->data_offset = offset;
1532 sm_table[i].offset = offset;
1533 sm_table[i].s = s;
1534 /* concatenate sections */
1535 size = sh->sh_size;
1536 if (sh->sh_type != SHT_NOBITS) {
1537 unsigned char *ptr;
1538 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1539 ptr = section_ptr_add(s, size);
1540 read(fd, ptr, size);
1541 } else {
1542 s->data_offset += size;
1546 /* second short pass to update sh_link and sh_info fields of new
1547 sections */
1548 sm = sm_table;
1549 for(i = 1; i < ehdr.e_shnum; i++) {
1550 s = sm_table[i].s;
1551 if (!s || !sm_table[i].new_section)
1552 continue;
1553 sh = &shdr[i];
1554 if (sh->sh_link > 0)
1555 s->link = sm_table[sh->sh_link].s;
1556 if (sh->sh_type == SHT_REL) {
1557 s->sh_info = sm_table[sh->sh_info].s->sh_num;
1558 /* update backward link */
1559 s1->sections[s->sh_info]->reloc = s;
1563 /* resolve symbols */
1564 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
1566 sym = symtab + 1;
1567 for(i = 1; i < nb_syms; i++, sym++) {
1568 if (sym->st_shndx != SHN_UNDEF &&
1569 sym->st_shndx < SHN_LORESERVE) {
1570 sm = &sm_table[sym->st_shndx];
1571 /* if no corresponding section added, no need to add symbol */
1572 if (!sm->s)
1573 continue;
1574 /* convert section number */
1575 sym->st_shndx = sm->s->sh_num;
1576 /* offset value */
1577 sym->st_value += sm->offset;
1579 /* add symbol */
1580 name = strtab + sym->st_name;
1581 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
1582 sym->st_info, sym->st_shndx, name);
1583 old_to_new_syms[i] = sym_index;
1586 /* third pass to patch relocation entries */
1587 for(i = 1; i < ehdr.e_shnum; i++) {
1588 s = sm_table[i].s;
1589 if (!s)
1590 continue;
1591 sh = &shdr[i];
1592 offset = sm_table[i].offset;
1593 switch(s->sh_type) {
1594 case SHT_REL:
1595 /* take relocation offset information */
1596 offseti = sm_table[sh->sh_info].offset;
1597 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
1598 for(rel = (Elf32_Rel *)(s->data + offset);
1599 rel < rel_end;
1600 rel++) {
1601 int type;
1602 unsigned sym_index;
1603 /* convert symbol index */
1604 type = ELF32_R_TYPE(rel->r_info);
1605 sym_index = ELF32_R_SYM(rel->r_info);
1606 /* NOTE: only one symtab assumed */
1607 if (sym_index >= nb_syms)
1608 goto invalid_reloc;
1609 sym_index = old_to_new_syms[sym_index];
1610 if (!sym_index) {
1611 invalid_reloc:
1612 error_noabort("Invalid relocation entry");
1613 goto fail;
1615 rel->r_info = ELF32_R_INFO(sym_index, type);
1616 /* offset the relocation offset */
1617 rel->r_offset += offseti;
1619 break;
1620 default:
1621 break;
1625 ret = 0;
1626 the_end:
1627 tcc_free(symtab);
1628 tcc_free(strtab);
1629 tcc_free(old_to_new_syms);
1630 tcc_free(sm_table);
1631 tcc_free(strsec);
1632 tcc_free(shdr);
1633 return ret;
1636 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1638 typedef struct ArchiveHeader {
1639 char ar_name[16]; /* name of this member */
1640 char ar_date[12]; /* file mtime */
1641 char ar_uid[6]; /* owner uid; printed as decimal */
1642 char ar_gid[6]; /* owner gid; printed as decimal */
1643 char ar_mode[8]; /* file mode, printed as octal */
1644 char ar_size[10]; /* file size, printed as decimal */
1645 char ar_fmag[2]; /* should contain ARFMAG */
1646 } ArchiveHeader;
1648 /* load a '.a' file */
1649 static int tcc_load_archive(TCCState *s1, int fd)
1651 ArchiveHeader hdr;
1652 char ar_size[11];
1653 char ar_name[17];
1654 char magic[8];
1655 int size, len, i;
1656 unsigned long file_offset;
1658 /* skip magic which was already checked */
1659 read(fd, magic, sizeof(magic));
1661 for(;;) {
1662 len = read(fd, &hdr, sizeof(hdr));
1663 if (len == 0)
1664 break;
1665 if (len != sizeof(hdr)) {
1666 error_noabort("invalid archive");
1667 return -1;
1669 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
1670 ar_size[sizeof(hdr.ar_size)] = '\0';
1671 size = strtol(ar_size, NULL, 0);
1672 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
1673 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
1674 if (ar_name[i] != ' ')
1675 break;
1677 ar_name[i + 1] = '\0';
1678 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
1679 file_offset = lseek(fd, 0, SEEK_CUR);
1680 if (!strcmp(ar_name, "/") ||
1681 !strcmp(ar_name, "//") ||
1682 !strcmp(ar_name, "__.SYMDEF") ||
1683 !strcmp(ar_name, "__.SYMDEF/") ||
1684 !strcmp(ar_name, "ARFILENAMES/")) {
1685 /* skip symbol table or archive names */
1686 } else {
1687 if (tcc_load_object_file(s1, fd, file_offset) < 0)
1688 return -1;
1690 /* align to even */
1691 size = (size + 1) & ~1;
1692 lseek(fd, file_offset + size, SEEK_SET);
1694 return 0;
1697 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
1698 is referenced by the user (so it should be added as DT_NEEDED in
1699 the generated ELF file) */
1700 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
1702 Elf32_Ehdr ehdr;
1703 Elf32_Shdr *shdr, *sh, *sh1;
1704 int i, nb_syms, nb_dts, sym_bind, ret;
1705 Elf32_Sym *sym, *dynsym;
1706 Elf32_Dyn *dt, *dynamic;
1707 unsigned char *dynstr;
1708 const char *name, *soname, *p;
1709 DLLReference *dllref;
1711 read(fd, &ehdr, sizeof(ehdr));
1713 /* test CPU specific stuff */
1714 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1715 ehdr.e_machine != EM_386) {
1716 error_noabort("bad architecture");
1717 return -1;
1720 /* read sections */
1721 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
1723 /* load dynamic section and dynamic symbols */
1724 nb_syms = 0;
1725 nb_dts = 0;
1726 dynamic = NULL;
1727 dynsym = NULL; /* avoid warning */
1728 dynstr = NULL; /* avoid warning */
1729 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
1730 switch(sh->sh_type) {
1731 case SHT_DYNAMIC:
1732 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
1733 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
1734 break;
1735 case SHT_DYNSYM:
1736 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1737 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
1738 sh1 = &shdr[sh->sh_link];
1739 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
1740 break;
1741 default:
1742 break;
1746 /* compute the real library name */
1747 soname = filename;
1748 p = strrchr(soname, '/');
1749 if (p)
1750 soname = p + 1;
1752 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
1753 if (dt->d_tag == DT_SONAME) {
1754 soname = dynstr + dt->d_un.d_val;
1758 /* if the dll is already loaded, do not load it */
1759 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1760 dllref = s1->loaded_dlls[i];
1761 if (!strcmp(soname, dllref->name)) {
1762 /* but update level if needed */
1763 if (level < dllref->level)
1764 dllref->level = level;
1765 ret = 0;
1766 goto the_end;
1770 // printf("loading dll '%s'\n", soname);
1772 /* add the dll and its level */
1773 dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
1774 dllref->level = level;
1775 strcpy(dllref->name, soname);
1776 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
1778 /* add dynamic symbols in dynsym_section */
1779 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
1780 sym_bind = ELF32_ST_BIND(sym->st_info);
1781 if (sym_bind == STB_LOCAL)
1782 continue;
1783 name = dynstr + sym->st_name;
1784 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
1785 sym->st_info, sym->st_shndx, name);
1788 /* load all referenced DLLs */
1789 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
1790 switch(dt->d_tag) {
1791 case DT_NEEDED:
1792 name = dynstr + dt->d_un.d_val;
1793 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1794 dllref = s1->loaded_dlls[i];
1795 if (!strcmp(name, dllref->name))
1796 goto already_loaded;
1798 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
1799 error_noabort("referenced dll '%s' not found", name);
1800 ret = -1;
1801 goto the_end;
1803 already_loaded:
1804 break;
1807 ret = 0;
1808 the_end:
1809 tcc_free(dynstr);
1810 tcc_free(dynsym);
1811 tcc_free(dynamic);
1812 tcc_free(shdr);
1813 return ret;
1816 /* return -2 if error and CH_EOF if eof */
1817 static void ld_skipspaces(void)
1819 while (ch == ' ' || ch == '\t' || ch == '\n')
1820 cinp();
1823 static int ld_get_cmd(char *cmd, int cmd_size)
1825 char *q;
1827 ld_skipspaces();
1828 if (ch == CH_EOF)
1829 return -1;
1830 q = cmd;
1831 for(;;) {
1832 if (!((ch >= 'a' && ch <= 'z') ||
1833 (ch >= 'A' && ch <= 'Z') ||
1834 (ch >= '0' && ch <= '9') ||
1835 strchr("/.-_+=$:\\,~?*", ch)))
1836 break;
1837 if ((q - cmd) >= (cmd_size - 1))
1838 return -2;
1839 *q++ = ch;
1840 cinp();
1842 *q = '\0';
1843 return 0;
1846 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
1847 files */
1848 static int tcc_load_ldscript(TCCState *s1)
1850 char cmd[64];
1851 char filename[1024];
1852 int ret;
1854 inp();
1855 cinp();
1856 for(;;) {
1857 ret = ld_get_cmd(cmd, sizeof(cmd));
1858 if (ret == CH_EOF)
1859 return 0;
1860 else if (ret < 0)
1861 return -1;
1862 // printf("cmd='%s'\n", cmd);
1863 if (!strcmp(cmd, "INPUT") ||
1864 !strcmp(cmd, "GROUP")) {
1865 ld_skipspaces();
1866 if (ch != '(')
1867 expect("(");
1868 cinp();
1869 for(;;) {
1870 ld_get_cmd(filename, sizeof(filename));
1871 tcc_add_file(s1, filename);
1872 ld_skipspaces();
1873 if (ch == ',') {
1874 cinp();
1875 } else if (ch == ')') {
1876 cinp();
1877 break;
1878 } else if (ch == CH_EOF) {
1879 error_noabort("unexpected end of file");
1880 return -1;
1883 } else {
1884 return -1;
1887 return 0;