simpler function call API
[tinycc.git] / tccelf.c
blob891a68be598bdffbdc8f145b1c1deb7554bbeae8
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 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.o");
782 tcc_add_file(s1, buf);
783 #ifdef CONFIG_TCC_BCHECK
784 if (do_bounds_check) {
785 unsigned long *ptr;
786 Section *init_section;
787 unsigned char *pinit;
788 int sym_index;
790 /* XXX: add an object file to do that */
791 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
792 *ptr = 0;
793 add_elf_sym(symtab_section, 0, 0,
794 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
795 bounds_section->sh_num, "__bounds_start");
796 /* add bound check code */
797 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
798 tcc_add_file(s1, buf);
799 #ifdef TCC_TARGET_I386
800 if (s1->output_type != TCC_OUTPUT_MEMORY) {
801 /* add 'call __bound_init()' in .init section */
802 init_section = find_section(s1, ".init");
803 pinit = section_ptr_add(init_section, 5);
804 pinit[0] = 0xe8;
805 put32(pinit + 1, -4);
806 sym_index = find_elf_sym(symtab_section, "__bound_init");
807 put_elf_reloc(symtab_section, init_section,
808 init_section->data_offset - 4, R_386_PC32, sym_index);
810 #endif
812 #endif
813 /* add libc if not memory output */
814 if (s1->output_type != TCC_OUTPUT_MEMORY) {
815 tcc_add_library(s1, "c");
816 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
818 /* add various standard linker symbols */
819 add_elf_sym(symtab_section,
820 text_section->data_offset, 0,
821 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
822 text_section->sh_num, "_etext");
823 add_elf_sym(symtab_section,
824 data_section->data_offset, 0,
825 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
826 data_section->sh_num, "_edata");
827 add_elf_sym(symtab_section,
828 bss_section->data_offset, 0,
829 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
830 bss_section->sh_num, "_end");
831 /* add start and stop symbols for sections whose name can be
832 expressed in C */
833 for(i = 1; i < s1->nb_sections; i++) {
834 s = s1->sections[i];
835 if (s->sh_type == SHT_PROGBITS &&
836 (s->sh_flags & SHF_ALLOC)) {
837 const char *p;
838 int ch;
840 /* check if section name can be expressed in C */
841 p = s->name;
842 for(;;) {
843 ch = *p;
844 if (!ch)
845 break;
846 if (!isid(ch) && !isnum(ch))
847 goto next_sec;
848 p++;
850 snprintf(buf, sizeof(buf), "__start_%s", s->name);
851 add_elf_sym(symtab_section,
852 0, 0,
853 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
854 s->sh_num, buf);
855 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
856 add_elf_sym(symtab_section,
857 s->data_offset, 0,
858 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
859 s->sh_num, buf);
861 next_sec: ;
865 /* name of ELF interpreter */
866 #ifdef __FreeBSD__
867 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
868 #else
869 static char elf_interp[] = "/lib/ld-linux.so.2";
870 #endif
872 #define ELF_START_ADDR 0x08048000
873 #define ELF_PAGE_SIZE 0x1000
875 /* output an ELF file */
876 /* XXX: suppress unneeded sections */
877 int tcc_output_file(TCCState *s1, const char *filename)
879 Elf32_Ehdr ehdr;
880 FILE *f;
881 int fd, mode, ret;
882 int *section_order;
883 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
884 unsigned long addr;
885 Section *strsec, *s;
886 Elf32_Shdr shdr, *sh;
887 Elf32_Phdr *phdr, *ph;
888 Section *interp, *dynamic, *dynstr;
889 unsigned long saved_dynamic_data_offset;
890 Elf32_Sym *sym;
891 int type, file_type;
892 unsigned long rel_addr, rel_size;
894 file_type = s1->output_type;
895 s1->nb_errors = 0;
897 if (file_type != TCC_OUTPUT_OBJ)
898 tcc_add_runtime(s1);
900 phdr = NULL;
901 section_order = NULL;
902 interp = NULL;
903 dynamic = NULL;
904 dynstr = NULL; /* avoid warning */
905 saved_dynamic_data_offset = 0; /* avoid warning */
907 if (file_type != TCC_OUTPUT_OBJ) {
909 relocate_common_syms();
911 if (!s1->static_link) {
912 const char *name;
913 int sym_index, index;
914 Elf32_Sym *esym, *sym_end;
916 if (file_type == TCC_OUTPUT_EXE) {
917 char *ptr;
918 /* add interpreter section only if executable */
919 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
920 interp->sh_addralign = 1;
921 ptr = section_ptr_add(interp, sizeof(elf_interp));
922 strcpy(ptr, elf_interp);
925 /* add dynamic symbol table */
926 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
927 ".dynstr",
928 ".hash", SHF_ALLOC);
929 dynstr = s1->dynsym->link;
931 /* add dynamic section */
932 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
933 SHF_ALLOC | SHF_WRITE);
934 dynamic->link = dynstr;
935 dynamic->sh_entsize = sizeof(Elf32_Dyn);
937 /* add PLT */
938 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
939 SHF_ALLOC | SHF_EXECINSTR);
940 s1->plt->sh_entsize = 4;
942 build_got(s1);
944 /* scan for undefined symbols and see if they are in the
945 dynamic symbols. If a symbol STT_FUNC is found, then we
946 add it in the PLT. If a symbol STT_OBJECT is found, we
947 add it in the .bss section with a suitable relocation */
948 sym_end = (Elf32_Sym *)(symtab_section->data +
949 symtab_section->data_offset);
950 if (file_type == TCC_OUTPUT_EXE) {
951 for(sym = (Elf32_Sym *)symtab_section->data + 1;
952 sym < sym_end;
953 sym++) {
954 if (sym->st_shndx == SHN_UNDEF) {
955 name = symtab_section->link->data + sym->st_name;
956 sym_index = find_elf_sym(s1->dynsymtab_section, name);
957 if (sym_index) {
958 esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
959 type = ELF32_ST_TYPE(esym->st_info);
960 if (type == STT_FUNC) {
961 put_got_entry(s1, R_386_JMP_SLOT, esym->st_size,
962 esym->st_info,
963 sym - (Elf32_Sym *)symtab_section->data);
964 } else if (type == STT_OBJECT) {
965 unsigned long offset;
966 offset = bss_section->data_offset;
967 /* XXX: which alignment ? */
968 offset = (offset + 8 - 1) & -8;
969 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
970 esym->st_info, 0,
971 bss_section->sh_num, name);
972 put_elf_reloc(s1->dynsym, bss_section,
973 offset, R_386_COPY, index);
974 offset += esym->st_size;
975 bss_section->data_offset = offset;
977 } else {
978 /* STB_WEAK undefined symbols are accepted */
979 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
980 it */
981 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
982 !strcmp(name, "_fp_hw")) {
983 } else {
984 error_noabort("undefined symbol '%s'", name);
990 if (s1->nb_errors)
991 goto fail;
993 /* now look at unresolved dynamic symbols and export
994 corresponding symbol */
995 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
996 s1->dynsymtab_section->data_offset);
997 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
998 esym < sym_end;
999 esym++) {
1000 if (esym->st_shndx == SHN_UNDEF) {
1001 name = s1->dynsymtab_section->link->data + esym->st_name;
1002 sym_index = find_elf_sym(symtab_section, name);
1003 if (sym_index) {
1004 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1005 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1006 sym->st_info, 0,
1007 sym->st_shndx, name);
1008 } else {
1009 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
1010 /* weak symbols can stay undefined */
1011 } else {
1012 warning("undefined dynamic symbol '%s'", name);
1017 } else {
1018 int nb_syms;
1019 /* shared library case : we simply export all the global symbols */
1020 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
1021 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1022 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1023 sym < sym_end;
1024 sym++) {
1025 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1026 name = symtab_section->link->data + sym->st_name;
1027 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1028 sym->st_info, 0,
1029 sym->st_shndx, name);
1030 s1->symtab_to_dynsym[sym -
1031 (Elf32_Sym *)symtab_section->data] =
1032 index;
1037 build_got_entries(s1);
1039 /* add a list of needed dlls */
1040 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1041 DLLReference *dllref = s1->loaded_dlls[i];
1042 if (dllref->level == 0)
1043 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1045 /* XXX: currently, since we do not handle PIC code, we
1046 must relocate the readonly segments */
1047 if (file_type == TCC_OUTPUT_DLL)
1048 put_dt(dynamic, DT_TEXTREL, 0);
1050 /* add necessary space for other entries */
1051 saved_dynamic_data_offset = dynamic->data_offset;
1052 dynamic->data_offset += 8 * 9;
1053 } else {
1054 /* still need to build got entries in case of static link */
1055 build_got_entries(s1);
1059 memset(&ehdr, 0, sizeof(ehdr));
1061 /* we add a section for symbols */
1062 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1063 put_elf_str(strsec, "");
1065 /* compute number of sections */
1066 shnum = s1->nb_sections;
1068 /* this array is used to reorder sections in the output file */
1069 section_order = tcc_malloc(sizeof(int) * shnum);
1070 section_order[0] = 0;
1071 sh_order_index = 1;
1073 /* compute number of program headers */
1074 switch(file_type) {
1075 default:
1076 case TCC_OUTPUT_OBJ:
1077 phnum = 0;
1078 break;
1079 case TCC_OUTPUT_EXE:
1080 if (!s1->static_link)
1081 phnum = 4;
1082 else
1083 phnum = 2;
1084 break;
1085 case TCC_OUTPUT_DLL:
1086 phnum = 3;
1087 break;
1090 /* allocate strings for section names and decide if an unallocated
1091 section should be output */
1092 /* NOTE: the strsec section comes last, so its size is also
1093 correct ! */
1094 for(i = 1; i < s1->nb_sections; i++) {
1095 s = s1->sections[i];
1096 s->sh_name = put_elf_str(strsec, s->name);
1097 /* when generating a DLL, we include relocations but we may
1098 patch them */
1099 if (file_type == TCC_OUTPUT_DLL &&
1100 s->sh_type == SHT_REL &&
1101 !(s->sh_flags & SHF_ALLOC)) {
1102 prepare_dynamic_rel(s1, s);
1103 } else if (do_debug ||
1104 file_type == TCC_OUTPUT_OBJ ||
1105 (s->sh_flags & SHF_ALLOC) ||
1106 i == (s1->nb_sections - 1)) {
1107 /* we output all sections if debug or object file */
1108 s->sh_size = s->data_offset;
1112 /* allocate program segment headers */
1113 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1115 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1116 if (phnum > 0) {
1117 /* compute section to program header mapping */
1118 if (file_type == TCC_OUTPUT_DLL)
1119 addr = 0;
1120 else
1121 addr = ELF_START_ADDR;
1123 /* dynamic relocation table information, for .dynamic section */
1124 rel_size = 0;
1125 rel_addr = 0;
1127 /* compute address after headers */
1128 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1130 /* leave one program header for the program interpreter */
1131 ph = &phdr[0];
1132 if (interp)
1133 ph++;
1135 for(j = 0; j < 2; j++) {
1136 ph->p_type = PT_LOAD;
1137 if (j == 0)
1138 ph->p_flags = PF_R | PF_X;
1139 else
1140 ph->p_flags = PF_R | PF_W;
1141 ph->p_align = ELF_PAGE_SIZE;
1143 /* we do the following ordering: interp, symbol tables,
1144 relocations, progbits, nobits */
1145 /* XXX: do faster and simpler sorting */
1146 for(k = 0; k < 5; k++) {
1147 for(i = 1; i < s1->nb_sections; i++) {
1148 s = s1->sections[i];
1149 /* compute if section should be included */
1150 if (j == 0) {
1151 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1152 SHF_ALLOC)
1153 continue;
1154 } else {
1155 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1156 (SHF_ALLOC | SHF_WRITE))
1157 continue;
1159 if (s == interp) {
1160 if (k != 0)
1161 continue;
1162 } else if (s->sh_type == SHT_DYNSYM ||
1163 s->sh_type == SHT_STRTAB ||
1164 s->sh_type == SHT_HASH) {
1165 if (k != 1)
1166 continue;
1167 } else if (s->sh_type == SHT_REL) {
1168 if (k != 2)
1169 continue;
1170 } else if (s->sh_type == SHT_NOBITS) {
1171 if (k != 4)
1172 continue;
1173 } else {
1174 if (k != 3)
1175 continue;
1177 section_order[sh_order_index++] = i;
1179 /* section matches: we align it and add its size */
1180 tmp = file_offset;
1181 file_offset = (file_offset + s->sh_addralign - 1) &
1182 ~(s->sh_addralign - 1);
1183 s->sh_offset = file_offset;
1184 addr += file_offset - tmp;
1185 s->sh_addr = addr;
1187 /* update program header infos */
1188 if (ph->p_offset == 0) {
1189 ph->p_offset = file_offset;
1190 ph->p_vaddr = addr;
1191 ph->p_paddr = ph->p_vaddr;
1193 /* update dynamic relocation infos */
1194 if (s->sh_type == SHT_REL) {
1195 if (rel_size == 0)
1196 rel_addr = addr;
1197 rel_size += s->sh_size;
1199 addr += s->sh_size;
1200 if (s->sh_type != SHT_NOBITS)
1201 file_offset += s->sh_size;
1204 ph->p_filesz = file_offset - ph->p_offset;
1205 ph->p_memsz = addr - ph->p_vaddr;
1206 ph++;
1207 /* if in the middle of a page, we duplicate the page in
1208 memory so that one copy is RX and the other is RW */
1209 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1210 addr += ELF_PAGE_SIZE;
1213 /* if interpreter, then add corresponing program header */
1214 if (interp) {
1215 ph = &phdr[0];
1217 ph->p_type = PT_INTERP;
1218 ph->p_offset = interp->sh_offset;
1219 ph->p_vaddr = interp->sh_addr;
1220 ph->p_paddr = ph->p_vaddr;
1221 ph->p_filesz = interp->sh_size;
1222 ph->p_memsz = interp->sh_size;
1223 ph->p_flags = PF_R;
1224 ph->p_align = interp->sh_addralign;
1227 /* if dynamic section, then add corresponing program header */
1228 if (dynamic) {
1229 Elf32_Sym *sym_end;
1231 ph = &phdr[phnum - 1];
1233 ph->p_type = PT_DYNAMIC;
1234 ph->p_offset = dynamic->sh_offset;
1235 ph->p_vaddr = dynamic->sh_addr;
1236 ph->p_paddr = ph->p_vaddr;
1237 ph->p_filesz = dynamic->sh_size;
1238 ph->p_memsz = dynamic->sh_size;
1239 ph->p_flags = PF_R | PF_W;
1240 ph->p_align = dynamic->sh_addralign;
1242 /* put GOT dynamic section address */
1243 put32(s1->got->data, dynamic->sh_addr);
1245 /* relocate the PLT */
1246 if (file_type == TCC_OUTPUT_EXE) {
1247 uint8_t *p, *p_end;
1249 p = s1->plt->data;
1250 p_end = p + s1->plt->data_offset;
1251 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1252 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1253 p += 16;
1254 while (p < p_end) {
1255 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1256 p += 16;
1260 /* relocate symbols in .dynsym */
1261 sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
1262 for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
1263 sym < sym_end;
1264 sym++) {
1265 if (sym->st_shndx == SHN_UNDEF) {
1266 /* relocate to the PLT if the symbol corresponds
1267 to a PLT entry */
1268 if (sym->st_value)
1269 sym->st_value += s1->plt->sh_addr;
1270 } else if (sym->st_shndx < SHN_LORESERVE) {
1271 /* do symbol relocation */
1272 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1276 /* put dynamic section entries */
1277 dynamic->data_offset = saved_dynamic_data_offset;
1278 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1279 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1280 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1281 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1282 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
1283 put_dt(dynamic, DT_REL, rel_addr);
1284 put_dt(dynamic, DT_RELSZ, rel_size);
1285 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
1286 put_dt(dynamic, DT_NULL, 0);
1289 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1290 ehdr.e_phnum = phnum;
1291 ehdr.e_phoff = sizeof(Elf32_Ehdr);
1294 /* all other sections come after */
1295 for(i = 1; i < s1->nb_sections; i++) {
1296 s = s1->sections[i];
1297 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1298 continue;
1299 section_order[sh_order_index++] = i;
1301 file_offset = (file_offset + s->sh_addralign - 1) &
1302 ~(s->sh_addralign - 1);
1303 s->sh_offset = file_offset;
1304 if (s->sh_type != SHT_NOBITS)
1305 file_offset += s->sh_size;
1308 /* if building executable or DLL, then relocate each section
1309 except the GOT which is already relocated */
1310 if (file_type != TCC_OUTPUT_OBJ) {
1311 relocate_syms(s1, 0);
1313 if (s1->nb_errors != 0) {
1314 fail:
1315 ret = -1;
1316 goto the_end;
1319 /* relocate sections */
1320 /* XXX: ignore sections with allocated relocations ? */
1321 for(i = 1; i < s1->nb_sections; i++) {
1322 s = s1->sections[i];
1323 if (s->reloc && s != s1->got)
1324 relocate_section(s1, s);
1327 /* relocate relocation entries if the relocation tables are
1328 allocated in the executable */
1329 for(i = 1; i < s1->nb_sections; i++) {
1330 s = s1->sections[i];
1331 if ((s->sh_flags & SHF_ALLOC) &&
1332 s->sh_type == SHT_REL) {
1333 relocate_rel(s1, s);
1337 /* get entry point address */
1338 if (file_type == TCC_OUTPUT_EXE)
1339 ehdr.e_entry = (unsigned long)tcc_get_symbol(s1, "_start");
1340 else
1341 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1344 sort_syms(s1, symtab_section);
1346 /* align to 4 */
1347 file_offset = (file_offset + 3) & -4;
1349 /* fill header */
1350 ehdr.e_ident[0] = ELFMAG0;
1351 ehdr.e_ident[1] = ELFMAG1;
1352 ehdr.e_ident[2] = ELFMAG2;
1353 ehdr.e_ident[3] = ELFMAG3;
1354 ehdr.e_ident[4] = ELFCLASS32;
1355 ehdr.e_ident[5] = ELFDATA2LSB;
1356 ehdr.e_ident[6] = EV_CURRENT;
1357 #ifdef __FreeBSD__
1358 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1359 #endif
1360 switch(file_type) {
1361 default:
1362 case TCC_OUTPUT_EXE:
1363 ehdr.e_type = ET_EXEC;
1364 break;
1365 case TCC_OUTPUT_DLL:
1366 ehdr.e_type = ET_DYN;
1367 break;
1368 case TCC_OUTPUT_OBJ:
1369 ehdr.e_type = ET_REL;
1370 break;
1372 ehdr.e_machine = EM_386;
1373 ehdr.e_version = EV_CURRENT;
1374 ehdr.e_shoff = file_offset;
1375 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1376 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1377 ehdr.e_shnum = shnum;
1378 ehdr.e_shstrndx = shnum - 1;
1380 /* write elf file */
1381 if (file_type == TCC_OUTPUT_OBJ)
1382 mode = 0666;
1383 else
1384 mode = 0777;
1385 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
1386 if (fd < 0) {
1387 error_noabort("could not write '%s'", filename);
1388 goto fail;
1390 f = fdopen(fd, "w");
1391 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1392 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1393 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1394 for(i=1;i<s1->nb_sections;i++) {
1395 s = s1->sections[section_order[i]];
1396 if (s->sh_type != SHT_NOBITS) {
1397 while (offset < s->sh_offset) {
1398 fputc(0, f);
1399 offset++;
1401 size = s->sh_size;
1402 fwrite(s->data, 1, size, f);
1403 offset += size;
1406 while (offset < ehdr.e_shoff) {
1407 fputc(0, f);
1408 offset++;
1411 /* output section headers */
1412 for(i=0;i<s1->nb_sections;i++) {
1413 sh = &shdr;
1414 memset(sh, 0, sizeof(Elf32_Shdr));
1415 s = s1->sections[i];
1416 if (s) {
1417 sh->sh_name = s->sh_name;
1418 sh->sh_type = s->sh_type;
1419 sh->sh_flags = s->sh_flags;
1420 sh->sh_entsize = s->sh_entsize;
1421 sh->sh_info = s->sh_info;
1422 if (s->link)
1423 sh->sh_link = s->link->sh_num;
1424 sh->sh_addralign = s->sh_addralign;
1425 sh->sh_addr = s->sh_addr;
1426 sh->sh_offset = s->sh_offset;
1427 sh->sh_size = s->sh_size;
1429 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1431 fclose(f);
1433 ret = 0;
1434 the_end:
1435 tcc_free(s1->symtab_to_dynsym);
1436 tcc_free(section_order);
1437 tcc_free(phdr);
1438 tcc_free(s1->got_offsets);
1439 return ret;
1442 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1444 void *data;
1446 data = tcc_malloc(size);
1447 lseek(fd, file_offset, SEEK_SET);
1448 read(fd, data, size);
1449 return data;
1452 typedef struct SectionMergeInfo {
1453 Section *s; /* corresponding existing section */
1454 unsigned long offset; /* offset of the new section in the existing section */
1455 int new_section; /* true if section 's' was added */
1456 } SectionMergeInfo;
1458 /* load an object file and merge it with current files */
1459 /* XXX: handle correctly stab (debug) info */
1460 static int tcc_load_object_file(TCCState *s1,
1461 int fd, unsigned long file_offset)
1463 Elf32_Ehdr ehdr;
1464 Elf32_Shdr *shdr, *sh;
1465 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1466 unsigned char *strsec, *strtab;
1467 int *old_to_new_syms;
1468 char *sh_name, *name;
1469 SectionMergeInfo *sm_table, *sm;
1470 Elf32_Sym *sym, *symtab;
1471 Elf32_Rel *rel, *rel_end;
1472 Section *s;
1474 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1475 goto fail1;
1476 if (ehdr.e_ident[0] != ELFMAG0 ||
1477 ehdr.e_ident[1] != ELFMAG1 ||
1478 ehdr.e_ident[2] != ELFMAG2 ||
1479 ehdr.e_ident[3] != ELFMAG3)
1480 goto fail1;
1481 /* test if object file */
1482 if (ehdr.e_type != ET_REL)
1483 goto fail1;
1484 /* test CPU specific stuff */
1485 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1486 ehdr.e_machine != EM_386) {
1487 fail1:
1488 error_noabort("invalid object file");
1489 return -1;
1491 /* read sections */
1492 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1493 sizeof(Elf32_Shdr) * ehdr.e_shnum);
1494 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1496 /* load section names */
1497 sh = &shdr[ehdr.e_shstrndx];
1498 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1500 /* load symtab and strtab */
1501 old_to_new_syms = NULL;
1502 symtab = NULL;
1503 strtab = NULL;
1504 nb_syms = 0;
1505 for(i = 1; i < ehdr.e_shnum; i++) {
1506 sh = &shdr[i];
1507 if (sh->sh_type == SHT_SYMTAB) {
1508 if (symtab) {
1509 error_noabort("object must contain only one symtab");
1510 fail:
1511 ret = -1;
1512 goto the_end;
1514 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1515 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1516 sm_table[i].s = symtab_section;
1518 /* now load strtab */
1519 sh = &shdr[sh->sh_link];
1520 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1524 /* now examine each section and try to merge its content with the
1525 ones in memory */
1526 for(i = 1; i < ehdr.e_shnum; i++) {
1527 /* no need to examine section name strtab */
1528 if (i == ehdr.e_shstrndx)
1529 continue;
1530 sh = &shdr[i];
1531 sh_name = strsec + sh->sh_name;
1532 /* ignore sections types we do not handle */
1533 if (sh->sh_type != SHT_PROGBITS &&
1534 sh->sh_type != SHT_REL &&
1535 sh->sh_type != SHT_NOBITS)
1536 continue;
1537 if (sh->sh_addralign < 1)
1538 sh->sh_addralign = 1;
1539 /* find corresponding section, if any */
1540 for(j = 1; j < s1->nb_sections;j++) {
1541 s = s1->sections[j];
1542 if (!strcmp(s->name, sh_name))
1543 goto found;
1545 /* not found: create new section */
1546 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1547 /* take as much info as possible from the section. sh_link and
1548 sh_info will be updated later */
1549 s->sh_addralign = sh->sh_addralign;
1550 s->sh_entsize = sh->sh_entsize;
1551 sm_table[i].new_section = 1;
1552 found:
1553 if (sh->sh_type != s->sh_type) {
1554 error_noabort("invalid section type");
1555 goto fail;
1558 /* align start of section */
1559 offset = s->data_offset;
1560 size = sh->sh_addralign - 1;
1561 offset = (offset + size) & ~size;
1562 if (sh->sh_addralign > s->sh_addralign)
1563 s->sh_addralign = sh->sh_addralign;
1564 s->data_offset = offset;
1565 sm_table[i].offset = offset;
1566 sm_table[i].s = s;
1567 /* concatenate sections */
1568 size = sh->sh_size;
1569 if (sh->sh_type != SHT_NOBITS) {
1570 unsigned char *ptr;
1571 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1572 ptr = section_ptr_add(s, size);
1573 read(fd, ptr, size);
1574 } else {
1575 s->data_offset += size;
1579 /* second short pass to update sh_link and sh_info fields of new
1580 sections */
1581 sm = sm_table;
1582 for(i = 1; i < ehdr.e_shnum; i++) {
1583 s = sm_table[i].s;
1584 if (!s || !sm_table[i].new_section)
1585 continue;
1586 sh = &shdr[i];
1587 if (sh->sh_link > 0)
1588 s->link = sm_table[sh->sh_link].s;
1589 if (sh->sh_type == SHT_REL) {
1590 s->sh_info = sm_table[sh->sh_info].s->sh_num;
1591 /* update backward link */
1592 s1->sections[s->sh_info]->reloc = s;
1596 /* resolve symbols */
1597 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
1599 sym = symtab + 1;
1600 for(i = 1; i < nb_syms; i++, sym++) {
1601 if (sym->st_shndx != SHN_UNDEF &&
1602 sym->st_shndx < SHN_LORESERVE) {
1603 sm = &sm_table[sym->st_shndx];
1604 /* if no corresponding section added, no need to add symbol */
1605 if (!sm->s)
1606 continue;
1607 /* convert section number */
1608 sym->st_shndx = sm->s->sh_num;
1609 /* offset value */
1610 sym->st_value += sm->offset;
1612 /* add symbol */
1613 name = strtab + sym->st_name;
1614 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
1615 sym->st_info, sym->st_shndx, name);
1616 old_to_new_syms[i] = sym_index;
1619 /* third pass to patch relocation entries */
1620 for(i = 1; i < ehdr.e_shnum; i++) {
1621 s = sm_table[i].s;
1622 if (!s)
1623 continue;
1624 sh = &shdr[i];
1625 offset = sm_table[i].offset;
1626 switch(s->sh_type) {
1627 case SHT_REL:
1628 /* take relocation offset information */
1629 offseti = sm_table[sh->sh_info].offset;
1630 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
1631 for(rel = (Elf32_Rel *)(s->data + offset);
1632 rel < rel_end;
1633 rel++) {
1634 int type;
1635 unsigned sym_index;
1636 /* convert symbol index */
1637 type = ELF32_R_TYPE(rel->r_info);
1638 sym_index = ELF32_R_SYM(rel->r_info);
1639 /* NOTE: only one symtab assumed */
1640 if (sym_index >= nb_syms)
1641 goto invalid_reloc;
1642 sym_index = old_to_new_syms[sym_index];
1643 if (!sym_index) {
1644 invalid_reloc:
1645 error_noabort("Invalid relocation entry");
1646 goto fail;
1648 rel->r_info = ELF32_R_INFO(sym_index, type);
1649 /* offset the relocation offset */
1650 rel->r_offset += offseti;
1652 break;
1653 default:
1654 break;
1658 ret = 0;
1659 the_end:
1660 tcc_free(symtab);
1661 tcc_free(strtab);
1662 tcc_free(old_to_new_syms);
1663 tcc_free(sm_table);
1664 tcc_free(strsec);
1665 tcc_free(shdr);
1666 return ret;
1669 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1671 typedef struct ArchiveHeader {
1672 char ar_name[16]; /* name of this member */
1673 char ar_date[12]; /* file mtime */
1674 char ar_uid[6]; /* owner uid; printed as decimal */
1675 char ar_gid[6]; /* owner gid; printed as decimal */
1676 char ar_mode[8]; /* file mode, printed as octal */
1677 char ar_size[10]; /* file size, printed as decimal */
1678 char ar_fmag[2]; /* should contain ARFMAG */
1679 } ArchiveHeader;
1681 /* load a '.a' file */
1682 static int tcc_load_archive(TCCState *s1, int fd)
1684 ArchiveHeader hdr;
1685 char ar_size[11];
1686 char ar_name[17];
1687 char magic[8];
1688 int size, len, i;
1689 unsigned long file_offset;
1691 /* skip magic which was already checked */
1692 read(fd, magic, sizeof(magic));
1694 for(;;) {
1695 len = read(fd, &hdr, sizeof(hdr));
1696 if (len == 0)
1697 break;
1698 if (len != sizeof(hdr)) {
1699 error_noabort("invalid archive");
1700 return -1;
1702 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
1703 ar_size[sizeof(hdr.ar_size)] = '\0';
1704 size = strtol(ar_size, NULL, 0);
1705 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
1706 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
1707 if (ar_name[i] != ' ')
1708 break;
1710 ar_name[i + 1] = '\0';
1711 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
1712 file_offset = lseek(fd, 0, SEEK_CUR);
1713 if (!strcmp(ar_name, "/") ||
1714 !strcmp(ar_name, "//") ||
1715 !strcmp(ar_name, "__.SYMDEF") ||
1716 !strcmp(ar_name, "__.SYMDEF/") ||
1717 !strcmp(ar_name, "ARFILENAMES/")) {
1718 /* skip symbol table or archive names */
1719 } else {
1720 if (tcc_load_object_file(s1, fd, file_offset) < 0)
1721 return -1;
1723 /* align to even */
1724 size = (size + 1) & ~1;
1725 lseek(fd, file_offset + size, SEEK_SET);
1727 return 0;
1730 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
1731 is referenced by the user (so it should be added as DT_NEEDED in
1732 the generated ELF file) */
1733 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
1735 Elf32_Ehdr ehdr;
1736 Elf32_Shdr *shdr, *sh, *sh1;
1737 int i, nb_syms, nb_dts, sym_bind, ret;
1738 Elf32_Sym *sym, *dynsym;
1739 Elf32_Dyn *dt, *dynamic;
1740 unsigned char *dynstr;
1741 const char *name, *soname, *p;
1742 DLLReference *dllref;
1744 read(fd, &ehdr, sizeof(ehdr));
1746 /* test CPU specific stuff */
1747 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1748 ehdr.e_machine != EM_386) {
1749 error_noabort("bad architecture");
1750 return -1;
1753 /* read sections */
1754 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
1756 /* load dynamic section and dynamic symbols */
1757 nb_syms = 0;
1758 nb_dts = 0;
1759 dynamic = NULL;
1760 dynsym = NULL; /* avoid warning */
1761 dynstr = NULL; /* avoid warning */
1762 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
1763 switch(sh->sh_type) {
1764 case SHT_DYNAMIC:
1765 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
1766 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
1767 break;
1768 case SHT_DYNSYM:
1769 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1770 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
1771 sh1 = &shdr[sh->sh_link];
1772 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
1773 break;
1774 default:
1775 break;
1779 /* compute the real library name */
1780 soname = filename;
1781 p = strrchr(soname, '/');
1782 if (p)
1783 soname = p + 1;
1785 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
1786 if (dt->d_tag == DT_SONAME) {
1787 soname = dynstr + dt->d_un.d_val;
1791 /* if the dll is already loaded, do not load it */
1792 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1793 dllref = s1->loaded_dlls[i];
1794 if (!strcmp(soname, dllref->name)) {
1795 /* but update level if needed */
1796 if (level < dllref->level)
1797 dllref->level = level;
1798 ret = 0;
1799 goto the_end;
1803 // printf("loading dll '%s'\n", soname);
1805 /* add the dll and its level */
1806 dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
1807 dllref->level = level;
1808 strcpy(dllref->name, soname);
1809 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
1811 /* add dynamic symbols in dynsym_section */
1812 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
1813 sym_bind = ELF32_ST_BIND(sym->st_info);
1814 if (sym_bind == STB_LOCAL)
1815 continue;
1816 name = dynstr + sym->st_name;
1817 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
1818 sym->st_info, sym->st_shndx, name);
1821 /* load all referenced DLLs */
1822 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
1823 switch(dt->d_tag) {
1824 case DT_NEEDED:
1825 name = dynstr + dt->d_un.d_val;
1826 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1827 dllref = s1->loaded_dlls[i];
1828 if (!strcmp(name, dllref->name))
1829 goto already_loaded;
1831 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
1832 error_noabort("referenced dll '%s' not found", name);
1833 ret = -1;
1834 goto the_end;
1836 already_loaded:
1837 break;
1840 ret = 0;
1841 the_end:
1842 tcc_free(dynstr);
1843 tcc_free(dynsym);
1844 tcc_free(dynamic);
1845 tcc_free(shdr);
1846 return ret;
1849 #define LD_TOK_NAME 256
1850 #define LD_TOK_EOF (-1)
1852 /* return next ld script token */
1853 static int ld_next(TCCState *s1, char *name, int name_size)
1855 int c;
1856 char *q;
1858 redo:
1859 switch(ch) {
1860 case ' ':
1861 case '\t':
1862 case '\f':
1863 case '\v':
1864 case '\r':
1865 case '\n':
1866 inp();
1867 goto redo;
1868 case '/':
1869 minp();
1870 if (ch == '*') {
1871 file->buf_ptr = parse_comment(file->buf_ptr);
1872 ch = file->buf_ptr[0];
1873 goto redo;
1874 } else {
1875 q = name;
1876 *q++ = '/';
1877 goto parse_name;
1879 break;
1880 case 'a' ... 'z':
1881 case 'A' ... 'Z':
1882 case '_':
1883 case '\\':
1884 case '.':
1885 case '$':
1886 case '~':
1887 q = name;
1888 parse_name:
1889 for(;;) {
1890 if (!((ch >= 'a' && ch <= 'z') ||
1891 (ch >= 'A' && ch <= 'Z') ||
1892 (ch >= '0' && ch <= '9') ||
1893 strchr("/.-_+=$:\\,~", ch)))
1894 break;
1895 if ((q - name) < name_size - 1) {
1896 *q++ = ch;
1898 minp();
1900 *q = '\0';
1901 c = LD_TOK_NAME;
1902 break;
1903 case CH_EOF:
1904 c = LD_TOK_EOF;
1905 break;
1906 default:
1907 c = ch;
1908 inp();
1909 break;
1911 #if 0
1912 printf("tok=%c %d\n", c, c);
1913 if (c == LD_TOK_NAME)
1914 printf(" name=%s\n", name);
1915 #endif
1916 return c;
1919 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
1920 files */
1921 static int tcc_load_ldscript(TCCState *s1)
1923 char cmd[64];
1924 char filename[1024];
1925 int t;
1927 ch = file->buf_ptr[0];
1928 ch = handle_eob();
1929 for(;;) {
1930 t = ld_next(s1, cmd, sizeof(cmd));
1931 if (t == LD_TOK_EOF)
1932 return 0;
1933 else if (t != LD_TOK_NAME)
1934 return -1;
1935 if (!strcmp(cmd, "INPUT") ||
1936 !strcmp(cmd, "GROUP")) {
1937 t = ld_next(s1, cmd, sizeof(cmd));
1938 if (t != '(')
1939 expect("(");
1940 t = ld_next(s1, filename, sizeof(filename));
1941 for(;;) {
1942 if (t == LD_TOK_EOF) {
1943 error_noabort("unexpected end of file");
1944 return -1;
1945 } else if (t == ')') {
1946 break;
1947 } else if (t != LD_TOK_NAME) {
1948 error_noabort("filename expected");
1949 return -1;
1951 tcc_add_file(s1, filename);
1952 t = ld_next(s1, filename, sizeof(filename));
1953 if (t == ',') {
1954 t = ld_next(s1, filename, sizeof(filename));
1957 } else {
1958 return -1;
1961 return 0;