initial TMS320C67xx support (TK)
[tinycc.git] / tccelf.c
blobe5998676f7164052df962d27bc389160a0d74309
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 default:
556 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
557 type,addr,(unsigned int )ptr,val);
558 break;
559 #else
560 #error unsupported processor
561 #endif
564 /* if the relocation is allocated, we change its symbol table */
565 if (sr->sh_flags & SHF_ALLOC)
566 sr->link = s1->dynsym;
569 /* relocate relocation table in 'sr' */
570 static void relocate_rel(TCCState *s1, Section *sr)
572 Section *s;
573 Elf32_Rel *rel, *rel_end;
575 s = s1->sections[sr->sh_info];
576 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
577 for(rel = (Elf32_Rel *)sr->data;
578 rel < rel_end;
579 rel++) {
580 rel->r_offset += s->sh_addr;
584 /* count the number of dynamic relocations so that we can reserve
585 their space */
586 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
588 Elf32_Rel *rel, *rel_end;
589 int sym_index, esym_index, type, count;
591 count = 0;
592 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
593 for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) {
594 sym_index = ELF32_R_SYM(rel->r_info);
595 type = ELF32_R_TYPE(rel->r_info);
596 switch(type) {
597 case R_386_32:
598 count++;
599 break;
600 case R_386_PC32:
601 esym_index = s1->symtab_to_dynsym[sym_index];
602 if (esym_index)
603 count++;
604 break;
605 default:
606 break;
609 if (count) {
610 /* allocate the section */
611 sr->sh_flags |= SHF_ALLOC;
612 sr->sh_size = count * sizeof(Elf32_Rel);
614 return count;
617 static void put_got_offset(TCCState *s1, int index, unsigned long val)
619 int n;
620 unsigned long *tab;
622 if (index >= s1->nb_got_offsets) {
623 /* find immediately bigger power of 2 and reallocate array */
624 n = 1;
625 while (index >= n)
626 n *= 2;
627 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
628 if (!tab)
629 error("memory full");
630 s1->got_offsets = tab;
631 memset(s1->got_offsets + s1->nb_got_offsets, 0,
632 (n - s1->nb_got_offsets) * sizeof(unsigned long));
633 s1->nb_got_offsets = n;
635 s1->got_offsets[index] = val;
638 /* XXX: suppress that */
639 static void put32(unsigned char *p, uint32_t val)
641 p[0] = val;
642 p[1] = val >> 8;
643 p[2] = val >> 16;
644 p[3] = val >> 24;
647 static uint32_t get32(unsigned char *p)
649 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
652 static void build_got(TCCState *s1)
654 unsigned char *ptr;
656 /* if no got, then create it */
657 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
658 s1->got->sh_entsize = 4;
659 add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
660 s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
661 ptr = section_ptr_add(s1->got, 3 * sizeof(int));
662 /* keep space for _DYNAMIC pointer, if present */
663 put32(ptr, 0);
664 /* two dummy got entries */
665 put32(ptr + 4, 0);
666 put32(ptr + 8, 0);
669 /* put a got entry corresponding to a symbol in symtab_section. 'size'
670 and 'info' can be modifed if more precise info comes from the DLL */
671 static void put_got_entry(TCCState *s1,
672 int reloc_type, unsigned long size, int info,
673 int sym_index)
675 int index;
676 const char *name;
677 Elf32_Sym *sym;
678 unsigned long offset;
679 int *ptr;
681 if (!s1->got)
682 build_got(s1);
684 /* if a got entry already exists for that symbol, no need to add one */
685 if (sym_index < s1->nb_got_offsets &&
686 s1->got_offsets[sym_index] != 0)
687 return;
689 put_got_offset(s1, sym_index, s1->got->data_offset);
691 if (s1->dynsym) {
692 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
693 name = symtab_section->link->data + sym->st_name;
694 offset = sym->st_value;
695 #ifdef TCC_TARGET_I386
696 if (reloc_type == R_386_JMP_SLOT) {
697 Section *plt;
698 uint8_t *p;
699 int modrm;
701 /* if we build a DLL, we add a %ebx offset */
702 if (s1->output_type == TCC_OUTPUT_DLL)
703 modrm = 0xa3;
704 else
705 modrm = 0x25;
707 /* add a PLT entry */
708 plt = s1->plt;
709 if (plt->data_offset == 0) {
710 /* first plt entry */
711 p = section_ptr_add(plt, 16);
712 p[0] = 0xff; /* pushl got + 4 */
713 p[1] = modrm + 0x10;
714 put32(p + 2, 4);
715 p[6] = 0xff; /* jmp *(got + 8) */
716 p[7] = modrm;
717 put32(p + 8, 8);
720 p = section_ptr_add(plt, 16);
721 p[0] = 0xff; /* jmp *(got + x) */
722 p[1] = modrm;
723 put32(p + 2, s1->got->data_offset);
724 p[6] = 0x68; /* push $xxx */
725 put32(p + 7, (plt->data_offset - 32) >> 1);
726 p[11] = 0xe9; /* jmp plt_start */
727 put32(p + 12, -(plt->data_offset));
729 /* the symbol is modified so that it will be relocated to
730 the PLT */
731 if (s1->output_type == TCC_OUTPUT_EXE)
732 offset = plt->data_offset - 16;
734 #elif defined(TCC_TARGET_ARM)
735 if (reloc_type == R_ARM_JUMP_SLOT) {
736 Section *plt;
737 uint8_t *p;
739 /* if we build a DLL, we add a %ebx offset */
740 if (s1->output_type == TCC_OUTPUT_DLL)
741 error("DLLs unimplemented!");
743 /* add a PLT entry */
744 plt = s1->plt;
745 if (plt->data_offset == 0) {
746 /* first plt entry */
747 p = section_ptr_add(plt, 16);
748 put32(p , 0xe52de004);
749 put32(p + 4, 0xe59fe010);
750 put32(p + 8, 0xe08fe00e);
751 put32(p + 12, 0xe5bef008);
754 p = section_ptr_add(plt, 16);
755 put32(p , 0xe59fc004);
756 put32(p+4, 0xe08fc00c);
757 put32(p+8, 0xe59cf000);
758 put32(p+12, s1->got->data_offset);
760 /* the symbol is modified so that it will be relocated to
761 the PLT */
762 if (s1->output_type == TCC_OUTPUT_EXE)
763 offset = plt->data_offset - 16;
765 #elif defined(TCC_TARGET_C67)
766 error("C67 got not implemented");
767 #else
768 #error unsupported CPU
769 #endif
770 index = put_elf_sym(s1->dynsym, offset,
771 size, info, 0, sym->st_shndx, name);
772 /* put a got entry */
773 put_elf_reloc(s1->dynsym, s1->got,
774 s1->got->data_offset,
775 reloc_type, index);
777 ptr = section_ptr_add(s1->got, sizeof(int));
778 *ptr = 0;
781 /* build GOT and PLT entries */
782 static void build_got_entries(TCCState *s1)
784 Section *s, *symtab;
785 Elf32_Rel *rel, *rel_end;
786 Elf32_Sym *sym;
787 int i, type, reloc_type, sym_index;
789 for(i = 1; i < s1->nb_sections; i++) {
790 s = s1->sections[i];
791 if (s->sh_type != SHT_REL)
792 continue;
793 /* no need to handle got relocations */
794 if (s->link != symtab_section)
795 continue;
796 symtab = s->link;
797 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
798 for(rel = (Elf32_Rel *)s->data;
799 rel < rel_end;
800 rel++) {
801 type = ELF32_R_TYPE(rel->r_info);
802 switch(type) {
803 #if defined(TCC_TARGET_I386)
804 case R_386_GOT32:
805 case R_386_GOTOFF:
806 case R_386_GOTPC:
807 case R_386_PLT32:
808 if (!s1->got)
809 build_got(s1);
810 if (type == R_386_GOT32 || type == R_386_PLT32) {
811 sym_index = ELF32_R_SYM(rel->r_info);
812 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
813 /* look at the symbol got offset. If none, then add one */
814 if (type == R_386_GOT32)
815 reloc_type = R_386_GLOB_DAT;
816 else
817 reloc_type = R_386_JMP_SLOT;
818 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
819 sym_index);
821 break;
822 #elif defined(TCC_TARGET_ARM)
823 case R_ARM_GOT32:
824 case R_ARM_GOTOFF:
825 case R_ARM_GOTPC:
826 case R_ARM_PLT32:
827 if (!s1->got)
828 build_got(s1);
829 if (type == R_ARM_GOT32 || type == R_ARM_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_ARM_GOT32)
834 reloc_type = R_ARM_GLOB_DAT;
835 else
836 reloc_type = R_ARM_JUMP_SLOT;
837 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
838 sym_index);
840 break;
841 #elif defined(TCC_TARGET_C67)
842 case R_C60_GOT32:
843 case R_C60_GOTOFF:
844 case R_C60_GOTPC:
845 case R_C60_PLT32:
846 if (!s1->got)
847 build_got(s1);
848 if (type == R_C60_GOT32 || type == R_C60_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_C60_GOT32)
853 reloc_type = R_C60_GLOB_DAT;
854 else
855 reloc_type = R_C60_JMP_SLOT;
856 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
857 sym_index);
859 break;
860 #else
861 #error unsupported CPU
862 #endif
863 default:
864 break;
870 static Section *new_symtab(TCCState *s1,
871 const char *symtab_name, int sh_type, int sh_flags,
872 const char *strtab_name,
873 const char *hash_name, int hash_sh_flags)
875 Section *symtab, *strtab, *hash;
876 int *ptr, nb_buckets;
878 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
879 symtab->sh_entsize = sizeof(Elf32_Sym);
880 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
881 put_elf_str(strtab, "");
882 symtab->link = strtab;
883 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
885 nb_buckets = 1;
887 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
888 hash->sh_entsize = sizeof(int);
889 symtab->hash = hash;
890 hash->link = symtab;
892 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
893 ptr[0] = nb_buckets;
894 ptr[1] = 1;
895 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
896 return symtab;
899 /* put dynamic tag */
900 static void put_dt(Section *dynamic, int dt, unsigned long val)
902 Elf32_Dyn *dyn;
903 dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
904 dyn->d_tag = dt;
905 dyn->d_un.d_val = val;
908 static void add_init_array_defines(TCCState *s1, const char *section_name)
910 Section *s;
911 long end_offset;
912 char sym_start[1024];
913 char sym_end[1024];
915 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
916 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
918 s = find_section(s1, section_name);
919 if (!s) {
920 end_offset = 0;
921 s = data_section;
922 } else {
923 end_offset = s->data_offset;
926 add_elf_sym(symtab_section,
927 0, 0,
928 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
929 s->sh_num, sym_start);
930 add_elf_sym(symtab_section,
931 end_offset, 0,
932 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
933 s->sh_num, sym_end);
936 /* add tcc runtime libraries */
937 static void tcc_add_runtime(TCCState *s1)
939 char buf[1024];
940 int i;
941 Section *s;
943 if (!s1->nostdlib) {
944 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
945 tcc_add_file(s1, buf);
947 #ifdef CONFIG_TCC_BCHECK
948 if (do_bounds_check) {
949 unsigned long *ptr;
950 Section *init_section;
951 unsigned char *pinit;
952 int sym_index;
954 /* XXX: add an object file to do that */
955 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
956 *ptr = 0;
957 add_elf_sym(symtab_section, 0, 0,
958 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
959 bounds_section->sh_num, "__bounds_start");
960 /* add bound check code */
961 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
962 tcc_add_file(s1, buf);
963 #ifdef TCC_TARGET_I386
964 if (s1->output_type != TCC_OUTPUT_MEMORY) {
965 /* add 'call __bound_init()' in .init section */
966 init_section = find_section(s1, ".init");
967 pinit = section_ptr_add(init_section, 5);
968 pinit[0] = 0xe8;
969 put32(pinit + 1, -4);
970 sym_index = find_elf_sym(symtab_section, "__bound_init");
971 put_elf_reloc(symtab_section, init_section,
972 init_section->data_offset - 4, R_386_PC32, sym_index);
974 #endif
976 #endif
977 /* add libc */
978 if (!s1->nostdlib) {
979 tcc_add_library(s1, "c");
981 /* add crt end if not memory output */
982 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
983 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
985 /* add various standard linker symbols */
986 add_elf_sym(symtab_section,
987 text_section->data_offset, 0,
988 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
989 text_section->sh_num, "_etext");
990 add_elf_sym(symtab_section,
991 data_section->data_offset, 0,
992 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
993 data_section->sh_num, "_edata");
994 add_elf_sym(symtab_section,
995 bss_section->data_offset, 0,
996 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
997 bss_section->sh_num, "_end");
998 /* horrible new standard ldscript defines */
999 add_init_array_defines(s1, ".preinit_array");
1000 add_init_array_defines(s1, ".init_array");
1001 add_init_array_defines(s1, ".fini_array");
1003 /* add start and stop symbols for sections whose name can be
1004 expressed in C */
1005 for(i = 1; i < s1->nb_sections; i++) {
1006 s = s1->sections[i];
1007 if (s->sh_type == SHT_PROGBITS &&
1008 (s->sh_flags & SHF_ALLOC)) {
1009 const char *p;
1010 int ch;
1012 /* check if section name can be expressed in C */
1013 p = s->name;
1014 for(;;) {
1015 ch = *p;
1016 if (!ch)
1017 break;
1018 if (!isid(ch) && !isnum(ch))
1019 goto next_sec;
1020 p++;
1022 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1023 add_elf_sym(symtab_section,
1024 0, 0,
1025 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
1026 s->sh_num, buf);
1027 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1028 add_elf_sym(symtab_section,
1029 s->data_offset, 0,
1030 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
1031 s->sh_num, buf);
1033 next_sec: ;
1037 /* name of ELF interpreter */
1038 #ifdef __FreeBSD__
1039 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1040 #else
1041 static char elf_interp[] = "/lib/ld-linux.so.2";
1042 #endif
1044 /* output an ELF file */
1045 /* XXX: suppress unneeded sections */
1046 int tcc_output_file(TCCState *s1, const char *filename)
1048 Elf32_Ehdr ehdr;
1049 FILE *f;
1050 int fd, mode, ret;
1051 int *section_order;
1052 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1053 unsigned long addr;
1054 Section *strsec, *s;
1055 Elf32_Shdr shdr, *sh;
1056 Elf32_Phdr *phdr, *ph;
1057 Section *interp, *dynamic, *dynstr;
1058 unsigned long saved_dynamic_data_offset;
1059 Elf32_Sym *sym;
1060 int type, file_type;
1061 unsigned long rel_addr, rel_size;
1063 file_type = s1->output_type;
1064 s1->nb_errors = 0;
1066 if (file_type != TCC_OUTPUT_OBJ)
1067 tcc_add_runtime(s1);
1069 phdr = NULL;
1070 section_order = NULL;
1071 interp = NULL;
1072 dynamic = NULL;
1073 dynstr = NULL; /* avoid warning */
1074 saved_dynamic_data_offset = 0; /* avoid warning */
1076 if (file_type != TCC_OUTPUT_OBJ) {
1078 relocate_common_syms();
1080 if (!s1->static_link) {
1081 const char *name;
1082 int sym_index, index;
1083 Elf32_Sym *esym, *sym_end;
1085 if (file_type == TCC_OUTPUT_EXE) {
1086 char *ptr;
1087 /* add interpreter section only if executable */
1088 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1089 interp->sh_addralign = 1;
1090 ptr = section_ptr_add(interp, sizeof(elf_interp));
1091 strcpy(ptr, elf_interp);
1094 /* add dynamic symbol table */
1095 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1096 ".dynstr",
1097 ".hash", SHF_ALLOC);
1098 dynstr = s1->dynsym->link;
1100 /* add dynamic section */
1101 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1102 SHF_ALLOC | SHF_WRITE);
1103 dynamic->link = dynstr;
1104 dynamic->sh_entsize = sizeof(Elf32_Dyn);
1106 /* add PLT */
1107 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1108 SHF_ALLOC | SHF_EXECINSTR);
1109 s1->plt->sh_entsize = 4;
1111 build_got(s1);
1113 /* scan for undefined symbols and see if they are in the
1114 dynamic symbols. If a symbol STT_FUNC is found, then we
1115 add it in the PLT. If a symbol STT_OBJECT is found, we
1116 add it in the .bss section with a suitable relocation */
1117 sym_end = (Elf32_Sym *)(symtab_section->data +
1118 symtab_section->data_offset);
1119 if (file_type == TCC_OUTPUT_EXE) {
1120 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1121 sym < sym_end;
1122 sym++) {
1123 if (sym->st_shndx == SHN_UNDEF) {
1124 name = symtab_section->link->data + sym->st_name;
1125 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1126 if (sym_index) {
1127 esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
1128 type = ELF32_ST_TYPE(esym->st_info);
1129 if (type == STT_FUNC) {
1130 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1131 esym->st_info,
1132 sym - (Elf32_Sym *)symtab_section->data);
1133 } else if (type == STT_OBJECT) {
1134 unsigned long offset;
1135 offset = bss_section->data_offset;
1136 /* XXX: which alignment ? */
1137 offset = (offset + 16 - 1) & -16;
1138 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1139 esym->st_info, 0,
1140 bss_section->sh_num, name);
1141 put_elf_reloc(s1->dynsym, bss_section,
1142 offset, R_COPY, index);
1143 offset += esym->st_size;
1144 bss_section->data_offset = offset;
1146 } else {
1147 /* STB_WEAK undefined symbols are accepted */
1148 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1149 it */
1150 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
1151 !strcmp(name, "_fp_hw")) {
1152 } else {
1153 error_noabort("undefined symbol '%s'", name);
1156 } else if (s1->rdynamic &&
1157 ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1158 /* if -rdynamic option, then export all non
1159 local symbols */
1160 name = symtab_section->link->data + sym->st_name;
1161 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1162 sym->st_info, 0,
1163 sym->st_shndx, name);
1167 if (s1->nb_errors)
1168 goto fail;
1170 /* now look at unresolved dynamic symbols and export
1171 corresponding symbol */
1172 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
1173 s1->dynsymtab_section->data_offset);
1174 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
1175 esym < sym_end;
1176 esym++) {
1177 if (esym->st_shndx == SHN_UNDEF) {
1178 name = s1->dynsymtab_section->link->data + esym->st_name;
1179 sym_index = find_elf_sym(symtab_section, name);
1180 if (sym_index) {
1181 /* XXX: avoid adding a symbol if already
1182 present because of -rdynamic ? */
1183 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1184 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1185 sym->st_info, 0,
1186 sym->st_shndx, name);
1187 } else {
1188 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
1189 /* weak symbols can stay undefined */
1190 } else {
1191 warning("undefined dynamic symbol '%s'", name);
1196 } else {
1197 int nb_syms;
1198 /* shared library case : we simply export all the global symbols */
1199 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
1200 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1201 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1202 sym < sym_end;
1203 sym++) {
1204 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1205 name = symtab_section->link->data + sym->st_name;
1206 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1207 sym->st_info, 0,
1208 sym->st_shndx, name);
1209 s1->symtab_to_dynsym[sym -
1210 (Elf32_Sym *)symtab_section->data] =
1211 index;
1216 build_got_entries(s1);
1218 /* add a list of needed dlls */
1219 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1220 DLLReference *dllref = s1->loaded_dlls[i];
1221 if (dllref->level == 0)
1222 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1224 /* XXX: currently, since we do not handle PIC code, we
1225 must relocate the readonly segments */
1226 if (file_type == TCC_OUTPUT_DLL)
1227 put_dt(dynamic, DT_TEXTREL, 0);
1229 /* add necessary space for other entries */
1230 saved_dynamic_data_offset = dynamic->data_offset;
1231 dynamic->data_offset += 8 * 9;
1232 } else {
1233 /* still need to build got entries in case of static link */
1234 build_got_entries(s1);
1238 memset(&ehdr, 0, sizeof(ehdr));
1240 /* we add a section for symbols */
1241 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1242 put_elf_str(strsec, "");
1244 /* compute number of sections */
1245 shnum = s1->nb_sections;
1247 /* this array is used to reorder sections in the output file */
1248 section_order = tcc_malloc(sizeof(int) * shnum);
1249 section_order[0] = 0;
1250 sh_order_index = 1;
1252 /* compute number of program headers */
1253 switch(file_type) {
1254 default:
1255 case TCC_OUTPUT_OBJ:
1256 phnum = 0;
1257 break;
1258 case TCC_OUTPUT_EXE:
1259 if (!s1->static_link)
1260 phnum = 4;
1261 else
1262 phnum = 2;
1263 break;
1264 case TCC_OUTPUT_DLL:
1265 phnum = 3;
1266 break;
1269 /* allocate strings for section names and decide if an unallocated
1270 section should be output */
1271 /* NOTE: the strsec section comes last, so its size is also
1272 correct ! */
1273 for(i = 1; i < s1->nb_sections; i++) {
1274 s = s1->sections[i];
1275 s->sh_name = put_elf_str(strsec, s->name);
1276 /* when generating a DLL, we include relocations but we may
1277 patch them */
1278 if (file_type == TCC_OUTPUT_DLL &&
1279 s->sh_type == SHT_REL &&
1280 !(s->sh_flags & SHF_ALLOC)) {
1281 prepare_dynamic_rel(s1, s);
1282 } else if (do_debug ||
1283 file_type == TCC_OUTPUT_OBJ ||
1284 (s->sh_flags & SHF_ALLOC) ||
1285 i == (s1->nb_sections - 1)) {
1286 /* we output all sections if debug or object file */
1287 s->sh_size = s->data_offset;
1291 /* allocate program segment headers */
1292 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1294 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1295 if (phnum > 0) {
1296 /* compute section to program header mapping */
1297 if (file_type == TCC_OUTPUT_DLL)
1298 addr = 0;
1299 else
1300 addr = ELF_START_ADDR;
1302 /* dynamic relocation table information, for .dynamic section */
1303 rel_size = 0;
1304 rel_addr = 0;
1306 /* compute address after headers */
1307 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1309 /* leave one program header for the program interpreter */
1310 ph = &phdr[0];
1311 if (interp)
1312 ph++;
1314 for(j = 0; j < 2; j++) {
1315 ph->p_type = PT_LOAD;
1316 if (j == 0)
1317 ph->p_flags = PF_R | PF_X;
1318 else
1319 ph->p_flags = PF_R | PF_W;
1320 ph->p_align = ELF_PAGE_SIZE;
1322 /* we do the following ordering: interp, symbol tables,
1323 relocations, progbits, nobits */
1324 /* XXX: do faster and simpler sorting */
1325 for(k = 0; k < 5; k++) {
1326 for(i = 1; i < s1->nb_sections; i++) {
1327 s = s1->sections[i];
1328 /* compute if section should be included */
1329 if (j == 0) {
1330 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1331 SHF_ALLOC)
1332 continue;
1333 } else {
1334 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1335 (SHF_ALLOC | SHF_WRITE))
1336 continue;
1338 if (s == interp) {
1339 if (k != 0)
1340 continue;
1341 } else if (s->sh_type == SHT_DYNSYM ||
1342 s->sh_type == SHT_STRTAB ||
1343 s->sh_type == SHT_HASH) {
1344 if (k != 1)
1345 continue;
1346 } else if (s->sh_type == SHT_REL) {
1347 if (k != 2)
1348 continue;
1349 } else if (s->sh_type == SHT_NOBITS) {
1350 if (k != 4)
1351 continue;
1352 } else {
1353 if (k != 3)
1354 continue;
1356 section_order[sh_order_index++] = i;
1358 /* section matches: we align it and add its size */
1359 tmp = file_offset;
1360 file_offset = (file_offset + s->sh_addralign - 1) &
1361 ~(s->sh_addralign - 1);
1362 s->sh_offset = file_offset;
1363 addr += file_offset - tmp;
1364 s->sh_addr = addr;
1366 /* update program header infos */
1367 if (ph->p_offset == 0) {
1368 ph->p_offset = file_offset;
1369 ph->p_vaddr = addr;
1370 ph->p_paddr = ph->p_vaddr;
1372 /* update dynamic relocation infos */
1373 if (s->sh_type == SHT_REL) {
1374 if (rel_size == 0)
1375 rel_addr = addr;
1376 rel_size += s->sh_size;
1378 addr += s->sh_size;
1379 if (s->sh_type != SHT_NOBITS)
1380 file_offset += s->sh_size;
1383 ph->p_filesz = file_offset - ph->p_offset;
1384 ph->p_memsz = addr - ph->p_vaddr;
1385 ph++;
1386 /* if in the middle of a page, we duplicate the page in
1387 memory so that one copy is RX and the other is RW */
1388 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1389 addr += ELF_PAGE_SIZE;
1392 /* if interpreter, then add corresponing program header */
1393 if (interp) {
1394 ph = &phdr[0];
1396 ph->p_type = PT_INTERP;
1397 ph->p_offset = interp->sh_offset;
1398 ph->p_vaddr = interp->sh_addr;
1399 ph->p_paddr = ph->p_vaddr;
1400 ph->p_filesz = interp->sh_size;
1401 ph->p_memsz = interp->sh_size;
1402 ph->p_flags = PF_R;
1403 ph->p_align = interp->sh_addralign;
1406 /* if dynamic section, then add corresponing program header */
1407 if (dynamic) {
1408 Elf32_Sym *sym_end;
1410 ph = &phdr[phnum - 1];
1412 ph->p_type = PT_DYNAMIC;
1413 ph->p_offset = dynamic->sh_offset;
1414 ph->p_vaddr = dynamic->sh_addr;
1415 ph->p_paddr = ph->p_vaddr;
1416 ph->p_filesz = dynamic->sh_size;
1417 ph->p_memsz = dynamic->sh_size;
1418 ph->p_flags = PF_R | PF_W;
1419 ph->p_align = dynamic->sh_addralign;
1421 /* put GOT dynamic section address */
1422 put32(s1->got->data, dynamic->sh_addr);
1424 /* relocate the PLT */
1425 if (file_type == TCC_OUTPUT_EXE) {
1426 uint8_t *p, *p_end;
1428 p = s1->plt->data;
1429 p_end = p + s1->plt->data_offset;
1430 if (p < p_end) {
1431 #if defined(TCC_TARGET_I386)
1432 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1433 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1434 p += 16;
1435 while (p < p_end) {
1436 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1437 p += 16;
1439 #elif defined(TCC_TARGET_ARM)
1440 int x;
1441 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1442 p +=16;
1443 while (p < p_end) {
1444 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1445 p += 16;
1447 #elif defined(TCC_TARGET_C67)
1448 /* XXX: TODO */
1449 #else
1450 #error unsupported CPU
1451 #endif
1455 /* relocate symbols in .dynsym */
1456 sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
1457 for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
1458 sym < sym_end;
1459 sym++) {
1460 if (sym->st_shndx == SHN_UNDEF) {
1461 /* relocate to the PLT if the symbol corresponds
1462 to a PLT entry */
1463 if (sym->st_value)
1464 sym->st_value += s1->plt->sh_addr;
1465 } else if (sym->st_shndx < SHN_LORESERVE) {
1466 /* do symbol relocation */
1467 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1471 /* put dynamic section entries */
1472 dynamic->data_offset = saved_dynamic_data_offset;
1473 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1474 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1475 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1476 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1477 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
1478 put_dt(dynamic, DT_REL, rel_addr);
1479 put_dt(dynamic, DT_RELSZ, rel_size);
1480 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
1481 put_dt(dynamic, DT_NULL, 0);
1484 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1485 ehdr.e_phnum = phnum;
1486 ehdr.e_phoff = sizeof(Elf32_Ehdr);
1489 /* all other sections come after */
1490 for(i = 1; i < s1->nb_sections; i++) {
1491 s = s1->sections[i];
1492 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1493 continue;
1494 section_order[sh_order_index++] = i;
1496 file_offset = (file_offset + s->sh_addralign - 1) &
1497 ~(s->sh_addralign - 1);
1498 s->sh_offset = file_offset;
1499 if (s->sh_type != SHT_NOBITS)
1500 file_offset += s->sh_size;
1503 /* if building executable or DLL, then relocate each section
1504 except the GOT which is already relocated */
1505 if (file_type != TCC_OUTPUT_OBJ) {
1506 relocate_syms(s1, 0);
1508 if (s1->nb_errors != 0) {
1509 fail:
1510 ret = -1;
1511 goto the_end;
1514 /* relocate sections */
1515 /* XXX: ignore sections with allocated relocations ? */
1516 for(i = 1; i < s1->nb_sections; i++) {
1517 s = s1->sections[i];
1518 if (s->reloc && s != s1->got)
1519 relocate_section(s1, s);
1522 /* relocate relocation entries if the relocation tables are
1523 allocated in the executable */
1524 for(i = 1; i < s1->nb_sections; i++) {
1525 s = s1->sections[i];
1526 if ((s->sh_flags & SHF_ALLOC) &&
1527 s->sh_type == SHT_REL) {
1528 relocate_rel(s1, s);
1532 /* get entry point address */
1533 if (file_type == TCC_OUTPUT_EXE)
1534 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
1535 else
1536 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1539 sort_syms(s1, symtab_section);
1541 /* align to 4 */
1542 file_offset = (file_offset + 3) & -4;
1544 /* fill header */
1545 ehdr.e_ident[0] = ELFMAG0;
1546 ehdr.e_ident[1] = ELFMAG1;
1547 ehdr.e_ident[2] = ELFMAG2;
1548 ehdr.e_ident[3] = ELFMAG3;
1549 ehdr.e_ident[4] = ELFCLASS32;
1550 ehdr.e_ident[5] = ELFDATA2LSB;
1551 ehdr.e_ident[6] = EV_CURRENT;
1552 #ifdef __FreeBSD__
1553 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1554 #endif
1555 #ifdef TCC_TARGET_ARM
1556 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1557 #endif
1558 switch(file_type) {
1559 default:
1560 case TCC_OUTPUT_EXE:
1561 ehdr.e_type = ET_EXEC;
1562 break;
1563 case TCC_OUTPUT_DLL:
1564 ehdr.e_type = ET_DYN;
1565 break;
1566 case TCC_OUTPUT_OBJ:
1567 ehdr.e_type = ET_REL;
1568 break;
1570 ehdr.e_machine = EM_TCC_TARGET;
1571 ehdr.e_version = EV_CURRENT;
1572 ehdr.e_shoff = file_offset;
1573 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1574 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1575 ehdr.e_shnum = shnum;
1576 ehdr.e_shstrndx = shnum - 1;
1578 /* write elf file */
1579 if (file_type == TCC_OUTPUT_OBJ)
1580 mode = 0666;
1581 else
1582 mode = 0777;
1583 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
1584 if (fd < 0) {
1585 error_noabort("could not write '%s'", filename);
1586 goto fail;
1588 f = fdopen(fd, "w");
1589 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1590 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1591 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1592 for(i=1;i<s1->nb_sections;i++) {
1593 s = s1->sections[section_order[i]];
1594 if (s->sh_type != SHT_NOBITS) {
1595 while (offset < s->sh_offset) {
1596 fputc(0, f);
1597 offset++;
1599 size = s->sh_size;
1600 fwrite(s->data, 1, size, f);
1601 offset += size;
1604 while (offset < ehdr.e_shoff) {
1605 fputc(0, f);
1606 offset++;
1609 /* output section headers */
1610 for(i=0;i<s1->nb_sections;i++) {
1611 sh = &shdr;
1612 memset(sh, 0, sizeof(Elf32_Shdr));
1613 s = s1->sections[i];
1614 if (s) {
1615 sh->sh_name = s->sh_name;
1616 sh->sh_type = s->sh_type;
1617 sh->sh_flags = s->sh_flags;
1618 sh->sh_entsize = s->sh_entsize;
1619 sh->sh_info = s->sh_info;
1620 if (s->link)
1621 sh->sh_link = s->link->sh_num;
1622 sh->sh_addralign = s->sh_addralign;
1623 sh->sh_addr = s->sh_addr;
1624 sh->sh_offset = s->sh_offset;
1625 sh->sh_size = s->sh_size;
1627 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1629 fclose(f);
1631 ret = 0;
1632 the_end:
1633 tcc_free(s1->symtab_to_dynsym);
1634 tcc_free(section_order);
1635 tcc_free(phdr);
1636 tcc_free(s1->got_offsets);
1637 return ret;
1640 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1642 void *data;
1644 data = tcc_malloc(size);
1645 lseek(fd, file_offset, SEEK_SET);
1646 read(fd, data, size);
1647 return data;
1650 typedef struct SectionMergeInfo {
1651 Section *s; /* corresponding existing section */
1652 unsigned long offset; /* offset of the new section in the existing section */
1653 uint8_t new_section; /* true if section 's' was added */
1654 uint8_t link_once; /* true if link once section */
1655 } SectionMergeInfo;
1657 /* load an object file and merge it with current files */
1658 /* XXX: handle correctly stab (debug) info */
1659 static int tcc_load_object_file(TCCState *s1,
1660 int fd, unsigned long file_offset)
1662 Elf32_Ehdr ehdr;
1663 Elf32_Shdr *shdr, *sh;
1664 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1665 unsigned char *strsec, *strtab;
1666 int *old_to_new_syms;
1667 char *sh_name, *name;
1668 SectionMergeInfo *sm_table, *sm;
1669 Elf32_Sym *sym, *symtab;
1670 Elf32_Rel *rel, *rel_end;
1671 Section *s;
1673 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1674 goto fail1;
1675 if (ehdr.e_ident[0] != ELFMAG0 ||
1676 ehdr.e_ident[1] != ELFMAG1 ||
1677 ehdr.e_ident[2] != ELFMAG2 ||
1678 ehdr.e_ident[3] != ELFMAG3)
1679 goto fail1;
1680 /* test if object file */
1681 if (ehdr.e_type != ET_REL)
1682 goto fail1;
1683 /* test CPU specific stuff */
1684 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1685 ehdr.e_machine != EM_TCC_TARGET) {
1686 fail1:
1687 error_noabort("invalid object file");
1688 return -1;
1690 /* read sections */
1691 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1692 sizeof(Elf32_Shdr) * ehdr.e_shnum);
1693 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1695 /* load section names */
1696 sh = &shdr[ehdr.e_shstrndx];
1697 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1699 /* load symtab and strtab */
1700 old_to_new_syms = NULL;
1701 symtab = NULL;
1702 strtab = NULL;
1703 nb_syms = 0;
1704 for(i = 1; i < ehdr.e_shnum; i++) {
1705 sh = &shdr[i];
1706 if (sh->sh_type == SHT_SYMTAB) {
1707 if (symtab) {
1708 error_noabort("object must contain only one symtab");
1709 fail:
1710 ret = -1;
1711 goto the_end;
1713 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1714 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1715 sm_table[i].s = symtab_section;
1717 /* now load strtab */
1718 sh = &shdr[sh->sh_link];
1719 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1723 /* now examine each section and try to merge its content with the
1724 ones in memory */
1725 for(i = 1; i < ehdr.e_shnum; i++) {
1726 /* no need to examine section name strtab */
1727 if (i == ehdr.e_shstrndx)
1728 continue;
1729 sh = &shdr[i];
1730 sh_name = strsec + sh->sh_name;
1731 /* ignore sections types we do not handle */
1732 if (sh->sh_type != SHT_PROGBITS &&
1733 sh->sh_type != SHT_REL &&
1734 sh->sh_type != SHT_NOBITS)
1735 continue;
1736 if (sh->sh_addralign < 1)
1737 sh->sh_addralign = 1;
1738 /* find corresponding section, if any */
1739 for(j = 1; j < s1->nb_sections;j++) {
1740 s = s1->sections[j];
1741 if (!strcmp(s->name, sh_name)) {
1742 if (!strncmp(sh_name, ".gnu.linkonce",
1743 sizeof(".gnu.linkonce") - 1)) {
1744 /* if a 'linkonce' section is already present, we
1745 do not add it again. It is a little tricky as
1746 symbols can still be defined in
1747 it. */
1748 sm_table[i].link_once = 1;
1749 goto next;
1750 } else {
1751 goto found;
1755 /* not found: create new section */
1756 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1757 /* take as much info as possible from the section. sh_link and
1758 sh_info will be updated later */
1759 s->sh_addralign = sh->sh_addralign;
1760 s->sh_entsize = sh->sh_entsize;
1761 sm_table[i].new_section = 1;
1762 found:
1763 if (sh->sh_type != s->sh_type) {
1764 error_noabort("invalid section type");
1765 goto fail;
1768 /* align start of section */
1769 offset = s->data_offset;
1770 size = sh->sh_addralign - 1;
1771 offset = (offset + size) & ~size;
1772 if (sh->sh_addralign > s->sh_addralign)
1773 s->sh_addralign = sh->sh_addralign;
1774 s->data_offset = offset;
1775 sm_table[i].offset = offset;
1776 sm_table[i].s = s;
1777 /* concatenate sections */
1778 size = sh->sh_size;
1779 if (sh->sh_type != SHT_NOBITS) {
1780 unsigned char *ptr;
1781 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1782 ptr = section_ptr_add(s, size);
1783 read(fd, ptr, size);
1784 } else {
1785 s->data_offset += size;
1787 next: ;
1790 /* second short pass to update sh_link and sh_info fields of new
1791 sections */
1792 sm = sm_table;
1793 for(i = 1; i < ehdr.e_shnum; i++) {
1794 s = sm_table[i].s;
1795 if (!s || !sm_table[i].new_section)
1796 continue;
1797 sh = &shdr[i];
1798 if (sh->sh_link > 0)
1799 s->link = sm_table[sh->sh_link].s;
1800 if (sh->sh_type == SHT_REL) {
1801 s->sh_info = sm_table[sh->sh_info].s->sh_num;
1802 /* update backward link */
1803 s1->sections[s->sh_info]->reloc = s;
1807 /* resolve symbols */
1808 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
1810 sym = symtab + 1;
1811 for(i = 1; i < nb_syms; i++, sym++) {
1812 if (sym->st_shndx != SHN_UNDEF &&
1813 sym->st_shndx < SHN_LORESERVE) {
1814 sm = &sm_table[sym->st_shndx];
1815 if (sm->link_once) {
1816 /* if a symbol is in a link once section, we use the
1817 already defined symbol. It is very important to get
1818 correct relocations */
1819 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1820 name = strtab + sym->st_name;
1821 sym_index = find_elf_sym(symtab_section, name);
1822 if (sym_index)
1823 old_to_new_syms[i] = sym_index;
1825 continue;
1827 /* if no corresponding section added, no need to add symbol */
1828 if (!sm->s)
1829 continue;
1830 /* convert section number */
1831 sym->st_shndx = sm->s->sh_num;
1832 /* offset value */
1833 sym->st_value += sm->offset;
1835 /* add symbol */
1836 name = strtab + sym->st_name;
1837 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
1838 sym->st_info, sym->st_shndx, name);
1839 old_to_new_syms[i] = sym_index;
1842 /* third pass to patch relocation entries */
1843 for(i = 1; i < ehdr.e_shnum; i++) {
1844 s = sm_table[i].s;
1845 if (!s)
1846 continue;
1847 sh = &shdr[i];
1848 offset = sm_table[i].offset;
1849 switch(s->sh_type) {
1850 case SHT_REL:
1851 /* take relocation offset information */
1852 offseti = sm_table[sh->sh_info].offset;
1853 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
1854 for(rel = (Elf32_Rel *)(s->data + offset);
1855 rel < rel_end;
1856 rel++) {
1857 int type;
1858 unsigned sym_index;
1859 /* convert symbol index */
1860 type = ELF32_R_TYPE(rel->r_info);
1861 sym_index = ELF32_R_SYM(rel->r_info);
1862 /* NOTE: only one symtab assumed */
1863 if (sym_index >= nb_syms)
1864 goto invalid_reloc;
1865 sym_index = old_to_new_syms[sym_index];
1866 if (!sym_index) {
1867 invalid_reloc:
1868 error_noabort("Invalid relocation entry");
1869 goto fail;
1871 rel->r_info = ELF32_R_INFO(sym_index, type);
1872 /* offset the relocation offset */
1873 rel->r_offset += offseti;
1875 break;
1876 default:
1877 break;
1881 ret = 0;
1882 the_end:
1883 tcc_free(symtab);
1884 tcc_free(strtab);
1885 tcc_free(old_to_new_syms);
1886 tcc_free(sm_table);
1887 tcc_free(strsec);
1888 tcc_free(shdr);
1889 return ret;
1892 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1894 typedef struct ArchiveHeader {
1895 char ar_name[16]; /* name of this member */
1896 char ar_date[12]; /* file mtime */
1897 char ar_uid[6]; /* owner uid; printed as decimal */
1898 char ar_gid[6]; /* owner gid; printed as decimal */
1899 char ar_mode[8]; /* file mode, printed as octal */
1900 char ar_size[10]; /* file size, printed as decimal */
1901 char ar_fmag[2]; /* should contain ARFMAG */
1902 } ArchiveHeader;
1904 static int get_be32(const uint8_t *b)
1906 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
1909 /* load only the objects which resolve undefined symbols */
1910 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
1912 int i, bound, nsyms, sym_index, off, ret;
1913 uint8_t *data;
1914 const char *ar_names, *p;
1915 const uint8_t *ar_index;
1916 Elf32_Sym *sym;
1918 data = tcc_malloc(size);
1919 if (read(fd, data, size) != size)
1920 goto fail;
1921 nsyms = get_be32(data);
1922 ar_index = data + 4;
1923 ar_names = ar_index + nsyms * 4;
1925 do {
1926 bound = 0;
1927 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
1928 sym_index = find_elf_sym(symtab_section, p);
1929 if(sym_index) {
1930 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1931 if(sym->st_shndx == SHN_UNDEF) {
1932 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
1933 #if 0
1934 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
1935 #endif
1936 ++bound;
1937 lseek(fd, off, SEEK_SET);
1938 if(tcc_load_object_file(s1, fd, off) < 0) {
1939 fail:
1940 ret = -1;
1941 goto the_end;
1946 } while(bound);
1947 ret = 0;
1948 the_end:
1949 tcc_free(data);
1950 return ret;
1953 /* load a '.a' file */
1954 static int tcc_load_archive(TCCState *s1, int fd)
1956 ArchiveHeader hdr;
1957 char ar_size[11];
1958 char ar_name[17];
1959 char magic[8];
1960 int size, len, i;
1961 unsigned long file_offset;
1963 /* skip magic which was already checked */
1964 read(fd, magic, sizeof(magic));
1966 for(;;) {
1967 len = read(fd, &hdr, sizeof(hdr));
1968 if (len == 0)
1969 break;
1970 if (len != sizeof(hdr)) {
1971 error_noabort("invalid archive");
1972 return -1;
1974 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
1975 ar_size[sizeof(hdr.ar_size)] = '\0';
1976 size = strtol(ar_size, NULL, 0);
1977 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
1978 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
1979 if (ar_name[i] != ' ')
1980 break;
1982 ar_name[i + 1] = '\0';
1983 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
1984 file_offset = lseek(fd, 0, SEEK_CUR);
1985 /* align to even */
1986 size = (size + 1) & ~1;
1987 if (!strcmp(ar_name, "/")) {
1988 /* coff symbol table : we handle it */
1989 if(s1->alacarte_link)
1990 return tcc_load_alacarte(s1, fd, size);
1991 } else if (!strcmp(ar_name, "//") ||
1992 !strcmp(ar_name, "__.SYMDEF") ||
1993 !strcmp(ar_name, "__.SYMDEF/") ||
1994 !strcmp(ar_name, "ARFILENAMES/")) {
1995 /* skip symbol table or archive names */
1996 } else {
1997 if (tcc_load_object_file(s1, fd, file_offset) < 0)
1998 return -1;
2000 lseek(fd, file_offset + size, SEEK_SET);
2002 return 0;
2005 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2006 is referenced by the user (so it should be added as DT_NEEDED in
2007 the generated ELF file) */
2008 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2010 Elf32_Ehdr ehdr;
2011 Elf32_Shdr *shdr, *sh, *sh1;
2012 int i, nb_syms, nb_dts, sym_bind, ret;
2013 Elf32_Sym *sym, *dynsym;
2014 Elf32_Dyn *dt, *dynamic;
2015 unsigned char *dynstr;
2016 const char *name, *soname, *p;
2017 DLLReference *dllref;
2019 read(fd, &ehdr, sizeof(ehdr));
2021 /* test CPU specific stuff */
2022 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2023 ehdr.e_machine != EM_TCC_TARGET) {
2024 error_noabort("bad architecture");
2025 return -1;
2028 /* read sections */
2029 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
2031 /* load dynamic section and dynamic symbols */
2032 nb_syms = 0;
2033 nb_dts = 0;
2034 dynamic = NULL;
2035 dynsym = NULL; /* avoid warning */
2036 dynstr = NULL; /* avoid warning */
2037 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2038 switch(sh->sh_type) {
2039 case SHT_DYNAMIC:
2040 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
2041 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2042 break;
2043 case SHT_DYNSYM:
2044 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
2045 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2046 sh1 = &shdr[sh->sh_link];
2047 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2048 break;
2049 default:
2050 break;
2054 /* compute the real library name */
2055 soname = filename;
2056 p = strrchr(soname, '/');
2057 if (p)
2058 soname = p + 1;
2060 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2061 if (dt->d_tag == DT_SONAME) {
2062 soname = dynstr + dt->d_un.d_val;
2066 /* if the dll is already loaded, do not load it */
2067 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2068 dllref = s1->loaded_dlls[i];
2069 if (!strcmp(soname, dllref->name)) {
2070 /* but update level if needed */
2071 if (level < dllref->level)
2072 dllref->level = level;
2073 ret = 0;
2074 goto the_end;
2078 // printf("loading dll '%s'\n", soname);
2080 /* add the dll and its level */
2081 dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
2082 dllref->level = level;
2083 strcpy(dllref->name, soname);
2084 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2086 /* add dynamic symbols in dynsym_section */
2087 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2088 sym_bind = ELF32_ST_BIND(sym->st_info);
2089 if (sym_bind == STB_LOCAL)
2090 continue;
2091 name = dynstr + sym->st_name;
2092 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2093 sym->st_info, sym->st_shndx, name);
2096 /* load all referenced DLLs */
2097 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2098 switch(dt->d_tag) {
2099 case DT_NEEDED:
2100 name = dynstr + dt->d_un.d_val;
2101 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2102 dllref = s1->loaded_dlls[i];
2103 if (!strcmp(name, dllref->name))
2104 goto already_loaded;
2106 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2107 error_noabort("referenced dll '%s' not found", name);
2108 ret = -1;
2109 goto the_end;
2111 already_loaded:
2112 break;
2115 ret = 0;
2116 the_end:
2117 tcc_free(dynstr);
2118 tcc_free(dynsym);
2119 tcc_free(dynamic);
2120 tcc_free(shdr);
2121 return ret;
2124 #define LD_TOK_NAME 256
2125 #define LD_TOK_EOF (-1)
2127 /* return next ld script token */
2128 static int ld_next(TCCState *s1, char *name, int name_size)
2130 int c;
2131 char *q;
2133 redo:
2134 switch(ch) {
2135 case ' ':
2136 case '\t':
2137 case '\f':
2138 case '\v':
2139 case '\r':
2140 case '\n':
2141 inp();
2142 goto redo;
2143 case '/':
2144 minp();
2145 if (ch == '*') {
2146 file->buf_ptr = parse_comment(file->buf_ptr);
2147 ch = file->buf_ptr[0];
2148 goto redo;
2149 } else {
2150 q = name;
2151 *q++ = '/';
2152 goto parse_name;
2154 break;
2155 case 'a' ... 'z':
2156 case 'A' ... 'Z':
2157 case '_':
2158 case '\\':
2159 case '.':
2160 case '$':
2161 case '~':
2162 q = name;
2163 parse_name:
2164 for(;;) {
2165 if (!((ch >= 'a' && ch <= 'z') ||
2166 (ch >= 'A' && ch <= 'Z') ||
2167 (ch >= '0' && ch <= '9') ||
2168 strchr("/.-_+=$:\\,~", ch)))
2169 break;
2170 if ((q - name) < name_size - 1) {
2171 *q++ = ch;
2173 minp();
2175 *q = '\0';
2176 c = LD_TOK_NAME;
2177 break;
2178 case CH_EOF:
2179 c = LD_TOK_EOF;
2180 break;
2181 default:
2182 c = ch;
2183 inp();
2184 break;
2186 #if 0
2187 printf("tok=%c %d\n", c, c);
2188 if (c == LD_TOK_NAME)
2189 printf(" name=%s\n", name);
2190 #endif
2191 return c;
2194 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2195 files */
2196 static int tcc_load_ldscript(TCCState *s1)
2198 char cmd[64];
2199 char filename[1024];
2200 int t;
2202 ch = file->buf_ptr[0];
2203 ch = handle_eob();
2204 for(;;) {
2205 t = ld_next(s1, cmd, sizeof(cmd));
2206 if (t == LD_TOK_EOF)
2207 return 0;
2208 else if (t != LD_TOK_NAME)
2209 return -1;
2210 if (!strcmp(cmd, "INPUT") ||
2211 !strcmp(cmd, "GROUP")) {
2212 t = ld_next(s1, cmd, sizeof(cmd));
2213 if (t != '(')
2214 expect("(");
2215 t = ld_next(s1, filename, sizeof(filename));
2216 for(;;) {
2217 if (t == LD_TOK_EOF) {
2218 error_noabort("unexpected end of file");
2219 return -1;
2220 } else if (t == ')') {
2221 break;
2222 } else if (t != LD_TOK_NAME) {
2223 error_noabort("filename expected");
2224 return -1;
2226 tcc_add_file(s1, filename);
2227 t = ld_next(s1, filename, sizeof(filename));
2228 if (t == ',') {
2229 t = ld_next(s1, filename, sizeof(filename));
2232 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2233 !strcmp(cmd, "TARGET")) {
2234 /* ignore some commands */
2235 t = ld_next(s1, cmd, sizeof(cmd));
2236 if (t != '(')
2237 expect("(");
2238 for(;;) {
2239 t = ld_next(s1, filename, sizeof(filename));
2240 if (t == LD_TOK_EOF) {
2241 error_noabort("unexpected end of file");
2242 return -1;
2243 } else if (t == ')') {
2244 break;
2247 } else {
2248 return -1;
2251 return 0;