added cvsignore
[tinycc.git] / tccelf.c
blobcd654ce32607bc8765181b77ea93db57e10ad672
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 static unsigned long get_elf_sym_val(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 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 != dynsymtab_section)
203 error("'%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(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(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 < nb_sections; i++) {
339 sr = 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(NULL, 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(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 (dynsym) {
408 /* if dynamic symbol exist, then use it */
409 sym_index = find_elf_sym(dynsym, name);
410 if (sym_index) {
411 esym = &((Elf32_Sym *)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("undefined symbol '%s'", name);
428 } else if (sh_num < SHN_LORESERVE) {
429 /* add section base */
430 sym->st_value += 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 = 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 = 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 += got->sh_addr - addr;
499 break;
500 case R_386_GOTOFF:
501 *(int *)ptr += val - got->sh_addr;
502 break;
503 case R_386_GOT32:
504 /* we load the got offset */
505 *(int *)ptr += 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 = dynsym;
514 /* relocate relocation table in 'sr' */
515 static void relocate_rel(Section *sr)
517 Section *s;
518 Elf32_Rel *rel, *rel_end;
520 s = 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(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 = 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(int index, unsigned long val)
564 int n;
565 unsigned long *tab;
567 if (index >= 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(got_offsets, n * sizeof(unsigned long));
573 if (!tab)
574 error("memory full");
575 got_offsets = tab;
576 memset(got_offsets + nb_got_offsets, 0,
577 (n - nb_got_offsets) * sizeof(unsigned long));
578 nb_got_offsets = n;
580 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(void)
594 unsigned char *ptr;
596 /* if no got, then create it */
597 got = new_section(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
598 got->sh_entsize = 4;
599 add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
600 got->sh_num, "_GLOBAL_OFFSET_TABLE_");
601 ptr = section_ptr_add(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(int reloc_type, unsigned long size, int info,
612 int sym_index)
614 int index;
615 const char *name;
616 Elf32_Sym *sym;
617 unsigned long offset;
618 int *ptr;
620 if (!got)
621 build_got();
623 /* if a got entry already exists for that symbol, no need to add one */
624 if (sym_index < nb_got_offsets &&
625 got_offsets[sym_index] != 0)
626 return;
628 put_got_offset(sym_index, got->data_offset);
630 if (dynsym) {
631 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
632 name = symtab_section->link->data + sym->st_name;
633 offset = sym->st_value;
634 /* NOTE: we put temporarily the got offset */
635 if (reloc_type == R_386_JMP_SLOT) {
636 nb_plt_entries++;
637 offset = got->data_offset;
639 index = put_elf_sym(dynsym, offset,
640 size, info, 0, sym->st_shndx, name);
641 /* put a got entry */
642 put_elf_reloc(dynsym, got,
643 got->data_offset,
644 reloc_type, index);
646 ptr = section_ptr_add(got, sizeof(int));
647 *ptr = 0;
650 /* build GOT and PLT entries */
651 static void build_got_entries(void)
653 Section *s, *symtab;
654 Elf32_Rel *rel, *rel_end;
655 Elf32_Sym *sym;
656 int i, type, reloc_type, sym_index;
658 for(i = 1; i < nb_sections; i++) {
659 s = sections[i];
660 if (s->sh_type != SHT_REL)
661 continue;
662 /* no need to handle got relocations */
663 if (s->link != symtab_section)
664 continue;
665 symtab = s->link;
666 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
667 for(rel = (Elf32_Rel *)s->data;
668 rel < rel_end;
669 rel++) {
670 type = ELF32_R_TYPE(rel->r_info);
671 switch(type) {
672 case R_386_GOT32:
673 case R_386_GOTOFF:
674 case R_386_GOTPC:
675 case R_386_PLT32:
676 if (!got)
677 build_got();
678 if (type == R_386_GOT32 || type == R_386_PLT32) {
679 sym_index = ELF32_R_SYM(rel->r_info);
680 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
681 /* look at the symbol got offset. If none, then add one */
682 if (type == R_386_GOT32)
683 reloc_type = R_386_GLOB_DAT;
684 else
685 reloc_type = R_386_JMP_SLOT;
686 put_got_entry(reloc_type, sym->st_size, sym->st_info,
687 sym_index);
689 break;
690 default:
691 break;
697 static Section *new_symtab(const char *symtab_name, int sh_type, int sh_flags,
698 const char *strtab_name,
699 const char *hash_name, int hash_sh_flags)
701 Section *symtab, *strtab, *hash;
702 int *ptr, nb_buckets;
704 symtab = new_section(symtab_name, sh_type, sh_flags);
705 symtab->sh_entsize = sizeof(Elf32_Sym);
706 strtab = new_section(strtab_name, SHT_STRTAB, sh_flags);
707 put_elf_str(strtab, "");
708 symtab->link = strtab;
709 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
711 nb_buckets = 1;
713 hash = new_section(hash_name, SHT_HASH, hash_sh_flags);
714 hash->sh_entsize = sizeof(int);
715 symtab->hash = hash;
716 hash->link = symtab;
718 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
719 ptr[0] = nb_buckets;
720 ptr[1] = 1;
721 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
722 return symtab;
725 /* put dynamic tag */
726 static void put_dt(Section *dynamic, int dt, unsigned long val)
728 Elf32_Dyn *dyn;
729 dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
730 dyn->d_tag = dt;
731 dyn->d_un.d_val = val;
734 /* add tcc runtime libraries */
735 static void tcc_add_runtime(TCCState *s1)
737 char buf[1024];
738 int i;
739 Section *s;
741 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.o");
742 tcc_add_file(s1, buf);
743 #ifdef CONFIG_TCC_BCHECK
744 if (do_bounds_check) {
745 unsigned long *ptr;
746 Section *init_section;
747 unsigned char *pinit;
748 int sym_index;
750 /* XXX: add an object file to do that */
751 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
752 *ptr = 0;
753 add_elf_sym(symtab_section, 0, 0,
754 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
755 bounds_section->sh_num, "__bounds_start");
756 /* add bound check code */
757 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
758 tcc_add_file(s1, buf);
759 #ifdef TCC_TARGET_I386
760 if (s1->output_type != TCC_OUTPUT_MEMORY) {
761 /* add 'call __bound_init()' in .init section */
762 init_section = find_section(".init");
763 pinit = section_ptr_add(init_section, 5);
764 pinit[0] = 0xe8;
765 put32(pinit + 1, -4);
766 sym_index = find_elf_sym(symtab_section, "__bound_init");
767 put_elf_reloc(symtab_section, init_section,
768 init_section->data_offset - 4, R_386_PC32, sym_index);
770 #endif
772 #endif
773 /* add libc if not memory output */
774 if (s1->output_type != TCC_OUTPUT_MEMORY) {
775 tcc_add_library(s1, "c");
776 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
778 /* add various standard linker symbols */
779 add_elf_sym(symtab_section,
780 text_section->data_offset, 0,
781 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
782 text_section->sh_num, "_etext");
783 add_elf_sym(symtab_section,
784 data_section->data_offset, 0,
785 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
786 data_section->sh_num, "_edata");
787 add_elf_sym(symtab_section,
788 bss_section->data_offset, 0,
789 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
790 bss_section->sh_num, "_end");
791 /* add start and stop symbols for sections whose name can be
792 expressed in C */
793 for(i = 1; i < nb_sections; i++) {
794 s = sections[i];
795 if (s->sh_type == SHT_PROGBITS &&
796 (s->sh_flags & SHF_ALLOC)) {
797 const char *p;
798 int ch;
800 /* check if section name can be expressed in C */
801 p = s->name;
802 for(;;) {
803 ch = *p;
804 if (!ch)
805 break;
806 if (!isid(ch) && !isnum(ch))
807 goto next_sec;
808 p++;
810 snprintf(buf, sizeof(buf), "__start_%s", s->name);
811 add_elf_sym(symtab_section,
812 0, 0,
813 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
814 s->sh_num, buf);
815 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
816 add_elf_sym(symtab_section,
817 s->data_offset, 0,
818 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
819 s->sh_num, buf);
821 next_sec: ;
825 /* name of ELF interpreter */
826 static char elf_interp[] = "/lib/ld-linux.so.2";
828 #define ELF_START_ADDR 0x08048000
829 #define ELF_PAGE_SIZE 0x1000
831 /* output an ELF file */
832 /* XXX: suppress unneeded sections */
833 int tcc_output_file(TCCState *s1, const char *filename)
835 Elf32_Ehdr ehdr;
836 FILE *f;
837 int fd, mode;
838 int *section_order;
839 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
840 unsigned long addr;
841 Section *strsec, *s;
842 Elf32_Shdr shdr, *sh;
843 Elf32_Phdr *phdr, *ph;
844 Section *interp, *plt, *dynamic, *dynstr;
845 unsigned long saved_dynamic_data_offset;
846 Elf32_Sym *sym;
847 int type, file_type;
848 unsigned long rel_addr, rel_size;
850 file_type = s1->output_type;
852 if (file_type != TCC_OUTPUT_OBJ)
853 tcc_add_runtime(s1);
855 interp = NULL;
856 dynamic = NULL;
857 dynsym = NULL;
858 got = NULL;
859 nb_plt_entries = 0;
860 plt = NULL; /* avoid warning */
861 dynstr = NULL; /* avoid warning */
862 saved_dynamic_data_offset = 0; /* avoid warning */
864 if (file_type != TCC_OUTPUT_OBJ) {
866 relocate_common_syms();
868 if (!static_link) {
869 const char *name;
870 int sym_index, index;
871 Elf32_Sym *esym, *sym_end;
873 if (file_type == TCC_OUTPUT_EXE) {
874 char *ptr;
875 /* add interpreter section only if executable */
876 interp = new_section(".interp", SHT_PROGBITS, SHF_ALLOC);
877 interp->sh_addralign = 1;
878 ptr = section_ptr_add(interp, sizeof(elf_interp));
879 strcpy(ptr, elf_interp);
882 /* add dynamic symbol table */
883 dynsym = new_symtab(".dynsym", SHT_DYNSYM, SHF_ALLOC,
884 ".dynstr",
885 ".hash", SHF_ALLOC);
886 dynstr = dynsym->link;
888 /* add dynamic section */
889 dynamic = new_section(".dynamic", SHT_DYNAMIC,
890 SHF_ALLOC | SHF_WRITE);
891 dynamic->link = dynstr;
892 dynamic->sh_entsize = sizeof(Elf32_Dyn);
894 /* add PLT */
895 plt = new_section(".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
896 plt->sh_entsize = 4;
898 build_got();
900 /* scan for undefined symbols and see if they are in the
901 dynamic symbols. If a symbol STT_FUNC is found, then we
902 add it in the PLT. If a symbol STT_OBJECT is found, we
903 add it in the .bss section with a suitable relocation */
904 sym_end = (Elf32_Sym *)(symtab_section->data +
905 symtab_section->data_offset);
906 if (file_type == TCC_OUTPUT_EXE) {
907 for(sym = (Elf32_Sym *)symtab_section->data + 1;
908 sym < sym_end;
909 sym++) {
910 if (sym->st_shndx == SHN_UNDEF) {
911 name = symtab_section->link->data + sym->st_name;
912 sym_index = find_elf_sym(dynsymtab_section, name);
913 if (sym_index) {
914 esym = &((Elf32_Sym *)dynsymtab_section->data)[sym_index];
915 type = ELF32_ST_TYPE(esym->st_info);
916 if (type == STT_FUNC) {
917 put_got_entry(R_386_JMP_SLOT, esym->st_size,
918 esym->st_info,
919 sym - (Elf32_Sym *)symtab_section->data);
920 } else if (type == STT_OBJECT) {
921 unsigned long offset;
922 offset = bss_section->data_offset;
923 /* XXX: which alignment ? */
924 offset = (offset + 8 - 1) & -8;
925 index = put_elf_sym(dynsym, offset, esym->st_size,
926 esym->st_info, 0,
927 bss_section->sh_num, name);
928 put_elf_reloc(dynsym, bss_section,
929 offset, R_386_COPY, index);
930 offset += esym->st_size;
931 bss_section->data_offset = offset;
933 } else {
934 /* STB_WEAK undefined symbols are accepted */
935 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
936 it */
937 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
938 !strcmp(name, "_fp_hw")) {
939 } else {
940 error("undefined symbol '%s'", name);
946 /* now look at unresolved dynamic symbols and export
947 corresponding symbol */
948 sym_end = (Elf32_Sym *)(dynsymtab_section->data +
949 dynsymtab_section->data_offset);
950 for(esym = (Elf32_Sym *)dynsymtab_section->data + 1;
951 esym < sym_end;
952 esym++) {
953 if (esym->st_shndx == SHN_UNDEF) {
954 name = dynsymtab_section->link->data + esym->st_name;
955 sym_index = find_elf_sym(symtab_section, name);
956 if (sym_index) {
957 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
958 put_elf_sym(dynsym, sym->st_value, sym->st_size,
959 sym->st_info, 0,
960 sym->st_shndx, name);
961 } else {
962 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
963 /* weak symbols can stay undefined */
964 } else {
965 warning("undefined dynamic symbol '%s'", name);
970 } else {
971 int nb_syms;
972 /* shared library case : we simply export all the global symbols */
973 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
974 symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
975 for(sym = (Elf32_Sym *)symtab_section->data + 1;
976 sym < sym_end;
977 sym++) {
978 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
979 name = symtab_section->link->data + sym->st_name;
980 index = put_elf_sym(dynsym, sym->st_value, sym->st_size,
981 sym->st_info, 0,
982 sym->st_shndx, name);
983 symtab_to_dynsym[sym - (Elf32_Sym *)symtab_section->data] =
984 index;
989 build_got_entries();
991 /* update PLT/GOT sizes so that we can allocate their space */
992 plt->data_offset += 16 * (nb_plt_entries + 1);
994 /* add a list of needed dlls */
995 for(i = 0; i < nb_loaded_dlls; i++) {
996 DLLReference *dllref = loaded_dlls[i];
997 if (dllref->level == 0)
998 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1000 /* XXX: currently, since we do not handle PIC code, we
1001 must relocate the readonly segments */
1002 if (file_type == TCC_OUTPUT_DLL)
1003 put_dt(dynamic, DT_TEXTREL, 0);
1005 /* add necessary space for other entries */
1006 saved_dynamic_data_offset = dynamic->data_offset;
1007 dynamic->data_offset += 8 * 9;
1008 } else {
1009 /* still need to build got entries in case of static link */
1010 build_got_entries();
1014 memset(&ehdr, 0, sizeof(ehdr));
1016 /* we add a section for symbols */
1017 strsec = new_section(".shstrtab", SHT_STRTAB, 0);
1018 put_elf_str(strsec, "");
1020 /* compute number of sections */
1021 shnum = nb_sections;
1023 /* this array is used to reorder sections in the output file */
1024 section_order = tcc_malloc(sizeof(int) * shnum);
1025 section_order[0] = 0;
1026 sh_order_index = 1;
1028 /* compute number of program headers */
1029 switch(file_type) {
1030 default:
1031 case TCC_OUTPUT_OBJ:
1032 phnum = 0;
1033 break;
1034 case TCC_OUTPUT_EXE:
1035 if (!static_link)
1036 phnum = 4;
1037 else
1038 phnum = 2;
1039 break;
1040 case TCC_OUTPUT_DLL:
1041 phnum = 3;
1042 break;
1045 /* allocate strings for section names and decide if an unallocated
1046 section should be output */
1047 /* NOTE: the strsec section comes last, so its size is also
1048 correct ! */
1049 for(i = 1; i < nb_sections; i++) {
1050 s = sections[i];
1051 s->sh_name = put_elf_str(strsec, s->name);
1052 /* when generating a DLL, we include relocations but we may
1053 patch them */
1054 if (file_type == TCC_OUTPUT_DLL &&
1055 s->sh_type == SHT_REL &&
1056 !(s->sh_flags & SHF_ALLOC)) {
1057 prepare_dynamic_rel(s);
1058 } else if (do_debug ||
1059 file_type == TCC_OUTPUT_OBJ ||
1060 (s->sh_flags & SHF_ALLOC) ||
1061 i == (nb_sections - 1)) {
1062 /* we output all sections if debug or object file */
1063 s->sh_size = s->data_offset;
1067 /* allocate program segment headers */
1068 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1070 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1071 if (phnum > 0) {
1072 /* compute section to program header mapping */
1073 if (file_type == TCC_OUTPUT_DLL)
1074 addr = 0;
1075 else
1076 addr = ELF_START_ADDR;
1078 /* dynamic relocation table information, for .dynamic section */
1079 rel_size = 0;
1080 rel_addr = 0;
1082 /* compute address after headers */
1083 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1085 /* leave one program header for the program interpreter */
1086 ph = &phdr[0];
1087 if (interp)
1088 ph++;
1090 for(j = 0; j < 2; j++) {
1091 ph->p_type = PT_LOAD;
1092 if (j == 0)
1093 ph->p_flags = PF_R | PF_X;
1094 else
1095 ph->p_flags = PF_R | PF_W;
1096 ph->p_align = ELF_PAGE_SIZE;
1098 /* we do the following ordering: interp, symbol tables,
1099 relocations, progbits, nobits */
1100 /* XXX: do faster and simpler sorting */
1101 for(k = 0; k < 5; k++) {
1102 for(i = 1; i < nb_sections; i++) {
1103 s = sections[i];
1104 /* compute if section should be included */
1105 if (j == 0) {
1106 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1107 SHF_ALLOC)
1108 continue;
1109 } else {
1110 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1111 (SHF_ALLOC | SHF_WRITE))
1112 continue;
1114 if (s == interp) {
1115 if (k != 0)
1116 continue;
1117 } else if (s->sh_type == SHT_DYNSYM ||
1118 s->sh_type == SHT_STRTAB ||
1119 s->sh_type == SHT_HASH) {
1120 if (k != 1)
1121 continue;
1122 } else if (s->sh_type == SHT_REL) {
1123 if (k != 2)
1124 continue;
1125 } else if (s->sh_type == SHT_NOBITS) {
1126 if (k != 4)
1127 continue;
1128 } else {
1129 if (k != 3)
1130 continue;
1132 section_order[sh_order_index++] = i;
1134 /* section matches: we align it and add its size */
1135 tmp = file_offset;
1136 file_offset = (file_offset + s->sh_addralign - 1) &
1137 ~(s->sh_addralign - 1);
1138 s->sh_offset = file_offset;
1139 addr += file_offset - tmp;
1140 s->sh_addr = addr;
1142 /* update program header infos */
1143 if (ph->p_offset == 0) {
1144 ph->p_offset = file_offset;
1145 ph->p_vaddr = addr;
1146 ph->p_paddr = ph->p_vaddr;
1148 /* update dynamic relocation infos */
1149 if (s->sh_type == SHT_REL) {
1150 if (rel_size == 0)
1151 rel_addr = addr;
1152 rel_size += s->sh_size;
1154 addr += s->sh_size;
1155 if (s->sh_type != SHT_NOBITS)
1156 file_offset += s->sh_size;
1159 ph->p_filesz = file_offset - ph->p_offset;
1160 ph->p_memsz = addr - ph->p_vaddr;
1161 ph++;
1164 /* if interpreter, then add corresponing program header */
1165 if (interp) {
1166 ph = &phdr[0];
1168 ph->p_type = PT_INTERP;
1169 ph->p_offset = interp->sh_offset;
1170 ph->p_vaddr = interp->sh_addr;
1171 ph->p_paddr = ph->p_vaddr;
1172 ph->p_filesz = interp->sh_size;
1173 ph->p_memsz = interp->sh_size;
1174 ph->p_flags = PF_R;
1175 ph->p_align = interp->sh_addralign;
1178 /* if dynamic section, then add corresponing program header */
1179 if (dynamic) {
1180 int plt_offset;
1181 unsigned char *p;
1182 Elf32_Sym *sym_end;
1184 ph = &phdr[phnum - 1];
1186 ph->p_type = PT_DYNAMIC;
1187 ph->p_offset = dynamic->sh_offset;
1188 ph->p_vaddr = dynamic->sh_addr;
1189 ph->p_paddr = ph->p_vaddr;
1190 ph->p_filesz = dynamic->sh_size;
1191 ph->p_memsz = dynamic->sh_size;
1192 ph->p_flags = PF_R | PF_W;
1193 ph->p_align = dynamic->sh_addralign;
1195 /* put GOT dynamic section address */
1196 put32(got->data, dynamic->sh_addr);
1198 /* compute the PLT */
1199 plt->data_offset = 0;
1201 /* first plt entry */
1202 p = section_ptr_add(plt, 16);
1203 p[0] = 0xff; /* pushl got + 4 */
1204 p[1] = 0x35;
1205 put32(p + 2, got->sh_addr + 4);
1206 p[6] = 0xff; /* jmp *(got + 8) */
1207 p[7] = 0x25;
1208 put32(p + 8, got->sh_addr + 8);
1210 /* relocation symbols in .dynsym and build PLT. */
1211 plt_offset = 0;
1212 sym_end = (Elf32_Sym *)(dynsym->data + dynsym->data_offset);
1213 for(sym = (Elf32_Sym *)dynsym->data + 1;
1214 sym < sym_end;
1215 sym++) {
1216 type = ELF32_ST_TYPE(sym->st_info);
1217 if (sym->st_shndx == SHN_UNDEF) {
1218 if (type == STT_FUNC) {
1219 /* one more entry in PLT */
1220 p = section_ptr_add(plt, 16);
1221 p[0] = 0xff; /* jmp *(got + x) */
1222 p[1] = 0x25;
1223 put32(p + 2, got->sh_addr + sym->st_value);
1224 p[6] = 0x68; /* push $xxx */
1225 put32(p + 7, plt_offset);
1226 p[11] = 0xe9; /* jmp plt_start */
1227 put32(p + 12, -(plt->data_offset));
1229 /* patch symbol value to point to plt */
1230 sym->st_value = plt->sh_addr + p - plt->data;
1232 plt_offset += 8;
1234 } else if (sym->st_shndx < SHN_LORESERVE) {
1235 /* do symbol relocation */
1236 sym->st_value += sections[sym->st_shndx]->sh_addr;
1239 /* put dynamic section entries */
1241 dynamic->data_offset = saved_dynamic_data_offset;
1242 put_dt(dynamic, DT_HASH, dynsym->hash->sh_addr);
1243 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1244 put_dt(dynamic, DT_SYMTAB, dynsym->sh_addr);
1245 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1246 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
1247 put_dt(dynamic, DT_REL, rel_addr);
1248 put_dt(dynamic, DT_RELSZ, rel_size);
1249 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
1250 put_dt(dynamic, DT_NULL, 0);
1253 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1254 ehdr.e_phnum = phnum;
1255 ehdr.e_phoff = sizeof(Elf32_Ehdr);
1258 /* all other sections come after */
1259 for(i = 1; i < nb_sections; i++) {
1260 s = sections[i];
1261 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1262 continue;
1263 section_order[sh_order_index++] = i;
1265 file_offset = (file_offset + s->sh_addralign - 1) &
1266 ~(s->sh_addralign - 1);
1267 s->sh_offset = file_offset;
1268 if (s->sh_type != SHT_NOBITS)
1269 file_offset += s->sh_size;
1272 /* if building executable or DLL, then relocate each section
1273 except the GOT which is already relocated */
1274 if (file_type != TCC_OUTPUT_OBJ) {
1275 relocate_syms(0);
1277 /* relocate sections */
1278 /* XXX: ignore sections with allocated relocations ? */
1279 for(i = 1; i < nb_sections; i++) {
1280 s = sections[i];
1281 if (s->reloc && s != got)
1282 relocate_section(s1, s);
1285 /* relocate relocation entries if the relocation tables are
1286 allocated in the executable */
1287 for(i = 1; i < nb_sections; i++) {
1288 s = sections[i];
1289 if ((s->sh_flags & SHF_ALLOC) &&
1290 s->sh_type == SHT_REL) {
1291 relocate_rel(s);
1295 /* get entry point address */
1296 if (file_type == TCC_OUTPUT_EXE)
1297 ehdr.e_entry = get_elf_sym_val("_start");
1298 else
1299 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1302 sort_syms(symtab_section);
1304 /* align to 4 */
1305 file_offset = (file_offset + 3) & -4;
1307 /* fill header */
1308 ehdr.e_ident[0] = ELFMAG0;
1309 ehdr.e_ident[1] = ELFMAG1;
1310 ehdr.e_ident[2] = ELFMAG2;
1311 ehdr.e_ident[3] = ELFMAG3;
1312 ehdr.e_ident[4] = ELFCLASS32;
1313 ehdr.e_ident[5] = ELFDATA2LSB;
1314 ehdr.e_ident[6] = EV_CURRENT;
1315 switch(file_type) {
1316 default:
1317 case TCC_OUTPUT_EXE:
1318 ehdr.e_type = ET_EXEC;
1319 break;
1320 case TCC_OUTPUT_DLL:
1321 ehdr.e_type = ET_DYN;
1322 break;
1323 case TCC_OUTPUT_OBJ:
1324 ehdr.e_type = ET_REL;
1325 break;
1327 ehdr.e_machine = EM_386;
1328 ehdr.e_version = EV_CURRENT;
1329 ehdr.e_shoff = file_offset;
1330 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1331 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1332 ehdr.e_shnum = shnum;
1333 ehdr.e_shstrndx = shnum - 1;
1335 /* write elf file */
1336 if (file_type == TCC_OUTPUT_OBJ)
1337 mode = 0666;
1338 else
1339 mode = 0777;
1340 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
1341 if (fd < 0)
1342 error("could not write '%s'", filename);
1344 f = fdopen(fd, "w");
1345 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1346 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1347 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1348 for(i=1;i<nb_sections;i++) {
1349 s = sections[section_order[i]];
1350 if (s->sh_type != SHT_NOBITS) {
1351 while (offset < s->sh_offset) {
1352 fputc(0, f);
1353 offset++;
1355 size = s->sh_size;
1356 fwrite(s->data, 1, size, f);
1357 offset += size;
1360 while (offset < ehdr.e_shoff) {
1361 fputc(0, f);
1362 offset++;
1365 /* output section headers */
1366 for(i=0;i<nb_sections;i++) {
1367 sh = &shdr;
1368 memset(sh, 0, sizeof(Elf32_Shdr));
1369 s = sections[i];
1370 if (s) {
1371 sh->sh_name = s->sh_name;
1372 sh->sh_type = s->sh_type;
1373 sh->sh_flags = s->sh_flags;
1374 sh->sh_entsize = s->sh_entsize;
1375 sh->sh_info = s->sh_info;
1376 if (s->link)
1377 sh->sh_link = s->link->sh_num;
1378 sh->sh_addralign = s->sh_addralign;
1379 sh->sh_addr = s->sh_addr;
1380 sh->sh_offset = s->sh_offset;
1381 sh->sh_size = s->sh_size;
1383 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1385 fclose(f);
1387 tcc_free(section_order);
1388 tcc_free(phdr);
1389 return 0;
1392 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1394 void *data;
1396 data = tcc_malloc(size);
1397 lseek(fd, file_offset, SEEK_SET);
1398 read(fd, data, size);
1399 return data;
1402 typedef struct SectionMergeInfo {
1403 Section *s; /* corresponding existing section */
1404 unsigned long offset; /* offset of the new section in the existing section */
1405 int new_section; /* true if section 's' was added */
1406 } SectionMergeInfo;
1408 /* load an object file and merge it with current files */
1409 /* XXX: handle correctly stab (debug) info */
1410 static int tcc_load_object_file(TCCState *s1,
1411 int fd, unsigned long file_offset)
1413 Elf32_Ehdr ehdr;
1414 Elf32_Shdr *shdr, *sh;
1415 int size, i, j, offset, offseti, nb_syms, sym_index;
1416 unsigned char *strsec, *strtab;
1417 int *old_to_new_syms;
1418 char *sh_name, *name;
1419 SectionMergeInfo *sm_table, *sm;
1420 Elf32_Sym *sym, *symtab;
1421 Elf32_Rel *rel, *rel_end;
1422 Section *s;
1424 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1425 goto fail;
1426 if (ehdr.e_ident[0] != ELFMAG0 ||
1427 ehdr.e_ident[1] != ELFMAG1 ||
1428 ehdr.e_ident[2] != ELFMAG2 ||
1429 ehdr.e_ident[3] != ELFMAG3)
1430 goto fail;
1431 /* test if object file */
1432 if (ehdr.e_type != ET_REL)
1433 goto fail;
1434 /* test CPU specific stuff */
1435 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1436 ehdr.e_machine != EM_386) {
1437 fail:
1438 error("invalid object file");
1440 /* read sections */
1441 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1442 sizeof(Elf32_Shdr) * ehdr.e_shnum);
1443 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1445 /* load section names */
1446 sh = &shdr[ehdr.e_shstrndx];
1447 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1449 /* load symtab and strtab */
1450 symtab = NULL;
1451 strtab = NULL;
1452 nb_syms = 0;
1453 for(i = 1; i < ehdr.e_shnum; i++) {
1454 sh = &shdr[i];
1455 if (sh->sh_type == SHT_SYMTAB) {
1456 if (symtab)
1457 error("object must contain only one symtab");
1458 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1459 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1460 sm_table[i].s = symtab_section;
1462 /* now load strtab */
1463 sh = &shdr[sh->sh_link];
1464 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1468 /* now examine each section and try to merge its content with the
1469 ones in memory */
1470 for(i = 1; i < ehdr.e_shnum; i++) {
1471 /* no need to examine section name strtab */
1472 if (i == ehdr.e_shstrndx)
1473 continue;
1474 sh = &shdr[i];
1475 sh_name = strsec + sh->sh_name;
1476 /* ignore sections types we do not handle */
1477 if (sh->sh_type != SHT_PROGBITS &&
1478 sh->sh_type != SHT_REL &&
1479 sh->sh_type != SHT_NOBITS)
1480 continue;
1481 if (sh->sh_addralign < 1)
1482 sh->sh_addralign = 1;
1483 /* find corresponding section, if any */
1484 for(j = 1; j < nb_sections;j++) {
1485 s = sections[j];
1486 if (!strcmp(s->name, sh_name))
1487 goto found;
1489 /* not found: create new section */
1490 s = new_section(sh_name, sh->sh_type, sh->sh_flags);
1491 /* take as much info as possible from the section. sh_link and
1492 sh_info will be updated later */
1493 s->sh_addralign = sh->sh_addralign;
1494 s->sh_entsize = sh->sh_entsize;
1495 sm_table[i].new_section = 1;
1496 found:
1497 if (sh->sh_type != s->sh_type)
1498 goto fail;
1500 /* align start of section */
1501 offset = s->data_offset;
1502 size = sh->sh_addralign - 1;
1503 offset = (offset + size) & ~size;
1504 if (sh->sh_addralign > s->sh_addralign)
1505 s->sh_addralign = sh->sh_addralign;
1506 s->data_offset = offset;
1507 sm_table[i].offset = offset;
1508 sm_table[i].s = s;
1509 /* concatenate sections */
1510 size = sh->sh_size;
1511 if (sh->sh_type != SHT_NOBITS) {
1512 unsigned char *ptr;
1513 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1514 ptr = section_ptr(s, size);
1515 read(fd, ptr, size);
1517 s->data_offset += size;
1520 /* second short pass to update sh_link and sh_info fields of new
1521 sections */
1522 sm = sm_table;
1523 for(i = 1; i < ehdr.e_shnum; i++) {
1524 s = sm_table[i].s;
1525 if (!s || !sm_table[i].new_section)
1526 continue;
1527 sh = &shdr[i];
1528 if (sh->sh_link > 0)
1529 s->link = sm_table[sh->sh_link].s;
1530 if (sh->sh_type == SHT_REL) {
1531 s->sh_info = sm_table[sh->sh_info].s->sh_num;
1532 /* update backward link */
1533 sections[s->sh_info]->reloc = s;
1537 /* resolve symbols */
1538 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
1540 sym = symtab + 1;
1541 for(i = 1; i < nb_syms; i++, sym++) {
1542 if (sym->st_shndx != SHN_UNDEF &&
1543 sym->st_shndx < SHN_LORESERVE) {
1544 sm = &sm_table[sym->st_shndx];
1545 /* if no corresponding section added, no need to add symbol */
1546 if (!sm->s)
1547 continue;
1548 /* convert section number */
1549 sym->st_shndx = sm->s->sh_num;
1550 /* offset value */
1551 sym->st_value += sm->offset;
1553 /* add symbol */
1554 name = strtab + sym->st_name;
1555 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
1556 sym->st_info, sym->st_shndx, name);
1557 old_to_new_syms[i] = sym_index;
1560 /* third pass to patch relocation entries */
1561 for(i = 1; i < ehdr.e_shnum; i++) {
1562 s = sm_table[i].s;
1563 if (!s)
1564 continue;
1565 sh = &shdr[i];
1566 offset = sm_table[i].offset;
1567 switch(s->sh_type) {
1568 case SHT_REL:
1569 /* take relocation offset information */
1570 offseti = sm_table[sh->sh_info].offset;
1571 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
1572 for(rel = (Elf32_Rel *)(s->data + offset);
1573 rel < rel_end;
1574 rel++) {
1575 int type;
1576 unsigned sym_index;
1577 /* convert symbol index */
1578 type = ELF32_R_TYPE(rel->r_info);
1579 sym_index = ELF32_R_SYM(rel->r_info);
1580 /* NOTE: only one symtab assumed */
1581 if (sym_index >= nb_syms)
1582 goto invalid_reloc;
1583 sym_index = old_to_new_syms[sym_index];
1584 if (!sym_index) {
1585 invalid_reloc:
1586 error("Invalid relocation entry");
1588 rel->r_info = ELF32_R_INFO(sym_index, type);
1589 /* offset the relocation offset */
1590 rel->r_offset += offseti;
1592 break;
1593 default:
1594 break;
1597 tcc_free(symtab);
1598 tcc_free(strtab);
1599 tcc_free(old_to_new_syms);
1600 tcc_free(sm_table);
1601 tcc_free(shdr);
1602 return 0;
1605 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1607 typedef struct ArchiveHeader {
1608 char ar_name[16]; /* name of this member */
1609 char ar_date[12]; /* file mtime */
1610 char ar_uid[6]; /* owner uid; printed as decimal */
1611 char ar_gid[6]; /* owner gid; printed as decimal */
1612 char ar_mode[8]; /* file mode, printed as octal */
1613 char ar_size[10]; /* file size, printed as decimal */
1614 char ar_fmag[2]; /* should contain ARFMAG */
1615 } ArchiveHeader;
1617 /* load a '.a' file */
1618 static int tcc_load_archive(TCCState *s1, int fd)
1620 ArchiveHeader hdr;
1621 char ar_size[11];
1622 char ar_name[17];
1623 char magic[8];
1624 int size, len, i;
1625 unsigned long file_offset;
1627 /* skip magic which was already checked */
1628 read(fd, magic, sizeof(magic));
1630 for(;;) {
1631 len = read(fd, &hdr, sizeof(hdr));
1632 if (len == 0)
1633 break;
1634 if (len != sizeof(hdr))
1635 error("invalid archive");
1636 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
1637 ar_size[sizeof(hdr.ar_size)] = '\0';
1638 size = strtol(ar_size, NULL, 0);
1639 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
1640 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
1641 if (ar_name[i] != ' ')
1642 break;
1644 ar_name[i + 1] = '\0';
1645 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
1646 file_offset = lseek(fd, 0, SEEK_CUR);
1647 if (!strcmp(ar_name, "/") ||
1648 !strcmp(ar_name, "//") ||
1649 !strcmp(ar_name, "__.SYMDEF") ||
1650 !strcmp(ar_name, "__.SYMDEF/") ||
1651 !strcmp(ar_name, "ARFILENAMES/")) {
1652 /* skip symbol table or archive names */
1653 } else {
1654 tcc_load_object_file(s1, fd, file_offset);
1656 /* align to even */
1657 size = (size + 1) & ~1;
1658 lseek(fd, file_offset + size, SEEK_SET);
1660 return 0;
1663 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
1664 is referenced by the user (so it should be added as DT_NEEDED in
1665 the generated ELF file) */
1666 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
1668 Elf32_Ehdr ehdr;
1669 Elf32_Shdr *shdr, *sh, *sh1;
1670 int i, nb_syms, nb_dts, sym_bind;
1671 Elf32_Sym *sym, *dynsym;
1672 Elf32_Dyn *dt, *dynamic;
1673 unsigned char *dynstr;
1674 const char *name, *soname, *p;
1675 DLLReference *dllref;
1677 read(fd, &ehdr, sizeof(ehdr));
1679 /* test CPU specific stuff */
1680 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1681 ehdr.e_machine != EM_386)
1682 error("bad architecture");
1684 /* read sections */
1685 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
1687 /* load dynamic section and dynamic symbols */
1688 nb_syms = 0;
1689 nb_dts = 0;
1690 dynamic = NULL;
1691 dynsym = NULL; /* avoid warning */
1692 dynstr = NULL; /* avoid warning */
1693 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
1694 switch(sh->sh_type) {
1695 case SHT_DYNAMIC:
1696 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
1697 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
1698 break;
1699 case SHT_DYNSYM:
1700 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1701 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
1702 sh1 = &shdr[sh->sh_link];
1703 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
1704 break;
1705 default:
1706 break;
1710 /* compute the real library name */
1711 soname = filename;
1712 p = strrchr(soname, '/');
1713 if (p)
1714 soname = p + 1;
1716 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
1717 if (dt->d_tag == DT_SONAME) {
1718 soname = dynstr + dt->d_un.d_val;
1722 /* if the dll is already loaded, do not load it */
1723 for(i = 0; i < nb_loaded_dlls; i++) {
1724 dllref = loaded_dlls[i];
1725 if (!strcmp(soname, dllref->name)) {
1726 /* but update level if needed */
1727 if (level < dllref->level)
1728 dllref->level = level;
1729 goto the_end;
1733 // printf("loading dll '%s'\n", soname);
1735 /* add the dll and its level */
1736 dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
1737 dllref->level = level;
1738 strcpy(dllref->name, soname);
1739 dynarray_add((void ***)&loaded_dlls, &nb_loaded_dlls, dllref);
1741 /* add dynamic symbols in dynsym_section */
1742 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
1743 sym_bind = ELF32_ST_BIND(sym->st_info);
1744 if (sym_bind == STB_LOCAL)
1745 continue;
1746 name = dynstr + sym->st_name;
1747 add_elf_sym(dynsymtab_section, sym->st_value, sym->st_size,
1748 sym->st_info, sym->st_shndx, name);
1751 /* load all referenced DLLs */
1752 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
1753 switch(dt->d_tag) {
1754 case DT_NEEDED:
1755 name = dynstr + dt->d_un.d_val;
1756 for(i = 0; i < nb_loaded_dlls; i++) {
1757 dllref = loaded_dlls[i];
1758 if (!strcmp(name, dllref->name))
1759 goto already_loaded;
1761 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0)
1762 error("referenced dll '%s' not found", name);
1763 already_loaded:
1764 break;
1767 the_end:
1768 tcc_free(shdr);
1769 return 0;
1772 /* return -2 if error and CH_EOF if eof */
1773 static void ld_skipspaces(void)
1775 while (ch == ' ' || ch == '\t' || ch == '\n')
1776 cinp();
1779 static int ld_get_cmd(char *cmd, int cmd_size)
1781 char *q;
1783 ld_skipspaces();
1784 if (ch == CH_EOF)
1785 return -1;
1786 q = cmd;
1787 for(;;) {
1788 if (!((ch >= 'a' && ch <= 'z') ||
1789 (ch >= 'A' && ch <= 'Z') ||
1790 (ch >= '0' && ch <= '9') ||
1791 strchr("/.-_+=$:\\,~?*", ch)))
1792 break;
1793 if ((q - cmd) >= (cmd_size - 1))
1794 return -2;
1795 *q++ = ch;
1796 cinp();
1798 *q = '\0';
1799 return 0;
1802 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
1803 files */
1804 static int tcc_load_ldscript(TCCState *s1)
1806 char cmd[64];
1807 char filename[1024];
1808 int ret;
1810 inp();
1811 cinp();
1812 for(;;) {
1813 ret = ld_get_cmd(cmd, sizeof(cmd));
1814 if (ret == CH_EOF)
1815 return 0;
1816 else if (ret < 0)
1817 return -1;
1818 // printf("cmd='%s'\n", cmd);
1819 if (!strcmp(cmd, "INPUT") ||
1820 !strcmp(cmd, "GROUP")) {
1821 ld_skipspaces();
1822 if (ch != '(')
1823 expect("(");
1824 cinp();
1825 for(;;) {
1826 ld_get_cmd(filename, sizeof(filename));
1827 tcc_add_file(s1, filename);
1828 ld_skipspaces();
1829 if (ch == ',') {
1830 cinp();
1831 } else if (ch == ')') {
1832 cinp();
1833 break;
1834 } else if (ch == CH_EOF) {
1835 error("unexpected end of file");
1838 } else {
1839 return -1;
1842 return 0;