update
[tinycc.git] / tccelf.c
blobc3167f0e2150ad9516d9d13a0ba877cfd42be48a
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(RTLD_DEFAULT, 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 dependent) */
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, uint32_t val)
586 p[0] = val;
587 p[1] = val >> 8;
588 p[2] = val >> 16;
589 p[3] = val >> 24;
592 static uint32_t get32(unsigned char *p)
594 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
597 static void build_got(TCCState *s1)
599 unsigned char *ptr;
601 /* if no got, then create it */
602 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
603 s1->got->sh_entsize = 4;
604 add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
605 s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
606 ptr = section_ptr_add(s1->got, 3 * sizeof(int));
607 /* keep space for _DYNAMIC pointer, if present */
608 put32(ptr, 0);
609 /* two dummy got entries */
610 put32(ptr + 4, 0);
611 put32(ptr + 8, 0);
614 /* put a got entry corresponding to a symbol in symtab_section. 'size'
615 and 'info' can be modifed if more precise info comes from the DLL */
616 static void put_got_entry(TCCState *s1,
617 int reloc_type, unsigned long size, int info,
618 int sym_index)
620 int index;
621 const char *name;
622 Elf32_Sym *sym;
623 unsigned long offset;
624 int *ptr;
626 if (!s1->got)
627 build_got(s1);
629 /* if a got entry already exists for that symbol, no need to add one */
630 if (sym_index < s1->nb_got_offsets &&
631 s1->got_offsets[sym_index] != 0)
632 return;
634 put_got_offset(s1, sym_index, s1->got->data_offset);
636 if (s1->dynsym) {
637 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
638 name = symtab_section->link->data + sym->st_name;
639 offset = sym->st_value;
640 if (reloc_type == R_386_JMP_SLOT) {
641 Section *plt;
642 uint8_t *p;
643 int modrm;
645 /* if we build a DLL, we add a %ebx offset */
646 if (s1->output_type == TCC_OUTPUT_DLL)
647 modrm = 0xa3;
648 else
649 modrm = 0x25;
651 /* add a PLT entry */
652 plt = s1->plt;
653 if (plt->data_offset == 0) {
654 /* first plt entry */
655 p = section_ptr_add(plt, 16);
656 p[0] = 0xff; /* pushl got + 4 */
657 p[1] = modrm + 0x10;
658 put32(p + 2, 4);
659 p[6] = 0xff; /* jmp *(got + 8) */
660 p[7] = modrm;
661 put32(p + 8, 8);
664 p = section_ptr_add(plt, 16);
665 p[0] = 0xff; /* jmp *(got + x) */
666 p[1] = modrm;
667 put32(p + 2, s1->got->data_offset);
668 p[6] = 0x68; /* push $xxx */
669 put32(p + 7, (plt->data_offset - 32) >> 1);
670 p[11] = 0xe9; /* jmp plt_start */
671 put32(p + 12, -(plt->data_offset));
673 /* the symbol is modified so that it will be relocated to
674 the PLT */
675 if (s1->output_type == TCC_OUTPUT_EXE)
676 offset = plt->data_offset - 16;
678 index = put_elf_sym(s1->dynsym, offset,
679 size, info, 0, sym->st_shndx, name);
680 /* put a got entry */
681 put_elf_reloc(s1->dynsym, s1->got,
682 s1->got->data_offset,
683 reloc_type, index);
685 ptr = section_ptr_add(s1->got, sizeof(int));
686 *ptr = 0;
689 /* build GOT and PLT entries */
690 static void build_got_entries(TCCState *s1)
692 Section *s, *symtab;
693 Elf32_Rel *rel, *rel_end;
694 Elf32_Sym *sym;
695 int i, type, reloc_type, sym_index;
697 for(i = 1; i < s1->nb_sections; i++) {
698 s = s1->sections[i];
699 if (s->sh_type != SHT_REL)
700 continue;
701 /* no need to handle got relocations */
702 if (s->link != symtab_section)
703 continue;
704 symtab = s->link;
705 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
706 for(rel = (Elf32_Rel *)s->data;
707 rel < rel_end;
708 rel++) {
709 type = ELF32_R_TYPE(rel->r_info);
710 switch(type) {
711 case R_386_GOT32:
712 case R_386_GOTOFF:
713 case R_386_GOTPC:
714 case R_386_PLT32:
715 if (!s1->got)
716 build_got(s1);
717 if (type == R_386_GOT32 || type == R_386_PLT32) {
718 sym_index = ELF32_R_SYM(rel->r_info);
719 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
720 /* look at the symbol got offset. If none, then add one */
721 if (type == R_386_GOT32)
722 reloc_type = R_386_GLOB_DAT;
723 else
724 reloc_type = R_386_JMP_SLOT;
725 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
726 sym_index);
728 break;
729 default:
730 break;
736 static Section *new_symtab(TCCState *s1,
737 const char *symtab_name, int sh_type, int sh_flags,
738 const char *strtab_name,
739 const char *hash_name, int hash_sh_flags)
741 Section *symtab, *strtab, *hash;
742 int *ptr, nb_buckets;
744 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
745 symtab->sh_entsize = sizeof(Elf32_Sym);
746 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
747 put_elf_str(strtab, "");
748 symtab->link = strtab;
749 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
751 nb_buckets = 1;
753 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
754 hash->sh_entsize = sizeof(int);
755 symtab->hash = hash;
756 hash->link = symtab;
758 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
759 ptr[0] = nb_buckets;
760 ptr[1] = 1;
761 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
762 return symtab;
765 /* put dynamic tag */
766 static void put_dt(Section *dynamic, int dt, unsigned long val)
768 Elf32_Dyn *dyn;
769 dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
770 dyn->d_tag = dt;
771 dyn->d_un.d_val = val;
774 /* add tcc runtime libraries */
775 static void tcc_add_runtime(TCCState *s1)
777 char buf[1024];
778 int i;
779 Section *s;
781 if (!s1->nostdlib) {
782 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.o");
783 tcc_add_file(s1, buf);
785 #ifdef CONFIG_TCC_BCHECK
786 if (do_bounds_check) {
787 unsigned long *ptr;
788 Section *init_section;
789 unsigned char *pinit;
790 int sym_index;
792 /* XXX: add an object file to do that */
793 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
794 *ptr = 0;
795 add_elf_sym(symtab_section, 0, 0,
796 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
797 bounds_section->sh_num, "__bounds_start");
798 /* add bound check code */
799 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
800 tcc_add_file(s1, buf);
801 #ifdef TCC_TARGET_I386
802 if (s1->output_type != TCC_OUTPUT_MEMORY) {
803 /* add 'call __bound_init()' in .init section */
804 init_section = find_section(s1, ".init");
805 pinit = section_ptr_add(init_section, 5);
806 pinit[0] = 0xe8;
807 put32(pinit + 1, -4);
808 sym_index = find_elf_sym(symtab_section, "__bound_init");
809 put_elf_reloc(symtab_section, init_section,
810 init_section->data_offset - 4, R_386_PC32, sym_index);
812 #endif
814 #endif
815 /* add libc if not memory output */
816 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
817 tcc_add_library(s1, "c");
818 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
820 /* add various standard linker symbols */
821 add_elf_sym(symtab_section,
822 text_section->data_offset, 0,
823 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
824 text_section->sh_num, "_etext");
825 add_elf_sym(symtab_section,
826 data_section->data_offset, 0,
827 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
828 data_section->sh_num, "_edata");
829 add_elf_sym(symtab_section,
830 bss_section->data_offset, 0,
831 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
832 bss_section->sh_num, "_end");
833 /* add start and stop symbols for sections whose name can be
834 expressed in C */
835 for(i = 1; i < s1->nb_sections; i++) {
836 s = s1->sections[i];
837 if (s->sh_type == SHT_PROGBITS &&
838 (s->sh_flags & SHF_ALLOC)) {
839 const char *p;
840 int ch;
842 /* check if section name can be expressed in C */
843 p = s->name;
844 for(;;) {
845 ch = *p;
846 if (!ch)
847 break;
848 if (!isid(ch) && !isnum(ch))
849 goto next_sec;
850 p++;
852 snprintf(buf, sizeof(buf), "__start_%s", s->name);
853 add_elf_sym(symtab_section,
854 0, 0,
855 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
856 s->sh_num, buf);
857 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
858 add_elf_sym(symtab_section,
859 s->data_offset, 0,
860 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
861 s->sh_num, buf);
863 next_sec: ;
867 /* name of ELF interpreter */
868 #ifdef __FreeBSD__
869 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
870 #else
871 static char elf_interp[] = "/lib/ld-linux.so.2";
872 #endif
874 #define ELF_START_ADDR 0x08048000
875 #define ELF_PAGE_SIZE 0x1000
877 /* output an ELF file */
878 /* XXX: suppress unneeded sections */
879 int tcc_output_file(TCCState *s1, const char *filename)
881 Elf32_Ehdr ehdr;
882 FILE *f;
883 int fd, mode, ret;
884 int *section_order;
885 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
886 unsigned long addr;
887 Section *strsec, *s;
888 Elf32_Shdr shdr, *sh;
889 Elf32_Phdr *phdr, *ph;
890 Section *interp, *dynamic, *dynstr;
891 unsigned long saved_dynamic_data_offset;
892 Elf32_Sym *sym;
893 int type, file_type;
894 unsigned long rel_addr, rel_size;
896 file_type = s1->output_type;
897 s1->nb_errors = 0;
899 if (file_type != TCC_OUTPUT_OBJ)
900 tcc_add_runtime(s1);
902 phdr = NULL;
903 section_order = NULL;
904 interp = NULL;
905 dynamic = NULL;
906 dynstr = NULL; /* avoid warning */
907 saved_dynamic_data_offset = 0; /* avoid warning */
909 if (file_type != TCC_OUTPUT_OBJ) {
911 relocate_common_syms();
913 if (!s1->static_link) {
914 const char *name;
915 int sym_index, index;
916 Elf32_Sym *esym, *sym_end;
918 if (file_type == TCC_OUTPUT_EXE) {
919 char *ptr;
920 /* add interpreter section only if executable */
921 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
922 interp->sh_addralign = 1;
923 ptr = section_ptr_add(interp, sizeof(elf_interp));
924 strcpy(ptr, elf_interp);
927 /* add dynamic symbol table */
928 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
929 ".dynstr",
930 ".hash", SHF_ALLOC);
931 dynstr = s1->dynsym->link;
933 /* add dynamic section */
934 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
935 SHF_ALLOC | SHF_WRITE);
936 dynamic->link = dynstr;
937 dynamic->sh_entsize = sizeof(Elf32_Dyn);
939 /* add PLT */
940 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
941 SHF_ALLOC | SHF_EXECINSTR);
942 s1->plt->sh_entsize = 4;
944 build_got(s1);
946 /* scan for undefined symbols and see if they are in the
947 dynamic symbols. If a symbol STT_FUNC is found, then we
948 add it in the PLT. If a symbol STT_OBJECT is found, we
949 add it in the .bss section with a suitable relocation */
950 sym_end = (Elf32_Sym *)(symtab_section->data +
951 symtab_section->data_offset);
952 if (file_type == TCC_OUTPUT_EXE) {
953 for(sym = (Elf32_Sym *)symtab_section->data + 1;
954 sym < sym_end;
955 sym++) {
956 if (sym->st_shndx == SHN_UNDEF) {
957 name = symtab_section->link->data + sym->st_name;
958 sym_index = find_elf_sym(s1->dynsymtab_section, name);
959 if (sym_index) {
960 esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
961 type = ELF32_ST_TYPE(esym->st_info);
962 if (type == STT_FUNC) {
963 put_got_entry(s1, R_386_JMP_SLOT, esym->st_size,
964 esym->st_info,
965 sym - (Elf32_Sym *)symtab_section->data);
966 } else if (type == STT_OBJECT) {
967 unsigned long offset;
968 offset = bss_section->data_offset;
969 /* XXX: which alignment ? */
970 offset = (offset + 8 - 1) & -8;
971 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
972 esym->st_info, 0,
973 bss_section->sh_num, name);
974 put_elf_reloc(s1->dynsym, bss_section,
975 offset, R_386_COPY, index);
976 offset += esym->st_size;
977 bss_section->data_offset = offset;
979 } else {
980 /* STB_WEAK undefined symbols are accepted */
981 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
982 it */
983 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
984 !strcmp(name, "_fp_hw")) {
985 } else {
986 error_noabort("undefined symbol '%s'", name);
992 if (s1->nb_errors)
993 goto fail;
995 /* now look at unresolved dynamic symbols and export
996 corresponding symbol */
997 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
998 s1->dynsymtab_section->data_offset);
999 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
1000 esym < sym_end;
1001 esym++) {
1002 if (esym->st_shndx == SHN_UNDEF) {
1003 name = s1->dynsymtab_section->link->data + esym->st_name;
1004 sym_index = find_elf_sym(symtab_section, name);
1005 if (sym_index) {
1006 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1007 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1008 sym->st_info, 0,
1009 sym->st_shndx, name);
1010 } else {
1011 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
1012 /* weak symbols can stay undefined */
1013 } else {
1014 warning("undefined dynamic symbol '%s'", name);
1019 } else {
1020 int nb_syms;
1021 /* shared library case : we simply export all the global symbols */
1022 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
1023 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1024 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1025 sym < sym_end;
1026 sym++) {
1027 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1028 name = symtab_section->link->data + sym->st_name;
1029 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1030 sym->st_info, 0,
1031 sym->st_shndx, name);
1032 s1->symtab_to_dynsym[sym -
1033 (Elf32_Sym *)symtab_section->data] =
1034 index;
1039 build_got_entries(s1);
1041 /* add a list of needed dlls */
1042 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1043 DLLReference *dllref = s1->loaded_dlls[i];
1044 if (dllref->level == 0)
1045 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1047 /* XXX: currently, since we do not handle PIC code, we
1048 must relocate the readonly segments */
1049 if (file_type == TCC_OUTPUT_DLL)
1050 put_dt(dynamic, DT_TEXTREL, 0);
1052 /* add necessary space for other entries */
1053 saved_dynamic_data_offset = dynamic->data_offset;
1054 dynamic->data_offset += 8 * 9;
1055 } else {
1056 /* still need to build got entries in case of static link */
1057 build_got_entries(s1);
1061 memset(&ehdr, 0, sizeof(ehdr));
1063 /* we add a section for symbols */
1064 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1065 put_elf_str(strsec, "");
1067 /* compute number of sections */
1068 shnum = s1->nb_sections;
1070 /* this array is used to reorder sections in the output file */
1071 section_order = tcc_malloc(sizeof(int) * shnum);
1072 section_order[0] = 0;
1073 sh_order_index = 1;
1075 /* compute number of program headers */
1076 switch(file_type) {
1077 default:
1078 case TCC_OUTPUT_OBJ:
1079 phnum = 0;
1080 break;
1081 case TCC_OUTPUT_EXE:
1082 if (!s1->static_link)
1083 phnum = 4;
1084 else
1085 phnum = 2;
1086 break;
1087 case TCC_OUTPUT_DLL:
1088 phnum = 3;
1089 break;
1092 /* allocate strings for section names and decide if an unallocated
1093 section should be output */
1094 /* NOTE: the strsec section comes last, so its size is also
1095 correct ! */
1096 for(i = 1; i < s1->nb_sections; i++) {
1097 s = s1->sections[i];
1098 s->sh_name = put_elf_str(strsec, s->name);
1099 /* when generating a DLL, we include relocations but we may
1100 patch them */
1101 if (file_type == TCC_OUTPUT_DLL &&
1102 s->sh_type == SHT_REL &&
1103 !(s->sh_flags & SHF_ALLOC)) {
1104 prepare_dynamic_rel(s1, s);
1105 } else if (do_debug ||
1106 file_type == TCC_OUTPUT_OBJ ||
1107 (s->sh_flags & SHF_ALLOC) ||
1108 i == (s1->nb_sections - 1)) {
1109 /* we output all sections if debug or object file */
1110 s->sh_size = s->data_offset;
1114 /* allocate program segment headers */
1115 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1117 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1118 if (phnum > 0) {
1119 /* compute section to program header mapping */
1120 if (file_type == TCC_OUTPUT_DLL)
1121 addr = 0;
1122 else
1123 addr = ELF_START_ADDR;
1125 /* dynamic relocation table information, for .dynamic section */
1126 rel_size = 0;
1127 rel_addr = 0;
1129 /* compute address after headers */
1130 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1132 /* leave one program header for the program interpreter */
1133 ph = &phdr[0];
1134 if (interp)
1135 ph++;
1137 for(j = 0; j < 2; j++) {
1138 ph->p_type = PT_LOAD;
1139 if (j == 0)
1140 ph->p_flags = PF_R | PF_X;
1141 else
1142 ph->p_flags = PF_R | PF_W;
1143 ph->p_align = ELF_PAGE_SIZE;
1145 /* we do the following ordering: interp, symbol tables,
1146 relocations, progbits, nobits */
1147 /* XXX: do faster and simpler sorting */
1148 for(k = 0; k < 5; k++) {
1149 for(i = 1; i < s1->nb_sections; i++) {
1150 s = s1->sections[i];
1151 /* compute if section should be included */
1152 if (j == 0) {
1153 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1154 SHF_ALLOC)
1155 continue;
1156 } else {
1157 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1158 (SHF_ALLOC | SHF_WRITE))
1159 continue;
1161 if (s == interp) {
1162 if (k != 0)
1163 continue;
1164 } else if (s->sh_type == SHT_DYNSYM ||
1165 s->sh_type == SHT_STRTAB ||
1166 s->sh_type == SHT_HASH) {
1167 if (k != 1)
1168 continue;
1169 } else if (s->sh_type == SHT_REL) {
1170 if (k != 2)
1171 continue;
1172 } else if (s->sh_type == SHT_NOBITS) {
1173 if (k != 4)
1174 continue;
1175 } else {
1176 if (k != 3)
1177 continue;
1179 section_order[sh_order_index++] = i;
1181 /* section matches: we align it and add its size */
1182 tmp = file_offset;
1183 file_offset = (file_offset + s->sh_addralign - 1) &
1184 ~(s->sh_addralign - 1);
1185 s->sh_offset = file_offset;
1186 addr += file_offset - tmp;
1187 s->sh_addr = addr;
1189 /* update program header infos */
1190 if (ph->p_offset == 0) {
1191 ph->p_offset = file_offset;
1192 ph->p_vaddr = addr;
1193 ph->p_paddr = ph->p_vaddr;
1195 /* update dynamic relocation infos */
1196 if (s->sh_type == SHT_REL) {
1197 if (rel_size == 0)
1198 rel_addr = addr;
1199 rel_size += s->sh_size;
1201 addr += s->sh_size;
1202 if (s->sh_type != SHT_NOBITS)
1203 file_offset += s->sh_size;
1206 ph->p_filesz = file_offset - ph->p_offset;
1207 ph->p_memsz = addr - ph->p_vaddr;
1208 ph++;
1209 /* if in the middle of a page, we duplicate the page in
1210 memory so that one copy is RX and the other is RW */
1211 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1212 addr += ELF_PAGE_SIZE;
1215 /* if interpreter, then add corresponing program header */
1216 if (interp) {
1217 ph = &phdr[0];
1219 ph->p_type = PT_INTERP;
1220 ph->p_offset = interp->sh_offset;
1221 ph->p_vaddr = interp->sh_addr;
1222 ph->p_paddr = ph->p_vaddr;
1223 ph->p_filesz = interp->sh_size;
1224 ph->p_memsz = interp->sh_size;
1225 ph->p_flags = PF_R;
1226 ph->p_align = interp->sh_addralign;
1229 /* if dynamic section, then add corresponing program header */
1230 if (dynamic) {
1231 Elf32_Sym *sym_end;
1233 ph = &phdr[phnum - 1];
1235 ph->p_type = PT_DYNAMIC;
1236 ph->p_offset = dynamic->sh_offset;
1237 ph->p_vaddr = dynamic->sh_addr;
1238 ph->p_paddr = ph->p_vaddr;
1239 ph->p_filesz = dynamic->sh_size;
1240 ph->p_memsz = dynamic->sh_size;
1241 ph->p_flags = PF_R | PF_W;
1242 ph->p_align = dynamic->sh_addralign;
1244 /* put GOT dynamic section address */
1245 put32(s1->got->data, dynamic->sh_addr);
1247 /* relocate the PLT */
1248 if (file_type == TCC_OUTPUT_EXE) {
1249 uint8_t *p, *p_end;
1251 p = s1->plt->data;
1252 p_end = p + s1->plt->data_offset;
1253 if (p < p_end) {
1254 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1255 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1256 p += 16;
1257 while (p < p_end) {
1258 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1259 p += 16;
1264 /* relocate symbols in .dynsym */
1265 sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
1266 for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
1267 sym < sym_end;
1268 sym++) {
1269 if (sym->st_shndx == SHN_UNDEF) {
1270 /* relocate to the PLT if the symbol corresponds
1271 to a PLT entry */
1272 if (sym->st_value)
1273 sym->st_value += s1->plt->sh_addr;
1274 } else if (sym->st_shndx < SHN_LORESERVE) {
1275 /* do symbol relocation */
1276 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1280 /* put dynamic section entries */
1281 dynamic->data_offset = saved_dynamic_data_offset;
1282 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1283 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1284 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1285 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1286 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
1287 put_dt(dynamic, DT_REL, rel_addr);
1288 put_dt(dynamic, DT_RELSZ, rel_size);
1289 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
1290 put_dt(dynamic, DT_NULL, 0);
1293 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1294 ehdr.e_phnum = phnum;
1295 ehdr.e_phoff = sizeof(Elf32_Ehdr);
1298 /* all other sections come after */
1299 for(i = 1; i < s1->nb_sections; i++) {
1300 s = s1->sections[i];
1301 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1302 continue;
1303 section_order[sh_order_index++] = i;
1305 file_offset = (file_offset + s->sh_addralign - 1) &
1306 ~(s->sh_addralign - 1);
1307 s->sh_offset = file_offset;
1308 if (s->sh_type != SHT_NOBITS)
1309 file_offset += s->sh_size;
1312 /* if building executable or DLL, then relocate each section
1313 except the GOT which is already relocated */
1314 if (file_type != TCC_OUTPUT_OBJ) {
1315 relocate_syms(s1, 0);
1317 if (s1->nb_errors != 0) {
1318 fail:
1319 ret = -1;
1320 goto the_end;
1323 /* relocate sections */
1324 /* XXX: ignore sections with allocated relocations ? */
1325 for(i = 1; i < s1->nb_sections; i++) {
1326 s = s1->sections[i];
1327 if (s->reloc && s != s1->got)
1328 relocate_section(s1, s);
1331 /* relocate relocation entries if the relocation tables are
1332 allocated in the executable */
1333 for(i = 1; i < s1->nb_sections; i++) {
1334 s = s1->sections[i];
1335 if ((s->sh_flags & SHF_ALLOC) &&
1336 s->sh_type == SHT_REL) {
1337 relocate_rel(s1, s);
1341 /* get entry point address */
1342 if (file_type == TCC_OUTPUT_EXE)
1343 ehdr.e_entry = (unsigned long)tcc_get_symbol(s1, "_start");
1344 else
1345 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1348 sort_syms(s1, symtab_section);
1350 /* align to 4 */
1351 file_offset = (file_offset + 3) & -4;
1353 /* fill header */
1354 ehdr.e_ident[0] = ELFMAG0;
1355 ehdr.e_ident[1] = ELFMAG1;
1356 ehdr.e_ident[2] = ELFMAG2;
1357 ehdr.e_ident[3] = ELFMAG3;
1358 ehdr.e_ident[4] = ELFCLASS32;
1359 ehdr.e_ident[5] = ELFDATA2LSB;
1360 ehdr.e_ident[6] = EV_CURRENT;
1361 #ifdef __FreeBSD__
1362 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1363 #endif
1364 switch(file_type) {
1365 default:
1366 case TCC_OUTPUT_EXE:
1367 ehdr.e_type = ET_EXEC;
1368 break;
1369 case TCC_OUTPUT_DLL:
1370 ehdr.e_type = ET_DYN;
1371 break;
1372 case TCC_OUTPUT_OBJ:
1373 ehdr.e_type = ET_REL;
1374 break;
1376 ehdr.e_machine = EM_386;
1377 ehdr.e_version = EV_CURRENT;
1378 ehdr.e_shoff = file_offset;
1379 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1380 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1381 ehdr.e_shnum = shnum;
1382 ehdr.e_shstrndx = shnum - 1;
1384 /* write elf file */
1385 if (file_type == TCC_OUTPUT_OBJ)
1386 mode = 0666;
1387 else
1388 mode = 0777;
1389 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
1390 if (fd < 0) {
1391 error_noabort("could not write '%s'", filename);
1392 goto fail;
1394 f = fdopen(fd, "w");
1395 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1396 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1397 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1398 for(i=1;i<s1->nb_sections;i++) {
1399 s = s1->sections[section_order[i]];
1400 if (s->sh_type != SHT_NOBITS) {
1401 while (offset < s->sh_offset) {
1402 fputc(0, f);
1403 offset++;
1405 size = s->sh_size;
1406 fwrite(s->data, 1, size, f);
1407 offset += size;
1410 while (offset < ehdr.e_shoff) {
1411 fputc(0, f);
1412 offset++;
1415 /* output section headers */
1416 for(i=0;i<s1->nb_sections;i++) {
1417 sh = &shdr;
1418 memset(sh, 0, sizeof(Elf32_Shdr));
1419 s = s1->sections[i];
1420 if (s) {
1421 sh->sh_name = s->sh_name;
1422 sh->sh_type = s->sh_type;
1423 sh->sh_flags = s->sh_flags;
1424 sh->sh_entsize = s->sh_entsize;
1425 sh->sh_info = s->sh_info;
1426 if (s->link)
1427 sh->sh_link = s->link->sh_num;
1428 sh->sh_addralign = s->sh_addralign;
1429 sh->sh_addr = s->sh_addr;
1430 sh->sh_offset = s->sh_offset;
1431 sh->sh_size = s->sh_size;
1433 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1435 fclose(f);
1437 ret = 0;
1438 the_end:
1439 tcc_free(s1->symtab_to_dynsym);
1440 tcc_free(section_order);
1441 tcc_free(phdr);
1442 tcc_free(s1->got_offsets);
1443 return ret;
1446 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1448 void *data;
1450 data = tcc_malloc(size);
1451 lseek(fd, file_offset, SEEK_SET);
1452 read(fd, data, size);
1453 return data;
1456 typedef struct SectionMergeInfo {
1457 Section *s; /* corresponding existing section */
1458 unsigned long offset; /* offset of the new section in the existing section */
1459 int new_section; /* true if section 's' was added */
1460 } SectionMergeInfo;
1462 /* load an object file and merge it with current files */
1463 /* XXX: handle correctly stab (debug) info */
1464 static int tcc_load_object_file(TCCState *s1,
1465 int fd, unsigned long file_offset)
1467 Elf32_Ehdr ehdr;
1468 Elf32_Shdr *shdr, *sh;
1469 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1470 unsigned char *strsec, *strtab;
1471 int *old_to_new_syms;
1472 char *sh_name, *name;
1473 SectionMergeInfo *sm_table, *sm;
1474 Elf32_Sym *sym, *symtab;
1475 Elf32_Rel *rel, *rel_end;
1476 Section *s;
1478 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1479 goto fail1;
1480 if (ehdr.e_ident[0] != ELFMAG0 ||
1481 ehdr.e_ident[1] != ELFMAG1 ||
1482 ehdr.e_ident[2] != ELFMAG2 ||
1483 ehdr.e_ident[3] != ELFMAG3)
1484 goto fail1;
1485 /* test if object file */
1486 if (ehdr.e_type != ET_REL)
1487 goto fail1;
1488 /* test CPU specific stuff */
1489 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1490 ehdr.e_machine != EM_386) {
1491 fail1:
1492 error_noabort("invalid object file");
1493 return -1;
1495 /* read sections */
1496 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1497 sizeof(Elf32_Shdr) * ehdr.e_shnum);
1498 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1500 /* load section names */
1501 sh = &shdr[ehdr.e_shstrndx];
1502 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1504 /* load symtab and strtab */
1505 old_to_new_syms = NULL;
1506 symtab = NULL;
1507 strtab = NULL;
1508 nb_syms = 0;
1509 for(i = 1; i < ehdr.e_shnum; i++) {
1510 sh = &shdr[i];
1511 if (sh->sh_type == SHT_SYMTAB) {
1512 if (symtab) {
1513 error_noabort("object must contain only one symtab");
1514 fail:
1515 ret = -1;
1516 goto the_end;
1518 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1519 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1520 sm_table[i].s = symtab_section;
1522 /* now load strtab */
1523 sh = &shdr[sh->sh_link];
1524 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1528 /* now examine each section and try to merge its content with the
1529 ones in memory */
1530 for(i = 1; i < ehdr.e_shnum; i++) {
1531 /* no need to examine section name strtab */
1532 if (i == ehdr.e_shstrndx)
1533 continue;
1534 sh = &shdr[i];
1535 sh_name = strsec + sh->sh_name;
1536 /* ignore sections types we do not handle */
1537 if (sh->sh_type != SHT_PROGBITS &&
1538 sh->sh_type != SHT_REL &&
1539 sh->sh_type != SHT_NOBITS)
1540 continue;
1541 if (sh->sh_addralign < 1)
1542 sh->sh_addralign = 1;
1543 /* find corresponding section, if any */
1544 for(j = 1; j < s1->nb_sections;j++) {
1545 s = s1->sections[j];
1546 if (!strcmp(s->name, sh_name))
1547 goto found;
1549 /* not found: create new section */
1550 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1551 /* take as much info as possible from the section. sh_link and
1552 sh_info will be updated later */
1553 s->sh_addralign = sh->sh_addralign;
1554 s->sh_entsize = sh->sh_entsize;
1555 sm_table[i].new_section = 1;
1556 found:
1557 if (sh->sh_type != s->sh_type) {
1558 error_noabort("invalid section type");
1559 goto fail;
1562 /* align start of section */
1563 offset = s->data_offset;
1564 size = sh->sh_addralign - 1;
1565 offset = (offset + size) & ~size;
1566 if (sh->sh_addralign > s->sh_addralign)
1567 s->sh_addralign = sh->sh_addralign;
1568 s->data_offset = offset;
1569 sm_table[i].offset = offset;
1570 sm_table[i].s = s;
1571 /* concatenate sections */
1572 size = sh->sh_size;
1573 if (sh->sh_type != SHT_NOBITS) {
1574 unsigned char *ptr;
1575 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1576 ptr = section_ptr_add(s, size);
1577 read(fd, ptr, size);
1578 } else {
1579 s->data_offset += size;
1583 /* second short pass to update sh_link and sh_info fields of new
1584 sections */
1585 sm = sm_table;
1586 for(i = 1; i < ehdr.e_shnum; i++) {
1587 s = sm_table[i].s;
1588 if (!s || !sm_table[i].new_section)
1589 continue;
1590 sh = &shdr[i];
1591 if (sh->sh_link > 0)
1592 s->link = sm_table[sh->sh_link].s;
1593 if (sh->sh_type == SHT_REL) {
1594 s->sh_info = sm_table[sh->sh_info].s->sh_num;
1595 /* update backward link */
1596 s1->sections[s->sh_info]->reloc = s;
1600 /* resolve symbols */
1601 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
1603 sym = symtab + 1;
1604 for(i = 1; i < nb_syms; i++, sym++) {
1605 if (sym->st_shndx != SHN_UNDEF &&
1606 sym->st_shndx < SHN_LORESERVE) {
1607 sm = &sm_table[sym->st_shndx];
1608 /* if no corresponding section added, no need to add symbol */
1609 if (!sm->s)
1610 continue;
1611 /* convert section number */
1612 sym->st_shndx = sm->s->sh_num;
1613 /* offset value */
1614 sym->st_value += sm->offset;
1616 /* add symbol */
1617 name = strtab + sym->st_name;
1618 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
1619 sym->st_info, sym->st_shndx, name);
1620 old_to_new_syms[i] = sym_index;
1623 /* third pass to patch relocation entries */
1624 for(i = 1; i < ehdr.e_shnum; i++) {
1625 s = sm_table[i].s;
1626 if (!s)
1627 continue;
1628 sh = &shdr[i];
1629 offset = sm_table[i].offset;
1630 switch(s->sh_type) {
1631 case SHT_REL:
1632 /* take relocation offset information */
1633 offseti = sm_table[sh->sh_info].offset;
1634 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
1635 for(rel = (Elf32_Rel *)(s->data + offset);
1636 rel < rel_end;
1637 rel++) {
1638 int type;
1639 unsigned sym_index;
1640 /* convert symbol index */
1641 type = ELF32_R_TYPE(rel->r_info);
1642 sym_index = ELF32_R_SYM(rel->r_info);
1643 /* NOTE: only one symtab assumed */
1644 if (sym_index >= nb_syms)
1645 goto invalid_reloc;
1646 sym_index = old_to_new_syms[sym_index];
1647 if (!sym_index) {
1648 invalid_reloc:
1649 error_noabort("Invalid relocation entry");
1650 goto fail;
1652 rel->r_info = ELF32_R_INFO(sym_index, type);
1653 /* offset the relocation offset */
1654 rel->r_offset += offseti;
1656 break;
1657 default:
1658 break;
1662 ret = 0;
1663 the_end:
1664 tcc_free(symtab);
1665 tcc_free(strtab);
1666 tcc_free(old_to_new_syms);
1667 tcc_free(sm_table);
1668 tcc_free(strsec);
1669 tcc_free(shdr);
1670 return ret;
1673 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1675 typedef struct ArchiveHeader {
1676 char ar_name[16]; /* name of this member */
1677 char ar_date[12]; /* file mtime */
1678 char ar_uid[6]; /* owner uid; printed as decimal */
1679 char ar_gid[6]; /* owner gid; printed as decimal */
1680 char ar_mode[8]; /* file mode, printed as octal */
1681 char ar_size[10]; /* file size, printed as decimal */
1682 char ar_fmag[2]; /* should contain ARFMAG */
1683 } ArchiveHeader;
1685 /* load a '.a' file */
1686 static int tcc_load_archive(TCCState *s1, int fd)
1688 ArchiveHeader hdr;
1689 char ar_size[11];
1690 char ar_name[17];
1691 char magic[8];
1692 int size, len, i;
1693 unsigned long file_offset;
1695 /* skip magic which was already checked */
1696 read(fd, magic, sizeof(magic));
1698 for(;;) {
1699 len = read(fd, &hdr, sizeof(hdr));
1700 if (len == 0)
1701 break;
1702 if (len != sizeof(hdr)) {
1703 error_noabort("invalid archive");
1704 return -1;
1706 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
1707 ar_size[sizeof(hdr.ar_size)] = '\0';
1708 size = strtol(ar_size, NULL, 0);
1709 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
1710 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
1711 if (ar_name[i] != ' ')
1712 break;
1714 ar_name[i + 1] = '\0';
1715 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
1716 file_offset = lseek(fd, 0, SEEK_CUR);
1717 if (!strcmp(ar_name, "/") ||
1718 !strcmp(ar_name, "//") ||
1719 !strcmp(ar_name, "__.SYMDEF") ||
1720 !strcmp(ar_name, "__.SYMDEF/") ||
1721 !strcmp(ar_name, "ARFILENAMES/")) {
1722 /* skip symbol table or archive names */
1723 } else {
1724 if (tcc_load_object_file(s1, fd, file_offset) < 0)
1725 return -1;
1727 /* align to even */
1728 size = (size + 1) & ~1;
1729 lseek(fd, file_offset + size, SEEK_SET);
1731 return 0;
1734 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
1735 is referenced by the user (so it should be added as DT_NEEDED in
1736 the generated ELF file) */
1737 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
1739 Elf32_Ehdr ehdr;
1740 Elf32_Shdr *shdr, *sh, *sh1;
1741 int i, nb_syms, nb_dts, sym_bind, ret;
1742 Elf32_Sym *sym, *dynsym;
1743 Elf32_Dyn *dt, *dynamic;
1744 unsigned char *dynstr;
1745 const char *name, *soname, *p;
1746 DLLReference *dllref;
1748 read(fd, &ehdr, sizeof(ehdr));
1750 /* test CPU specific stuff */
1751 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1752 ehdr.e_machine != EM_386) {
1753 error_noabort("bad architecture");
1754 return -1;
1757 /* read sections */
1758 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
1760 /* load dynamic section and dynamic symbols */
1761 nb_syms = 0;
1762 nb_dts = 0;
1763 dynamic = NULL;
1764 dynsym = NULL; /* avoid warning */
1765 dynstr = NULL; /* avoid warning */
1766 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
1767 switch(sh->sh_type) {
1768 case SHT_DYNAMIC:
1769 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
1770 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
1771 break;
1772 case SHT_DYNSYM:
1773 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1774 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
1775 sh1 = &shdr[sh->sh_link];
1776 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
1777 break;
1778 default:
1779 break;
1783 /* compute the real library name */
1784 soname = filename;
1785 p = strrchr(soname, '/');
1786 if (p)
1787 soname = p + 1;
1789 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
1790 if (dt->d_tag == DT_SONAME) {
1791 soname = dynstr + dt->d_un.d_val;
1795 /* if the dll is already loaded, do not load it */
1796 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1797 dllref = s1->loaded_dlls[i];
1798 if (!strcmp(soname, dllref->name)) {
1799 /* but update level if needed */
1800 if (level < dllref->level)
1801 dllref->level = level;
1802 ret = 0;
1803 goto the_end;
1807 // printf("loading dll '%s'\n", soname);
1809 /* add the dll and its level */
1810 dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
1811 dllref->level = level;
1812 strcpy(dllref->name, soname);
1813 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
1815 /* add dynamic symbols in dynsym_section */
1816 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
1817 sym_bind = ELF32_ST_BIND(sym->st_info);
1818 if (sym_bind == STB_LOCAL)
1819 continue;
1820 name = dynstr + sym->st_name;
1821 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
1822 sym->st_info, sym->st_shndx, name);
1825 /* load all referenced DLLs */
1826 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
1827 switch(dt->d_tag) {
1828 case DT_NEEDED:
1829 name = dynstr + dt->d_un.d_val;
1830 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1831 dllref = s1->loaded_dlls[i];
1832 if (!strcmp(name, dllref->name))
1833 goto already_loaded;
1835 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
1836 error_noabort("referenced dll '%s' not found", name);
1837 ret = -1;
1838 goto the_end;
1840 already_loaded:
1841 break;
1844 ret = 0;
1845 the_end:
1846 tcc_free(dynstr);
1847 tcc_free(dynsym);
1848 tcc_free(dynamic);
1849 tcc_free(shdr);
1850 return ret;
1853 #define LD_TOK_NAME 256
1854 #define LD_TOK_EOF (-1)
1856 /* return next ld script token */
1857 static int ld_next(TCCState *s1, char *name, int name_size)
1859 int c;
1860 char *q;
1862 redo:
1863 switch(ch) {
1864 case ' ':
1865 case '\t':
1866 case '\f':
1867 case '\v':
1868 case '\r':
1869 case '\n':
1870 inp();
1871 goto redo;
1872 case '/':
1873 minp();
1874 if (ch == '*') {
1875 file->buf_ptr = parse_comment(file->buf_ptr);
1876 ch = file->buf_ptr[0];
1877 goto redo;
1878 } else {
1879 q = name;
1880 *q++ = '/';
1881 goto parse_name;
1883 break;
1884 case 'a' ... 'z':
1885 case 'A' ... 'Z':
1886 case '_':
1887 case '\\':
1888 case '.':
1889 case '$':
1890 case '~':
1891 q = name;
1892 parse_name:
1893 for(;;) {
1894 if (!((ch >= 'a' && ch <= 'z') ||
1895 (ch >= 'A' && ch <= 'Z') ||
1896 (ch >= '0' && ch <= '9') ||
1897 strchr("/.-_+=$:\\,~", ch)))
1898 break;
1899 if ((q - name) < name_size - 1) {
1900 *q++ = ch;
1902 minp();
1904 *q = '\0';
1905 c = LD_TOK_NAME;
1906 break;
1907 case CH_EOF:
1908 c = LD_TOK_EOF;
1909 break;
1910 default:
1911 c = ch;
1912 inp();
1913 break;
1915 #if 0
1916 printf("tok=%c %d\n", c, c);
1917 if (c == LD_TOK_NAME)
1918 printf(" name=%s\n", name);
1919 #endif
1920 return c;
1923 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
1924 files */
1925 static int tcc_load_ldscript(TCCState *s1)
1927 char cmd[64];
1928 char filename[1024];
1929 int t;
1931 ch = file->buf_ptr[0];
1932 ch = handle_eob();
1933 for(;;) {
1934 t = ld_next(s1, cmd, sizeof(cmd));
1935 if (t == LD_TOK_EOF)
1936 return 0;
1937 else if (t != LD_TOK_NAME)
1938 return -1;
1939 if (!strcmp(cmd, "INPUT") ||
1940 !strcmp(cmd, "GROUP")) {
1941 t = ld_next(s1, cmd, sizeof(cmd));
1942 if (t != '(')
1943 expect("(");
1944 t = ld_next(s1, filename, sizeof(filename));
1945 for(;;) {
1946 if (t == LD_TOK_EOF) {
1947 error_noabort("unexpected end of file");
1948 return -1;
1949 } else if (t == ')') {
1950 break;
1951 } else if (t != LD_TOK_NAME) {
1952 error_noabort("filename expected");
1953 return -1;
1955 tcc_add_file(s1, filename);
1956 t = ld_next(s1, filename, sizeof(filename));
1957 if (t == ',') {
1958 t = ld_next(s1, filename, sizeof(filename));
1961 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
1962 !strcmp(cmd, "TARGET")) {
1963 /* ignore some commands */
1964 t = ld_next(s1, cmd, sizeof(cmd));
1965 if (t != '(')
1966 expect("(");
1967 for(;;) {
1968 t = ld_next(s1, filename, sizeof(filename));
1969 if (t == LD_TOK_EOF) {
1970 error_noabort("unexpected end of file");
1971 return -1;
1972 } else if (t == ')') {
1973 break;
1976 } else {
1977 return -1;
1980 return 0;