removed warnings
[tinycc.git] / tccelf.c
blob6ba3bf2a96435a09797921087ca61cc3bfdade9a
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;
452 unsigned char *ptr;
453 unsigned long val, addr;
454 #if defined(TCC_TARGET_I386)
455 int esym_index;
456 #endif
458 sr = s->reloc;
459 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
460 qrel = (Elf32_Rel *)sr->data;
461 for(rel = qrel;
462 rel < rel_end;
463 rel++) {
464 ptr = s->data + rel->r_offset;
466 sym_index = ELF32_R_SYM(rel->r_info);
467 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
468 val = sym->st_value;
469 type = ELF32_R_TYPE(rel->r_info);
470 addr = s->sh_addr + rel->r_offset;
472 /* CPU specific */
473 switch(type) {
474 #if defined(TCC_TARGET_I386)
475 case R_386_32:
476 if (s1->output_type == TCC_OUTPUT_DLL) {
477 esym_index = s1->symtab_to_dynsym[sym_index];
478 qrel->r_offset = rel->r_offset;
479 if (esym_index) {
480 qrel->r_info = ELF32_R_INFO(esym_index, R_386_32);
481 qrel++;
482 break;
483 } else {
484 qrel->r_info = ELF32_R_INFO(0, R_386_RELATIVE);
485 qrel++;
488 *(int *)ptr += val;
489 break;
490 case R_386_PC32:
491 if (s1->output_type == TCC_OUTPUT_DLL) {
492 /* DLL relocation */
493 esym_index = s1->symtab_to_dynsym[sym_index];
494 if (esym_index) {
495 qrel->r_offset = rel->r_offset;
496 qrel->r_info = ELF32_R_INFO(esym_index, R_386_PC32);
497 qrel++;
498 break;
501 *(int *)ptr += val - addr;
502 break;
503 case R_386_PLT32:
504 *(int *)ptr += val - addr;
505 break;
506 case R_386_GLOB_DAT:
507 case R_386_JMP_SLOT:
508 *(int *)ptr = val;
509 break;
510 case R_386_GOTPC:
511 *(int *)ptr += s1->got->sh_addr - addr;
512 break;
513 case R_386_GOTOFF:
514 *(int *)ptr += val - s1->got->sh_addr;
515 break;
516 case R_386_GOT32:
517 /* we load the got offset */
518 *(int *)ptr += s1->got_offsets[sym_index];
519 break;
520 #elif defined(TCC_TARGET_ARM)
521 case R_ARM_PC24:
522 case R_ARM_PLT32:
524 int x;
525 x = (*(int *)ptr)&0xffffff;
526 (*(int *)ptr) &= 0xff000000;
527 if (x & 0x800000)
528 x -= 0x1000000;
529 x *= 4;
530 x += val - addr;
531 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
532 error("can't relocate value at %x",addr);
533 x >>= 2;
534 x &= 0xffffff;
535 (*(int *)ptr) |= x;
537 break;
538 case R_ARM_ABS32:
539 *(int *)ptr += val;
540 break;
541 case R_ARM_GOTPC:
542 *(int *)ptr += s1->got->sh_addr - addr;
543 break;
544 case R_ARM_GOT32:
545 /* we load the got offset */
546 *(int *)ptr += s1->got_offsets[sym_index];
547 break;
548 case R_ARM_COPY:
549 break;
550 default:
551 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
552 type,addr,(unsigned int )ptr,val);
553 break;
554 #elif defined(TCC_TARGET_C67)
555 case R_C60_32:
556 *(int *)ptr += val;
557 break;
558 case R_C60LO16:
560 uint32_t orig;
562 /* put the low 16 bits of the absolute address */
563 // add to what is already there
565 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
566 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
568 //patch both at once - assumes always in pairs Low - High
570 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
571 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
573 break;
574 case R_C60HI16:
575 break;
576 default:
577 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
578 type,addr,(unsigned int )ptr,val);
579 break;
580 #else
581 #error unsupported processor
582 #endif
585 /* if the relocation is allocated, we change its symbol table */
586 if (sr->sh_flags & SHF_ALLOC)
587 sr->link = s1->dynsym;
590 /* relocate relocation table in 'sr' */
591 static void relocate_rel(TCCState *s1, Section *sr)
593 Section *s;
594 Elf32_Rel *rel, *rel_end;
596 s = s1->sections[sr->sh_info];
597 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
598 for(rel = (Elf32_Rel *)sr->data;
599 rel < rel_end;
600 rel++) {
601 rel->r_offset += s->sh_addr;
605 /* count the number of dynamic relocations so that we can reserve
606 their space */
607 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
609 Elf32_Rel *rel, *rel_end;
610 int sym_index, esym_index, type, count;
612 count = 0;
613 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
614 for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) {
615 sym_index = ELF32_R_SYM(rel->r_info);
616 type = ELF32_R_TYPE(rel->r_info);
617 switch(type) {
618 case R_386_32:
619 count++;
620 break;
621 case R_386_PC32:
622 esym_index = s1->symtab_to_dynsym[sym_index];
623 if (esym_index)
624 count++;
625 break;
626 default:
627 break;
630 if (count) {
631 /* allocate the section */
632 sr->sh_flags |= SHF_ALLOC;
633 sr->sh_size = count * sizeof(Elf32_Rel);
635 return count;
638 static void put_got_offset(TCCState *s1, int index, unsigned long val)
640 int n;
641 unsigned long *tab;
643 if (index >= s1->nb_got_offsets) {
644 /* find immediately bigger power of 2 and reallocate array */
645 n = 1;
646 while (index >= n)
647 n *= 2;
648 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
649 if (!tab)
650 error("memory full");
651 s1->got_offsets = tab;
652 memset(s1->got_offsets + s1->nb_got_offsets, 0,
653 (n - s1->nb_got_offsets) * sizeof(unsigned long));
654 s1->nb_got_offsets = n;
656 s1->got_offsets[index] = val;
659 /* XXX: suppress that */
660 static void put32(unsigned char *p, uint32_t val)
662 p[0] = val;
663 p[1] = val >> 8;
664 p[2] = val >> 16;
665 p[3] = val >> 24;
668 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM)
669 static uint32_t get32(unsigned char *p)
671 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
673 #endif
675 static void build_got(TCCState *s1)
677 unsigned char *ptr;
679 /* if no got, then create it */
680 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
681 s1->got->sh_entsize = 4;
682 add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
683 s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
684 ptr = section_ptr_add(s1->got, 3 * sizeof(int));
685 /* keep space for _DYNAMIC pointer, if present */
686 put32(ptr, 0);
687 /* two dummy got entries */
688 put32(ptr + 4, 0);
689 put32(ptr + 8, 0);
692 /* put a got entry corresponding to a symbol in symtab_section. 'size'
693 and 'info' can be modifed if more precise info comes from the DLL */
694 static void put_got_entry(TCCState *s1,
695 int reloc_type, unsigned long size, int info,
696 int sym_index)
698 int index;
699 const char *name;
700 Elf32_Sym *sym;
701 unsigned long offset;
702 int *ptr;
704 if (!s1->got)
705 build_got(s1);
707 /* if a got entry already exists for that symbol, no need to add one */
708 if (sym_index < s1->nb_got_offsets &&
709 s1->got_offsets[sym_index] != 0)
710 return;
712 put_got_offset(s1, sym_index, s1->got->data_offset);
714 if (s1->dynsym) {
715 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
716 name = symtab_section->link->data + sym->st_name;
717 offset = sym->st_value;
718 #ifdef TCC_TARGET_I386
719 if (reloc_type == R_386_JMP_SLOT) {
720 Section *plt;
721 uint8_t *p;
722 int modrm;
724 /* if we build a DLL, we add a %ebx offset */
725 if (s1->output_type == TCC_OUTPUT_DLL)
726 modrm = 0xa3;
727 else
728 modrm = 0x25;
730 /* add a PLT entry */
731 plt = s1->plt;
732 if (plt->data_offset == 0) {
733 /* first plt entry */
734 p = section_ptr_add(plt, 16);
735 p[0] = 0xff; /* pushl got + 4 */
736 p[1] = modrm + 0x10;
737 put32(p + 2, 4);
738 p[6] = 0xff; /* jmp *(got + 8) */
739 p[7] = modrm;
740 put32(p + 8, 8);
743 p = section_ptr_add(plt, 16);
744 p[0] = 0xff; /* jmp *(got + x) */
745 p[1] = modrm;
746 put32(p + 2, s1->got->data_offset);
747 p[6] = 0x68; /* push $xxx */
748 put32(p + 7, (plt->data_offset - 32) >> 1);
749 p[11] = 0xe9; /* jmp plt_start */
750 put32(p + 12, -(plt->data_offset));
752 /* the symbol is modified so that it will be relocated to
753 the PLT */
754 if (s1->output_type == TCC_OUTPUT_EXE)
755 offset = plt->data_offset - 16;
757 #elif defined(TCC_TARGET_ARM)
758 if (reloc_type == R_ARM_JUMP_SLOT) {
759 Section *plt;
760 uint8_t *p;
762 /* if we build a DLL, we add a %ebx offset */
763 if (s1->output_type == TCC_OUTPUT_DLL)
764 error("DLLs unimplemented!");
766 /* add a PLT entry */
767 plt = s1->plt;
768 if (plt->data_offset == 0) {
769 /* first plt entry */
770 p = section_ptr_add(plt, 16);
771 put32(p , 0xe52de004);
772 put32(p + 4, 0xe59fe010);
773 put32(p + 8, 0xe08fe00e);
774 put32(p + 12, 0xe5bef008);
777 p = section_ptr_add(plt, 16);
778 put32(p , 0xe59fc004);
779 put32(p+4, 0xe08fc00c);
780 put32(p+8, 0xe59cf000);
781 put32(p+12, s1->got->data_offset);
783 /* the symbol is modified so that it will be relocated to
784 the PLT */
785 if (s1->output_type == TCC_OUTPUT_EXE)
786 offset = plt->data_offset - 16;
788 #elif defined(TCC_TARGET_C67)
789 error("C67 got not implemented");
790 #else
791 #error unsupported CPU
792 #endif
793 index = put_elf_sym(s1->dynsym, offset,
794 size, info, 0, sym->st_shndx, name);
795 /* put a got entry */
796 put_elf_reloc(s1->dynsym, s1->got,
797 s1->got->data_offset,
798 reloc_type, index);
800 ptr = section_ptr_add(s1->got, sizeof(int));
801 *ptr = 0;
804 /* build GOT and PLT entries */
805 static void build_got_entries(TCCState *s1)
807 Section *s, *symtab;
808 Elf32_Rel *rel, *rel_end;
809 Elf32_Sym *sym;
810 int i, type, reloc_type, sym_index;
812 for(i = 1; i < s1->nb_sections; i++) {
813 s = s1->sections[i];
814 if (s->sh_type != SHT_REL)
815 continue;
816 /* no need to handle got relocations */
817 if (s->link != symtab_section)
818 continue;
819 symtab = s->link;
820 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
821 for(rel = (Elf32_Rel *)s->data;
822 rel < rel_end;
823 rel++) {
824 type = ELF32_R_TYPE(rel->r_info);
825 switch(type) {
826 #if defined(TCC_TARGET_I386)
827 case R_386_GOT32:
828 case R_386_GOTOFF:
829 case R_386_GOTPC:
830 case R_386_PLT32:
831 if (!s1->got)
832 build_got(s1);
833 if (type == R_386_GOT32 || type == R_386_PLT32) {
834 sym_index = ELF32_R_SYM(rel->r_info);
835 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
836 /* look at the symbol got offset. If none, then add one */
837 if (type == R_386_GOT32)
838 reloc_type = R_386_GLOB_DAT;
839 else
840 reloc_type = R_386_JMP_SLOT;
841 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
842 sym_index);
844 break;
845 #elif defined(TCC_TARGET_ARM)
846 case R_ARM_GOT32:
847 case R_ARM_GOTOFF:
848 case R_ARM_GOTPC:
849 case R_ARM_PLT32:
850 if (!s1->got)
851 build_got(s1);
852 if (type == R_ARM_GOT32 || type == R_ARM_PLT32) {
853 sym_index = ELF32_R_SYM(rel->r_info);
854 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
855 /* look at the symbol got offset. If none, then add one */
856 if (type == R_ARM_GOT32)
857 reloc_type = R_ARM_GLOB_DAT;
858 else
859 reloc_type = R_ARM_JUMP_SLOT;
860 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
861 sym_index);
863 break;
864 #elif defined(TCC_TARGET_C67)
865 case R_C60_GOT32:
866 case R_C60_GOTOFF:
867 case R_C60_GOTPC:
868 case R_C60_PLT32:
869 if (!s1->got)
870 build_got(s1);
871 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
872 sym_index = ELF32_R_SYM(rel->r_info);
873 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
874 /* look at the symbol got offset. If none, then add one */
875 if (type == R_C60_GOT32)
876 reloc_type = R_C60_GLOB_DAT;
877 else
878 reloc_type = R_C60_JMP_SLOT;
879 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
880 sym_index);
882 break;
883 #else
884 #error unsupported CPU
885 #endif
886 default:
887 break;
893 static Section *new_symtab(TCCState *s1,
894 const char *symtab_name, int sh_type, int sh_flags,
895 const char *strtab_name,
896 const char *hash_name, int hash_sh_flags)
898 Section *symtab, *strtab, *hash;
899 int *ptr, nb_buckets;
901 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
902 symtab->sh_entsize = sizeof(Elf32_Sym);
903 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
904 put_elf_str(strtab, "");
905 symtab->link = strtab;
906 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
908 nb_buckets = 1;
910 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
911 hash->sh_entsize = sizeof(int);
912 symtab->hash = hash;
913 hash->link = symtab;
915 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
916 ptr[0] = nb_buckets;
917 ptr[1] = 1;
918 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
919 return symtab;
922 /* put dynamic tag */
923 static void put_dt(Section *dynamic, int dt, unsigned long val)
925 Elf32_Dyn *dyn;
926 dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
927 dyn->d_tag = dt;
928 dyn->d_un.d_val = val;
931 static void add_init_array_defines(TCCState *s1, const char *section_name)
933 Section *s;
934 long end_offset;
935 char sym_start[1024];
936 char sym_end[1024];
938 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
939 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
941 s = find_section(s1, section_name);
942 if (!s) {
943 end_offset = 0;
944 s = data_section;
945 } else {
946 end_offset = s->data_offset;
949 add_elf_sym(symtab_section,
950 0, 0,
951 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
952 s->sh_num, sym_start);
953 add_elf_sym(symtab_section,
954 end_offset, 0,
955 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
956 s->sh_num, sym_end);
959 /* add tcc runtime libraries */
960 static void tcc_add_runtime(TCCState *s1)
962 char buf[1024];
964 #ifdef CONFIG_TCC_BCHECK
965 if (do_bounds_check) {
966 unsigned long *ptr;
967 Section *init_section;
968 unsigned char *pinit;
969 int sym_index;
971 /* XXX: add an object file to do that */
972 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
973 *ptr = 0;
974 add_elf_sym(symtab_section, 0, 0,
975 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
976 bounds_section->sh_num, "__bounds_start");
977 /* add bound check code */
978 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
979 tcc_add_file(s1, buf);
980 #ifdef TCC_TARGET_I386
981 if (s1->output_type != TCC_OUTPUT_MEMORY) {
982 /* add 'call __bound_init()' in .init section */
983 init_section = find_section(s1, ".init");
984 pinit = section_ptr_add(init_section, 5);
985 pinit[0] = 0xe8;
986 put32(pinit + 1, -4);
987 sym_index = find_elf_sym(symtab_section, "__bound_init");
988 put_elf_reloc(symtab_section, init_section,
989 init_section->data_offset - 4, R_386_PC32, sym_index);
991 #endif
993 #endif
994 /* add libc */
995 if (!s1->nostdlib) {
996 tcc_add_library(s1, "c");
998 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
999 tcc_add_file(s1, buf);
1001 /* add crt end if not memory output */
1002 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
1003 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1007 /* add various standard linker symbols (must be done after the
1008 sections are filled (for example after allocating common
1009 symbols)) */
1010 static void tcc_add_linker_symbols(TCCState *s1)
1012 char buf[1024];
1013 int i;
1014 Section *s;
1016 add_elf_sym(symtab_section,
1017 text_section->data_offset, 0,
1018 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
1019 text_section->sh_num, "_etext");
1020 add_elf_sym(symtab_section,
1021 data_section->data_offset, 0,
1022 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
1023 data_section->sh_num, "_edata");
1024 add_elf_sym(symtab_section,
1025 bss_section->data_offset, 0,
1026 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
1027 bss_section->sh_num, "_end");
1028 /* horrible new standard ldscript defines */
1029 add_init_array_defines(s1, ".preinit_array");
1030 add_init_array_defines(s1, ".init_array");
1031 add_init_array_defines(s1, ".fini_array");
1033 /* add start and stop symbols for sections whose name can be
1034 expressed in C */
1035 for(i = 1; i < s1->nb_sections; i++) {
1036 s = s1->sections[i];
1037 if (s->sh_type == SHT_PROGBITS &&
1038 (s->sh_flags & SHF_ALLOC)) {
1039 const char *p;
1040 int ch;
1042 /* check if section name can be expressed in C */
1043 p = s->name;
1044 for(;;) {
1045 ch = *p;
1046 if (!ch)
1047 break;
1048 if (!isid(ch) && !isnum(ch))
1049 goto next_sec;
1050 p++;
1052 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1053 add_elf_sym(symtab_section,
1054 0, 0,
1055 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
1056 s->sh_num, buf);
1057 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1058 add_elf_sym(symtab_section,
1059 s->data_offset, 0,
1060 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
1061 s->sh_num, buf);
1063 next_sec: ;
1067 /* name of ELF interpreter */
1068 #ifdef __FreeBSD__
1069 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1070 #else
1071 static char elf_interp[] = "/lib/ld-linux.so.2";
1072 #endif
1074 static void tcc_output_binary(TCCState *s1, FILE *f,
1075 const int *section_order)
1077 Section *s;
1078 int i, offset, size;
1080 offset = 0;
1081 for(i=1;i<s1->nb_sections;i++) {
1082 s = s1->sections[section_order[i]];
1083 if (s->sh_type != SHT_NOBITS &&
1084 (s->sh_flags & SHF_ALLOC)) {
1085 while (offset < s->sh_offset) {
1086 fputc(0, f);
1087 offset++;
1089 size = s->sh_size;
1090 fwrite(s->data, 1, size, f);
1091 offset += size;
1096 /* output an ELF file */
1097 /* XXX: suppress unneeded sections */
1098 int tcc_output_file(TCCState *s1, const char *filename)
1100 Elf32_Ehdr ehdr;
1101 FILE *f;
1102 int fd, mode, ret;
1103 int *section_order;
1104 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1105 unsigned long addr;
1106 Section *strsec, *s;
1107 Elf32_Shdr shdr, *sh;
1108 Elf32_Phdr *phdr, *ph;
1109 Section *interp, *dynamic, *dynstr;
1110 unsigned long saved_dynamic_data_offset;
1111 Elf32_Sym *sym;
1112 int type, file_type;
1113 unsigned long rel_addr, rel_size;
1115 file_type = s1->output_type;
1116 s1->nb_errors = 0;
1118 if (file_type != TCC_OUTPUT_OBJ) {
1119 tcc_add_runtime(s1);
1122 phdr = NULL;
1123 section_order = NULL;
1124 interp = NULL;
1125 dynamic = NULL;
1126 dynstr = NULL; /* avoid warning */
1127 saved_dynamic_data_offset = 0; /* avoid warning */
1129 if (file_type != TCC_OUTPUT_OBJ) {
1130 relocate_common_syms();
1132 tcc_add_linker_symbols(s1);
1134 if (!s1->static_link) {
1135 const char *name;
1136 int sym_index, index;
1137 Elf32_Sym *esym, *sym_end;
1139 if (file_type == TCC_OUTPUT_EXE) {
1140 char *ptr;
1141 /* add interpreter section only if executable */
1142 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1143 interp->sh_addralign = 1;
1144 ptr = section_ptr_add(interp, sizeof(elf_interp));
1145 strcpy(ptr, elf_interp);
1148 /* add dynamic symbol table */
1149 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1150 ".dynstr",
1151 ".hash", SHF_ALLOC);
1152 dynstr = s1->dynsym->link;
1154 /* add dynamic section */
1155 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1156 SHF_ALLOC | SHF_WRITE);
1157 dynamic->link = dynstr;
1158 dynamic->sh_entsize = sizeof(Elf32_Dyn);
1160 /* add PLT */
1161 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1162 SHF_ALLOC | SHF_EXECINSTR);
1163 s1->plt->sh_entsize = 4;
1165 build_got(s1);
1167 /* scan for undefined symbols and see if they are in the
1168 dynamic symbols. If a symbol STT_FUNC is found, then we
1169 add it in the PLT. If a symbol STT_OBJECT is found, we
1170 add it in the .bss section with a suitable relocation */
1171 sym_end = (Elf32_Sym *)(symtab_section->data +
1172 symtab_section->data_offset);
1173 if (file_type == TCC_OUTPUT_EXE) {
1174 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1175 sym < sym_end;
1176 sym++) {
1177 if (sym->st_shndx == SHN_UNDEF) {
1178 name = symtab_section->link->data + sym->st_name;
1179 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1180 if (sym_index) {
1181 esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
1182 type = ELF32_ST_TYPE(esym->st_info);
1183 if (type == STT_FUNC) {
1184 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1185 esym->st_info,
1186 sym - (Elf32_Sym *)symtab_section->data);
1187 } else if (type == STT_OBJECT) {
1188 unsigned long offset;
1189 offset = bss_section->data_offset;
1190 /* XXX: which alignment ? */
1191 offset = (offset + 16 - 1) & -16;
1192 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1193 esym->st_info, 0,
1194 bss_section->sh_num, name);
1195 put_elf_reloc(s1->dynsym, bss_section,
1196 offset, R_COPY, index);
1197 offset += esym->st_size;
1198 bss_section->data_offset = offset;
1200 } else {
1201 /* STB_WEAK undefined symbols are accepted */
1202 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1203 it */
1204 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
1205 !strcmp(name, "_fp_hw")) {
1206 } else {
1207 error_noabort("undefined symbol '%s'", name);
1210 } else if (s1->rdynamic &&
1211 ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1212 /* if -rdynamic option, then export all non
1213 local symbols */
1214 name = symtab_section->link->data + sym->st_name;
1215 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1216 sym->st_info, 0,
1217 sym->st_shndx, name);
1221 if (s1->nb_errors)
1222 goto fail;
1224 /* now look at unresolved dynamic symbols and export
1225 corresponding symbol */
1226 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
1227 s1->dynsymtab_section->data_offset);
1228 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
1229 esym < sym_end;
1230 esym++) {
1231 if (esym->st_shndx == SHN_UNDEF) {
1232 name = s1->dynsymtab_section->link->data + esym->st_name;
1233 sym_index = find_elf_sym(symtab_section, name);
1234 if (sym_index) {
1235 /* XXX: avoid adding a symbol if already
1236 present because of -rdynamic ? */
1237 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1238 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1239 sym->st_info, 0,
1240 sym->st_shndx, name);
1241 } else {
1242 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
1243 /* weak symbols can stay undefined */
1244 } else {
1245 warning("undefined dynamic symbol '%s'", name);
1250 } else {
1251 int nb_syms;
1252 /* shared library case : we simply export all the global symbols */
1253 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
1254 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1255 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1256 sym < sym_end;
1257 sym++) {
1258 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1259 name = symtab_section->link->data + sym->st_name;
1260 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1261 sym->st_info, 0,
1262 sym->st_shndx, name);
1263 s1->symtab_to_dynsym[sym -
1264 (Elf32_Sym *)symtab_section->data] =
1265 index;
1270 build_got_entries(s1);
1272 /* add a list of needed dlls */
1273 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1274 DLLReference *dllref = s1->loaded_dlls[i];
1275 if (dllref->level == 0)
1276 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1278 /* XXX: currently, since we do not handle PIC code, we
1279 must relocate the readonly segments */
1280 if (file_type == TCC_OUTPUT_DLL)
1281 put_dt(dynamic, DT_TEXTREL, 0);
1283 /* add necessary space for other entries */
1284 saved_dynamic_data_offset = dynamic->data_offset;
1285 dynamic->data_offset += 8 * 9;
1286 } else {
1287 /* still need to build got entries in case of static link */
1288 build_got_entries(s1);
1292 memset(&ehdr, 0, sizeof(ehdr));
1294 /* we add a section for symbols */
1295 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1296 put_elf_str(strsec, "");
1298 /* compute number of sections */
1299 shnum = s1->nb_sections;
1301 /* this array is used to reorder sections in the output file */
1302 section_order = tcc_malloc(sizeof(int) * shnum);
1303 section_order[0] = 0;
1304 sh_order_index = 1;
1306 /* compute number of program headers */
1307 switch(file_type) {
1308 default:
1309 case TCC_OUTPUT_OBJ:
1310 phnum = 0;
1311 break;
1312 case TCC_OUTPUT_EXE:
1313 if (!s1->static_link)
1314 phnum = 4;
1315 else
1316 phnum = 2;
1317 break;
1318 case TCC_OUTPUT_DLL:
1319 phnum = 3;
1320 break;
1323 /* allocate strings for section names and decide if an unallocated
1324 section should be output */
1325 /* NOTE: the strsec section comes last, so its size is also
1326 correct ! */
1327 for(i = 1; i < s1->nb_sections; i++) {
1328 s = s1->sections[i];
1329 s->sh_name = put_elf_str(strsec, s->name);
1330 /* when generating a DLL, we include relocations but we may
1331 patch them */
1332 if (file_type == TCC_OUTPUT_DLL &&
1333 s->sh_type == SHT_REL &&
1334 !(s->sh_flags & SHF_ALLOC)) {
1335 prepare_dynamic_rel(s1, s);
1336 } else if (do_debug ||
1337 file_type == TCC_OUTPUT_OBJ ||
1338 (s->sh_flags & SHF_ALLOC) ||
1339 i == (s1->nb_sections - 1)) {
1340 /* we output all sections if debug or object file */
1341 s->sh_size = s->data_offset;
1345 /* allocate program segment headers */
1346 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1348 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1349 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1350 } else {
1351 file_offset = 0;
1353 if (phnum > 0) {
1354 /* compute section to program header mapping */
1355 if (s1->has_text_addr) {
1356 int a_offset, p_offset;
1357 addr = s1->text_addr;
1358 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1359 ELF_PAGE_SIZE */
1360 a_offset = addr & (ELF_PAGE_SIZE - 1);
1361 p_offset = file_offset & (ELF_PAGE_SIZE - 1);
1362 if (a_offset < p_offset)
1363 a_offset += ELF_PAGE_SIZE;
1364 file_offset += (a_offset - p_offset);
1365 } else {
1366 if (file_type == TCC_OUTPUT_DLL)
1367 addr = 0;
1368 else
1369 addr = ELF_START_ADDR;
1370 /* compute address after headers */
1371 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1374 /* dynamic relocation table information, for .dynamic section */
1375 rel_size = 0;
1376 rel_addr = 0;
1378 /* leave one program header for the program interpreter */
1379 ph = &phdr[0];
1380 if (interp)
1381 ph++;
1383 for(j = 0; j < 2; j++) {
1384 ph->p_type = PT_LOAD;
1385 if (j == 0)
1386 ph->p_flags = PF_R | PF_X;
1387 else
1388 ph->p_flags = PF_R | PF_W;
1389 ph->p_align = ELF_PAGE_SIZE;
1391 /* we do the following ordering: interp, symbol tables,
1392 relocations, progbits, nobits */
1393 /* XXX: do faster and simpler sorting */
1394 for(k = 0; k < 5; k++) {
1395 for(i = 1; i < s1->nb_sections; i++) {
1396 s = s1->sections[i];
1397 /* compute if section should be included */
1398 if (j == 0) {
1399 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1400 SHF_ALLOC)
1401 continue;
1402 } else {
1403 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1404 (SHF_ALLOC | SHF_WRITE))
1405 continue;
1407 if (s == interp) {
1408 if (k != 0)
1409 continue;
1410 } else if (s->sh_type == SHT_DYNSYM ||
1411 s->sh_type == SHT_STRTAB ||
1412 s->sh_type == SHT_HASH) {
1413 if (k != 1)
1414 continue;
1415 } else if (s->sh_type == SHT_REL) {
1416 if (k != 2)
1417 continue;
1418 } else if (s->sh_type == SHT_NOBITS) {
1419 if (k != 4)
1420 continue;
1421 } else {
1422 if (k != 3)
1423 continue;
1425 section_order[sh_order_index++] = i;
1427 /* section matches: we align it and add its size */
1428 tmp = addr;
1429 addr = (addr + s->sh_addralign - 1) &
1430 ~(s->sh_addralign - 1);
1431 file_offset += addr - tmp;
1432 s->sh_offset = file_offset;
1433 s->sh_addr = addr;
1435 /* update program header infos */
1436 if (ph->p_offset == 0) {
1437 ph->p_offset = file_offset;
1438 ph->p_vaddr = addr;
1439 ph->p_paddr = ph->p_vaddr;
1441 /* update dynamic relocation infos */
1442 if (s->sh_type == SHT_REL) {
1443 if (rel_size == 0)
1444 rel_addr = addr;
1445 rel_size += s->sh_size;
1447 addr += s->sh_size;
1448 if (s->sh_type != SHT_NOBITS)
1449 file_offset += s->sh_size;
1452 ph->p_filesz = file_offset - ph->p_offset;
1453 ph->p_memsz = addr - ph->p_vaddr;
1454 ph++;
1455 if (j == 0) {
1456 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1457 /* if in the middle of a page, we duplicate the page in
1458 memory so that one copy is RX and the other is RW */
1459 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1460 addr += ELF_PAGE_SIZE;
1461 } else {
1462 addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
1463 file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
1464 ~(ELF_PAGE_SIZE - 1);
1469 /* if interpreter, then add corresponing program header */
1470 if (interp) {
1471 ph = &phdr[0];
1473 ph->p_type = PT_INTERP;
1474 ph->p_offset = interp->sh_offset;
1475 ph->p_vaddr = interp->sh_addr;
1476 ph->p_paddr = ph->p_vaddr;
1477 ph->p_filesz = interp->sh_size;
1478 ph->p_memsz = interp->sh_size;
1479 ph->p_flags = PF_R;
1480 ph->p_align = interp->sh_addralign;
1483 /* if dynamic section, then add corresponing program header */
1484 if (dynamic) {
1485 Elf32_Sym *sym_end;
1487 ph = &phdr[phnum - 1];
1489 ph->p_type = PT_DYNAMIC;
1490 ph->p_offset = dynamic->sh_offset;
1491 ph->p_vaddr = dynamic->sh_addr;
1492 ph->p_paddr = ph->p_vaddr;
1493 ph->p_filesz = dynamic->sh_size;
1494 ph->p_memsz = dynamic->sh_size;
1495 ph->p_flags = PF_R | PF_W;
1496 ph->p_align = dynamic->sh_addralign;
1498 /* put GOT dynamic section address */
1499 put32(s1->got->data, dynamic->sh_addr);
1501 /* relocate the PLT */
1502 if (file_type == TCC_OUTPUT_EXE) {
1503 uint8_t *p, *p_end;
1505 p = s1->plt->data;
1506 p_end = p + s1->plt->data_offset;
1507 if (p < p_end) {
1508 #if defined(TCC_TARGET_I386)
1509 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1510 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1511 p += 16;
1512 while (p < p_end) {
1513 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1514 p += 16;
1516 #elif defined(TCC_TARGET_ARM)
1517 int x;
1518 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1519 p +=16;
1520 while (p < p_end) {
1521 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1522 p += 16;
1524 #elif defined(TCC_TARGET_C67)
1525 /* XXX: TODO */
1526 #else
1527 #error unsupported CPU
1528 #endif
1532 /* relocate symbols in .dynsym */
1533 sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
1534 for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
1535 sym < sym_end;
1536 sym++) {
1537 if (sym->st_shndx == SHN_UNDEF) {
1538 /* relocate to the PLT if the symbol corresponds
1539 to a PLT entry */
1540 if (sym->st_value)
1541 sym->st_value += s1->plt->sh_addr;
1542 } else if (sym->st_shndx < SHN_LORESERVE) {
1543 /* do symbol relocation */
1544 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1548 /* put dynamic section entries */
1549 dynamic->data_offset = saved_dynamic_data_offset;
1550 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1551 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1552 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1553 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1554 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
1555 put_dt(dynamic, DT_REL, rel_addr);
1556 put_dt(dynamic, DT_RELSZ, rel_size);
1557 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
1558 put_dt(dynamic, DT_NULL, 0);
1561 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1562 ehdr.e_phnum = phnum;
1563 ehdr.e_phoff = sizeof(Elf32_Ehdr);
1566 /* all other sections come after */
1567 for(i = 1; i < s1->nb_sections; i++) {
1568 s = s1->sections[i];
1569 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1570 continue;
1571 section_order[sh_order_index++] = i;
1573 file_offset = (file_offset + s->sh_addralign - 1) &
1574 ~(s->sh_addralign - 1);
1575 s->sh_offset = file_offset;
1576 if (s->sh_type != SHT_NOBITS)
1577 file_offset += s->sh_size;
1580 /* if building executable or DLL, then relocate each section
1581 except the GOT which is already relocated */
1582 if (file_type != TCC_OUTPUT_OBJ) {
1583 relocate_syms(s1, 0);
1585 if (s1->nb_errors != 0) {
1586 fail:
1587 ret = -1;
1588 goto the_end;
1591 /* relocate sections */
1592 /* XXX: ignore sections with allocated relocations ? */
1593 for(i = 1; i < s1->nb_sections; i++) {
1594 s = s1->sections[i];
1595 if (s->reloc && s != s1->got)
1596 relocate_section(s1, s);
1599 /* relocate relocation entries if the relocation tables are
1600 allocated in the executable */
1601 for(i = 1; i < s1->nb_sections; i++) {
1602 s = s1->sections[i];
1603 if ((s->sh_flags & SHF_ALLOC) &&
1604 s->sh_type == SHT_REL) {
1605 relocate_rel(s1, s);
1609 /* get entry point address */
1610 if (file_type == TCC_OUTPUT_EXE)
1611 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
1612 else
1613 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1616 /* write elf file */
1617 if (file_type == TCC_OUTPUT_OBJ)
1618 mode = 0666;
1619 else
1620 mode = 0777;
1621 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1622 if (fd < 0) {
1623 error_noabort("could not write '%s'", filename);
1624 goto fail;
1626 f = fdopen(fd, "wb");
1628 #ifdef TCC_TARGET_COFF
1629 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1630 tcc_output_coff(s1, f);
1631 } else
1632 #endif
1633 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1634 sort_syms(s1, symtab_section);
1636 /* align to 4 */
1637 file_offset = (file_offset + 3) & -4;
1639 /* fill header */
1640 ehdr.e_ident[0] = ELFMAG0;
1641 ehdr.e_ident[1] = ELFMAG1;
1642 ehdr.e_ident[2] = ELFMAG2;
1643 ehdr.e_ident[3] = ELFMAG3;
1644 ehdr.e_ident[4] = ELFCLASS32;
1645 ehdr.e_ident[5] = ELFDATA2LSB;
1646 ehdr.e_ident[6] = EV_CURRENT;
1647 #ifdef __FreeBSD__
1648 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1649 #endif
1650 #ifdef TCC_TARGET_ARM
1651 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1652 #endif
1653 switch(file_type) {
1654 default:
1655 case TCC_OUTPUT_EXE:
1656 ehdr.e_type = ET_EXEC;
1657 break;
1658 case TCC_OUTPUT_DLL:
1659 ehdr.e_type = ET_DYN;
1660 break;
1661 case TCC_OUTPUT_OBJ:
1662 ehdr.e_type = ET_REL;
1663 break;
1665 ehdr.e_machine = EM_TCC_TARGET;
1666 ehdr.e_version = EV_CURRENT;
1667 ehdr.e_shoff = file_offset;
1668 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1669 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1670 ehdr.e_shnum = shnum;
1671 ehdr.e_shstrndx = shnum - 1;
1673 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1674 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1675 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1677 for(i=1;i<s1->nb_sections;i++) {
1678 s = s1->sections[section_order[i]];
1679 if (s->sh_type != SHT_NOBITS) {
1680 while (offset < s->sh_offset) {
1681 fputc(0, f);
1682 offset++;
1684 size = s->sh_size;
1685 fwrite(s->data, 1, size, f);
1686 offset += size;
1690 /* output section headers */
1691 while (offset < ehdr.e_shoff) {
1692 fputc(0, f);
1693 offset++;
1696 for(i=0;i<s1->nb_sections;i++) {
1697 sh = &shdr;
1698 memset(sh, 0, sizeof(Elf32_Shdr));
1699 s = s1->sections[i];
1700 if (s) {
1701 sh->sh_name = s->sh_name;
1702 sh->sh_type = s->sh_type;
1703 sh->sh_flags = s->sh_flags;
1704 sh->sh_entsize = s->sh_entsize;
1705 sh->sh_info = s->sh_info;
1706 if (s->link)
1707 sh->sh_link = s->link->sh_num;
1708 sh->sh_addralign = s->sh_addralign;
1709 sh->sh_addr = s->sh_addr;
1710 sh->sh_offset = s->sh_offset;
1711 sh->sh_size = s->sh_size;
1713 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1715 } else {
1716 tcc_output_binary(s1, f, section_order);
1718 fclose(f);
1720 ret = 0;
1721 the_end:
1722 tcc_free(s1->symtab_to_dynsym);
1723 tcc_free(section_order);
1724 tcc_free(phdr);
1725 tcc_free(s1->got_offsets);
1726 return ret;
1729 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1731 void *data;
1733 data = tcc_malloc(size);
1734 lseek(fd, file_offset, SEEK_SET);
1735 read(fd, data, size);
1736 return data;
1739 typedef struct SectionMergeInfo {
1740 Section *s; /* corresponding existing section */
1741 unsigned long offset; /* offset of the new section in the existing section */
1742 uint8_t new_section; /* true if section 's' was added */
1743 uint8_t link_once; /* true if link once section */
1744 } SectionMergeInfo;
1746 /* load an object file and merge it with current files */
1747 /* XXX: handle correctly stab (debug) info */
1748 static int tcc_load_object_file(TCCState *s1,
1749 int fd, unsigned long file_offset)
1751 Elf32_Ehdr ehdr;
1752 Elf32_Shdr *shdr, *sh;
1753 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1754 unsigned char *strsec, *strtab;
1755 int *old_to_new_syms;
1756 char *sh_name, *name;
1757 SectionMergeInfo *sm_table, *sm;
1758 Elf32_Sym *sym, *symtab;
1759 Elf32_Rel *rel, *rel_end;
1760 Section *s;
1762 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1763 goto fail1;
1764 if (ehdr.e_ident[0] != ELFMAG0 ||
1765 ehdr.e_ident[1] != ELFMAG1 ||
1766 ehdr.e_ident[2] != ELFMAG2 ||
1767 ehdr.e_ident[3] != ELFMAG3)
1768 goto fail1;
1769 /* test if object file */
1770 if (ehdr.e_type != ET_REL)
1771 goto fail1;
1772 /* test CPU specific stuff */
1773 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1774 ehdr.e_machine != EM_TCC_TARGET) {
1775 fail1:
1776 error_noabort("invalid object file");
1777 return -1;
1779 /* read sections */
1780 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1781 sizeof(Elf32_Shdr) * ehdr.e_shnum);
1782 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1784 /* load section names */
1785 sh = &shdr[ehdr.e_shstrndx];
1786 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1788 /* load symtab and strtab */
1789 old_to_new_syms = NULL;
1790 symtab = NULL;
1791 strtab = NULL;
1792 nb_syms = 0;
1793 for(i = 1; i < ehdr.e_shnum; i++) {
1794 sh = &shdr[i];
1795 if (sh->sh_type == SHT_SYMTAB) {
1796 if (symtab) {
1797 error_noabort("object must contain only one symtab");
1798 fail:
1799 ret = -1;
1800 goto the_end;
1802 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1803 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1804 sm_table[i].s = symtab_section;
1806 /* now load strtab */
1807 sh = &shdr[sh->sh_link];
1808 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1812 /* now examine each section and try to merge its content with the
1813 ones in memory */
1814 for(i = 1; i < ehdr.e_shnum; i++) {
1815 /* no need to examine section name strtab */
1816 if (i == ehdr.e_shstrndx)
1817 continue;
1818 sh = &shdr[i];
1819 sh_name = strsec + sh->sh_name;
1820 /* ignore sections types we do not handle */
1821 if (sh->sh_type != SHT_PROGBITS &&
1822 sh->sh_type != SHT_REL &&
1823 sh->sh_type != SHT_NOBITS)
1824 continue;
1825 if (sh->sh_addralign < 1)
1826 sh->sh_addralign = 1;
1827 /* find corresponding section, if any */
1828 for(j = 1; j < s1->nb_sections;j++) {
1829 s = s1->sections[j];
1830 if (!strcmp(s->name, sh_name)) {
1831 if (!strncmp(sh_name, ".gnu.linkonce",
1832 sizeof(".gnu.linkonce") - 1)) {
1833 /* if a 'linkonce' section is already present, we
1834 do not add it again. It is a little tricky as
1835 symbols can still be defined in
1836 it. */
1837 sm_table[i].link_once = 1;
1838 goto next;
1839 } else {
1840 goto found;
1844 /* not found: create new section */
1845 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1846 /* take as much info as possible from the section. sh_link and
1847 sh_info will be updated later */
1848 s->sh_addralign = sh->sh_addralign;
1849 s->sh_entsize = sh->sh_entsize;
1850 sm_table[i].new_section = 1;
1851 found:
1852 if (sh->sh_type != s->sh_type) {
1853 error_noabort("invalid section type");
1854 goto fail;
1857 /* align start of section */
1858 offset = s->data_offset;
1859 size = sh->sh_addralign - 1;
1860 offset = (offset + size) & ~size;
1861 if (sh->sh_addralign > s->sh_addralign)
1862 s->sh_addralign = sh->sh_addralign;
1863 s->data_offset = offset;
1864 sm_table[i].offset = offset;
1865 sm_table[i].s = s;
1866 /* concatenate sections */
1867 size = sh->sh_size;
1868 if (sh->sh_type != SHT_NOBITS) {
1869 unsigned char *ptr;
1870 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1871 ptr = section_ptr_add(s, size);
1872 read(fd, ptr, size);
1873 } else {
1874 s->data_offset += size;
1876 next: ;
1879 /* second short pass to update sh_link and sh_info fields of new
1880 sections */
1881 sm = sm_table;
1882 for(i = 1; i < ehdr.e_shnum; i++) {
1883 s = sm_table[i].s;
1884 if (!s || !sm_table[i].new_section)
1885 continue;
1886 sh = &shdr[i];
1887 if (sh->sh_link > 0)
1888 s->link = sm_table[sh->sh_link].s;
1889 if (sh->sh_type == SHT_REL) {
1890 s->sh_info = sm_table[sh->sh_info].s->sh_num;
1891 /* update backward link */
1892 s1->sections[s->sh_info]->reloc = s;
1896 /* resolve symbols */
1897 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
1899 sym = symtab + 1;
1900 for(i = 1; i < nb_syms; i++, sym++) {
1901 if (sym->st_shndx != SHN_UNDEF &&
1902 sym->st_shndx < SHN_LORESERVE) {
1903 sm = &sm_table[sym->st_shndx];
1904 if (sm->link_once) {
1905 /* if a symbol is in a link once section, we use the
1906 already defined symbol. It is very important to get
1907 correct relocations */
1908 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1909 name = strtab + sym->st_name;
1910 sym_index = find_elf_sym(symtab_section, name);
1911 if (sym_index)
1912 old_to_new_syms[i] = sym_index;
1914 continue;
1916 /* if no corresponding section added, no need to add symbol */
1917 if (!sm->s)
1918 continue;
1919 /* convert section number */
1920 sym->st_shndx = sm->s->sh_num;
1921 /* offset value */
1922 sym->st_value += sm->offset;
1924 /* add symbol */
1925 name = strtab + sym->st_name;
1926 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
1927 sym->st_info, sym->st_shndx, name);
1928 old_to_new_syms[i] = sym_index;
1931 /* third pass to patch relocation entries */
1932 for(i = 1; i < ehdr.e_shnum; i++) {
1933 s = sm_table[i].s;
1934 if (!s)
1935 continue;
1936 sh = &shdr[i];
1937 offset = sm_table[i].offset;
1938 switch(s->sh_type) {
1939 case SHT_REL:
1940 /* take relocation offset information */
1941 offseti = sm_table[sh->sh_info].offset;
1942 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
1943 for(rel = (Elf32_Rel *)(s->data + offset);
1944 rel < rel_end;
1945 rel++) {
1946 int type;
1947 unsigned sym_index;
1948 /* convert symbol index */
1949 type = ELF32_R_TYPE(rel->r_info);
1950 sym_index = ELF32_R_SYM(rel->r_info);
1951 /* NOTE: only one symtab assumed */
1952 if (sym_index >= nb_syms)
1953 goto invalid_reloc;
1954 sym_index = old_to_new_syms[sym_index];
1955 if (!sym_index) {
1956 invalid_reloc:
1957 error_noabort("Invalid relocation entry");
1958 goto fail;
1960 rel->r_info = ELF32_R_INFO(sym_index, type);
1961 /* offset the relocation offset */
1962 rel->r_offset += offseti;
1964 break;
1965 default:
1966 break;
1970 ret = 0;
1971 the_end:
1972 tcc_free(symtab);
1973 tcc_free(strtab);
1974 tcc_free(old_to_new_syms);
1975 tcc_free(sm_table);
1976 tcc_free(strsec);
1977 tcc_free(shdr);
1978 return ret;
1981 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1983 typedef struct ArchiveHeader {
1984 char ar_name[16]; /* name of this member */
1985 char ar_date[12]; /* file mtime */
1986 char ar_uid[6]; /* owner uid; printed as decimal */
1987 char ar_gid[6]; /* owner gid; printed as decimal */
1988 char ar_mode[8]; /* file mode, printed as octal */
1989 char ar_size[10]; /* file size, printed as decimal */
1990 char ar_fmag[2]; /* should contain ARFMAG */
1991 } ArchiveHeader;
1993 static int get_be32(const uint8_t *b)
1995 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
1998 /* load only the objects which resolve undefined symbols */
1999 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
2001 int i, bound, nsyms, sym_index, off, ret;
2002 uint8_t *data;
2003 const char *ar_names, *p;
2004 const uint8_t *ar_index;
2005 Elf32_Sym *sym;
2007 data = tcc_malloc(size);
2008 if (read(fd, data, size) != size)
2009 goto fail;
2010 nsyms = get_be32(data);
2011 ar_index = data + 4;
2012 ar_names = ar_index + nsyms * 4;
2014 do {
2015 bound = 0;
2016 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2017 sym_index = find_elf_sym(symtab_section, p);
2018 if(sym_index) {
2019 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
2020 if(sym->st_shndx == SHN_UNDEF) {
2021 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2022 #if 0
2023 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2024 #endif
2025 ++bound;
2026 lseek(fd, off, SEEK_SET);
2027 if(tcc_load_object_file(s1, fd, off) < 0) {
2028 fail:
2029 ret = -1;
2030 goto the_end;
2035 } while(bound);
2036 ret = 0;
2037 the_end:
2038 tcc_free(data);
2039 return ret;
2042 /* load a '.a' file */
2043 static int tcc_load_archive(TCCState *s1, int fd)
2045 ArchiveHeader hdr;
2046 char ar_size[11];
2047 char ar_name[17];
2048 char magic[8];
2049 int size, len, i;
2050 unsigned long file_offset;
2052 /* skip magic which was already checked */
2053 read(fd, magic, sizeof(magic));
2055 for(;;) {
2056 len = read(fd, &hdr, sizeof(hdr));
2057 if (len == 0)
2058 break;
2059 if (len != sizeof(hdr)) {
2060 error_noabort("invalid archive");
2061 return -1;
2063 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2064 ar_size[sizeof(hdr.ar_size)] = '\0';
2065 size = strtol(ar_size, NULL, 0);
2066 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2067 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2068 if (ar_name[i] != ' ')
2069 break;
2071 ar_name[i + 1] = '\0';
2072 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2073 file_offset = lseek(fd, 0, SEEK_CUR);
2074 /* align to even */
2075 size = (size + 1) & ~1;
2076 if (!strcmp(ar_name, "/")) {
2077 /* coff symbol table : we handle it */
2078 if(s1->alacarte_link)
2079 return tcc_load_alacarte(s1, fd, size);
2080 } else if (!strcmp(ar_name, "//") ||
2081 !strcmp(ar_name, "__.SYMDEF") ||
2082 !strcmp(ar_name, "__.SYMDEF/") ||
2083 !strcmp(ar_name, "ARFILENAMES/")) {
2084 /* skip symbol table or archive names */
2085 } else {
2086 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2087 return -1;
2089 lseek(fd, file_offset + size, SEEK_SET);
2091 return 0;
2094 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2095 is referenced by the user (so it should be added as DT_NEEDED in
2096 the generated ELF file) */
2097 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2099 Elf32_Ehdr ehdr;
2100 Elf32_Shdr *shdr, *sh, *sh1;
2101 int i, nb_syms, nb_dts, sym_bind, ret;
2102 Elf32_Sym *sym, *dynsym;
2103 Elf32_Dyn *dt, *dynamic;
2104 unsigned char *dynstr;
2105 const char *name, *soname, *p;
2106 DLLReference *dllref;
2108 read(fd, &ehdr, sizeof(ehdr));
2110 /* test CPU specific stuff */
2111 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2112 ehdr.e_machine != EM_TCC_TARGET) {
2113 error_noabort("bad architecture");
2114 return -1;
2117 /* read sections */
2118 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
2120 /* load dynamic section and dynamic symbols */
2121 nb_syms = 0;
2122 nb_dts = 0;
2123 dynamic = NULL;
2124 dynsym = NULL; /* avoid warning */
2125 dynstr = NULL; /* avoid warning */
2126 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2127 switch(sh->sh_type) {
2128 case SHT_DYNAMIC:
2129 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
2130 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2131 break;
2132 case SHT_DYNSYM:
2133 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
2134 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2135 sh1 = &shdr[sh->sh_link];
2136 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2137 break;
2138 default:
2139 break;
2143 /* compute the real library name */
2144 soname = filename;
2145 p = strrchr(soname, '/');
2146 if (p)
2147 soname = p + 1;
2149 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2150 if (dt->d_tag == DT_SONAME) {
2151 soname = dynstr + dt->d_un.d_val;
2155 /* if the dll is already loaded, do not load it */
2156 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2157 dllref = s1->loaded_dlls[i];
2158 if (!strcmp(soname, dllref->name)) {
2159 /* but update level if needed */
2160 if (level < dllref->level)
2161 dllref->level = level;
2162 ret = 0;
2163 goto the_end;
2167 // printf("loading dll '%s'\n", soname);
2169 /* add the dll and its level */
2170 dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
2171 dllref->level = level;
2172 strcpy(dllref->name, soname);
2173 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2175 /* add dynamic symbols in dynsym_section */
2176 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2177 sym_bind = ELF32_ST_BIND(sym->st_info);
2178 if (sym_bind == STB_LOCAL)
2179 continue;
2180 name = dynstr + sym->st_name;
2181 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2182 sym->st_info, sym->st_shndx, name);
2185 /* load all referenced DLLs */
2186 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2187 switch(dt->d_tag) {
2188 case DT_NEEDED:
2189 name = dynstr + dt->d_un.d_val;
2190 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2191 dllref = s1->loaded_dlls[i];
2192 if (!strcmp(name, dllref->name))
2193 goto already_loaded;
2195 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2196 error_noabort("referenced dll '%s' not found", name);
2197 ret = -1;
2198 goto the_end;
2200 already_loaded:
2201 break;
2204 ret = 0;
2205 the_end:
2206 tcc_free(dynstr);
2207 tcc_free(dynsym);
2208 tcc_free(dynamic);
2209 tcc_free(shdr);
2210 return ret;
2213 #define LD_TOK_NAME 256
2214 #define LD_TOK_EOF (-1)
2216 /* return next ld script token */
2217 static int ld_next(TCCState *s1, char *name, int name_size)
2219 int c;
2220 char *q;
2222 redo:
2223 switch(ch) {
2224 case ' ':
2225 case '\t':
2226 case '\f':
2227 case '\v':
2228 case '\r':
2229 case '\n':
2230 inp();
2231 goto redo;
2232 case '/':
2233 minp();
2234 if (ch == '*') {
2235 file->buf_ptr = parse_comment(file->buf_ptr);
2236 ch = file->buf_ptr[0];
2237 goto redo;
2238 } else {
2239 q = name;
2240 *q++ = '/';
2241 goto parse_name;
2243 break;
2244 case 'a' ... 'z':
2245 case 'A' ... 'Z':
2246 case '_':
2247 case '\\':
2248 case '.':
2249 case '$':
2250 case '~':
2251 q = name;
2252 parse_name:
2253 for(;;) {
2254 if (!((ch >= 'a' && ch <= 'z') ||
2255 (ch >= 'A' && ch <= 'Z') ||
2256 (ch >= '0' && ch <= '9') ||
2257 strchr("/.-_+=$:\\,~", ch)))
2258 break;
2259 if ((q - name) < name_size - 1) {
2260 *q++ = ch;
2262 minp();
2264 *q = '\0';
2265 c = LD_TOK_NAME;
2266 break;
2267 case CH_EOF:
2268 c = LD_TOK_EOF;
2269 break;
2270 default:
2271 c = ch;
2272 inp();
2273 break;
2275 #if 0
2276 printf("tok=%c %d\n", c, c);
2277 if (c == LD_TOK_NAME)
2278 printf(" name=%s\n", name);
2279 #endif
2280 return c;
2283 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2284 files */
2285 static int tcc_load_ldscript(TCCState *s1)
2287 char cmd[64];
2288 char filename[1024];
2289 int t;
2291 ch = file->buf_ptr[0];
2292 ch = handle_eob();
2293 for(;;) {
2294 t = ld_next(s1, cmd, sizeof(cmd));
2295 if (t == LD_TOK_EOF)
2296 return 0;
2297 else if (t != LD_TOK_NAME)
2298 return -1;
2299 if (!strcmp(cmd, "INPUT") ||
2300 !strcmp(cmd, "GROUP")) {
2301 t = ld_next(s1, cmd, sizeof(cmd));
2302 if (t != '(')
2303 expect("(");
2304 t = ld_next(s1, filename, sizeof(filename));
2305 for(;;) {
2306 if (t == LD_TOK_EOF) {
2307 error_noabort("unexpected end of file");
2308 return -1;
2309 } else if (t == ')') {
2310 break;
2311 } else if (t != LD_TOK_NAME) {
2312 error_noabort("filename expected");
2313 return -1;
2315 tcc_add_file(s1, filename);
2316 t = ld_next(s1, filename, sizeof(filename));
2317 if (t == ',') {
2318 t = ld_next(s1, filename, sizeof(filename));
2321 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2322 !strcmp(cmd, "TARGET")) {
2323 /* ignore some commands */
2324 t = ld_next(s1, cmd, sizeof(cmd));
2325 if (t != '(')
2326 expect("(");
2327 for(;;) {
2328 t = ld_next(s1, filename, sizeof(filename));
2329 if (t == LD_TOK_EOF) {
2330 error_noabort("unexpected end of file");
2331 return -1;
2332 } else if (t == ')') {
2333 break;
2336 } else {
2337 return -1;
2340 return 0;