added _Bool in bit-fields
[tinycc/miki.git] / tccelf.c
blob6f8ebdf4b7b5a40b0b97a93af6a1f37f79831a95
1 /*
2 * ELF file handling for TCC
3 *
4 * Copyright (c) 2001-2004 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];
959 #ifdef CONFIG_TCC_BCHECK
960 if (do_bounds_check) {
961 unsigned long *ptr;
962 Section *init_section;
963 unsigned char *pinit;
964 int sym_index;
966 /* XXX: add an object file to do that */
967 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
968 *ptr = 0;
969 add_elf_sym(symtab_section, 0, 0,
970 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
971 bounds_section->sh_num, "__bounds_start");
972 /* add bound check code */
973 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
974 tcc_add_file(s1, buf);
975 #ifdef TCC_TARGET_I386
976 if (s1->output_type != TCC_OUTPUT_MEMORY) {
977 /* add 'call __bound_init()' in .init section */
978 init_section = find_section(s1, ".init");
979 pinit = section_ptr_add(init_section, 5);
980 pinit[0] = 0xe8;
981 put32(pinit + 1, -4);
982 sym_index = find_elf_sym(symtab_section, "__bound_init");
983 put_elf_reloc(symtab_section, init_section,
984 init_section->data_offset - 4, R_386_PC32, sym_index);
986 #endif
988 #endif
989 /* add libc */
990 if (!s1->nostdlib) {
991 tcc_add_library(s1, "c");
993 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
994 tcc_add_file(s1, buf);
996 /* add crt end if not memory output */
997 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
998 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1002 /* add various standard linker symbols (must be done after the
1003 sections are filled (for example after allocating common
1004 symbols)) */
1005 static void tcc_add_linker_symbols(TCCState *s1)
1007 char buf[1024];
1008 int i;
1009 Section *s;
1011 add_elf_sym(symtab_section,
1012 text_section->data_offset, 0,
1013 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
1014 text_section->sh_num, "_etext");
1015 add_elf_sym(symtab_section,
1016 data_section->data_offset, 0,
1017 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
1018 data_section->sh_num, "_edata");
1019 add_elf_sym(symtab_section,
1020 bss_section->data_offset, 0,
1021 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
1022 bss_section->sh_num, "_end");
1023 /* horrible new standard ldscript defines */
1024 add_init_array_defines(s1, ".preinit_array");
1025 add_init_array_defines(s1, ".init_array");
1026 add_init_array_defines(s1, ".fini_array");
1028 /* add start and stop symbols for sections whose name can be
1029 expressed in C */
1030 for(i = 1; i < s1->nb_sections; i++) {
1031 s = s1->sections[i];
1032 if (s->sh_type == SHT_PROGBITS &&
1033 (s->sh_flags & SHF_ALLOC)) {
1034 const char *p;
1035 int ch;
1037 /* check if section name can be expressed in C */
1038 p = s->name;
1039 for(;;) {
1040 ch = *p;
1041 if (!ch)
1042 break;
1043 if (!isid(ch) && !isnum(ch))
1044 goto next_sec;
1045 p++;
1047 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1048 add_elf_sym(symtab_section,
1049 0, 0,
1050 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
1051 s->sh_num, buf);
1052 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1053 add_elf_sym(symtab_section,
1054 s->data_offset, 0,
1055 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
1056 s->sh_num, buf);
1058 next_sec: ;
1062 /* name of ELF interpreter */
1063 #ifdef __FreeBSD__
1064 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1065 #else
1066 static char elf_interp[] = "/lib/ld-linux.so.2";
1067 #endif
1069 static void tcc_output_binary(TCCState *s1, FILE *f,
1070 const int *section_order)
1072 Section *s;
1073 int i, offset, size;
1075 offset = 0;
1076 for(i=1;i<s1->nb_sections;i++) {
1077 s = s1->sections[section_order[i]];
1078 if (s->sh_type != SHT_NOBITS &&
1079 (s->sh_flags & SHF_ALLOC)) {
1080 while (offset < s->sh_offset) {
1081 fputc(0, f);
1082 offset++;
1084 size = s->sh_size;
1085 fwrite(s->data, 1, size, f);
1086 offset += size;
1091 /* output an ELF file */
1092 /* XXX: suppress unneeded sections */
1093 int tcc_output_file(TCCState *s1, const char *filename)
1095 Elf32_Ehdr ehdr;
1096 FILE *f;
1097 int fd, mode, ret;
1098 int *section_order;
1099 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1100 unsigned long addr;
1101 Section *strsec, *s;
1102 Elf32_Shdr shdr, *sh;
1103 Elf32_Phdr *phdr, *ph;
1104 Section *interp, *dynamic, *dynstr;
1105 unsigned long saved_dynamic_data_offset;
1106 Elf32_Sym *sym;
1107 int type, file_type;
1108 unsigned long rel_addr, rel_size;
1110 file_type = s1->output_type;
1111 s1->nb_errors = 0;
1113 if (file_type != TCC_OUTPUT_OBJ) {
1114 tcc_add_runtime(s1);
1117 phdr = NULL;
1118 section_order = NULL;
1119 interp = NULL;
1120 dynamic = NULL;
1121 dynstr = NULL; /* avoid warning */
1122 saved_dynamic_data_offset = 0; /* avoid warning */
1124 if (file_type != TCC_OUTPUT_OBJ) {
1125 relocate_common_syms();
1127 tcc_add_linker_symbols(s1);
1129 if (!s1->static_link) {
1130 const char *name;
1131 int sym_index, index;
1132 Elf32_Sym *esym, *sym_end;
1134 if (file_type == TCC_OUTPUT_EXE) {
1135 char *ptr;
1136 /* add interpreter section only if executable */
1137 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1138 interp->sh_addralign = 1;
1139 ptr = section_ptr_add(interp, sizeof(elf_interp));
1140 strcpy(ptr, elf_interp);
1143 /* add dynamic symbol table */
1144 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1145 ".dynstr",
1146 ".hash", SHF_ALLOC);
1147 dynstr = s1->dynsym->link;
1149 /* add dynamic section */
1150 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1151 SHF_ALLOC | SHF_WRITE);
1152 dynamic->link = dynstr;
1153 dynamic->sh_entsize = sizeof(Elf32_Dyn);
1155 /* add PLT */
1156 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1157 SHF_ALLOC | SHF_EXECINSTR);
1158 s1->plt->sh_entsize = 4;
1160 build_got(s1);
1162 /* scan for undefined symbols and see if they are in the
1163 dynamic symbols. If a symbol STT_FUNC is found, then we
1164 add it in the PLT. If a symbol STT_OBJECT is found, we
1165 add it in the .bss section with a suitable relocation */
1166 sym_end = (Elf32_Sym *)(symtab_section->data +
1167 symtab_section->data_offset);
1168 if (file_type == TCC_OUTPUT_EXE) {
1169 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1170 sym < sym_end;
1171 sym++) {
1172 if (sym->st_shndx == SHN_UNDEF) {
1173 name = symtab_section->link->data + sym->st_name;
1174 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1175 if (sym_index) {
1176 esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
1177 type = ELF32_ST_TYPE(esym->st_info);
1178 if (type == STT_FUNC) {
1179 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1180 esym->st_info,
1181 sym - (Elf32_Sym *)symtab_section->data);
1182 } else if (type == STT_OBJECT) {
1183 unsigned long offset;
1184 offset = bss_section->data_offset;
1185 /* XXX: which alignment ? */
1186 offset = (offset + 16 - 1) & -16;
1187 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1188 esym->st_info, 0,
1189 bss_section->sh_num, name);
1190 put_elf_reloc(s1->dynsym, bss_section,
1191 offset, R_COPY, index);
1192 offset += esym->st_size;
1193 bss_section->data_offset = offset;
1195 } else {
1196 /* STB_WEAK undefined symbols are accepted */
1197 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1198 it */
1199 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
1200 !strcmp(name, "_fp_hw")) {
1201 } else {
1202 error_noabort("undefined symbol '%s'", name);
1205 } else if (s1->rdynamic &&
1206 ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1207 /* if -rdynamic option, then export all non
1208 local symbols */
1209 name = symtab_section->link->data + sym->st_name;
1210 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1211 sym->st_info, 0,
1212 sym->st_shndx, name);
1216 if (s1->nb_errors)
1217 goto fail;
1219 /* now look at unresolved dynamic symbols and export
1220 corresponding symbol */
1221 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
1222 s1->dynsymtab_section->data_offset);
1223 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
1224 esym < sym_end;
1225 esym++) {
1226 if (esym->st_shndx == SHN_UNDEF) {
1227 name = s1->dynsymtab_section->link->data + esym->st_name;
1228 sym_index = find_elf_sym(symtab_section, name);
1229 if (sym_index) {
1230 /* XXX: avoid adding a symbol if already
1231 present because of -rdynamic ? */
1232 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1233 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1234 sym->st_info, 0,
1235 sym->st_shndx, name);
1236 } else {
1237 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
1238 /* weak symbols can stay undefined */
1239 } else {
1240 warning("undefined dynamic symbol '%s'", name);
1245 } else {
1246 int nb_syms;
1247 /* shared library case : we simply export all the global symbols */
1248 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
1249 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1250 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1251 sym < sym_end;
1252 sym++) {
1253 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1254 name = symtab_section->link->data + sym->st_name;
1255 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1256 sym->st_info, 0,
1257 sym->st_shndx, name);
1258 s1->symtab_to_dynsym[sym -
1259 (Elf32_Sym *)symtab_section->data] =
1260 index;
1265 build_got_entries(s1);
1267 /* add a list of needed dlls */
1268 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1269 DLLReference *dllref = s1->loaded_dlls[i];
1270 if (dllref->level == 0)
1271 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1273 /* XXX: currently, since we do not handle PIC code, we
1274 must relocate the readonly segments */
1275 if (file_type == TCC_OUTPUT_DLL)
1276 put_dt(dynamic, DT_TEXTREL, 0);
1278 /* add necessary space for other entries */
1279 saved_dynamic_data_offset = dynamic->data_offset;
1280 dynamic->data_offset += 8 * 9;
1281 } else {
1282 /* still need to build got entries in case of static link */
1283 build_got_entries(s1);
1287 memset(&ehdr, 0, sizeof(ehdr));
1289 /* we add a section for symbols */
1290 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1291 put_elf_str(strsec, "");
1293 /* compute number of sections */
1294 shnum = s1->nb_sections;
1296 /* this array is used to reorder sections in the output file */
1297 section_order = tcc_malloc(sizeof(int) * shnum);
1298 section_order[0] = 0;
1299 sh_order_index = 1;
1301 /* compute number of program headers */
1302 switch(file_type) {
1303 default:
1304 case TCC_OUTPUT_OBJ:
1305 phnum = 0;
1306 break;
1307 case TCC_OUTPUT_EXE:
1308 if (!s1->static_link)
1309 phnum = 4;
1310 else
1311 phnum = 2;
1312 break;
1313 case TCC_OUTPUT_DLL:
1314 phnum = 3;
1315 break;
1318 /* allocate strings for section names and decide if an unallocated
1319 section should be output */
1320 /* NOTE: the strsec section comes last, so its size is also
1321 correct ! */
1322 for(i = 1; i < s1->nb_sections; i++) {
1323 s = s1->sections[i];
1324 s->sh_name = put_elf_str(strsec, s->name);
1325 /* when generating a DLL, we include relocations but we may
1326 patch them */
1327 if (file_type == TCC_OUTPUT_DLL &&
1328 s->sh_type == SHT_REL &&
1329 !(s->sh_flags & SHF_ALLOC)) {
1330 prepare_dynamic_rel(s1, s);
1331 } else if (do_debug ||
1332 file_type == TCC_OUTPUT_OBJ ||
1333 (s->sh_flags & SHF_ALLOC) ||
1334 i == (s1->nb_sections - 1)) {
1335 /* we output all sections if debug or object file */
1336 s->sh_size = s->data_offset;
1340 /* allocate program segment headers */
1341 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1343 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1344 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1345 } else {
1346 file_offset = 0;
1348 if (phnum > 0) {
1349 /* compute section to program header mapping */
1350 if (s1->has_text_addr) {
1351 int a_offset, p_offset;
1352 addr = s1->text_addr;
1353 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1354 ELF_PAGE_SIZE */
1355 a_offset = addr & (ELF_PAGE_SIZE - 1);
1356 p_offset = file_offset & (ELF_PAGE_SIZE - 1);
1357 if (a_offset < p_offset)
1358 a_offset += ELF_PAGE_SIZE;
1359 file_offset += (a_offset - p_offset);
1360 } else {
1361 if (file_type == TCC_OUTPUT_DLL)
1362 addr = 0;
1363 else
1364 addr = ELF_START_ADDR;
1365 /* compute address after headers */
1366 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1369 /* dynamic relocation table information, for .dynamic section */
1370 rel_size = 0;
1371 rel_addr = 0;
1373 /* leave one program header for the program interpreter */
1374 ph = &phdr[0];
1375 if (interp)
1376 ph++;
1378 for(j = 0; j < 2; j++) {
1379 ph->p_type = PT_LOAD;
1380 if (j == 0)
1381 ph->p_flags = PF_R | PF_X;
1382 else
1383 ph->p_flags = PF_R | PF_W;
1384 ph->p_align = ELF_PAGE_SIZE;
1386 /* we do the following ordering: interp, symbol tables,
1387 relocations, progbits, nobits */
1388 /* XXX: do faster and simpler sorting */
1389 for(k = 0; k < 5; k++) {
1390 for(i = 1; i < s1->nb_sections; i++) {
1391 s = s1->sections[i];
1392 /* compute if section should be included */
1393 if (j == 0) {
1394 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1395 SHF_ALLOC)
1396 continue;
1397 } else {
1398 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1399 (SHF_ALLOC | SHF_WRITE))
1400 continue;
1402 if (s == interp) {
1403 if (k != 0)
1404 continue;
1405 } else if (s->sh_type == SHT_DYNSYM ||
1406 s->sh_type == SHT_STRTAB ||
1407 s->sh_type == SHT_HASH) {
1408 if (k != 1)
1409 continue;
1410 } else if (s->sh_type == SHT_REL) {
1411 if (k != 2)
1412 continue;
1413 } else if (s->sh_type == SHT_NOBITS) {
1414 if (k != 4)
1415 continue;
1416 } else {
1417 if (k != 3)
1418 continue;
1420 section_order[sh_order_index++] = i;
1422 /* section matches: we align it and add its size */
1423 tmp = addr;
1424 addr = (addr + s->sh_addralign - 1) &
1425 ~(s->sh_addralign - 1);
1426 file_offset += addr - tmp;
1427 s->sh_offset = file_offset;
1428 s->sh_addr = addr;
1430 /* update program header infos */
1431 if (ph->p_offset == 0) {
1432 ph->p_offset = file_offset;
1433 ph->p_vaddr = addr;
1434 ph->p_paddr = ph->p_vaddr;
1436 /* update dynamic relocation infos */
1437 if (s->sh_type == SHT_REL) {
1438 if (rel_size == 0)
1439 rel_addr = addr;
1440 rel_size += s->sh_size;
1442 addr += s->sh_size;
1443 if (s->sh_type != SHT_NOBITS)
1444 file_offset += s->sh_size;
1447 ph->p_filesz = file_offset - ph->p_offset;
1448 ph->p_memsz = addr - ph->p_vaddr;
1449 ph++;
1450 if (j == 0) {
1451 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1452 /* if in the middle of a page, we duplicate the page in
1453 memory so that one copy is RX and the other is RW */
1454 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1455 addr += ELF_PAGE_SIZE;
1456 } else {
1457 addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
1458 file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
1459 ~(ELF_PAGE_SIZE - 1);
1464 /* if interpreter, then add corresponing program header */
1465 if (interp) {
1466 ph = &phdr[0];
1468 ph->p_type = PT_INTERP;
1469 ph->p_offset = interp->sh_offset;
1470 ph->p_vaddr = interp->sh_addr;
1471 ph->p_paddr = ph->p_vaddr;
1472 ph->p_filesz = interp->sh_size;
1473 ph->p_memsz = interp->sh_size;
1474 ph->p_flags = PF_R;
1475 ph->p_align = interp->sh_addralign;
1478 /* if dynamic section, then add corresponing program header */
1479 if (dynamic) {
1480 Elf32_Sym *sym_end;
1482 ph = &phdr[phnum - 1];
1484 ph->p_type = PT_DYNAMIC;
1485 ph->p_offset = dynamic->sh_offset;
1486 ph->p_vaddr = dynamic->sh_addr;
1487 ph->p_paddr = ph->p_vaddr;
1488 ph->p_filesz = dynamic->sh_size;
1489 ph->p_memsz = dynamic->sh_size;
1490 ph->p_flags = PF_R | PF_W;
1491 ph->p_align = dynamic->sh_addralign;
1493 /* put GOT dynamic section address */
1494 put32(s1->got->data, dynamic->sh_addr);
1496 /* relocate the PLT */
1497 if (file_type == TCC_OUTPUT_EXE) {
1498 uint8_t *p, *p_end;
1500 p = s1->plt->data;
1501 p_end = p + s1->plt->data_offset;
1502 if (p < p_end) {
1503 #if defined(TCC_TARGET_I386)
1504 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1505 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1506 p += 16;
1507 while (p < p_end) {
1508 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1509 p += 16;
1511 #elif defined(TCC_TARGET_ARM)
1512 int x;
1513 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1514 p +=16;
1515 while (p < p_end) {
1516 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1517 p += 16;
1519 #elif defined(TCC_TARGET_C67)
1520 /* XXX: TODO */
1521 #else
1522 #error unsupported CPU
1523 #endif
1527 /* relocate symbols in .dynsym */
1528 sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
1529 for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
1530 sym < sym_end;
1531 sym++) {
1532 if (sym->st_shndx == SHN_UNDEF) {
1533 /* relocate to the PLT if the symbol corresponds
1534 to a PLT entry */
1535 if (sym->st_value)
1536 sym->st_value += s1->plt->sh_addr;
1537 } else if (sym->st_shndx < SHN_LORESERVE) {
1538 /* do symbol relocation */
1539 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1543 /* put dynamic section entries */
1544 dynamic->data_offset = saved_dynamic_data_offset;
1545 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1546 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1547 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1548 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1549 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
1550 put_dt(dynamic, DT_REL, rel_addr);
1551 put_dt(dynamic, DT_RELSZ, rel_size);
1552 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
1553 put_dt(dynamic, DT_NULL, 0);
1556 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1557 ehdr.e_phnum = phnum;
1558 ehdr.e_phoff = sizeof(Elf32_Ehdr);
1561 /* all other sections come after */
1562 for(i = 1; i < s1->nb_sections; i++) {
1563 s = s1->sections[i];
1564 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1565 continue;
1566 section_order[sh_order_index++] = i;
1568 file_offset = (file_offset + s->sh_addralign - 1) &
1569 ~(s->sh_addralign - 1);
1570 s->sh_offset = file_offset;
1571 if (s->sh_type != SHT_NOBITS)
1572 file_offset += s->sh_size;
1575 /* if building executable or DLL, then relocate each section
1576 except the GOT which is already relocated */
1577 if (file_type != TCC_OUTPUT_OBJ) {
1578 relocate_syms(s1, 0);
1580 if (s1->nb_errors != 0) {
1581 fail:
1582 ret = -1;
1583 goto the_end;
1586 /* relocate sections */
1587 /* XXX: ignore sections with allocated relocations ? */
1588 for(i = 1; i < s1->nb_sections; i++) {
1589 s = s1->sections[i];
1590 if (s->reloc && s != s1->got)
1591 relocate_section(s1, s);
1594 /* relocate relocation entries if the relocation tables are
1595 allocated in the executable */
1596 for(i = 1; i < s1->nb_sections; i++) {
1597 s = s1->sections[i];
1598 if ((s->sh_flags & SHF_ALLOC) &&
1599 s->sh_type == SHT_REL) {
1600 relocate_rel(s1, s);
1604 /* get entry point address */
1605 if (file_type == TCC_OUTPUT_EXE)
1606 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
1607 else
1608 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
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 | O_BINARY, mode);
1617 if (fd < 0) {
1618 error_noabort("could not write '%s'", filename);
1619 goto fail;
1621 f = fdopen(fd, "wb");
1623 #ifdef TCC_TARGET_COFF
1624 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1625 tcc_output_coff(s1, f);
1626 } else
1627 #endif
1628 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1629 sort_syms(s1, symtab_section);
1631 /* align to 4 */
1632 file_offset = (file_offset + 3) & -4;
1634 /* fill header */
1635 ehdr.e_ident[0] = ELFMAG0;
1636 ehdr.e_ident[1] = ELFMAG1;
1637 ehdr.e_ident[2] = ELFMAG2;
1638 ehdr.e_ident[3] = ELFMAG3;
1639 ehdr.e_ident[4] = ELFCLASS32;
1640 ehdr.e_ident[5] = ELFDATA2LSB;
1641 ehdr.e_ident[6] = EV_CURRENT;
1642 #ifdef __FreeBSD__
1643 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1644 #endif
1645 #ifdef TCC_TARGET_ARM
1646 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1647 #endif
1648 switch(file_type) {
1649 default:
1650 case TCC_OUTPUT_EXE:
1651 ehdr.e_type = ET_EXEC;
1652 break;
1653 case TCC_OUTPUT_DLL:
1654 ehdr.e_type = ET_DYN;
1655 break;
1656 case TCC_OUTPUT_OBJ:
1657 ehdr.e_type = ET_REL;
1658 break;
1660 ehdr.e_machine = EM_TCC_TARGET;
1661 ehdr.e_version = EV_CURRENT;
1662 ehdr.e_shoff = file_offset;
1663 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1664 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1665 ehdr.e_shnum = shnum;
1666 ehdr.e_shstrndx = shnum - 1;
1668 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1669 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1670 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1672 for(i=1;i<s1->nb_sections;i++) {
1673 s = s1->sections[section_order[i]];
1674 if (s->sh_type != SHT_NOBITS) {
1675 while (offset < s->sh_offset) {
1676 fputc(0, f);
1677 offset++;
1679 size = s->sh_size;
1680 fwrite(s->data, 1, size, f);
1681 offset += size;
1685 /* output section headers */
1686 while (offset < ehdr.e_shoff) {
1687 fputc(0, f);
1688 offset++;
1691 for(i=0;i<s1->nb_sections;i++) {
1692 sh = &shdr;
1693 memset(sh, 0, sizeof(Elf32_Shdr));
1694 s = s1->sections[i];
1695 if (s) {
1696 sh->sh_name = s->sh_name;
1697 sh->sh_type = s->sh_type;
1698 sh->sh_flags = s->sh_flags;
1699 sh->sh_entsize = s->sh_entsize;
1700 sh->sh_info = s->sh_info;
1701 if (s->link)
1702 sh->sh_link = s->link->sh_num;
1703 sh->sh_addralign = s->sh_addralign;
1704 sh->sh_addr = s->sh_addr;
1705 sh->sh_offset = s->sh_offset;
1706 sh->sh_size = s->sh_size;
1708 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1710 } else {
1711 tcc_output_binary(s1, f, section_order);
1713 fclose(f);
1715 ret = 0;
1716 the_end:
1717 tcc_free(s1->symtab_to_dynsym);
1718 tcc_free(section_order);
1719 tcc_free(phdr);
1720 tcc_free(s1->got_offsets);
1721 return ret;
1724 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1726 void *data;
1728 data = tcc_malloc(size);
1729 lseek(fd, file_offset, SEEK_SET);
1730 read(fd, data, size);
1731 return data;
1734 typedef struct SectionMergeInfo {
1735 Section *s; /* corresponding existing section */
1736 unsigned long offset; /* offset of the new section in the existing section */
1737 uint8_t new_section; /* true if section 's' was added */
1738 uint8_t link_once; /* true if link once section */
1739 } SectionMergeInfo;
1741 /* load an object file and merge it with current files */
1742 /* XXX: handle correctly stab (debug) info */
1743 static int tcc_load_object_file(TCCState *s1,
1744 int fd, unsigned long file_offset)
1746 Elf32_Ehdr ehdr;
1747 Elf32_Shdr *shdr, *sh;
1748 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1749 unsigned char *strsec, *strtab;
1750 int *old_to_new_syms;
1751 char *sh_name, *name;
1752 SectionMergeInfo *sm_table, *sm;
1753 Elf32_Sym *sym, *symtab;
1754 Elf32_Rel *rel, *rel_end;
1755 Section *s;
1757 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1758 goto fail1;
1759 if (ehdr.e_ident[0] != ELFMAG0 ||
1760 ehdr.e_ident[1] != ELFMAG1 ||
1761 ehdr.e_ident[2] != ELFMAG2 ||
1762 ehdr.e_ident[3] != ELFMAG3)
1763 goto fail1;
1764 /* test if object file */
1765 if (ehdr.e_type != ET_REL)
1766 goto fail1;
1767 /* test CPU specific stuff */
1768 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1769 ehdr.e_machine != EM_TCC_TARGET) {
1770 fail1:
1771 error_noabort("invalid object file");
1772 return -1;
1774 /* read sections */
1775 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1776 sizeof(Elf32_Shdr) * ehdr.e_shnum);
1777 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1779 /* load section names */
1780 sh = &shdr[ehdr.e_shstrndx];
1781 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1783 /* load symtab and strtab */
1784 old_to_new_syms = NULL;
1785 symtab = NULL;
1786 strtab = NULL;
1787 nb_syms = 0;
1788 for(i = 1; i < ehdr.e_shnum; i++) {
1789 sh = &shdr[i];
1790 if (sh->sh_type == SHT_SYMTAB) {
1791 if (symtab) {
1792 error_noabort("object must contain only one symtab");
1793 fail:
1794 ret = -1;
1795 goto the_end;
1797 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1798 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1799 sm_table[i].s = symtab_section;
1801 /* now load strtab */
1802 sh = &shdr[sh->sh_link];
1803 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1807 /* now examine each section and try to merge its content with the
1808 ones in memory */
1809 for(i = 1; i < ehdr.e_shnum; i++) {
1810 /* no need to examine section name strtab */
1811 if (i == ehdr.e_shstrndx)
1812 continue;
1813 sh = &shdr[i];
1814 sh_name = strsec + sh->sh_name;
1815 /* ignore sections types we do not handle */
1816 if (sh->sh_type != SHT_PROGBITS &&
1817 sh->sh_type != SHT_REL &&
1818 sh->sh_type != SHT_NOBITS)
1819 continue;
1820 if (sh->sh_addralign < 1)
1821 sh->sh_addralign = 1;
1822 /* find corresponding section, if any */
1823 for(j = 1; j < s1->nb_sections;j++) {
1824 s = s1->sections[j];
1825 if (!strcmp(s->name, sh_name)) {
1826 if (!strncmp(sh_name, ".gnu.linkonce",
1827 sizeof(".gnu.linkonce") - 1)) {
1828 /* if a 'linkonce' section is already present, we
1829 do not add it again. It is a little tricky as
1830 symbols can still be defined in
1831 it. */
1832 sm_table[i].link_once = 1;
1833 goto next;
1834 } else {
1835 goto found;
1839 /* not found: create new section */
1840 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1841 /* take as much info as possible from the section. sh_link and
1842 sh_info will be updated later */
1843 s->sh_addralign = sh->sh_addralign;
1844 s->sh_entsize = sh->sh_entsize;
1845 sm_table[i].new_section = 1;
1846 found:
1847 if (sh->sh_type != s->sh_type) {
1848 error_noabort("invalid section type");
1849 goto fail;
1852 /* align start of section */
1853 offset = s->data_offset;
1854 size = sh->sh_addralign - 1;
1855 offset = (offset + size) & ~size;
1856 if (sh->sh_addralign > s->sh_addralign)
1857 s->sh_addralign = sh->sh_addralign;
1858 s->data_offset = offset;
1859 sm_table[i].offset = offset;
1860 sm_table[i].s = s;
1861 /* concatenate sections */
1862 size = sh->sh_size;
1863 if (sh->sh_type != SHT_NOBITS) {
1864 unsigned char *ptr;
1865 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1866 ptr = section_ptr_add(s, size);
1867 read(fd, ptr, size);
1868 } else {
1869 s->data_offset += size;
1871 next: ;
1874 /* second short pass to update sh_link and sh_info fields of new
1875 sections */
1876 sm = sm_table;
1877 for(i = 1; i < ehdr.e_shnum; i++) {
1878 s = sm_table[i].s;
1879 if (!s || !sm_table[i].new_section)
1880 continue;
1881 sh = &shdr[i];
1882 if (sh->sh_link > 0)
1883 s->link = sm_table[sh->sh_link].s;
1884 if (sh->sh_type == SHT_REL) {
1885 s->sh_info = sm_table[sh->sh_info].s->sh_num;
1886 /* update backward link */
1887 s1->sections[s->sh_info]->reloc = s;
1891 /* resolve symbols */
1892 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
1894 sym = symtab + 1;
1895 for(i = 1; i < nb_syms; i++, sym++) {
1896 if (sym->st_shndx != SHN_UNDEF &&
1897 sym->st_shndx < SHN_LORESERVE) {
1898 sm = &sm_table[sym->st_shndx];
1899 if (sm->link_once) {
1900 /* if a symbol is in a link once section, we use the
1901 already defined symbol. It is very important to get
1902 correct relocations */
1903 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1904 name = strtab + sym->st_name;
1905 sym_index = find_elf_sym(symtab_section, name);
1906 if (sym_index)
1907 old_to_new_syms[i] = sym_index;
1909 continue;
1911 /* if no corresponding section added, no need to add symbol */
1912 if (!sm->s)
1913 continue;
1914 /* convert section number */
1915 sym->st_shndx = sm->s->sh_num;
1916 /* offset value */
1917 sym->st_value += sm->offset;
1919 /* add symbol */
1920 name = strtab + sym->st_name;
1921 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
1922 sym->st_info, sym->st_shndx, name);
1923 old_to_new_syms[i] = sym_index;
1926 /* third pass to patch relocation entries */
1927 for(i = 1; i < ehdr.e_shnum; i++) {
1928 s = sm_table[i].s;
1929 if (!s)
1930 continue;
1931 sh = &shdr[i];
1932 offset = sm_table[i].offset;
1933 switch(s->sh_type) {
1934 case SHT_REL:
1935 /* take relocation offset information */
1936 offseti = sm_table[sh->sh_info].offset;
1937 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
1938 for(rel = (Elf32_Rel *)(s->data + offset);
1939 rel < rel_end;
1940 rel++) {
1941 int type;
1942 unsigned sym_index;
1943 /* convert symbol index */
1944 type = ELF32_R_TYPE(rel->r_info);
1945 sym_index = ELF32_R_SYM(rel->r_info);
1946 /* NOTE: only one symtab assumed */
1947 if (sym_index >= nb_syms)
1948 goto invalid_reloc;
1949 sym_index = old_to_new_syms[sym_index];
1950 if (!sym_index) {
1951 invalid_reloc:
1952 error_noabort("Invalid relocation entry");
1953 goto fail;
1955 rel->r_info = ELF32_R_INFO(sym_index, type);
1956 /* offset the relocation offset */
1957 rel->r_offset += offseti;
1959 break;
1960 default:
1961 break;
1965 ret = 0;
1966 the_end:
1967 tcc_free(symtab);
1968 tcc_free(strtab);
1969 tcc_free(old_to_new_syms);
1970 tcc_free(sm_table);
1971 tcc_free(strsec);
1972 tcc_free(shdr);
1973 return ret;
1976 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1978 typedef struct ArchiveHeader {
1979 char ar_name[16]; /* name of this member */
1980 char ar_date[12]; /* file mtime */
1981 char ar_uid[6]; /* owner uid; printed as decimal */
1982 char ar_gid[6]; /* owner gid; printed as decimal */
1983 char ar_mode[8]; /* file mode, printed as octal */
1984 char ar_size[10]; /* file size, printed as decimal */
1985 char ar_fmag[2]; /* should contain ARFMAG */
1986 } ArchiveHeader;
1988 static int get_be32(const uint8_t *b)
1990 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
1993 /* load only the objects which resolve undefined symbols */
1994 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
1996 int i, bound, nsyms, sym_index, off, ret;
1997 uint8_t *data;
1998 const char *ar_names, *p;
1999 const uint8_t *ar_index;
2000 Elf32_Sym *sym;
2002 data = tcc_malloc(size);
2003 if (read(fd, data, size) != size)
2004 goto fail;
2005 nsyms = get_be32(data);
2006 ar_index = data + 4;
2007 ar_names = ar_index + nsyms * 4;
2009 do {
2010 bound = 0;
2011 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2012 sym_index = find_elf_sym(symtab_section, p);
2013 if(sym_index) {
2014 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
2015 if(sym->st_shndx == SHN_UNDEF) {
2016 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2017 #if 0
2018 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2019 #endif
2020 ++bound;
2021 lseek(fd, off, SEEK_SET);
2022 if(tcc_load_object_file(s1, fd, off) < 0) {
2023 fail:
2024 ret = -1;
2025 goto the_end;
2030 } while(bound);
2031 ret = 0;
2032 the_end:
2033 tcc_free(data);
2034 return ret;
2037 /* load a '.a' file */
2038 static int tcc_load_archive(TCCState *s1, int fd)
2040 ArchiveHeader hdr;
2041 char ar_size[11];
2042 char ar_name[17];
2043 char magic[8];
2044 int size, len, i;
2045 unsigned long file_offset;
2047 /* skip magic which was already checked */
2048 read(fd, magic, sizeof(magic));
2050 for(;;) {
2051 len = read(fd, &hdr, sizeof(hdr));
2052 if (len == 0)
2053 break;
2054 if (len != sizeof(hdr)) {
2055 error_noabort("invalid archive");
2056 return -1;
2058 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2059 ar_size[sizeof(hdr.ar_size)] = '\0';
2060 size = strtol(ar_size, NULL, 0);
2061 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2062 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2063 if (ar_name[i] != ' ')
2064 break;
2066 ar_name[i + 1] = '\0';
2067 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2068 file_offset = lseek(fd, 0, SEEK_CUR);
2069 /* align to even */
2070 size = (size + 1) & ~1;
2071 if (!strcmp(ar_name, "/")) {
2072 /* coff symbol table : we handle it */
2073 if(s1->alacarte_link)
2074 return tcc_load_alacarte(s1, fd, size);
2075 } else if (!strcmp(ar_name, "//") ||
2076 !strcmp(ar_name, "__.SYMDEF") ||
2077 !strcmp(ar_name, "__.SYMDEF/") ||
2078 !strcmp(ar_name, "ARFILENAMES/")) {
2079 /* skip symbol table or archive names */
2080 } else {
2081 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2082 return -1;
2084 lseek(fd, file_offset + size, SEEK_SET);
2086 return 0;
2089 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2090 is referenced by the user (so it should be added as DT_NEEDED in
2091 the generated ELF file) */
2092 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2094 Elf32_Ehdr ehdr;
2095 Elf32_Shdr *shdr, *sh, *sh1;
2096 int i, nb_syms, nb_dts, sym_bind, ret;
2097 Elf32_Sym *sym, *dynsym;
2098 Elf32_Dyn *dt, *dynamic;
2099 unsigned char *dynstr;
2100 const char *name, *soname, *p;
2101 DLLReference *dllref;
2103 read(fd, &ehdr, sizeof(ehdr));
2105 /* test CPU specific stuff */
2106 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2107 ehdr.e_machine != EM_TCC_TARGET) {
2108 error_noabort("bad architecture");
2109 return -1;
2112 /* read sections */
2113 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
2115 /* load dynamic section and dynamic symbols */
2116 nb_syms = 0;
2117 nb_dts = 0;
2118 dynamic = NULL;
2119 dynsym = NULL; /* avoid warning */
2120 dynstr = NULL; /* avoid warning */
2121 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2122 switch(sh->sh_type) {
2123 case SHT_DYNAMIC:
2124 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
2125 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2126 break;
2127 case SHT_DYNSYM:
2128 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
2129 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2130 sh1 = &shdr[sh->sh_link];
2131 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2132 break;
2133 default:
2134 break;
2138 /* compute the real library name */
2139 soname = filename;
2140 p = strrchr(soname, '/');
2141 if (p)
2142 soname = p + 1;
2144 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2145 if (dt->d_tag == DT_SONAME) {
2146 soname = dynstr + dt->d_un.d_val;
2150 /* if the dll is already loaded, do not load it */
2151 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2152 dllref = s1->loaded_dlls[i];
2153 if (!strcmp(soname, dllref->name)) {
2154 /* but update level if needed */
2155 if (level < dllref->level)
2156 dllref->level = level;
2157 ret = 0;
2158 goto the_end;
2162 // printf("loading dll '%s'\n", soname);
2164 /* add the dll and its level */
2165 dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
2166 dllref->level = level;
2167 strcpy(dllref->name, soname);
2168 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2170 /* add dynamic symbols in dynsym_section */
2171 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2172 sym_bind = ELF32_ST_BIND(sym->st_info);
2173 if (sym_bind == STB_LOCAL)
2174 continue;
2175 name = dynstr + sym->st_name;
2176 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2177 sym->st_info, sym->st_shndx, name);
2180 /* load all referenced DLLs */
2181 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2182 switch(dt->d_tag) {
2183 case DT_NEEDED:
2184 name = dynstr + dt->d_un.d_val;
2185 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2186 dllref = s1->loaded_dlls[i];
2187 if (!strcmp(name, dllref->name))
2188 goto already_loaded;
2190 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2191 error_noabort("referenced dll '%s' not found", name);
2192 ret = -1;
2193 goto the_end;
2195 already_loaded:
2196 break;
2199 ret = 0;
2200 the_end:
2201 tcc_free(dynstr);
2202 tcc_free(dynsym);
2203 tcc_free(dynamic);
2204 tcc_free(shdr);
2205 return ret;
2208 #define LD_TOK_NAME 256
2209 #define LD_TOK_EOF (-1)
2211 /* return next ld script token */
2212 static int ld_next(TCCState *s1, char *name, int name_size)
2214 int c;
2215 char *q;
2217 redo:
2218 switch(ch) {
2219 case ' ':
2220 case '\t':
2221 case '\f':
2222 case '\v':
2223 case '\r':
2224 case '\n':
2225 inp();
2226 goto redo;
2227 case '/':
2228 minp();
2229 if (ch == '*') {
2230 file->buf_ptr = parse_comment(file->buf_ptr);
2231 ch = file->buf_ptr[0];
2232 goto redo;
2233 } else {
2234 q = name;
2235 *q++ = '/';
2236 goto parse_name;
2238 break;
2239 case 'a' ... 'z':
2240 case 'A' ... 'Z':
2241 case '_':
2242 case '\\':
2243 case '.':
2244 case '$':
2245 case '~':
2246 q = name;
2247 parse_name:
2248 for(;;) {
2249 if (!((ch >= 'a' && ch <= 'z') ||
2250 (ch >= 'A' && ch <= 'Z') ||
2251 (ch >= '0' && ch <= '9') ||
2252 strchr("/.-_+=$:\\,~", ch)))
2253 break;
2254 if ((q - name) < name_size - 1) {
2255 *q++ = ch;
2257 minp();
2259 *q = '\0';
2260 c = LD_TOK_NAME;
2261 break;
2262 case CH_EOF:
2263 c = LD_TOK_EOF;
2264 break;
2265 default:
2266 c = ch;
2267 inp();
2268 break;
2270 #if 0
2271 printf("tok=%c %d\n", c, c);
2272 if (c == LD_TOK_NAME)
2273 printf(" name=%s\n", name);
2274 #endif
2275 return c;
2278 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2279 files */
2280 static int tcc_load_ldscript(TCCState *s1)
2282 char cmd[64];
2283 char filename[1024];
2284 int t;
2286 ch = file->buf_ptr[0];
2287 ch = handle_eob();
2288 for(;;) {
2289 t = ld_next(s1, cmd, sizeof(cmd));
2290 if (t == LD_TOK_EOF)
2291 return 0;
2292 else if (t != LD_TOK_NAME)
2293 return -1;
2294 if (!strcmp(cmd, "INPUT") ||
2295 !strcmp(cmd, "GROUP")) {
2296 t = ld_next(s1, cmd, sizeof(cmd));
2297 if (t != '(')
2298 expect("(");
2299 t = ld_next(s1, filename, sizeof(filename));
2300 for(;;) {
2301 if (t == LD_TOK_EOF) {
2302 error_noabort("unexpected end of file");
2303 return -1;
2304 } else if (t == ')') {
2305 break;
2306 } else if (t != LD_TOK_NAME) {
2307 error_noabort("filename expected");
2308 return -1;
2310 tcc_add_file(s1, filename);
2311 t = ld_next(s1, filename, sizeof(filename));
2312 if (t == ',') {
2313 t = ld_next(s1, filename, sizeof(filename));
2316 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2317 !strcmp(cmd, "TARGET")) {
2318 /* ignore some commands */
2319 t = ld_next(s1, cmd, sizeof(cmd));
2320 if (t != '(')
2321 expect("(");
2322 for(;;) {
2323 t = ld_next(s1, filename, sizeof(filename));
2324 if (t == LD_TOK_EOF) {
2325 error_noabort("unexpected end of file");
2326 return -1;
2327 } else if (t == ')') {
2328 break;
2331 } else {
2332 return -1;
2335 return 0;