fastcall keywords
[tinycc.git] / tccelf.c
blob7b2da885537eefedf11e315475584fbbfa34efca
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 other, 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;
220 esym->st_other = other;
222 } else {
223 do_def:
224 sym_index = put_elf_sym(s, value, size,
225 ELF32_ST_INFO(sym_bind, sym_type), other,
226 sh_num, name);
228 return sym_index;
231 /* put relocation */
232 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
233 int type, int symbol)
235 char buf[256];
236 Section *sr;
237 Elf32_Rel *rel;
239 sr = s->reloc;
240 if (!sr) {
241 /* if no relocation section, create it */
242 snprintf(buf, sizeof(buf), ".rel%s", s->name);
243 /* if the symtab is allocated, then we consider the relocation
244 are also */
245 sr = new_section(tcc_state, buf, SHT_REL, symtab->sh_flags);
246 sr->sh_entsize = sizeof(Elf32_Rel);
247 sr->link = symtab;
248 sr->sh_info = s->sh_num;
249 s->reloc = sr;
251 rel = section_ptr_add(sr, sizeof(Elf32_Rel));
252 rel->r_offset = offset;
253 rel->r_info = ELF32_R_INFO(symbol, type);
256 /* put stab debug information */
258 typedef struct {
259 unsigned long n_strx; /* index into string table of name */
260 unsigned char n_type; /* type of symbol */
261 unsigned char n_other; /* misc info (usually empty) */
262 unsigned short n_desc; /* description field */
263 unsigned long n_value; /* value of symbol */
264 } Stab_Sym;
266 static void put_stabs(const char *str, int type, int other, int desc,
267 unsigned long value)
269 Stab_Sym *sym;
271 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
272 if (str) {
273 sym->n_strx = put_elf_str(stabstr_section, str);
274 } else {
275 sym->n_strx = 0;
277 sym->n_type = type;
278 sym->n_other = other;
279 sym->n_desc = desc;
280 sym->n_value = value;
283 static void put_stabs_r(const char *str, int type, int other, int desc,
284 unsigned long value, Section *sec, int sym_index)
286 put_stabs(str, type, other, desc, value);
287 put_elf_reloc(symtab_section, stab_section,
288 stab_section->data_offset - sizeof(unsigned long),
289 R_DATA_32, sym_index);
292 static void put_stabn(int type, int other, int desc, int value)
294 put_stabs(NULL, type, other, desc, value);
297 static void put_stabd(int type, int other, int desc)
299 put_stabs(NULL, type, other, desc, 0);
302 /* In an ELF file symbol table, the local symbols must appear below
303 the global and weak ones. Since TCC cannot sort it while generating
304 the code, we must do it after. All the relocation tables are also
305 modified to take into account the symbol table sorting */
306 static void sort_syms(TCCState *s1, Section *s)
308 int *old_to_new_syms;
309 Elf32_Sym *new_syms;
310 int nb_syms, i;
311 Elf32_Sym *p, *q;
312 Elf32_Rel *rel, *rel_end;
313 Section *sr;
314 int type, sym_index;
316 nb_syms = s->data_offset / sizeof(Elf32_Sym);
317 new_syms = tcc_malloc(nb_syms * sizeof(Elf32_Sym));
318 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
320 /* first pass for local symbols */
321 p = (Elf32_Sym *)s->data;
322 q = new_syms;
323 for(i = 0; i < nb_syms; i++) {
324 if (ELF32_ST_BIND(p->st_info) == STB_LOCAL) {
325 old_to_new_syms[i] = q - new_syms;
326 *q++ = *p;
328 p++;
330 /* save the number of local symbols in section header */
331 s->sh_info = q - new_syms;
333 /* then second pass for non local symbols */
334 p = (Elf32_Sym *)s->data;
335 for(i = 0; i < nb_syms; i++) {
336 if (ELF32_ST_BIND(p->st_info) != STB_LOCAL) {
337 old_to_new_syms[i] = q - new_syms;
338 *q++ = *p;
340 p++;
343 /* we copy the new symbols to the old */
344 memcpy(s->data, new_syms, nb_syms * sizeof(Elf32_Sym));
345 tcc_free(new_syms);
347 /* now we modify all the relocations */
348 for(i = 1; i < s1->nb_sections; i++) {
349 sr = s1->sections[i];
350 if (sr->sh_type == SHT_REL && sr->link == s) {
351 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
352 for(rel = (Elf32_Rel *)sr->data;
353 rel < rel_end;
354 rel++) {
355 sym_index = ELF32_R_SYM(rel->r_info);
356 type = ELF32_R_TYPE(rel->r_info);
357 sym_index = old_to_new_syms[sym_index];
358 rel->r_info = ELF32_R_INFO(sym_index, type);
363 tcc_free(old_to_new_syms);
366 /* relocate common symbols in the .bss section */
367 static void relocate_common_syms(void)
369 Elf32_Sym *sym, *sym_end;
370 unsigned long offset, align;
372 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
373 for(sym = (Elf32_Sym *)symtab_section->data + 1;
374 sym < sym_end;
375 sym++) {
376 if (sym->st_shndx == SHN_COMMON) {
377 /* align symbol */
378 align = sym->st_value;
379 offset = bss_section->data_offset;
380 offset = (offset + align - 1) & -align;
381 sym->st_value = offset;
382 sym->st_shndx = bss_section->sh_num;
383 offset += sym->st_size;
384 bss_section->data_offset = offset;
389 /* relocate symbol table, resolve undefined symbols if do_resolve is
390 true and output error if undefined symbol. */
391 static void relocate_syms(TCCState *s1, int do_resolve)
393 Elf32_Sym *sym, *esym, *sym_end;
394 int sym_bind, sh_num, sym_index;
395 const char *name;
396 unsigned long addr;
398 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
399 for(sym = (Elf32_Sym *)symtab_section->data + 1;
400 sym < sym_end;
401 sym++) {
402 sh_num = sym->st_shndx;
403 if (sh_num == SHN_UNDEF) {
404 name = strtab_section->data + sym->st_name;
405 if (do_resolve) {
406 name = symtab_section->link->data + sym->st_name;
407 addr = (unsigned long)resolve_sym(s1, name, ELF32_ST_TYPE(sym->st_info));
408 if (addr) {
409 sym->st_value = addr;
410 goto found;
412 } else if (s1->dynsym) {
413 /* if dynamic symbol exist, then use it */
414 sym_index = find_elf_sym(s1->dynsym, name);
415 if (sym_index) {
416 esym = &((Elf32_Sym *)s1->dynsym->data)[sym_index];
417 sym->st_value = esym->st_value;
418 goto found;
421 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
422 it */
423 if (!strcmp(name, "_fp_hw"))
424 goto found;
425 /* only weak symbols are accepted to be undefined. Their
426 value is zero */
427 sym_bind = ELF32_ST_BIND(sym->st_info);
428 if (sym_bind == STB_WEAK) {
429 sym->st_value = 0;
430 } else {
431 error_noabort("undefined symbol '%s'", name);
433 } else if (sh_num < SHN_LORESERVE) {
434 /* add section base */
435 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
437 found: ;
441 /* relocate a given section (CPU dependent) */
442 static void relocate_section(TCCState *s1, Section *s)
444 Section *sr;
445 Elf32_Rel *rel, *rel_end, *qrel;
446 Elf32_Sym *sym;
447 int type, sym_index;
448 unsigned char *ptr;
449 unsigned long val, addr;
450 #if defined(TCC_TARGET_I386)
451 int esym_index;
452 #endif
454 sr = s->reloc;
455 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
456 qrel = (Elf32_Rel *)sr->data;
457 for(rel = qrel;
458 rel < rel_end;
459 rel++) {
460 ptr = s->data + rel->r_offset;
462 sym_index = ELF32_R_SYM(rel->r_info);
463 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
464 val = sym->st_value;
465 type = ELF32_R_TYPE(rel->r_info);
466 addr = s->sh_addr + rel->r_offset;
468 /* CPU specific */
469 switch(type) {
470 #if defined(TCC_TARGET_I386)
471 case R_386_32:
472 if (s1->output_type == TCC_OUTPUT_DLL) {
473 esym_index = s1->symtab_to_dynsym[sym_index];
474 qrel->r_offset = rel->r_offset;
475 if (esym_index) {
476 qrel->r_info = ELF32_R_INFO(esym_index, R_386_32);
477 qrel++;
478 break;
479 } else {
480 qrel->r_info = ELF32_R_INFO(0, R_386_RELATIVE);
481 qrel++;
484 *(int *)ptr += val;
485 break;
486 case R_386_PC32:
487 if (s1->output_type == TCC_OUTPUT_DLL) {
488 /* DLL relocation */
489 esym_index = s1->symtab_to_dynsym[sym_index];
490 if (esym_index) {
491 qrel->r_offset = rel->r_offset;
492 qrel->r_info = ELF32_R_INFO(esym_index, R_386_PC32);
493 qrel++;
494 break;
497 *(int *)ptr += val - addr;
498 break;
499 case R_386_PLT32:
500 *(int *)ptr += val - addr;
501 break;
502 case R_386_GLOB_DAT:
503 case R_386_JMP_SLOT:
504 *(int *)ptr = val;
505 break;
506 case R_386_GOTPC:
507 *(int *)ptr += s1->got->sh_addr - addr;
508 break;
509 case R_386_GOTOFF:
510 *(int *)ptr += val - s1->got->sh_addr;
511 break;
512 case R_386_GOT32:
513 /* we load the got offset */
514 *(int *)ptr += s1->got_offsets[sym_index];
515 break;
516 #elif defined(TCC_TARGET_ARM)
517 case R_ARM_PC24:
518 case R_ARM_PLT32:
520 int x;
521 x = (*(int *)ptr)&0xffffff;
522 (*(int *)ptr) &= 0xff000000;
523 if (x & 0x800000)
524 x -= 0x1000000;
525 x *= 4;
526 x += val - addr;
527 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
528 error("can't relocate value at %x",addr);
529 x >>= 2;
530 x &= 0xffffff;
531 (*(int *)ptr) |= x;
533 break;
534 case R_ARM_ABS32:
535 *(int *)ptr += val;
536 break;
537 case R_ARM_GOTPC:
538 *(int *)ptr += s1->got->sh_addr - addr;
539 break;
540 case R_ARM_GOT32:
541 /* we load the got offset */
542 *(int *)ptr += s1->got_offsets[sym_index];
543 break;
544 case R_ARM_COPY:
545 break;
546 default:
547 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
548 type,addr,(unsigned int )ptr,val);
549 break;
550 #elif defined(TCC_TARGET_C67)
551 case R_C60_32:
552 *(int *)ptr += val;
553 break;
554 case R_C60LO16:
556 uint32_t orig;
558 /* put the low 16 bits of the absolute address */
559 // add to what is already there
561 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
562 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
564 //patch both at once - assumes always in pairs Low - High
566 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
567 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
569 break;
570 case R_C60HI16:
571 break;
572 default:
573 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
574 type,addr,(unsigned int )ptr,val);
575 break;
576 #else
577 #error unsupported processor
578 #endif
581 /* if the relocation is allocated, we change its symbol table */
582 if (sr->sh_flags & SHF_ALLOC)
583 sr->link = s1->dynsym;
586 /* relocate relocation table in 'sr' */
587 static void relocate_rel(TCCState *s1, Section *sr)
589 Section *s;
590 Elf32_Rel *rel, *rel_end;
592 s = s1->sections[sr->sh_info];
593 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
594 for(rel = (Elf32_Rel *)sr->data;
595 rel < rel_end;
596 rel++) {
597 rel->r_offset += s->sh_addr;
601 /* count the number of dynamic relocations so that we can reserve
602 their space */
603 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
605 Elf32_Rel *rel, *rel_end;
606 int sym_index, esym_index, type, count;
608 count = 0;
609 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
610 for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) {
611 sym_index = ELF32_R_SYM(rel->r_info);
612 type = ELF32_R_TYPE(rel->r_info);
613 switch(type) {
614 case R_386_32:
615 count++;
616 break;
617 case R_386_PC32:
618 esym_index = s1->symtab_to_dynsym[sym_index];
619 if (esym_index)
620 count++;
621 break;
622 default:
623 break;
626 if (count) {
627 /* allocate the section */
628 sr->sh_flags |= SHF_ALLOC;
629 sr->sh_size = count * sizeof(Elf32_Rel);
631 return count;
634 static void put_got_offset(TCCState *s1, int index, unsigned long val)
636 int n;
637 unsigned long *tab;
639 if (index >= s1->nb_got_offsets) {
640 /* find immediately bigger power of 2 and reallocate array */
641 n = 1;
642 while (index >= n)
643 n *= 2;
644 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
645 if (!tab)
646 error("memory full");
647 s1->got_offsets = tab;
648 memset(s1->got_offsets + s1->nb_got_offsets, 0,
649 (n - s1->nb_got_offsets) * sizeof(unsigned long));
650 s1->nb_got_offsets = n;
652 s1->got_offsets[index] = val;
655 /* XXX: suppress that */
656 static void put32(unsigned char *p, uint32_t val)
658 p[0] = val;
659 p[1] = val >> 8;
660 p[2] = val >> 16;
661 p[3] = val >> 24;
664 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM)
665 static uint32_t get32(unsigned char *p)
667 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
669 #endif
671 static void build_got(TCCState *s1)
673 unsigned char *ptr;
675 /* if no got, then create it */
676 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
677 s1->got->sh_entsize = 4;
678 add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
679 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
680 ptr = section_ptr_add(s1->got, 3 * sizeof(int));
681 /* keep space for _DYNAMIC pointer, if present */
682 put32(ptr, 0);
683 /* two dummy got entries */
684 put32(ptr + 4, 0);
685 put32(ptr + 8, 0);
688 /* put a got entry corresponding to a symbol in symtab_section. 'size'
689 and 'info' can be modifed if more precise info comes from the DLL */
690 static void put_got_entry(TCCState *s1,
691 int reloc_type, unsigned long size, int info,
692 int sym_index)
694 int index;
695 const char *name;
696 Elf32_Sym *sym;
697 unsigned long offset;
698 int *ptr;
700 if (!s1->got)
701 build_got(s1);
703 /* if a got entry already exists for that symbol, no need to add one */
704 if (sym_index < s1->nb_got_offsets &&
705 s1->got_offsets[sym_index] != 0)
706 return;
708 put_got_offset(s1, sym_index, s1->got->data_offset);
710 if (s1->dynsym) {
711 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
712 name = symtab_section->link->data + sym->st_name;
713 offset = sym->st_value;
714 #ifdef TCC_TARGET_I386
715 if (reloc_type == R_386_JMP_SLOT) {
716 Section *plt;
717 uint8_t *p;
718 int modrm;
720 /* if we build a DLL, we add a %ebx offset */
721 if (s1->output_type == TCC_OUTPUT_DLL)
722 modrm = 0xa3;
723 else
724 modrm = 0x25;
726 /* add a PLT entry */
727 plt = s1->plt;
728 if (plt->data_offset == 0) {
729 /* first plt entry */
730 p = section_ptr_add(plt, 16);
731 p[0] = 0xff; /* pushl got + 4 */
732 p[1] = modrm + 0x10;
733 put32(p + 2, 4);
734 p[6] = 0xff; /* jmp *(got + 8) */
735 p[7] = modrm;
736 put32(p + 8, 8);
739 p = section_ptr_add(plt, 16);
740 p[0] = 0xff; /* jmp *(got + x) */
741 p[1] = modrm;
742 put32(p + 2, s1->got->data_offset);
743 p[6] = 0x68; /* push $xxx */
744 put32(p + 7, (plt->data_offset - 32) >> 1);
745 p[11] = 0xe9; /* jmp plt_start */
746 put32(p + 12, -(plt->data_offset));
748 /* the symbol is modified so that it will be relocated to
749 the PLT */
750 if (s1->output_type == TCC_OUTPUT_EXE)
751 offset = plt->data_offset - 16;
753 #elif defined(TCC_TARGET_ARM)
754 if (reloc_type == R_ARM_JUMP_SLOT) {
755 Section *plt;
756 uint8_t *p;
758 /* if we build a DLL, we add a %ebx offset */
759 if (s1->output_type == TCC_OUTPUT_DLL)
760 error("DLLs unimplemented!");
762 /* add a PLT entry */
763 plt = s1->plt;
764 if (plt->data_offset == 0) {
765 /* first plt entry */
766 p = section_ptr_add(plt, 16);
767 put32(p , 0xe52de004);
768 put32(p + 4, 0xe59fe010);
769 put32(p + 8, 0xe08fe00e);
770 put32(p + 12, 0xe5bef008);
773 p = section_ptr_add(plt, 16);
774 put32(p , 0xe59fc004);
775 put32(p+4, 0xe08fc00c);
776 put32(p+8, 0xe59cf000);
777 put32(p+12, s1->got->data_offset);
779 /* the symbol is modified so that it will be relocated to
780 the PLT */
781 if (s1->output_type == TCC_OUTPUT_EXE)
782 offset = plt->data_offset - 16;
784 #elif defined(TCC_TARGET_C67)
785 error("C67 got not implemented");
786 #else
787 #error unsupported CPU
788 #endif
789 index = put_elf_sym(s1->dynsym, offset,
790 size, info, 0, sym->st_shndx, name);
791 /* put a got entry */
792 put_elf_reloc(s1->dynsym, s1->got,
793 s1->got->data_offset,
794 reloc_type, index);
796 ptr = section_ptr_add(s1->got, sizeof(int));
797 *ptr = 0;
800 /* build GOT and PLT entries */
801 static void build_got_entries(TCCState *s1)
803 Section *s, *symtab;
804 Elf32_Rel *rel, *rel_end;
805 Elf32_Sym *sym;
806 int i, type, reloc_type, sym_index;
808 for(i = 1; i < s1->nb_sections; i++) {
809 s = s1->sections[i];
810 if (s->sh_type != SHT_REL)
811 continue;
812 /* no need to handle got relocations */
813 if (s->link != symtab_section)
814 continue;
815 symtab = s->link;
816 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
817 for(rel = (Elf32_Rel *)s->data;
818 rel < rel_end;
819 rel++) {
820 type = ELF32_R_TYPE(rel->r_info);
821 switch(type) {
822 #if defined(TCC_TARGET_I386)
823 case R_386_GOT32:
824 case R_386_GOTOFF:
825 case R_386_GOTPC:
826 case R_386_PLT32:
827 if (!s1->got)
828 build_got(s1);
829 if (type == R_386_GOT32 || type == R_386_PLT32) {
830 sym_index = ELF32_R_SYM(rel->r_info);
831 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
832 /* look at the symbol got offset. If none, then add one */
833 if (type == R_386_GOT32)
834 reloc_type = R_386_GLOB_DAT;
835 else
836 reloc_type = R_386_JMP_SLOT;
837 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
838 sym_index);
840 break;
841 #elif defined(TCC_TARGET_ARM)
842 case R_ARM_GOT32:
843 case R_ARM_GOTOFF:
844 case R_ARM_GOTPC:
845 case R_ARM_PLT32:
846 if (!s1->got)
847 build_got(s1);
848 if (type == R_ARM_GOT32 || type == R_ARM_PLT32) {
849 sym_index = ELF32_R_SYM(rel->r_info);
850 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
851 /* look at the symbol got offset. If none, then add one */
852 if (type == R_ARM_GOT32)
853 reloc_type = R_ARM_GLOB_DAT;
854 else
855 reloc_type = R_ARM_JUMP_SLOT;
856 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
857 sym_index);
859 break;
860 #elif defined(TCC_TARGET_C67)
861 case R_C60_GOT32:
862 case R_C60_GOTOFF:
863 case R_C60_GOTPC:
864 case R_C60_PLT32:
865 if (!s1->got)
866 build_got(s1);
867 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
868 sym_index = ELF32_R_SYM(rel->r_info);
869 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
870 /* look at the symbol got offset. If none, then add one */
871 if (type == R_C60_GOT32)
872 reloc_type = R_C60_GLOB_DAT;
873 else
874 reloc_type = R_C60_JMP_SLOT;
875 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
876 sym_index);
878 break;
879 #else
880 #error unsupported CPU
881 #endif
882 default:
883 break;
889 static Section *new_symtab(TCCState *s1,
890 const char *symtab_name, int sh_type, int sh_flags,
891 const char *strtab_name,
892 const char *hash_name, int hash_sh_flags)
894 Section *symtab, *strtab, *hash;
895 int *ptr, nb_buckets;
897 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
898 symtab->sh_entsize = sizeof(Elf32_Sym);
899 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
900 put_elf_str(strtab, "");
901 symtab->link = strtab;
902 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
904 nb_buckets = 1;
906 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
907 hash->sh_entsize = sizeof(int);
908 symtab->hash = hash;
909 hash->link = symtab;
911 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
912 ptr[0] = nb_buckets;
913 ptr[1] = 1;
914 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
915 return symtab;
918 /* put dynamic tag */
919 static void put_dt(Section *dynamic, int dt, unsigned long val)
921 Elf32_Dyn *dyn;
922 dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
923 dyn->d_tag = dt;
924 dyn->d_un.d_val = val;
927 static void add_init_array_defines(TCCState *s1, const char *section_name)
929 Section *s;
930 long end_offset;
931 char sym_start[1024];
932 char sym_end[1024];
934 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
935 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
937 s = find_section(s1, section_name);
938 if (!s) {
939 end_offset = 0;
940 s = data_section;
941 } else {
942 end_offset = s->data_offset;
945 add_elf_sym(symtab_section,
946 0, 0,
947 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
948 s->sh_num, sym_start);
949 add_elf_sym(symtab_section,
950 end_offset, 0,
951 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
952 s->sh_num, sym_end);
955 /* add tcc runtime libraries */
956 static void tcc_add_runtime(TCCState *s1)
958 char buf[1024];
960 #ifdef CONFIG_TCC_BCHECK
961 if (do_bounds_check) {
962 unsigned long *ptr;
963 Section *init_section;
964 unsigned char *pinit;
965 int sym_index;
967 /* XXX: add an object file to do that */
968 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
969 *ptr = 0;
970 add_elf_sym(symtab_section, 0, 0,
971 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
972 bounds_section->sh_num, "__bounds_start");
973 /* add bound check code */
974 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
975 tcc_add_file(s1, buf);
976 #ifdef TCC_TARGET_I386
977 if (s1->output_type != TCC_OUTPUT_MEMORY) {
978 /* add 'call __bound_init()' in .init section */
979 init_section = find_section(s1, ".init");
980 pinit = section_ptr_add(init_section, 5);
981 pinit[0] = 0xe8;
982 put32(pinit + 1, -4);
983 sym_index = find_elf_sym(symtab_section, "__bound_init");
984 put_elf_reloc(symtab_section, init_section,
985 init_section->data_offset - 4, R_386_PC32, sym_index);
987 #endif
989 #endif
990 /* add libc */
991 if (!s1->nostdlib) {
992 tcc_add_library(s1, "c");
994 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
995 tcc_add_file(s1, buf);
997 /* add crt end if not memory output */
998 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
999 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1003 /* add various standard linker symbols (must be done after the
1004 sections are filled (for example after allocating common
1005 symbols)) */
1006 static void tcc_add_linker_symbols(TCCState *s1)
1008 char buf[1024];
1009 int i;
1010 Section *s;
1012 add_elf_sym(symtab_section,
1013 text_section->data_offset, 0,
1014 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1015 text_section->sh_num, "_etext");
1016 add_elf_sym(symtab_section,
1017 data_section->data_offset, 0,
1018 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1019 data_section->sh_num, "_edata");
1020 add_elf_sym(symtab_section,
1021 bss_section->data_offset, 0,
1022 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1023 bss_section->sh_num, "_end");
1024 /* horrible new standard ldscript defines */
1025 add_init_array_defines(s1, ".preinit_array");
1026 add_init_array_defines(s1, ".init_array");
1027 add_init_array_defines(s1, ".fini_array");
1029 /* add start and stop symbols for sections whose name can be
1030 expressed in C */
1031 for(i = 1; i < s1->nb_sections; i++) {
1032 s = s1->sections[i];
1033 if (s->sh_type == SHT_PROGBITS &&
1034 (s->sh_flags & SHF_ALLOC)) {
1035 const char *p;
1036 int ch;
1038 /* check if section name can be expressed in C */
1039 p = s->name;
1040 for(;;) {
1041 ch = *p;
1042 if (!ch)
1043 break;
1044 if (!isid(ch) && !isnum(ch))
1045 goto next_sec;
1046 p++;
1048 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1049 add_elf_sym(symtab_section,
1050 0, 0,
1051 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1052 s->sh_num, buf);
1053 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1054 add_elf_sym(symtab_section,
1055 s->data_offset, 0,
1056 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
1057 s->sh_num, buf);
1059 next_sec: ;
1063 /* name of ELF interpreter */
1064 #ifdef __FreeBSD__
1065 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1066 #else
1067 static char elf_interp[] = "/lib/ld-linux.so.2";
1068 #endif
1070 static void tcc_output_binary(TCCState *s1, FILE *f,
1071 const int *section_order)
1073 Section *s;
1074 int i, offset, size;
1076 offset = 0;
1077 for(i=1;i<s1->nb_sections;i++) {
1078 s = s1->sections[section_order[i]];
1079 if (s->sh_type != SHT_NOBITS &&
1080 (s->sh_flags & SHF_ALLOC)) {
1081 while (offset < s->sh_offset) {
1082 fputc(0, f);
1083 offset++;
1085 size = s->sh_size;
1086 fwrite(s->data, 1, size, f);
1087 offset += size;
1092 /* output an ELF file */
1093 /* XXX: suppress unneeded sections */
1094 int tcc_output_file(TCCState *s1, const char *filename)
1096 Elf32_Ehdr ehdr;
1097 FILE *f;
1098 int fd, mode, ret;
1099 int *section_order;
1100 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1101 unsigned long addr;
1102 Section *strsec, *s;
1103 Elf32_Shdr shdr, *sh;
1104 Elf32_Phdr *phdr, *ph;
1105 Section *interp, *dynamic, *dynstr;
1106 unsigned long saved_dynamic_data_offset;
1107 Elf32_Sym *sym;
1108 int type, file_type;
1109 unsigned long rel_addr, rel_size;
1111 file_type = s1->output_type;
1112 s1->nb_errors = 0;
1114 if (file_type != TCC_OUTPUT_OBJ) {
1115 tcc_add_runtime(s1);
1118 phdr = NULL;
1119 section_order = NULL;
1120 interp = NULL;
1121 dynamic = NULL;
1122 dynstr = NULL; /* avoid warning */
1123 saved_dynamic_data_offset = 0; /* avoid warning */
1125 if (file_type != TCC_OUTPUT_OBJ) {
1126 relocate_common_syms();
1128 tcc_add_linker_symbols(s1);
1130 if (!s1->static_link) {
1131 const char *name;
1132 int sym_index, index;
1133 Elf32_Sym *esym, *sym_end;
1135 if (file_type == TCC_OUTPUT_EXE) {
1136 char *ptr;
1137 /* add interpreter section only if executable */
1138 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1139 interp->sh_addralign = 1;
1140 ptr = section_ptr_add(interp, sizeof(elf_interp));
1141 strcpy(ptr, elf_interp);
1144 /* add dynamic symbol table */
1145 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1146 ".dynstr",
1147 ".hash", SHF_ALLOC);
1148 dynstr = s1->dynsym->link;
1150 /* add dynamic section */
1151 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1152 SHF_ALLOC | SHF_WRITE);
1153 dynamic->link = dynstr;
1154 dynamic->sh_entsize = sizeof(Elf32_Dyn);
1156 /* add PLT */
1157 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1158 SHF_ALLOC | SHF_EXECINSTR);
1159 s1->plt->sh_entsize = 4;
1161 build_got(s1);
1163 /* scan for undefined symbols and see if they are in the
1164 dynamic symbols. If a symbol STT_FUNC is found, then we
1165 add it in the PLT. If a symbol STT_OBJECT is found, we
1166 add it in the .bss section with a suitable relocation */
1167 sym_end = (Elf32_Sym *)(symtab_section->data +
1168 symtab_section->data_offset);
1169 if (file_type == TCC_OUTPUT_EXE) {
1170 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1171 sym < sym_end;
1172 sym++) {
1173 if (sym->st_shndx == SHN_UNDEF) {
1174 name = symtab_section->link->data + sym->st_name;
1175 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1176 if (sym_index) {
1177 esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
1178 type = ELF32_ST_TYPE(esym->st_info);
1179 if (type == STT_FUNC) {
1180 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1181 esym->st_info,
1182 sym - (Elf32_Sym *)symtab_section->data);
1183 } else if (type == STT_OBJECT) {
1184 unsigned long offset;
1185 offset = bss_section->data_offset;
1186 /* XXX: which alignment ? */
1187 offset = (offset + 16 - 1) & -16;
1188 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1189 esym->st_info, 0,
1190 bss_section->sh_num, name);
1191 put_elf_reloc(s1->dynsym, bss_section,
1192 offset, R_COPY, index);
1193 offset += esym->st_size;
1194 bss_section->data_offset = offset;
1196 } else {
1197 /* STB_WEAK undefined symbols are accepted */
1198 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1199 it */
1200 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
1201 !strcmp(name, "_fp_hw")) {
1202 } else {
1203 error_noabort("undefined symbol '%s'", name);
1206 } else if (s1->rdynamic &&
1207 ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1208 /* if -rdynamic option, then export all non
1209 local symbols */
1210 name = symtab_section->link->data + sym->st_name;
1211 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1212 sym->st_info, 0,
1213 sym->st_shndx, name);
1217 if (s1->nb_errors)
1218 goto fail;
1220 /* now look at unresolved dynamic symbols and export
1221 corresponding symbol */
1222 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
1223 s1->dynsymtab_section->data_offset);
1224 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
1225 esym < sym_end;
1226 esym++) {
1227 if (esym->st_shndx == SHN_UNDEF) {
1228 name = s1->dynsymtab_section->link->data + esym->st_name;
1229 sym_index = find_elf_sym(symtab_section, name);
1230 if (sym_index) {
1231 /* XXX: avoid adding a symbol if already
1232 present because of -rdynamic ? */
1233 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1234 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1235 sym->st_info, 0,
1236 sym->st_shndx, name);
1237 } else {
1238 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
1239 /* weak symbols can stay undefined */
1240 } else {
1241 warning("undefined dynamic symbol '%s'", name);
1246 } else {
1247 int nb_syms;
1248 /* shared library case : we simply export all the global symbols */
1249 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
1250 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1251 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1252 sym < sym_end;
1253 sym++) {
1254 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1255 name = symtab_section->link->data + sym->st_name;
1256 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1257 sym->st_info, 0,
1258 sym->st_shndx, name);
1259 s1->symtab_to_dynsym[sym -
1260 (Elf32_Sym *)symtab_section->data] =
1261 index;
1266 build_got_entries(s1);
1268 /* add a list of needed dlls */
1269 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1270 DLLReference *dllref = s1->loaded_dlls[i];
1271 if (dllref->level == 0)
1272 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1274 /* XXX: currently, since we do not handle PIC code, we
1275 must relocate the readonly segments */
1276 if (file_type == TCC_OUTPUT_DLL)
1277 put_dt(dynamic, DT_TEXTREL, 0);
1279 /* add necessary space for other entries */
1280 saved_dynamic_data_offset = dynamic->data_offset;
1281 dynamic->data_offset += 8 * 9;
1282 } else {
1283 /* still need to build got entries in case of static link */
1284 build_got_entries(s1);
1288 memset(&ehdr, 0, sizeof(ehdr));
1290 /* we add a section for symbols */
1291 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1292 put_elf_str(strsec, "");
1294 /* compute number of sections */
1295 shnum = s1->nb_sections;
1297 /* this array is used to reorder sections in the output file */
1298 section_order = tcc_malloc(sizeof(int) * shnum);
1299 section_order[0] = 0;
1300 sh_order_index = 1;
1302 /* compute number of program headers */
1303 switch(file_type) {
1304 default:
1305 case TCC_OUTPUT_OBJ:
1306 phnum = 0;
1307 break;
1308 case TCC_OUTPUT_EXE:
1309 if (!s1->static_link)
1310 phnum = 4;
1311 else
1312 phnum = 2;
1313 break;
1314 case TCC_OUTPUT_DLL:
1315 phnum = 3;
1316 break;
1319 /* allocate strings for section names and decide if an unallocated
1320 section should be output */
1321 /* NOTE: the strsec section comes last, so its size is also
1322 correct ! */
1323 for(i = 1; i < s1->nb_sections; i++) {
1324 s = s1->sections[i];
1325 s->sh_name = put_elf_str(strsec, s->name);
1326 /* when generating a DLL, we include relocations but we may
1327 patch them */
1328 if (file_type == TCC_OUTPUT_DLL &&
1329 s->sh_type == SHT_REL &&
1330 !(s->sh_flags & SHF_ALLOC)) {
1331 prepare_dynamic_rel(s1, s);
1332 } else if (do_debug ||
1333 file_type == TCC_OUTPUT_OBJ ||
1334 (s->sh_flags & SHF_ALLOC) ||
1335 i == (s1->nb_sections - 1)) {
1336 /* we output all sections if debug or object file */
1337 s->sh_size = s->data_offset;
1341 /* allocate program segment headers */
1342 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1344 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1345 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1346 } else {
1347 file_offset = 0;
1349 if (phnum > 0) {
1350 /* compute section to program header mapping */
1351 if (s1->has_text_addr) {
1352 int a_offset, p_offset;
1353 addr = s1->text_addr;
1354 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1355 ELF_PAGE_SIZE */
1356 a_offset = addr & (ELF_PAGE_SIZE - 1);
1357 p_offset = file_offset & (ELF_PAGE_SIZE - 1);
1358 if (a_offset < p_offset)
1359 a_offset += ELF_PAGE_SIZE;
1360 file_offset += (a_offset - p_offset);
1361 } else {
1362 if (file_type == TCC_OUTPUT_DLL)
1363 addr = 0;
1364 else
1365 addr = ELF_START_ADDR;
1366 /* compute address after headers */
1367 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1370 /* dynamic relocation table information, for .dynamic section */
1371 rel_size = 0;
1372 rel_addr = 0;
1374 /* leave one program header for the program interpreter */
1375 ph = &phdr[0];
1376 if (interp)
1377 ph++;
1379 for(j = 0; j < 2; j++) {
1380 ph->p_type = PT_LOAD;
1381 if (j == 0)
1382 ph->p_flags = PF_R | PF_X;
1383 else
1384 ph->p_flags = PF_R | PF_W;
1385 ph->p_align = ELF_PAGE_SIZE;
1387 /* we do the following ordering: interp, symbol tables,
1388 relocations, progbits, nobits */
1389 /* XXX: do faster and simpler sorting */
1390 for(k = 0; k < 5; k++) {
1391 for(i = 1; i < s1->nb_sections; i++) {
1392 s = s1->sections[i];
1393 /* compute if section should be included */
1394 if (j == 0) {
1395 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1396 SHF_ALLOC)
1397 continue;
1398 } else {
1399 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1400 (SHF_ALLOC | SHF_WRITE))
1401 continue;
1403 if (s == interp) {
1404 if (k != 0)
1405 continue;
1406 } else if (s->sh_type == SHT_DYNSYM ||
1407 s->sh_type == SHT_STRTAB ||
1408 s->sh_type == SHT_HASH) {
1409 if (k != 1)
1410 continue;
1411 } else if (s->sh_type == SHT_REL) {
1412 if (k != 2)
1413 continue;
1414 } else if (s->sh_type == SHT_NOBITS) {
1415 if (k != 4)
1416 continue;
1417 } else {
1418 if (k != 3)
1419 continue;
1421 section_order[sh_order_index++] = i;
1423 /* section matches: we align it and add its size */
1424 tmp = addr;
1425 addr = (addr + s->sh_addralign - 1) &
1426 ~(s->sh_addralign - 1);
1427 file_offset += addr - tmp;
1428 s->sh_offset = file_offset;
1429 s->sh_addr = addr;
1431 /* update program header infos */
1432 if (ph->p_offset == 0) {
1433 ph->p_offset = file_offset;
1434 ph->p_vaddr = addr;
1435 ph->p_paddr = ph->p_vaddr;
1437 /* update dynamic relocation infos */
1438 if (s->sh_type == SHT_REL) {
1439 if (rel_size == 0)
1440 rel_addr = addr;
1441 rel_size += s->sh_size;
1443 addr += s->sh_size;
1444 if (s->sh_type != SHT_NOBITS)
1445 file_offset += s->sh_size;
1448 ph->p_filesz = file_offset - ph->p_offset;
1449 ph->p_memsz = addr - ph->p_vaddr;
1450 ph++;
1451 if (j == 0) {
1452 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1453 /* if in the middle of a page, we duplicate the page in
1454 memory so that one copy is RX and the other is RW */
1455 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1456 addr += ELF_PAGE_SIZE;
1457 } else {
1458 addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
1459 file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
1460 ~(ELF_PAGE_SIZE - 1);
1465 /* if interpreter, then add corresponing program header */
1466 if (interp) {
1467 ph = &phdr[0];
1469 ph->p_type = PT_INTERP;
1470 ph->p_offset = interp->sh_offset;
1471 ph->p_vaddr = interp->sh_addr;
1472 ph->p_paddr = ph->p_vaddr;
1473 ph->p_filesz = interp->sh_size;
1474 ph->p_memsz = interp->sh_size;
1475 ph->p_flags = PF_R;
1476 ph->p_align = interp->sh_addralign;
1479 /* if dynamic section, then add corresponing program header */
1480 if (dynamic) {
1481 Elf32_Sym *sym_end;
1483 ph = &phdr[phnum - 1];
1485 ph->p_type = PT_DYNAMIC;
1486 ph->p_offset = dynamic->sh_offset;
1487 ph->p_vaddr = dynamic->sh_addr;
1488 ph->p_paddr = ph->p_vaddr;
1489 ph->p_filesz = dynamic->sh_size;
1490 ph->p_memsz = dynamic->sh_size;
1491 ph->p_flags = PF_R | PF_W;
1492 ph->p_align = dynamic->sh_addralign;
1494 /* put GOT dynamic section address */
1495 put32(s1->got->data, dynamic->sh_addr);
1497 /* relocate the PLT */
1498 if (file_type == TCC_OUTPUT_EXE) {
1499 uint8_t *p, *p_end;
1501 p = s1->plt->data;
1502 p_end = p + s1->plt->data_offset;
1503 if (p < p_end) {
1504 #if defined(TCC_TARGET_I386)
1505 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1506 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1507 p += 16;
1508 while (p < p_end) {
1509 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1510 p += 16;
1512 #elif defined(TCC_TARGET_ARM)
1513 int x;
1514 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1515 p +=16;
1516 while (p < p_end) {
1517 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1518 p += 16;
1520 #elif defined(TCC_TARGET_C67)
1521 /* XXX: TODO */
1522 #else
1523 #error unsupported CPU
1524 #endif
1528 /* relocate symbols in .dynsym */
1529 sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
1530 for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
1531 sym < sym_end;
1532 sym++) {
1533 if (sym->st_shndx == SHN_UNDEF) {
1534 /* relocate to the PLT if the symbol corresponds
1535 to a PLT entry */
1536 if (sym->st_value)
1537 sym->st_value += s1->plt->sh_addr;
1538 } else if (sym->st_shndx < SHN_LORESERVE) {
1539 /* do symbol relocation */
1540 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1544 /* put dynamic section entries */
1545 dynamic->data_offset = saved_dynamic_data_offset;
1546 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1547 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1548 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1549 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1550 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
1551 put_dt(dynamic, DT_REL, rel_addr);
1552 put_dt(dynamic, DT_RELSZ, rel_size);
1553 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
1554 put_dt(dynamic, DT_NULL, 0);
1557 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1558 ehdr.e_phnum = phnum;
1559 ehdr.e_phoff = sizeof(Elf32_Ehdr);
1562 /* all other sections come after */
1563 for(i = 1; i < s1->nb_sections; i++) {
1564 s = s1->sections[i];
1565 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1566 continue;
1567 section_order[sh_order_index++] = i;
1569 file_offset = (file_offset + s->sh_addralign - 1) &
1570 ~(s->sh_addralign - 1);
1571 s->sh_offset = file_offset;
1572 if (s->sh_type != SHT_NOBITS)
1573 file_offset += s->sh_size;
1576 /* if building executable or DLL, then relocate each section
1577 except the GOT which is already relocated */
1578 if (file_type != TCC_OUTPUT_OBJ) {
1579 relocate_syms(s1, 0);
1581 if (s1->nb_errors != 0) {
1582 fail:
1583 ret = -1;
1584 goto the_end;
1587 /* relocate sections */
1588 /* XXX: ignore sections with allocated relocations ? */
1589 for(i = 1; i < s1->nb_sections; i++) {
1590 s = s1->sections[i];
1591 if (s->reloc && s != s1->got)
1592 relocate_section(s1, s);
1595 /* relocate relocation entries if the relocation tables are
1596 allocated in the executable */
1597 for(i = 1; i < s1->nb_sections; i++) {
1598 s = s1->sections[i];
1599 if ((s->sh_flags & SHF_ALLOC) &&
1600 s->sh_type == SHT_REL) {
1601 relocate_rel(s1, s);
1605 /* get entry point address */
1606 if (file_type == TCC_OUTPUT_EXE)
1607 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
1608 else
1609 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1612 /* write elf file */
1613 if (file_type == TCC_OUTPUT_OBJ)
1614 mode = 0666;
1615 else
1616 mode = 0777;
1617 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1618 if (fd < 0) {
1619 error_noabort("could not write '%s'", filename);
1620 goto fail;
1622 f = fdopen(fd, "wb");
1624 #ifdef TCC_TARGET_COFF
1625 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1626 tcc_output_coff(s1, f);
1627 } else
1628 #endif
1629 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1630 sort_syms(s1, symtab_section);
1632 /* align to 4 */
1633 file_offset = (file_offset + 3) & -4;
1635 /* fill header */
1636 ehdr.e_ident[0] = ELFMAG0;
1637 ehdr.e_ident[1] = ELFMAG1;
1638 ehdr.e_ident[2] = ELFMAG2;
1639 ehdr.e_ident[3] = ELFMAG3;
1640 ehdr.e_ident[4] = ELFCLASS32;
1641 ehdr.e_ident[5] = ELFDATA2LSB;
1642 ehdr.e_ident[6] = EV_CURRENT;
1643 #ifdef __FreeBSD__
1644 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1645 #endif
1646 #ifdef TCC_TARGET_ARM
1647 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1648 #endif
1649 switch(file_type) {
1650 default:
1651 case TCC_OUTPUT_EXE:
1652 ehdr.e_type = ET_EXEC;
1653 break;
1654 case TCC_OUTPUT_DLL:
1655 ehdr.e_type = ET_DYN;
1656 break;
1657 case TCC_OUTPUT_OBJ:
1658 ehdr.e_type = ET_REL;
1659 break;
1661 ehdr.e_machine = EM_TCC_TARGET;
1662 ehdr.e_version = EV_CURRENT;
1663 ehdr.e_shoff = file_offset;
1664 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1665 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1666 ehdr.e_shnum = shnum;
1667 ehdr.e_shstrndx = shnum - 1;
1669 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1670 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1671 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1673 for(i=1;i<s1->nb_sections;i++) {
1674 s = s1->sections[section_order[i]];
1675 if (s->sh_type != SHT_NOBITS) {
1676 while (offset < s->sh_offset) {
1677 fputc(0, f);
1678 offset++;
1680 size = s->sh_size;
1681 fwrite(s->data, 1, size, f);
1682 offset += size;
1686 /* output section headers */
1687 while (offset < ehdr.e_shoff) {
1688 fputc(0, f);
1689 offset++;
1692 for(i=0;i<s1->nb_sections;i++) {
1693 sh = &shdr;
1694 memset(sh, 0, sizeof(Elf32_Shdr));
1695 s = s1->sections[i];
1696 if (s) {
1697 sh->sh_name = s->sh_name;
1698 sh->sh_type = s->sh_type;
1699 sh->sh_flags = s->sh_flags;
1700 sh->sh_entsize = s->sh_entsize;
1701 sh->sh_info = s->sh_info;
1702 if (s->link)
1703 sh->sh_link = s->link->sh_num;
1704 sh->sh_addralign = s->sh_addralign;
1705 sh->sh_addr = s->sh_addr;
1706 sh->sh_offset = s->sh_offset;
1707 sh->sh_size = s->sh_size;
1709 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1711 } else {
1712 tcc_output_binary(s1, f, section_order);
1714 fclose(f);
1716 ret = 0;
1717 the_end:
1718 tcc_free(s1->symtab_to_dynsym);
1719 tcc_free(section_order);
1720 tcc_free(phdr);
1721 tcc_free(s1->got_offsets);
1722 return ret;
1725 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1727 void *data;
1729 data = tcc_malloc(size);
1730 lseek(fd, file_offset, SEEK_SET);
1731 read(fd, data, size);
1732 return data;
1735 typedef struct SectionMergeInfo {
1736 Section *s; /* corresponding existing section */
1737 unsigned long offset; /* offset of the new section in the existing section */
1738 uint8_t new_section; /* true if section 's' was added */
1739 uint8_t link_once; /* true if link once section */
1740 } SectionMergeInfo;
1742 /* load an object file and merge it with current files */
1743 /* XXX: handle correctly stab (debug) info */
1744 static int tcc_load_object_file(TCCState *s1,
1745 int fd, unsigned long file_offset)
1747 Elf32_Ehdr ehdr;
1748 Elf32_Shdr *shdr, *sh;
1749 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1750 unsigned char *strsec, *strtab;
1751 int *old_to_new_syms;
1752 char *sh_name, *name;
1753 SectionMergeInfo *sm_table, *sm;
1754 Elf32_Sym *sym, *symtab;
1755 Elf32_Rel *rel, *rel_end;
1756 Section *s;
1758 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1759 goto fail1;
1760 if (ehdr.e_ident[0] != ELFMAG0 ||
1761 ehdr.e_ident[1] != ELFMAG1 ||
1762 ehdr.e_ident[2] != ELFMAG2 ||
1763 ehdr.e_ident[3] != ELFMAG3)
1764 goto fail1;
1765 /* test if object file */
1766 if (ehdr.e_type != ET_REL)
1767 goto fail1;
1768 /* test CPU specific stuff */
1769 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1770 ehdr.e_machine != EM_TCC_TARGET) {
1771 fail1:
1772 error_noabort("invalid object file");
1773 return -1;
1775 /* read sections */
1776 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1777 sizeof(Elf32_Shdr) * ehdr.e_shnum);
1778 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1780 /* load section names */
1781 sh = &shdr[ehdr.e_shstrndx];
1782 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1784 /* load symtab and strtab */
1785 old_to_new_syms = NULL;
1786 symtab = NULL;
1787 strtab = NULL;
1788 nb_syms = 0;
1789 for(i = 1; i < ehdr.e_shnum; i++) {
1790 sh = &shdr[i];
1791 if (sh->sh_type == SHT_SYMTAB) {
1792 if (symtab) {
1793 error_noabort("object must contain only one symtab");
1794 fail:
1795 ret = -1;
1796 goto the_end;
1798 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1799 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1800 sm_table[i].s = symtab_section;
1802 /* now load strtab */
1803 sh = &shdr[sh->sh_link];
1804 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1808 /* now examine each section and try to merge its content with the
1809 ones in memory */
1810 for(i = 1; i < ehdr.e_shnum; i++) {
1811 /* no need to examine section name strtab */
1812 if (i == ehdr.e_shstrndx)
1813 continue;
1814 sh = &shdr[i];
1815 sh_name = strsec + sh->sh_name;
1816 /* ignore sections types we do not handle */
1817 if (sh->sh_type != SHT_PROGBITS &&
1818 sh->sh_type != SHT_REL &&
1819 sh->sh_type != SHT_NOBITS)
1820 continue;
1821 if (sh->sh_addralign < 1)
1822 sh->sh_addralign = 1;
1823 /* find corresponding section, if any */
1824 for(j = 1; j < s1->nb_sections;j++) {
1825 s = s1->sections[j];
1826 if (!strcmp(s->name, sh_name)) {
1827 if (!strncmp(sh_name, ".gnu.linkonce",
1828 sizeof(".gnu.linkonce") - 1)) {
1829 /* if a 'linkonce' section is already present, we
1830 do not add it again. It is a little tricky as
1831 symbols can still be defined in
1832 it. */
1833 sm_table[i].link_once = 1;
1834 goto next;
1835 } else {
1836 goto found;
1840 /* not found: create new section */
1841 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1842 /* take as much info as possible from the section. sh_link and
1843 sh_info will be updated later */
1844 s->sh_addralign = sh->sh_addralign;
1845 s->sh_entsize = sh->sh_entsize;
1846 sm_table[i].new_section = 1;
1847 found:
1848 if (sh->sh_type != s->sh_type) {
1849 error_noabort("invalid section type");
1850 goto fail;
1853 /* align start of section */
1854 offset = s->data_offset;
1855 size = sh->sh_addralign - 1;
1856 offset = (offset + size) & ~size;
1857 if (sh->sh_addralign > s->sh_addralign)
1858 s->sh_addralign = sh->sh_addralign;
1859 s->data_offset = offset;
1860 sm_table[i].offset = offset;
1861 sm_table[i].s = s;
1862 /* concatenate sections */
1863 size = sh->sh_size;
1864 if (sh->sh_type != SHT_NOBITS) {
1865 unsigned char *ptr;
1866 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1867 ptr = section_ptr_add(s, size);
1868 read(fd, ptr, size);
1869 } else {
1870 s->data_offset += size;
1872 next: ;
1875 /* second short pass to update sh_link and sh_info fields of new
1876 sections */
1877 sm = sm_table;
1878 for(i = 1; i < ehdr.e_shnum; i++) {
1879 s = sm_table[i].s;
1880 if (!s || !sm_table[i].new_section)
1881 continue;
1882 sh = &shdr[i];
1883 if (sh->sh_link > 0)
1884 s->link = sm_table[sh->sh_link].s;
1885 if (sh->sh_type == SHT_REL) {
1886 s->sh_info = sm_table[sh->sh_info].s->sh_num;
1887 /* update backward link */
1888 s1->sections[s->sh_info]->reloc = s;
1892 /* resolve symbols */
1893 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
1895 sym = symtab + 1;
1896 for(i = 1; i < nb_syms; i++, sym++) {
1897 if (sym->st_shndx != SHN_UNDEF &&
1898 sym->st_shndx < SHN_LORESERVE) {
1899 sm = &sm_table[sym->st_shndx];
1900 if (sm->link_once) {
1901 /* if a symbol is in a link once section, we use the
1902 already defined symbol. It is very important to get
1903 correct relocations */
1904 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1905 name = strtab + sym->st_name;
1906 sym_index = find_elf_sym(symtab_section, name);
1907 if (sym_index)
1908 old_to_new_syms[i] = sym_index;
1910 continue;
1912 /* if no corresponding section added, no need to add symbol */
1913 if (!sm->s)
1914 continue;
1915 /* convert section number */
1916 sym->st_shndx = sm->s->sh_num;
1917 /* offset value */
1918 sym->st_value += sm->offset;
1920 /* add symbol */
1921 name = strtab + sym->st_name;
1922 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
1923 sym->st_info, sym->st_other,
1924 sym->st_shndx, name);
1925 old_to_new_syms[i] = sym_index;
1928 /* third pass to patch relocation entries */
1929 for(i = 1; i < ehdr.e_shnum; i++) {
1930 s = sm_table[i].s;
1931 if (!s)
1932 continue;
1933 sh = &shdr[i];
1934 offset = sm_table[i].offset;
1935 switch(s->sh_type) {
1936 case SHT_REL:
1937 /* take relocation offset information */
1938 offseti = sm_table[sh->sh_info].offset;
1939 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
1940 for(rel = (Elf32_Rel *)(s->data + offset);
1941 rel < rel_end;
1942 rel++) {
1943 int type;
1944 unsigned sym_index;
1945 /* convert symbol index */
1946 type = ELF32_R_TYPE(rel->r_info);
1947 sym_index = ELF32_R_SYM(rel->r_info);
1948 /* NOTE: only one symtab assumed */
1949 if (sym_index >= nb_syms)
1950 goto invalid_reloc;
1951 sym_index = old_to_new_syms[sym_index];
1952 if (!sym_index) {
1953 invalid_reloc:
1954 error_noabort("Invalid relocation entry");
1955 goto fail;
1957 rel->r_info = ELF32_R_INFO(sym_index, type);
1958 /* offset the relocation offset */
1959 rel->r_offset += offseti;
1961 break;
1962 default:
1963 break;
1967 ret = 0;
1968 the_end:
1969 tcc_free(symtab);
1970 tcc_free(strtab);
1971 tcc_free(old_to_new_syms);
1972 tcc_free(sm_table);
1973 tcc_free(strsec);
1974 tcc_free(shdr);
1975 return ret;
1978 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1980 typedef struct ArchiveHeader {
1981 char ar_name[16]; /* name of this member */
1982 char ar_date[12]; /* file mtime */
1983 char ar_uid[6]; /* owner uid; printed as decimal */
1984 char ar_gid[6]; /* owner gid; printed as decimal */
1985 char ar_mode[8]; /* file mode, printed as octal */
1986 char ar_size[10]; /* file size, printed as decimal */
1987 char ar_fmag[2]; /* should contain ARFMAG */
1988 } ArchiveHeader;
1990 static int get_be32(const uint8_t *b)
1992 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
1995 /* load only the objects which resolve undefined symbols */
1996 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
1998 int i, bound, nsyms, sym_index, off, ret;
1999 uint8_t *data;
2000 const char *ar_names, *p;
2001 const uint8_t *ar_index;
2002 Elf32_Sym *sym;
2004 data = tcc_malloc(size);
2005 if (read(fd, data, size) != size)
2006 goto fail;
2007 nsyms = get_be32(data);
2008 ar_index = data + 4;
2009 ar_names = ar_index + nsyms * 4;
2011 do {
2012 bound = 0;
2013 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2014 sym_index = find_elf_sym(symtab_section, p);
2015 if(sym_index) {
2016 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
2017 if(sym->st_shndx == SHN_UNDEF) {
2018 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2019 #if 0
2020 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2021 #endif
2022 ++bound;
2023 lseek(fd, off, SEEK_SET);
2024 if(tcc_load_object_file(s1, fd, off) < 0) {
2025 fail:
2026 ret = -1;
2027 goto the_end;
2032 } while(bound);
2033 ret = 0;
2034 the_end:
2035 tcc_free(data);
2036 return ret;
2039 /* load a '.a' file */
2040 static int tcc_load_archive(TCCState *s1, int fd)
2042 ArchiveHeader hdr;
2043 char ar_size[11];
2044 char ar_name[17];
2045 char magic[8];
2046 int size, len, i;
2047 unsigned long file_offset;
2049 /* skip magic which was already checked */
2050 read(fd, magic, sizeof(magic));
2052 for(;;) {
2053 len = read(fd, &hdr, sizeof(hdr));
2054 if (len == 0)
2055 break;
2056 if (len != sizeof(hdr)) {
2057 error_noabort("invalid archive");
2058 return -1;
2060 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2061 ar_size[sizeof(hdr.ar_size)] = '\0';
2062 size = strtol(ar_size, NULL, 0);
2063 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2064 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2065 if (ar_name[i] != ' ')
2066 break;
2068 ar_name[i + 1] = '\0';
2069 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2070 file_offset = lseek(fd, 0, SEEK_CUR);
2071 /* align to even */
2072 size = (size + 1) & ~1;
2073 if (!strcmp(ar_name, "/")) {
2074 /* coff symbol table : we handle it */
2075 if(s1->alacarte_link)
2076 return tcc_load_alacarte(s1, fd, size);
2077 } else if (!strcmp(ar_name, "//") ||
2078 !strcmp(ar_name, "__.SYMDEF") ||
2079 !strcmp(ar_name, "__.SYMDEF/") ||
2080 !strcmp(ar_name, "ARFILENAMES/")) {
2081 /* skip symbol table or archive names */
2082 } else {
2083 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2084 return -1;
2086 lseek(fd, file_offset + size, SEEK_SET);
2088 return 0;
2091 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2092 is referenced by the user (so it should be added as DT_NEEDED in
2093 the generated ELF file) */
2094 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2096 Elf32_Ehdr ehdr;
2097 Elf32_Shdr *shdr, *sh, *sh1;
2098 int i, nb_syms, nb_dts, sym_bind, ret;
2099 Elf32_Sym *sym, *dynsym;
2100 Elf32_Dyn *dt, *dynamic;
2101 unsigned char *dynstr;
2102 const char *name, *soname, *p;
2103 DLLReference *dllref;
2105 read(fd, &ehdr, sizeof(ehdr));
2107 /* test CPU specific stuff */
2108 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2109 ehdr.e_machine != EM_TCC_TARGET) {
2110 error_noabort("bad architecture");
2111 return -1;
2114 /* read sections */
2115 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
2117 /* load dynamic section and dynamic symbols */
2118 nb_syms = 0;
2119 nb_dts = 0;
2120 dynamic = NULL;
2121 dynsym = NULL; /* avoid warning */
2122 dynstr = NULL; /* avoid warning */
2123 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2124 switch(sh->sh_type) {
2125 case SHT_DYNAMIC:
2126 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
2127 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2128 break;
2129 case SHT_DYNSYM:
2130 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
2131 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2132 sh1 = &shdr[sh->sh_link];
2133 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2134 break;
2135 default:
2136 break;
2140 /* compute the real library name */
2141 soname = filename;
2142 p = strrchr(soname, '/');
2143 if (p)
2144 soname = p + 1;
2146 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2147 if (dt->d_tag == DT_SONAME) {
2148 soname = dynstr + dt->d_un.d_val;
2152 /* if the dll is already loaded, do not load it */
2153 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2154 dllref = s1->loaded_dlls[i];
2155 if (!strcmp(soname, dllref->name)) {
2156 /* but update level if needed */
2157 if (level < dllref->level)
2158 dllref->level = level;
2159 ret = 0;
2160 goto the_end;
2164 // printf("loading dll '%s'\n", soname);
2166 /* add the dll and its level */
2167 dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
2168 dllref->level = level;
2169 strcpy(dllref->name, soname);
2170 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2172 /* add dynamic symbols in dynsym_section */
2173 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2174 sym_bind = ELF32_ST_BIND(sym->st_info);
2175 if (sym_bind == STB_LOCAL)
2176 continue;
2177 name = dynstr + sym->st_name;
2178 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2179 sym->st_info, sym->st_other, sym->st_shndx, name);
2182 /* load all referenced DLLs */
2183 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2184 switch(dt->d_tag) {
2185 case DT_NEEDED:
2186 name = dynstr + dt->d_un.d_val;
2187 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2188 dllref = s1->loaded_dlls[i];
2189 if (!strcmp(name, dllref->name))
2190 goto already_loaded;
2192 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2193 error_noabort("referenced dll '%s' not found", name);
2194 ret = -1;
2195 goto the_end;
2197 already_loaded:
2198 break;
2201 ret = 0;
2202 the_end:
2203 tcc_free(dynstr);
2204 tcc_free(dynsym);
2205 tcc_free(dynamic);
2206 tcc_free(shdr);
2207 return ret;
2210 #define LD_TOK_NAME 256
2211 #define LD_TOK_EOF (-1)
2213 /* return next ld script token */
2214 static int ld_next(TCCState *s1, char *name, int name_size)
2216 int c;
2217 char *q;
2219 redo:
2220 switch(ch) {
2221 case ' ':
2222 case '\t':
2223 case '\f':
2224 case '\v':
2225 case '\r':
2226 case '\n':
2227 inp();
2228 goto redo;
2229 case '/':
2230 minp();
2231 if (ch == '*') {
2232 file->buf_ptr = parse_comment(file->buf_ptr);
2233 ch = file->buf_ptr[0];
2234 goto redo;
2235 } else {
2236 q = name;
2237 *q++ = '/';
2238 goto parse_name;
2240 break;
2241 case 'a' ... 'z':
2242 case 'A' ... 'Z':
2243 case '_':
2244 case '\\':
2245 case '.':
2246 case '$':
2247 case '~':
2248 q = name;
2249 parse_name:
2250 for(;;) {
2251 if (!((ch >= 'a' && ch <= 'z') ||
2252 (ch >= 'A' && ch <= 'Z') ||
2253 (ch >= '0' && ch <= '9') ||
2254 strchr("/.-_+=$:\\,~", ch)))
2255 break;
2256 if ((q - name) < name_size - 1) {
2257 *q++ = ch;
2259 minp();
2261 *q = '\0';
2262 c = LD_TOK_NAME;
2263 break;
2264 case CH_EOF:
2265 c = LD_TOK_EOF;
2266 break;
2267 default:
2268 c = ch;
2269 inp();
2270 break;
2272 #if 0
2273 printf("tok=%c %d\n", c, c);
2274 if (c == LD_TOK_NAME)
2275 printf(" name=%s\n", name);
2276 #endif
2277 return c;
2280 static int ld_add_file_list(TCCState *s1, int as_needed)
2282 char filename[1024];
2283 int t, ret;
2285 t = ld_next(s1, filename, sizeof(filename));
2286 if (t != '(')
2287 expect("(");
2288 t = ld_next(s1, filename, sizeof(filename));
2289 for(;;) {
2290 if (t == LD_TOK_EOF) {
2291 error_noabort("unexpected end of file");
2292 return -1;
2293 } else if (t == ')') {
2294 break;
2295 } else if (t != LD_TOK_NAME) {
2296 error_noabort("filename expected");
2297 return -1;
2299 if (!strcmp(filename, "AS_NEEDED")) {
2300 ret = ld_add_file_list(s1, 1);
2301 if (ret)
2302 return ret;
2303 } else {
2304 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2305 if (!as_needed)
2306 tcc_add_file(s1, filename);
2308 t = ld_next(s1, filename, sizeof(filename));
2309 if (t == ',') {
2310 t = ld_next(s1, filename, sizeof(filename));
2313 return 0;
2316 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2317 files */
2318 static int tcc_load_ldscript(TCCState *s1)
2320 char cmd[64];
2321 char filename[1024];
2322 int t, ret;
2324 ch = file->buf_ptr[0];
2325 ch = handle_eob();
2326 for(;;) {
2327 t = ld_next(s1, cmd, sizeof(cmd));
2328 if (t == LD_TOK_EOF)
2329 return 0;
2330 else if (t != LD_TOK_NAME)
2331 return -1;
2332 if (!strcmp(cmd, "INPUT") ||
2333 !strcmp(cmd, "GROUP")) {
2334 ret = ld_add_file_list(s1, 0);
2335 if (ret)
2336 return ret;
2337 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2338 !strcmp(cmd, "TARGET")) {
2339 /* ignore some commands */
2340 t = ld_next(s1, cmd, sizeof(cmd));
2341 if (t != '(')
2342 expect("(");
2343 for(;;) {
2344 t = ld_next(s1, filename, sizeof(filename));
2345 if (t == LD_TOK_EOF) {
2346 error_noabort("unexpected end of file");
2347 return -1;
2348 } else if (t == ')') {
2349 break;
2352 } else {
2353 return -1;
2356 return 0;