added init_array defines for new ld compatibility
[tinycc.git] / tccelf.c
blob5d9efc9f5a045297c2ab293172da1275dafa311b
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 static void add_init_array_defines(TCCState *s1, const char *section_name)
776 Section *s;
777 long end_offset;
778 char sym_start[1024];
779 char sym_end[1024];
781 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
782 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
784 s = find_section(s1, section_name);
785 if (!s) {
786 end_offset = 0;
787 s = data_section;
788 } else {
789 end_offset = s->data_offset;
792 add_elf_sym(symtab_section,
793 0, 0,
794 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
795 s->sh_num, sym_start);
796 add_elf_sym(symtab_section,
797 end_offset, 0,
798 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
799 s->sh_num, sym_end);
802 /* add tcc runtime libraries */
803 static void tcc_add_runtime(TCCState *s1)
805 char buf[1024];
806 int i;
807 Section *s;
809 if (!s1->nostdlib) {
810 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
811 tcc_add_file(s1, buf);
813 #ifdef CONFIG_TCC_BCHECK
814 if (do_bounds_check) {
815 unsigned long *ptr;
816 Section *init_section;
817 unsigned char *pinit;
818 int sym_index;
820 /* XXX: add an object file to do that */
821 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
822 *ptr = 0;
823 add_elf_sym(symtab_section, 0, 0,
824 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
825 bounds_section->sh_num, "__bounds_start");
826 /* add bound check code */
827 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
828 tcc_add_file(s1, buf);
829 #ifdef TCC_TARGET_I386
830 if (s1->output_type != TCC_OUTPUT_MEMORY) {
831 /* add 'call __bound_init()' in .init section */
832 init_section = find_section(s1, ".init");
833 pinit = section_ptr_add(init_section, 5);
834 pinit[0] = 0xe8;
835 put32(pinit + 1, -4);
836 sym_index = find_elf_sym(symtab_section, "__bound_init");
837 put_elf_reloc(symtab_section, init_section,
838 init_section->data_offset - 4, R_386_PC32, sym_index);
840 #endif
842 #endif
843 /* add libc if not memory output */
844 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
845 tcc_add_library(s1, "c");
846 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
848 /* add various standard linker symbols */
849 add_elf_sym(symtab_section,
850 text_section->data_offset, 0,
851 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
852 text_section->sh_num, "_etext");
853 add_elf_sym(symtab_section,
854 data_section->data_offset, 0,
855 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
856 data_section->sh_num, "_edata");
857 add_elf_sym(symtab_section,
858 bss_section->data_offset, 0,
859 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
860 bss_section->sh_num, "_end");
861 /* horrible new standard ldscript defines */
862 add_init_array_defines(s1, ".preinit_array");
863 add_init_array_defines(s1, ".init_array");
864 add_init_array_defines(s1, ".fini_array");
866 /* add start and stop symbols for sections whose name can be
867 expressed in C */
868 for(i = 1; i < s1->nb_sections; i++) {
869 s = s1->sections[i];
870 if (s->sh_type == SHT_PROGBITS &&
871 (s->sh_flags & SHF_ALLOC)) {
872 const char *p;
873 int ch;
875 /* check if section name can be expressed in C */
876 p = s->name;
877 for(;;) {
878 ch = *p;
879 if (!ch)
880 break;
881 if (!isid(ch) && !isnum(ch))
882 goto next_sec;
883 p++;
885 snprintf(buf, sizeof(buf), "__start_%s", s->name);
886 add_elf_sym(symtab_section,
887 0, 0,
888 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
889 s->sh_num, buf);
890 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
891 add_elf_sym(symtab_section,
892 s->data_offset, 0,
893 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
894 s->sh_num, buf);
896 next_sec: ;
900 /* name of ELF interpreter */
901 #ifdef __FreeBSD__
902 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
903 #else
904 static char elf_interp[] = "/lib/ld-linux.so.2";
905 #endif
907 #define ELF_START_ADDR 0x08048000
908 #define ELF_PAGE_SIZE 0x1000
910 /* output an ELF file */
911 /* XXX: suppress unneeded sections */
912 int tcc_output_file(TCCState *s1, const char *filename)
914 Elf32_Ehdr ehdr;
915 FILE *f;
916 int fd, mode, ret;
917 int *section_order;
918 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
919 unsigned long addr;
920 Section *strsec, *s;
921 Elf32_Shdr shdr, *sh;
922 Elf32_Phdr *phdr, *ph;
923 Section *interp, *dynamic, *dynstr;
924 unsigned long saved_dynamic_data_offset;
925 Elf32_Sym *sym;
926 int type, file_type;
927 unsigned long rel_addr, rel_size;
929 file_type = s1->output_type;
930 s1->nb_errors = 0;
932 if (file_type != TCC_OUTPUT_OBJ)
933 tcc_add_runtime(s1);
935 phdr = NULL;
936 section_order = NULL;
937 interp = NULL;
938 dynamic = NULL;
939 dynstr = NULL; /* avoid warning */
940 saved_dynamic_data_offset = 0; /* avoid warning */
942 if (file_type != TCC_OUTPUT_OBJ) {
944 relocate_common_syms();
946 if (!s1->static_link) {
947 const char *name;
948 int sym_index, index;
949 Elf32_Sym *esym, *sym_end;
951 if (file_type == TCC_OUTPUT_EXE) {
952 char *ptr;
953 /* add interpreter section only if executable */
954 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
955 interp->sh_addralign = 1;
956 ptr = section_ptr_add(interp, sizeof(elf_interp));
957 strcpy(ptr, elf_interp);
960 /* add dynamic symbol table */
961 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
962 ".dynstr",
963 ".hash", SHF_ALLOC);
964 dynstr = s1->dynsym->link;
966 /* add dynamic section */
967 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
968 SHF_ALLOC | SHF_WRITE);
969 dynamic->link = dynstr;
970 dynamic->sh_entsize = sizeof(Elf32_Dyn);
972 /* add PLT */
973 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
974 SHF_ALLOC | SHF_EXECINSTR);
975 s1->plt->sh_entsize = 4;
977 build_got(s1);
979 /* scan for undefined symbols and see if they are in the
980 dynamic symbols. If a symbol STT_FUNC is found, then we
981 add it in the PLT. If a symbol STT_OBJECT is found, we
982 add it in the .bss section with a suitable relocation */
983 sym_end = (Elf32_Sym *)(symtab_section->data +
984 symtab_section->data_offset);
985 if (file_type == TCC_OUTPUT_EXE) {
986 for(sym = (Elf32_Sym *)symtab_section->data + 1;
987 sym < sym_end;
988 sym++) {
989 if (sym->st_shndx == SHN_UNDEF) {
990 name = symtab_section->link->data + sym->st_name;
991 sym_index = find_elf_sym(s1->dynsymtab_section, name);
992 if (sym_index) {
993 esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
994 type = ELF32_ST_TYPE(esym->st_info);
995 if (type == STT_FUNC) {
996 put_got_entry(s1, R_386_JMP_SLOT, esym->st_size,
997 esym->st_info,
998 sym - (Elf32_Sym *)symtab_section->data);
999 } else if (type == STT_OBJECT) {
1000 unsigned long offset;
1001 offset = bss_section->data_offset;
1002 /* XXX: which alignment ? */
1003 offset = (offset + 16 - 1) & -16;
1004 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1005 esym->st_info, 0,
1006 bss_section->sh_num, name);
1007 put_elf_reloc(s1->dynsym, bss_section,
1008 offset, R_386_COPY, index);
1009 offset += esym->st_size;
1010 bss_section->data_offset = offset;
1012 } else {
1013 /* STB_WEAK undefined symbols are accepted */
1014 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1015 it */
1016 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
1017 !strcmp(name, "_fp_hw")) {
1018 } else {
1019 error_noabort("undefined symbol '%s'", name);
1022 } else if (s1->rdynamic &&
1023 ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1024 /* if -rdynamic option, then export all non
1025 local symbols */
1026 name = symtab_section->link->data + sym->st_name;
1027 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1028 sym->st_info, 0,
1029 sym->st_shndx, name);
1033 if (s1->nb_errors)
1034 goto fail;
1036 /* now look at unresolved dynamic symbols and export
1037 corresponding symbol */
1038 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
1039 s1->dynsymtab_section->data_offset);
1040 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
1041 esym < sym_end;
1042 esym++) {
1043 if (esym->st_shndx == SHN_UNDEF) {
1044 name = s1->dynsymtab_section->link->data + esym->st_name;
1045 sym_index = find_elf_sym(symtab_section, name);
1046 if (sym_index) {
1047 /* XXX: avoid adding a symbol if already
1048 present because of -rdynamic ? */
1049 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1050 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1051 sym->st_info, 0,
1052 sym->st_shndx, name);
1053 } else {
1054 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
1055 /* weak symbols can stay undefined */
1056 } else {
1057 warning("undefined dynamic symbol '%s'", name);
1062 } else {
1063 int nb_syms;
1064 /* shared library case : we simply export all the global symbols */
1065 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
1066 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1067 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1068 sym < sym_end;
1069 sym++) {
1070 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1071 name = symtab_section->link->data + sym->st_name;
1072 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1073 sym->st_info, 0,
1074 sym->st_shndx, name);
1075 s1->symtab_to_dynsym[sym -
1076 (Elf32_Sym *)symtab_section->data] =
1077 index;
1082 build_got_entries(s1);
1084 /* add a list of needed dlls */
1085 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1086 DLLReference *dllref = s1->loaded_dlls[i];
1087 if (dllref->level == 0)
1088 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1090 /* XXX: currently, since we do not handle PIC code, we
1091 must relocate the readonly segments */
1092 if (file_type == TCC_OUTPUT_DLL)
1093 put_dt(dynamic, DT_TEXTREL, 0);
1095 /* add necessary space for other entries */
1096 saved_dynamic_data_offset = dynamic->data_offset;
1097 dynamic->data_offset += 8 * 9;
1098 } else {
1099 /* still need to build got entries in case of static link */
1100 build_got_entries(s1);
1104 memset(&ehdr, 0, sizeof(ehdr));
1106 /* we add a section for symbols */
1107 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1108 put_elf_str(strsec, "");
1110 /* compute number of sections */
1111 shnum = s1->nb_sections;
1113 /* this array is used to reorder sections in the output file */
1114 section_order = tcc_malloc(sizeof(int) * shnum);
1115 section_order[0] = 0;
1116 sh_order_index = 1;
1118 /* compute number of program headers */
1119 switch(file_type) {
1120 default:
1121 case TCC_OUTPUT_OBJ:
1122 phnum = 0;
1123 break;
1124 case TCC_OUTPUT_EXE:
1125 if (!s1->static_link)
1126 phnum = 4;
1127 else
1128 phnum = 2;
1129 break;
1130 case TCC_OUTPUT_DLL:
1131 phnum = 3;
1132 break;
1135 /* allocate strings for section names and decide if an unallocated
1136 section should be output */
1137 /* NOTE: the strsec section comes last, so its size is also
1138 correct ! */
1139 for(i = 1; i < s1->nb_sections; i++) {
1140 s = s1->sections[i];
1141 s->sh_name = put_elf_str(strsec, s->name);
1142 /* when generating a DLL, we include relocations but we may
1143 patch them */
1144 if (file_type == TCC_OUTPUT_DLL &&
1145 s->sh_type == SHT_REL &&
1146 !(s->sh_flags & SHF_ALLOC)) {
1147 prepare_dynamic_rel(s1, s);
1148 } else if (do_debug ||
1149 file_type == TCC_OUTPUT_OBJ ||
1150 (s->sh_flags & SHF_ALLOC) ||
1151 i == (s1->nb_sections - 1)) {
1152 /* we output all sections if debug or object file */
1153 s->sh_size = s->data_offset;
1157 /* allocate program segment headers */
1158 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1160 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1161 if (phnum > 0) {
1162 /* compute section to program header mapping */
1163 if (file_type == TCC_OUTPUT_DLL)
1164 addr = 0;
1165 else
1166 addr = ELF_START_ADDR;
1168 /* dynamic relocation table information, for .dynamic section */
1169 rel_size = 0;
1170 rel_addr = 0;
1172 /* compute address after headers */
1173 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1175 /* leave one program header for the program interpreter */
1176 ph = &phdr[0];
1177 if (interp)
1178 ph++;
1180 for(j = 0; j < 2; j++) {
1181 ph->p_type = PT_LOAD;
1182 if (j == 0)
1183 ph->p_flags = PF_R | PF_X;
1184 else
1185 ph->p_flags = PF_R | PF_W;
1186 ph->p_align = ELF_PAGE_SIZE;
1188 /* we do the following ordering: interp, symbol tables,
1189 relocations, progbits, nobits */
1190 /* XXX: do faster and simpler sorting */
1191 for(k = 0; k < 5; k++) {
1192 for(i = 1; i < s1->nb_sections; i++) {
1193 s = s1->sections[i];
1194 /* compute if section should be included */
1195 if (j == 0) {
1196 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1197 SHF_ALLOC)
1198 continue;
1199 } else {
1200 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1201 (SHF_ALLOC | SHF_WRITE))
1202 continue;
1204 if (s == interp) {
1205 if (k != 0)
1206 continue;
1207 } else if (s->sh_type == SHT_DYNSYM ||
1208 s->sh_type == SHT_STRTAB ||
1209 s->sh_type == SHT_HASH) {
1210 if (k != 1)
1211 continue;
1212 } else if (s->sh_type == SHT_REL) {
1213 if (k != 2)
1214 continue;
1215 } else if (s->sh_type == SHT_NOBITS) {
1216 if (k != 4)
1217 continue;
1218 } else {
1219 if (k != 3)
1220 continue;
1222 section_order[sh_order_index++] = i;
1224 /* section matches: we align it and add its size */
1225 tmp = file_offset;
1226 file_offset = (file_offset + s->sh_addralign - 1) &
1227 ~(s->sh_addralign - 1);
1228 s->sh_offset = file_offset;
1229 addr += file_offset - tmp;
1230 s->sh_addr = addr;
1232 /* update program header infos */
1233 if (ph->p_offset == 0) {
1234 ph->p_offset = file_offset;
1235 ph->p_vaddr = addr;
1236 ph->p_paddr = ph->p_vaddr;
1238 /* update dynamic relocation infos */
1239 if (s->sh_type == SHT_REL) {
1240 if (rel_size == 0)
1241 rel_addr = addr;
1242 rel_size += s->sh_size;
1244 addr += s->sh_size;
1245 if (s->sh_type != SHT_NOBITS)
1246 file_offset += s->sh_size;
1249 ph->p_filesz = file_offset - ph->p_offset;
1250 ph->p_memsz = addr - ph->p_vaddr;
1251 ph++;
1252 /* if in the middle of a page, we duplicate the page in
1253 memory so that one copy is RX and the other is RW */
1254 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1255 addr += ELF_PAGE_SIZE;
1258 /* if interpreter, then add corresponing program header */
1259 if (interp) {
1260 ph = &phdr[0];
1262 ph->p_type = PT_INTERP;
1263 ph->p_offset = interp->sh_offset;
1264 ph->p_vaddr = interp->sh_addr;
1265 ph->p_paddr = ph->p_vaddr;
1266 ph->p_filesz = interp->sh_size;
1267 ph->p_memsz = interp->sh_size;
1268 ph->p_flags = PF_R;
1269 ph->p_align = interp->sh_addralign;
1272 /* if dynamic section, then add corresponing program header */
1273 if (dynamic) {
1274 Elf32_Sym *sym_end;
1276 ph = &phdr[phnum - 1];
1278 ph->p_type = PT_DYNAMIC;
1279 ph->p_offset = dynamic->sh_offset;
1280 ph->p_vaddr = dynamic->sh_addr;
1281 ph->p_paddr = ph->p_vaddr;
1282 ph->p_filesz = dynamic->sh_size;
1283 ph->p_memsz = dynamic->sh_size;
1284 ph->p_flags = PF_R | PF_W;
1285 ph->p_align = dynamic->sh_addralign;
1287 /* put GOT dynamic section address */
1288 put32(s1->got->data, dynamic->sh_addr);
1290 /* relocate the PLT */
1291 if (file_type == TCC_OUTPUT_EXE) {
1292 uint8_t *p, *p_end;
1294 p = s1->plt->data;
1295 p_end = p + s1->plt->data_offset;
1296 if (p < p_end) {
1297 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1298 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1299 p += 16;
1300 while (p < p_end) {
1301 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1302 p += 16;
1307 /* relocate symbols in .dynsym */
1308 sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
1309 for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
1310 sym < sym_end;
1311 sym++) {
1312 if (sym->st_shndx == SHN_UNDEF) {
1313 /* relocate to the PLT if the symbol corresponds
1314 to a PLT entry */
1315 if (sym->st_value)
1316 sym->st_value += s1->plt->sh_addr;
1317 } else if (sym->st_shndx < SHN_LORESERVE) {
1318 /* do symbol relocation */
1319 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1323 /* put dynamic section entries */
1324 dynamic->data_offset = saved_dynamic_data_offset;
1325 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1326 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1327 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1328 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1329 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
1330 put_dt(dynamic, DT_REL, rel_addr);
1331 put_dt(dynamic, DT_RELSZ, rel_size);
1332 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
1333 put_dt(dynamic, DT_NULL, 0);
1336 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1337 ehdr.e_phnum = phnum;
1338 ehdr.e_phoff = sizeof(Elf32_Ehdr);
1341 /* all other sections come after */
1342 for(i = 1; i < s1->nb_sections; i++) {
1343 s = s1->sections[i];
1344 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1345 continue;
1346 section_order[sh_order_index++] = i;
1348 file_offset = (file_offset + s->sh_addralign - 1) &
1349 ~(s->sh_addralign - 1);
1350 s->sh_offset = file_offset;
1351 if (s->sh_type != SHT_NOBITS)
1352 file_offset += s->sh_size;
1355 /* if building executable or DLL, then relocate each section
1356 except the GOT which is already relocated */
1357 if (file_type != TCC_OUTPUT_OBJ) {
1358 relocate_syms(s1, 0);
1360 if (s1->nb_errors != 0) {
1361 fail:
1362 ret = -1;
1363 goto the_end;
1366 /* relocate sections */
1367 /* XXX: ignore sections with allocated relocations ? */
1368 for(i = 1; i < s1->nb_sections; i++) {
1369 s = s1->sections[i];
1370 if (s->reloc && s != s1->got)
1371 relocate_section(s1, s);
1374 /* relocate relocation entries if the relocation tables are
1375 allocated in the executable */
1376 for(i = 1; i < s1->nb_sections; i++) {
1377 s = s1->sections[i];
1378 if ((s->sh_flags & SHF_ALLOC) &&
1379 s->sh_type == SHT_REL) {
1380 relocate_rel(s1, s);
1384 /* get entry point address */
1385 if (file_type == TCC_OUTPUT_EXE)
1386 ehdr.e_entry = (unsigned long)tcc_get_symbol(s1, "_start");
1387 else
1388 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1391 sort_syms(s1, symtab_section);
1393 /* align to 4 */
1394 file_offset = (file_offset + 3) & -4;
1396 /* fill header */
1397 ehdr.e_ident[0] = ELFMAG0;
1398 ehdr.e_ident[1] = ELFMAG1;
1399 ehdr.e_ident[2] = ELFMAG2;
1400 ehdr.e_ident[3] = ELFMAG3;
1401 ehdr.e_ident[4] = ELFCLASS32;
1402 ehdr.e_ident[5] = ELFDATA2LSB;
1403 ehdr.e_ident[6] = EV_CURRENT;
1404 #ifdef __FreeBSD__
1405 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1406 #endif
1407 switch(file_type) {
1408 default:
1409 case TCC_OUTPUT_EXE:
1410 ehdr.e_type = ET_EXEC;
1411 break;
1412 case TCC_OUTPUT_DLL:
1413 ehdr.e_type = ET_DYN;
1414 break;
1415 case TCC_OUTPUT_OBJ:
1416 ehdr.e_type = ET_REL;
1417 break;
1419 ehdr.e_machine = EM_386;
1420 ehdr.e_version = EV_CURRENT;
1421 ehdr.e_shoff = file_offset;
1422 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1423 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1424 ehdr.e_shnum = shnum;
1425 ehdr.e_shstrndx = shnum - 1;
1427 /* write elf file */
1428 if (file_type == TCC_OUTPUT_OBJ)
1429 mode = 0666;
1430 else
1431 mode = 0777;
1432 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
1433 if (fd < 0) {
1434 error_noabort("could not write '%s'", filename);
1435 goto fail;
1437 f = fdopen(fd, "w");
1438 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1439 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1440 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1441 for(i=1;i<s1->nb_sections;i++) {
1442 s = s1->sections[section_order[i]];
1443 if (s->sh_type != SHT_NOBITS) {
1444 while (offset < s->sh_offset) {
1445 fputc(0, f);
1446 offset++;
1448 size = s->sh_size;
1449 fwrite(s->data, 1, size, f);
1450 offset += size;
1453 while (offset < ehdr.e_shoff) {
1454 fputc(0, f);
1455 offset++;
1458 /* output section headers */
1459 for(i=0;i<s1->nb_sections;i++) {
1460 sh = &shdr;
1461 memset(sh, 0, sizeof(Elf32_Shdr));
1462 s = s1->sections[i];
1463 if (s) {
1464 sh->sh_name = s->sh_name;
1465 sh->sh_type = s->sh_type;
1466 sh->sh_flags = s->sh_flags;
1467 sh->sh_entsize = s->sh_entsize;
1468 sh->sh_info = s->sh_info;
1469 if (s->link)
1470 sh->sh_link = s->link->sh_num;
1471 sh->sh_addralign = s->sh_addralign;
1472 sh->sh_addr = s->sh_addr;
1473 sh->sh_offset = s->sh_offset;
1474 sh->sh_size = s->sh_size;
1476 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1478 fclose(f);
1480 ret = 0;
1481 the_end:
1482 tcc_free(s1->symtab_to_dynsym);
1483 tcc_free(section_order);
1484 tcc_free(phdr);
1485 tcc_free(s1->got_offsets);
1486 return ret;
1489 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1491 void *data;
1493 data = tcc_malloc(size);
1494 lseek(fd, file_offset, SEEK_SET);
1495 read(fd, data, size);
1496 return data;
1499 typedef struct SectionMergeInfo {
1500 Section *s; /* corresponding existing section */
1501 unsigned long offset; /* offset of the new section in the existing section */
1502 int new_section; /* true if section 's' was added */
1503 } SectionMergeInfo;
1505 /* load an object file and merge it with current files */
1506 /* XXX: handle correctly stab (debug) info */
1507 static int tcc_load_object_file(TCCState *s1,
1508 int fd, unsigned long file_offset)
1510 Elf32_Ehdr ehdr;
1511 Elf32_Shdr *shdr, *sh;
1512 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1513 unsigned char *strsec, *strtab;
1514 int *old_to_new_syms;
1515 char *sh_name, *name;
1516 SectionMergeInfo *sm_table, *sm;
1517 Elf32_Sym *sym, *symtab;
1518 Elf32_Rel *rel, *rel_end;
1519 Section *s;
1521 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1522 goto fail1;
1523 if (ehdr.e_ident[0] != ELFMAG0 ||
1524 ehdr.e_ident[1] != ELFMAG1 ||
1525 ehdr.e_ident[2] != ELFMAG2 ||
1526 ehdr.e_ident[3] != ELFMAG3)
1527 goto fail1;
1528 /* test if object file */
1529 if (ehdr.e_type != ET_REL)
1530 goto fail1;
1531 /* test CPU specific stuff */
1532 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1533 ehdr.e_machine != EM_386) {
1534 fail1:
1535 error_noabort("invalid object file");
1536 return -1;
1538 /* read sections */
1539 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1540 sizeof(Elf32_Shdr) * ehdr.e_shnum);
1541 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1543 /* load section names */
1544 sh = &shdr[ehdr.e_shstrndx];
1545 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1547 /* load symtab and strtab */
1548 old_to_new_syms = NULL;
1549 symtab = NULL;
1550 strtab = NULL;
1551 nb_syms = 0;
1552 for(i = 1; i < ehdr.e_shnum; i++) {
1553 sh = &shdr[i];
1554 if (sh->sh_type == SHT_SYMTAB) {
1555 if (symtab) {
1556 error_noabort("object must contain only one symtab");
1557 fail:
1558 ret = -1;
1559 goto the_end;
1561 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1562 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1563 sm_table[i].s = symtab_section;
1565 /* now load strtab */
1566 sh = &shdr[sh->sh_link];
1567 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1571 /* now examine each section and try to merge its content with the
1572 ones in memory */
1573 for(i = 1; i < ehdr.e_shnum; i++) {
1574 /* no need to examine section name strtab */
1575 if (i == ehdr.e_shstrndx)
1576 continue;
1577 sh = &shdr[i];
1578 sh_name = strsec + sh->sh_name;
1579 /* ignore sections types we do not handle */
1580 if (sh->sh_type != SHT_PROGBITS &&
1581 sh->sh_type != SHT_REL &&
1582 sh->sh_type != SHT_NOBITS)
1583 continue;
1584 if (sh->sh_addralign < 1)
1585 sh->sh_addralign = 1;
1586 /* find corresponding section, if any */
1587 for(j = 1; j < s1->nb_sections;j++) {
1588 s = s1->sections[j];
1589 if (!strcmp(s->name, sh_name))
1590 goto found;
1592 /* not found: create new section */
1593 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1594 /* take as much info as possible from the section. sh_link and
1595 sh_info will be updated later */
1596 s->sh_addralign = sh->sh_addralign;
1597 s->sh_entsize = sh->sh_entsize;
1598 sm_table[i].new_section = 1;
1599 found:
1600 if (sh->sh_type != s->sh_type) {
1601 error_noabort("invalid section type");
1602 goto fail;
1605 /* align start of section */
1606 offset = s->data_offset;
1607 size = sh->sh_addralign - 1;
1608 offset = (offset + size) & ~size;
1609 if (sh->sh_addralign > s->sh_addralign)
1610 s->sh_addralign = sh->sh_addralign;
1611 s->data_offset = offset;
1612 sm_table[i].offset = offset;
1613 sm_table[i].s = s;
1614 /* concatenate sections */
1615 size = sh->sh_size;
1616 if (sh->sh_type != SHT_NOBITS) {
1617 unsigned char *ptr;
1618 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1619 ptr = section_ptr_add(s, size);
1620 read(fd, ptr, size);
1621 } else {
1622 s->data_offset += size;
1626 /* second short pass to update sh_link and sh_info fields of new
1627 sections */
1628 sm = sm_table;
1629 for(i = 1; i < ehdr.e_shnum; i++) {
1630 s = sm_table[i].s;
1631 if (!s || !sm_table[i].new_section)
1632 continue;
1633 sh = &shdr[i];
1634 if (sh->sh_link > 0)
1635 s->link = sm_table[sh->sh_link].s;
1636 if (sh->sh_type == SHT_REL) {
1637 s->sh_info = sm_table[sh->sh_info].s->sh_num;
1638 /* update backward link */
1639 s1->sections[s->sh_info]->reloc = s;
1643 /* resolve symbols */
1644 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
1646 sym = symtab + 1;
1647 for(i = 1; i < nb_syms; i++, sym++) {
1648 if (sym->st_shndx != SHN_UNDEF &&
1649 sym->st_shndx < SHN_LORESERVE) {
1650 sm = &sm_table[sym->st_shndx];
1651 /* if no corresponding section added, no need to add symbol */
1652 if (!sm->s)
1653 continue;
1654 /* convert section number */
1655 sym->st_shndx = sm->s->sh_num;
1656 /* offset value */
1657 sym->st_value += sm->offset;
1659 /* add symbol */
1660 name = strtab + sym->st_name;
1661 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
1662 sym->st_info, sym->st_shndx, name);
1663 old_to_new_syms[i] = sym_index;
1666 /* third pass to patch relocation entries */
1667 for(i = 1; i < ehdr.e_shnum; i++) {
1668 s = sm_table[i].s;
1669 if (!s)
1670 continue;
1671 sh = &shdr[i];
1672 offset = sm_table[i].offset;
1673 switch(s->sh_type) {
1674 case SHT_REL:
1675 /* take relocation offset information */
1676 offseti = sm_table[sh->sh_info].offset;
1677 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
1678 for(rel = (Elf32_Rel *)(s->data + offset);
1679 rel < rel_end;
1680 rel++) {
1681 int type;
1682 unsigned sym_index;
1683 /* convert symbol index */
1684 type = ELF32_R_TYPE(rel->r_info);
1685 sym_index = ELF32_R_SYM(rel->r_info);
1686 /* NOTE: only one symtab assumed */
1687 if (sym_index >= nb_syms)
1688 goto invalid_reloc;
1689 sym_index = old_to_new_syms[sym_index];
1690 if (!sym_index) {
1691 invalid_reloc:
1692 error_noabort("Invalid relocation entry");
1693 goto fail;
1695 rel->r_info = ELF32_R_INFO(sym_index, type);
1696 /* offset the relocation offset */
1697 rel->r_offset += offseti;
1699 break;
1700 default:
1701 break;
1705 ret = 0;
1706 the_end:
1707 tcc_free(symtab);
1708 tcc_free(strtab);
1709 tcc_free(old_to_new_syms);
1710 tcc_free(sm_table);
1711 tcc_free(strsec);
1712 tcc_free(shdr);
1713 return ret;
1716 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1718 typedef struct ArchiveHeader {
1719 char ar_name[16]; /* name of this member */
1720 char ar_date[12]; /* file mtime */
1721 char ar_uid[6]; /* owner uid; printed as decimal */
1722 char ar_gid[6]; /* owner gid; printed as decimal */
1723 char ar_mode[8]; /* file mode, printed as octal */
1724 char ar_size[10]; /* file size, printed as decimal */
1725 char ar_fmag[2]; /* should contain ARFMAG */
1726 } ArchiveHeader;
1728 static int get_be32(const uint8_t *b)
1730 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
1733 /* load only the objects which resolve undefined symbols */
1734 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
1736 int i, bound, nsyms, sym_index, off, ret;
1737 uint8_t *data;
1738 const char *ar_names, *p;
1739 const uint8_t *ar_index;
1740 Elf32_Sym *sym;
1742 data = tcc_malloc(size);
1743 if (read(fd, data, size) != size)
1744 goto fail;
1745 nsyms = get_be32(data);
1746 ar_index = data + 4;
1747 ar_names = ar_index + nsyms * 4;
1749 do {
1750 bound = 0;
1751 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
1752 sym_index = find_elf_sym(symtab_section, p);
1753 if(sym_index) {
1754 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1755 if(sym->st_shndx == SHN_UNDEF) {
1756 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
1757 #if 0
1758 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
1759 #endif
1760 ++bound;
1761 lseek(fd, off, SEEK_SET);
1762 if(tcc_load_object_file(s1, fd, off) < 0) {
1763 fail:
1764 ret = -1;
1765 goto the_end;
1770 } while(bound);
1771 ret = 0;
1772 the_end:
1773 tcc_free(data);
1774 return ret;
1777 /* load a '.a' file */
1778 static int tcc_load_archive(TCCState *s1, int fd)
1780 ArchiveHeader hdr;
1781 char ar_size[11];
1782 char ar_name[17];
1783 char magic[8];
1784 int size, len, i;
1785 unsigned long file_offset;
1787 /* skip magic which was already checked */
1788 read(fd, magic, sizeof(magic));
1790 for(;;) {
1791 len = read(fd, &hdr, sizeof(hdr));
1792 if (len == 0)
1793 break;
1794 if (len != sizeof(hdr)) {
1795 error_noabort("invalid archive");
1796 return -1;
1798 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
1799 ar_size[sizeof(hdr.ar_size)] = '\0';
1800 size = strtol(ar_size, NULL, 0);
1801 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
1802 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
1803 if (ar_name[i] != ' ')
1804 break;
1806 ar_name[i + 1] = '\0';
1807 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
1808 file_offset = lseek(fd, 0, SEEK_CUR);
1809 /* align to even */
1810 size = (size + 1) & ~1;
1811 if (!strcmp(ar_name, "/")) {
1812 /* coff symbol table : we handle it */
1813 if(s1->alacarte_link)
1814 return tcc_load_alacarte(s1, fd, size);
1815 } else if (!strcmp(ar_name, "//") ||
1816 !strcmp(ar_name, "__.SYMDEF") ||
1817 !strcmp(ar_name, "__.SYMDEF/") ||
1818 !strcmp(ar_name, "ARFILENAMES/")) {
1819 /* skip symbol table or archive names */
1820 } else {
1821 if (tcc_load_object_file(s1, fd, file_offset) < 0)
1822 return -1;
1824 lseek(fd, file_offset + size, SEEK_SET);
1826 return 0;
1829 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
1830 is referenced by the user (so it should be added as DT_NEEDED in
1831 the generated ELF file) */
1832 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
1834 Elf32_Ehdr ehdr;
1835 Elf32_Shdr *shdr, *sh, *sh1;
1836 int i, nb_syms, nb_dts, sym_bind, ret;
1837 Elf32_Sym *sym, *dynsym;
1838 Elf32_Dyn *dt, *dynamic;
1839 unsigned char *dynstr;
1840 const char *name, *soname, *p;
1841 DLLReference *dllref;
1843 read(fd, &ehdr, sizeof(ehdr));
1845 /* test CPU specific stuff */
1846 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1847 ehdr.e_machine != EM_386) {
1848 error_noabort("bad architecture");
1849 return -1;
1852 /* read sections */
1853 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
1855 /* load dynamic section and dynamic symbols */
1856 nb_syms = 0;
1857 nb_dts = 0;
1858 dynamic = NULL;
1859 dynsym = NULL; /* avoid warning */
1860 dynstr = NULL; /* avoid warning */
1861 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
1862 switch(sh->sh_type) {
1863 case SHT_DYNAMIC:
1864 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
1865 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
1866 break;
1867 case SHT_DYNSYM:
1868 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1869 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
1870 sh1 = &shdr[sh->sh_link];
1871 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
1872 break;
1873 default:
1874 break;
1878 /* compute the real library name */
1879 soname = filename;
1880 p = strrchr(soname, '/');
1881 if (p)
1882 soname = p + 1;
1884 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
1885 if (dt->d_tag == DT_SONAME) {
1886 soname = dynstr + dt->d_un.d_val;
1890 /* if the dll is already loaded, do not load it */
1891 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1892 dllref = s1->loaded_dlls[i];
1893 if (!strcmp(soname, dllref->name)) {
1894 /* but update level if needed */
1895 if (level < dllref->level)
1896 dllref->level = level;
1897 ret = 0;
1898 goto the_end;
1902 // printf("loading dll '%s'\n", soname);
1904 /* add the dll and its level */
1905 dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
1906 dllref->level = level;
1907 strcpy(dllref->name, soname);
1908 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
1910 /* add dynamic symbols in dynsym_section */
1911 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
1912 sym_bind = ELF32_ST_BIND(sym->st_info);
1913 if (sym_bind == STB_LOCAL)
1914 continue;
1915 name = dynstr + sym->st_name;
1916 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
1917 sym->st_info, sym->st_shndx, name);
1920 /* load all referenced DLLs */
1921 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
1922 switch(dt->d_tag) {
1923 case DT_NEEDED:
1924 name = dynstr + dt->d_un.d_val;
1925 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1926 dllref = s1->loaded_dlls[i];
1927 if (!strcmp(name, dllref->name))
1928 goto already_loaded;
1930 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
1931 error_noabort("referenced dll '%s' not found", name);
1932 ret = -1;
1933 goto the_end;
1935 already_loaded:
1936 break;
1939 ret = 0;
1940 the_end:
1941 tcc_free(dynstr);
1942 tcc_free(dynsym);
1943 tcc_free(dynamic);
1944 tcc_free(shdr);
1945 return ret;
1948 #define LD_TOK_NAME 256
1949 #define LD_TOK_EOF (-1)
1951 /* return next ld script token */
1952 static int ld_next(TCCState *s1, char *name, int name_size)
1954 int c;
1955 char *q;
1957 redo:
1958 switch(ch) {
1959 case ' ':
1960 case '\t':
1961 case '\f':
1962 case '\v':
1963 case '\r':
1964 case '\n':
1965 inp();
1966 goto redo;
1967 case '/':
1968 minp();
1969 if (ch == '*') {
1970 file->buf_ptr = parse_comment(file->buf_ptr);
1971 ch = file->buf_ptr[0];
1972 goto redo;
1973 } else {
1974 q = name;
1975 *q++ = '/';
1976 goto parse_name;
1978 break;
1979 case 'a' ... 'z':
1980 case 'A' ... 'Z':
1981 case '_':
1982 case '\\':
1983 case '.':
1984 case '$':
1985 case '~':
1986 q = name;
1987 parse_name:
1988 for(;;) {
1989 if (!((ch >= 'a' && ch <= 'z') ||
1990 (ch >= 'A' && ch <= 'Z') ||
1991 (ch >= '0' && ch <= '9') ||
1992 strchr("/.-_+=$:\\,~", ch)))
1993 break;
1994 if ((q - name) < name_size - 1) {
1995 *q++ = ch;
1997 minp();
1999 *q = '\0';
2000 c = LD_TOK_NAME;
2001 break;
2002 case CH_EOF:
2003 c = LD_TOK_EOF;
2004 break;
2005 default:
2006 c = ch;
2007 inp();
2008 break;
2010 #if 0
2011 printf("tok=%c %d\n", c, c);
2012 if (c == LD_TOK_NAME)
2013 printf(" name=%s\n", name);
2014 #endif
2015 return c;
2018 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2019 files */
2020 static int tcc_load_ldscript(TCCState *s1)
2022 char cmd[64];
2023 char filename[1024];
2024 int t;
2026 ch = file->buf_ptr[0];
2027 ch = handle_eob();
2028 for(;;) {
2029 t = ld_next(s1, cmd, sizeof(cmd));
2030 if (t == LD_TOK_EOF)
2031 return 0;
2032 else if (t != LD_TOK_NAME)
2033 return -1;
2034 if (!strcmp(cmd, "INPUT") ||
2035 !strcmp(cmd, "GROUP")) {
2036 t = ld_next(s1, cmd, sizeof(cmd));
2037 if (t != '(')
2038 expect("(");
2039 t = ld_next(s1, filename, sizeof(filename));
2040 for(;;) {
2041 if (t == LD_TOK_EOF) {
2042 error_noabort("unexpected end of file");
2043 return -1;
2044 } else if (t == ')') {
2045 break;
2046 } else if (t != LD_TOK_NAME) {
2047 error_noabort("filename expected");
2048 return -1;
2050 tcc_add_file(s1, filename);
2051 t = ld_next(s1, filename, sizeof(filename));
2052 if (t == ',') {
2053 t = ld_next(s1, filename, sizeof(filename));
2056 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2057 !strcmp(cmd, "TARGET")) {
2058 /* ignore some commands */
2059 t = ld_next(s1, cmd, sizeof(cmd));
2060 if (t != '(')
2061 expect("(");
2062 for(;;) {
2063 t = ld_next(s1, filename, sizeof(filename));
2064 if (t == LD_TOK_EOF) {
2065 error_noabort("unexpected end of file");
2066 return -1;
2067 } else if (t == ')') {
2068 break;
2071 } else {
2072 return -1;
2075 return 0;