update
[tinycc.git] / tccelf.c
bloba259818ea443e603209c928a9a8a3126068a2e29
1 /*
2 * ELF file handling for TCC
3 *
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 static int put_elf_str(Section *s, const char *sym)
23 int offset, len;
24 char *ptr;
26 len = strlen(sym) + 1;
27 offset = s->data_offset;
28 ptr = section_ptr_add(s, len);
29 memcpy(ptr, sym, len);
30 return offset;
33 /* elf symbol hashing function */
34 static unsigned long elf_hash(const unsigned char *name)
36 unsigned long h = 0, g;
38 while (*name) {
39 h = (h << 4) + *name++;
40 g = h & 0xf0000000;
41 if (g)
42 h ^= g >> 24;
43 h &= ~g;
45 return h;
48 /* rebuild hash table of section s */
49 /* NOTE: we do factorize the hash table code to go faster */
50 static void rebuild_hash(Section *s, unsigned int nb_buckets)
52 Elf32_Sym *sym;
53 int *ptr, *hash, nb_syms, sym_index, h;
54 char *strtab;
56 strtab = s->link->data;
57 nb_syms = s->data_offset / sizeof(Elf32_Sym);
59 s->hash->data_offset = 0;
60 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
61 ptr[0] = nb_buckets;
62 ptr[1] = nb_syms;
63 ptr += 2;
64 hash = ptr;
65 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
66 ptr += nb_buckets + 1;
68 sym = (Elf32_Sym *)s->data + 1;
69 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
70 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
71 h = elf_hash(strtab + sym->st_name) % nb_buckets;
72 *ptr = hash[h];
73 hash[h] = sym_index;
74 } else {
75 *ptr = 0;
77 ptr++;
78 sym++;
82 /* return the symbol number */
83 static int put_elf_sym(Section *s,
84 unsigned long value, unsigned long size,
85 int info, int other, int shndx, const char *name)
87 int name_offset, sym_index;
88 int nbuckets, h;
89 Elf32_Sym *sym;
90 Section *hs;
92 sym = section_ptr_add(s, sizeof(Elf32_Sym));
93 if (name)
94 name_offset = put_elf_str(s->link, name);
95 else
96 name_offset = 0;
97 /* XXX: endianness */
98 sym->st_name = name_offset;
99 sym->st_value = value;
100 sym->st_size = size;
101 sym->st_info = info;
102 sym->st_other = other;
103 sym->st_shndx = shndx;
104 sym_index = sym - (Elf32_Sym *)s->data;
105 hs = s->hash;
106 if (hs) {
107 int *ptr, *base;
108 ptr = section_ptr_add(hs, sizeof(int));
109 base = (int *)hs->data;
110 /* only add global or weak symbols */
111 if (ELF32_ST_BIND(info) != STB_LOCAL) {
112 /* add another hashing entry */
113 nbuckets = base[0];
114 h = elf_hash(name) % nbuckets;
115 *ptr = base[2 + h];
116 base[2 + h] = sym_index;
117 base[1]++;
118 /* we resize the hash table */
119 hs->nb_hashed_syms++;
120 if (hs->nb_hashed_syms > 2 * nbuckets) {
121 rebuild_hash(s, 2 * nbuckets);
123 } else {
124 *ptr = 0;
125 base[1]++;
128 return sym_index;
131 /* find global ELF symbol 'name' and return its index. Return 0 if not
132 found. */
133 static int find_elf_sym(Section *s, const char *name)
135 Elf32_Sym *sym;
136 Section *hs;
137 int nbuckets, sym_index, h;
138 const char *name1;
140 hs = s->hash;
141 if (!hs)
142 return 0;
143 nbuckets = ((int *)hs->data)[0];
144 h = elf_hash(name) % nbuckets;
145 sym_index = ((int *)hs->data)[2 + h];
146 while (sym_index != 0) {
147 sym = &((Elf32_Sym *)s->data)[sym_index];
148 name1 = s->link->data + sym->st_name;
149 if (!strcmp(name, name1))
150 return sym_index;
151 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
153 return 0;
156 /* return elf symbol value or error */
157 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.a");
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 + 16 - 1) & -16;
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);
989 } else if (s1->rdynamic &&
990 ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
991 /* if -rdynamic option, then export all non
992 local symbols */
993 name = symtab_section->link->data + sym->st_name;
994 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
995 sym->st_info, 0,
996 sym->st_shndx, name);
1000 if (s1->nb_errors)
1001 goto fail;
1003 /* now look at unresolved dynamic symbols and export
1004 corresponding symbol */
1005 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
1006 s1->dynsymtab_section->data_offset);
1007 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
1008 esym < sym_end;
1009 esym++) {
1010 if (esym->st_shndx == SHN_UNDEF) {
1011 name = s1->dynsymtab_section->link->data + esym->st_name;
1012 sym_index = find_elf_sym(symtab_section, name);
1013 if (sym_index) {
1014 /* XXX: avoid adding a symbol if already
1015 present because of -rdynamic ? */
1016 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1017 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1018 sym->st_info, 0,
1019 sym->st_shndx, name);
1020 } else {
1021 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
1022 /* weak symbols can stay undefined */
1023 } else {
1024 warning("undefined dynamic symbol '%s'", name);
1029 } else {
1030 int nb_syms;
1031 /* shared library case : we simply export all the global symbols */
1032 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
1033 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1034 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1035 sym < sym_end;
1036 sym++) {
1037 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1038 name = symtab_section->link->data + sym->st_name;
1039 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1040 sym->st_info, 0,
1041 sym->st_shndx, name);
1042 s1->symtab_to_dynsym[sym -
1043 (Elf32_Sym *)symtab_section->data] =
1044 index;
1049 build_got_entries(s1);
1051 /* add a list of needed dlls */
1052 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1053 DLLReference *dllref = s1->loaded_dlls[i];
1054 if (dllref->level == 0)
1055 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1057 /* XXX: currently, since we do not handle PIC code, we
1058 must relocate the readonly segments */
1059 if (file_type == TCC_OUTPUT_DLL)
1060 put_dt(dynamic, DT_TEXTREL, 0);
1062 /* add necessary space for other entries */
1063 saved_dynamic_data_offset = dynamic->data_offset;
1064 dynamic->data_offset += 8 * 9;
1065 } else {
1066 /* still need to build got entries in case of static link */
1067 build_got_entries(s1);
1071 memset(&ehdr, 0, sizeof(ehdr));
1073 /* we add a section for symbols */
1074 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1075 put_elf_str(strsec, "");
1077 /* compute number of sections */
1078 shnum = s1->nb_sections;
1080 /* this array is used to reorder sections in the output file */
1081 section_order = tcc_malloc(sizeof(int) * shnum);
1082 section_order[0] = 0;
1083 sh_order_index = 1;
1085 /* compute number of program headers */
1086 switch(file_type) {
1087 default:
1088 case TCC_OUTPUT_OBJ:
1089 phnum = 0;
1090 break;
1091 case TCC_OUTPUT_EXE:
1092 if (!s1->static_link)
1093 phnum = 4;
1094 else
1095 phnum = 2;
1096 break;
1097 case TCC_OUTPUT_DLL:
1098 phnum = 3;
1099 break;
1102 /* allocate strings for section names and decide if an unallocated
1103 section should be output */
1104 /* NOTE: the strsec section comes last, so its size is also
1105 correct ! */
1106 for(i = 1; i < s1->nb_sections; i++) {
1107 s = s1->sections[i];
1108 s->sh_name = put_elf_str(strsec, s->name);
1109 /* when generating a DLL, we include relocations but we may
1110 patch them */
1111 if (file_type == TCC_OUTPUT_DLL &&
1112 s->sh_type == SHT_REL &&
1113 !(s->sh_flags & SHF_ALLOC)) {
1114 prepare_dynamic_rel(s1, s);
1115 } else if (do_debug ||
1116 file_type == TCC_OUTPUT_OBJ ||
1117 (s->sh_flags & SHF_ALLOC) ||
1118 i == (s1->nb_sections - 1)) {
1119 /* we output all sections if debug or object file */
1120 s->sh_size = s->data_offset;
1124 /* allocate program segment headers */
1125 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1127 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1128 if (phnum > 0) {
1129 /* compute section to program header mapping */
1130 if (file_type == TCC_OUTPUT_DLL)
1131 addr = 0;
1132 else
1133 addr = ELF_START_ADDR;
1135 /* dynamic relocation table information, for .dynamic section */
1136 rel_size = 0;
1137 rel_addr = 0;
1139 /* compute address after headers */
1140 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1142 /* leave one program header for the program interpreter */
1143 ph = &phdr[0];
1144 if (interp)
1145 ph++;
1147 for(j = 0; j < 2; j++) {
1148 ph->p_type = PT_LOAD;
1149 if (j == 0)
1150 ph->p_flags = PF_R | PF_X;
1151 else
1152 ph->p_flags = PF_R | PF_W;
1153 ph->p_align = ELF_PAGE_SIZE;
1155 /* we do the following ordering: interp, symbol tables,
1156 relocations, progbits, nobits */
1157 /* XXX: do faster and simpler sorting */
1158 for(k = 0; k < 5; k++) {
1159 for(i = 1; i < s1->nb_sections; i++) {
1160 s = s1->sections[i];
1161 /* compute if section should be included */
1162 if (j == 0) {
1163 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1164 SHF_ALLOC)
1165 continue;
1166 } else {
1167 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1168 (SHF_ALLOC | SHF_WRITE))
1169 continue;
1171 if (s == interp) {
1172 if (k != 0)
1173 continue;
1174 } else if (s->sh_type == SHT_DYNSYM ||
1175 s->sh_type == SHT_STRTAB ||
1176 s->sh_type == SHT_HASH) {
1177 if (k != 1)
1178 continue;
1179 } else if (s->sh_type == SHT_REL) {
1180 if (k != 2)
1181 continue;
1182 } else if (s->sh_type == SHT_NOBITS) {
1183 if (k != 4)
1184 continue;
1185 } else {
1186 if (k != 3)
1187 continue;
1189 section_order[sh_order_index++] = i;
1191 /* section matches: we align it and add its size */
1192 tmp = file_offset;
1193 file_offset = (file_offset + s->sh_addralign - 1) &
1194 ~(s->sh_addralign - 1);
1195 s->sh_offset = file_offset;
1196 addr += file_offset - tmp;
1197 s->sh_addr = addr;
1199 /* update program header infos */
1200 if (ph->p_offset == 0) {
1201 ph->p_offset = file_offset;
1202 ph->p_vaddr = addr;
1203 ph->p_paddr = ph->p_vaddr;
1205 /* update dynamic relocation infos */
1206 if (s->sh_type == SHT_REL) {
1207 if (rel_size == 0)
1208 rel_addr = addr;
1209 rel_size += s->sh_size;
1211 addr += s->sh_size;
1212 if (s->sh_type != SHT_NOBITS)
1213 file_offset += s->sh_size;
1216 ph->p_filesz = file_offset - ph->p_offset;
1217 ph->p_memsz = addr - ph->p_vaddr;
1218 ph++;
1219 /* if in the middle of a page, we duplicate the page in
1220 memory so that one copy is RX and the other is RW */
1221 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1222 addr += ELF_PAGE_SIZE;
1225 /* if interpreter, then add corresponing program header */
1226 if (interp) {
1227 ph = &phdr[0];
1229 ph->p_type = PT_INTERP;
1230 ph->p_offset = interp->sh_offset;
1231 ph->p_vaddr = interp->sh_addr;
1232 ph->p_paddr = ph->p_vaddr;
1233 ph->p_filesz = interp->sh_size;
1234 ph->p_memsz = interp->sh_size;
1235 ph->p_flags = PF_R;
1236 ph->p_align = interp->sh_addralign;
1239 /* if dynamic section, then add corresponing program header */
1240 if (dynamic) {
1241 Elf32_Sym *sym_end;
1243 ph = &phdr[phnum - 1];
1245 ph->p_type = PT_DYNAMIC;
1246 ph->p_offset = dynamic->sh_offset;
1247 ph->p_vaddr = dynamic->sh_addr;
1248 ph->p_paddr = ph->p_vaddr;
1249 ph->p_filesz = dynamic->sh_size;
1250 ph->p_memsz = dynamic->sh_size;
1251 ph->p_flags = PF_R | PF_W;
1252 ph->p_align = dynamic->sh_addralign;
1254 /* put GOT dynamic section address */
1255 put32(s1->got->data, dynamic->sh_addr);
1257 /* relocate the PLT */
1258 if (file_type == TCC_OUTPUT_EXE) {
1259 uint8_t *p, *p_end;
1261 p = s1->plt->data;
1262 p_end = p + s1->plt->data_offset;
1263 if (p < p_end) {
1264 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1265 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1266 p += 16;
1267 while (p < p_end) {
1268 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1269 p += 16;
1274 /* relocate symbols in .dynsym */
1275 sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
1276 for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
1277 sym < sym_end;
1278 sym++) {
1279 if (sym->st_shndx == SHN_UNDEF) {
1280 /* relocate to the PLT if the symbol corresponds
1281 to a PLT entry */
1282 if (sym->st_value)
1283 sym->st_value += s1->plt->sh_addr;
1284 } else if (sym->st_shndx < SHN_LORESERVE) {
1285 /* do symbol relocation */
1286 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1290 /* put dynamic section entries */
1291 dynamic->data_offset = saved_dynamic_data_offset;
1292 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1293 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1294 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1295 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1296 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
1297 put_dt(dynamic, DT_REL, rel_addr);
1298 put_dt(dynamic, DT_RELSZ, rel_size);
1299 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
1300 put_dt(dynamic, DT_NULL, 0);
1303 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1304 ehdr.e_phnum = phnum;
1305 ehdr.e_phoff = sizeof(Elf32_Ehdr);
1308 /* all other sections come after */
1309 for(i = 1; i < s1->nb_sections; i++) {
1310 s = s1->sections[i];
1311 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1312 continue;
1313 section_order[sh_order_index++] = i;
1315 file_offset = (file_offset + s->sh_addralign - 1) &
1316 ~(s->sh_addralign - 1);
1317 s->sh_offset = file_offset;
1318 if (s->sh_type != SHT_NOBITS)
1319 file_offset += s->sh_size;
1322 /* if building executable or DLL, then relocate each section
1323 except the GOT which is already relocated */
1324 if (file_type != TCC_OUTPUT_OBJ) {
1325 relocate_syms(s1, 0);
1327 if (s1->nb_errors != 0) {
1328 fail:
1329 ret = -1;
1330 goto the_end;
1333 /* relocate sections */
1334 /* XXX: ignore sections with allocated relocations ? */
1335 for(i = 1; i < s1->nb_sections; i++) {
1336 s = s1->sections[i];
1337 if (s->reloc && s != s1->got)
1338 relocate_section(s1, s);
1341 /* relocate relocation entries if the relocation tables are
1342 allocated in the executable */
1343 for(i = 1; i < s1->nb_sections; i++) {
1344 s = s1->sections[i];
1345 if ((s->sh_flags & SHF_ALLOC) &&
1346 s->sh_type == SHT_REL) {
1347 relocate_rel(s1, s);
1351 /* get entry point address */
1352 if (file_type == TCC_OUTPUT_EXE)
1353 ehdr.e_entry = (unsigned long)tcc_get_symbol(s1, "_start");
1354 else
1355 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1358 sort_syms(s1, symtab_section);
1360 /* align to 4 */
1361 file_offset = (file_offset + 3) & -4;
1363 /* fill header */
1364 ehdr.e_ident[0] = ELFMAG0;
1365 ehdr.e_ident[1] = ELFMAG1;
1366 ehdr.e_ident[2] = ELFMAG2;
1367 ehdr.e_ident[3] = ELFMAG3;
1368 ehdr.e_ident[4] = ELFCLASS32;
1369 ehdr.e_ident[5] = ELFDATA2LSB;
1370 ehdr.e_ident[6] = EV_CURRENT;
1371 #ifdef __FreeBSD__
1372 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1373 #endif
1374 switch(file_type) {
1375 default:
1376 case TCC_OUTPUT_EXE:
1377 ehdr.e_type = ET_EXEC;
1378 break;
1379 case TCC_OUTPUT_DLL:
1380 ehdr.e_type = ET_DYN;
1381 break;
1382 case TCC_OUTPUT_OBJ:
1383 ehdr.e_type = ET_REL;
1384 break;
1386 ehdr.e_machine = EM_386;
1387 ehdr.e_version = EV_CURRENT;
1388 ehdr.e_shoff = file_offset;
1389 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1390 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1391 ehdr.e_shnum = shnum;
1392 ehdr.e_shstrndx = shnum - 1;
1394 /* write elf file */
1395 if (file_type == TCC_OUTPUT_OBJ)
1396 mode = 0666;
1397 else
1398 mode = 0777;
1399 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
1400 if (fd < 0) {
1401 error_noabort("could not write '%s'", filename);
1402 goto fail;
1404 f = fdopen(fd, "w");
1405 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1406 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1407 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1408 for(i=1;i<s1->nb_sections;i++) {
1409 s = s1->sections[section_order[i]];
1410 if (s->sh_type != SHT_NOBITS) {
1411 while (offset < s->sh_offset) {
1412 fputc(0, f);
1413 offset++;
1415 size = s->sh_size;
1416 fwrite(s->data, 1, size, f);
1417 offset += size;
1420 while (offset < ehdr.e_shoff) {
1421 fputc(0, f);
1422 offset++;
1425 /* output section headers */
1426 for(i=0;i<s1->nb_sections;i++) {
1427 sh = &shdr;
1428 memset(sh, 0, sizeof(Elf32_Shdr));
1429 s = s1->sections[i];
1430 if (s) {
1431 sh->sh_name = s->sh_name;
1432 sh->sh_type = s->sh_type;
1433 sh->sh_flags = s->sh_flags;
1434 sh->sh_entsize = s->sh_entsize;
1435 sh->sh_info = s->sh_info;
1436 if (s->link)
1437 sh->sh_link = s->link->sh_num;
1438 sh->sh_addralign = s->sh_addralign;
1439 sh->sh_addr = s->sh_addr;
1440 sh->sh_offset = s->sh_offset;
1441 sh->sh_size = s->sh_size;
1443 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1445 fclose(f);
1447 ret = 0;
1448 the_end:
1449 tcc_free(s1->symtab_to_dynsym);
1450 tcc_free(section_order);
1451 tcc_free(phdr);
1452 tcc_free(s1->got_offsets);
1453 return ret;
1456 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1458 void *data;
1460 data = tcc_malloc(size);
1461 lseek(fd, file_offset, SEEK_SET);
1462 read(fd, data, size);
1463 return data;
1466 typedef struct SectionMergeInfo {
1467 Section *s; /* corresponding existing section */
1468 unsigned long offset; /* offset of the new section in the existing section */
1469 int new_section; /* true if section 's' was added */
1470 } SectionMergeInfo;
1472 /* load an object file and merge it with current files */
1473 /* XXX: handle correctly stab (debug) info */
1474 static int tcc_load_object_file(TCCState *s1,
1475 int fd, unsigned long file_offset)
1477 Elf32_Ehdr ehdr;
1478 Elf32_Shdr *shdr, *sh;
1479 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1480 unsigned char *strsec, *strtab;
1481 int *old_to_new_syms;
1482 char *sh_name, *name;
1483 SectionMergeInfo *sm_table, *sm;
1484 Elf32_Sym *sym, *symtab;
1485 Elf32_Rel *rel, *rel_end;
1486 Section *s;
1488 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1489 goto fail1;
1490 if (ehdr.e_ident[0] != ELFMAG0 ||
1491 ehdr.e_ident[1] != ELFMAG1 ||
1492 ehdr.e_ident[2] != ELFMAG2 ||
1493 ehdr.e_ident[3] != ELFMAG3)
1494 goto fail1;
1495 /* test if object file */
1496 if (ehdr.e_type != ET_REL)
1497 goto fail1;
1498 /* test CPU specific stuff */
1499 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1500 ehdr.e_machine != EM_386) {
1501 fail1:
1502 error_noabort("invalid object file");
1503 return -1;
1505 /* read sections */
1506 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1507 sizeof(Elf32_Shdr) * ehdr.e_shnum);
1508 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1510 /* load section names */
1511 sh = &shdr[ehdr.e_shstrndx];
1512 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1514 /* load symtab and strtab */
1515 old_to_new_syms = NULL;
1516 symtab = NULL;
1517 strtab = NULL;
1518 nb_syms = 0;
1519 for(i = 1; i < ehdr.e_shnum; i++) {
1520 sh = &shdr[i];
1521 if (sh->sh_type == SHT_SYMTAB) {
1522 if (symtab) {
1523 error_noabort("object must contain only one symtab");
1524 fail:
1525 ret = -1;
1526 goto the_end;
1528 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1529 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1530 sm_table[i].s = symtab_section;
1532 /* now load strtab */
1533 sh = &shdr[sh->sh_link];
1534 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1538 /* now examine each section and try to merge its content with the
1539 ones in memory */
1540 for(i = 1; i < ehdr.e_shnum; i++) {
1541 /* no need to examine section name strtab */
1542 if (i == ehdr.e_shstrndx)
1543 continue;
1544 sh = &shdr[i];
1545 sh_name = strsec + sh->sh_name;
1546 /* ignore sections types we do not handle */
1547 if (sh->sh_type != SHT_PROGBITS &&
1548 sh->sh_type != SHT_REL &&
1549 sh->sh_type != SHT_NOBITS)
1550 continue;
1551 if (sh->sh_addralign < 1)
1552 sh->sh_addralign = 1;
1553 /* find corresponding section, if any */
1554 for(j = 1; j < s1->nb_sections;j++) {
1555 s = s1->sections[j];
1556 if (!strcmp(s->name, sh_name))
1557 goto found;
1559 /* not found: create new section */
1560 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1561 /* take as much info as possible from the section. sh_link and
1562 sh_info will be updated later */
1563 s->sh_addralign = sh->sh_addralign;
1564 s->sh_entsize = sh->sh_entsize;
1565 sm_table[i].new_section = 1;
1566 found:
1567 if (sh->sh_type != s->sh_type) {
1568 error_noabort("invalid section type");
1569 goto fail;
1572 /* align start of section */
1573 offset = s->data_offset;
1574 size = sh->sh_addralign - 1;
1575 offset = (offset + size) & ~size;
1576 if (sh->sh_addralign > s->sh_addralign)
1577 s->sh_addralign = sh->sh_addralign;
1578 s->data_offset = offset;
1579 sm_table[i].offset = offset;
1580 sm_table[i].s = s;
1581 /* concatenate sections */
1582 size = sh->sh_size;
1583 if (sh->sh_type != SHT_NOBITS) {
1584 unsigned char *ptr;
1585 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1586 ptr = section_ptr_add(s, size);
1587 read(fd, ptr, size);
1588 } else {
1589 s->data_offset += size;
1593 /* second short pass to update sh_link and sh_info fields of new
1594 sections */
1595 sm = sm_table;
1596 for(i = 1; i < ehdr.e_shnum; i++) {
1597 s = sm_table[i].s;
1598 if (!s || !sm_table[i].new_section)
1599 continue;
1600 sh = &shdr[i];
1601 if (sh->sh_link > 0)
1602 s->link = sm_table[sh->sh_link].s;
1603 if (sh->sh_type == SHT_REL) {
1604 s->sh_info = sm_table[sh->sh_info].s->sh_num;
1605 /* update backward link */
1606 s1->sections[s->sh_info]->reloc = s;
1610 /* resolve symbols */
1611 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
1613 sym = symtab + 1;
1614 for(i = 1; i < nb_syms; i++, sym++) {
1615 if (sym->st_shndx != SHN_UNDEF &&
1616 sym->st_shndx < SHN_LORESERVE) {
1617 sm = &sm_table[sym->st_shndx];
1618 /* if no corresponding section added, no need to add symbol */
1619 if (!sm->s)
1620 continue;
1621 /* convert section number */
1622 sym->st_shndx = sm->s->sh_num;
1623 /* offset value */
1624 sym->st_value += sm->offset;
1626 /* add symbol */
1627 name = strtab + sym->st_name;
1628 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
1629 sym->st_info, sym->st_shndx, name);
1630 old_to_new_syms[i] = sym_index;
1633 /* third pass to patch relocation entries */
1634 for(i = 1; i < ehdr.e_shnum; i++) {
1635 s = sm_table[i].s;
1636 if (!s)
1637 continue;
1638 sh = &shdr[i];
1639 offset = sm_table[i].offset;
1640 switch(s->sh_type) {
1641 case SHT_REL:
1642 /* take relocation offset information */
1643 offseti = sm_table[sh->sh_info].offset;
1644 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
1645 for(rel = (Elf32_Rel *)(s->data + offset);
1646 rel < rel_end;
1647 rel++) {
1648 int type;
1649 unsigned sym_index;
1650 /* convert symbol index */
1651 type = ELF32_R_TYPE(rel->r_info);
1652 sym_index = ELF32_R_SYM(rel->r_info);
1653 /* NOTE: only one symtab assumed */
1654 if (sym_index >= nb_syms)
1655 goto invalid_reloc;
1656 sym_index = old_to_new_syms[sym_index];
1657 if (!sym_index) {
1658 invalid_reloc:
1659 error_noabort("Invalid relocation entry");
1660 goto fail;
1662 rel->r_info = ELF32_R_INFO(sym_index, type);
1663 /* offset the relocation offset */
1664 rel->r_offset += offseti;
1666 break;
1667 default:
1668 break;
1672 ret = 0;
1673 the_end:
1674 tcc_free(symtab);
1675 tcc_free(strtab);
1676 tcc_free(old_to_new_syms);
1677 tcc_free(sm_table);
1678 tcc_free(strsec);
1679 tcc_free(shdr);
1680 return ret;
1683 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1685 typedef struct ArchiveHeader {
1686 char ar_name[16]; /* name of this member */
1687 char ar_date[12]; /* file mtime */
1688 char ar_uid[6]; /* owner uid; printed as decimal */
1689 char ar_gid[6]; /* owner gid; printed as decimal */
1690 char ar_mode[8]; /* file mode, printed as octal */
1691 char ar_size[10]; /* file size, printed as decimal */
1692 char ar_fmag[2]; /* should contain ARFMAG */
1693 } ArchiveHeader;
1695 static int get_be32(const uint8_t *b)
1697 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
1700 /* load only the objects which resolve undefined symbols */
1701 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
1703 int i, bound, nsyms, sym_index, off, ret;
1704 uint8_t *data;
1705 const char *ar_names, *p;
1706 const uint8_t *ar_index;
1707 Elf32_Sym *sym;
1709 data = tcc_malloc(size);
1710 if (read(fd, data, size) != size)
1711 goto fail;
1712 nsyms = get_be32(data);
1713 ar_index = data + 4;
1714 ar_names = ar_index + nsyms * 4;
1716 do {
1717 bound = 0;
1718 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
1719 sym_index = find_elf_sym(symtab_section, p);
1720 if(sym_index) {
1721 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1722 if(sym->st_shndx == SHN_UNDEF) {
1723 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
1724 #if 0
1725 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
1726 #endif
1727 ++bound;
1728 lseek(fd, off, SEEK_SET);
1729 if(tcc_load_object_file(s1, fd, off) < 0) {
1730 fail:
1731 ret = -1;
1732 goto the_end;
1737 } while(bound);
1738 ret = 0;
1739 the_end:
1740 tcc_free(data);
1741 return ret;
1744 /* load a '.a' file */
1745 static int tcc_load_archive(TCCState *s1, int fd)
1747 ArchiveHeader hdr;
1748 char ar_size[11];
1749 char ar_name[17];
1750 char magic[8];
1751 int size, len, i;
1752 unsigned long file_offset;
1754 /* skip magic which was already checked */
1755 read(fd, magic, sizeof(magic));
1757 for(;;) {
1758 len = read(fd, &hdr, sizeof(hdr));
1759 if (len == 0)
1760 break;
1761 if (len != sizeof(hdr)) {
1762 error_noabort("invalid archive");
1763 return -1;
1765 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
1766 ar_size[sizeof(hdr.ar_size)] = '\0';
1767 size = strtol(ar_size, NULL, 0);
1768 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
1769 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
1770 if (ar_name[i] != ' ')
1771 break;
1773 ar_name[i + 1] = '\0';
1774 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
1775 file_offset = lseek(fd, 0, SEEK_CUR);
1776 /* align to even */
1777 size = (size + 1) & ~1;
1778 if (!strcmp(ar_name, "/")) {
1779 /* coff symbol table : we handle it */
1780 if(s1->alacarte_link)
1781 return tcc_load_alacarte(s1, fd, size);
1782 } else if (!strcmp(ar_name, "//") ||
1783 !strcmp(ar_name, "__.SYMDEF") ||
1784 !strcmp(ar_name, "__.SYMDEF/") ||
1785 !strcmp(ar_name, "ARFILENAMES/")) {
1786 /* skip symbol table or archive names */
1787 } else {
1788 if (tcc_load_object_file(s1, fd, file_offset) < 0)
1789 return -1;
1791 lseek(fd, file_offset + size, SEEK_SET);
1793 return 0;
1796 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
1797 is referenced by the user (so it should be added as DT_NEEDED in
1798 the generated ELF file) */
1799 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
1801 Elf32_Ehdr ehdr;
1802 Elf32_Shdr *shdr, *sh, *sh1;
1803 int i, nb_syms, nb_dts, sym_bind, ret;
1804 Elf32_Sym *sym, *dynsym;
1805 Elf32_Dyn *dt, *dynamic;
1806 unsigned char *dynstr;
1807 const char *name, *soname, *p;
1808 DLLReference *dllref;
1810 read(fd, &ehdr, sizeof(ehdr));
1812 /* test CPU specific stuff */
1813 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1814 ehdr.e_machine != EM_386) {
1815 error_noabort("bad architecture");
1816 return -1;
1819 /* read sections */
1820 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
1822 /* load dynamic section and dynamic symbols */
1823 nb_syms = 0;
1824 nb_dts = 0;
1825 dynamic = NULL;
1826 dynsym = NULL; /* avoid warning */
1827 dynstr = NULL; /* avoid warning */
1828 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
1829 switch(sh->sh_type) {
1830 case SHT_DYNAMIC:
1831 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
1832 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
1833 break;
1834 case SHT_DYNSYM:
1835 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1836 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
1837 sh1 = &shdr[sh->sh_link];
1838 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
1839 break;
1840 default:
1841 break;
1845 /* compute the real library name */
1846 soname = filename;
1847 p = strrchr(soname, '/');
1848 if (p)
1849 soname = p + 1;
1851 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
1852 if (dt->d_tag == DT_SONAME) {
1853 soname = dynstr + dt->d_un.d_val;
1857 /* if the dll is already loaded, do not load it */
1858 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1859 dllref = s1->loaded_dlls[i];
1860 if (!strcmp(soname, dllref->name)) {
1861 /* but update level if needed */
1862 if (level < dllref->level)
1863 dllref->level = level;
1864 ret = 0;
1865 goto the_end;
1869 // printf("loading dll '%s'\n", soname);
1871 /* add the dll and its level */
1872 dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
1873 dllref->level = level;
1874 strcpy(dllref->name, soname);
1875 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
1877 /* add dynamic symbols in dynsym_section */
1878 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
1879 sym_bind = ELF32_ST_BIND(sym->st_info);
1880 if (sym_bind == STB_LOCAL)
1881 continue;
1882 name = dynstr + sym->st_name;
1883 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
1884 sym->st_info, sym->st_shndx, name);
1887 /* load all referenced DLLs */
1888 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
1889 switch(dt->d_tag) {
1890 case DT_NEEDED:
1891 name = dynstr + dt->d_un.d_val;
1892 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1893 dllref = s1->loaded_dlls[i];
1894 if (!strcmp(name, dllref->name))
1895 goto already_loaded;
1897 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
1898 error_noabort("referenced dll '%s' not found", name);
1899 ret = -1;
1900 goto the_end;
1902 already_loaded:
1903 break;
1906 ret = 0;
1907 the_end:
1908 tcc_free(dynstr);
1909 tcc_free(dynsym);
1910 tcc_free(dynamic);
1911 tcc_free(shdr);
1912 return ret;
1915 #define LD_TOK_NAME 256
1916 #define LD_TOK_EOF (-1)
1918 /* return next ld script token */
1919 static int ld_next(TCCState *s1, char *name, int name_size)
1921 int c;
1922 char *q;
1924 redo:
1925 switch(ch) {
1926 case ' ':
1927 case '\t':
1928 case '\f':
1929 case '\v':
1930 case '\r':
1931 case '\n':
1932 inp();
1933 goto redo;
1934 case '/':
1935 minp();
1936 if (ch == '*') {
1937 file->buf_ptr = parse_comment(file->buf_ptr);
1938 ch = file->buf_ptr[0];
1939 goto redo;
1940 } else {
1941 q = name;
1942 *q++ = '/';
1943 goto parse_name;
1945 break;
1946 case 'a' ... 'z':
1947 case 'A' ... 'Z':
1948 case '_':
1949 case '\\':
1950 case '.':
1951 case '$':
1952 case '~':
1953 q = name;
1954 parse_name:
1955 for(;;) {
1956 if (!((ch >= 'a' && ch <= 'z') ||
1957 (ch >= 'A' && ch <= 'Z') ||
1958 (ch >= '0' && ch <= '9') ||
1959 strchr("/.-_+=$:\\,~", ch)))
1960 break;
1961 if ((q - name) < name_size - 1) {
1962 *q++ = ch;
1964 minp();
1966 *q = '\0';
1967 c = LD_TOK_NAME;
1968 break;
1969 case CH_EOF:
1970 c = LD_TOK_EOF;
1971 break;
1972 default:
1973 c = ch;
1974 inp();
1975 break;
1977 #if 0
1978 printf("tok=%c %d\n", c, c);
1979 if (c == LD_TOK_NAME)
1980 printf(" name=%s\n", name);
1981 #endif
1982 return c;
1985 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
1986 files */
1987 static int tcc_load_ldscript(TCCState *s1)
1989 char cmd[64];
1990 char filename[1024];
1991 int t;
1993 ch = file->buf_ptr[0];
1994 ch = handle_eob();
1995 for(;;) {
1996 t = ld_next(s1, cmd, sizeof(cmd));
1997 if (t == LD_TOK_EOF)
1998 return 0;
1999 else if (t != LD_TOK_NAME)
2000 return -1;
2001 if (!strcmp(cmd, "INPUT") ||
2002 !strcmp(cmd, "GROUP")) {
2003 t = ld_next(s1, cmd, sizeof(cmd));
2004 if (t != '(')
2005 expect("(");
2006 t = ld_next(s1, filename, sizeof(filename));
2007 for(;;) {
2008 if (t == LD_TOK_EOF) {
2009 error_noabort("unexpected end of file");
2010 return -1;
2011 } else if (t == ')') {
2012 break;
2013 } else if (t != LD_TOK_NAME) {
2014 error_noabort("filename expected");
2015 return -1;
2017 tcc_add_file(s1, filename);
2018 t = ld_next(s1, filename, sizeof(filename));
2019 if (t == ',') {
2020 t = ld_next(s1, filename, sizeof(filename));
2023 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2024 !strcmp(cmd, "TARGET")) {
2025 /* ignore some commands */
2026 t = ld_next(s1, cmd, sizeof(cmd));
2027 if (t != '(')
2028 expect("(");
2029 for(;;) {
2030 t = ld_next(s1, filename, sizeof(filename));
2031 if (t == LD_TOK_EOF) {
2032 error_noabort("unexpected end of file");
2033 return -1;
2034 } else if (t == ')') {
2035 break;
2038 } else {
2039 return -1;
2042 return 0;