better _Bool lvalue support
[tinycc.git] / tccelf.c
bloba94fd4ffa8952e1203f3587589e8ac492d7f7f82
1 /*
2 * ELF file handling for TCC
3 *
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 static int put_elf_str(Section *s, const char *sym)
23 int offset, len;
24 char *ptr;
26 len = strlen(sym) + 1;
27 offset = s->data_offset;
28 ptr = section_ptr_add(s, len);
29 memcpy(ptr, sym, len);
30 return offset;
33 /* elf symbol hashing function */
34 static unsigned long elf_hash(const unsigned char *name)
36 unsigned long h = 0, g;
38 while (*name) {
39 h = (h << 4) + *name++;
40 g = h & 0xf0000000;
41 if (g)
42 h ^= g >> 24;
43 h &= ~g;
45 return h;
48 /* rebuild hash table of section s */
49 /* NOTE: we do factorize the hash table code to go faster */
50 static void rebuild_hash(Section *s, unsigned int nb_buckets)
52 Elf32_Sym *sym;
53 int *ptr, *hash, nb_syms, sym_index, h;
54 char *strtab;
56 strtab = s->link->data;
57 nb_syms = s->data_offset / sizeof(Elf32_Sym);
59 s->hash->data_offset = 0;
60 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
61 ptr[0] = nb_buckets;
62 ptr[1] = nb_syms;
63 ptr += 2;
64 hash = ptr;
65 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
66 ptr += nb_buckets + 1;
68 sym = (Elf32_Sym *)s->data + 1;
69 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
70 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
71 h = elf_hash(strtab + sym->st_name) % nb_buckets;
72 *ptr = hash[h];
73 hash[h] = sym_index;
74 } else {
75 *ptr = 0;
77 ptr++;
78 sym++;
82 /* return the symbol number */
83 static int put_elf_sym(Section *s,
84 unsigned long value, unsigned long size,
85 int info, int other, int shndx, const char *name)
87 int name_offset, sym_index;
88 int nbuckets, h;
89 Elf32_Sym *sym;
90 Section *hs;
92 sym = section_ptr_add(s, sizeof(Elf32_Sym));
93 if (name)
94 name_offset = put_elf_str(s->link, name);
95 else
96 name_offset = 0;
97 /* XXX: endianness */
98 sym->st_name = name_offset;
99 sym->st_value = value;
100 sym->st_size = size;
101 sym->st_info = info;
102 sym->st_other = other;
103 sym->st_shndx = shndx;
104 sym_index = sym - (Elf32_Sym *)s->data;
105 hs = s->hash;
106 if (hs) {
107 int *ptr, *base;
108 ptr = section_ptr_add(hs, sizeof(int));
109 base = (int *)hs->data;
110 /* only add global or weak symbols */
111 if (ELF32_ST_BIND(info) != STB_LOCAL) {
112 /* add another hashing entry */
113 nbuckets = base[0];
114 h = elf_hash(name) % nbuckets;
115 *ptr = base[2 + h];
116 base[2 + h] = sym_index;
117 base[1]++;
118 /* we resize the hash table */
119 hs->nb_hashed_syms++;
120 if (hs->nb_hashed_syms > 2 * nbuckets) {
121 rebuild_hash(s, 2 * nbuckets);
123 } else {
124 *ptr = 0;
125 base[1]++;
128 return sym_index;
131 /* find global ELF symbol 'name' and return its index. Return 0 if not
132 found. */
133 static int find_elf_sym(Section *s, const char *name)
135 Elf32_Sym *sym;
136 Section *hs;
137 int nbuckets, sym_index, h;
138 const char *name1;
140 hs = s->hash;
141 if (!hs)
142 return 0;
143 nbuckets = ((int *)hs->data)[0];
144 h = elf_hash(name) % nbuckets;
145 sym_index = ((int *)hs->data)[2 + h];
146 while (sym_index != 0) {
147 sym = &((Elf32_Sym *)s->data)[sym_index];
148 name1 = s->link->data + sym->st_name;
149 if (!strcmp(name, name1))
150 return sym_index;
151 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
153 return 0;
156 /* return elf symbol value or error */
157 void *tcc_get_symbol(TCCState *s, const char *name)
159 int sym_index;
160 Elf32_Sym *sym;
162 sym_index = find_elf_sym(symtab_section, name);
163 if (!sym_index)
164 error("%s not defined", name);
165 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
166 return (void *)sym->st_value;
169 /* add an elf symbol : check if it is already defined and patch
170 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
171 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
172 int info, int sh_num, const char *name)
174 Elf32_Sym *esym;
175 int sym_bind, sym_index, sym_type, esym_bind;
177 sym_bind = ELF32_ST_BIND(info);
178 sym_type = ELF32_ST_TYPE(info);
180 if (sym_bind != STB_LOCAL) {
181 /* we search global or weak symbols */
182 sym_index = find_elf_sym(s, name);
183 if (!sym_index)
184 goto do_def;
185 esym = &((Elf32_Sym *)s->data)[sym_index];
186 if (esym->st_shndx != SHN_UNDEF) {
187 esym_bind = ELF32_ST_BIND(esym->st_info);
188 if (sh_num == SHN_UNDEF) {
189 /* ignore adding of undefined symbol if the
190 corresponding symbol is already defined */
191 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
192 /* global overrides weak, so patch */
193 goto do_patch;
194 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
195 /* weak is ignored if already global */
196 } else {
197 #if 0
198 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
199 sym_bind, sh_num, esym_bind, esym->st_shndx);
200 #endif
201 /* NOTE: we accept that two DLL define the same symbol */
202 if (s != tcc_state->dynsymtab_section)
203 error_noabort("'%s' defined twice", name);
205 } else {
206 do_patch:
207 esym->st_info = ELF32_ST_INFO(sym_bind, sym_type);
208 esym->st_shndx = sh_num;
209 esym->st_value = value;
210 esym->st_size = size;
212 } else {
213 do_def:
214 sym_index = put_elf_sym(s, value, size,
215 ELF32_ST_INFO(sym_bind, sym_type), 0,
216 sh_num, name);
218 return sym_index;
221 /* put relocation */
222 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
223 int type, int symbol)
225 char buf[256];
226 Section *sr;
227 Elf32_Rel *rel;
229 sr = s->reloc;
230 if (!sr) {
231 /* if no relocation section, create it */
232 snprintf(buf, sizeof(buf), ".rel%s", s->name);
233 /* if the symtab is allocated, then we consider the relocation
234 are also */
235 sr = new_section(tcc_state, buf, SHT_REL, symtab->sh_flags);
236 sr->sh_entsize = sizeof(Elf32_Rel);
237 sr->link = symtab;
238 sr->sh_info = s->sh_num;
239 s->reloc = sr;
241 rel = section_ptr_add(sr, sizeof(Elf32_Rel));
242 rel->r_offset = offset;
243 rel->r_info = ELF32_R_INFO(symbol, type);
246 /* put stab debug information */
248 typedef struct {
249 unsigned long n_strx; /* index into string table of name */
250 unsigned char n_type; /* type of symbol */
251 unsigned char n_other; /* misc info (usually empty) */
252 unsigned short n_desc; /* description field */
253 unsigned long n_value; /* value of symbol */
254 } Stab_Sym;
256 static void put_stabs(const char *str, int type, int other, int desc,
257 unsigned long value)
259 Stab_Sym *sym;
261 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
262 if (str) {
263 sym->n_strx = put_elf_str(stabstr_section, str);
264 } else {
265 sym->n_strx = 0;
267 sym->n_type = type;
268 sym->n_other = other;
269 sym->n_desc = desc;
270 sym->n_value = value;
273 static void put_stabs_r(const char *str, int type, int other, int desc,
274 unsigned long value, Section *sec, int sym_index)
276 put_stabs(str, type, other, desc, value);
277 put_elf_reloc(symtab_section, stab_section,
278 stab_section->data_offset - sizeof(unsigned long),
279 R_DATA_32, sym_index);
282 static void put_stabn(int type, int other, int desc, int value)
284 put_stabs(NULL, type, other, desc, value);
287 static void put_stabd(int type, int other, int desc)
289 put_stabs(NULL, type, other, desc, 0);
292 /* In an ELF file symbol table, the local symbols must appear below
293 the global and weak ones. Since TCC cannot sort it while generating
294 the code, we must do it after. All the relocation tables are also
295 modified to take into account the symbol table sorting */
296 static void sort_syms(TCCState *s1, Section *s)
298 int *old_to_new_syms;
299 Elf32_Sym *new_syms;
300 int nb_syms, i;
301 Elf32_Sym *p, *q;
302 Elf32_Rel *rel, *rel_end;
303 Section *sr;
304 int type, sym_index;
306 nb_syms = s->data_offset / sizeof(Elf32_Sym);
307 new_syms = tcc_malloc(nb_syms * sizeof(Elf32_Sym));
308 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
310 /* first pass for local symbols */
311 p = (Elf32_Sym *)s->data;
312 q = new_syms;
313 for(i = 0; i < nb_syms; i++) {
314 if (ELF32_ST_BIND(p->st_info) == STB_LOCAL) {
315 old_to_new_syms[i] = q - new_syms;
316 *q++ = *p;
318 p++;
320 /* save the number of local symbols in section header */
321 s->sh_info = q - new_syms;
323 /* then second pass for non local symbols */
324 p = (Elf32_Sym *)s->data;
325 for(i = 0; i < nb_syms; i++) {
326 if (ELF32_ST_BIND(p->st_info) != STB_LOCAL) {
327 old_to_new_syms[i] = q - new_syms;
328 *q++ = *p;
330 p++;
333 /* we copy the new symbols to the old */
334 memcpy(s->data, new_syms, nb_syms * sizeof(Elf32_Sym));
335 tcc_free(new_syms);
337 /* now we modify all the relocations */
338 for(i = 1; i < s1->nb_sections; i++) {
339 sr = s1->sections[i];
340 if (sr->sh_type == SHT_REL && sr->link == s) {
341 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
342 for(rel = (Elf32_Rel *)sr->data;
343 rel < rel_end;
344 rel++) {
345 sym_index = ELF32_R_SYM(rel->r_info);
346 type = ELF32_R_TYPE(rel->r_info);
347 sym_index = old_to_new_syms[sym_index];
348 rel->r_info = ELF32_R_INFO(sym_index, type);
353 tcc_free(old_to_new_syms);
356 /* relocate common symbols in the .bss section */
357 static void relocate_common_syms(void)
359 Elf32_Sym *sym, *sym_end;
360 unsigned long offset, align;
362 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
363 for(sym = (Elf32_Sym *)symtab_section->data + 1;
364 sym < sym_end;
365 sym++) {
366 if (sym->st_shndx == SHN_COMMON) {
367 /* align symbol */
368 align = sym->st_value;
369 offset = bss_section->data_offset;
370 offset = (offset + align - 1) & -align;
371 sym->st_value = offset;
372 sym->st_shndx = bss_section->sh_num;
373 offset += sym->st_size;
374 bss_section->data_offset = offset;
379 static void *resolve_sym(const char *sym)
381 return dlsym(RTLD_DEFAULT, sym);
384 /* relocate symbol table, resolve undefined symbols if do_resolve is
385 true and output error if undefined symbol. */
386 static void relocate_syms(TCCState *s1, int do_resolve)
388 Elf32_Sym *sym, *esym, *sym_end;
389 int sym_bind, sh_num, sym_index;
390 const char *name;
391 unsigned long addr;
393 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
394 for(sym = (Elf32_Sym *)symtab_section->data + 1;
395 sym < sym_end;
396 sym++) {
397 sh_num = sym->st_shndx;
398 if (sh_num == SHN_UNDEF) {
399 name = strtab_section->data + sym->st_name;
400 if (do_resolve) {
401 name = symtab_section->link->data + sym->st_name;
402 addr = (unsigned long)resolve_sym(name);
403 if (addr) {
404 sym->st_value = addr;
405 goto found;
407 } else if (s1->dynsym) {
408 /* if dynamic symbol exist, then use it */
409 sym_index = find_elf_sym(s1->dynsym, name);
410 if (sym_index) {
411 esym = &((Elf32_Sym *)s1->dynsym->data)[sym_index];
412 sym->st_value = esym->st_value;
413 goto found;
416 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
417 it */
418 if (!strcmp(name, "_fp_hw"))
419 goto found;
420 /* only weak symbols are accepted to be undefined. Their
421 value is zero */
422 sym_bind = ELF32_ST_BIND(sym->st_info);
423 if (sym_bind == STB_WEAK) {
424 sym->st_value = 0;
425 } else {
426 error_noabort("undefined symbol '%s'", name);
428 } else if (sh_num < SHN_LORESERVE) {
429 /* add section base */
430 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
432 found: ;
436 /* relocate a given section (CPU dependant) */
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, unsigned int val)
586 p[0] = val;
587 p[1] = val >> 8;
588 p[2] = val >> 16;
589 p[3] = val >> 24;
592 static void build_got(TCCState *s1)
594 unsigned char *ptr;
596 /* if no got, then create it */
597 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
598 s1->got->sh_entsize = 4;
599 add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
600 s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
601 ptr = section_ptr_add(s1->got, 3 * sizeof(int));
602 /* keep space for _DYNAMIC pointer, if present */
603 put32(ptr, 0);
604 /* two dummy got entries */
605 put32(ptr + 4, 0);
606 put32(ptr + 8, 0);
609 /* put a got entry corresponding to a symbol in symtab_section. 'size'
610 and 'info' can be modifed if more precise info comes from the DLL */
611 static void put_got_entry(TCCState *s1,
612 int reloc_type, unsigned long size, int info,
613 int sym_index)
615 int index;
616 const char *name;
617 Elf32_Sym *sym;
618 unsigned long offset;
619 int *ptr;
621 if (!s1->got)
622 build_got(s1);
624 /* if a got entry already exists for that symbol, no need to add one */
625 if (sym_index < s1->nb_got_offsets &&
626 s1->got_offsets[sym_index] != 0)
627 return;
629 put_got_offset(s1, sym_index, s1->got->data_offset);
631 if (s1->dynsym) {
632 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
633 name = symtab_section->link->data + sym->st_name;
634 offset = sym->st_value;
635 /* NOTE: we put temporarily the got offset */
636 if (reloc_type == R_386_JMP_SLOT) {
637 s1->nb_plt_entries++;
638 offset = s1->got->data_offset;
640 index = put_elf_sym(s1->dynsym, offset,
641 size, info, 0, sym->st_shndx, name);
642 /* put a got entry */
643 put_elf_reloc(s1->dynsym, s1->got,
644 s1->got->data_offset,
645 reloc_type, index);
647 ptr = section_ptr_add(s1->got, sizeof(int));
648 *ptr = 0;
651 /* build GOT and PLT entries */
652 static void build_got_entries(TCCState *s1)
654 Section *s, *symtab;
655 Elf32_Rel *rel, *rel_end;
656 Elf32_Sym *sym;
657 int i, type, reloc_type, sym_index;
659 for(i = 1; i < s1->nb_sections; i++) {
660 s = s1->sections[i];
661 if (s->sh_type != SHT_REL)
662 continue;
663 /* no need to handle got relocations */
664 if (s->link != symtab_section)
665 continue;
666 symtab = s->link;
667 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
668 for(rel = (Elf32_Rel *)s->data;
669 rel < rel_end;
670 rel++) {
671 type = ELF32_R_TYPE(rel->r_info);
672 switch(type) {
673 case R_386_GOT32:
674 case R_386_GOTOFF:
675 case R_386_GOTPC:
676 case R_386_PLT32:
677 if (!s1->got)
678 build_got(s1);
679 if (type == R_386_GOT32 || type == R_386_PLT32) {
680 sym_index = ELF32_R_SYM(rel->r_info);
681 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
682 /* look at the symbol got offset. If none, then add one */
683 if (type == R_386_GOT32)
684 reloc_type = R_386_GLOB_DAT;
685 else
686 reloc_type = R_386_JMP_SLOT;
687 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
688 sym_index);
690 break;
691 default:
692 break;
698 static Section *new_symtab(TCCState *s1,
699 const char *symtab_name, int sh_type, int sh_flags,
700 const char *strtab_name,
701 const char *hash_name, int hash_sh_flags)
703 Section *symtab, *strtab, *hash;
704 int *ptr, nb_buckets;
706 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
707 symtab->sh_entsize = sizeof(Elf32_Sym);
708 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
709 put_elf_str(strtab, "");
710 symtab->link = strtab;
711 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
713 nb_buckets = 1;
715 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
716 hash->sh_entsize = sizeof(int);
717 symtab->hash = hash;
718 hash->link = symtab;
720 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
721 ptr[0] = nb_buckets;
722 ptr[1] = 1;
723 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
724 return symtab;
727 /* put dynamic tag */
728 static void put_dt(Section *dynamic, int dt, unsigned long val)
730 Elf32_Dyn *dyn;
731 dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
732 dyn->d_tag = dt;
733 dyn->d_un.d_val = val;
736 /* add tcc runtime libraries */
737 static void tcc_add_runtime(TCCState *s1)
739 char buf[1024];
740 int i;
741 Section *s;
743 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.o");
744 tcc_add_file(s1, buf);
745 #ifdef CONFIG_TCC_BCHECK
746 if (do_bounds_check) {
747 unsigned long *ptr;
748 Section *init_section;
749 unsigned char *pinit;
750 int sym_index;
752 /* XXX: add an object file to do that */
753 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
754 *ptr = 0;
755 add_elf_sym(symtab_section, 0, 0,
756 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
757 bounds_section->sh_num, "__bounds_start");
758 /* add bound check code */
759 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
760 tcc_add_file(s1, buf);
761 #ifdef TCC_TARGET_I386
762 if (s1->output_type != TCC_OUTPUT_MEMORY) {
763 /* add 'call __bound_init()' in .init section */
764 init_section = find_section(s1, ".init");
765 pinit = section_ptr_add(init_section, 5);
766 pinit[0] = 0xe8;
767 put32(pinit + 1, -4);
768 sym_index = find_elf_sym(symtab_section, "__bound_init");
769 put_elf_reloc(symtab_section, init_section,
770 init_section->data_offset - 4, R_386_PC32, sym_index);
772 #endif
774 #endif
775 /* add libc if not memory output */
776 if (s1->output_type != TCC_OUTPUT_MEMORY) {
777 tcc_add_library(s1, "c");
778 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
780 /* add various standard linker symbols */
781 add_elf_sym(symtab_section,
782 text_section->data_offset, 0,
783 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
784 text_section->sh_num, "_etext");
785 add_elf_sym(symtab_section,
786 data_section->data_offset, 0,
787 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
788 data_section->sh_num, "_edata");
789 add_elf_sym(symtab_section,
790 bss_section->data_offset, 0,
791 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
792 bss_section->sh_num, "_end");
793 /* add start and stop symbols for sections whose name can be
794 expressed in C */
795 for(i = 1; i < s1->nb_sections; i++) {
796 s = s1->sections[i];
797 if (s->sh_type == SHT_PROGBITS &&
798 (s->sh_flags & SHF_ALLOC)) {
799 const char *p;
800 int ch;
802 /* check if section name can be expressed in C */
803 p = s->name;
804 for(;;) {
805 ch = *p;
806 if (!ch)
807 break;
808 if (!isid(ch) && !isnum(ch))
809 goto next_sec;
810 p++;
812 snprintf(buf, sizeof(buf), "__start_%s", s->name);
813 add_elf_sym(symtab_section,
814 0, 0,
815 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
816 s->sh_num, buf);
817 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
818 add_elf_sym(symtab_section,
819 s->data_offset, 0,
820 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
821 s->sh_num, buf);
823 next_sec: ;
827 /* name of ELF interpreter */
828 #ifdef __FreeBSD__
829 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
830 #else
831 static char elf_interp[] = "/lib/ld-linux.so.2";
832 #endif
834 #define ELF_START_ADDR 0x08048000
835 #define ELF_PAGE_SIZE 0x1000
837 /* output an ELF file */
838 /* XXX: suppress unneeded sections */
839 int tcc_output_file(TCCState *s1, const char *filename)
841 Elf32_Ehdr ehdr;
842 FILE *f;
843 int fd, mode, ret;
844 int *section_order;
845 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
846 unsigned long addr;
847 Section *strsec, *s;
848 Elf32_Shdr shdr, *sh;
849 Elf32_Phdr *phdr, *ph;
850 Section *interp, *plt, *dynamic, *dynstr;
851 unsigned long saved_dynamic_data_offset;
852 Elf32_Sym *sym;
853 int type, file_type;
854 unsigned long rel_addr, rel_size;
856 file_type = s1->output_type;
857 s1->nb_errors = 0;
859 if (file_type != TCC_OUTPUT_OBJ)
860 tcc_add_runtime(s1);
862 phdr = NULL;
863 section_order = NULL;
864 interp = NULL;
865 dynamic = NULL;
866 plt = NULL; /* avoid warning */
867 dynstr = NULL; /* avoid warning */
868 saved_dynamic_data_offset = 0; /* avoid warning */
870 if (file_type != TCC_OUTPUT_OBJ) {
872 relocate_common_syms();
874 if (!s1->static_link) {
875 const char *name;
876 int sym_index, index;
877 Elf32_Sym *esym, *sym_end;
879 if (file_type == TCC_OUTPUT_EXE) {
880 char *ptr;
881 /* add interpreter section only if executable */
882 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
883 interp->sh_addralign = 1;
884 ptr = section_ptr_add(interp, sizeof(elf_interp));
885 strcpy(ptr, elf_interp);
888 /* add dynamic symbol table */
889 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
890 ".dynstr",
891 ".hash", SHF_ALLOC);
892 dynstr = s1->dynsym->link;
894 /* add dynamic section */
895 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
896 SHF_ALLOC | SHF_WRITE);
897 dynamic->link = dynstr;
898 dynamic->sh_entsize = sizeof(Elf32_Dyn);
900 /* add PLT */
901 plt = new_section(s1, ".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
902 plt->sh_entsize = 4;
904 build_got(s1);
906 /* scan for undefined symbols and see if they are in the
907 dynamic symbols. If a symbol STT_FUNC is found, then we
908 add it in the PLT. If a symbol STT_OBJECT is found, we
909 add it in the .bss section with a suitable relocation */
910 sym_end = (Elf32_Sym *)(symtab_section->data +
911 symtab_section->data_offset);
912 if (file_type == TCC_OUTPUT_EXE) {
913 for(sym = (Elf32_Sym *)symtab_section->data + 1;
914 sym < sym_end;
915 sym++) {
916 if (sym->st_shndx == SHN_UNDEF) {
917 name = symtab_section->link->data + sym->st_name;
918 sym_index = find_elf_sym(s1->dynsymtab_section, name);
919 if (sym_index) {
920 esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
921 type = ELF32_ST_TYPE(esym->st_info);
922 if (type == STT_FUNC) {
923 put_got_entry(s1, R_386_JMP_SLOT, esym->st_size,
924 esym->st_info,
925 sym - (Elf32_Sym *)symtab_section->data);
926 } else if (type == STT_OBJECT) {
927 unsigned long offset;
928 offset = bss_section->data_offset;
929 /* XXX: which alignment ? */
930 offset = (offset + 8 - 1) & -8;
931 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
932 esym->st_info, 0,
933 bss_section->sh_num, name);
934 put_elf_reloc(s1->dynsym, bss_section,
935 offset, R_386_COPY, index);
936 offset += esym->st_size;
937 bss_section->data_offset = offset;
939 } else {
940 /* STB_WEAK undefined symbols are accepted */
941 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
942 it */
943 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
944 !strcmp(name, "_fp_hw")) {
945 } else {
946 error_noabort("undefined symbol '%s'", name);
952 if (s1->nb_errors)
953 goto fail;
955 /* now look at unresolved dynamic symbols and export
956 corresponding symbol */
957 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
958 s1->dynsymtab_section->data_offset);
959 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
960 esym < sym_end;
961 esym++) {
962 if (esym->st_shndx == SHN_UNDEF) {
963 name = s1->dynsymtab_section->link->data + esym->st_name;
964 sym_index = find_elf_sym(symtab_section, name);
965 if (sym_index) {
966 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
967 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
968 sym->st_info, 0,
969 sym->st_shndx, name);
970 } else {
971 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
972 /* weak symbols can stay undefined */
973 } else {
974 warning("undefined dynamic symbol '%s'", name);
979 } else {
980 int nb_syms;
981 /* shared library case : we simply export all the global symbols */
982 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
983 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
984 for(sym = (Elf32_Sym *)symtab_section->data + 1;
985 sym < sym_end;
986 sym++) {
987 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
988 name = symtab_section->link->data + sym->st_name;
989 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
990 sym->st_info, 0,
991 sym->st_shndx, name);
992 s1->symtab_to_dynsym[sym -
993 (Elf32_Sym *)symtab_section->data] =
994 index;
999 build_got_entries(s1);
1001 /* update PLT/GOT sizes so that we can allocate their space */
1002 plt->data_offset += 16 * (s1->nb_plt_entries + 1);
1004 /* add a list of needed dlls */
1005 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1006 DLLReference *dllref = s1->loaded_dlls[i];
1007 if (dllref->level == 0)
1008 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1010 /* XXX: currently, since we do not handle PIC code, we
1011 must relocate the readonly segments */
1012 if (file_type == TCC_OUTPUT_DLL)
1013 put_dt(dynamic, DT_TEXTREL, 0);
1015 /* add necessary space for other entries */
1016 saved_dynamic_data_offset = dynamic->data_offset;
1017 dynamic->data_offset += 8 * 9;
1018 } else {
1019 /* still need to build got entries in case of static link */
1020 build_got_entries(s1);
1024 memset(&ehdr, 0, sizeof(ehdr));
1026 /* we add a section for symbols */
1027 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1028 put_elf_str(strsec, "");
1030 /* compute number of sections */
1031 shnum = s1->nb_sections;
1033 /* this array is used to reorder sections in the output file */
1034 section_order = tcc_malloc(sizeof(int) * shnum);
1035 section_order[0] = 0;
1036 sh_order_index = 1;
1038 /* compute number of program headers */
1039 switch(file_type) {
1040 default:
1041 case TCC_OUTPUT_OBJ:
1042 phnum = 0;
1043 break;
1044 case TCC_OUTPUT_EXE:
1045 if (!s1->static_link)
1046 phnum = 4;
1047 else
1048 phnum = 2;
1049 break;
1050 case TCC_OUTPUT_DLL:
1051 phnum = 3;
1052 break;
1055 /* allocate strings for section names and decide if an unallocated
1056 section should be output */
1057 /* NOTE: the strsec section comes last, so its size is also
1058 correct ! */
1059 for(i = 1; i < s1->nb_sections; i++) {
1060 s = s1->sections[i];
1061 s->sh_name = put_elf_str(strsec, s->name);
1062 /* when generating a DLL, we include relocations but we may
1063 patch them */
1064 if (file_type == TCC_OUTPUT_DLL &&
1065 s->sh_type == SHT_REL &&
1066 !(s->sh_flags & SHF_ALLOC)) {
1067 prepare_dynamic_rel(s1, s);
1068 } else if (do_debug ||
1069 file_type == TCC_OUTPUT_OBJ ||
1070 (s->sh_flags & SHF_ALLOC) ||
1071 i == (s1->nb_sections - 1)) {
1072 /* we output all sections if debug or object file */
1073 s->sh_size = s->data_offset;
1077 /* allocate program segment headers */
1078 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1080 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1081 if (phnum > 0) {
1082 /* compute section to program header mapping */
1083 if (file_type == TCC_OUTPUT_DLL)
1084 addr = 0;
1085 else
1086 addr = ELF_START_ADDR;
1088 /* dynamic relocation table information, for .dynamic section */
1089 rel_size = 0;
1090 rel_addr = 0;
1092 /* compute address after headers */
1093 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1095 /* leave one program header for the program interpreter */
1096 ph = &phdr[0];
1097 if (interp)
1098 ph++;
1100 for(j = 0; j < 2; j++) {
1101 ph->p_type = PT_LOAD;
1102 if (j == 0)
1103 ph->p_flags = PF_R | PF_X;
1104 else
1105 ph->p_flags = PF_R | PF_W;
1106 ph->p_align = ELF_PAGE_SIZE;
1108 /* we do the following ordering: interp, symbol tables,
1109 relocations, progbits, nobits */
1110 /* XXX: do faster and simpler sorting */
1111 for(k = 0; k < 5; k++) {
1112 for(i = 1; i < s1->nb_sections; i++) {
1113 s = s1->sections[i];
1114 /* compute if section should be included */
1115 if (j == 0) {
1116 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1117 SHF_ALLOC)
1118 continue;
1119 } else {
1120 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1121 (SHF_ALLOC | SHF_WRITE))
1122 continue;
1124 if (s == interp) {
1125 if (k != 0)
1126 continue;
1127 } else if (s->sh_type == SHT_DYNSYM ||
1128 s->sh_type == SHT_STRTAB ||
1129 s->sh_type == SHT_HASH) {
1130 if (k != 1)
1131 continue;
1132 } else if (s->sh_type == SHT_REL) {
1133 if (k != 2)
1134 continue;
1135 } else if (s->sh_type == SHT_NOBITS) {
1136 if (k != 4)
1137 continue;
1138 } else {
1139 if (k != 3)
1140 continue;
1142 section_order[sh_order_index++] = i;
1144 /* section matches: we align it and add its size */
1145 tmp = file_offset;
1146 file_offset = (file_offset + s->sh_addralign - 1) &
1147 ~(s->sh_addralign - 1);
1148 s->sh_offset = file_offset;
1149 addr += file_offset - tmp;
1150 s->sh_addr = addr;
1152 /* update program header infos */
1153 if (ph->p_offset == 0) {
1154 ph->p_offset = file_offset;
1155 ph->p_vaddr = addr;
1156 ph->p_paddr = ph->p_vaddr;
1158 /* update dynamic relocation infos */
1159 if (s->sh_type == SHT_REL) {
1160 if (rel_size == 0)
1161 rel_addr = addr;
1162 rel_size += s->sh_size;
1164 addr += s->sh_size;
1165 if (s->sh_type != SHT_NOBITS)
1166 file_offset += s->sh_size;
1169 ph->p_filesz = file_offset - ph->p_offset;
1170 ph->p_memsz = addr - ph->p_vaddr;
1171 ph++;
1172 /* if in the middle of a page, we duplicate the page in
1173 memory so that one copy is RX and the other is RW */
1174 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1175 addr += ELF_PAGE_SIZE;
1178 /* if interpreter, then add corresponing program header */
1179 if (interp) {
1180 ph = &phdr[0];
1182 ph->p_type = PT_INTERP;
1183 ph->p_offset = interp->sh_offset;
1184 ph->p_vaddr = interp->sh_addr;
1185 ph->p_paddr = ph->p_vaddr;
1186 ph->p_filesz = interp->sh_size;
1187 ph->p_memsz = interp->sh_size;
1188 ph->p_flags = PF_R;
1189 ph->p_align = interp->sh_addralign;
1192 /* if dynamic section, then add corresponing program header */
1193 if (dynamic) {
1194 int plt_offset;
1195 unsigned char *p;
1196 Elf32_Sym *sym_end;
1198 ph = &phdr[phnum - 1];
1200 ph->p_type = PT_DYNAMIC;
1201 ph->p_offset = dynamic->sh_offset;
1202 ph->p_vaddr = dynamic->sh_addr;
1203 ph->p_paddr = ph->p_vaddr;
1204 ph->p_filesz = dynamic->sh_size;
1205 ph->p_memsz = dynamic->sh_size;
1206 ph->p_flags = PF_R | PF_W;
1207 ph->p_align = dynamic->sh_addralign;
1209 /* put GOT dynamic section address */
1210 put32(s1->got->data, dynamic->sh_addr);
1212 /* compute the PLT */
1213 plt->data_offset = 0;
1215 /* first plt entry */
1216 p = section_ptr_add(plt, 16);
1217 p[0] = 0xff; /* pushl got + 4 */
1218 p[1] = 0x35;
1219 put32(p + 2, s1->got->sh_addr + 4);
1220 p[6] = 0xff; /* jmp *(got + 8) */
1221 p[7] = 0x25;
1222 put32(p + 8, s1->got->sh_addr + 8);
1224 /* relocation symbols in .dynsym and build PLT. */
1225 plt_offset = 0;
1226 sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
1227 for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
1228 sym < sym_end;
1229 sym++) {
1230 type = ELF32_ST_TYPE(sym->st_info);
1231 if (sym->st_shndx == SHN_UNDEF) {
1232 if (type == STT_FUNC) {
1233 /* one more entry in PLT */
1234 p = section_ptr_add(plt, 16);
1235 p[0] = 0xff; /* jmp *(got + x) */
1236 p[1] = 0x25;
1237 put32(p + 2, s1->got->sh_addr + sym->st_value);
1238 p[6] = 0x68; /* push $xxx */
1239 put32(p + 7, plt_offset);
1240 p[11] = 0xe9; /* jmp plt_start */
1241 put32(p + 12, -(plt->data_offset));
1243 /* patch symbol value to point to plt */
1244 sym->st_value = plt->sh_addr + p - plt->data;
1246 plt_offset += 8;
1248 } else if (sym->st_shndx < SHN_LORESERVE) {
1249 /* do symbol relocation */
1250 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1253 /* put dynamic section entries */
1255 dynamic->data_offset = saved_dynamic_data_offset;
1256 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1257 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1258 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1259 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1260 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
1261 put_dt(dynamic, DT_REL, rel_addr);
1262 put_dt(dynamic, DT_RELSZ, rel_size);
1263 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
1264 put_dt(dynamic, DT_NULL, 0);
1267 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1268 ehdr.e_phnum = phnum;
1269 ehdr.e_phoff = sizeof(Elf32_Ehdr);
1272 /* all other sections come after */
1273 for(i = 1; i < s1->nb_sections; i++) {
1274 s = s1->sections[i];
1275 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1276 continue;
1277 section_order[sh_order_index++] = i;
1279 file_offset = (file_offset + s->sh_addralign - 1) &
1280 ~(s->sh_addralign - 1);
1281 s->sh_offset = file_offset;
1282 if (s->sh_type != SHT_NOBITS)
1283 file_offset += s->sh_size;
1286 /* if building executable or DLL, then relocate each section
1287 except the GOT which is already relocated */
1288 if (file_type != TCC_OUTPUT_OBJ) {
1289 relocate_syms(s1, 0);
1291 if (s1->nb_errors != 0) {
1292 fail:
1293 ret = -1;
1294 goto the_end;
1297 /* relocate sections */
1298 /* XXX: ignore sections with allocated relocations ? */
1299 for(i = 1; i < s1->nb_sections; i++) {
1300 s = s1->sections[i];
1301 if (s->reloc && s != s1->got)
1302 relocate_section(s1, s);
1305 /* relocate relocation entries if the relocation tables are
1306 allocated in the executable */
1307 for(i = 1; i < s1->nb_sections; i++) {
1308 s = s1->sections[i];
1309 if ((s->sh_flags & SHF_ALLOC) &&
1310 s->sh_type == SHT_REL) {
1311 relocate_rel(s1, s);
1315 /* get entry point address */
1316 if (file_type == TCC_OUTPUT_EXE)
1317 ehdr.e_entry = (unsigned long)tcc_get_symbol(s1, "_start");
1318 else
1319 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1322 sort_syms(s1, symtab_section);
1324 /* align to 4 */
1325 file_offset = (file_offset + 3) & -4;
1327 /* fill header */
1328 ehdr.e_ident[0] = ELFMAG0;
1329 ehdr.e_ident[1] = ELFMAG1;
1330 ehdr.e_ident[2] = ELFMAG2;
1331 ehdr.e_ident[3] = ELFMAG3;
1332 ehdr.e_ident[4] = ELFCLASS32;
1333 ehdr.e_ident[5] = ELFDATA2LSB;
1334 ehdr.e_ident[6] = EV_CURRENT;
1335 #ifdef __FreeBSD__
1336 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1337 #endif
1338 switch(file_type) {
1339 default:
1340 case TCC_OUTPUT_EXE:
1341 ehdr.e_type = ET_EXEC;
1342 break;
1343 case TCC_OUTPUT_DLL:
1344 ehdr.e_type = ET_DYN;
1345 break;
1346 case TCC_OUTPUT_OBJ:
1347 ehdr.e_type = ET_REL;
1348 break;
1350 ehdr.e_machine = EM_386;
1351 ehdr.e_version = EV_CURRENT;
1352 ehdr.e_shoff = file_offset;
1353 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1354 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1355 ehdr.e_shnum = shnum;
1356 ehdr.e_shstrndx = shnum - 1;
1358 /* write elf file */
1359 if (file_type == TCC_OUTPUT_OBJ)
1360 mode = 0666;
1361 else
1362 mode = 0777;
1363 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
1364 if (fd < 0) {
1365 error_noabort("could not write '%s'", filename);
1366 goto fail;
1368 f = fdopen(fd, "w");
1369 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1370 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1371 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1372 for(i=1;i<s1->nb_sections;i++) {
1373 s = s1->sections[section_order[i]];
1374 if (s->sh_type != SHT_NOBITS) {
1375 while (offset < s->sh_offset) {
1376 fputc(0, f);
1377 offset++;
1379 size = s->sh_size;
1380 fwrite(s->data, 1, size, f);
1381 offset += size;
1384 while (offset < ehdr.e_shoff) {
1385 fputc(0, f);
1386 offset++;
1389 /* output section headers */
1390 for(i=0;i<s1->nb_sections;i++) {
1391 sh = &shdr;
1392 memset(sh, 0, sizeof(Elf32_Shdr));
1393 s = s1->sections[i];
1394 if (s) {
1395 sh->sh_name = s->sh_name;
1396 sh->sh_type = s->sh_type;
1397 sh->sh_flags = s->sh_flags;
1398 sh->sh_entsize = s->sh_entsize;
1399 sh->sh_info = s->sh_info;
1400 if (s->link)
1401 sh->sh_link = s->link->sh_num;
1402 sh->sh_addralign = s->sh_addralign;
1403 sh->sh_addr = s->sh_addr;
1404 sh->sh_offset = s->sh_offset;
1405 sh->sh_size = s->sh_size;
1407 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1409 fclose(f);
1411 ret = 0;
1412 the_end:
1413 tcc_free(s1->symtab_to_dynsym);
1414 tcc_free(section_order);
1415 tcc_free(phdr);
1416 tcc_free(s1->got_offsets);
1417 return ret;
1420 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1422 void *data;
1424 data = tcc_malloc(size);
1425 lseek(fd, file_offset, SEEK_SET);
1426 read(fd, data, size);
1427 return data;
1430 typedef struct SectionMergeInfo {
1431 Section *s; /* corresponding existing section */
1432 unsigned long offset; /* offset of the new section in the existing section */
1433 int new_section; /* true if section 's' was added */
1434 } SectionMergeInfo;
1436 /* load an object file and merge it with current files */
1437 /* XXX: handle correctly stab (debug) info */
1438 static int tcc_load_object_file(TCCState *s1,
1439 int fd, unsigned long file_offset)
1441 Elf32_Ehdr ehdr;
1442 Elf32_Shdr *shdr, *sh;
1443 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1444 unsigned char *strsec, *strtab;
1445 int *old_to_new_syms;
1446 char *sh_name, *name;
1447 SectionMergeInfo *sm_table, *sm;
1448 Elf32_Sym *sym, *symtab;
1449 Elf32_Rel *rel, *rel_end;
1450 Section *s;
1452 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1453 goto fail1;
1454 if (ehdr.e_ident[0] != ELFMAG0 ||
1455 ehdr.e_ident[1] != ELFMAG1 ||
1456 ehdr.e_ident[2] != ELFMAG2 ||
1457 ehdr.e_ident[3] != ELFMAG3)
1458 goto fail1;
1459 /* test if object file */
1460 if (ehdr.e_type != ET_REL)
1461 goto fail1;
1462 /* test CPU specific stuff */
1463 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1464 ehdr.e_machine != EM_386) {
1465 fail1:
1466 error_noabort("invalid object file");
1467 return -1;
1469 /* read sections */
1470 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1471 sizeof(Elf32_Shdr) * ehdr.e_shnum);
1472 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1474 /* load section names */
1475 sh = &shdr[ehdr.e_shstrndx];
1476 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1478 /* load symtab and strtab */
1479 old_to_new_syms = NULL;
1480 symtab = NULL;
1481 strtab = NULL;
1482 nb_syms = 0;
1483 for(i = 1; i < ehdr.e_shnum; i++) {
1484 sh = &shdr[i];
1485 if (sh->sh_type == SHT_SYMTAB) {
1486 if (symtab) {
1487 error_noabort("object must contain only one symtab");
1488 fail:
1489 ret = -1;
1490 goto the_end;
1492 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1493 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1494 sm_table[i].s = symtab_section;
1496 /* now load strtab */
1497 sh = &shdr[sh->sh_link];
1498 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1502 /* now examine each section and try to merge its content with the
1503 ones in memory */
1504 for(i = 1; i < ehdr.e_shnum; i++) {
1505 /* no need to examine section name strtab */
1506 if (i == ehdr.e_shstrndx)
1507 continue;
1508 sh = &shdr[i];
1509 sh_name = strsec + sh->sh_name;
1510 /* ignore sections types we do not handle */
1511 if (sh->sh_type != SHT_PROGBITS &&
1512 sh->sh_type != SHT_REL &&
1513 sh->sh_type != SHT_NOBITS)
1514 continue;
1515 if (sh->sh_addralign < 1)
1516 sh->sh_addralign = 1;
1517 /* find corresponding section, if any */
1518 for(j = 1; j < s1->nb_sections;j++) {
1519 s = s1->sections[j];
1520 if (!strcmp(s->name, sh_name))
1521 goto found;
1523 /* not found: create new section */
1524 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1525 /* take as much info as possible from the section. sh_link and
1526 sh_info will be updated later */
1527 s->sh_addralign = sh->sh_addralign;
1528 s->sh_entsize = sh->sh_entsize;
1529 sm_table[i].new_section = 1;
1530 found:
1531 if (sh->sh_type != s->sh_type) {
1532 error_noabort("invalid section type");
1533 goto fail;
1536 /* align start of section */
1537 offset = s->data_offset;
1538 size = sh->sh_addralign - 1;
1539 offset = (offset + size) & ~size;
1540 if (sh->sh_addralign > s->sh_addralign)
1541 s->sh_addralign = sh->sh_addralign;
1542 s->data_offset = offset;
1543 sm_table[i].offset = offset;
1544 sm_table[i].s = s;
1545 /* concatenate sections */
1546 size = sh->sh_size;
1547 if (sh->sh_type != SHT_NOBITS) {
1548 unsigned char *ptr;
1549 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1550 ptr = section_ptr_add(s, size);
1551 read(fd, ptr, size);
1552 } else {
1553 s->data_offset += size;
1557 /* second short pass to update sh_link and sh_info fields of new
1558 sections */
1559 sm = sm_table;
1560 for(i = 1; i < ehdr.e_shnum; i++) {
1561 s = sm_table[i].s;
1562 if (!s || !sm_table[i].new_section)
1563 continue;
1564 sh = &shdr[i];
1565 if (sh->sh_link > 0)
1566 s->link = sm_table[sh->sh_link].s;
1567 if (sh->sh_type == SHT_REL) {
1568 s->sh_info = sm_table[sh->sh_info].s->sh_num;
1569 /* update backward link */
1570 s1->sections[s->sh_info]->reloc = s;
1574 /* resolve symbols */
1575 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
1577 sym = symtab + 1;
1578 for(i = 1; i < nb_syms; i++, sym++) {
1579 if (sym->st_shndx != SHN_UNDEF &&
1580 sym->st_shndx < SHN_LORESERVE) {
1581 sm = &sm_table[sym->st_shndx];
1582 /* if no corresponding section added, no need to add symbol */
1583 if (!sm->s)
1584 continue;
1585 /* convert section number */
1586 sym->st_shndx = sm->s->sh_num;
1587 /* offset value */
1588 sym->st_value += sm->offset;
1590 /* add symbol */
1591 name = strtab + sym->st_name;
1592 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
1593 sym->st_info, sym->st_shndx, name);
1594 old_to_new_syms[i] = sym_index;
1597 /* third pass to patch relocation entries */
1598 for(i = 1; i < ehdr.e_shnum; i++) {
1599 s = sm_table[i].s;
1600 if (!s)
1601 continue;
1602 sh = &shdr[i];
1603 offset = sm_table[i].offset;
1604 switch(s->sh_type) {
1605 case SHT_REL:
1606 /* take relocation offset information */
1607 offseti = sm_table[sh->sh_info].offset;
1608 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
1609 for(rel = (Elf32_Rel *)(s->data + offset);
1610 rel < rel_end;
1611 rel++) {
1612 int type;
1613 unsigned sym_index;
1614 /* convert symbol index */
1615 type = ELF32_R_TYPE(rel->r_info);
1616 sym_index = ELF32_R_SYM(rel->r_info);
1617 /* NOTE: only one symtab assumed */
1618 if (sym_index >= nb_syms)
1619 goto invalid_reloc;
1620 sym_index = old_to_new_syms[sym_index];
1621 if (!sym_index) {
1622 invalid_reloc:
1623 error_noabort("Invalid relocation entry");
1624 goto fail;
1626 rel->r_info = ELF32_R_INFO(sym_index, type);
1627 /* offset the relocation offset */
1628 rel->r_offset += offseti;
1630 break;
1631 default:
1632 break;
1636 ret = 0;
1637 the_end:
1638 tcc_free(symtab);
1639 tcc_free(strtab);
1640 tcc_free(old_to_new_syms);
1641 tcc_free(sm_table);
1642 tcc_free(strsec);
1643 tcc_free(shdr);
1644 return ret;
1647 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1649 typedef struct ArchiveHeader {
1650 char ar_name[16]; /* name of this member */
1651 char ar_date[12]; /* file mtime */
1652 char ar_uid[6]; /* owner uid; printed as decimal */
1653 char ar_gid[6]; /* owner gid; printed as decimal */
1654 char ar_mode[8]; /* file mode, printed as octal */
1655 char ar_size[10]; /* file size, printed as decimal */
1656 char ar_fmag[2]; /* should contain ARFMAG */
1657 } ArchiveHeader;
1659 /* load a '.a' file */
1660 static int tcc_load_archive(TCCState *s1, int fd)
1662 ArchiveHeader hdr;
1663 char ar_size[11];
1664 char ar_name[17];
1665 char magic[8];
1666 int size, len, i;
1667 unsigned long file_offset;
1669 /* skip magic which was already checked */
1670 read(fd, magic, sizeof(magic));
1672 for(;;) {
1673 len = read(fd, &hdr, sizeof(hdr));
1674 if (len == 0)
1675 break;
1676 if (len != sizeof(hdr)) {
1677 error_noabort("invalid archive");
1678 return -1;
1680 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
1681 ar_size[sizeof(hdr.ar_size)] = '\0';
1682 size = strtol(ar_size, NULL, 0);
1683 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
1684 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
1685 if (ar_name[i] != ' ')
1686 break;
1688 ar_name[i + 1] = '\0';
1689 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
1690 file_offset = lseek(fd, 0, SEEK_CUR);
1691 if (!strcmp(ar_name, "/") ||
1692 !strcmp(ar_name, "//") ||
1693 !strcmp(ar_name, "__.SYMDEF") ||
1694 !strcmp(ar_name, "__.SYMDEF/") ||
1695 !strcmp(ar_name, "ARFILENAMES/")) {
1696 /* skip symbol table or archive names */
1697 } else {
1698 if (tcc_load_object_file(s1, fd, file_offset) < 0)
1699 return -1;
1701 /* align to even */
1702 size = (size + 1) & ~1;
1703 lseek(fd, file_offset + size, SEEK_SET);
1705 return 0;
1708 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
1709 is referenced by the user (so it should be added as DT_NEEDED in
1710 the generated ELF file) */
1711 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
1713 Elf32_Ehdr ehdr;
1714 Elf32_Shdr *shdr, *sh, *sh1;
1715 int i, nb_syms, nb_dts, sym_bind, ret;
1716 Elf32_Sym *sym, *dynsym;
1717 Elf32_Dyn *dt, *dynamic;
1718 unsigned char *dynstr;
1719 const char *name, *soname, *p;
1720 DLLReference *dllref;
1722 read(fd, &ehdr, sizeof(ehdr));
1724 /* test CPU specific stuff */
1725 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1726 ehdr.e_machine != EM_386) {
1727 error_noabort("bad architecture");
1728 return -1;
1731 /* read sections */
1732 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
1734 /* load dynamic section and dynamic symbols */
1735 nb_syms = 0;
1736 nb_dts = 0;
1737 dynamic = NULL;
1738 dynsym = NULL; /* avoid warning */
1739 dynstr = NULL; /* avoid warning */
1740 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
1741 switch(sh->sh_type) {
1742 case SHT_DYNAMIC:
1743 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
1744 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
1745 break;
1746 case SHT_DYNSYM:
1747 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1748 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
1749 sh1 = &shdr[sh->sh_link];
1750 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
1751 break;
1752 default:
1753 break;
1757 /* compute the real library name */
1758 soname = filename;
1759 p = strrchr(soname, '/');
1760 if (p)
1761 soname = p + 1;
1763 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
1764 if (dt->d_tag == DT_SONAME) {
1765 soname = dynstr + dt->d_un.d_val;
1769 /* if the dll is already loaded, do not load it */
1770 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1771 dllref = s1->loaded_dlls[i];
1772 if (!strcmp(soname, dllref->name)) {
1773 /* but update level if needed */
1774 if (level < dllref->level)
1775 dllref->level = level;
1776 ret = 0;
1777 goto the_end;
1781 // printf("loading dll '%s'\n", soname);
1783 /* add the dll and its level */
1784 dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
1785 dllref->level = level;
1786 strcpy(dllref->name, soname);
1787 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
1789 /* add dynamic symbols in dynsym_section */
1790 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
1791 sym_bind = ELF32_ST_BIND(sym->st_info);
1792 if (sym_bind == STB_LOCAL)
1793 continue;
1794 name = dynstr + sym->st_name;
1795 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
1796 sym->st_info, sym->st_shndx, name);
1799 /* load all referenced DLLs */
1800 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
1801 switch(dt->d_tag) {
1802 case DT_NEEDED:
1803 name = dynstr + dt->d_un.d_val;
1804 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1805 dllref = s1->loaded_dlls[i];
1806 if (!strcmp(name, dllref->name))
1807 goto already_loaded;
1809 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
1810 error_noabort("referenced dll '%s' not found", name);
1811 ret = -1;
1812 goto the_end;
1814 already_loaded:
1815 break;
1818 ret = 0;
1819 the_end:
1820 tcc_free(dynstr);
1821 tcc_free(dynsym);
1822 tcc_free(dynamic);
1823 tcc_free(shdr);
1824 return ret;
1827 #define LD_TOK_NAME 256
1828 #define LD_TOK_EOF (-1)
1830 /* return next ld script token */
1831 static int ld_next(TCCState *s1, char *name, int name_size)
1833 int c;
1834 char *q;
1836 redo:
1837 switch(ch) {
1838 case ' ':
1839 case '\t':
1840 case '\f':
1841 case '\v':
1842 case '\r':
1843 case '\n':
1844 inp();
1845 goto redo;
1846 case '/':
1847 minp();
1848 if (ch == '*') {
1849 parse_comment();
1850 goto redo;
1851 } else {
1852 q = name;
1853 *q++ = '/';
1854 goto parse_name;
1856 break;
1857 case 'a' ... 'z':
1858 case 'A' ... 'Z':
1859 case '_':
1860 case '\\':
1861 case '.':
1862 case '$':
1863 case '~':
1864 q = name;
1865 parse_name:
1866 for(;;) {
1867 if (!((ch >= 'a' && ch <= 'z') ||
1868 (ch >= 'A' && ch <= 'Z') ||
1869 (ch >= '0' && ch <= '9') ||
1870 strchr("/.-_+=$:\\,~", ch)))
1871 break;
1872 if ((q - name) < name_size - 1) {
1873 *q++ = ch;
1875 minp();
1877 *q = '\0';
1878 c = LD_TOK_NAME;
1879 break;
1880 case CH_EOF:
1881 c = LD_TOK_EOF;
1882 break;
1883 default:
1884 c = ch;
1885 inp();
1886 break;
1888 #if 0
1889 printf("tok=%c %d\n", c, c);
1890 if (c == LD_TOK_NAME)
1891 printf(" name=%s\n", name);
1892 #endif
1893 return c;
1896 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
1897 files */
1898 static int tcc_load_ldscript(TCCState *s1)
1900 char cmd[64];
1901 char filename[1024];
1902 int t;
1904 ch = file->buf_ptr[0];
1905 ch = handle_eob();
1906 for(;;) {
1907 t = ld_next(s1, cmd, sizeof(cmd));
1908 if (t == LD_TOK_EOF)
1909 return 0;
1910 else if (t != LD_TOK_NAME)
1911 return -1;
1912 if (!strcmp(cmd, "INPUT") ||
1913 !strcmp(cmd, "GROUP")) {
1914 t = ld_next(s1, cmd, sizeof(cmd));
1915 if (t != '(')
1916 expect("(");
1917 t = ld_next(s1, filename, sizeof(filename));
1918 for(;;) {
1919 if (t == LD_TOK_EOF) {
1920 error_noabort("unexpected end of file");
1921 return -1;
1922 } else if (t == ')') {
1923 break;
1924 } else if (t != LD_TOK_NAME) {
1925 error_noabort("filename expected");
1926 return -1;
1928 tcc_add_file(s1, filename);
1929 t = ld_next(s1, filename, sizeof(filename));
1930 if (t == ',') {
1931 t = ld_next(s1, filename, sizeof(filename));
1934 } else {
1935 return -1;
1938 return 0;