changed tcc_get_symbol() prototype
[tinycc.git] / tccelf.c
blobe5e69d36dcef3040cb4ae812cded42327e10da12
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 int tcc_get_symbol(TCCState *s, unsigned long *pval, 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 return -1;
165 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
166 *pval = sym->st_value;
167 return 0;
170 void *tcc_get_symbol_err(TCCState *s, const char *name)
172 unsigned long val;
173 if (tcc_get_symbol(s, &val, name) < 0)
174 error("%s not defined", name);
175 return (void *)val;
178 /* add an elf symbol : check if it is already defined and patch
179 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
180 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
181 int info, int sh_num, const char *name)
183 Elf32_Sym *esym;
184 int sym_bind, sym_index, sym_type, esym_bind;
186 sym_bind = ELF32_ST_BIND(info);
187 sym_type = ELF32_ST_TYPE(info);
189 if (sym_bind != STB_LOCAL) {
190 /* we search global or weak symbols */
191 sym_index = find_elf_sym(s, name);
192 if (!sym_index)
193 goto do_def;
194 esym = &((Elf32_Sym *)s->data)[sym_index];
195 if (esym->st_shndx != SHN_UNDEF) {
196 esym_bind = ELF32_ST_BIND(esym->st_info);
197 if (sh_num == SHN_UNDEF) {
198 /* ignore adding of undefined symbol if the
199 corresponding symbol is already defined */
200 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
201 /* global overrides weak, so patch */
202 goto do_patch;
203 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
204 /* weak is ignored if already global */
205 } else {
206 #if 0
207 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
208 sym_bind, sh_num, esym_bind, esym->st_shndx);
209 #endif
210 /* NOTE: we accept that two DLL define the same symbol */
211 if (s != tcc_state->dynsymtab_section)
212 error_noabort("'%s' defined twice", name);
214 } else {
215 do_patch:
216 esym->st_info = ELF32_ST_INFO(sym_bind, sym_type);
217 esym->st_shndx = sh_num;
218 esym->st_value = value;
219 esym->st_size = size;
221 } else {
222 do_def:
223 sym_index = put_elf_sym(s, value, size,
224 ELF32_ST_INFO(sym_bind, sym_type), 0,
225 sh_num, name);
227 return sym_index;
230 /* put relocation */
231 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
232 int type, int symbol)
234 char buf[256];
235 Section *sr;
236 Elf32_Rel *rel;
238 sr = s->reloc;
239 if (!sr) {
240 /* if no relocation section, create it */
241 snprintf(buf, sizeof(buf), ".rel%s", s->name);
242 /* if the symtab is allocated, then we consider the relocation
243 are also */
244 sr = new_section(tcc_state, buf, SHT_REL, symtab->sh_flags);
245 sr->sh_entsize = sizeof(Elf32_Rel);
246 sr->link = symtab;
247 sr->sh_info = s->sh_num;
248 s->reloc = sr;
250 rel = section_ptr_add(sr, sizeof(Elf32_Rel));
251 rel->r_offset = offset;
252 rel->r_info = ELF32_R_INFO(symbol, type);
255 /* put stab debug information */
257 typedef struct {
258 unsigned long n_strx; /* index into string table of name */
259 unsigned char n_type; /* type of symbol */
260 unsigned char n_other; /* misc info (usually empty) */
261 unsigned short n_desc; /* description field */
262 unsigned long n_value; /* value of symbol */
263 } Stab_Sym;
265 static void put_stabs(const char *str, int type, int other, int desc,
266 unsigned long value)
268 Stab_Sym *sym;
270 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
271 if (str) {
272 sym->n_strx = put_elf_str(stabstr_section, str);
273 } else {
274 sym->n_strx = 0;
276 sym->n_type = type;
277 sym->n_other = other;
278 sym->n_desc = desc;
279 sym->n_value = value;
282 static void put_stabs_r(const char *str, int type, int other, int desc,
283 unsigned long value, Section *sec, int sym_index)
285 put_stabs(str, type, other, desc, value);
286 put_elf_reloc(symtab_section, stab_section,
287 stab_section->data_offset - sizeof(unsigned long),
288 R_DATA_32, sym_index);
291 static void put_stabn(int type, int other, int desc, int value)
293 put_stabs(NULL, type, other, desc, value);
296 static void put_stabd(int type, int other, int desc)
298 put_stabs(NULL, type, other, desc, 0);
301 /* In an ELF file symbol table, the local symbols must appear below
302 the global and weak ones. Since TCC cannot sort it while generating
303 the code, we must do it after. All the relocation tables are also
304 modified to take into account the symbol table sorting */
305 static void sort_syms(TCCState *s1, Section *s)
307 int *old_to_new_syms;
308 Elf32_Sym *new_syms;
309 int nb_syms, i;
310 Elf32_Sym *p, *q;
311 Elf32_Rel *rel, *rel_end;
312 Section *sr;
313 int type, sym_index;
315 nb_syms = s->data_offset / sizeof(Elf32_Sym);
316 new_syms = tcc_malloc(nb_syms * sizeof(Elf32_Sym));
317 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
319 /* first pass for local symbols */
320 p = (Elf32_Sym *)s->data;
321 q = new_syms;
322 for(i = 0; i < nb_syms; i++) {
323 if (ELF32_ST_BIND(p->st_info) == STB_LOCAL) {
324 old_to_new_syms[i] = q - new_syms;
325 *q++ = *p;
327 p++;
329 /* save the number of local symbols in section header */
330 s->sh_info = q - new_syms;
332 /* then second pass for non local symbols */
333 p = (Elf32_Sym *)s->data;
334 for(i = 0; i < nb_syms; i++) {
335 if (ELF32_ST_BIND(p->st_info) != STB_LOCAL) {
336 old_to_new_syms[i] = q - new_syms;
337 *q++ = *p;
339 p++;
342 /* we copy the new symbols to the old */
343 memcpy(s->data, new_syms, nb_syms * sizeof(Elf32_Sym));
344 tcc_free(new_syms);
346 /* now we modify all the relocations */
347 for(i = 1; i < s1->nb_sections; i++) {
348 sr = s1->sections[i];
349 if (sr->sh_type == SHT_REL && sr->link == s) {
350 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
351 for(rel = (Elf32_Rel *)sr->data;
352 rel < rel_end;
353 rel++) {
354 sym_index = ELF32_R_SYM(rel->r_info);
355 type = ELF32_R_TYPE(rel->r_info);
356 sym_index = old_to_new_syms[sym_index];
357 rel->r_info = ELF32_R_INFO(sym_index, type);
362 tcc_free(old_to_new_syms);
365 /* relocate common symbols in the .bss section */
366 static void relocate_common_syms(void)
368 Elf32_Sym *sym, *sym_end;
369 unsigned long offset, align;
371 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
372 for(sym = (Elf32_Sym *)symtab_section->data + 1;
373 sym < sym_end;
374 sym++) {
375 if (sym->st_shndx == SHN_COMMON) {
376 /* align symbol */
377 align = sym->st_value;
378 offset = bss_section->data_offset;
379 offset = (offset + align - 1) & -align;
380 sym->st_value = offset;
381 sym->st_shndx = bss_section->sh_num;
382 offset += sym->st_size;
383 bss_section->data_offset = offset;
388 static void *resolve_sym(const char *sym)
390 return dlsym(RTLD_DEFAULT, sym);
393 /* relocate symbol table, resolve undefined symbols if do_resolve is
394 true and output error if undefined symbol. */
395 static void relocate_syms(TCCState *s1, int do_resolve)
397 Elf32_Sym *sym, *esym, *sym_end;
398 int sym_bind, sh_num, sym_index;
399 const char *name;
400 unsigned long addr;
402 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
403 for(sym = (Elf32_Sym *)symtab_section->data + 1;
404 sym < sym_end;
405 sym++) {
406 sh_num = sym->st_shndx;
407 if (sh_num == SHN_UNDEF) {
408 name = strtab_section->data + sym->st_name;
409 if (do_resolve) {
410 name = symtab_section->link->data + sym->st_name;
411 addr = (unsigned long)resolve_sym(name);
412 if (addr) {
413 sym->st_value = addr;
414 goto found;
416 } else if (s1->dynsym) {
417 /* if dynamic symbol exist, then use it */
418 sym_index = find_elf_sym(s1->dynsym, name);
419 if (sym_index) {
420 esym = &((Elf32_Sym *)s1->dynsym->data)[sym_index];
421 sym->st_value = esym->st_value;
422 goto found;
425 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
426 it */
427 if (!strcmp(name, "_fp_hw"))
428 goto found;
429 /* only weak symbols are accepted to be undefined. Their
430 value is zero */
431 sym_bind = ELF32_ST_BIND(sym->st_info);
432 if (sym_bind == STB_WEAK) {
433 sym->st_value = 0;
434 } else {
435 error_noabort("undefined symbol '%s'", name);
437 } else if (sh_num < SHN_LORESERVE) {
438 /* add section base */
439 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
441 found: ;
445 /* relocate a given section (CPU dependent) */
446 static void relocate_section(TCCState *s1, Section *s)
448 Section *sr;
449 Elf32_Rel *rel, *rel_end, *qrel;
450 Elf32_Sym *sym;
451 int type, sym_index, esym_index;
452 unsigned char *ptr;
453 unsigned long val, addr;
455 sr = s->reloc;
456 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
457 qrel = (Elf32_Rel *)sr->data;
458 for(rel = qrel;
459 rel < rel_end;
460 rel++) {
461 ptr = s->data + rel->r_offset;
463 sym_index = ELF32_R_SYM(rel->r_info);
464 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
465 val = sym->st_value;
466 type = ELF32_R_TYPE(rel->r_info);
467 addr = s->sh_addr + rel->r_offset;
469 /* CPU specific */
470 switch(type) {
471 case R_386_32:
472 if (s1->output_type == TCC_OUTPUT_DLL) {
473 esym_index = s1->symtab_to_dynsym[sym_index];
474 qrel->r_offset = rel->r_offset;
475 if (esym_index) {
476 qrel->r_info = ELF32_R_INFO(esym_index, R_386_32);
477 qrel++;
478 break;
479 } else {
480 qrel->r_info = ELF32_R_INFO(0, R_386_RELATIVE);
481 qrel++;
484 *(int *)ptr += val;
485 break;
486 case R_386_PC32:
487 if (s1->output_type == TCC_OUTPUT_DLL) {
488 /* DLL relocation */
489 esym_index = s1->symtab_to_dynsym[sym_index];
490 if (esym_index) {
491 qrel->r_offset = rel->r_offset;
492 qrel->r_info = ELF32_R_INFO(esym_index, R_386_PC32);
493 qrel++;
494 break;
497 *(int *)ptr += val - addr;
498 break;
499 case R_386_PLT32:
500 *(int *)ptr += val - addr;
501 break;
502 case R_386_GLOB_DAT:
503 case R_386_JMP_SLOT:
504 *(int *)ptr = val;
505 break;
506 case R_386_GOTPC:
507 *(int *)ptr += s1->got->sh_addr - addr;
508 break;
509 case R_386_GOTOFF:
510 *(int *)ptr += val - s1->got->sh_addr;
511 break;
512 case R_386_GOT32:
513 /* we load the got offset */
514 *(int *)ptr += s1->got_offsets[sym_index];
515 break;
518 /* if the relocation is allocated, we change its symbol table */
519 if (sr->sh_flags & SHF_ALLOC)
520 sr->link = s1->dynsym;
523 /* relocate relocation table in 'sr' */
524 static void relocate_rel(TCCState *s1, Section *sr)
526 Section *s;
527 Elf32_Rel *rel, *rel_end;
529 s = s1->sections[sr->sh_info];
530 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
531 for(rel = (Elf32_Rel *)sr->data;
532 rel < rel_end;
533 rel++) {
534 rel->r_offset += s->sh_addr;
538 /* count the number of dynamic relocations so that we can reserve
539 their space */
540 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
542 Elf32_Rel *rel, *rel_end;
543 int sym_index, esym_index, type, count;
545 count = 0;
546 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
547 for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) {
548 sym_index = ELF32_R_SYM(rel->r_info);
549 type = ELF32_R_TYPE(rel->r_info);
550 switch(type) {
551 case R_386_32:
552 count++;
553 break;
554 case R_386_PC32:
555 esym_index = s1->symtab_to_dynsym[sym_index];
556 if (esym_index)
557 count++;
558 break;
559 default:
560 break;
563 if (count) {
564 /* allocate the section */
565 sr->sh_flags |= SHF_ALLOC;
566 sr->sh_size = count * sizeof(Elf32_Rel);
568 return count;
571 static void put_got_offset(TCCState *s1, int index, unsigned long val)
573 int n;
574 unsigned long *tab;
576 if (index >= s1->nb_got_offsets) {
577 /* find immediately bigger power of 2 and reallocate array */
578 n = 1;
579 while (index >= n)
580 n *= 2;
581 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
582 if (!tab)
583 error("memory full");
584 s1->got_offsets = tab;
585 memset(s1->got_offsets + s1->nb_got_offsets, 0,
586 (n - s1->nb_got_offsets) * sizeof(unsigned long));
587 s1->nb_got_offsets = n;
589 s1->got_offsets[index] = val;
592 /* XXX: suppress that */
593 static void put32(unsigned char *p, uint32_t val)
595 p[0] = val;
596 p[1] = val >> 8;
597 p[2] = val >> 16;
598 p[3] = val >> 24;
601 static uint32_t get32(unsigned char *p)
603 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
606 static void build_got(TCCState *s1)
608 unsigned char *ptr;
610 /* if no got, then create it */
611 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
612 s1->got->sh_entsize = 4;
613 add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
614 s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
615 ptr = section_ptr_add(s1->got, 3 * sizeof(int));
616 /* keep space for _DYNAMIC pointer, if present */
617 put32(ptr, 0);
618 /* two dummy got entries */
619 put32(ptr + 4, 0);
620 put32(ptr + 8, 0);
623 /* put a got entry corresponding to a symbol in symtab_section. 'size'
624 and 'info' can be modifed if more precise info comes from the DLL */
625 static void put_got_entry(TCCState *s1,
626 int reloc_type, unsigned long size, int info,
627 int sym_index)
629 int index;
630 const char *name;
631 Elf32_Sym *sym;
632 unsigned long offset;
633 int *ptr;
635 if (!s1->got)
636 build_got(s1);
638 /* if a got entry already exists for that symbol, no need to add one */
639 if (sym_index < s1->nb_got_offsets &&
640 s1->got_offsets[sym_index] != 0)
641 return;
643 put_got_offset(s1, sym_index, s1->got->data_offset);
645 if (s1->dynsym) {
646 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
647 name = symtab_section->link->data + sym->st_name;
648 offset = sym->st_value;
649 if (reloc_type == R_386_JMP_SLOT) {
650 Section *plt;
651 uint8_t *p;
652 int modrm;
654 /* if we build a DLL, we add a %ebx offset */
655 if (s1->output_type == TCC_OUTPUT_DLL)
656 modrm = 0xa3;
657 else
658 modrm = 0x25;
660 /* add a PLT entry */
661 plt = s1->plt;
662 if (plt->data_offset == 0) {
663 /* first plt entry */
664 p = section_ptr_add(plt, 16);
665 p[0] = 0xff; /* pushl got + 4 */
666 p[1] = modrm + 0x10;
667 put32(p + 2, 4);
668 p[6] = 0xff; /* jmp *(got + 8) */
669 p[7] = modrm;
670 put32(p + 8, 8);
673 p = section_ptr_add(plt, 16);
674 p[0] = 0xff; /* jmp *(got + x) */
675 p[1] = modrm;
676 put32(p + 2, s1->got->data_offset);
677 p[6] = 0x68; /* push $xxx */
678 put32(p + 7, (plt->data_offset - 32) >> 1);
679 p[11] = 0xe9; /* jmp plt_start */
680 put32(p + 12, -(plt->data_offset));
682 /* the symbol is modified so that it will be relocated to
683 the PLT */
684 if (s1->output_type == TCC_OUTPUT_EXE)
685 offset = plt->data_offset - 16;
687 index = put_elf_sym(s1->dynsym, offset,
688 size, info, 0, sym->st_shndx, name);
689 /* put a got entry */
690 put_elf_reloc(s1->dynsym, s1->got,
691 s1->got->data_offset,
692 reloc_type, index);
694 ptr = section_ptr_add(s1->got, sizeof(int));
695 *ptr = 0;
698 /* build GOT and PLT entries */
699 static void build_got_entries(TCCState *s1)
701 Section *s, *symtab;
702 Elf32_Rel *rel, *rel_end;
703 Elf32_Sym *sym;
704 int i, type, reloc_type, sym_index;
706 for(i = 1; i < s1->nb_sections; i++) {
707 s = s1->sections[i];
708 if (s->sh_type != SHT_REL)
709 continue;
710 /* no need to handle got relocations */
711 if (s->link != symtab_section)
712 continue;
713 symtab = s->link;
714 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
715 for(rel = (Elf32_Rel *)s->data;
716 rel < rel_end;
717 rel++) {
718 type = ELF32_R_TYPE(rel->r_info);
719 switch(type) {
720 case R_386_GOT32:
721 case R_386_GOTOFF:
722 case R_386_GOTPC:
723 case R_386_PLT32:
724 if (!s1->got)
725 build_got(s1);
726 if (type == R_386_GOT32 || type == R_386_PLT32) {
727 sym_index = ELF32_R_SYM(rel->r_info);
728 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
729 /* look at the symbol got offset. If none, then add one */
730 if (type == R_386_GOT32)
731 reloc_type = R_386_GLOB_DAT;
732 else
733 reloc_type = R_386_JMP_SLOT;
734 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
735 sym_index);
737 break;
738 default:
739 break;
745 static Section *new_symtab(TCCState *s1,
746 const char *symtab_name, int sh_type, int sh_flags,
747 const char *strtab_name,
748 const char *hash_name, int hash_sh_flags)
750 Section *symtab, *strtab, *hash;
751 int *ptr, nb_buckets;
753 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
754 symtab->sh_entsize = sizeof(Elf32_Sym);
755 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
756 put_elf_str(strtab, "");
757 symtab->link = strtab;
758 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
760 nb_buckets = 1;
762 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
763 hash->sh_entsize = sizeof(int);
764 symtab->hash = hash;
765 hash->link = symtab;
767 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
768 ptr[0] = nb_buckets;
769 ptr[1] = 1;
770 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
771 return symtab;
774 /* put dynamic tag */
775 static void put_dt(Section *dynamic, int dt, unsigned long val)
777 Elf32_Dyn *dyn;
778 dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
779 dyn->d_tag = dt;
780 dyn->d_un.d_val = val;
783 static void add_init_array_defines(TCCState *s1, const char *section_name)
785 Section *s;
786 long end_offset;
787 char sym_start[1024];
788 char sym_end[1024];
790 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
791 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
793 s = find_section(s1, section_name);
794 if (!s) {
795 end_offset = 0;
796 s = data_section;
797 } else {
798 end_offset = s->data_offset;
801 add_elf_sym(symtab_section,
802 0, 0,
803 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
804 s->sh_num, sym_start);
805 add_elf_sym(symtab_section,
806 end_offset, 0,
807 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
808 s->sh_num, sym_end);
811 /* add tcc runtime libraries */
812 static void tcc_add_runtime(TCCState *s1)
814 char buf[1024];
815 int i;
816 Section *s;
818 if (!s1->nostdlib) {
819 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
820 tcc_add_file(s1, buf);
822 #ifdef CONFIG_TCC_BCHECK
823 if (do_bounds_check) {
824 unsigned long *ptr;
825 Section *init_section;
826 unsigned char *pinit;
827 int sym_index;
829 /* XXX: add an object file to do that */
830 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
831 *ptr = 0;
832 add_elf_sym(symtab_section, 0, 0,
833 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
834 bounds_section->sh_num, "__bounds_start");
835 /* add bound check code */
836 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
837 tcc_add_file(s1, buf);
838 #ifdef TCC_TARGET_I386
839 if (s1->output_type != TCC_OUTPUT_MEMORY) {
840 /* add 'call __bound_init()' in .init section */
841 init_section = find_section(s1, ".init");
842 pinit = section_ptr_add(init_section, 5);
843 pinit[0] = 0xe8;
844 put32(pinit + 1, -4);
845 sym_index = find_elf_sym(symtab_section, "__bound_init");
846 put_elf_reloc(symtab_section, init_section,
847 init_section->data_offset - 4, R_386_PC32, sym_index);
849 #endif
851 #endif
852 /* add libc if not memory output */
853 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
854 tcc_add_library(s1, "c");
855 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
857 /* add various standard linker symbols */
858 add_elf_sym(symtab_section,
859 text_section->data_offset, 0,
860 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
861 text_section->sh_num, "_etext");
862 add_elf_sym(symtab_section,
863 data_section->data_offset, 0,
864 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
865 data_section->sh_num, "_edata");
866 add_elf_sym(symtab_section,
867 bss_section->data_offset, 0,
868 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
869 bss_section->sh_num, "_end");
870 /* horrible new standard ldscript defines */
871 add_init_array_defines(s1, ".preinit_array");
872 add_init_array_defines(s1, ".init_array");
873 add_init_array_defines(s1, ".fini_array");
875 /* add start and stop symbols for sections whose name can be
876 expressed in C */
877 for(i = 1; i < s1->nb_sections; i++) {
878 s = s1->sections[i];
879 if (s->sh_type == SHT_PROGBITS &&
880 (s->sh_flags & SHF_ALLOC)) {
881 const char *p;
882 int ch;
884 /* check if section name can be expressed in C */
885 p = s->name;
886 for(;;) {
887 ch = *p;
888 if (!ch)
889 break;
890 if (!isid(ch) && !isnum(ch))
891 goto next_sec;
892 p++;
894 snprintf(buf, sizeof(buf), "__start_%s", s->name);
895 add_elf_sym(symtab_section,
896 0, 0,
897 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
898 s->sh_num, buf);
899 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
900 add_elf_sym(symtab_section,
901 s->data_offset, 0,
902 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
903 s->sh_num, buf);
905 next_sec: ;
909 /* name of ELF interpreter */
910 #ifdef __FreeBSD__
911 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
912 #else
913 static char elf_interp[] = "/lib/ld-linux.so.2";
914 #endif
916 #define ELF_START_ADDR 0x08048000
917 #define ELF_PAGE_SIZE 0x1000
919 /* output an ELF file */
920 /* XXX: suppress unneeded sections */
921 int tcc_output_file(TCCState *s1, const char *filename)
923 Elf32_Ehdr ehdr;
924 FILE *f;
925 int fd, mode, ret;
926 int *section_order;
927 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
928 unsigned long addr;
929 Section *strsec, *s;
930 Elf32_Shdr shdr, *sh;
931 Elf32_Phdr *phdr, *ph;
932 Section *interp, *dynamic, *dynstr;
933 unsigned long saved_dynamic_data_offset;
934 Elf32_Sym *sym;
935 int type, file_type;
936 unsigned long rel_addr, rel_size;
938 file_type = s1->output_type;
939 s1->nb_errors = 0;
941 if (file_type != TCC_OUTPUT_OBJ)
942 tcc_add_runtime(s1);
944 phdr = NULL;
945 section_order = NULL;
946 interp = NULL;
947 dynamic = NULL;
948 dynstr = NULL; /* avoid warning */
949 saved_dynamic_data_offset = 0; /* avoid warning */
951 if (file_type != TCC_OUTPUT_OBJ) {
953 relocate_common_syms();
955 if (!s1->static_link) {
956 const char *name;
957 int sym_index, index;
958 Elf32_Sym *esym, *sym_end;
960 if (file_type == TCC_OUTPUT_EXE) {
961 char *ptr;
962 /* add interpreter section only if executable */
963 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
964 interp->sh_addralign = 1;
965 ptr = section_ptr_add(interp, sizeof(elf_interp));
966 strcpy(ptr, elf_interp);
969 /* add dynamic symbol table */
970 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
971 ".dynstr",
972 ".hash", SHF_ALLOC);
973 dynstr = s1->dynsym->link;
975 /* add dynamic section */
976 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
977 SHF_ALLOC | SHF_WRITE);
978 dynamic->link = dynstr;
979 dynamic->sh_entsize = sizeof(Elf32_Dyn);
981 /* add PLT */
982 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
983 SHF_ALLOC | SHF_EXECINSTR);
984 s1->plt->sh_entsize = 4;
986 build_got(s1);
988 /* scan for undefined symbols and see if they are in the
989 dynamic symbols. If a symbol STT_FUNC is found, then we
990 add it in the PLT. If a symbol STT_OBJECT is found, we
991 add it in the .bss section with a suitable relocation */
992 sym_end = (Elf32_Sym *)(symtab_section->data +
993 symtab_section->data_offset);
994 if (file_type == TCC_OUTPUT_EXE) {
995 for(sym = (Elf32_Sym *)symtab_section->data + 1;
996 sym < sym_end;
997 sym++) {
998 if (sym->st_shndx == SHN_UNDEF) {
999 name = symtab_section->link->data + sym->st_name;
1000 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1001 if (sym_index) {
1002 esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
1003 type = ELF32_ST_TYPE(esym->st_info);
1004 if (type == STT_FUNC) {
1005 put_got_entry(s1, R_386_JMP_SLOT, esym->st_size,
1006 esym->st_info,
1007 sym - (Elf32_Sym *)symtab_section->data);
1008 } else if (type == STT_OBJECT) {
1009 unsigned long offset;
1010 offset = bss_section->data_offset;
1011 /* XXX: which alignment ? */
1012 offset = (offset + 16 - 1) & -16;
1013 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1014 esym->st_info, 0,
1015 bss_section->sh_num, name);
1016 put_elf_reloc(s1->dynsym, bss_section,
1017 offset, R_386_COPY, index);
1018 offset += esym->st_size;
1019 bss_section->data_offset = offset;
1021 } else {
1022 /* STB_WEAK undefined symbols are accepted */
1023 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1024 it */
1025 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
1026 !strcmp(name, "_fp_hw")) {
1027 } else {
1028 error_noabort("undefined symbol '%s'", name);
1031 } else if (s1->rdynamic &&
1032 ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1033 /* if -rdynamic option, then export all non
1034 local symbols */
1035 name = symtab_section->link->data + sym->st_name;
1036 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1037 sym->st_info, 0,
1038 sym->st_shndx, name);
1042 if (s1->nb_errors)
1043 goto fail;
1045 /* now look at unresolved dynamic symbols and export
1046 corresponding symbol */
1047 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
1048 s1->dynsymtab_section->data_offset);
1049 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
1050 esym < sym_end;
1051 esym++) {
1052 if (esym->st_shndx == SHN_UNDEF) {
1053 name = s1->dynsymtab_section->link->data + esym->st_name;
1054 sym_index = find_elf_sym(symtab_section, name);
1055 if (sym_index) {
1056 /* XXX: avoid adding a symbol if already
1057 present because of -rdynamic ? */
1058 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1059 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1060 sym->st_info, 0,
1061 sym->st_shndx, name);
1062 } else {
1063 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
1064 /* weak symbols can stay undefined */
1065 } else {
1066 warning("undefined dynamic symbol '%s'", name);
1071 } else {
1072 int nb_syms;
1073 /* shared library case : we simply export all the global symbols */
1074 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
1075 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1076 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1077 sym < sym_end;
1078 sym++) {
1079 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1080 name = symtab_section->link->data + sym->st_name;
1081 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1082 sym->st_info, 0,
1083 sym->st_shndx, name);
1084 s1->symtab_to_dynsym[sym -
1085 (Elf32_Sym *)symtab_section->data] =
1086 index;
1091 build_got_entries(s1);
1093 /* add a list of needed dlls */
1094 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1095 DLLReference *dllref = s1->loaded_dlls[i];
1096 if (dllref->level == 0)
1097 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1099 /* XXX: currently, since we do not handle PIC code, we
1100 must relocate the readonly segments */
1101 if (file_type == TCC_OUTPUT_DLL)
1102 put_dt(dynamic, DT_TEXTREL, 0);
1104 /* add necessary space for other entries */
1105 saved_dynamic_data_offset = dynamic->data_offset;
1106 dynamic->data_offset += 8 * 9;
1107 } else {
1108 /* still need to build got entries in case of static link */
1109 build_got_entries(s1);
1113 memset(&ehdr, 0, sizeof(ehdr));
1115 /* we add a section for symbols */
1116 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1117 put_elf_str(strsec, "");
1119 /* compute number of sections */
1120 shnum = s1->nb_sections;
1122 /* this array is used to reorder sections in the output file */
1123 section_order = tcc_malloc(sizeof(int) * shnum);
1124 section_order[0] = 0;
1125 sh_order_index = 1;
1127 /* compute number of program headers */
1128 switch(file_type) {
1129 default:
1130 case TCC_OUTPUT_OBJ:
1131 phnum = 0;
1132 break;
1133 case TCC_OUTPUT_EXE:
1134 if (!s1->static_link)
1135 phnum = 4;
1136 else
1137 phnum = 2;
1138 break;
1139 case TCC_OUTPUT_DLL:
1140 phnum = 3;
1141 break;
1144 /* allocate strings for section names and decide if an unallocated
1145 section should be output */
1146 /* NOTE: the strsec section comes last, so its size is also
1147 correct ! */
1148 for(i = 1; i < s1->nb_sections; i++) {
1149 s = s1->sections[i];
1150 s->sh_name = put_elf_str(strsec, s->name);
1151 /* when generating a DLL, we include relocations but we may
1152 patch them */
1153 if (file_type == TCC_OUTPUT_DLL &&
1154 s->sh_type == SHT_REL &&
1155 !(s->sh_flags & SHF_ALLOC)) {
1156 prepare_dynamic_rel(s1, s);
1157 } else if (do_debug ||
1158 file_type == TCC_OUTPUT_OBJ ||
1159 (s->sh_flags & SHF_ALLOC) ||
1160 i == (s1->nb_sections - 1)) {
1161 /* we output all sections if debug or object file */
1162 s->sh_size = s->data_offset;
1166 /* allocate program segment headers */
1167 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1169 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1170 if (phnum > 0) {
1171 /* compute section to program header mapping */
1172 if (file_type == TCC_OUTPUT_DLL)
1173 addr = 0;
1174 else
1175 addr = ELF_START_ADDR;
1177 /* dynamic relocation table information, for .dynamic section */
1178 rel_size = 0;
1179 rel_addr = 0;
1181 /* compute address after headers */
1182 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1184 /* leave one program header for the program interpreter */
1185 ph = &phdr[0];
1186 if (interp)
1187 ph++;
1189 for(j = 0; j < 2; j++) {
1190 ph->p_type = PT_LOAD;
1191 if (j == 0)
1192 ph->p_flags = PF_R | PF_X;
1193 else
1194 ph->p_flags = PF_R | PF_W;
1195 ph->p_align = ELF_PAGE_SIZE;
1197 /* we do the following ordering: interp, symbol tables,
1198 relocations, progbits, nobits */
1199 /* XXX: do faster and simpler sorting */
1200 for(k = 0; k < 5; k++) {
1201 for(i = 1; i < s1->nb_sections; i++) {
1202 s = s1->sections[i];
1203 /* compute if section should be included */
1204 if (j == 0) {
1205 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1206 SHF_ALLOC)
1207 continue;
1208 } else {
1209 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1210 (SHF_ALLOC | SHF_WRITE))
1211 continue;
1213 if (s == interp) {
1214 if (k != 0)
1215 continue;
1216 } else if (s->sh_type == SHT_DYNSYM ||
1217 s->sh_type == SHT_STRTAB ||
1218 s->sh_type == SHT_HASH) {
1219 if (k != 1)
1220 continue;
1221 } else if (s->sh_type == SHT_REL) {
1222 if (k != 2)
1223 continue;
1224 } else if (s->sh_type == SHT_NOBITS) {
1225 if (k != 4)
1226 continue;
1227 } else {
1228 if (k != 3)
1229 continue;
1231 section_order[sh_order_index++] = i;
1233 /* section matches: we align it and add its size */
1234 tmp = file_offset;
1235 file_offset = (file_offset + s->sh_addralign - 1) &
1236 ~(s->sh_addralign - 1);
1237 s->sh_offset = file_offset;
1238 addr += file_offset - tmp;
1239 s->sh_addr = addr;
1241 /* update program header infos */
1242 if (ph->p_offset == 0) {
1243 ph->p_offset = file_offset;
1244 ph->p_vaddr = addr;
1245 ph->p_paddr = ph->p_vaddr;
1247 /* update dynamic relocation infos */
1248 if (s->sh_type == SHT_REL) {
1249 if (rel_size == 0)
1250 rel_addr = addr;
1251 rel_size += s->sh_size;
1253 addr += s->sh_size;
1254 if (s->sh_type != SHT_NOBITS)
1255 file_offset += s->sh_size;
1258 ph->p_filesz = file_offset - ph->p_offset;
1259 ph->p_memsz = addr - ph->p_vaddr;
1260 ph++;
1261 /* if in the middle of a page, we duplicate the page in
1262 memory so that one copy is RX and the other is RW */
1263 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1264 addr += ELF_PAGE_SIZE;
1267 /* if interpreter, then add corresponing program header */
1268 if (interp) {
1269 ph = &phdr[0];
1271 ph->p_type = PT_INTERP;
1272 ph->p_offset = interp->sh_offset;
1273 ph->p_vaddr = interp->sh_addr;
1274 ph->p_paddr = ph->p_vaddr;
1275 ph->p_filesz = interp->sh_size;
1276 ph->p_memsz = interp->sh_size;
1277 ph->p_flags = PF_R;
1278 ph->p_align = interp->sh_addralign;
1281 /* if dynamic section, then add corresponing program header */
1282 if (dynamic) {
1283 Elf32_Sym *sym_end;
1285 ph = &phdr[phnum - 1];
1287 ph->p_type = PT_DYNAMIC;
1288 ph->p_offset = dynamic->sh_offset;
1289 ph->p_vaddr = dynamic->sh_addr;
1290 ph->p_paddr = ph->p_vaddr;
1291 ph->p_filesz = dynamic->sh_size;
1292 ph->p_memsz = dynamic->sh_size;
1293 ph->p_flags = PF_R | PF_W;
1294 ph->p_align = dynamic->sh_addralign;
1296 /* put GOT dynamic section address */
1297 put32(s1->got->data, dynamic->sh_addr);
1299 /* relocate the PLT */
1300 if (file_type == TCC_OUTPUT_EXE) {
1301 uint8_t *p, *p_end;
1303 p = s1->plt->data;
1304 p_end = p + s1->plt->data_offset;
1305 if (p < p_end) {
1306 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1307 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1308 p += 16;
1309 while (p < p_end) {
1310 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1311 p += 16;
1316 /* relocate symbols in .dynsym */
1317 sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
1318 for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
1319 sym < sym_end;
1320 sym++) {
1321 if (sym->st_shndx == SHN_UNDEF) {
1322 /* relocate to the PLT if the symbol corresponds
1323 to a PLT entry */
1324 if (sym->st_value)
1325 sym->st_value += s1->plt->sh_addr;
1326 } else if (sym->st_shndx < SHN_LORESERVE) {
1327 /* do symbol relocation */
1328 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1332 /* put dynamic section entries */
1333 dynamic->data_offset = saved_dynamic_data_offset;
1334 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1335 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1336 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1337 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1338 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
1339 put_dt(dynamic, DT_REL, rel_addr);
1340 put_dt(dynamic, DT_RELSZ, rel_size);
1341 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
1342 put_dt(dynamic, DT_NULL, 0);
1345 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1346 ehdr.e_phnum = phnum;
1347 ehdr.e_phoff = sizeof(Elf32_Ehdr);
1350 /* all other sections come after */
1351 for(i = 1; i < s1->nb_sections; i++) {
1352 s = s1->sections[i];
1353 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1354 continue;
1355 section_order[sh_order_index++] = i;
1357 file_offset = (file_offset + s->sh_addralign - 1) &
1358 ~(s->sh_addralign - 1);
1359 s->sh_offset = file_offset;
1360 if (s->sh_type != SHT_NOBITS)
1361 file_offset += s->sh_size;
1364 /* if building executable or DLL, then relocate each section
1365 except the GOT which is already relocated */
1366 if (file_type != TCC_OUTPUT_OBJ) {
1367 relocate_syms(s1, 0);
1369 if (s1->nb_errors != 0) {
1370 fail:
1371 ret = -1;
1372 goto the_end;
1375 /* relocate sections */
1376 /* XXX: ignore sections with allocated relocations ? */
1377 for(i = 1; i < s1->nb_sections; i++) {
1378 s = s1->sections[i];
1379 if (s->reloc && s != s1->got)
1380 relocate_section(s1, s);
1383 /* relocate relocation entries if the relocation tables are
1384 allocated in the executable */
1385 for(i = 1; i < s1->nb_sections; i++) {
1386 s = s1->sections[i];
1387 if ((s->sh_flags & SHF_ALLOC) &&
1388 s->sh_type == SHT_REL) {
1389 relocate_rel(s1, s);
1393 /* get entry point address */
1394 if (file_type == TCC_OUTPUT_EXE)
1395 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
1396 else
1397 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1400 sort_syms(s1, symtab_section);
1402 /* align to 4 */
1403 file_offset = (file_offset + 3) & -4;
1405 /* fill header */
1406 ehdr.e_ident[0] = ELFMAG0;
1407 ehdr.e_ident[1] = ELFMAG1;
1408 ehdr.e_ident[2] = ELFMAG2;
1409 ehdr.e_ident[3] = ELFMAG3;
1410 ehdr.e_ident[4] = ELFCLASS32;
1411 ehdr.e_ident[5] = ELFDATA2LSB;
1412 ehdr.e_ident[6] = EV_CURRENT;
1413 #ifdef __FreeBSD__
1414 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1415 #endif
1416 switch(file_type) {
1417 default:
1418 case TCC_OUTPUT_EXE:
1419 ehdr.e_type = ET_EXEC;
1420 break;
1421 case TCC_OUTPUT_DLL:
1422 ehdr.e_type = ET_DYN;
1423 break;
1424 case TCC_OUTPUT_OBJ:
1425 ehdr.e_type = ET_REL;
1426 break;
1428 ehdr.e_machine = EM_386;
1429 ehdr.e_version = EV_CURRENT;
1430 ehdr.e_shoff = file_offset;
1431 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1432 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1433 ehdr.e_shnum = shnum;
1434 ehdr.e_shstrndx = shnum - 1;
1436 /* write elf file */
1437 if (file_type == TCC_OUTPUT_OBJ)
1438 mode = 0666;
1439 else
1440 mode = 0777;
1441 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
1442 if (fd < 0) {
1443 error_noabort("could not write '%s'", filename);
1444 goto fail;
1446 f = fdopen(fd, "w");
1447 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1448 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1449 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1450 for(i=1;i<s1->nb_sections;i++) {
1451 s = s1->sections[section_order[i]];
1452 if (s->sh_type != SHT_NOBITS) {
1453 while (offset < s->sh_offset) {
1454 fputc(0, f);
1455 offset++;
1457 size = s->sh_size;
1458 fwrite(s->data, 1, size, f);
1459 offset += size;
1462 while (offset < ehdr.e_shoff) {
1463 fputc(0, f);
1464 offset++;
1467 /* output section headers */
1468 for(i=0;i<s1->nb_sections;i++) {
1469 sh = &shdr;
1470 memset(sh, 0, sizeof(Elf32_Shdr));
1471 s = s1->sections[i];
1472 if (s) {
1473 sh->sh_name = s->sh_name;
1474 sh->sh_type = s->sh_type;
1475 sh->sh_flags = s->sh_flags;
1476 sh->sh_entsize = s->sh_entsize;
1477 sh->sh_info = s->sh_info;
1478 if (s->link)
1479 sh->sh_link = s->link->sh_num;
1480 sh->sh_addralign = s->sh_addralign;
1481 sh->sh_addr = s->sh_addr;
1482 sh->sh_offset = s->sh_offset;
1483 sh->sh_size = s->sh_size;
1485 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1487 fclose(f);
1489 ret = 0;
1490 the_end:
1491 tcc_free(s1->symtab_to_dynsym);
1492 tcc_free(section_order);
1493 tcc_free(phdr);
1494 tcc_free(s1->got_offsets);
1495 return ret;
1498 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1500 void *data;
1502 data = tcc_malloc(size);
1503 lseek(fd, file_offset, SEEK_SET);
1504 read(fd, data, size);
1505 return data;
1508 typedef struct SectionMergeInfo {
1509 Section *s; /* corresponding existing section */
1510 unsigned long offset; /* offset of the new section in the existing section */
1511 int new_section; /* true if section 's' was added */
1512 } SectionMergeInfo;
1514 /* load an object file and merge it with current files */
1515 /* XXX: handle correctly stab (debug) info */
1516 static int tcc_load_object_file(TCCState *s1,
1517 int fd, unsigned long file_offset)
1519 Elf32_Ehdr ehdr;
1520 Elf32_Shdr *shdr, *sh;
1521 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1522 unsigned char *strsec, *strtab;
1523 int *old_to_new_syms;
1524 char *sh_name, *name;
1525 SectionMergeInfo *sm_table, *sm;
1526 Elf32_Sym *sym, *symtab;
1527 Elf32_Rel *rel, *rel_end;
1528 Section *s;
1530 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1531 goto fail1;
1532 if (ehdr.e_ident[0] != ELFMAG0 ||
1533 ehdr.e_ident[1] != ELFMAG1 ||
1534 ehdr.e_ident[2] != ELFMAG2 ||
1535 ehdr.e_ident[3] != ELFMAG3)
1536 goto fail1;
1537 /* test if object file */
1538 if (ehdr.e_type != ET_REL)
1539 goto fail1;
1540 /* test CPU specific stuff */
1541 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1542 ehdr.e_machine != EM_386) {
1543 fail1:
1544 error_noabort("invalid object file");
1545 return -1;
1547 /* read sections */
1548 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1549 sizeof(Elf32_Shdr) * ehdr.e_shnum);
1550 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1552 /* load section names */
1553 sh = &shdr[ehdr.e_shstrndx];
1554 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1556 /* load symtab and strtab */
1557 old_to_new_syms = NULL;
1558 symtab = NULL;
1559 strtab = NULL;
1560 nb_syms = 0;
1561 for(i = 1; i < ehdr.e_shnum; i++) {
1562 sh = &shdr[i];
1563 if (sh->sh_type == SHT_SYMTAB) {
1564 if (symtab) {
1565 error_noabort("object must contain only one symtab");
1566 fail:
1567 ret = -1;
1568 goto the_end;
1570 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1571 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1572 sm_table[i].s = symtab_section;
1574 /* now load strtab */
1575 sh = &shdr[sh->sh_link];
1576 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1580 /* now examine each section and try to merge its content with the
1581 ones in memory */
1582 for(i = 1; i < ehdr.e_shnum; i++) {
1583 /* no need to examine section name strtab */
1584 if (i == ehdr.e_shstrndx)
1585 continue;
1586 sh = &shdr[i];
1587 sh_name = strsec + sh->sh_name;
1588 /* ignore sections types we do not handle */
1589 if (sh->sh_type != SHT_PROGBITS &&
1590 sh->sh_type != SHT_REL &&
1591 sh->sh_type != SHT_NOBITS)
1592 continue;
1593 if (sh->sh_addralign < 1)
1594 sh->sh_addralign = 1;
1595 /* find corresponding section, if any */
1596 for(j = 1; j < s1->nb_sections;j++) {
1597 s = s1->sections[j];
1598 if (!strcmp(s->name, sh_name))
1599 goto found;
1601 /* not found: create new section */
1602 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1603 /* take as much info as possible from the section. sh_link and
1604 sh_info will be updated later */
1605 s->sh_addralign = sh->sh_addralign;
1606 s->sh_entsize = sh->sh_entsize;
1607 sm_table[i].new_section = 1;
1608 found:
1609 if (sh->sh_type != s->sh_type) {
1610 error_noabort("invalid section type");
1611 goto fail;
1614 /* align start of section */
1615 offset = s->data_offset;
1616 size = sh->sh_addralign - 1;
1617 offset = (offset + size) & ~size;
1618 if (sh->sh_addralign > s->sh_addralign)
1619 s->sh_addralign = sh->sh_addralign;
1620 s->data_offset = offset;
1621 sm_table[i].offset = offset;
1622 sm_table[i].s = s;
1623 /* concatenate sections */
1624 size = sh->sh_size;
1625 if (sh->sh_type != SHT_NOBITS) {
1626 unsigned char *ptr;
1627 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1628 ptr = section_ptr_add(s, size);
1629 read(fd, ptr, size);
1630 } else {
1631 s->data_offset += size;
1635 /* second short pass to update sh_link and sh_info fields of new
1636 sections */
1637 sm = sm_table;
1638 for(i = 1; i < ehdr.e_shnum; i++) {
1639 s = sm_table[i].s;
1640 if (!s || !sm_table[i].new_section)
1641 continue;
1642 sh = &shdr[i];
1643 if (sh->sh_link > 0)
1644 s->link = sm_table[sh->sh_link].s;
1645 if (sh->sh_type == SHT_REL) {
1646 s->sh_info = sm_table[sh->sh_info].s->sh_num;
1647 /* update backward link */
1648 s1->sections[s->sh_info]->reloc = s;
1652 /* resolve symbols */
1653 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
1655 sym = symtab + 1;
1656 for(i = 1; i < nb_syms; i++, sym++) {
1657 if (sym->st_shndx != SHN_UNDEF &&
1658 sym->st_shndx < SHN_LORESERVE) {
1659 sm = &sm_table[sym->st_shndx];
1660 /* if no corresponding section added, no need to add symbol */
1661 if (!sm->s)
1662 continue;
1663 /* convert section number */
1664 sym->st_shndx = sm->s->sh_num;
1665 /* offset value */
1666 sym->st_value += sm->offset;
1668 /* add symbol */
1669 name = strtab + sym->st_name;
1670 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
1671 sym->st_info, sym->st_shndx, name);
1672 old_to_new_syms[i] = sym_index;
1675 /* third pass to patch relocation entries */
1676 for(i = 1; i < ehdr.e_shnum; i++) {
1677 s = sm_table[i].s;
1678 if (!s)
1679 continue;
1680 sh = &shdr[i];
1681 offset = sm_table[i].offset;
1682 switch(s->sh_type) {
1683 case SHT_REL:
1684 /* take relocation offset information */
1685 offseti = sm_table[sh->sh_info].offset;
1686 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
1687 for(rel = (Elf32_Rel *)(s->data + offset);
1688 rel < rel_end;
1689 rel++) {
1690 int type;
1691 unsigned sym_index;
1692 /* convert symbol index */
1693 type = ELF32_R_TYPE(rel->r_info);
1694 sym_index = ELF32_R_SYM(rel->r_info);
1695 /* NOTE: only one symtab assumed */
1696 if (sym_index >= nb_syms)
1697 goto invalid_reloc;
1698 sym_index = old_to_new_syms[sym_index];
1699 if (!sym_index) {
1700 invalid_reloc:
1701 error_noabort("Invalid relocation entry");
1702 goto fail;
1704 rel->r_info = ELF32_R_INFO(sym_index, type);
1705 /* offset the relocation offset */
1706 rel->r_offset += offseti;
1708 break;
1709 default:
1710 break;
1714 ret = 0;
1715 the_end:
1716 tcc_free(symtab);
1717 tcc_free(strtab);
1718 tcc_free(old_to_new_syms);
1719 tcc_free(sm_table);
1720 tcc_free(strsec);
1721 tcc_free(shdr);
1722 return ret;
1725 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1727 typedef struct ArchiveHeader {
1728 char ar_name[16]; /* name of this member */
1729 char ar_date[12]; /* file mtime */
1730 char ar_uid[6]; /* owner uid; printed as decimal */
1731 char ar_gid[6]; /* owner gid; printed as decimal */
1732 char ar_mode[8]; /* file mode, printed as octal */
1733 char ar_size[10]; /* file size, printed as decimal */
1734 char ar_fmag[2]; /* should contain ARFMAG */
1735 } ArchiveHeader;
1737 static int get_be32(const uint8_t *b)
1739 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
1742 /* load only the objects which resolve undefined symbols */
1743 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
1745 int i, bound, nsyms, sym_index, off, ret;
1746 uint8_t *data;
1747 const char *ar_names, *p;
1748 const uint8_t *ar_index;
1749 Elf32_Sym *sym;
1751 data = tcc_malloc(size);
1752 if (read(fd, data, size) != size)
1753 goto fail;
1754 nsyms = get_be32(data);
1755 ar_index = data + 4;
1756 ar_names = ar_index + nsyms * 4;
1758 do {
1759 bound = 0;
1760 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
1761 sym_index = find_elf_sym(symtab_section, p);
1762 if(sym_index) {
1763 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1764 if(sym->st_shndx == SHN_UNDEF) {
1765 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
1766 #if 0
1767 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
1768 #endif
1769 ++bound;
1770 lseek(fd, off, SEEK_SET);
1771 if(tcc_load_object_file(s1, fd, off) < 0) {
1772 fail:
1773 ret = -1;
1774 goto the_end;
1779 } while(bound);
1780 ret = 0;
1781 the_end:
1782 tcc_free(data);
1783 return ret;
1786 /* load a '.a' file */
1787 static int tcc_load_archive(TCCState *s1, int fd)
1789 ArchiveHeader hdr;
1790 char ar_size[11];
1791 char ar_name[17];
1792 char magic[8];
1793 int size, len, i;
1794 unsigned long file_offset;
1796 /* skip magic which was already checked */
1797 read(fd, magic, sizeof(magic));
1799 for(;;) {
1800 len = read(fd, &hdr, sizeof(hdr));
1801 if (len == 0)
1802 break;
1803 if (len != sizeof(hdr)) {
1804 error_noabort("invalid archive");
1805 return -1;
1807 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
1808 ar_size[sizeof(hdr.ar_size)] = '\0';
1809 size = strtol(ar_size, NULL, 0);
1810 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
1811 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
1812 if (ar_name[i] != ' ')
1813 break;
1815 ar_name[i + 1] = '\0';
1816 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
1817 file_offset = lseek(fd, 0, SEEK_CUR);
1818 /* align to even */
1819 size = (size + 1) & ~1;
1820 if (!strcmp(ar_name, "/")) {
1821 /* coff symbol table : we handle it */
1822 if(s1->alacarte_link)
1823 return tcc_load_alacarte(s1, fd, size);
1824 } else if (!strcmp(ar_name, "//") ||
1825 !strcmp(ar_name, "__.SYMDEF") ||
1826 !strcmp(ar_name, "__.SYMDEF/") ||
1827 !strcmp(ar_name, "ARFILENAMES/")) {
1828 /* skip symbol table or archive names */
1829 } else {
1830 if (tcc_load_object_file(s1, fd, file_offset) < 0)
1831 return -1;
1833 lseek(fd, file_offset + size, SEEK_SET);
1835 return 0;
1838 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
1839 is referenced by the user (so it should be added as DT_NEEDED in
1840 the generated ELF file) */
1841 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
1843 Elf32_Ehdr ehdr;
1844 Elf32_Shdr *shdr, *sh, *sh1;
1845 int i, nb_syms, nb_dts, sym_bind, ret;
1846 Elf32_Sym *sym, *dynsym;
1847 Elf32_Dyn *dt, *dynamic;
1848 unsigned char *dynstr;
1849 const char *name, *soname, *p;
1850 DLLReference *dllref;
1852 read(fd, &ehdr, sizeof(ehdr));
1854 /* test CPU specific stuff */
1855 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1856 ehdr.e_machine != EM_386) {
1857 error_noabort("bad architecture");
1858 return -1;
1861 /* read sections */
1862 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
1864 /* load dynamic section and dynamic symbols */
1865 nb_syms = 0;
1866 nb_dts = 0;
1867 dynamic = NULL;
1868 dynsym = NULL; /* avoid warning */
1869 dynstr = NULL; /* avoid warning */
1870 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
1871 switch(sh->sh_type) {
1872 case SHT_DYNAMIC:
1873 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
1874 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
1875 break;
1876 case SHT_DYNSYM:
1877 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1878 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
1879 sh1 = &shdr[sh->sh_link];
1880 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
1881 break;
1882 default:
1883 break;
1887 /* compute the real library name */
1888 soname = filename;
1889 p = strrchr(soname, '/');
1890 if (p)
1891 soname = p + 1;
1893 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
1894 if (dt->d_tag == DT_SONAME) {
1895 soname = dynstr + dt->d_un.d_val;
1899 /* if the dll is already loaded, do not load it */
1900 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1901 dllref = s1->loaded_dlls[i];
1902 if (!strcmp(soname, dllref->name)) {
1903 /* but update level if needed */
1904 if (level < dllref->level)
1905 dllref->level = level;
1906 ret = 0;
1907 goto the_end;
1911 // printf("loading dll '%s'\n", soname);
1913 /* add the dll and its level */
1914 dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
1915 dllref->level = level;
1916 strcpy(dllref->name, soname);
1917 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
1919 /* add dynamic symbols in dynsym_section */
1920 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
1921 sym_bind = ELF32_ST_BIND(sym->st_info);
1922 if (sym_bind == STB_LOCAL)
1923 continue;
1924 name = dynstr + sym->st_name;
1925 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
1926 sym->st_info, sym->st_shndx, name);
1929 /* load all referenced DLLs */
1930 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
1931 switch(dt->d_tag) {
1932 case DT_NEEDED:
1933 name = dynstr + dt->d_un.d_val;
1934 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1935 dllref = s1->loaded_dlls[i];
1936 if (!strcmp(name, dllref->name))
1937 goto already_loaded;
1939 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
1940 error_noabort("referenced dll '%s' not found", name);
1941 ret = -1;
1942 goto the_end;
1944 already_loaded:
1945 break;
1948 ret = 0;
1949 the_end:
1950 tcc_free(dynstr);
1951 tcc_free(dynsym);
1952 tcc_free(dynamic);
1953 tcc_free(shdr);
1954 return ret;
1957 #define LD_TOK_NAME 256
1958 #define LD_TOK_EOF (-1)
1960 /* return next ld script token */
1961 static int ld_next(TCCState *s1, char *name, int name_size)
1963 int c;
1964 char *q;
1966 redo:
1967 switch(ch) {
1968 case ' ':
1969 case '\t':
1970 case '\f':
1971 case '\v':
1972 case '\r':
1973 case '\n':
1974 inp();
1975 goto redo;
1976 case '/':
1977 minp();
1978 if (ch == '*') {
1979 file->buf_ptr = parse_comment(file->buf_ptr);
1980 ch = file->buf_ptr[0];
1981 goto redo;
1982 } else {
1983 q = name;
1984 *q++ = '/';
1985 goto parse_name;
1987 break;
1988 case 'a' ... 'z':
1989 case 'A' ... 'Z':
1990 case '_':
1991 case '\\':
1992 case '.':
1993 case '$':
1994 case '~':
1995 q = name;
1996 parse_name:
1997 for(;;) {
1998 if (!((ch >= 'a' && ch <= 'z') ||
1999 (ch >= 'A' && ch <= 'Z') ||
2000 (ch >= '0' && ch <= '9') ||
2001 strchr("/.-_+=$:\\,~", ch)))
2002 break;
2003 if ((q - name) < name_size - 1) {
2004 *q++ = ch;
2006 minp();
2008 *q = '\0';
2009 c = LD_TOK_NAME;
2010 break;
2011 case CH_EOF:
2012 c = LD_TOK_EOF;
2013 break;
2014 default:
2015 c = ch;
2016 inp();
2017 break;
2019 #if 0
2020 printf("tok=%c %d\n", c, c);
2021 if (c == LD_TOK_NAME)
2022 printf(" name=%s\n", name);
2023 #endif
2024 return c;
2027 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2028 files */
2029 static int tcc_load_ldscript(TCCState *s1)
2031 char cmd[64];
2032 char filename[1024];
2033 int t;
2035 ch = file->buf_ptr[0];
2036 ch = handle_eob();
2037 for(;;) {
2038 t = ld_next(s1, cmd, sizeof(cmd));
2039 if (t == LD_TOK_EOF)
2040 return 0;
2041 else if (t != LD_TOK_NAME)
2042 return -1;
2043 if (!strcmp(cmd, "INPUT") ||
2044 !strcmp(cmd, "GROUP")) {
2045 t = ld_next(s1, cmd, sizeof(cmd));
2046 if (t != '(')
2047 expect("(");
2048 t = ld_next(s1, filename, sizeof(filename));
2049 for(;;) {
2050 if (t == LD_TOK_EOF) {
2051 error_noabort("unexpected end of file");
2052 return -1;
2053 } else if (t == ')') {
2054 break;
2055 } else if (t != LD_TOK_NAME) {
2056 error_noabort("filename expected");
2057 return -1;
2059 tcc_add_file(s1, filename);
2060 t = ld_next(s1, filename, sizeof(filename));
2061 if (t == ',') {
2062 t = ld_next(s1, filename, sizeof(filename));
2065 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2066 !strcmp(cmd, "TARGET")) {
2067 /* ignore some commands */
2068 t = ld_next(s1, cmd, sizeof(cmd));
2069 if (t != '(')
2070 expect("(");
2071 for(;;) {
2072 t = ld_next(s1, filename, sizeof(filename));
2073 if (t == LD_TOK_EOF) {
2074 error_noabort("unexpected end of file");
2075 return -1;
2076 } else if (t == ')') {
2077 break;
2080 } else {
2081 return -1;
2084 return 0;