fixed linker symbol generation - output format support
[tinycc.git] / tccelf.c
blobc5dc023e847050a83ff2f87f847a520ae338845a
1 /*
2 * ELF file handling for TCC
3 *
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 static int put_elf_str(Section *s, const char *sym)
23 int offset, len;
24 char *ptr;
26 len = strlen(sym) + 1;
27 offset = s->data_offset;
28 ptr = section_ptr_add(s, len);
29 memcpy(ptr, sym, len);
30 return offset;
33 /* elf symbol hashing function */
34 static unsigned long elf_hash(const unsigned char *name)
36 unsigned long h = 0, g;
38 while (*name) {
39 h = (h << 4) + *name++;
40 g = h & 0xf0000000;
41 if (g)
42 h ^= g >> 24;
43 h &= ~g;
45 return h;
48 /* rebuild hash table of section s */
49 /* NOTE: we do factorize the hash table code to go faster */
50 static void rebuild_hash(Section *s, unsigned int nb_buckets)
52 Elf32_Sym *sym;
53 int *ptr, *hash, nb_syms, sym_index, h;
54 char *strtab;
56 strtab = s->link->data;
57 nb_syms = s->data_offset / sizeof(Elf32_Sym);
59 s->hash->data_offset = 0;
60 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
61 ptr[0] = nb_buckets;
62 ptr[1] = nb_syms;
63 ptr += 2;
64 hash = ptr;
65 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
66 ptr += nb_buckets + 1;
68 sym = (Elf32_Sym *)s->data + 1;
69 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
70 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
71 h = elf_hash(strtab + sym->st_name) % nb_buckets;
72 *ptr = hash[h];
73 hash[h] = sym_index;
74 } else {
75 *ptr = 0;
77 ptr++;
78 sym++;
82 /* return the symbol number */
83 static int put_elf_sym(Section *s,
84 unsigned long value, unsigned long size,
85 int info, int other, int shndx, const char *name)
87 int name_offset, sym_index;
88 int nbuckets, h;
89 Elf32_Sym *sym;
90 Section *hs;
92 sym = section_ptr_add(s, sizeof(Elf32_Sym));
93 if (name)
94 name_offset = put_elf_str(s->link, name);
95 else
96 name_offset = 0;
97 /* XXX: endianness */
98 sym->st_name = name_offset;
99 sym->st_value = value;
100 sym->st_size = size;
101 sym->st_info = info;
102 sym->st_other = other;
103 sym->st_shndx = shndx;
104 sym_index = sym - (Elf32_Sym *)s->data;
105 hs = s->hash;
106 if (hs) {
107 int *ptr, *base;
108 ptr = section_ptr_add(hs, sizeof(int));
109 base = (int *)hs->data;
110 /* only add global or weak symbols */
111 if (ELF32_ST_BIND(info) != STB_LOCAL) {
112 /* add another hashing entry */
113 nbuckets = base[0];
114 h = elf_hash(name) % nbuckets;
115 *ptr = base[2 + h];
116 base[2 + h] = sym_index;
117 base[1]++;
118 /* we resize the hash table */
119 hs->nb_hashed_syms++;
120 if (hs->nb_hashed_syms > 2 * nbuckets) {
121 rebuild_hash(s, 2 * nbuckets);
123 } else {
124 *ptr = 0;
125 base[1]++;
128 return sym_index;
131 /* find global ELF symbol 'name' and return its index. Return 0 if not
132 found. */
133 static int find_elf_sym(Section *s, const char *name)
135 Elf32_Sym *sym;
136 Section *hs;
137 int nbuckets, sym_index, h;
138 const char *name1;
140 hs = s->hash;
141 if (!hs)
142 return 0;
143 nbuckets = ((int *)hs->data)[0];
144 h = elf_hash(name) % nbuckets;
145 sym_index = ((int *)hs->data)[2 + h];
146 while (sym_index != 0) {
147 sym = &((Elf32_Sym *)s->data)[sym_index];
148 name1 = s->link->data + sym->st_name;
149 if (!strcmp(name, name1))
150 return sym_index;
151 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
153 return 0;
156 /* return elf symbol value or error */
157 int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name)
159 int sym_index;
160 Elf32_Sym *sym;
162 sym_index = find_elf_sym(symtab_section, name);
163 if (!sym_index)
164 return -1;
165 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
166 *pval = sym->st_value;
167 return 0;
170 void *tcc_get_symbol_err(TCCState *s, const char *name)
172 unsigned long val;
173 if (tcc_get_symbol(s, &val, name) < 0)
174 error("%s not defined", name);
175 return (void *)val;
178 /* add an elf symbol : check if it is already defined and patch
179 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
180 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
181 int info, int sh_num, const char *name)
183 Elf32_Sym *esym;
184 int sym_bind, sym_index, sym_type, esym_bind;
186 sym_bind = ELF32_ST_BIND(info);
187 sym_type = ELF32_ST_TYPE(info);
189 if (sym_bind != STB_LOCAL) {
190 /* we search global or weak symbols */
191 sym_index = find_elf_sym(s, name);
192 if (!sym_index)
193 goto do_def;
194 esym = &((Elf32_Sym *)s->data)[sym_index];
195 if (esym->st_shndx != SHN_UNDEF) {
196 esym_bind = ELF32_ST_BIND(esym->st_info);
197 if (sh_num == SHN_UNDEF) {
198 /* ignore adding of undefined symbol if the
199 corresponding symbol is already defined */
200 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
201 /* global overrides weak, so patch */
202 goto do_patch;
203 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
204 /* weak is ignored if already global */
205 } else {
206 #if 0
207 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
208 sym_bind, sh_num, esym_bind, esym->st_shndx);
209 #endif
210 /* NOTE: we accept that two DLL define the same symbol */
211 if (s != tcc_state->dynsymtab_section)
212 error_noabort("'%s' defined twice", name);
214 } else {
215 do_patch:
216 esym->st_info = ELF32_ST_INFO(sym_bind, sym_type);
217 esym->st_shndx = sh_num;
218 esym->st_value = value;
219 esym->st_size = size;
221 } else {
222 do_def:
223 sym_index = put_elf_sym(s, value, size,
224 ELF32_ST_INFO(sym_bind, sym_type), 0,
225 sh_num, name);
227 return sym_index;
230 /* put relocation */
231 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
232 int type, int symbol)
234 char buf[256];
235 Section *sr;
236 Elf32_Rel *rel;
238 sr = s->reloc;
239 if (!sr) {
240 /* if no relocation section, create it */
241 snprintf(buf, sizeof(buf), ".rel%s", s->name);
242 /* if the symtab is allocated, then we consider the relocation
243 are also */
244 sr = new_section(tcc_state, buf, SHT_REL, symtab->sh_flags);
245 sr->sh_entsize = sizeof(Elf32_Rel);
246 sr->link = symtab;
247 sr->sh_info = s->sh_num;
248 s->reloc = sr;
250 rel = section_ptr_add(sr, sizeof(Elf32_Rel));
251 rel->r_offset = offset;
252 rel->r_info = ELF32_R_INFO(symbol, type);
255 /* put stab debug information */
257 typedef struct {
258 unsigned long n_strx; /* index into string table of name */
259 unsigned char n_type; /* type of symbol */
260 unsigned char n_other; /* misc info (usually empty) */
261 unsigned short n_desc; /* description field */
262 unsigned long n_value; /* value of symbol */
263 } Stab_Sym;
265 static void put_stabs(const char *str, int type, int other, int desc,
266 unsigned long value)
268 Stab_Sym *sym;
270 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
271 if (str) {
272 sym->n_strx = put_elf_str(stabstr_section, str);
273 } else {
274 sym->n_strx = 0;
276 sym->n_type = type;
277 sym->n_other = other;
278 sym->n_desc = desc;
279 sym->n_value = value;
282 static void put_stabs_r(const char *str, int type, int other, int desc,
283 unsigned long value, Section *sec, int sym_index)
285 put_stabs(str, type, other, desc, value);
286 put_elf_reloc(symtab_section, stab_section,
287 stab_section->data_offset - sizeof(unsigned long),
288 R_DATA_32, sym_index);
291 static void put_stabn(int type, int other, int desc, int value)
293 put_stabs(NULL, type, other, desc, value);
296 static void put_stabd(int type, int other, int desc)
298 put_stabs(NULL, type, other, desc, 0);
301 /* In an ELF file symbol table, the local symbols must appear below
302 the global and weak ones. Since TCC cannot sort it while generating
303 the code, we must do it after. All the relocation tables are also
304 modified to take into account the symbol table sorting */
305 static void sort_syms(TCCState *s1, Section *s)
307 int *old_to_new_syms;
308 Elf32_Sym *new_syms;
309 int nb_syms, i;
310 Elf32_Sym *p, *q;
311 Elf32_Rel *rel, *rel_end;
312 Section *sr;
313 int type, sym_index;
315 nb_syms = s->data_offset / sizeof(Elf32_Sym);
316 new_syms = tcc_malloc(nb_syms * sizeof(Elf32_Sym));
317 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
319 /* first pass for local symbols */
320 p = (Elf32_Sym *)s->data;
321 q = new_syms;
322 for(i = 0; i < nb_syms; i++) {
323 if (ELF32_ST_BIND(p->st_info) == STB_LOCAL) {
324 old_to_new_syms[i] = q - new_syms;
325 *q++ = *p;
327 p++;
329 /* save the number of local symbols in section header */
330 s->sh_info = q - new_syms;
332 /* then second pass for non local symbols */
333 p = (Elf32_Sym *)s->data;
334 for(i = 0; i < nb_syms; i++) {
335 if (ELF32_ST_BIND(p->st_info) != STB_LOCAL) {
336 old_to_new_syms[i] = q - new_syms;
337 *q++ = *p;
339 p++;
342 /* we copy the new symbols to the old */
343 memcpy(s->data, new_syms, nb_syms * sizeof(Elf32_Sym));
344 tcc_free(new_syms);
346 /* now we modify all the relocations */
347 for(i = 1; i < s1->nb_sections; i++) {
348 sr = s1->sections[i];
349 if (sr->sh_type == SHT_REL && sr->link == s) {
350 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
351 for(rel = (Elf32_Rel *)sr->data;
352 rel < rel_end;
353 rel++) {
354 sym_index = ELF32_R_SYM(rel->r_info);
355 type = ELF32_R_TYPE(rel->r_info);
356 sym_index = old_to_new_syms[sym_index];
357 rel->r_info = ELF32_R_INFO(sym_index, type);
362 tcc_free(old_to_new_syms);
365 /* relocate common symbols in the .bss section */
366 static void relocate_common_syms(void)
368 Elf32_Sym *sym, *sym_end;
369 unsigned long offset, align;
371 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
372 for(sym = (Elf32_Sym *)symtab_section->data + 1;
373 sym < sym_end;
374 sym++) {
375 if (sym->st_shndx == SHN_COMMON) {
376 /* align symbol */
377 align = sym->st_value;
378 offset = bss_section->data_offset;
379 offset = (offset + align - 1) & -align;
380 sym->st_value = offset;
381 sym->st_shndx = bss_section->sh_num;
382 offset += sym->st_size;
383 bss_section->data_offset = offset;
388 static void *resolve_sym(const char *sym)
390 return dlsym(RTLD_DEFAULT, sym);
393 /* relocate symbol table, resolve undefined symbols if do_resolve is
394 true and output error if undefined symbol. */
395 static void relocate_syms(TCCState *s1, int do_resolve)
397 Elf32_Sym *sym, *esym, *sym_end;
398 int sym_bind, sh_num, sym_index;
399 const char *name;
400 unsigned long addr;
402 sym_end = (Elf32_Sym *)(symtab_section->data + symtab_section->data_offset);
403 for(sym = (Elf32_Sym *)symtab_section->data + 1;
404 sym < sym_end;
405 sym++) {
406 sh_num = sym->st_shndx;
407 if (sh_num == SHN_UNDEF) {
408 name = strtab_section->data + sym->st_name;
409 if (do_resolve) {
410 name = symtab_section->link->data + sym->st_name;
411 addr = (unsigned long)resolve_sym(name);
412 if (addr) {
413 sym->st_value = addr;
414 goto found;
416 } else if (s1->dynsym) {
417 /* if dynamic symbol exist, then use it */
418 sym_index = find_elf_sym(s1->dynsym, name);
419 if (sym_index) {
420 esym = &((Elf32_Sym *)s1->dynsym->data)[sym_index];
421 sym->st_value = esym->st_value;
422 goto found;
425 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
426 it */
427 if (!strcmp(name, "_fp_hw"))
428 goto found;
429 /* only weak symbols are accepted to be undefined. Their
430 value is zero */
431 sym_bind = ELF32_ST_BIND(sym->st_info);
432 if (sym_bind == STB_WEAK) {
433 sym->st_value = 0;
434 } else {
435 error_noabort("undefined symbol '%s'", name);
437 } else if (sh_num < SHN_LORESERVE) {
438 /* add section base */
439 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
441 found: ;
445 /* relocate a given section (CPU dependent) */
446 static void relocate_section(TCCState *s1, Section *s)
448 Section *sr;
449 Elf32_Rel *rel, *rel_end, *qrel;
450 Elf32_Sym *sym;
451 int type, sym_index, esym_index;
452 unsigned char *ptr;
453 unsigned long val, addr;
455 sr = s->reloc;
456 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
457 qrel = (Elf32_Rel *)sr->data;
458 for(rel = qrel;
459 rel < rel_end;
460 rel++) {
461 ptr = s->data + rel->r_offset;
463 sym_index = ELF32_R_SYM(rel->r_info);
464 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
465 val = sym->st_value;
466 type = ELF32_R_TYPE(rel->r_info);
467 addr = s->sh_addr + rel->r_offset;
469 /* CPU specific */
470 switch(type) {
471 #if defined(TCC_TARGET_I386)
472 case R_386_32:
473 if (s1->output_type == TCC_OUTPUT_DLL) {
474 esym_index = s1->symtab_to_dynsym[sym_index];
475 qrel->r_offset = rel->r_offset;
476 if (esym_index) {
477 qrel->r_info = ELF32_R_INFO(esym_index, R_386_32);
478 qrel++;
479 break;
480 } else {
481 qrel->r_info = ELF32_R_INFO(0, R_386_RELATIVE);
482 qrel++;
485 *(int *)ptr += val;
486 break;
487 case R_386_PC32:
488 if (s1->output_type == TCC_OUTPUT_DLL) {
489 /* DLL relocation */
490 esym_index = s1->symtab_to_dynsym[sym_index];
491 if (esym_index) {
492 qrel->r_offset = rel->r_offset;
493 qrel->r_info = ELF32_R_INFO(esym_index, R_386_PC32);
494 qrel++;
495 break;
498 *(int *)ptr += val - addr;
499 break;
500 case R_386_PLT32:
501 *(int *)ptr += val - addr;
502 break;
503 case R_386_GLOB_DAT:
504 case R_386_JMP_SLOT:
505 *(int *)ptr = val;
506 break;
507 case R_386_GOTPC:
508 *(int *)ptr += s1->got->sh_addr - addr;
509 break;
510 case R_386_GOTOFF:
511 *(int *)ptr += val - s1->got->sh_addr;
512 break;
513 case R_386_GOT32:
514 /* we load the got offset */
515 *(int *)ptr += s1->got_offsets[sym_index];
516 break;
517 #elif defined(TCC_TARGET_ARM)
518 case R_ARM_PC24:
519 case R_ARM_PLT32:
521 int x;
522 x = (*(int *)ptr)&0xffffff;
523 (*(int *)ptr) &= 0xff000000;
524 if (x & 0x800000)
525 x -= 0x1000000;
526 x *= 4;
527 x += val - addr;
528 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
529 error("can't relocate value at %x",addr);
530 x >>= 2;
531 x &= 0xffffff;
532 (*(int *)ptr) |= x;
534 break;
535 case R_ARM_ABS32:
536 *(int *)ptr += val;
537 break;
538 case R_ARM_GOTPC:
539 *(int *)ptr += s1->got->sh_addr - addr;
540 break;
541 case R_ARM_GOT32:
542 /* we load the got offset */
543 *(int *)ptr += s1->got_offsets[sym_index];
544 break;
545 case R_ARM_COPY:
546 break;
547 default:
548 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
549 type,addr,(unsigned int )ptr,val);
550 break;
551 #elif defined(TCC_TARGET_C67)
552 case R_C60_32:
553 *(int *)ptr += val;
554 break;
555 case R_C60LO16:
557 uint32_t orig;
559 /* put the low 16 bits of the absolute address */
560 // add to what is already there
562 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
563 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
565 //patch both at once - assumes always in pairs Low - High
567 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
568 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
570 break;
571 case R_C60HI16:
572 break;
573 default:
574 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
575 type,addr,(unsigned int )ptr,val);
576 break;
577 #else
578 #error unsupported processor
579 #endif
582 /* if the relocation is allocated, we change its symbol table */
583 if (sr->sh_flags & SHF_ALLOC)
584 sr->link = s1->dynsym;
587 /* relocate relocation table in 'sr' */
588 static void relocate_rel(TCCState *s1, Section *sr)
590 Section *s;
591 Elf32_Rel *rel, *rel_end;
593 s = s1->sections[sr->sh_info];
594 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
595 for(rel = (Elf32_Rel *)sr->data;
596 rel < rel_end;
597 rel++) {
598 rel->r_offset += s->sh_addr;
602 /* count the number of dynamic relocations so that we can reserve
603 their space */
604 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
606 Elf32_Rel *rel, *rel_end;
607 int sym_index, esym_index, type, count;
609 count = 0;
610 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
611 for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) {
612 sym_index = ELF32_R_SYM(rel->r_info);
613 type = ELF32_R_TYPE(rel->r_info);
614 switch(type) {
615 case R_386_32:
616 count++;
617 break;
618 case R_386_PC32:
619 esym_index = s1->symtab_to_dynsym[sym_index];
620 if (esym_index)
621 count++;
622 break;
623 default:
624 break;
627 if (count) {
628 /* allocate the section */
629 sr->sh_flags |= SHF_ALLOC;
630 sr->sh_size = count * sizeof(Elf32_Rel);
632 return count;
635 static void put_got_offset(TCCState *s1, int index, unsigned long val)
637 int n;
638 unsigned long *tab;
640 if (index >= s1->nb_got_offsets) {
641 /* find immediately bigger power of 2 and reallocate array */
642 n = 1;
643 while (index >= n)
644 n *= 2;
645 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
646 if (!tab)
647 error("memory full");
648 s1->got_offsets = tab;
649 memset(s1->got_offsets + s1->nb_got_offsets, 0,
650 (n - s1->nb_got_offsets) * sizeof(unsigned long));
651 s1->nb_got_offsets = n;
653 s1->got_offsets[index] = val;
656 /* XXX: suppress that */
657 static void put32(unsigned char *p, uint32_t val)
659 p[0] = val;
660 p[1] = val >> 8;
661 p[2] = val >> 16;
662 p[3] = val >> 24;
665 static uint32_t get32(unsigned char *p)
667 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
670 static void build_got(TCCState *s1)
672 unsigned char *ptr;
674 /* if no got, then create it */
675 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
676 s1->got->sh_entsize = 4;
677 add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
678 s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
679 ptr = section_ptr_add(s1->got, 3 * sizeof(int));
680 /* keep space for _DYNAMIC pointer, if present */
681 put32(ptr, 0);
682 /* two dummy got entries */
683 put32(ptr + 4, 0);
684 put32(ptr + 8, 0);
687 /* put a got entry corresponding to a symbol in symtab_section. 'size'
688 and 'info' can be modifed if more precise info comes from the DLL */
689 static void put_got_entry(TCCState *s1,
690 int reloc_type, unsigned long size, int info,
691 int sym_index)
693 int index;
694 const char *name;
695 Elf32_Sym *sym;
696 unsigned long offset;
697 int *ptr;
699 if (!s1->got)
700 build_got(s1);
702 /* if a got entry already exists for that symbol, no need to add one */
703 if (sym_index < s1->nb_got_offsets &&
704 s1->got_offsets[sym_index] != 0)
705 return;
707 put_got_offset(s1, sym_index, s1->got->data_offset);
709 if (s1->dynsym) {
710 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
711 name = symtab_section->link->data + sym->st_name;
712 offset = sym->st_value;
713 #ifdef TCC_TARGET_I386
714 if (reloc_type == R_386_JMP_SLOT) {
715 Section *plt;
716 uint8_t *p;
717 int modrm;
719 /* if we build a DLL, we add a %ebx offset */
720 if (s1->output_type == TCC_OUTPUT_DLL)
721 modrm = 0xa3;
722 else
723 modrm = 0x25;
725 /* add a PLT entry */
726 plt = s1->plt;
727 if (plt->data_offset == 0) {
728 /* first plt entry */
729 p = section_ptr_add(plt, 16);
730 p[0] = 0xff; /* pushl got + 4 */
731 p[1] = modrm + 0x10;
732 put32(p + 2, 4);
733 p[6] = 0xff; /* jmp *(got + 8) */
734 p[7] = modrm;
735 put32(p + 8, 8);
738 p = section_ptr_add(plt, 16);
739 p[0] = 0xff; /* jmp *(got + x) */
740 p[1] = modrm;
741 put32(p + 2, s1->got->data_offset);
742 p[6] = 0x68; /* push $xxx */
743 put32(p + 7, (plt->data_offset - 32) >> 1);
744 p[11] = 0xe9; /* jmp plt_start */
745 put32(p + 12, -(plt->data_offset));
747 /* the symbol is modified so that it will be relocated to
748 the PLT */
749 if (s1->output_type == TCC_OUTPUT_EXE)
750 offset = plt->data_offset - 16;
752 #elif defined(TCC_TARGET_ARM)
753 if (reloc_type == R_ARM_JUMP_SLOT) {
754 Section *plt;
755 uint8_t *p;
757 /* if we build a DLL, we add a %ebx offset */
758 if (s1->output_type == TCC_OUTPUT_DLL)
759 error("DLLs unimplemented!");
761 /* add a PLT entry */
762 plt = s1->plt;
763 if (plt->data_offset == 0) {
764 /* first plt entry */
765 p = section_ptr_add(plt, 16);
766 put32(p , 0xe52de004);
767 put32(p + 4, 0xe59fe010);
768 put32(p + 8, 0xe08fe00e);
769 put32(p + 12, 0xe5bef008);
772 p = section_ptr_add(plt, 16);
773 put32(p , 0xe59fc004);
774 put32(p+4, 0xe08fc00c);
775 put32(p+8, 0xe59cf000);
776 put32(p+12, s1->got->data_offset);
778 /* the symbol is modified so that it will be relocated to
779 the PLT */
780 if (s1->output_type == TCC_OUTPUT_EXE)
781 offset = plt->data_offset - 16;
783 #elif defined(TCC_TARGET_C67)
784 error("C67 got not implemented");
785 #else
786 #error unsupported CPU
787 #endif
788 index = put_elf_sym(s1->dynsym, offset,
789 size, info, 0, sym->st_shndx, name);
790 /* put a got entry */
791 put_elf_reloc(s1->dynsym, s1->got,
792 s1->got->data_offset,
793 reloc_type, index);
795 ptr = section_ptr_add(s1->got, sizeof(int));
796 *ptr = 0;
799 /* build GOT and PLT entries */
800 static void build_got_entries(TCCState *s1)
802 Section *s, *symtab;
803 Elf32_Rel *rel, *rel_end;
804 Elf32_Sym *sym;
805 int i, type, reloc_type, sym_index;
807 for(i = 1; i < s1->nb_sections; i++) {
808 s = s1->sections[i];
809 if (s->sh_type != SHT_REL)
810 continue;
811 /* no need to handle got relocations */
812 if (s->link != symtab_section)
813 continue;
814 symtab = s->link;
815 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
816 for(rel = (Elf32_Rel *)s->data;
817 rel < rel_end;
818 rel++) {
819 type = ELF32_R_TYPE(rel->r_info);
820 switch(type) {
821 #if defined(TCC_TARGET_I386)
822 case R_386_GOT32:
823 case R_386_GOTOFF:
824 case R_386_GOTPC:
825 case R_386_PLT32:
826 if (!s1->got)
827 build_got(s1);
828 if (type == R_386_GOT32 || type == R_386_PLT32) {
829 sym_index = ELF32_R_SYM(rel->r_info);
830 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
831 /* look at the symbol got offset. If none, then add one */
832 if (type == R_386_GOT32)
833 reloc_type = R_386_GLOB_DAT;
834 else
835 reloc_type = R_386_JMP_SLOT;
836 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
837 sym_index);
839 break;
840 #elif defined(TCC_TARGET_ARM)
841 case R_ARM_GOT32:
842 case R_ARM_GOTOFF:
843 case R_ARM_GOTPC:
844 case R_ARM_PLT32:
845 if (!s1->got)
846 build_got(s1);
847 if (type == R_ARM_GOT32 || type == R_ARM_PLT32) {
848 sym_index = ELF32_R_SYM(rel->r_info);
849 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
850 /* look at the symbol got offset. If none, then add one */
851 if (type == R_ARM_GOT32)
852 reloc_type = R_ARM_GLOB_DAT;
853 else
854 reloc_type = R_ARM_JUMP_SLOT;
855 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
856 sym_index);
858 break;
859 #elif defined(TCC_TARGET_C67)
860 case R_C60_GOT32:
861 case R_C60_GOTOFF:
862 case R_C60_GOTPC:
863 case R_C60_PLT32:
864 if (!s1->got)
865 build_got(s1);
866 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
867 sym_index = ELF32_R_SYM(rel->r_info);
868 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
869 /* look at the symbol got offset. If none, then add one */
870 if (type == R_C60_GOT32)
871 reloc_type = R_C60_GLOB_DAT;
872 else
873 reloc_type = R_C60_JMP_SLOT;
874 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
875 sym_index);
877 break;
878 #else
879 #error unsupported CPU
880 #endif
881 default:
882 break;
888 static Section *new_symtab(TCCState *s1,
889 const char *symtab_name, int sh_type, int sh_flags,
890 const char *strtab_name,
891 const char *hash_name, int hash_sh_flags)
893 Section *symtab, *strtab, *hash;
894 int *ptr, nb_buckets;
896 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
897 symtab->sh_entsize = sizeof(Elf32_Sym);
898 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
899 put_elf_str(strtab, "");
900 symtab->link = strtab;
901 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
903 nb_buckets = 1;
905 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
906 hash->sh_entsize = sizeof(int);
907 symtab->hash = hash;
908 hash->link = symtab;
910 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
911 ptr[0] = nb_buckets;
912 ptr[1] = 1;
913 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
914 return symtab;
917 /* put dynamic tag */
918 static void put_dt(Section *dynamic, int dt, unsigned long val)
920 Elf32_Dyn *dyn;
921 dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
922 dyn->d_tag = dt;
923 dyn->d_un.d_val = val;
926 static void add_init_array_defines(TCCState *s1, const char *section_name)
928 Section *s;
929 long end_offset;
930 char sym_start[1024];
931 char sym_end[1024];
933 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
934 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
936 s = find_section(s1, section_name);
937 if (!s) {
938 end_offset = 0;
939 s = data_section;
940 } else {
941 end_offset = s->data_offset;
944 add_elf_sym(symtab_section,
945 0, 0,
946 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
947 s->sh_num, sym_start);
948 add_elf_sym(symtab_section,
949 end_offset, 0,
950 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
951 s->sh_num, sym_end);
954 /* add tcc runtime libraries */
955 static void tcc_add_runtime(TCCState *s1)
957 char buf[1024];
959 if (!s1->nostdlib) {
960 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
961 tcc_add_file(s1, buf);
963 #ifdef CONFIG_TCC_BCHECK
964 if (do_bounds_check) {
965 unsigned long *ptr;
966 Section *init_section;
967 unsigned char *pinit;
968 int sym_index;
970 /* XXX: add an object file to do that */
971 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
972 *ptr = 0;
973 add_elf_sym(symtab_section, 0, 0,
974 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
975 bounds_section->sh_num, "__bounds_start");
976 /* add bound check code */
977 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
978 tcc_add_file(s1, buf);
979 #ifdef TCC_TARGET_I386
980 if (s1->output_type != TCC_OUTPUT_MEMORY) {
981 /* add 'call __bound_init()' in .init section */
982 init_section = find_section(s1, ".init");
983 pinit = section_ptr_add(init_section, 5);
984 pinit[0] = 0xe8;
985 put32(pinit + 1, -4);
986 sym_index = find_elf_sym(symtab_section, "__bound_init");
987 put_elf_reloc(symtab_section, init_section,
988 init_section->data_offset - 4, R_386_PC32, sym_index);
990 #endif
992 #endif
993 /* add libc */
994 if (!s1->nostdlib) {
995 tcc_add_library(s1, "c");
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),
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),
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),
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),
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),
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_shndx, name);
1924 old_to_new_syms[i] = sym_index;
1927 /* third pass to patch relocation entries */
1928 for(i = 1; i < ehdr.e_shnum; i++) {
1929 s = sm_table[i].s;
1930 if (!s)
1931 continue;
1932 sh = &shdr[i];
1933 offset = sm_table[i].offset;
1934 switch(s->sh_type) {
1935 case SHT_REL:
1936 /* take relocation offset information */
1937 offseti = sm_table[sh->sh_info].offset;
1938 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
1939 for(rel = (Elf32_Rel *)(s->data + offset);
1940 rel < rel_end;
1941 rel++) {
1942 int type;
1943 unsigned sym_index;
1944 /* convert symbol index */
1945 type = ELF32_R_TYPE(rel->r_info);
1946 sym_index = ELF32_R_SYM(rel->r_info);
1947 /* NOTE: only one symtab assumed */
1948 if (sym_index >= nb_syms)
1949 goto invalid_reloc;
1950 sym_index = old_to_new_syms[sym_index];
1951 if (!sym_index) {
1952 invalid_reloc:
1953 error_noabort("Invalid relocation entry");
1954 goto fail;
1956 rel->r_info = ELF32_R_INFO(sym_index, type);
1957 /* offset the relocation offset */
1958 rel->r_offset += offseti;
1960 break;
1961 default:
1962 break;
1966 ret = 0;
1967 the_end:
1968 tcc_free(symtab);
1969 tcc_free(strtab);
1970 tcc_free(old_to_new_syms);
1971 tcc_free(sm_table);
1972 tcc_free(strsec);
1973 tcc_free(shdr);
1974 return ret;
1977 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1979 typedef struct ArchiveHeader {
1980 char ar_name[16]; /* name of this member */
1981 char ar_date[12]; /* file mtime */
1982 char ar_uid[6]; /* owner uid; printed as decimal */
1983 char ar_gid[6]; /* owner gid; printed as decimal */
1984 char ar_mode[8]; /* file mode, printed as octal */
1985 char ar_size[10]; /* file size, printed as decimal */
1986 char ar_fmag[2]; /* should contain ARFMAG */
1987 } ArchiveHeader;
1989 static int get_be32(const uint8_t *b)
1991 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
1994 /* load only the objects which resolve undefined symbols */
1995 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
1997 int i, bound, nsyms, sym_index, off, ret;
1998 uint8_t *data;
1999 const char *ar_names, *p;
2000 const uint8_t *ar_index;
2001 Elf32_Sym *sym;
2003 data = tcc_malloc(size);
2004 if (read(fd, data, size) != size)
2005 goto fail;
2006 nsyms = get_be32(data);
2007 ar_index = data + 4;
2008 ar_names = ar_index + nsyms * 4;
2010 do {
2011 bound = 0;
2012 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2013 sym_index = find_elf_sym(symtab_section, p);
2014 if(sym_index) {
2015 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
2016 if(sym->st_shndx == SHN_UNDEF) {
2017 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2018 #if 0
2019 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2020 #endif
2021 ++bound;
2022 lseek(fd, off, SEEK_SET);
2023 if(tcc_load_object_file(s1, fd, off) < 0) {
2024 fail:
2025 ret = -1;
2026 goto the_end;
2031 } while(bound);
2032 ret = 0;
2033 the_end:
2034 tcc_free(data);
2035 return ret;
2038 /* load a '.a' file */
2039 static int tcc_load_archive(TCCState *s1, int fd)
2041 ArchiveHeader hdr;
2042 char ar_size[11];
2043 char ar_name[17];
2044 char magic[8];
2045 int size, len, i;
2046 unsigned long file_offset;
2048 /* skip magic which was already checked */
2049 read(fd, magic, sizeof(magic));
2051 for(;;) {
2052 len = read(fd, &hdr, sizeof(hdr));
2053 if (len == 0)
2054 break;
2055 if (len != sizeof(hdr)) {
2056 error_noabort("invalid archive");
2057 return -1;
2059 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2060 ar_size[sizeof(hdr.ar_size)] = '\0';
2061 size = strtol(ar_size, NULL, 0);
2062 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2063 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2064 if (ar_name[i] != ' ')
2065 break;
2067 ar_name[i + 1] = '\0';
2068 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2069 file_offset = lseek(fd, 0, SEEK_CUR);
2070 /* align to even */
2071 size = (size + 1) & ~1;
2072 if (!strcmp(ar_name, "/")) {
2073 /* coff symbol table : we handle it */
2074 if(s1->alacarte_link)
2075 return tcc_load_alacarte(s1, fd, size);
2076 } else if (!strcmp(ar_name, "//") ||
2077 !strcmp(ar_name, "__.SYMDEF") ||
2078 !strcmp(ar_name, "__.SYMDEF/") ||
2079 !strcmp(ar_name, "ARFILENAMES/")) {
2080 /* skip symbol table or archive names */
2081 } else {
2082 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2083 return -1;
2085 lseek(fd, file_offset + size, SEEK_SET);
2087 return 0;
2090 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2091 is referenced by the user (so it should be added as DT_NEEDED in
2092 the generated ELF file) */
2093 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2095 Elf32_Ehdr ehdr;
2096 Elf32_Shdr *shdr, *sh, *sh1;
2097 int i, nb_syms, nb_dts, sym_bind, ret;
2098 Elf32_Sym *sym, *dynsym;
2099 Elf32_Dyn *dt, *dynamic;
2100 unsigned char *dynstr;
2101 const char *name, *soname, *p;
2102 DLLReference *dllref;
2104 read(fd, &ehdr, sizeof(ehdr));
2106 /* test CPU specific stuff */
2107 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2108 ehdr.e_machine != EM_TCC_TARGET) {
2109 error_noabort("bad architecture");
2110 return -1;
2113 /* read sections */
2114 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
2116 /* load dynamic section and dynamic symbols */
2117 nb_syms = 0;
2118 nb_dts = 0;
2119 dynamic = NULL;
2120 dynsym = NULL; /* avoid warning */
2121 dynstr = NULL; /* avoid warning */
2122 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2123 switch(sh->sh_type) {
2124 case SHT_DYNAMIC:
2125 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
2126 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2127 break;
2128 case SHT_DYNSYM:
2129 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
2130 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2131 sh1 = &shdr[sh->sh_link];
2132 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2133 break;
2134 default:
2135 break;
2139 /* compute the real library name */
2140 soname = filename;
2141 p = strrchr(soname, '/');
2142 if (p)
2143 soname = p + 1;
2145 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2146 if (dt->d_tag == DT_SONAME) {
2147 soname = dynstr + dt->d_un.d_val;
2151 /* if the dll is already loaded, do not load it */
2152 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2153 dllref = s1->loaded_dlls[i];
2154 if (!strcmp(soname, dllref->name)) {
2155 /* but update level if needed */
2156 if (level < dllref->level)
2157 dllref->level = level;
2158 ret = 0;
2159 goto the_end;
2163 // printf("loading dll '%s'\n", soname);
2165 /* add the dll and its level */
2166 dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
2167 dllref->level = level;
2168 strcpy(dllref->name, soname);
2169 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2171 /* add dynamic symbols in dynsym_section */
2172 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2173 sym_bind = ELF32_ST_BIND(sym->st_info);
2174 if (sym_bind == STB_LOCAL)
2175 continue;
2176 name = dynstr + sym->st_name;
2177 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2178 sym->st_info, sym->st_shndx, name);
2181 /* load all referenced DLLs */
2182 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2183 switch(dt->d_tag) {
2184 case DT_NEEDED:
2185 name = dynstr + dt->d_un.d_val;
2186 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2187 dllref = s1->loaded_dlls[i];
2188 if (!strcmp(name, dllref->name))
2189 goto already_loaded;
2191 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2192 error_noabort("referenced dll '%s' not found", name);
2193 ret = -1;
2194 goto the_end;
2196 already_loaded:
2197 break;
2200 ret = 0;
2201 the_end:
2202 tcc_free(dynstr);
2203 tcc_free(dynsym);
2204 tcc_free(dynamic);
2205 tcc_free(shdr);
2206 return ret;
2209 #define LD_TOK_NAME 256
2210 #define LD_TOK_EOF (-1)
2212 /* return next ld script token */
2213 static int ld_next(TCCState *s1, char *name, int name_size)
2215 int c;
2216 char *q;
2218 redo:
2219 switch(ch) {
2220 case ' ':
2221 case '\t':
2222 case '\f':
2223 case '\v':
2224 case '\r':
2225 case '\n':
2226 inp();
2227 goto redo;
2228 case '/':
2229 minp();
2230 if (ch == '*') {
2231 file->buf_ptr = parse_comment(file->buf_ptr);
2232 ch = file->buf_ptr[0];
2233 goto redo;
2234 } else {
2235 q = name;
2236 *q++ = '/';
2237 goto parse_name;
2239 break;
2240 case 'a' ... 'z':
2241 case 'A' ... 'Z':
2242 case '_':
2243 case '\\':
2244 case '.':
2245 case '$':
2246 case '~':
2247 q = name;
2248 parse_name:
2249 for(;;) {
2250 if (!((ch >= 'a' && ch <= 'z') ||
2251 (ch >= 'A' && ch <= 'Z') ||
2252 (ch >= '0' && ch <= '9') ||
2253 strchr("/.-_+=$:\\,~", ch)))
2254 break;
2255 if ((q - name) < name_size - 1) {
2256 *q++ = ch;
2258 minp();
2260 *q = '\0';
2261 c = LD_TOK_NAME;
2262 break;
2263 case CH_EOF:
2264 c = LD_TOK_EOF;
2265 break;
2266 default:
2267 c = ch;
2268 inp();
2269 break;
2271 #if 0
2272 printf("tok=%c %d\n", c, c);
2273 if (c == LD_TOK_NAME)
2274 printf(" name=%s\n", name);
2275 #endif
2276 return c;
2279 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2280 files */
2281 static int tcc_load_ldscript(TCCState *s1)
2283 char cmd[64];
2284 char filename[1024];
2285 int t;
2287 ch = file->buf_ptr[0];
2288 ch = handle_eob();
2289 for(;;) {
2290 t = ld_next(s1, cmd, sizeof(cmd));
2291 if (t == LD_TOK_EOF)
2292 return 0;
2293 else if (t != LD_TOK_NAME)
2294 return -1;
2295 if (!strcmp(cmd, "INPUT") ||
2296 !strcmp(cmd, "GROUP")) {
2297 t = ld_next(s1, cmd, sizeof(cmd));
2298 if (t != '(')
2299 expect("(");
2300 t = ld_next(s1, filename, sizeof(filename));
2301 for(;;) {
2302 if (t == LD_TOK_EOF) {
2303 error_noabort("unexpected end of file");
2304 return -1;
2305 } else if (t == ')') {
2306 break;
2307 } else if (t != LD_TOK_NAME) {
2308 error_noabort("filename expected");
2309 return -1;
2311 tcc_add_file(s1, filename);
2312 t = ld_next(s1, filename, sizeof(filename));
2313 if (t == ',') {
2314 t = ld_next(s1, filename, sizeof(filename));
2317 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2318 !strcmp(cmd, "TARGET")) {
2319 /* ignore some commands */
2320 t = ld_next(s1, cmd, sizeof(cmd));
2321 if (t != '(')
2322 expect("(");
2323 for(;;) {
2324 t = ld_next(s1, filename, sizeof(filename));
2325 if (t == LD_TOK_EOF) {
2326 error_noabort("unexpected end of file");
2327 return -1;
2328 } else if (t == ')') {
2329 break;
2332 } else {
2333 return -1;
2336 return 0;