ARM target support (Daniel Glockner) - allow unsigned char as default on ARM (Daniel...
[tinycc.git] / tccelf.c
blobe31b4127b25521943ce744375eea62592e0e604d
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 #else
552 #error unsupported processor
553 #endif
556 /* if the relocation is allocated, we change its symbol table */
557 if (sr->sh_flags & SHF_ALLOC)
558 sr->link = s1->dynsym;
561 /* relocate relocation table in 'sr' */
562 static void relocate_rel(TCCState *s1, Section *sr)
564 Section *s;
565 Elf32_Rel *rel, *rel_end;
567 s = s1->sections[sr->sh_info];
568 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
569 for(rel = (Elf32_Rel *)sr->data;
570 rel < rel_end;
571 rel++) {
572 rel->r_offset += s->sh_addr;
576 /* count the number of dynamic relocations so that we can reserve
577 their space */
578 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
580 Elf32_Rel *rel, *rel_end;
581 int sym_index, esym_index, type, count;
583 count = 0;
584 rel_end = (Elf32_Rel *)(sr->data + sr->data_offset);
585 for(rel = (Elf32_Rel *)sr->data; rel < rel_end; rel++) {
586 sym_index = ELF32_R_SYM(rel->r_info);
587 type = ELF32_R_TYPE(rel->r_info);
588 switch(type) {
589 case R_386_32:
590 count++;
591 break;
592 case R_386_PC32:
593 esym_index = s1->symtab_to_dynsym[sym_index];
594 if (esym_index)
595 count++;
596 break;
597 default:
598 break;
601 if (count) {
602 /* allocate the section */
603 sr->sh_flags |= SHF_ALLOC;
604 sr->sh_size = count * sizeof(Elf32_Rel);
606 return count;
609 static void put_got_offset(TCCState *s1, int index, unsigned long val)
611 int n;
612 unsigned long *tab;
614 if (index >= s1->nb_got_offsets) {
615 /* find immediately bigger power of 2 and reallocate array */
616 n = 1;
617 while (index >= n)
618 n *= 2;
619 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
620 if (!tab)
621 error("memory full");
622 s1->got_offsets = tab;
623 memset(s1->got_offsets + s1->nb_got_offsets, 0,
624 (n - s1->nb_got_offsets) * sizeof(unsigned long));
625 s1->nb_got_offsets = n;
627 s1->got_offsets[index] = val;
630 /* XXX: suppress that */
631 static void put32(unsigned char *p, uint32_t val)
633 p[0] = val;
634 p[1] = val >> 8;
635 p[2] = val >> 16;
636 p[3] = val >> 24;
639 static uint32_t get32(unsigned char *p)
641 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
644 static void build_got(TCCState *s1)
646 unsigned char *ptr;
648 /* if no got, then create it */
649 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
650 s1->got->sh_entsize = 4;
651 add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
652 s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
653 ptr = section_ptr_add(s1->got, 3 * sizeof(int));
654 /* keep space for _DYNAMIC pointer, if present */
655 put32(ptr, 0);
656 /* two dummy got entries */
657 put32(ptr + 4, 0);
658 put32(ptr + 8, 0);
661 /* put a got entry corresponding to a symbol in symtab_section. 'size'
662 and 'info' can be modifed if more precise info comes from the DLL */
663 static void put_got_entry(TCCState *s1,
664 int reloc_type, unsigned long size, int info,
665 int sym_index)
667 int index;
668 const char *name;
669 Elf32_Sym *sym;
670 unsigned long offset;
671 int *ptr;
673 if (!s1->got)
674 build_got(s1);
676 /* if a got entry already exists for that symbol, no need to add one */
677 if (sym_index < s1->nb_got_offsets &&
678 s1->got_offsets[sym_index] != 0)
679 return;
681 put_got_offset(s1, sym_index, s1->got->data_offset);
683 if (s1->dynsym) {
684 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
685 name = symtab_section->link->data + sym->st_name;
686 offset = sym->st_value;
687 #ifdef TCC_TARGET_I386
688 if (reloc_type == R_386_JMP_SLOT) {
689 Section *plt;
690 uint8_t *p;
691 int modrm;
693 /* if we build a DLL, we add a %ebx offset */
694 if (s1->output_type == TCC_OUTPUT_DLL)
695 modrm = 0xa3;
696 else
697 modrm = 0x25;
699 /* add a PLT entry */
700 plt = s1->plt;
701 if (plt->data_offset == 0) {
702 /* first plt entry */
703 p = section_ptr_add(plt, 16);
704 p[0] = 0xff; /* pushl got + 4 */
705 p[1] = modrm + 0x10;
706 put32(p + 2, 4);
707 p[6] = 0xff; /* jmp *(got + 8) */
708 p[7] = modrm;
709 put32(p + 8, 8);
712 p = section_ptr_add(plt, 16);
713 p[0] = 0xff; /* jmp *(got + x) */
714 p[1] = modrm;
715 put32(p + 2, s1->got->data_offset);
716 p[6] = 0x68; /* push $xxx */
717 put32(p + 7, (plt->data_offset - 32) >> 1);
718 p[11] = 0xe9; /* jmp plt_start */
719 put32(p + 12, -(plt->data_offset));
721 /* the symbol is modified so that it will be relocated to
722 the PLT */
723 if (s1->output_type == TCC_OUTPUT_EXE)
724 offset = plt->data_offset - 16;
726 #elif defined(TCC_TARGET_ARM)
727 if (reloc_type == R_ARM_JUMP_SLOT) {
728 Section *plt;
729 uint8_t *p;
731 /* if we build a DLL, we add a %ebx offset */
732 if (s1->output_type == TCC_OUTPUT_DLL)
733 error("DLLs unimplemented!");
735 /* add a PLT entry */
736 plt = s1->plt;
737 if (plt->data_offset == 0) {
738 /* first plt entry */
739 p = section_ptr_add(plt, 16);
740 put32(p , 0xe52de004);
741 put32(p + 4, 0xe59fe010);
742 put32(p + 8, 0xe08fe00e);
743 put32(p + 12, 0xe5bef008);
746 p = section_ptr_add(plt, 16);
747 put32(p , 0xe59fc004);
748 put32(p+4, 0xe08fc00c);
749 put32(p+8, 0xe59cf000);
750 put32(p+12, s1->got->data_offset);
752 /* the symbol is modified so that it will be relocated to
753 the PLT */
754 if (s1->output_type == TCC_OUTPUT_EXE)
755 offset = plt->data_offset - 16;
757 #else
758 #error unsupported CPU
759 #endif
760 index = put_elf_sym(s1->dynsym, offset,
761 size, info, 0, sym->st_shndx, name);
762 /* put a got entry */
763 put_elf_reloc(s1->dynsym, s1->got,
764 s1->got->data_offset,
765 reloc_type, index);
767 ptr = section_ptr_add(s1->got, sizeof(int));
768 *ptr = 0;
771 /* build GOT and PLT entries */
772 static void build_got_entries(TCCState *s1)
774 Section *s, *symtab;
775 Elf32_Rel *rel, *rel_end;
776 Elf32_Sym *sym;
777 int i, type, reloc_type, sym_index;
779 for(i = 1; i < s1->nb_sections; i++) {
780 s = s1->sections[i];
781 if (s->sh_type != SHT_REL)
782 continue;
783 /* no need to handle got relocations */
784 if (s->link != symtab_section)
785 continue;
786 symtab = s->link;
787 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
788 for(rel = (Elf32_Rel *)s->data;
789 rel < rel_end;
790 rel++) {
791 type = ELF32_R_TYPE(rel->r_info);
792 switch(type) {
793 #if defined(TCC_TARGET_I386)
794 case R_386_GOT32:
795 case R_386_GOTOFF:
796 case R_386_GOTPC:
797 case R_386_PLT32:
798 if (!s1->got)
799 build_got(s1);
800 if (type == R_386_GOT32 || type == R_386_PLT32) {
801 sym_index = ELF32_R_SYM(rel->r_info);
802 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
803 /* look at the symbol got offset. If none, then add one */
804 if (type == R_386_GOT32)
805 reloc_type = R_386_GLOB_DAT;
806 else
807 reloc_type = R_386_JMP_SLOT;
808 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
809 sym_index);
811 break;
812 #elif defined(TCC_TARGET_ARM)
813 case R_ARM_GOT32:
814 case R_ARM_GOTOFF:
815 case R_ARM_GOTPC:
816 case R_ARM_PLT32:
817 if (!s1->got)
818 build_got(s1);
819 if (type == R_ARM_GOT32 || type == R_ARM_PLT32) {
820 sym_index = ELF32_R_SYM(rel->r_info);
821 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
822 /* look at the symbol got offset. If none, then add one */
823 if (type == R_ARM_GOT32)
824 reloc_type = R_ARM_GLOB_DAT;
825 else
826 reloc_type = R_ARM_JUMP_SLOT;
827 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
828 sym_index);
830 break;
831 #else
832 #error unsupported CPU
833 #endif
834 default:
835 break;
841 static Section *new_symtab(TCCState *s1,
842 const char *symtab_name, int sh_type, int sh_flags,
843 const char *strtab_name,
844 const char *hash_name, int hash_sh_flags)
846 Section *symtab, *strtab, *hash;
847 int *ptr, nb_buckets;
849 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
850 symtab->sh_entsize = sizeof(Elf32_Sym);
851 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
852 put_elf_str(strtab, "");
853 symtab->link = strtab;
854 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
856 nb_buckets = 1;
858 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
859 hash->sh_entsize = sizeof(int);
860 symtab->hash = hash;
861 hash->link = symtab;
863 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
864 ptr[0] = nb_buckets;
865 ptr[1] = 1;
866 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
867 return symtab;
870 /* put dynamic tag */
871 static void put_dt(Section *dynamic, int dt, unsigned long val)
873 Elf32_Dyn *dyn;
874 dyn = section_ptr_add(dynamic, sizeof(Elf32_Dyn));
875 dyn->d_tag = dt;
876 dyn->d_un.d_val = val;
879 static void add_init_array_defines(TCCState *s1, const char *section_name)
881 Section *s;
882 long end_offset;
883 char sym_start[1024];
884 char sym_end[1024];
886 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
887 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
889 s = find_section(s1, section_name);
890 if (!s) {
891 end_offset = 0;
892 s = data_section;
893 } else {
894 end_offset = s->data_offset;
897 add_elf_sym(symtab_section,
898 0, 0,
899 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
900 s->sh_num, sym_start);
901 add_elf_sym(symtab_section,
902 end_offset, 0,
903 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
904 s->sh_num, sym_end);
907 /* add tcc runtime libraries */
908 static void tcc_add_runtime(TCCState *s1)
910 char buf[1024];
911 int i;
912 Section *s;
914 if (!s1->nostdlib) {
915 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
916 tcc_add_file(s1, buf);
918 #ifdef CONFIG_TCC_BCHECK
919 if (do_bounds_check) {
920 unsigned long *ptr;
921 Section *init_section;
922 unsigned char *pinit;
923 int sym_index;
925 /* XXX: add an object file to do that */
926 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
927 *ptr = 0;
928 add_elf_sym(symtab_section, 0, 0,
929 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
930 bounds_section->sh_num, "__bounds_start");
931 /* add bound check code */
932 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
933 tcc_add_file(s1, buf);
934 #ifdef TCC_TARGET_I386
935 if (s1->output_type != TCC_OUTPUT_MEMORY) {
936 /* add 'call __bound_init()' in .init section */
937 init_section = find_section(s1, ".init");
938 pinit = section_ptr_add(init_section, 5);
939 pinit[0] = 0xe8;
940 put32(pinit + 1, -4);
941 sym_index = find_elf_sym(symtab_section, "__bound_init");
942 put_elf_reloc(symtab_section, init_section,
943 init_section->data_offset - 4, R_386_PC32, sym_index);
945 #endif
947 #endif
948 /* add libc */
949 if (!s1->nostdlib) {
950 tcc_add_library(s1, "c");
952 /* add crt end if not memory output */
953 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
954 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
956 /* add various standard linker symbols */
957 add_elf_sym(symtab_section,
958 text_section->data_offset, 0,
959 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
960 text_section->sh_num, "_etext");
961 add_elf_sym(symtab_section,
962 data_section->data_offset, 0,
963 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
964 data_section->sh_num, "_edata");
965 add_elf_sym(symtab_section,
966 bss_section->data_offset, 0,
967 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
968 bss_section->sh_num, "_end");
969 /* horrible new standard ldscript defines */
970 add_init_array_defines(s1, ".preinit_array");
971 add_init_array_defines(s1, ".init_array");
972 add_init_array_defines(s1, ".fini_array");
974 /* add start and stop symbols for sections whose name can be
975 expressed in C */
976 for(i = 1; i < s1->nb_sections; i++) {
977 s = s1->sections[i];
978 if (s->sh_type == SHT_PROGBITS &&
979 (s->sh_flags & SHF_ALLOC)) {
980 const char *p;
981 int ch;
983 /* check if section name can be expressed in C */
984 p = s->name;
985 for(;;) {
986 ch = *p;
987 if (!ch)
988 break;
989 if (!isid(ch) && !isnum(ch))
990 goto next_sec;
991 p++;
993 snprintf(buf, sizeof(buf), "__start_%s", s->name);
994 add_elf_sym(symtab_section,
995 0, 0,
996 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
997 s->sh_num, buf);
998 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
999 add_elf_sym(symtab_section,
1000 s->data_offset, 0,
1001 ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE),
1002 s->sh_num, buf);
1004 next_sec: ;
1008 /* name of ELF interpreter */
1009 #ifdef __FreeBSD__
1010 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1011 #else
1012 static char elf_interp[] = "/lib/ld-linux.so.2";
1013 #endif
1015 /* output an ELF file */
1016 /* XXX: suppress unneeded sections */
1017 int tcc_output_file(TCCState *s1, const char *filename)
1019 Elf32_Ehdr ehdr;
1020 FILE *f;
1021 int fd, mode, ret;
1022 int *section_order;
1023 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1024 unsigned long addr;
1025 Section *strsec, *s;
1026 Elf32_Shdr shdr, *sh;
1027 Elf32_Phdr *phdr, *ph;
1028 Section *interp, *dynamic, *dynstr;
1029 unsigned long saved_dynamic_data_offset;
1030 Elf32_Sym *sym;
1031 int type, file_type;
1032 unsigned long rel_addr, rel_size;
1034 file_type = s1->output_type;
1035 s1->nb_errors = 0;
1037 if (file_type != TCC_OUTPUT_OBJ)
1038 tcc_add_runtime(s1);
1040 phdr = NULL;
1041 section_order = NULL;
1042 interp = NULL;
1043 dynamic = NULL;
1044 dynstr = NULL; /* avoid warning */
1045 saved_dynamic_data_offset = 0; /* avoid warning */
1047 if (file_type != TCC_OUTPUT_OBJ) {
1049 relocate_common_syms();
1051 if (!s1->static_link) {
1052 const char *name;
1053 int sym_index, index;
1054 Elf32_Sym *esym, *sym_end;
1056 if (file_type == TCC_OUTPUT_EXE) {
1057 char *ptr;
1058 /* add interpreter section only if executable */
1059 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1060 interp->sh_addralign = 1;
1061 ptr = section_ptr_add(interp, sizeof(elf_interp));
1062 strcpy(ptr, elf_interp);
1065 /* add dynamic symbol table */
1066 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1067 ".dynstr",
1068 ".hash", SHF_ALLOC);
1069 dynstr = s1->dynsym->link;
1071 /* add dynamic section */
1072 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1073 SHF_ALLOC | SHF_WRITE);
1074 dynamic->link = dynstr;
1075 dynamic->sh_entsize = sizeof(Elf32_Dyn);
1077 /* add PLT */
1078 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1079 SHF_ALLOC | SHF_EXECINSTR);
1080 s1->plt->sh_entsize = 4;
1082 build_got(s1);
1084 /* scan for undefined symbols and see if they are in the
1085 dynamic symbols. If a symbol STT_FUNC is found, then we
1086 add it in the PLT. If a symbol STT_OBJECT is found, we
1087 add it in the .bss section with a suitable relocation */
1088 sym_end = (Elf32_Sym *)(symtab_section->data +
1089 symtab_section->data_offset);
1090 if (file_type == TCC_OUTPUT_EXE) {
1091 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1092 sym < sym_end;
1093 sym++) {
1094 if (sym->st_shndx == SHN_UNDEF) {
1095 name = symtab_section->link->data + sym->st_name;
1096 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1097 if (sym_index) {
1098 esym = &((Elf32_Sym *)s1->dynsymtab_section->data)[sym_index];
1099 type = ELF32_ST_TYPE(esym->st_info);
1100 if (type == STT_FUNC) {
1101 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1102 esym->st_info,
1103 sym - (Elf32_Sym *)symtab_section->data);
1104 } else if (type == STT_OBJECT) {
1105 unsigned long offset;
1106 offset = bss_section->data_offset;
1107 /* XXX: which alignment ? */
1108 offset = (offset + 16 - 1) & -16;
1109 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1110 esym->st_info, 0,
1111 bss_section->sh_num, name);
1112 put_elf_reloc(s1->dynsym, bss_section,
1113 offset, R_COPY, index);
1114 offset += esym->st_size;
1115 bss_section->data_offset = offset;
1117 } else {
1118 /* STB_WEAK undefined symbols are accepted */
1119 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1120 it */
1121 if (ELF32_ST_BIND(sym->st_info) == STB_WEAK ||
1122 !strcmp(name, "_fp_hw")) {
1123 } else {
1124 error_noabort("undefined symbol '%s'", name);
1127 } else if (s1->rdynamic &&
1128 ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1129 /* if -rdynamic option, then export all non
1130 local symbols */
1131 name = symtab_section->link->data + sym->st_name;
1132 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1133 sym->st_info, 0,
1134 sym->st_shndx, name);
1138 if (s1->nb_errors)
1139 goto fail;
1141 /* now look at unresolved dynamic symbols and export
1142 corresponding symbol */
1143 sym_end = (Elf32_Sym *)(s1->dynsymtab_section->data +
1144 s1->dynsymtab_section->data_offset);
1145 for(esym = (Elf32_Sym *)s1->dynsymtab_section->data + 1;
1146 esym < sym_end;
1147 esym++) {
1148 if (esym->st_shndx == SHN_UNDEF) {
1149 name = s1->dynsymtab_section->link->data + esym->st_name;
1150 sym_index = find_elf_sym(symtab_section, name);
1151 if (sym_index) {
1152 /* XXX: avoid adding a symbol if already
1153 present because of -rdynamic ? */
1154 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1155 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1156 sym->st_info, 0,
1157 sym->st_shndx, name);
1158 } else {
1159 if (ELF32_ST_BIND(esym->st_info) == STB_WEAK) {
1160 /* weak symbols can stay undefined */
1161 } else {
1162 warning("undefined dynamic symbol '%s'", name);
1167 } else {
1168 int nb_syms;
1169 /* shared library case : we simply export all the global symbols */
1170 nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
1171 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1172 for(sym = (Elf32_Sym *)symtab_section->data + 1;
1173 sym < sym_end;
1174 sym++) {
1175 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1176 name = symtab_section->link->data + sym->st_name;
1177 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1178 sym->st_info, 0,
1179 sym->st_shndx, name);
1180 s1->symtab_to_dynsym[sym -
1181 (Elf32_Sym *)symtab_section->data] =
1182 index;
1187 build_got_entries(s1);
1189 /* add a list of needed dlls */
1190 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1191 DLLReference *dllref = s1->loaded_dlls[i];
1192 if (dllref->level == 0)
1193 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1195 /* XXX: currently, since we do not handle PIC code, we
1196 must relocate the readonly segments */
1197 if (file_type == TCC_OUTPUT_DLL)
1198 put_dt(dynamic, DT_TEXTREL, 0);
1200 /* add necessary space for other entries */
1201 saved_dynamic_data_offset = dynamic->data_offset;
1202 dynamic->data_offset += 8 * 9;
1203 } else {
1204 /* still need to build got entries in case of static link */
1205 build_got_entries(s1);
1209 memset(&ehdr, 0, sizeof(ehdr));
1211 /* we add a section for symbols */
1212 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1213 put_elf_str(strsec, "");
1215 /* compute number of sections */
1216 shnum = s1->nb_sections;
1218 /* this array is used to reorder sections in the output file */
1219 section_order = tcc_malloc(sizeof(int) * shnum);
1220 section_order[0] = 0;
1221 sh_order_index = 1;
1223 /* compute number of program headers */
1224 switch(file_type) {
1225 default:
1226 case TCC_OUTPUT_OBJ:
1227 phnum = 0;
1228 break;
1229 case TCC_OUTPUT_EXE:
1230 if (!s1->static_link)
1231 phnum = 4;
1232 else
1233 phnum = 2;
1234 break;
1235 case TCC_OUTPUT_DLL:
1236 phnum = 3;
1237 break;
1240 /* allocate strings for section names and decide if an unallocated
1241 section should be output */
1242 /* NOTE: the strsec section comes last, so its size is also
1243 correct ! */
1244 for(i = 1; i < s1->nb_sections; i++) {
1245 s = s1->sections[i];
1246 s->sh_name = put_elf_str(strsec, s->name);
1247 /* when generating a DLL, we include relocations but we may
1248 patch them */
1249 if (file_type == TCC_OUTPUT_DLL &&
1250 s->sh_type == SHT_REL &&
1251 !(s->sh_flags & SHF_ALLOC)) {
1252 prepare_dynamic_rel(s1, s);
1253 } else if (do_debug ||
1254 file_type == TCC_OUTPUT_OBJ ||
1255 (s->sh_flags & SHF_ALLOC) ||
1256 i == (s1->nb_sections - 1)) {
1257 /* we output all sections if debug or object file */
1258 s->sh_size = s->data_offset;
1262 /* allocate program segment headers */
1263 phdr = tcc_mallocz(phnum * sizeof(Elf32_Phdr));
1265 file_offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1266 if (phnum > 0) {
1267 /* compute section to program header mapping */
1268 if (file_type == TCC_OUTPUT_DLL)
1269 addr = 0;
1270 else
1271 addr = ELF_START_ADDR;
1273 /* dynamic relocation table information, for .dynamic section */
1274 rel_size = 0;
1275 rel_addr = 0;
1277 /* compute address after headers */
1278 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1280 /* leave one program header for the program interpreter */
1281 ph = &phdr[0];
1282 if (interp)
1283 ph++;
1285 for(j = 0; j < 2; j++) {
1286 ph->p_type = PT_LOAD;
1287 if (j == 0)
1288 ph->p_flags = PF_R | PF_X;
1289 else
1290 ph->p_flags = PF_R | PF_W;
1291 ph->p_align = ELF_PAGE_SIZE;
1293 /* we do the following ordering: interp, symbol tables,
1294 relocations, progbits, nobits */
1295 /* XXX: do faster and simpler sorting */
1296 for(k = 0; k < 5; k++) {
1297 for(i = 1; i < s1->nb_sections; i++) {
1298 s = s1->sections[i];
1299 /* compute if section should be included */
1300 if (j == 0) {
1301 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1302 SHF_ALLOC)
1303 continue;
1304 } else {
1305 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1306 (SHF_ALLOC | SHF_WRITE))
1307 continue;
1309 if (s == interp) {
1310 if (k != 0)
1311 continue;
1312 } else if (s->sh_type == SHT_DYNSYM ||
1313 s->sh_type == SHT_STRTAB ||
1314 s->sh_type == SHT_HASH) {
1315 if (k != 1)
1316 continue;
1317 } else if (s->sh_type == SHT_REL) {
1318 if (k != 2)
1319 continue;
1320 } else if (s->sh_type == SHT_NOBITS) {
1321 if (k != 4)
1322 continue;
1323 } else {
1324 if (k != 3)
1325 continue;
1327 section_order[sh_order_index++] = i;
1329 /* section matches: we align it and add its size */
1330 tmp = file_offset;
1331 file_offset = (file_offset + s->sh_addralign - 1) &
1332 ~(s->sh_addralign - 1);
1333 s->sh_offset = file_offset;
1334 addr += file_offset - tmp;
1335 s->sh_addr = addr;
1337 /* update program header infos */
1338 if (ph->p_offset == 0) {
1339 ph->p_offset = file_offset;
1340 ph->p_vaddr = addr;
1341 ph->p_paddr = ph->p_vaddr;
1343 /* update dynamic relocation infos */
1344 if (s->sh_type == SHT_REL) {
1345 if (rel_size == 0)
1346 rel_addr = addr;
1347 rel_size += s->sh_size;
1349 addr += s->sh_size;
1350 if (s->sh_type != SHT_NOBITS)
1351 file_offset += s->sh_size;
1354 ph->p_filesz = file_offset - ph->p_offset;
1355 ph->p_memsz = addr - ph->p_vaddr;
1356 ph++;
1357 /* if in the middle of a page, we duplicate the page in
1358 memory so that one copy is RX and the other is RW */
1359 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1360 addr += ELF_PAGE_SIZE;
1363 /* if interpreter, then add corresponing program header */
1364 if (interp) {
1365 ph = &phdr[0];
1367 ph->p_type = PT_INTERP;
1368 ph->p_offset = interp->sh_offset;
1369 ph->p_vaddr = interp->sh_addr;
1370 ph->p_paddr = ph->p_vaddr;
1371 ph->p_filesz = interp->sh_size;
1372 ph->p_memsz = interp->sh_size;
1373 ph->p_flags = PF_R;
1374 ph->p_align = interp->sh_addralign;
1377 /* if dynamic section, then add corresponing program header */
1378 if (dynamic) {
1379 Elf32_Sym *sym_end;
1381 ph = &phdr[phnum - 1];
1383 ph->p_type = PT_DYNAMIC;
1384 ph->p_offset = dynamic->sh_offset;
1385 ph->p_vaddr = dynamic->sh_addr;
1386 ph->p_paddr = ph->p_vaddr;
1387 ph->p_filesz = dynamic->sh_size;
1388 ph->p_memsz = dynamic->sh_size;
1389 ph->p_flags = PF_R | PF_W;
1390 ph->p_align = dynamic->sh_addralign;
1392 /* put GOT dynamic section address */
1393 put32(s1->got->data, dynamic->sh_addr);
1395 /* relocate the PLT */
1396 if (file_type == TCC_OUTPUT_EXE) {
1397 uint8_t *p, *p_end;
1399 p = s1->plt->data;
1400 p_end = p + s1->plt->data_offset;
1401 if (p < p_end) {
1402 #if defined(TCC_TARGET_I386)
1403 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1404 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1405 p += 16;
1406 while (p < p_end) {
1407 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1408 p += 16;
1410 #elif defined(TCC_TARGET_ARM)
1411 int x;
1412 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1413 p +=16;
1414 while (p < p_end) {
1415 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1416 p += 16;
1418 #else
1419 #error unsupported CPU
1420 #endif
1424 /* relocate symbols in .dynsym */
1425 sym_end = (Elf32_Sym *)(s1->dynsym->data + s1->dynsym->data_offset);
1426 for(sym = (Elf32_Sym *)s1->dynsym->data + 1;
1427 sym < sym_end;
1428 sym++) {
1429 if (sym->st_shndx == SHN_UNDEF) {
1430 /* relocate to the PLT if the symbol corresponds
1431 to a PLT entry */
1432 if (sym->st_value)
1433 sym->st_value += s1->plt->sh_addr;
1434 } else if (sym->st_shndx < SHN_LORESERVE) {
1435 /* do symbol relocation */
1436 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1440 /* put dynamic section entries */
1441 dynamic->data_offset = saved_dynamic_data_offset;
1442 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1443 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1444 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1445 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1446 put_dt(dynamic, DT_SYMENT, sizeof(Elf32_Sym));
1447 put_dt(dynamic, DT_REL, rel_addr);
1448 put_dt(dynamic, DT_RELSZ, rel_size);
1449 put_dt(dynamic, DT_RELENT, sizeof(Elf32_Rel));
1450 put_dt(dynamic, DT_NULL, 0);
1453 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1454 ehdr.e_phnum = phnum;
1455 ehdr.e_phoff = sizeof(Elf32_Ehdr);
1458 /* all other sections come after */
1459 for(i = 1; i < s1->nb_sections; i++) {
1460 s = s1->sections[i];
1461 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1462 continue;
1463 section_order[sh_order_index++] = i;
1465 file_offset = (file_offset + s->sh_addralign - 1) &
1466 ~(s->sh_addralign - 1);
1467 s->sh_offset = file_offset;
1468 if (s->sh_type != SHT_NOBITS)
1469 file_offset += s->sh_size;
1472 /* if building executable or DLL, then relocate each section
1473 except the GOT which is already relocated */
1474 if (file_type != TCC_OUTPUT_OBJ) {
1475 relocate_syms(s1, 0);
1477 if (s1->nb_errors != 0) {
1478 fail:
1479 ret = -1;
1480 goto the_end;
1483 /* relocate sections */
1484 /* XXX: ignore sections with allocated relocations ? */
1485 for(i = 1; i < s1->nb_sections; i++) {
1486 s = s1->sections[i];
1487 if (s->reloc && s != s1->got)
1488 relocate_section(s1, s);
1491 /* relocate relocation entries if the relocation tables are
1492 allocated in the executable */
1493 for(i = 1; i < s1->nb_sections; i++) {
1494 s = s1->sections[i];
1495 if ((s->sh_flags & SHF_ALLOC) &&
1496 s->sh_type == SHT_REL) {
1497 relocate_rel(s1, s);
1501 /* get entry point address */
1502 if (file_type == TCC_OUTPUT_EXE)
1503 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
1504 else
1505 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1508 sort_syms(s1, symtab_section);
1510 /* align to 4 */
1511 file_offset = (file_offset + 3) & -4;
1513 /* fill header */
1514 ehdr.e_ident[0] = ELFMAG0;
1515 ehdr.e_ident[1] = ELFMAG1;
1516 ehdr.e_ident[2] = ELFMAG2;
1517 ehdr.e_ident[3] = ELFMAG3;
1518 ehdr.e_ident[4] = ELFCLASS32;
1519 ehdr.e_ident[5] = ELFDATA2LSB;
1520 ehdr.e_ident[6] = EV_CURRENT;
1521 #ifdef __FreeBSD__
1522 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1523 #endif
1524 #ifdef TCC_TARGET_ARM
1525 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1526 #endif
1527 switch(file_type) {
1528 default:
1529 case TCC_OUTPUT_EXE:
1530 ehdr.e_type = ET_EXEC;
1531 break;
1532 case TCC_OUTPUT_DLL:
1533 ehdr.e_type = ET_DYN;
1534 break;
1535 case TCC_OUTPUT_OBJ:
1536 ehdr.e_type = ET_REL;
1537 break;
1539 ehdr.e_machine = EM_TCC_TARGET;
1540 ehdr.e_version = EV_CURRENT;
1541 ehdr.e_shoff = file_offset;
1542 ehdr.e_ehsize = sizeof(Elf32_Ehdr);
1543 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1544 ehdr.e_shnum = shnum;
1545 ehdr.e_shstrndx = shnum - 1;
1547 /* write elf file */
1548 if (file_type == TCC_OUTPUT_OBJ)
1549 mode = 0666;
1550 else
1551 mode = 0777;
1552 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
1553 if (fd < 0) {
1554 error_noabort("could not write '%s'", filename);
1555 goto fail;
1557 f = fdopen(fd, "w");
1558 fwrite(&ehdr, 1, sizeof(Elf32_Ehdr), f);
1559 fwrite(phdr, 1, phnum * sizeof(Elf32_Phdr), f);
1560 offset = sizeof(Elf32_Ehdr) + phnum * sizeof(Elf32_Phdr);
1561 for(i=1;i<s1->nb_sections;i++) {
1562 s = s1->sections[section_order[i]];
1563 if (s->sh_type != SHT_NOBITS) {
1564 while (offset < s->sh_offset) {
1565 fputc(0, f);
1566 offset++;
1568 size = s->sh_size;
1569 fwrite(s->data, 1, size, f);
1570 offset += size;
1573 while (offset < ehdr.e_shoff) {
1574 fputc(0, f);
1575 offset++;
1578 /* output section headers */
1579 for(i=0;i<s1->nb_sections;i++) {
1580 sh = &shdr;
1581 memset(sh, 0, sizeof(Elf32_Shdr));
1582 s = s1->sections[i];
1583 if (s) {
1584 sh->sh_name = s->sh_name;
1585 sh->sh_type = s->sh_type;
1586 sh->sh_flags = s->sh_flags;
1587 sh->sh_entsize = s->sh_entsize;
1588 sh->sh_info = s->sh_info;
1589 if (s->link)
1590 sh->sh_link = s->link->sh_num;
1591 sh->sh_addralign = s->sh_addralign;
1592 sh->sh_addr = s->sh_addr;
1593 sh->sh_offset = s->sh_offset;
1594 sh->sh_size = s->sh_size;
1596 fwrite(sh, 1, sizeof(Elf32_Shdr), f);
1598 fclose(f);
1600 ret = 0;
1601 the_end:
1602 tcc_free(s1->symtab_to_dynsym);
1603 tcc_free(section_order);
1604 tcc_free(phdr);
1605 tcc_free(s1->got_offsets);
1606 return ret;
1609 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
1611 void *data;
1613 data = tcc_malloc(size);
1614 lseek(fd, file_offset, SEEK_SET);
1615 read(fd, data, size);
1616 return data;
1619 typedef struct SectionMergeInfo {
1620 Section *s; /* corresponding existing section */
1621 unsigned long offset; /* offset of the new section in the existing section */
1622 uint8_t new_section; /* true if section 's' was added */
1623 uint8_t link_once; /* true if link once section */
1624 } SectionMergeInfo;
1626 /* load an object file and merge it with current files */
1627 /* XXX: handle correctly stab (debug) info */
1628 static int tcc_load_object_file(TCCState *s1,
1629 int fd, unsigned long file_offset)
1631 Elf32_Ehdr ehdr;
1632 Elf32_Shdr *shdr, *sh;
1633 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
1634 unsigned char *strsec, *strtab;
1635 int *old_to_new_syms;
1636 char *sh_name, *name;
1637 SectionMergeInfo *sm_table, *sm;
1638 Elf32_Sym *sym, *symtab;
1639 Elf32_Rel *rel, *rel_end;
1640 Section *s;
1642 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
1643 goto fail1;
1644 if (ehdr.e_ident[0] != ELFMAG0 ||
1645 ehdr.e_ident[1] != ELFMAG1 ||
1646 ehdr.e_ident[2] != ELFMAG2 ||
1647 ehdr.e_ident[3] != ELFMAG3)
1648 goto fail1;
1649 /* test if object file */
1650 if (ehdr.e_type != ET_REL)
1651 goto fail1;
1652 /* test CPU specific stuff */
1653 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1654 ehdr.e_machine != EM_TCC_TARGET) {
1655 fail1:
1656 error_noabort("invalid object file");
1657 return -1;
1659 /* read sections */
1660 shdr = load_data(fd, file_offset + ehdr.e_shoff,
1661 sizeof(Elf32_Shdr) * ehdr.e_shnum);
1662 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
1664 /* load section names */
1665 sh = &shdr[ehdr.e_shstrndx];
1666 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1668 /* load symtab and strtab */
1669 old_to_new_syms = NULL;
1670 symtab = NULL;
1671 strtab = NULL;
1672 nb_syms = 0;
1673 for(i = 1; i < ehdr.e_shnum; i++) {
1674 sh = &shdr[i];
1675 if (sh->sh_type == SHT_SYMTAB) {
1676 if (symtab) {
1677 error_noabort("object must contain only one symtab");
1678 fail:
1679 ret = -1;
1680 goto the_end;
1682 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
1683 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1684 sm_table[i].s = symtab_section;
1686 /* now load strtab */
1687 sh = &shdr[sh->sh_link];
1688 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
1692 /* now examine each section and try to merge its content with the
1693 ones in memory */
1694 for(i = 1; i < ehdr.e_shnum; i++) {
1695 /* no need to examine section name strtab */
1696 if (i == ehdr.e_shstrndx)
1697 continue;
1698 sh = &shdr[i];
1699 sh_name = strsec + sh->sh_name;
1700 /* ignore sections types we do not handle */
1701 if (sh->sh_type != SHT_PROGBITS &&
1702 sh->sh_type != SHT_REL &&
1703 sh->sh_type != SHT_NOBITS)
1704 continue;
1705 if (sh->sh_addralign < 1)
1706 sh->sh_addralign = 1;
1707 /* find corresponding section, if any */
1708 for(j = 1; j < s1->nb_sections;j++) {
1709 s = s1->sections[j];
1710 if (!strcmp(s->name, sh_name)) {
1711 if (!strncmp(sh_name, ".gnu.linkonce",
1712 sizeof(".gnu.linkonce") - 1)) {
1713 /* if a 'linkonce' section is already present, we
1714 do not add it again. It is a little tricky as
1715 symbols can still be defined in
1716 it. */
1717 sm_table[i].link_once = 1;
1718 goto next;
1719 } else {
1720 goto found;
1724 /* not found: create new section */
1725 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
1726 /* take as much info as possible from the section. sh_link and
1727 sh_info will be updated later */
1728 s->sh_addralign = sh->sh_addralign;
1729 s->sh_entsize = sh->sh_entsize;
1730 sm_table[i].new_section = 1;
1731 found:
1732 if (sh->sh_type != s->sh_type) {
1733 error_noabort("invalid section type");
1734 goto fail;
1737 /* align start of section */
1738 offset = s->data_offset;
1739 size = sh->sh_addralign - 1;
1740 offset = (offset + size) & ~size;
1741 if (sh->sh_addralign > s->sh_addralign)
1742 s->sh_addralign = sh->sh_addralign;
1743 s->data_offset = offset;
1744 sm_table[i].offset = offset;
1745 sm_table[i].s = s;
1746 /* concatenate sections */
1747 size = sh->sh_size;
1748 if (sh->sh_type != SHT_NOBITS) {
1749 unsigned char *ptr;
1750 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
1751 ptr = section_ptr_add(s, size);
1752 read(fd, ptr, size);
1753 } else {
1754 s->data_offset += size;
1756 next: ;
1759 /* second short pass to update sh_link and sh_info fields of new
1760 sections */
1761 sm = sm_table;
1762 for(i = 1; i < ehdr.e_shnum; i++) {
1763 s = sm_table[i].s;
1764 if (!s || !sm_table[i].new_section)
1765 continue;
1766 sh = &shdr[i];
1767 if (sh->sh_link > 0)
1768 s->link = sm_table[sh->sh_link].s;
1769 if (sh->sh_type == SHT_REL) {
1770 s->sh_info = sm_table[sh->sh_info].s->sh_num;
1771 /* update backward link */
1772 s1->sections[s->sh_info]->reloc = s;
1776 /* resolve symbols */
1777 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
1779 sym = symtab + 1;
1780 for(i = 1; i < nb_syms; i++, sym++) {
1781 if (sym->st_shndx != SHN_UNDEF &&
1782 sym->st_shndx < SHN_LORESERVE) {
1783 sm = &sm_table[sym->st_shndx];
1784 if (sm->link_once) {
1785 /* if a symbol is in a link once section, we use the
1786 already defined symbol. It is very important to get
1787 correct relocations */
1788 if (ELF32_ST_BIND(sym->st_info) != STB_LOCAL) {
1789 name = strtab + sym->st_name;
1790 sym_index = find_elf_sym(symtab_section, name);
1791 if (sym_index)
1792 old_to_new_syms[i] = sym_index;
1794 continue;
1796 /* if no corresponding section added, no need to add symbol */
1797 if (!sm->s)
1798 continue;
1799 /* convert section number */
1800 sym->st_shndx = sm->s->sh_num;
1801 /* offset value */
1802 sym->st_value += sm->offset;
1804 /* add symbol */
1805 name = strtab + sym->st_name;
1806 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
1807 sym->st_info, sym->st_shndx, name);
1808 old_to_new_syms[i] = sym_index;
1811 /* third pass to patch relocation entries */
1812 for(i = 1; i < ehdr.e_shnum; i++) {
1813 s = sm_table[i].s;
1814 if (!s)
1815 continue;
1816 sh = &shdr[i];
1817 offset = sm_table[i].offset;
1818 switch(s->sh_type) {
1819 case SHT_REL:
1820 /* take relocation offset information */
1821 offseti = sm_table[sh->sh_info].offset;
1822 rel_end = (Elf32_Rel *)(s->data + s->data_offset);
1823 for(rel = (Elf32_Rel *)(s->data + offset);
1824 rel < rel_end;
1825 rel++) {
1826 int type;
1827 unsigned sym_index;
1828 /* convert symbol index */
1829 type = ELF32_R_TYPE(rel->r_info);
1830 sym_index = ELF32_R_SYM(rel->r_info);
1831 /* NOTE: only one symtab assumed */
1832 if (sym_index >= nb_syms)
1833 goto invalid_reloc;
1834 sym_index = old_to_new_syms[sym_index];
1835 if (!sym_index) {
1836 invalid_reloc:
1837 error_noabort("Invalid relocation entry");
1838 goto fail;
1840 rel->r_info = ELF32_R_INFO(sym_index, type);
1841 /* offset the relocation offset */
1842 rel->r_offset += offseti;
1844 break;
1845 default:
1846 break;
1850 ret = 0;
1851 the_end:
1852 tcc_free(symtab);
1853 tcc_free(strtab);
1854 tcc_free(old_to_new_syms);
1855 tcc_free(sm_table);
1856 tcc_free(strsec);
1857 tcc_free(shdr);
1858 return ret;
1861 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1863 typedef struct ArchiveHeader {
1864 char ar_name[16]; /* name of this member */
1865 char ar_date[12]; /* file mtime */
1866 char ar_uid[6]; /* owner uid; printed as decimal */
1867 char ar_gid[6]; /* owner gid; printed as decimal */
1868 char ar_mode[8]; /* file mode, printed as octal */
1869 char ar_size[10]; /* file size, printed as decimal */
1870 char ar_fmag[2]; /* should contain ARFMAG */
1871 } ArchiveHeader;
1873 static int get_be32(const uint8_t *b)
1875 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
1878 /* load only the objects which resolve undefined symbols */
1879 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
1881 int i, bound, nsyms, sym_index, off, ret;
1882 uint8_t *data;
1883 const char *ar_names, *p;
1884 const uint8_t *ar_index;
1885 Elf32_Sym *sym;
1887 data = tcc_malloc(size);
1888 if (read(fd, data, size) != size)
1889 goto fail;
1890 nsyms = get_be32(data);
1891 ar_index = data + 4;
1892 ar_names = ar_index + nsyms * 4;
1894 do {
1895 bound = 0;
1896 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
1897 sym_index = find_elf_sym(symtab_section, p);
1898 if(sym_index) {
1899 sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
1900 if(sym->st_shndx == SHN_UNDEF) {
1901 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
1902 #if 0
1903 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
1904 #endif
1905 ++bound;
1906 lseek(fd, off, SEEK_SET);
1907 if(tcc_load_object_file(s1, fd, off) < 0) {
1908 fail:
1909 ret = -1;
1910 goto the_end;
1915 } while(bound);
1916 ret = 0;
1917 the_end:
1918 tcc_free(data);
1919 return ret;
1922 /* load a '.a' file */
1923 static int tcc_load_archive(TCCState *s1, int fd)
1925 ArchiveHeader hdr;
1926 char ar_size[11];
1927 char ar_name[17];
1928 char magic[8];
1929 int size, len, i;
1930 unsigned long file_offset;
1932 /* skip magic which was already checked */
1933 read(fd, magic, sizeof(magic));
1935 for(;;) {
1936 len = read(fd, &hdr, sizeof(hdr));
1937 if (len == 0)
1938 break;
1939 if (len != sizeof(hdr)) {
1940 error_noabort("invalid archive");
1941 return -1;
1943 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
1944 ar_size[sizeof(hdr.ar_size)] = '\0';
1945 size = strtol(ar_size, NULL, 0);
1946 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
1947 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
1948 if (ar_name[i] != ' ')
1949 break;
1951 ar_name[i + 1] = '\0';
1952 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
1953 file_offset = lseek(fd, 0, SEEK_CUR);
1954 /* align to even */
1955 size = (size + 1) & ~1;
1956 if (!strcmp(ar_name, "/")) {
1957 /* coff symbol table : we handle it */
1958 if(s1->alacarte_link)
1959 return tcc_load_alacarte(s1, fd, size);
1960 } else if (!strcmp(ar_name, "//") ||
1961 !strcmp(ar_name, "__.SYMDEF") ||
1962 !strcmp(ar_name, "__.SYMDEF/") ||
1963 !strcmp(ar_name, "ARFILENAMES/")) {
1964 /* skip symbol table or archive names */
1965 } else {
1966 if (tcc_load_object_file(s1, fd, file_offset) < 0)
1967 return -1;
1969 lseek(fd, file_offset + size, SEEK_SET);
1971 return 0;
1974 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
1975 is referenced by the user (so it should be added as DT_NEEDED in
1976 the generated ELF file) */
1977 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
1979 Elf32_Ehdr ehdr;
1980 Elf32_Shdr *shdr, *sh, *sh1;
1981 int i, nb_syms, nb_dts, sym_bind, ret;
1982 Elf32_Sym *sym, *dynsym;
1983 Elf32_Dyn *dt, *dynamic;
1984 unsigned char *dynstr;
1985 const char *name, *soname, *p;
1986 DLLReference *dllref;
1988 read(fd, &ehdr, sizeof(ehdr));
1990 /* test CPU specific stuff */
1991 if (ehdr.e_ident[5] != ELFDATA2LSB ||
1992 ehdr.e_machine != EM_TCC_TARGET) {
1993 error_noabort("bad architecture");
1994 return -1;
1997 /* read sections */
1998 shdr = load_data(fd, ehdr.e_shoff, sizeof(Elf32_Shdr) * ehdr.e_shnum);
2000 /* load dynamic section and dynamic symbols */
2001 nb_syms = 0;
2002 nb_dts = 0;
2003 dynamic = NULL;
2004 dynsym = NULL; /* avoid warning */
2005 dynstr = NULL; /* avoid warning */
2006 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2007 switch(sh->sh_type) {
2008 case SHT_DYNAMIC:
2009 nb_dts = sh->sh_size / sizeof(Elf32_Dyn);
2010 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2011 break;
2012 case SHT_DYNSYM:
2013 nb_syms = sh->sh_size / sizeof(Elf32_Sym);
2014 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2015 sh1 = &shdr[sh->sh_link];
2016 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2017 break;
2018 default:
2019 break;
2023 /* compute the real library name */
2024 soname = filename;
2025 p = strrchr(soname, '/');
2026 if (p)
2027 soname = p + 1;
2029 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2030 if (dt->d_tag == DT_SONAME) {
2031 soname = dynstr + dt->d_un.d_val;
2035 /* if the dll is already loaded, do not load it */
2036 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2037 dllref = s1->loaded_dlls[i];
2038 if (!strcmp(soname, dllref->name)) {
2039 /* but update level if needed */
2040 if (level < dllref->level)
2041 dllref->level = level;
2042 ret = 0;
2043 goto the_end;
2047 // printf("loading dll '%s'\n", soname);
2049 /* add the dll and its level */
2050 dllref = tcc_malloc(sizeof(DLLReference) + strlen(soname));
2051 dllref->level = level;
2052 strcpy(dllref->name, soname);
2053 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2055 /* add dynamic symbols in dynsym_section */
2056 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2057 sym_bind = ELF32_ST_BIND(sym->st_info);
2058 if (sym_bind == STB_LOCAL)
2059 continue;
2060 name = dynstr + sym->st_name;
2061 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2062 sym->st_info, sym->st_shndx, name);
2065 /* load all referenced DLLs */
2066 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2067 switch(dt->d_tag) {
2068 case DT_NEEDED:
2069 name = dynstr + dt->d_un.d_val;
2070 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2071 dllref = s1->loaded_dlls[i];
2072 if (!strcmp(name, dllref->name))
2073 goto already_loaded;
2075 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2076 error_noabort("referenced dll '%s' not found", name);
2077 ret = -1;
2078 goto the_end;
2080 already_loaded:
2081 break;
2084 ret = 0;
2085 the_end:
2086 tcc_free(dynstr);
2087 tcc_free(dynsym);
2088 tcc_free(dynamic);
2089 tcc_free(shdr);
2090 return ret;
2093 #define LD_TOK_NAME 256
2094 #define LD_TOK_EOF (-1)
2096 /* return next ld script token */
2097 static int ld_next(TCCState *s1, char *name, int name_size)
2099 int c;
2100 char *q;
2102 redo:
2103 switch(ch) {
2104 case ' ':
2105 case '\t':
2106 case '\f':
2107 case '\v':
2108 case '\r':
2109 case '\n':
2110 inp();
2111 goto redo;
2112 case '/':
2113 minp();
2114 if (ch == '*') {
2115 file->buf_ptr = parse_comment(file->buf_ptr);
2116 ch = file->buf_ptr[0];
2117 goto redo;
2118 } else {
2119 q = name;
2120 *q++ = '/';
2121 goto parse_name;
2123 break;
2124 case 'a' ... 'z':
2125 case 'A' ... 'Z':
2126 case '_':
2127 case '\\':
2128 case '.':
2129 case '$':
2130 case '~':
2131 q = name;
2132 parse_name:
2133 for(;;) {
2134 if (!((ch >= 'a' && ch <= 'z') ||
2135 (ch >= 'A' && ch <= 'Z') ||
2136 (ch >= '0' && ch <= '9') ||
2137 strchr("/.-_+=$:\\,~", ch)))
2138 break;
2139 if ((q - name) < name_size - 1) {
2140 *q++ = ch;
2142 minp();
2144 *q = '\0';
2145 c = LD_TOK_NAME;
2146 break;
2147 case CH_EOF:
2148 c = LD_TOK_EOF;
2149 break;
2150 default:
2151 c = ch;
2152 inp();
2153 break;
2155 #if 0
2156 printf("tok=%c %d\n", c, c);
2157 if (c == LD_TOK_NAME)
2158 printf(" name=%s\n", name);
2159 #endif
2160 return c;
2163 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2164 files */
2165 static int tcc_load_ldscript(TCCState *s1)
2167 char cmd[64];
2168 char filename[1024];
2169 int t;
2171 ch = file->buf_ptr[0];
2172 ch = handle_eob();
2173 for(;;) {
2174 t = ld_next(s1, cmd, sizeof(cmd));
2175 if (t == LD_TOK_EOF)
2176 return 0;
2177 else if (t != LD_TOK_NAME)
2178 return -1;
2179 if (!strcmp(cmd, "INPUT") ||
2180 !strcmp(cmd, "GROUP")) {
2181 t = ld_next(s1, cmd, sizeof(cmd));
2182 if (t != '(')
2183 expect("(");
2184 t = ld_next(s1, filename, sizeof(filename));
2185 for(;;) {
2186 if (t == LD_TOK_EOF) {
2187 error_noabort("unexpected end of file");
2188 return -1;
2189 } else if (t == ')') {
2190 break;
2191 } else if (t != LD_TOK_NAME) {
2192 error_noabort("filename expected");
2193 return -1;
2195 tcc_add_file(s1, filename);
2196 t = ld_next(s1, filename, sizeof(filename));
2197 if (t == ',') {
2198 t = ld_next(s1, filename, sizeof(filename));
2201 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2202 !strcmp(cmd, "TARGET")) {
2203 /* ignore some commands */
2204 t = ld_next(s1, cmd, sizeof(cmd));
2205 if (t != '(')
2206 expect("(");
2207 for(;;) {
2208 t = ld_next(s1, filename, sizeof(filename));
2209 if (t == LD_TOK_EOF) {
2210 error_noabort("unexpected end of file");
2211 return -1;
2212 } else if (t == ')') {
2213 break;
2216 } else {
2217 return -1;
2220 return 0;