added .ascii and .asciz directives
[tinycc.git] / tccelf.c
blob8a344427a39bb1318992720480b88f79755d2b04
1 /*
2 * ELF file handling for TCC
3 *
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 static int put_elf_str(Section *s, const char *sym)
23 int offset, len;
24 char *ptr;
26 len = strlen(sym) + 1;
27 offset = s->data_offset;
28 ptr = section_ptr_add(s, len);
29 memcpy(ptr, sym, len);
30 return offset;
33 /* elf symbol hashing function */
34 static unsigned long elf_hash(const unsigned char *name)
36 unsigned long h = 0, g;
38 while (*name) {
39 h = (h << 4) + *name++;
40 g = h & 0xf0000000;
41 if (g)
42 h ^= g >> 24;
43 h &= ~g;
45 return h;
48 /* rebuild hash table of section s */
49 /* NOTE: we do factorize the hash table code to go faster */
50 static void rebuild_hash(Section *s, unsigned int nb_buckets)
52 Elf32_Sym *sym;
53 int *ptr, *hash, nb_syms, sym_index, h;
54 char *strtab;
56 strtab = s->link->data;
57 nb_syms = s->data_offset / sizeof(Elf32_Sym);
59 s->hash->data_offset = 0;
60 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
61 ptr[0] = nb_buckets;
62 ptr[1] = nb_syms;
63 ptr += 2;
64 hash = ptr;
65 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
66 ptr += nb_buckets + 1;
68 sym = (Elf32_Sym *)s->data + 1;
69 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
70 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
71 h = elf_hash(strtab + sym->st_name) % nb_buckets;
72 *ptr = hash[h];
73 hash[h] = sym_index;
74 } else {
75 *ptr = 0;
77 ptr++;
78 sym++;
82 /* return the symbol number */
83 static int put_elf_sym(Section *s,
84 unsigned long value, unsigned long size,
85 int info, int other, int shndx, const char *name)
87 int name_offset, sym_index;
88 int nbuckets, h;
89 Elf32_Sym *sym;
90 Section *hs;
92 sym = section_ptr_add(s, sizeof(Elf32_Sym));
93 if (name)
94 name_offset = put_elf_str(s->link, name);
95 else
96 name_offset = 0;
97 /* XXX: endianness */
98 sym->st_name = name_offset;
99 sym->st_value = value;
100 sym->st_size = size;
101 sym->st_info = info;
102 sym->st_other = other;
103 sym->st_shndx = shndx;
104 sym_index = sym - (Elf32_Sym *)s->data;
105 hs = s->hash;
106 if (hs) {
107 int *ptr, *base;
108 ptr = section_ptr_add(hs, sizeof(int));
109 base = (int *)hs->data;
110 /* only add global or weak symbols */
111 if (ELF32_ST_BIND(info) != STB_LOCAL) {
112 /* add another hashing entry */
113 nbuckets = base[0];
114 h = elf_hash(name) % nbuckets;
115 *ptr = base[2 + h];
116 base[2 + h] = sym_index;
117 base[1]++;
118 /* we resize the hash table */
119 hs->nb_hashed_syms++;
120 if (hs->nb_hashed_syms > 2 * nbuckets) {
121 rebuild_hash(s, 2 * nbuckets);
123 } else {
124 *ptr = 0;
125 base[1]++;
128 return sym_index;
131 /* find global ELF symbol 'name' and return its index. Return 0 if not
132 found. */
133 static int find_elf_sym(Section *s, const char *name)
135 Elf32_Sym *sym;
136 Section *hs;
137 int nbuckets, sym_index, h;
138 const char *name1;
140 hs = s->hash;
141 if (!hs)
142 return 0;
143 nbuckets = ((int *)hs->data)[0];
144 h = elf_hash(name) % nbuckets;
145 sym_index = ((int *)hs->data)[2 + h];
146 while (sym_index != 0) {
147 sym = &((Elf32_Sym *)s->data)[sym_index];
148 name1 = s->link->data + sym->st_name;
149 if (!strcmp(name, name1))
150 return sym_index;
151 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
153 return 0;
156 /* return elf symbol value or error */
157 int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name)
159 int sym_index;
160 Elf32_Sym *sym;
162 sym_index = find_elf_sym(symtab_section, name);
163 if (!sym_index)
164 return -1;
165 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
166 *pval = sym->st_value;
167 return 0;
170 void *tcc_get_symbol_err(TCCState *s, const char *name)
172 unsigned long val;
173 if (tcc_get_symbol(s, &val, name) < 0)
174 error("%s not defined", name);
175 return (void *)val;
178 /* add an elf symbol : check if it is already defined and patch
179 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
180 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
181 int info, int sh_num, const char *name)
183 Elf32_Sym *esym;
184 int sym_bind, sym_index, sym_type, esym_bind;
186 sym_bind = ELF32_ST_BIND(info);
187 sym_type = ELF32_ST_TYPE(info);
189 if (sym_bind != STB_LOCAL) {
190 /* we search global or weak symbols */
191 sym_index = find_elf_sym(s, name);
192 if (!sym_index)
193 goto do_def;
194 esym = &((Elf32_Sym *)s->data)[sym_index];
195 if (esym->st_shndx != SHN_UNDEF) {
196 esym_bind = ELF32_ST_BIND(esym->st_info);
197 if (sh_num == SHN_UNDEF) {
198 /* ignore adding of undefined symbol if the
199 corresponding symbol is already defined */
200 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
201 /* global overrides weak, so patch */
202 goto do_patch;
203 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
204 /* weak is ignored if already global */
205 } else {
206 #if 0
207 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
208 sym_bind, sh_num, esym_bind, esym->st_shndx);
209 #endif
210 /* NOTE: we accept that two DLL define the same symbol */
211 if (s != tcc_state->dynsymtab_section)
212 error_noabort("'%s' defined twice", name);
214 } else {
215 do_patch:
216 esym->st_info = ELF32_ST_INFO(sym_bind, sym_type);
217 esym->st_shndx = sh_num;
218 esym->st_value = value;
219 esym->st_size = size;
221 } else {
222 do_def:
223 sym_index = put_elf_sym(s, value, size,
224 ELF32_ST_INFO(sym_bind, sym_type), 0,
225 sh_num, name);
227 return sym_index;
230 /* put relocation */
231 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
232 int type, int symbol)
234 char buf[256];
235 Section *sr;
236 Elf32_Rel *rel;
238 sr = s->reloc;
239 if (!sr) {
240 /* if no relocation section, create it */
241 snprintf(buf, sizeof(buf), ".rel%s", s->name);
242 /* if the symtab is allocated, then we consider the relocation
243 are also */
244 sr = new_section(tcc_state, buf, SHT_REL, symtab->sh_flags);
245 sr->sh_entsize = sizeof(Elf32_Rel);
246 sr->link = symtab;
247 sr->sh_info = s->sh_num;
248 s->reloc = sr;
250 rel = section_ptr_add(sr, sizeof(Elf32_Rel));
251 rel->r_offset = offset;
252 rel->r_info = ELF32_R_INFO(symbol, type);
255 /* put stab debug information */
257 typedef struct {
258 unsigned long n_strx; /* index into string table of name */
259 unsigned char n_type; /* type of symbol */
260 unsigned char n_other; /* misc info (usually empty) */
261 unsigned short n_desc; /* description field */
262 unsigned long n_value; /* value of symbol */
263 } Stab_Sym;
265 static void put_stabs(const char *str, int type, int other, int desc,
266 unsigned long value)
268 Stab_Sym *sym;
270 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
271 if (str) {
272 sym->n_strx = put_elf_str(stabstr_section, str);
273 } else {
274 sym->n_strx = 0;
276 sym->n_type = type;
277 sym->n_other = other;
278 sym->n_desc = desc;
279 sym->n_value = value;
282 static void put_stabs_r(const char *str, int type, int other, int desc,
283 unsigned long value, Section *sec, int sym_index)
285 put_stabs(str, type, other, desc, value);
286 put_elf_reloc(symtab_section, stab_section,
287 stab_section->data_offset - sizeof(unsigned long),
288 R_DATA_32, sym_index);
291 static void put_stabn(int type, int other, int desc, int value)
293 put_stabs(NULL, type, other, desc, value);
296 static void put_stabd(int type, int other, int desc)
298 put_stabs(NULL, type, other, desc, 0);
301 /* In an ELF file symbol table, the local symbols must appear below
302 the global and weak ones. Since TCC cannot sort it while generating
303 the code, we must do it after. All the relocation tables are also
304 modified to take into account the symbol table sorting */
305 static void sort_syms(TCCState *s1, Section *s)
307 int *old_to_new_syms;
308 Elf32_Sym *new_syms;
309 int nb_syms, i;
310 Elf32_Sym *p, *q;
311 Elf32_Rel *rel, *rel_end;
312 Section *sr;
313 int type, sym_index;
315 nb_syms = s->data_offset / sizeof(Elf32_Sym);
316 new_syms = tcc_malloc(nb_syms * sizeof(Elf32_Sym));
317 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
319 /* first pass for local symbols */
320 p = (Elf32_Sym *)s->data;
321 q = new_syms;
322 for(i = 0; i < nb_syms; i++) {
323 if (ELF32_ST_BIND(p->st_info) == STB_LOCAL) {
324 old_to_new_syms[i] = q - new_syms;
325 *q++ = *p;
327 p++;
329 /* save the number of local symbols in section header */
330 s->sh_info = q - new_syms;
332 /* then second pass for non local symbols */
333 p = (Elf32_Sym *)s->data;
334 for(i = 0; i < nb_syms; i++) {
335 if (ELF32_ST_BIND(p->st_info) != STB_LOCAL) {
336 old_to_new_syms[i] = q - new_syms;
337 *q++ = *p;
339 p++;
342 /* we copy the new symbols to the old */
343 memcpy(s->data, new_syms, nb_syms * sizeof(Elf32_Sym));
344 tcc_free(new_syms);
346 /* now we modify all the relocations */
347 for(i = 1; i < s1->nb_sections; i++) {
348 sr = s1->sections[i];
349 if (sr->sh_type == SHT_REL && sr->link == s) {
350 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
351 for(rel = (Elf32_Rel *)sr->data;
352 rel < rel_end;
353 rel++) {
354 sym_index = ELF32_R_SYM(rel->r_info);
355 type = ELF32_R_TYPE(rel->r_info);
356 sym_index = old_to_new_syms[sym_index];
357 rel->r_info = ELF32_R_INFO(sym_index, type);
362 tcc_free(old_to_new_syms);
365 /* relocate common symbols in the .bss section */
366 static void relocate_common_syms(void)
368 Elf32_Sym *sym, *sym_end;
369 unsigned long offset, align;
371 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
372 for(sym = (Elf32_Sym *)symtab_section->data + 1;
373 sym < sym_end;
374 sym++) {
375 if (sym->st_shndx == SHN_COMMON) {
376 /* align symbol */
377 align = sym->st_value;
378 offset = bss_section->data_offset;
379 offset = (offset + align - 1) & -align;
380 sym->st_value = offset;
381 sym->st_shndx = bss_section->sh_num;
382 offset += sym->st_size;
383 bss_section->data_offset = offset;
388 static void *resolve_sym(const char *sym)
390 return dlsym(RTLD_DEFAULT, sym);
393 /* relocate symbol table, resolve undefined symbols if do_resolve is
394 true and output error if undefined symbol. */
395 static void relocate_syms(TCCState *s1, int do_resolve)
397 Elf32_Sym *sym, *esym, *sym_end;
398 int sym_bind, sh_num, sym_index;
399 const char *name;
400 unsigned long addr;
402 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
403 for(sym = (Elf32_Sym *)symtab_section->data + 1;
404 sym < sym_end;
405 sym++) {
406 sh_num = sym->st_shndx;
407 if (sh_num == SHN_UNDEF) {
408 name = strtab_section->data + sym->st_name;
409 if (do_resolve) {
410 name = symtab_section->link->data + sym->st_name;
411 addr = (unsigned long)resolve_sym(name);
412 if (addr) {
413 sym->st_value = addr;
414 goto found;
416 } else if (s1->dynsym) {
417 /* if dynamic symbol exist, then use it */
418 sym_index = find_elf_sym(s1->dynsym, name);
419 if (sym_index) {
420 esym = &((Elf32_Sym *)s1->dynsym->data)[sym_index];
421 sym->st_value = esym->st_value;
422 goto found;
425 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
426 it */
427 if (!strcmp(name, "_fp_hw"))
428 goto found;
429 /* only weak symbols are accepted to be undefined. Their
430 value is zero */
431 sym_bind = ELF32_ST_BIND(sym->st_info);
432 if (sym_bind == STB_WEAK) {
433 sym->st_value = 0;
434 } else {
435 error_noabort("undefined symbol '%s'", name);
437 } else if (sh_num < SHN_LORESERVE) {
438 /* add section base */
439 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
441 found: ;
445 /* relocate a given section (CPU dependent) */
446 static void relocate_section(TCCState *s1, Section *s)
448 Section *sr;
449 Elf32_Rel *rel, *rel_end, *qrel;
450 Elf32_Sym *sym;
451 int type, sym_index, esym_index;
452 unsigned char *ptr;
453 unsigned long val, addr;
455 sr = s->reloc;
456 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
457 qrel = (Elf32_Rel *)sr->data;
458 for(rel = qrel;
459 rel < rel_end;
460 rel++) {
461 ptr = s->data + rel->r_offset;
463 sym_index = ELF32_R_SYM(rel->r_info);
464 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
465 val = sym->st_value;
466 type = ELF32_R_TYPE(rel->r_info);
467 addr = s->sh_addr + rel->r_offset;
469 /* CPU specific */
470 switch(type) {
471 #if defined(TCC_TARGET_I386)
472 case R_386_32:
473 if (s1->output_type == TCC_OUTPUT_DLL) {
474 esym_index = s1->symtab_to_dynsym[sym_index];
475 qrel->r_offset = rel->r_offset;
476 if (esym_index) {
477 qrel->r_info = ELF32_R_INFO(esym_index, R_386_32);
478 qrel++;
479 break;
480 } else {
481 qrel->r_info = ELF32_R_INFO(0, R_386_RELATIVE);
482 qrel++;
485 *(int *)ptr += val;
486 break;
487 case R_386_PC32:
488 if (s1->output_type == TCC_OUTPUT_DLL) {
489 /* DLL relocation */
490 esym_index = s1->symtab_to_dynsym[sym_index];
491 if (esym_index) {
492 qrel->r_offset = rel->r_offset;
493 qrel->r_info = ELF32_R_INFO(esym_index, R_386_PC32);
494 qrel++;
495 break;
498 *(int *)ptr += val - addr;
499 break;
500 case R_386_PLT32:
501 *(int *)ptr += val - addr;
502 break;
503 case R_386_GLOB_DAT:
504 case R_386_JMP_SLOT:
505 *(int *)ptr = val;
506 break;
507 case R_386_GOTPC:
508 *(int *)ptr += s1->got->sh_addr - addr;
509 break;
510 case R_386_GOTOFF:
511 *(int *)ptr += val - s1->got->sh_addr;
512 break;
513 case R_386_GOT32:
514 /* we load the got offset */
515 *(int *)ptr += s1->got_offsets[sym_index];
516 break;
517 #elif defined(TCC_TARGET_ARM)
518 case R_ARM_PC24:
519 case R_ARM_PLT32:
521 int x;
522 x = (*(int *)ptr)&0xffffff;
523 (*(int *)ptr) &= 0xff000000;
524 if (x & 0x800000)
525 x -= 0x1000000;
526 x *= 4;
527 x += val - addr;
528 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
529 error("can't relocate value at %x",addr);
530 x >>= 2;
531 x &= 0xffffff;
532 (*(int *)ptr) |= x;
534 break;
535 case R_ARM_ABS32:
536 *(int *)ptr += val;
537 break;
538 case R_ARM_GOTPC:
539 *(int *)ptr += s1->got->sh_addr - addr;
540 break;
541 case R_ARM_GOT32:
542 /* we load the got offset */
543 *(int *)ptr += s1->got_offsets[sym_index];
544 break;
545 case R_ARM_COPY:
546 break;
547 default:
548 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
549 type,addr,(unsigned int )ptr,val);
550 break;
551 #elif defined(TCC_TARGET_C67)
552 case R_C60_32:
553 *(int *)ptr += val;
554 break;
555 case R_C60LO16:
557 uint32_t orig;
559 /* put the low 16 bits of the absolute address */
560 // add to what is already there
562 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
563 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
565 //patch both at once - assumes always in pairs Low - High
567 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
568 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
570 break;
571 case R_C60HI16:
572 break;
573 default:
574 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
575 type,addr,(unsigned int )ptr,val);
576 break;
577 #else
578 #error unsupported processor
579 #endif
582 /* if the relocation is allocated, we change its symbol table */
583 if (sr->sh_flags & SHF_ALLOC)
584 sr->link = s1->dynsym;
587 /* relocate relocation table in 'sr' */
588 static void relocate_rel(TCCState *s1, Section *sr)
590 Section *s;
591 Elf32_Rel *rel, *rel_end;
593 s = s1->sections[sr->sh_info];
594 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
595 for(rel = (Elf32_Rel *)sr->data;
596 rel < rel_end;
597 rel++) {
598 rel->r_offset += s->sh_addr;
602 /* count the number of dynamic relocations so that we can reserve
603 their space */
604 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
606 Elf32_Rel *rel, *rel_end;
607 int sym_index, esym_index, type, count;
609 count = 0;
610 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
611 for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) {
612 sym_index = ELF32_R_SYM(rel->r_info);
613 type = ELF32_R_TYPE(rel->r_info);
614 switch(type) {
615 case R_386_32:
616 count++;
617 break;
618 case R_386_PC32:
619 esym_index = s1->symtab_to_dynsym[sym_index];
620 if (esym_index)
621 count++;
622 break;
623 default:
624 break;
627 if (count) {
628 /* allocate the section */
629 sr->sh_flags |= SHF_ALLOC;
630 sr->sh_size = count * sizeof(Elf32_Rel);
632 return count;
635 static void put_got_offset(TCCState *s1, int index, unsigned long val)
637 int n;
638 unsigned long *tab;
640 if (index >= s1->nb_got_offsets) {
641 /* find immediately bigger power of 2 and reallocate array */
642 n = 1;
643 while (index >= n)
644 n *= 2;
645 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
646 if (!tab)
647 error("memory full");
648 s1->got_offsets = tab;
649 memset(s1->got_offsets + s1->nb_got_offsets, 0,
650 (n - s1->nb_got_offsets) * sizeof(unsigned long));
651 s1->nb_got_offsets = n;
653 s1->got_offsets[index] = val;
656 /* XXX: suppress that */
657 static void put32(unsigned char *p, uint32_t val)
659 p[0] = val;
660 p[1] = val >> 8;
661 p[2] = val >> 16;
662 p[3] = val >> 24;
665 static uint32_t get32(unsigned char *p)
667 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
670 static void build_got(TCCState *s1)
672 unsigned char *ptr;
674 /* if no got, then create it */
675 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
676 s1->got->sh_entsize = 4;
677 add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
678 s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
679 ptr = section_ptr_add(s1->got, 3 * sizeof(int));
680 /* keep space for _DYNAMIC pointer, if present */
681 put32(ptr, 0);
682 /* two dummy got entries */
683 put32(ptr + 4, 0);
684 put32(ptr + 8, 0);
687 /* put a got entry corresponding to a symbol in symtab_section. 'size'
688 and 'info' can be modifed if more precise info comes from the DLL */
689 static void put_got_entry(TCCState *s1,
690 int reloc_type, unsigned long size, int info,
691 int sym_index)
693 int index;
694 const char *name;
695 Elf32_Sym *sym;
696 unsigned long offset;
697 int *ptr;
699 if (!s1->got)
700 build_got(s1);
702 /* if a got entry already exists for that symbol, no need to add one */
703 if (sym_index < s1->nb_got_offsets &&
704 s1->got_offsets[sym_index] != 0)
705 return;
707 put_got_offset(s1, sym_index, s1->got->data_offset);
709 if (s1->dynsym) {
710 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
711 name = symtab_section->link->data + sym->st_name;
712 offset = sym->st_value;
713 #ifdef TCC_TARGET_I386
714 if (reloc_type == R_386_JMP_SLOT) {
715 Section *plt;
716 uint8_t *p;
717 int modrm;
719 /* if we build a DLL, we add a %ebx offset */
720 if (s1->output_type == TCC_OUTPUT_DLL)
721 modrm = 0xa3;
722 else
723 modrm = 0x25;
725 /* add a PLT entry */
726 plt = s1->plt;
727 if (plt->data_offset == 0) {
728 /* first plt entry */
729 p = section_ptr_add(plt, 16);
730 p[0] = 0xff; /* pushl got + 4 */
731 p[1] = modrm + 0x10;
732 put32(p + 2, 4);
733 p[6] = 0xff; /* jmp *(got + 8) */
734 p[7] = modrm;
735 put32(p + 8, 8);
738 p = section_ptr_add(plt, 16);
739 p[0] = 0xff; /* jmp *(got + x) */
740 p[1] = modrm;
741 put32(p + 2, s1->got->data_offset);
742 p[6] = 0x68; /* push $xxx */
743 put32(p + 7, (plt->data_offset - 32) >> 1);
744 p[11] = 0xe9; /* jmp plt_start */
745 put32(p + 12, -(plt->data_offset));
747 /* the symbol is modified so that it will be relocated to
748 the PLT */
749 if (s1->output_type == TCC_OUTPUT_EXE)
750 offset = plt->data_offset - 16;
752 #elif defined(TCC_TARGET_ARM)
753 if (reloc_type == R_ARM_JUMP_SLOT) {
754 Section *plt;
755 uint8_t *p;
757 /* if we build a DLL, we add a %ebx offset */
758 if (s1->output_type == TCC_OUTPUT_DLL)
759 error("DLLs unimplemented!");
761 /* add a PLT entry */
762 plt = s1->plt;
763 if (plt->data_offset == 0) {
764 /* first plt entry */
765 p = section_ptr_add(plt, 16);
766 put32(p , 0xe52de004);
767 put32(p + 4, 0xe59fe010);
768 put32(p + 8, 0xe08fe00e);
769 put32(p + 12, 0xe5bef008);
772 p = section_ptr_add(plt, 16);
773 put32(p , 0xe59fc004);
774 put32(p+4, 0xe08fc00c);
775 put32(p+8, 0xe59cf000);
776 put32(p+12, s1->got->data_offset);
778 /* the symbol is modified so that it will be relocated to
779 the PLT */
780 if (s1->output_type == TCC_OUTPUT_EXE)
781 offset = plt->data_offset - 16;
783 #elif defined(TCC_TARGET_C67)
784 error("C67 got not implemented");
785 #else
786 #error unsupported CPU
787 #endif
788 index = put_elf_sym(s1->dynsym, offset,
789 size, info, 0, sym->st_shndx, name);
790 /* put a got entry */
791 put_elf_reloc(s1->dynsym, s1->got,
792 s1->got->data_offset,
793 reloc_type, index);
795 ptr = section_ptr_add(s1->got, sizeof(int));
796 *ptr = 0;
799 /* build GOT and PLT entries */
800 static void build_got_entries(TCCState *s1)
802 Section *s, *symtab;
803 Elf32_Rel *rel, *rel_end;
804 Elf32_Sym *sym;
805 int i, type, reloc_type, sym_index;
807 for(i = 1; i < s1->nb_sections; i++) {
808 s = s1->sections[i];
809 if (s->sh_type != SHT_REL)
810 continue;
811 /* no need to handle got relocations */
812 if (s->link != symtab_section)
813 continue;
814 symtab = s->link;
815 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
816 for(rel = (Elf32_Rel *)s->data;
817 rel < rel_end;
818 rel++) {
819 type = ELF32_R_TYPE(rel->r_info);
820 switch(type) {
821 #if defined(TCC_TARGET_I386)
822 case R_386_GOT32:
823 case R_386_GOTOFF:
824 case R_386_GOTPC:
825 case R_386_PLT32:
826 if (!s1->got)
827 build_got(s1);
828 if (type == R_386_GOT32 || type == R_386_PLT32) {
829 sym_index = ELF32_R_SYM(rel->r_info);
830 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
831 /* look at the symbol got offset. If none, then add one */
832 if (type == R_386_GOT32)
833 reloc_type = R_386_GLOB_DAT;
834 else
835 reloc_type = R_386_JMP_SLOT;
836 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
837 sym_index);
839 break;
840 #elif defined(TCC_TARGET_ARM)
841 case R_ARM_GOT32:
842 case R_ARM_GOTOFF:
843 case R_ARM_GOTPC:
844 case R_ARM_PLT32:
845 if (!s1->got)
846 build_got(s1);
847 if (type == R_ARM_GOT32 || type == R_ARM_PLT32) {
848 sym_index = ELF32_R_SYM(rel->r_info);
849 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
850 /* look at the symbol got offset. If none, then add one */
851 if (type == R_ARM_GOT32)
852 reloc_type = R_ARM_GLOB_DAT;
853 else
854 reloc_type = R_ARM_JUMP_SLOT;
855 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
856 sym_index);
858 break;
859 #elif defined(TCC_TARGET_C67)
860 case R_C60_GOT32:
861 case R_C60_GOTOFF:
862 case R_C60_GOTPC:
863 case R_C60_PLT32:
864 if (!s1->got)
865 build_got(s1);
866 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
867 sym_index = ELF32_R_SYM(rel->r_info);
868 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
869 /* look at the symbol got offset. If none, then add one */
870 if (type == R_C60_GOT32)
871 reloc_type = R_C60_GLOB_DAT;
872 else
873 reloc_type = R_C60_JMP_SLOT;
874 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
875 sym_index);
877 break;
878 #else
879 #error unsupported CPU
880 #endif
881 default:
882 break;
888 static Section *new_symtab(TCCState *s1,
889 const char *symtab_name, int sh_type, int sh_flags,
890 const char *strtab_name,
891 const char *hash_name, int hash_sh_flags)
893 Section *symtab, *strtab, *hash;
894 int *ptr, nb_buckets;
896 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
897 symtab->sh_entsize = sizeof(Elf32_Sym);
898 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
899 put_elf_str(strtab, "");
900 symtab->link = strtab;
901 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
903 nb_buckets = 1;
905 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
906 hash->sh_entsize = sizeof(int);
907 symtab->hash = hash;
908 hash->link = symtab;
910 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
911 ptr[0] = nb_buckets;
912 ptr[1] = 1;
913 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
914 return symtab;
917 /* put dynamic tag */
918 static void put_dt(Section *dynamic, int dt, unsigned long val)
920 Elf32_Dyn *dyn;
921 dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
922 dyn->d_tag = dt;
923 dyn->d_un.d_val = val;
926 static void add_init_array_defines(TCCState *s1, const char *section_name)
928 Section *s;
929 long end_offset;
930 char sym_start[1024];
931 char sym_end[1024];
933 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
934 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
936 s = find_section(s1, section_name);
937 if (!s) {
938 end_offset = 0;
939 s = data_section;
940 } else {
941 end_offset = s->data_offset;
944 add_elf_sym(symtab_section,
945 0, 0,
946 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
947 s->sh_num, sym_start);
948 add_elf_sym(symtab_section,
949 end_offset, 0,
950 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
951 s->sh_num, sym_end);
954 /* add tcc runtime libraries */
955 static void tcc_add_runtime(TCCState *s1)
957 char buf[1024];
958 int i;
959 Section *s;
961 if (!s1->nostdlib) {
962 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
963 tcc_add_file(s1, buf);
965 #ifdef CONFIG_TCC_BCHECK
966 if (do_bounds_check) {
967 unsigned long *ptr;
968 Section *init_section;
969 unsigned char *pinit;
970 int sym_index;
972 /* XXX: add an object file to do that */
973 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
974 *ptr = 0;
975 add_elf_sym(symtab_section, 0, 0,
976 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
977 bounds_section->sh_num, "__bounds_start");
978 /* add bound check code */
979 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
980 tcc_add_file(s1, buf);
981 #ifdef TCC_TARGET_I386
982 if (s1->output_type != TCC_OUTPUT_MEMORY) {
983 /* add 'call __bound_init()' in .init section */
984 init_section = find_section(s1, ".init");
985 pinit = section_ptr_add(init_section, 5);
986 pinit[0] = 0xe8;
987 put32(pinit + 1, -4);
988 sym_index = find_elf_sym(symtab_section, "__bound_init");
989 put_elf_reloc(symtab_section, init_section,
990 init_section->data_offset - 4, R_386_PC32, sym_index);
992 #endif
994 #endif
995 /* add libc */
996 if (!s1->nostdlib) {
997 tcc_add_library(s1, "c");
999 /* add crt end if not memory output */
1000 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
1001 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1003 /* add various standard linker symbols */
1004 add_elf_sym(symtab_section,
1005 text_section->data_offset, 0,
1006 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
1007 text_section->sh_num, "_etext");
1008 add_elf_sym(symtab_section,
1009 data_section->data_offset, 0,
1010 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
1011 data_section->sh_num, "_edata");
1012 add_elf_sym(symtab_section,
1013 bss_section->data_offset, 0,
1014 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
1015 bss_section->sh_num, "_end");
1016 /* horrible new standard ldscript defines */
1017 add_init_array_defines(s1, ".preinit_array");
1018 add_init_array_defines(s1, ".init_array");
1019 add_init_array_defines(s1, ".fini_array");
1021 /* add start and stop symbols for sections whose name can be
1022 expressed in C */
1023 for(i = 1; i < s1->nb_sections; i++) {
1024 s = s1->sections[i];
1025 if (s->sh_type == SHT_PROGBITS &&
1026 (s->sh_flags & SHF_ALLOC)) {
1027 const char *p;
1028 int ch;
1030 /* check if section name can be expressed in C */
1031 p = s->name;
1032 for(;;) {
1033 ch = *p;
1034 if (!ch)
1035 break;
1036 if (!isid(ch) && !isnum(ch))
1037 goto next_sec;
1038 p++;
1040 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1041 add_elf_sym(symtab_section,
1042 0, 0,
1043 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
1044 s->sh_num, buf);
1045 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1046 add_elf_sym(symtab_section,
1047 s->data_offset, 0,
1048 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
1049 s->sh_num, buf);
1051 next_sec: ;
1055 /* name of ELF interpreter */
1056 #ifdef __FreeBSD__
1057 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1058 #else
1059 static char elf_interp[] = "/lib/ld-linux.so.2";
1060 #endif
1062 /* output an ELF file */
1063 /* XXX: suppress unneeded sections */
1064 int tcc_output_file(TCCState *s1, const char *filename)
1066 Elf32_Ehdr ehdr;
1067 FILE *f;
1068 int fd, mode, ret;
1069 int *section_order;
1070 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1071 unsigned long addr;
1072 Section *strsec, *s;
1073 Elf32_Shdr shdr, *sh;
1074 Elf32_Phdr *phdr, *ph;
1075 Section *interp, *dynamic, *dynstr;
1076 unsigned long saved_dynamic_data_offset;
1077 Elf32_Sym *sym;
1078 int type, file_type;
1079 unsigned long rel_addr, rel_size;
1081 file_type = s1->output_type;
1082 s1->nb_errors = 0;
1084 if (file_type != TCC_OUTPUT_OBJ) {
1085 relocate_common_syms();
1087 tcc_add_runtime(s1);
1090 phdr = NULL;
1091 section_order = NULL;
1092 interp = NULL;
1093 dynamic = NULL;
1094 dynstr = NULL; /* avoid warning */
1095 saved_dynamic_data_offset = 0; /* avoid warning */
1097 if (file_type != TCC_OUTPUT_OBJ) {
1099 if (!s1->static_link) {
1100 const char *name;
1101 int sym_index, index;
1102 Elf32_Sym *esym, *sym_end;
1104 if (file_type == TCC_OUTPUT_EXE) {
1105 char *ptr;
1106 /* add interpreter section only if executable */
1107 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1108 interp->sh_addralign = 1;
1109 ptr = section_ptr_add(interp, sizeof(elf_interp));
1110 strcpy(ptr, elf_interp);
1113 /* add dynamic symbol table */
1114 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1115 ".dynstr",
1116 ".hash", SHF_ALLOC);
1117 dynstr = s1->dynsym->link;
1119 /* add dynamic section */
1120 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1121 SHF_ALLOC | SHF_WRITE);
1122 dynamic->link = dynstr;
1123 dynamic->sh_entsize = sizeof(Elf32_Dyn);
1125 /* add PLT */
1126 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1127 SHF_ALLOC | SHF_EXECINSTR);
1128 s1->plt->sh_entsize = 4;
1130 build_got(s1);
1132 /* scan for undefined symbols and see if they are in the
1133 dynamic symbols. If a symbol STT_FUNC is found, then we
1134 add it in the PLT. If a symbol STT_OBJECT is found, we
1135 add it in the .bss section with a suitable relocation */
1136 sym_end = (Elf32_Sym *)(symtab_section->data +
1137 symtab_section->data_offset);
1138 if (file_type == TCC_OUTPUT_EXE) {
1139 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1140 sym < sym_end;
1141 sym++) {
1142 if (sym->st_shndx == SHN_UNDEF) {
1143 name = symtab_section->link->data + sym->st_name;
1144 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1145 if (sym_index) {
1146 esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
1147 type = ELF32_ST_TYPE(esym->st_info);
1148 if (type == STT_FUNC) {
1149 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1150 esym->st_info,
1151 sym - (Elf32_Sym *)symtab_section->data);
1152 } else if (type == STT_OBJECT) {
1153 unsigned long offset;
1154 offset = bss_section->data_offset;
1155 /* XXX: which alignment ? */
1156 offset = (offset + 16 - 1) & -16;
1157 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1158 esym->st_info, 0,
1159 bss_section->sh_num, name);
1160 put_elf_reloc(s1->dynsym, bss_section,
1161 offset, R_COPY, index);
1162 offset += esym->st_size;
1163 bss_section->data_offset = offset;
1165 } else {
1166 /* STB_WEAK undefined symbols are accepted */
1167 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1168 it */
1169 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
1170 !strcmp(name, "_fp_hw")) {
1171 } else {
1172 error_noabort("undefined symbol '%s'", name);
1175 } else if (s1->rdynamic &&
1176 ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1177 /* if -rdynamic option, then export all non
1178 local symbols */
1179 name = symtab_section->link->data + sym->st_name;
1180 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1181 sym->st_info, 0,
1182 sym->st_shndx, name);
1186 if (s1->nb_errors)
1187 goto fail;
1189 /* now look at unresolved dynamic symbols and export
1190 corresponding symbol */
1191 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
1192 s1->dynsymtab_section->data_offset);
1193 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
1194 esym < sym_end;
1195 esym++) {
1196 if (esym->st_shndx == SHN_UNDEF) {
1197 name = s1->dynsymtab_section->link->data + esym->st_name;
1198 sym_index = find_elf_sym(symtab_section, name);
1199 if (sym_index) {
1200 /* XXX: avoid adding a symbol if already
1201 present because of -rdynamic ? */
1202 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1203 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1204 sym->st_info, 0,
1205 sym->st_shndx, name);
1206 } else {
1207 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
1208 /* weak symbols can stay undefined */
1209 } else {
1210 warning("undefined dynamic symbol '%s'", name);
1215 } else {
1216 int nb_syms;
1217 /* shared library case : we simply export all the global symbols */
1218 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
1219 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1220 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1221 sym < sym_end;
1222 sym++) {
1223 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1224 name = symtab_section->link->data + sym->st_name;
1225 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1226 sym->st_info, 0,
1227 sym->st_shndx, name);
1228 s1->symtab_to_dynsym[sym -
1229 (Elf32_Sym *)symtab_section->data] =
1230 index;
1235 build_got_entries(s1);
1237 /* add a list of needed dlls */
1238 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1239 DLLReference *dllref = s1->loaded_dlls[i];
1240 if (dllref->level == 0)
1241 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1243 /* XXX: currently, since we do not handle PIC code, we
1244 must relocate the readonly segments */
1245 if (file_type == TCC_OUTPUT_DLL)
1246 put_dt(dynamic, DT_TEXTREL, 0);
1248 /* add necessary space for other entries */
1249 saved_dynamic_data_offset = dynamic->data_offset;
1250 dynamic->data_offset += 8 * 9;
1251 } else {
1252 /* still need to build got entries in case of static link */
1253 build_got_entries(s1);
1257 memset(&ehdr, 0, sizeof(ehdr));
1259 /* we add a section for symbols */
1260 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1261 put_elf_str(strsec, "");
1263 /* compute number of sections */
1264 shnum = s1->nb_sections;
1266 /* this array is used to reorder sections in the output file */
1267 section_order = tcc_malloc(sizeof(int) * shnum);
1268 section_order[0] = 0;
1269 sh_order_index = 1;
1271 /* compute number of program headers */
1272 switch(file_type) {
1273 default:
1274 case TCC_OUTPUT_OBJ:
1275 phnum = 0;
1276 break;
1277 case TCC_OUTPUT_EXE:
1278 if (!s1->static_link)
1279 phnum = 4;
1280 else
1281 phnum = 2;
1282 break;
1283 case TCC_OUTPUT_DLL:
1284 phnum = 3;
1285 break;
1288 /* allocate strings for section names and decide if an unallocated
1289 section should be output */
1290 /* NOTE: the strsec section comes last, so its size is also
1291 correct ! */
1292 for(i = 1; i < s1->nb_sections; i++) {
1293 s = s1->sections[i];
1294 s->sh_name = put_elf_str(strsec, s->name);
1295 /* when generating a DLL, we include relocations but we may
1296 patch them */
1297 if (file_type == TCC_OUTPUT_DLL &&
1298 s->sh_type == SHT_REL &&
1299 !(s->sh_flags & SHF_ALLOC)) {
1300 prepare_dynamic_rel(s1, s);
1301 } else if (do_debug ||
1302 file_type == TCC_OUTPUT_OBJ ||
1303 (s->sh_flags & SHF_ALLOC) ||
1304 i == (s1->nb_sections - 1)) {
1305 /* we output all sections if debug or object file */
1306 s->sh_size = s->data_offset;
1310 /* allocate program segment headers */
1311 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1313 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1314 if (phnum > 0) {
1315 /* compute section to program header mapping */
1316 if (s1->has_text_addr) {
1317 int a_offset, p_offset;
1318 addr = s1->text_addr;
1319 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1320 ELF_PAGE_SIZE */
1321 a_offset = addr & (ELF_PAGE_SIZE - 1);
1322 p_offset = file_offset & (ELF_PAGE_SIZE - 1);
1323 if (a_offset < p_offset)
1324 a_offset += ELF_PAGE_SIZE;
1325 file_offset += (a_offset - p_offset);
1326 } else {
1327 if (file_type == TCC_OUTPUT_DLL)
1328 addr = 0;
1329 else
1330 addr = ELF_START_ADDR;
1331 /* compute address after headers */
1332 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1335 /* dynamic relocation table information, for .dynamic section */
1336 rel_size = 0;
1337 rel_addr = 0;
1339 /* leave one program header for the program interpreter */
1340 ph = &phdr[0];
1341 if (interp)
1342 ph++;
1344 for(j = 0; j < 2; j++) {
1345 ph->p_type = PT_LOAD;
1346 if (j == 0)
1347 ph->p_flags = PF_R | PF_X;
1348 else
1349 ph->p_flags = PF_R | PF_W;
1350 ph->p_align = ELF_PAGE_SIZE;
1352 /* we do the following ordering: interp, symbol tables,
1353 relocations, progbits, nobits */
1354 /* XXX: do faster and simpler sorting */
1355 for(k = 0; k < 5; k++) {
1356 for(i = 1; i < s1->nb_sections; i++) {
1357 s = s1->sections[i];
1358 /* compute if section should be included */
1359 if (j == 0) {
1360 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1361 SHF_ALLOC)
1362 continue;
1363 } else {
1364 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1365 (SHF_ALLOC | SHF_WRITE))
1366 continue;
1368 if (s == interp) {
1369 if (k != 0)
1370 continue;
1371 } else if (s->sh_type == SHT_DYNSYM ||
1372 s->sh_type == SHT_STRTAB ||
1373 s->sh_type == SHT_HASH) {
1374 if (k != 1)
1375 continue;
1376 } else if (s->sh_type == SHT_REL) {
1377 if (k != 2)
1378 continue;
1379 } else if (s->sh_type == SHT_NOBITS) {
1380 if (k != 4)
1381 continue;
1382 } else {
1383 if (k != 3)
1384 continue;
1386 section_order[sh_order_index++] = i;
1388 /* section matches: we align it and add its size */
1389 tmp = addr;
1390 addr = (addr + s->sh_addralign - 1) &
1391 ~(s->sh_addralign - 1);
1392 file_offset += addr - tmp;
1393 s->sh_offset = file_offset;
1394 s->sh_addr = addr;
1396 /* update program header infos */
1397 if (ph->p_offset == 0) {
1398 ph->p_offset = file_offset;
1399 ph->p_vaddr = addr;
1400 ph->p_paddr = ph->p_vaddr;
1402 /* update dynamic relocation infos */
1403 if (s->sh_type == SHT_REL) {
1404 if (rel_size == 0)
1405 rel_addr = addr;
1406 rel_size += s->sh_size;
1408 addr += s->sh_size;
1409 if (s->sh_type != SHT_NOBITS)
1410 file_offset += s->sh_size;
1413 ph->p_filesz = file_offset - ph->p_offset;
1414 ph->p_memsz = addr - ph->p_vaddr;
1415 ph++;
1416 /* if in the middle of a page, we duplicate the page in
1417 memory so that one copy is RX and the other is RW */
1418 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1419 addr += ELF_PAGE_SIZE;
1422 /* if interpreter, then add corresponing program header */
1423 if (interp) {
1424 ph = &phdr[0];
1426 ph->p_type = PT_INTERP;
1427 ph->p_offset = interp->sh_offset;
1428 ph->p_vaddr = interp->sh_addr;
1429 ph->p_paddr = ph->p_vaddr;
1430 ph->p_filesz = interp->sh_size;
1431 ph->p_memsz = interp->sh_size;
1432 ph->p_flags = PF_R;
1433 ph->p_align = interp->sh_addralign;
1436 /* if dynamic section, then add corresponing program header */
1437 if (dynamic) {
1438 Elf32_Sym *sym_end;
1440 ph = &phdr[phnum - 1];
1442 ph->p_type = PT_DYNAMIC;
1443 ph->p_offset = dynamic->sh_offset;
1444 ph->p_vaddr = dynamic->sh_addr;
1445 ph->p_paddr = ph->p_vaddr;
1446 ph->p_filesz = dynamic->sh_size;
1447 ph->p_memsz = dynamic->sh_size;
1448 ph->p_flags = PF_R | PF_W;
1449 ph->p_align = dynamic->sh_addralign;
1451 /* put GOT dynamic section address */
1452 put32(s1->got->data, dynamic->sh_addr);
1454 /* relocate the PLT */
1455 if (file_type == TCC_OUTPUT_EXE) {
1456 uint8_t *p, *p_end;
1458 p = s1->plt->data;
1459 p_end = p + s1->plt->data_offset;
1460 if (p < p_end) {
1461 #if defined(TCC_TARGET_I386)
1462 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1463 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1464 p += 16;
1465 while (p < p_end) {
1466 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1467 p += 16;
1469 #elif defined(TCC_TARGET_ARM)
1470 int x;
1471 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1472 p +=16;
1473 while (p < p_end) {
1474 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1475 p += 16;
1477 #elif defined(TCC_TARGET_C67)
1478 /* XXX: TODO */
1479 #else
1480 #error unsupported CPU
1481 #endif
1485 /* relocate symbols in .dynsym */
1486 sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
1487 for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
1488 sym < sym_end;
1489 sym++) {
1490 if (sym->st_shndx == SHN_UNDEF) {
1491 /* relocate to the PLT if the symbol corresponds
1492 to a PLT entry */
1493 if (sym->st_value)
1494 sym->st_value += s1->plt->sh_addr;
1495 } else if (sym->st_shndx < SHN_LORESERVE) {
1496 /* do symbol relocation */
1497 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1501 /* put dynamic section entries */
1502 dynamic->data_offset = saved_dynamic_data_offset;
1503 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1504 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1505 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1506 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1507 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
1508 put_dt(dynamic, DT_REL, rel_addr);
1509 put_dt(dynamic, DT_RELSZ, rel_size);
1510 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
1511 put_dt(dynamic, DT_NULL, 0);
1514 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1515 ehdr.e_phnum = phnum;
1516 ehdr.e_phoff = sizeof(Elf32_Ehdr);
1519 /* all other sections come after */
1520 for(i = 1; i < s1->nb_sections; i++) {
1521 s = s1->sections[i];
1522 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1523 continue;
1524 section_order[sh_order_index++] = i;
1526 file_offset = (file_offset + s->sh_addralign - 1) &
1527 ~(s->sh_addralign - 1);
1528 s->sh_offset = file_offset;
1529 if (s->sh_type != SHT_NOBITS)
1530 file_offset += s->sh_size;
1533 /* if building executable or DLL, then relocate each section
1534 except the GOT which is already relocated */
1535 if (file_type != TCC_OUTPUT_OBJ) {
1536 relocate_syms(s1, 0);
1538 if (s1->nb_errors != 0) {
1539 fail:
1540 ret = -1;
1541 goto the_end;
1544 /* relocate sections */
1545 /* XXX: ignore sections with allocated relocations ? */
1546 for(i = 1; i < s1->nb_sections; i++) {
1547 s = s1->sections[i];
1548 if (s->reloc && s != s1->got)
1549 relocate_section(s1, s);
1552 /* relocate relocation entries if the relocation tables are
1553 allocated in the executable */
1554 for(i = 1; i < s1->nb_sections; i++) {
1555 s = s1->sections[i];
1556 if ((s->sh_flags & SHF_ALLOC) &&
1557 s->sh_type == SHT_REL) {
1558 relocate_rel(s1, s);
1562 /* get entry point address */
1563 if (file_type == TCC_OUTPUT_EXE)
1564 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
1565 else
1566 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1569 #ifdef TCC_TARGET_COFF
1570 ret = tcc_output_coff(s1, filename);
1571 #else
1572 sort_syms(s1, symtab_section);
1574 /* align to 4 */
1575 file_offset = (file_offset + 3) & -4;
1577 /* fill header */
1578 ehdr.e_ident[0] = ELFMAG0;
1579 ehdr.e_ident[1] = ELFMAG1;
1580 ehdr.e_ident[2] = ELFMAG2;
1581 ehdr.e_ident[3] = ELFMAG3;
1582 ehdr.e_ident[4] = ELFCLASS32;
1583 ehdr.e_ident[5] = ELFDATA2LSB;
1584 ehdr.e_ident[6] = EV_CURRENT;
1585 #ifdef __FreeBSD__
1586 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1587 #endif
1588 #ifdef TCC_TARGET_ARM
1589 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1590 #endif
1591 switch(file_type) {
1592 default:
1593 case TCC_OUTPUT_EXE:
1594 ehdr.e_type = ET_EXEC;
1595 break;
1596 case TCC_OUTPUT_DLL:
1597 ehdr.e_type = ET_DYN;
1598 break;
1599 case TCC_OUTPUT_OBJ:
1600 ehdr.e_type = ET_REL;
1601 break;
1603 ehdr.e_machine = EM_TCC_TARGET;
1604 ehdr.e_version = EV_CURRENT;
1605 ehdr.e_shoff = file_offset;
1606 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1607 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1608 ehdr.e_shnum = shnum;
1609 ehdr.e_shstrndx = shnum - 1;
1611 /* write elf file */
1612 if (file_type == TCC_OUTPUT_OBJ)
1613 mode = 0666;
1614 else
1615 mode = 0777;
1616 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
1617 if (fd < 0) {
1618 error_noabort("could not write '%s'", filename);
1619 goto fail;
1621 f = fdopen(fd, "w");
1622 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1623 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1624 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1625 for(i=1;i<s1->nb_sections;i++) {
1626 s = s1->sections[section_order[i]];
1627 if (s->sh_type != SHT_NOBITS) {
1628 while (offset < s->sh_offset) {
1629 fputc(0, f);
1630 offset++;
1632 size = s->sh_size;
1633 fwrite(s->data, 1, size, f);
1634 offset += size;
1637 while (offset < ehdr.e_shoff) {
1638 fputc(0, f);
1639 offset++;
1642 /* output section headers */
1643 for(i=0;i<s1->nb_sections;i++) {
1644 sh = &shdr;
1645 memset(sh, 0, sizeof(Elf32_Shdr));
1646 s = s1->sections[i];
1647 if (s) {
1648 sh->sh_name = s->sh_name;
1649 sh->sh_type = s->sh_type;
1650 sh->sh_flags = s->sh_flags;
1651 sh->sh_entsize = s->sh_entsize;
1652 sh->sh_info = s->sh_info;
1653 if (s->link)
1654 sh->sh_link = s->link->sh_num;
1655 sh->sh_addralign = s->sh_addralign;
1656 sh->sh_addr = s->sh_addr;
1657 sh->sh_offset = s->sh_offset;
1658 sh->sh_size = s->sh_size;
1660 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1662 fclose(f);
1664 ret = 0;
1665 #endif
1666 the_end:
1667 tcc_free(s1->symtab_to_dynsym);
1668 tcc_free(section_order);
1669 tcc_free(phdr);
1670 tcc_free(s1->got_offsets);
1671 return ret;
1674 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1676 void *data;
1678 data = tcc_malloc(size);
1679 lseek(fd, file_offset, SEEK_SET);
1680 read(fd, data, size);
1681 return data;
1684 typedef struct SectionMergeInfo {
1685 Section *s; /* corresponding existing section */
1686 unsigned long offset; /* offset of the new section in the existing section */
1687 uint8_t new_section; /* true if section 's' was added */
1688 uint8_t link_once; /* true if link once section */
1689 } SectionMergeInfo;
1691 /* load an object file and merge it with current files */
1692 /* XXX: handle correctly stab (debug) info */
1693 static int tcc_load_object_file(TCCState *s1,
1694 int fd, unsigned long file_offset)
1696 Elf32_Ehdr ehdr;
1697 Elf32_Shdr *shdr, *sh;
1698 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1699 unsigned char *strsec, *strtab;
1700 int *old_to_new_syms;
1701 char *sh_name, *name;
1702 SectionMergeInfo *sm_table, *sm;
1703 Elf32_Sym *sym, *symtab;
1704 Elf32_Rel *rel, *rel_end;
1705 Section *s;
1707 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1708 goto fail1;
1709 if (ehdr.e_ident[0] != ELFMAG0 ||
1710 ehdr.e_ident[1] != ELFMAG1 ||
1711 ehdr.e_ident[2] != ELFMAG2 ||
1712 ehdr.e_ident[3] != ELFMAG3)
1713 goto fail1;
1714 /* test if object file */
1715 if (ehdr.e_type != ET_REL)
1716 goto fail1;
1717 /* test CPU specific stuff */
1718 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1719 ehdr.e_machine != EM_TCC_TARGET) {
1720 fail1:
1721 error_noabort("invalid object file");
1722 return -1;
1724 /* read sections */
1725 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1726 sizeof(Elf32_Shdr) * ehdr.e_shnum);
1727 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1729 /* load section names */
1730 sh = &shdr[ehdr.e_shstrndx];
1731 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1733 /* load symtab and strtab */
1734 old_to_new_syms = NULL;
1735 symtab = NULL;
1736 strtab = NULL;
1737 nb_syms = 0;
1738 for(i = 1; i < ehdr.e_shnum; i++) {
1739 sh = &shdr[i];
1740 if (sh->sh_type == SHT_SYMTAB) {
1741 if (symtab) {
1742 error_noabort("object must contain only one symtab");
1743 fail:
1744 ret = -1;
1745 goto the_end;
1747 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1748 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1749 sm_table[i].s = symtab_section;
1751 /* now load strtab */
1752 sh = &shdr[sh->sh_link];
1753 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1757 /* now examine each section and try to merge its content with the
1758 ones in memory */
1759 for(i = 1; i < ehdr.e_shnum; i++) {
1760 /* no need to examine section name strtab */
1761 if (i == ehdr.e_shstrndx)
1762 continue;
1763 sh = &shdr[i];
1764 sh_name = strsec + sh->sh_name;
1765 /* ignore sections types we do not handle */
1766 if (sh->sh_type != SHT_PROGBITS &&
1767 sh->sh_type != SHT_REL &&
1768 sh->sh_type != SHT_NOBITS)
1769 continue;
1770 if (sh->sh_addralign < 1)
1771 sh->sh_addralign = 1;
1772 /* find corresponding section, if any */
1773 for(j = 1; j < s1->nb_sections;j++) {
1774 s = s1->sections[j];
1775 if (!strcmp(s->name, sh_name)) {
1776 if (!strncmp(sh_name, ".gnu.linkonce",
1777 sizeof(".gnu.linkonce") - 1)) {
1778 /* if a 'linkonce' section is already present, we
1779 do not add it again. It is a little tricky as
1780 symbols can still be defined in
1781 it. */
1782 sm_table[i].link_once = 1;
1783 goto next;
1784 } else {
1785 goto found;
1789 /* not found: create new section */
1790 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1791 /* take as much info as possible from the section. sh_link and
1792 sh_info will be updated later */
1793 s->sh_addralign = sh->sh_addralign;
1794 s->sh_entsize = sh->sh_entsize;
1795 sm_table[i].new_section = 1;
1796 found:
1797 if (sh->sh_type != s->sh_type) {
1798 error_noabort("invalid section type");
1799 goto fail;
1802 /* align start of section */
1803 offset = s->data_offset;
1804 size = sh->sh_addralign - 1;
1805 offset = (offset + size) & ~size;
1806 if (sh->sh_addralign > s->sh_addralign)
1807 s->sh_addralign = sh->sh_addralign;
1808 s->data_offset = offset;
1809 sm_table[i].offset = offset;
1810 sm_table[i].s = s;
1811 /* concatenate sections */
1812 size = sh->sh_size;
1813 if (sh->sh_type != SHT_NOBITS) {
1814 unsigned char *ptr;
1815 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1816 ptr = section_ptr_add(s, size);
1817 read(fd, ptr, size);
1818 } else {
1819 s->data_offset += size;
1821 next: ;
1824 /* second short pass to update sh_link and sh_info fields of new
1825 sections */
1826 sm = sm_table;
1827 for(i = 1; i < ehdr.e_shnum; i++) {
1828 s = sm_table[i].s;
1829 if (!s || !sm_table[i].new_section)
1830 continue;
1831 sh = &shdr[i];
1832 if (sh->sh_link > 0)
1833 s->link = sm_table[sh->sh_link].s;
1834 if (sh->sh_type == SHT_REL) {
1835 s->sh_info = sm_table[sh->sh_info].s->sh_num;
1836 /* update backward link */
1837 s1->sections[s->sh_info]->reloc = s;
1841 /* resolve symbols */
1842 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
1844 sym = symtab + 1;
1845 for(i = 1; i < nb_syms; i++, sym++) {
1846 if (sym->st_shndx != SHN_UNDEF &&
1847 sym->st_shndx < SHN_LORESERVE) {
1848 sm = &sm_table[sym->st_shndx];
1849 if (sm->link_once) {
1850 /* if a symbol is in a link once section, we use the
1851 already defined symbol. It is very important to get
1852 correct relocations */
1853 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1854 name = strtab + sym->st_name;
1855 sym_index = find_elf_sym(symtab_section, name);
1856 if (sym_index)
1857 old_to_new_syms[i] = sym_index;
1859 continue;
1861 /* if no corresponding section added, no need to add symbol */
1862 if (!sm->s)
1863 continue;
1864 /* convert section number */
1865 sym->st_shndx = sm->s->sh_num;
1866 /* offset value */
1867 sym->st_value += sm->offset;
1869 /* add symbol */
1870 name = strtab + sym->st_name;
1871 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
1872 sym->st_info, sym->st_shndx, name);
1873 old_to_new_syms[i] = sym_index;
1876 /* third pass to patch relocation entries */
1877 for(i = 1; i < ehdr.e_shnum; i++) {
1878 s = sm_table[i].s;
1879 if (!s)
1880 continue;
1881 sh = &shdr[i];
1882 offset = sm_table[i].offset;
1883 switch(s->sh_type) {
1884 case SHT_REL:
1885 /* take relocation offset information */
1886 offseti = sm_table[sh->sh_info].offset;
1887 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
1888 for(rel = (Elf32_Rel *)(s->data + offset);
1889 rel < rel_end;
1890 rel++) {
1891 int type;
1892 unsigned sym_index;
1893 /* convert symbol index */
1894 type = ELF32_R_TYPE(rel->r_info);
1895 sym_index = ELF32_R_SYM(rel->r_info);
1896 /* NOTE: only one symtab assumed */
1897 if (sym_index >= nb_syms)
1898 goto invalid_reloc;
1899 sym_index = old_to_new_syms[sym_index];
1900 if (!sym_index) {
1901 invalid_reloc:
1902 error_noabort("Invalid relocation entry");
1903 goto fail;
1905 rel->r_info = ELF32_R_INFO(sym_index, type);
1906 /* offset the relocation offset */
1907 rel->r_offset += offseti;
1909 break;
1910 default:
1911 break;
1915 ret = 0;
1916 the_end:
1917 tcc_free(symtab);
1918 tcc_free(strtab);
1919 tcc_free(old_to_new_syms);
1920 tcc_free(sm_table);
1921 tcc_free(strsec);
1922 tcc_free(shdr);
1923 return ret;
1926 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1928 typedef struct ArchiveHeader {
1929 char ar_name[16]; /* name of this member */
1930 char ar_date[12]; /* file mtime */
1931 char ar_uid[6]; /* owner uid; printed as decimal */
1932 char ar_gid[6]; /* owner gid; printed as decimal */
1933 char ar_mode[8]; /* file mode, printed as octal */
1934 char ar_size[10]; /* file size, printed as decimal */
1935 char ar_fmag[2]; /* should contain ARFMAG */
1936 } ArchiveHeader;
1938 static int get_be32(const uint8_t *b)
1940 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
1943 /* load only the objects which resolve undefined symbols */
1944 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
1946 int i, bound, nsyms, sym_index, off, ret;
1947 uint8_t *data;
1948 const char *ar_names, *p;
1949 const uint8_t *ar_index;
1950 Elf32_Sym *sym;
1952 data = tcc_malloc(size);
1953 if (read(fd, data, size) != size)
1954 goto fail;
1955 nsyms = get_be32(data);
1956 ar_index = data + 4;
1957 ar_names = ar_index + nsyms * 4;
1959 do {
1960 bound = 0;
1961 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
1962 sym_index = find_elf_sym(symtab_section, p);
1963 if(sym_index) {
1964 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1965 if(sym->st_shndx == SHN_UNDEF) {
1966 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
1967 #if 0
1968 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
1969 #endif
1970 ++bound;
1971 lseek(fd, off, SEEK_SET);
1972 if(tcc_load_object_file(s1, fd, off) < 0) {
1973 fail:
1974 ret = -1;
1975 goto the_end;
1980 } while(bound);
1981 ret = 0;
1982 the_end:
1983 tcc_free(data);
1984 return ret;
1987 /* load a '.a' file */
1988 static int tcc_load_archive(TCCState *s1, int fd)
1990 ArchiveHeader hdr;
1991 char ar_size[11];
1992 char ar_name[17];
1993 char magic[8];
1994 int size, len, i;
1995 unsigned long file_offset;
1997 /* skip magic which was already checked */
1998 read(fd, magic, sizeof(magic));
2000 for(;;) {
2001 len = read(fd, &hdr, sizeof(hdr));
2002 if (len == 0)
2003 break;
2004 if (len != sizeof(hdr)) {
2005 error_noabort("invalid archive");
2006 return -1;
2008 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2009 ar_size[sizeof(hdr.ar_size)] = '\0';
2010 size = strtol(ar_size, NULL, 0);
2011 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2012 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2013 if (ar_name[i] != ' ')
2014 break;
2016 ar_name[i + 1] = '\0';
2017 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2018 file_offset = lseek(fd, 0, SEEK_CUR);
2019 /* align to even */
2020 size = (size + 1) & ~1;
2021 if (!strcmp(ar_name, "/")) {
2022 /* coff symbol table : we handle it */
2023 if(s1->alacarte_link)
2024 return tcc_load_alacarte(s1, fd, size);
2025 } else if (!strcmp(ar_name, "//") ||
2026 !strcmp(ar_name, "__.SYMDEF") ||
2027 !strcmp(ar_name, "__.SYMDEF/") ||
2028 !strcmp(ar_name, "ARFILENAMES/")) {
2029 /* skip symbol table or archive names */
2030 } else {
2031 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2032 return -1;
2034 lseek(fd, file_offset + size, SEEK_SET);
2036 return 0;
2039 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2040 is referenced by the user (so it should be added as DT_NEEDED in
2041 the generated ELF file) */
2042 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2044 Elf32_Ehdr ehdr;
2045 Elf32_Shdr *shdr, *sh, *sh1;
2046 int i, nb_syms, nb_dts, sym_bind, ret;
2047 Elf32_Sym *sym, *dynsym;
2048 Elf32_Dyn *dt, *dynamic;
2049 unsigned char *dynstr;
2050 const char *name, *soname, *p;
2051 DLLReference *dllref;
2053 read(fd, &ehdr, sizeof(ehdr));
2055 /* test CPU specific stuff */
2056 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2057 ehdr.e_machine != EM_TCC_TARGET) {
2058 error_noabort("bad architecture");
2059 return -1;
2062 /* read sections */
2063 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
2065 /* load dynamic section and dynamic symbols */
2066 nb_syms = 0;
2067 nb_dts = 0;
2068 dynamic = NULL;
2069 dynsym = NULL; /* avoid warning */
2070 dynstr = NULL; /* avoid warning */
2071 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2072 switch(sh->sh_type) {
2073 case SHT_DYNAMIC:
2074 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
2075 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2076 break;
2077 case SHT_DYNSYM:
2078 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
2079 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2080 sh1 = &shdr[sh->sh_link];
2081 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2082 break;
2083 default:
2084 break;
2088 /* compute the real library name */
2089 soname = filename;
2090 p = strrchr(soname, '/');
2091 if (p)
2092 soname = p + 1;
2094 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2095 if (dt->d_tag == DT_SONAME) {
2096 soname = dynstr + dt->d_un.d_val;
2100 /* if the dll is already loaded, do not load it */
2101 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2102 dllref = s1->loaded_dlls[i];
2103 if (!strcmp(soname, dllref->name)) {
2104 /* but update level if needed */
2105 if (level < dllref->level)
2106 dllref->level = level;
2107 ret = 0;
2108 goto the_end;
2112 // printf("loading dll '%s'\n", soname);
2114 /* add the dll and its level */
2115 dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
2116 dllref->level = level;
2117 strcpy(dllref->name, soname);
2118 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2120 /* add dynamic symbols in dynsym_section */
2121 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2122 sym_bind = ELF32_ST_BIND(sym->st_info);
2123 if (sym_bind == STB_LOCAL)
2124 continue;
2125 name = dynstr + sym->st_name;
2126 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2127 sym->st_info, sym->st_shndx, name);
2130 /* load all referenced DLLs */
2131 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2132 switch(dt->d_tag) {
2133 case DT_NEEDED:
2134 name = dynstr + dt->d_un.d_val;
2135 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2136 dllref = s1->loaded_dlls[i];
2137 if (!strcmp(name, dllref->name))
2138 goto already_loaded;
2140 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2141 error_noabort("referenced dll '%s' not found", name);
2142 ret = -1;
2143 goto the_end;
2145 already_loaded:
2146 break;
2149 ret = 0;
2150 the_end:
2151 tcc_free(dynstr);
2152 tcc_free(dynsym);
2153 tcc_free(dynamic);
2154 tcc_free(shdr);
2155 return ret;
2158 #define LD_TOK_NAME 256
2159 #define LD_TOK_EOF (-1)
2161 /* return next ld script token */
2162 static int ld_next(TCCState *s1, char *name, int name_size)
2164 int c;
2165 char *q;
2167 redo:
2168 switch(ch) {
2169 case ' ':
2170 case '\t':
2171 case '\f':
2172 case '\v':
2173 case '\r':
2174 case '\n':
2175 inp();
2176 goto redo;
2177 case '/':
2178 minp();
2179 if (ch == '*') {
2180 file->buf_ptr = parse_comment(file->buf_ptr);
2181 ch = file->buf_ptr[0];
2182 goto redo;
2183 } else {
2184 q = name;
2185 *q++ = '/';
2186 goto parse_name;
2188 break;
2189 case 'a' ... 'z':
2190 case 'A' ... 'Z':
2191 case '_':
2192 case '\\':
2193 case '.':
2194 case '$':
2195 case '~':
2196 q = name;
2197 parse_name:
2198 for(;;) {
2199 if (!((ch >= 'a' && ch <= 'z') ||
2200 (ch >= 'A' && ch <= 'Z') ||
2201 (ch >= '0' && ch <= '9') ||
2202 strchr("/.-_+=$:\\,~", ch)))
2203 break;
2204 if ((q - name) < name_size - 1) {
2205 *q++ = ch;
2207 minp();
2209 *q = '\0';
2210 c = LD_TOK_NAME;
2211 break;
2212 case CH_EOF:
2213 c = LD_TOK_EOF;
2214 break;
2215 default:
2216 c = ch;
2217 inp();
2218 break;
2220 #if 0
2221 printf("tok=%c %d\n", c, c);
2222 if (c == LD_TOK_NAME)
2223 printf(" name=%s\n", name);
2224 #endif
2225 return c;
2228 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2229 files */
2230 static int tcc_load_ldscript(TCCState *s1)
2232 char cmd[64];
2233 char filename[1024];
2234 int t;
2236 ch = file->buf_ptr[0];
2237 ch = handle_eob();
2238 for(;;) {
2239 t = ld_next(s1, cmd, sizeof(cmd));
2240 if (t == LD_TOK_EOF)
2241 return 0;
2242 else if (t != LD_TOK_NAME)
2243 return -1;
2244 if (!strcmp(cmd, "INPUT") ||
2245 !strcmp(cmd, "GROUP")) {
2246 t = ld_next(s1, cmd, sizeof(cmd));
2247 if (t != '(')
2248 expect("(");
2249 t = ld_next(s1, filename, sizeof(filename));
2250 for(;;) {
2251 if (t == LD_TOK_EOF) {
2252 error_noabort("unexpected end of file");
2253 return -1;
2254 } else if (t == ')') {
2255 break;
2256 } else if (t != LD_TOK_NAME) {
2257 error_noabort("filename expected");
2258 return -1;
2260 tcc_add_file(s1, filename);
2261 t = ld_next(s1, filename, sizeof(filename));
2262 if (t == ',') {
2263 t = ld_next(s1, filename, sizeof(filename));
2266 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2267 !strcmp(cmd, "TARGET")) {
2268 /* ignore some commands */
2269 t = ld_next(s1, cmd, sizeof(cmd));
2270 if (t != '(')
2271 expect("(");
2272 for(;;) {
2273 t = ld_next(s1, filename, sizeof(filename));
2274 if (t == LD_TOK_EOF) {
2275 error_noabort("unexpected end of file");
2276 return -1;
2277 } else if (t == ')') {
2278 break;
2281 } else {
2282 return -1;
2285 return 0;