Fix silly typos in the previous change.
[tinycc.git] / tccelf.c
blob6cf11e2bdfe29c6c46475f29461867972fa985f4
1 /*
2 * ELF file handling for TCC
3 *
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #ifdef TCC_TARGET_X86_64
22 #define ElfW_Rel ElfW(Rela)
23 #define SHT_RELX SHT_RELA
24 #define REL_SECTION_FMT ".rela%s"
25 /* x86-64 requires PLT for DLLs */
26 #define TCC_OUTPUT_DLL_WITH_PLT
27 #else
28 #define ElfW_Rel ElfW(Rel)
29 #define SHT_RELX SHT_REL
30 #define REL_SECTION_FMT ".rel%s"
31 #endif
33 /* XXX: DLL with PLT would only work with x86-64 for now */
34 //#define TCC_OUTPUT_DLL_WITH_PLT
36 static int put_elf_str(Section *s, const char *sym)
38 int offset, len;
39 char *ptr;
41 len = strlen(sym) + 1;
42 offset = s->data_offset;
43 ptr = section_ptr_add(s, len);
44 memcpy(ptr, sym, len);
45 return offset;
48 /* elf symbol hashing function */
49 static unsigned long elf_hash(const unsigned char *name)
51 unsigned long h = 0, g;
53 while (*name) {
54 h = (h << 4) + *name++;
55 g = h & 0xf0000000;
56 if (g)
57 h ^= g >> 24;
58 h &= ~g;
60 return h;
63 /* rebuild hash table of section s */
64 /* NOTE: we do factorize the hash table code to go faster */
65 static void rebuild_hash(Section *s, unsigned int nb_buckets)
67 ElfW(Sym) *sym;
68 int *ptr, *hash, nb_syms, sym_index, h;
69 char *strtab;
71 strtab = s->link->data;
72 nb_syms = s->data_offset / sizeof(ElfW(Sym));
74 s->hash->data_offset = 0;
75 ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
76 ptr[0] = nb_buckets;
77 ptr[1] = nb_syms;
78 ptr += 2;
79 hash = ptr;
80 memset(hash, 0, (nb_buckets + 1) * sizeof(int));
81 ptr += nb_buckets + 1;
83 sym = (ElfW(Sym) *)s->data + 1;
84 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
85 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
86 h = elf_hash(strtab + sym->st_name) % nb_buckets;
87 *ptr = hash[h];
88 hash[h] = sym_index;
89 } else {
90 *ptr = 0;
92 ptr++;
93 sym++;
97 /* return the symbol number */
98 static int put_elf_sym(Section *s,
99 unsigned long value, unsigned long size,
100 int info, int other, int shndx, const char *name)
102 int name_offset, sym_index;
103 int nbuckets, h;
104 ElfW(Sym) *sym;
105 Section *hs;
107 sym = section_ptr_add(s, sizeof(ElfW(Sym)));
108 if (name)
109 name_offset = put_elf_str(s->link, name);
110 else
111 name_offset = 0;
112 /* XXX: endianness */
113 sym->st_name = name_offset;
114 sym->st_value = value;
115 sym->st_size = size;
116 sym->st_info = info;
117 sym->st_other = other;
118 sym->st_shndx = shndx;
119 sym_index = sym - (ElfW(Sym) *)s->data;
120 hs = s->hash;
121 if (hs) {
122 int *ptr, *base;
123 ptr = section_ptr_add(hs, sizeof(int));
124 base = (int *)hs->data;
125 /* only add global or weak symbols */
126 if (ELFW(ST_BIND)(info) != STB_LOCAL) {
127 /* add another hashing entry */
128 nbuckets = base[0];
129 h = elf_hash(name) % nbuckets;
130 *ptr = base[2 + h];
131 base[2 + h] = sym_index;
132 base[1]++;
133 /* we resize the hash table */
134 hs->nb_hashed_syms++;
135 if (hs->nb_hashed_syms > 2 * nbuckets) {
136 rebuild_hash(s, 2 * nbuckets);
138 } else {
139 *ptr = 0;
140 base[1]++;
143 return sym_index;
146 /* find global ELF symbol 'name' and return its index. Return 0 if not
147 found. */
148 static int find_elf_sym(Section *s, const char *name)
150 ElfW(Sym) *sym;
151 Section *hs;
152 int nbuckets, sym_index, h;
153 const char *name1;
155 hs = s->hash;
156 if (!hs)
157 return 0;
158 nbuckets = ((int *)hs->data)[0];
159 h = elf_hash(name) % nbuckets;
160 sym_index = ((int *)hs->data)[2 + h];
161 while (sym_index != 0) {
162 sym = &((ElfW(Sym) *)s->data)[sym_index];
163 name1 = s->link->data + sym->st_name;
164 if (!strcmp(name, name1))
165 return sym_index;
166 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
168 return 0;
171 /* return elf symbol value or error */
172 int tcc_get_symbol(TCCState *s, unsigned long *pval, const char *name)
174 int sym_index;
175 ElfW(Sym) *sym;
177 sym_index = find_elf_sym(symtab_section, name);
178 if (!sym_index)
179 return -1;
180 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
181 *pval = sym->st_value;
182 return 0;
185 void *tcc_get_symbol_err(TCCState *s, const char *name)
187 unsigned long val;
188 if (tcc_get_symbol(s, &val, name) < 0)
189 error("%s not defined", name);
190 return (void *)val;
193 /* add an elf symbol : check if it is already defined and patch
194 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
195 static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
196 int info, int other, int sh_num, const char *name)
198 ElfW(Sym) *esym;
199 int sym_bind, sym_index, sym_type, esym_bind;
200 unsigned char sym_vis, esym_vis, new_vis;
202 sym_bind = ELFW(ST_BIND)(info);
203 sym_type = ELFW(ST_TYPE)(info);
204 sym_vis = ELFW(ST_VISIBILITY)(other);
206 if (sym_bind != STB_LOCAL) {
207 /* we search global or weak symbols */
208 sym_index = find_elf_sym(s, name);
209 if (!sym_index)
210 goto do_def;
211 esym = &((ElfW(Sym) *)s->data)[sym_index];
212 if (esym->st_shndx != SHN_UNDEF) {
213 esym_bind = ELFW(ST_BIND)(esym->st_info);
214 /* propagate the most constraining visibility */
215 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
216 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
217 if (esym_vis == STV_DEFAULT) {
218 new_vis = sym_vis;
219 } else if (sym_vis == STV_DEFAULT) {
220 new_vis = esym_vis;
221 } else {
222 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
224 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
225 | new_vis;
226 other = esym->st_other; /* in case we have to patch esym */
227 if (sh_num == SHN_UNDEF) {
228 /* ignore adding of undefined symbol if the
229 corresponding symbol is already defined */
230 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
231 /* global overrides weak, so patch */
232 goto do_patch;
233 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
234 /* weak is ignored if already global */
235 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
236 /* ignore hidden symbols after */
237 } else if (esym->st_shndx == SHN_COMMON && sh_num < SHN_LORESERVE) {
238 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
239 No idea if this is the correct solution ... */
240 goto do_patch;
241 } else if (s == tcc_state->dynsymtab_section) {
242 /* we accept that two DLL define the same symbol */
243 } else {
244 #if 1
245 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
246 sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
247 #endif
248 error_noabort("'%s' defined twice", name);
250 } else {
251 do_patch:
252 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
253 esym->st_shndx = sh_num;
254 esym->st_value = value;
255 esym->st_size = size;
256 esym->st_other = other;
258 } else {
259 do_def:
260 sym_index = put_elf_sym(s, value, size,
261 ELFW(ST_INFO)(sym_bind, sym_type), other,
262 sh_num, name);
264 return sym_index;
267 /* put relocation */
268 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
269 int type, int symbol)
271 char buf[256];
272 Section *sr;
273 ElfW_Rel *rel;
275 sr = s->reloc;
276 if (!sr) {
277 /* if no relocation section, create it */
278 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
279 /* if the symtab is allocated, then we consider the relocation
280 are also */
281 sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
282 sr->sh_entsize = sizeof(ElfW_Rel);
283 sr->link = symtab;
284 sr->sh_info = s->sh_num;
285 s->reloc = sr;
287 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
288 rel->r_offset = offset;
289 rel->r_info = ELFW(R_INFO)(symbol, type);
290 #ifdef TCC_TARGET_X86_64
291 rel->r_addend = 0;
292 #endif
295 /* put stab debug information */
297 typedef struct {
298 unsigned int n_strx; /* index into string table of name */
299 unsigned char n_type; /* type of symbol */
300 unsigned char n_other; /* misc info (usually empty) */
301 unsigned short n_desc; /* description field */
302 unsigned int n_value; /* value of symbol */
303 } Stab_Sym;
305 static void put_stabs(const char *str, int type, int other, int desc,
306 unsigned long value)
308 Stab_Sym *sym;
310 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
311 if (str) {
312 sym->n_strx = put_elf_str(stabstr_section, str);
313 } else {
314 sym->n_strx = 0;
316 sym->n_type = type;
317 sym->n_other = other;
318 sym->n_desc = desc;
319 sym->n_value = value;
322 static void put_stabs_r(const char *str, int type, int other, int desc,
323 unsigned long value, Section *sec, int sym_index)
325 put_stabs(str, type, other, desc, value);
326 put_elf_reloc(symtab_section, stab_section,
327 stab_section->data_offset - sizeof(unsigned int),
328 R_DATA_32, sym_index);
331 static void put_stabn(int type, int other, int desc, int value)
333 put_stabs(NULL, type, other, desc, value);
336 static void put_stabd(int type, int other, int desc)
338 put_stabs(NULL, type, other, desc, 0);
341 /* In an ELF file symbol table, the local symbols must appear below
342 the global and weak ones. Since TCC cannot sort it while generating
343 the code, we must do it after. All the relocation tables are also
344 modified to take into account the symbol table sorting */
345 static void sort_syms(TCCState *s1, Section *s)
347 int *old_to_new_syms;
348 ElfW(Sym) *new_syms;
349 int nb_syms, i;
350 ElfW(Sym) *p, *q;
351 ElfW_Rel *rel, *rel_end;
352 Section *sr;
353 int type, sym_index;
355 nb_syms = s->data_offset / sizeof(ElfW(Sym));
356 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
357 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
359 /* first pass for local symbols */
360 p = (ElfW(Sym) *)s->data;
361 q = new_syms;
362 for(i = 0; i < nb_syms; i++) {
363 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
364 old_to_new_syms[i] = q - new_syms;
365 *q++ = *p;
367 p++;
369 /* save the number of local symbols in section header */
370 s->sh_info = q - new_syms;
372 /* then second pass for non local symbols */
373 p = (ElfW(Sym) *)s->data;
374 for(i = 0; i < nb_syms; i++) {
375 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
376 old_to_new_syms[i] = q - new_syms;
377 *q++ = *p;
379 p++;
382 /* we copy the new symbols to the old */
383 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
384 tcc_free(new_syms);
386 /* now we modify all the relocations */
387 for(i = 1; i < s1->nb_sections; i++) {
388 sr = s1->sections[i];
389 if (sr->sh_type == SHT_RELX && sr->link == s) {
390 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
391 for(rel = (ElfW_Rel *)sr->data;
392 rel < rel_end;
393 rel++) {
394 sym_index = ELFW(R_SYM)(rel->r_info);
395 type = ELFW(R_TYPE)(rel->r_info);
396 sym_index = old_to_new_syms[sym_index];
397 rel->r_info = ELFW(R_INFO)(sym_index, type);
402 tcc_free(old_to_new_syms);
405 /* relocate common symbols in the .bss section */
406 static void relocate_common_syms(void)
408 ElfW(Sym) *sym, *sym_end;
409 unsigned long offset, align;
411 sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
412 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
413 sym < sym_end;
414 sym++) {
415 if (sym->st_shndx == SHN_COMMON) {
416 /* align symbol */
417 align = sym->st_value;
418 offset = bss_section->data_offset;
419 offset = (offset + align - 1) & -align;
420 sym->st_value = offset;
421 sym->st_shndx = bss_section->sh_num;
422 offset += sym->st_size;
423 bss_section->data_offset = offset;
428 /* relocate symbol table, resolve undefined symbols if do_resolve is
429 true and output error if undefined symbol. */
430 static void relocate_syms(TCCState *s1, int do_resolve)
432 ElfW(Sym) *sym, *esym, *sym_end;
433 int sym_bind, sh_num, sym_index;
434 const char *name;
435 unsigned long addr;
437 sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
438 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
439 sym < sym_end;
440 sym++) {
441 sh_num = sym->st_shndx;
442 if (sh_num == SHN_UNDEF) {
443 name = strtab_section->data + sym->st_name;
444 if (do_resolve) {
445 name = symtab_section->link->data + sym->st_name;
446 addr = (unsigned long)resolve_sym(s1, name, ELFW(ST_TYPE)(sym->st_info));
447 if (addr) {
448 sym->st_value = addr;
449 goto found;
451 } else if (s1->dynsym) {
452 /* if dynamic symbol exist, then use it */
453 sym_index = find_elf_sym(s1->dynsym, name);
454 if (sym_index) {
455 esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
456 sym->st_value = esym->st_value;
457 goto found;
460 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
461 it */
462 if (!strcmp(name, "_fp_hw"))
463 goto found;
464 /* only weak symbols are accepted to be undefined. Their
465 value is zero */
466 sym_bind = ELFW(ST_BIND)(sym->st_info);
467 if (sym_bind == STB_WEAK) {
468 sym->st_value = 0;
469 } else {
470 error_noabort("undefined symbol '%s'", name);
472 } else if (sh_num < SHN_LORESERVE) {
473 /* add section base */
474 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
476 found: ;
480 #ifdef TCC_TARGET_X86_64
481 #define JMP_TABLE_ENTRY_SIZE 14
482 static unsigned long add_jmp_table(TCCState *s1, unsigned long val)
484 char *p = (char *)section_ptr_add(text_section, JMP_TABLE_ENTRY_SIZE);
485 /* jmp *0x0(%rip) */
486 p[0] = 0xff;
487 p[1] = 0x25;
488 *(int *)(p + 2) = 0;
489 *(unsigned long *)(p + 6) = val;
490 return (unsigned long)p;
493 static unsigned long add_got_table(TCCState *s1, unsigned long val)
495 unsigned long *p =
496 (unsigned long *)section_ptr_add(text_section, sizeof(void *));
497 *p = val;
498 return (unsigned long)p;
500 #endif
502 /* relocate a given section (CPU dependent) */
503 static void relocate_section(TCCState *s1, Section *s)
505 Section *sr;
506 ElfW_Rel *rel, *rel_end, *qrel;
507 ElfW(Sym) *sym;
508 int type, sym_index;
509 unsigned char *ptr;
510 unsigned long val, addr;
511 int esym_index;
513 sr = s->reloc;
514 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
515 qrel = (ElfW_Rel *)sr->data;
516 for(rel = qrel;
517 rel < rel_end;
518 rel++) {
519 ptr = s->data + rel->r_offset;
521 sym_index = ELFW(R_SYM)(rel->r_info);
522 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
523 val = sym->st_value;
524 #ifdef TCC_TARGET_X86_64
525 /* XXX: not tested */
526 val += rel->r_addend;
527 #endif
528 type = ELFW(R_TYPE)(rel->r_info);
529 addr = s->sh_addr + rel->r_offset;
531 /* CPU specific */
532 switch(type) {
533 #if defined(TCC_TARGET_I386)
534 case R_386_32:
535 if (s1->output_type == TCC_OUTPUT_DLL) {
536 esym_index = s1->symtab_to_dynsym[sym_index];
537 qrel->r_offset = rel->r_offset;
538 if (esym_index) {
539 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
540 qrel++;
541 break;
542 } else {
543 qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
544 qrel++;
547 *(int *)ptr += val;
548 break;
549 case R_386_PC32:
550 if (s1->output_type == TCC_OUTPUT_DLL) {
551 /* DLL relocation */
552 esym_index = s1->symtab_to_dynsym[sym_index];
553 if (esym_index) {
554 qrel->r_offset = rel->r_offset;
555 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
556 qrel++;
557 break;
560 *(int *)ptr += val - addr;
561 break;
562 case R_386_PLT32:
563 *(int *)ptr += val - addr;
564 break;
565 case R_386_GLOB_DAT:
566 case R_386_JMP_SLOT:
567 *(int *)ptr = val;
568 break;
569 case R_386_GOTPC:
570 *(int *)ptr += s1->got->sh_addr - addr;
571 break;
572 case R_386_GOTOFF:
573 *(int *)ptr += val - s1->got->sh_addr;
574 break;
575 case R_386_GOT32:
576 /* we load the got offset */
577 *(int *)ptr += s1->got_offsets[sym_index];
578 break;
579 #elif defined(TCC_TARGET_ARM)
580 case R_ARM_PC24:
581 case R_ARM_CALL:
582 case R_ARM_JUMP24:
583 case R_ARM_PLT32:
585 int x;
586 x = (*(int *)ptr)&0xffffff;
587 (*(int *)ptr) &= 0xff000000;
588 if (x & 0x800000)
589 x -= 0x1000000;
590 x *= 4;
591 x += val - addr;
592 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
593 error("can't relocate value at %x",addr);
594 x >>= 2;
595 x &= 0xffffff;
596 (*(int *)ptr) |= x;
598 break;
599 case R_ARM_PREL31:
601 int x;
602 x = (*(int *)ptr) & 0x7fffffff;
603 (*(int *)ptr) &= 0x80000000;
604 x = (x * 2) / 2;
605 x += val - addr;
606 if((x^(x>>1))&0x40000000)
607 error("can't relocate value at %x",addr);
608 (*(int *)ptr) |= x & 0x7fffffff;
610 case R_ARM_ABS32:
611 *(int *)ptr += val;
612 break;
613 case R_ARM_BASE_PREL:
614 *(int *)ptr += s1->got->sh_addr - addr;
615 break;
616 case R_ARM_GOTOFF32:
617 *(int *)ptr += val - s1->got->sh_addr;
618 break;
619 case R_ARM_GOT_BREL:
620 /* we load the got offset */
621 *(int *)ptr += s1->got_offsets[sym_index];
622 break;
623 case R_ARM_COPY:
624 break;
625 default:
626 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
627 type,addr,(unsigned int )ptr,val);
628 break;
629 #elif defined(TCC_TARGET_C67)
630 case R_C60_32:
631 *(int *)ptr += val;
632 break;
633 case R_C60LO16:
635 uint32_t orig;
637 /* put the low 16 bits of the absolute address */
638 // add to what is already there
640 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
641 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
643 //patch both at once - assumes always in pairs Low - High
645 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
646 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
648 break;
649 case R_C60HI16:
650 break;
651 default:
652 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
653 type,addr,(unsigned int )ptr,val);
654 break;
655 #elif defined(TCC_TARGET_X86_64)
656 case R_X86_64_64:
657 if (s1->output_type == TCC_OUTPUT_DLL) {
658 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
659 qrel->r_addend = *(long long *)ptr + val;
660 qrel++;
662 *(long long *)ptr += val;
663 break;
664 case R_X86_64_32:
665 case R_X86_64_32S:
666 if (s1->output_type == TCC_OUTPUT_DLL) {
667 /* XXX: this logic may depend on TCC's codegen
668 now TCC uses R_X86_64_32 even for a 64bit pointer */
669 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
670 qrel->r_addend = *(int *)ptr + val;
671 qrel++;
673 *(int *)ptr += val;
674 break;
675 case R_X86_64_PC32: {
676 if (s1->output_type == TCC_OUTPUT_DLL) {
677 /* DLL relocation */
678 esym_index = s1->symtab_to_dynsym[sym_index];
679 if (esym_index) {
680 qrel->r_offset = rel->r_offset;
681 qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
682 qrel->r_addend = *(int *)ptr;
683 qrel++;
684 break;
687 long diff = val - addr;
688 if (diff < -2147483648 || diff > 2147483647) {
689 /* XXX: naive support for over 32bit jump */
690 if (s1->output_type == TCC_OUTPUT_MEMORY) {
691 val = add_jmp_table(s1, val);
692 diff = val - addr;
694 if (diff <= -2147483647 || diff > 2147483647) {
695 #if 0
696 /* output memory map to debug easily */
697 FILE* fp;
698 char buf[4096];
699 int size;
700 Dl_info di;
701 printf("%ld - %ld = %ld\n", val, addr, diff);
702 dladdr((void *)addr, &di);
703 printf("addr = %lx = %lx+%lx(%s) ptr=%p\n",
704 addr, s->sh_addr, rel->r_offset, di.dli_sname,
705 ptr);
706 fp = fopen("/proc/self/maps", "r");
707 size = fread(buf, 1, 4095, fp);
708 buf[size] = '\0';
709 printf("%s", buf);
710 #endif
711 error("internal error: relocation failed");
714 *(int *)ptr += diff;
716 break;
717 case R_X86_64_PLT32:
718 *(int *)ptr += val - addr;
719 break;
720 case R_X86_64_GLOB_DAT:
721 case R_X86_64_JUMP_SLOT:
722 *(int *)ptr = val;
723 break;
724 case R_X86_64_GOTPCREL:
725 if (s1->output_type == TCC_OUTPUT_MEMORY) {
726 val = add_got_table(s1, val - rel->r_addend) + rel->r_addend;
727 *(int *)ptr += val - addr;
728 break;
730 *(int *)ptr += (s1->got->sh_addr - addr +
731 s1->got_offsets[sym_index] - 4);
732 break;
733 case R_X86_64_GOTTPOFF:
734 *(int *)ptr += val - s1->got->sh_addr;
735 break;
736 case R_X86_64_GOT32:
737 /* we load the got offset */
738 *(int *)ptr += s1->got_offsets[sym_index];
739 break;
740 #else
741 #error unsupported processor
742 #endif
745 /* if the relocation is allocated, we change its symbol table */
746 if (sr->sh_flags & SHF_ALLOC)
747 sr->link = s1->dynsym;
750 /* relocate relocation table in 'sr' */
751 static void relocate_rel(TCCState *s1, Section *sr)
753 Section *s;
754 ElfW_Rel *rel, *rel_end;
756 s = s1->sections[sr->sh_info];
757 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
758 for(rel = (ElfW_Rel *)sr->data;
759 rel < rel_end;
760 rel++) {
761 rel->r_offset += s->sh_addr;
765 /* count the number of dynamic relocations so that we can reserve
766 their space */
767 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
769 ElfW_Rel *rel, *rel_end;
770 int sym_index, esym_index, type, count;
772 count = 0;
773 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
774 for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
775 sym_index = ELFW(R_SYM)(rel->r_info);
776 type = ELFW(R_TYPE)(rel->r_info);
777 switch(type) {
778 #if defined(TCC_TARGET_I386)
779 case R_386_32:
780 #elif defined(TCC_TARGET_X86_64)
781 case R_X86_64_32:
782 case R_X86_64_32S:
783 case R_X86_64_64:
784 #endif
785 count++;
786 break;
787 #if defined(TCC_TARGET_I386)
788 case R_386_PC32:
789 #elif defined(TCC_TARGET_X86_64)
790 case R_X86_64_PC32:
791 #endif
792 esym_index = s1->symtab_to_dynsym[sym_index];
793 if (esym_index)
794 count++;
795 break;
796 default:
797 break;
800 if (count) {
801 /* allocate the section */
802 sr->sh_flags |= SHF_ALLOC;
803 sr->sh_size = count * sizeof(ElfW_Rel);
805 return count;
808 static void put_got_offset(TCCState *s1, int index, unsigned long val)
810 int n;
811 unsigned long *tab;
813 if (index >= s1->nb_got_offsets) {
814 /* find immediately bigger power of 2 and reallocate array */
815 n = 1;
816 while (index >= n)
817 n *= 2;
818 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
819 if (!tab)
820 error("memory full");
821 s1->got_offsets = tab;
822 memset(s1->got_offsets + s1->nb_got_offsets, 0,
823 (n - s1->nb_got_offsets) * sizeof(unsigned long));
824 s1->nb_got_offsets = n;
826 s1->got_offsets[index] = val;
829 /* XXX: suppress that */
830 static void put32(unsigned char *p, uint32_t val)
832 p[0] = val;
833 p[1] = val >> 8;
834 p[2] = val >> 16;
835 p[3] = val >> 24;
838 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
839 defined(TCC_TARGET_X86_64)
840 static uint32_t get32(unsigned char *p)
842 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
844 #endif
846 static void build_got(TCCState *s1)
848 unsigned char *ptr;
850 /* if no got, then create it */
851 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
852 s1->got->sh_entsize = 4;
853 add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
854 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
855 ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
856 #if PTR_SIZE == 4
857 /* keep space for _DYNAMIC pointer, if present */
858 put32(ptr, 0);
859 /* two dummy got entries */
860 put32(ptr + 4, 0);
861 put32(ptr + 8, 0);
862 #else
863 /* keep space for _DYNAMIC pointer, if present */
864 put32(ptr, 0);
865 put32(ptr + 4, 0);
866 /* two dummy got entries */
867 put32(ptr + 8, 0);
868 put32(ptr + 12, 0);
869 put32(ptr + 16, 0);
870 put32(ptr + 20, 0);
871 #endif
874 /* put a got entry corresponding to a symbol in symtab_section. 'size'
875 and 'info' can be modifed if more precise info comes from the DLL */
876 static void put_got_entry(TCCState *s1,
877 int reloc_type, unsigned long size, int info,
878 int sym_index)
880 int index;
881 const char *name;
882 ElfW(Sym) *sym;
883 unsigned long offset;
884 int *ptr;
886 if (!s1->got)
887 build_got(s1);
889 /* if a got entry already exists for that symbol, no need to add one */
890 if (sym_index < s1->nb_got_offsets &&
891 s1->got_offsets[sym_index] != 0)
892 return;
894 put_got_offset(s1, sym_index, s1->got->data_offset);
896 if (s1->dynsym) {
897 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
898 name = symtab_section->link->data + sym->st_name;
899 offset = sym->st_value;
900 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
901 if (reloc_type ==
902 #ifdef TCC_TARGET_X86_64
903 R_X86_64_JUMP_SLOT
904 #else
905 R_386_JMP_SLOT
906 #endif
908 Section *plt;
909 uint8_t *p;
910 int modrm;
912 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
913 modrm = 0x25;
914 #else
915 /* if we build a DLL, we add a %ebx offset */
916 if (s1->output_type == TCC_OUTPUT_DLL)
917 modrm = 0xa3;
918 else
919 modrm = 0x25;
920 #endif
922 /* add a PLT entry */
923 plt = s1->plt;
924 if (plt->data_offset == 0) {
925 /* first plt entry */
926 p = section_ptr_add(plt, 16);
927 p[0] = 0xff; /* pushl got + PTR_SIZE */
928 p[1] = modrm + 0x10;
929 put32(p + 2, PTR_SIZE);
930 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
931 p[7] = modrm;
932 put32(p + 8, PTR_SIZE * 2);
935 p = section_ptr_add(plt, 16);
936 p[0] = 0xff; /* jmp *(got + x) */
937 p[1] = modrm;
938 put32(p + 2, s1->got->data_offset);
939 p[6] = 0x68; /* push $xxx */
940 put32(p + 7, (plt->data_offset - 32) >> 1);
941 p[11] = 0xe9; /* jmp plt_start */
942 put32(p + 12, -(plt->data_offset));
944 /* the symbol is modified so that it will be relocated to
945 the PLT */
946 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
947 if (s1->output_type == TCC_OUTPUT_EXE)
948 #endif
949 offset = plt->data_offset - 16;
951 #elif defined(TCC_TARGET_ARM)
952 if (reloc_type == R_ARM_JUMP_SLOT) {
953 Section *plt;
954 uint8_t *p;
956 /* if we build a DLL, we add a %ebx offset */
957 if (s1->output_type == TCC_OUTPUT_DLL)
958 error("DLLs unimplemented!");
960 /* add a PLT entry */
961 plt = s1->plt;
962 if (plt->data_offset == 0) {
963 /* first plt entry */
964 p = section_ptr_add(plt, 16);
965 put32(p , 0xe52de004);
966 put32(p + 4, 0xe59fe010);
967 put32(p + 8, 0xe08fe00e);
968 put32(p + 12, 0xe5bef008);
971 p = section_ptr_add(plt, 16);
972 put32(p , 0xe59fc004);
973 put32(p+4, 0xe08fc00c);
974 put32(p+8, 0xe59cf000);
975 put32(p+12, s1->got->data_offset);
977 /* the symbol is modified so that it will be relocated to
978 the PLT */
979 if (s1->output_type == TCC_OUTPUT_EXE)
980 offset = plt->data_offset - 16;
982 #elif defined(TCC_TARGET_C67)
983 error("C67 got not implemented");
984 #else
985 #error unsupported CPU
986 #endif
987 index = put_elf_sym(s1->dynsym, offset,
988 size, info, 0, sym->st_shndx, name);
989 /* put a got entry */
990 put_elf_reloc(s1->dynsym, s1->got,
991 s1->got->data_offset,
992 reloc_type, index);
994 ptr = section_ptr_add(s1->got, PTR_SIZE);
995 *ptr = 0;
998 /* build GOT and PLT entries */
999 static void build_got_entries(TCCState *s1)
1001 Section *s, *symtab;
1002 ElfW_Rel *rel, *rel_end;
1003 ElfW(Sym) *sym;
1004 int i, type, reloc_type, sym_index;
1006 for(i = 1; i < s1->nb_sections; i++) {
1007 s = s1->sections[i];
1008 if (s->sh_type != SHT_RELX)
1009 continue;
1010 /* no need to handle got relocations */
1011 if (s->link != symtab_section)
1012 continue;
1013 symtab = s->link;
1014 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
1015 for(rel = (ElfW_Rel *)s->data;
1016 rel < rel_end;
1017 rel++) {
1018 type = ELFW(R_TYPE)(rel->r_info);
1019 switch(type) {
1020 #if defined(TCC_TARGET_I386)
1021 case R_386_GOT32:
1022 case R_386_GOTOFF:
1023 case R_386_GOTPC:
1024 case R_386_PLT32:
1025 if (!s1->got)
1026 build_got(s1);
1027 if (type == R_386_GOT32 || type == R_386_PLT32) {
1028 sym_index = ELFW(R_SYM)(rel->r_info);
1029 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1030 /* look at the symbol got offset. If none, then add one */
1031 if (type == R_386_GOT32)
1032 reloc_type = R_386_GLOB_DAT;
1033 else
1034 reloc_type = R_386_JMP_SLOT;
1035 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1036 sym_index);
1038 break;
1039 #elif defined(TCC_TARGET_ARM)
1040 case R_ARM_GOT_BREL:
1041 case R_ARM_GOTOFF32:
1042 case R_ARM_BASE_PREL:
1043 case R_ARM_PLT32:
1044 if (!s1->got)
1045 build_got(s1);
1046 if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) {
1047 sym_index = ELFW(R_SYM)(rel->r_info);
1048 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1049 /* look at the symbol got offset. If none, then add one */
1050 if (type == R_ARM_GOT_BREL)
1051 reloc_type = R_ARM_GLOB_DAT;
1052 else
1053 reloc_type = R_ARM_JUMP_SLOT;
1054 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1055 sym_index);
1057 break;
1058 #elif defined(TCC_TARGET_C67)
1059 case R_C60_GOT32:
1060 case R_C60_GOTOFF:
1061 case R_C60_GOTPC:
1062 case R_C60_PLT32:
1063 if (!s1->got)
1064 build_got(s1);
1065 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
1066 sym_index = ELFW(R_SYM)(rel->r_info);
1067 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1068 /* look at the symbol got offset. If none, then add one */
1069 if (type == R_C60_GOT32)
1070 reloc_type = R_C60_GLOB_DAT;
1071 else
1072 reloc_type = R_C60_JMP_SLOT;
1073 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1074 sym_index);
1076 break;
1077 #elif defined(TCC_TARGET_X86_64)
1078 case R_X86_64_GOT32:
1079 case R_X86_64_GOTTPOFF:
1080 case R_X86_64_GOTPCREL:
1081 case R_X86_64_PLT32:
1082 if (!s1->got)
1083 build_got(s1);
1084 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
1085 type == R_X86_64_PLT32) {
1086 sym_index = ELFW(R_SYM)(rel->r_info);
1087 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1088 /* look at the symbol got offset. If none, then add one */
1089 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL)
1090 reloc_type = R_X86_64_GLOB_DAT;
1091 else
1092 reloc_type = R_X86_64_JUMP_SLOT;
1093 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1094 sym_index);
1096 break;
1097 #else
1098 #error unsupported CPU
1099 #endif
1100 default:
1101 break;
1107 static Section *new_symtab(TCCState *s1,
1108 const char *symtab_name, int sh_type, int sh_flags,
1109 const char *strtab_name,
1110 const char *hash_name, int hash_sh_flags)
1112 Section *symtab, *strtab, *hash;
1113 int *ptr, nb_buckets;
1115 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1116 symtab->sh_entsize = sizeof(ElfW(Sym));
1117 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1118 put_elf_str(strtab, "");
1119 symtab->link = strtab;
1120 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1122 nb_buckets = 1;
1124 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1125 hash->sh_entsize = sizeof(int);
1126 symtab->hash = hash;
1127 hash->link = symtab;
1129 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1130 ptr[0] = nb_buckets;
1131 ptr[1] = 1;
1132 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1133 return symtab;
1136 /* put dynamic tag */
1137 static void put_dt(Section *dynamic, int dt, unsigned long val)
1139 ElfW(Dyn) *dyn;
1140 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1141 dyn->d_tag = dt;
1142 dyn->d_un.d_val = val;
1145 static void add_init_array_defines(TCCState *s1, const char *section_name)
1147 Section *s;
1148 long end_offset;
1149 char sym_start[1024];
1150 char sym_end[1024];
1152 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1153 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1155 s = find_section(s1, section_name);
1156 if (!s) {
1157 end_offset = 0;
1158 s = data_section;
1159 } else {
1160 end_offset = s->data_offset;
1163 add_elf_sym(symtab_section,
1164 0, 0,
1165 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1166 s->sh_num, sym_start);
1167 add_elf_sym(symtab_section,
1168 end_offset, 0,
1169 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1170 s->sh_num, sym_end);
1173 /* add tcc runtime libraries */
1174 static void tcc_add_runtime(TCCState *s1)
1176 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1177 char buf[1024];
1178 #endif
1180 #ifdef CONFIG_TCC_BCHECK
1181 if (do_bounds_check) {
1182 unsigned long *ptr;
1183 Section *init_section;
1184 unsigned char *pinit;
1185 int sym_index;
1187 /* XXX: add an object file to do that */
1188 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
1189 *ptr = 0;
1190 add_elf_sym(symtab_section, 0, 0,
1191 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1192 bounds_section->sh_num, "__bounds_start");
1193 /* add bound check code */
1194 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
1195 tcc_add_file(s1, buf);
1196 #ifdef TCC_TARGET_I386
1197 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1198 /* add 'call __bound_init()' in .init section */
1199 init_section = find_section(s1, ".init");
1200 pinit = section_ptr_add(init_section, 5);
1201 pinit[0] = 0xe8;
1202 put32(pinit + 1, -4);
1203 sym_index = find_elf_sym(symtab_section, "__bound_init");
1204 put_elf_reloc(symtab_section, init_section,
1205 init_section->data_offset - 4, R_386_PC32, sym_index);
1207 #endif
1209 #endif
1210 /* add libc */
1211 if (!s1->nostdlib) {
1212 tcc_add_library(s1, "c");
1214 #ifdef CONFIG_USE_LIBGCC
1215 tcc_add_file(s1, CONFIG_SYSROOT "/lib/libgcc_s.so.1");
1216 #else
1217 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
1218 tcc_add_file(s1, buf);
1219 #endif
1221 /* add crt end if not memory output */
1222 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
1223 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1227 /* add various standard linker symbols (must be done after the
1228 sections are filled (for example after allocating common
1229 symbols)) */
1230 static void tcc_add_linker_symbols(TCCState *s1)
1232 char buf[1024];
1233 int i;
1234 Section *s;
1236 add_elf_sym(symtab_section,
1237 text_section->data_offset, 0,
1238 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1239 text_section->sh_num, "_etext");
1240 add_elf_sym(symtab_section,
1241 data_section->data_offset, 0,
1242 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1243 data_section->sh_num, "_edata");
1244 add_elf_sym(symtab_section,
1245 bss_section->data_offset, 0,
1246 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1247 bss_section->sh_num, "_end");
1248 /* horrible new standard ldscript defines */
1249 add_init_array_defines(s1, ".preinit_array");
1250 add_init_array_defines(s1, ".init_array");
1251 add_init_array_defines(s1, ".fini_array");
1253 /* add start and stop symbols for sections whose name can be
1254 expressed in C */
1255 for(i = 1; i < s1->nb_sections; i++) {
1256 s = s1->sections[i];
1257 if (s->sh_type == SHT_PROGBITS &&
1258 (s->sh_flags & SHF_ALLOC)) {
1259 const char *p;
1260 int ch;
1262 /* check if section name can be expressed in C */
1263 p = s->name;
1264 for(;;) {
1265 ch = *p;
1266 if (!ch)
1267 break;
1268 if (!isid(ch) && !isnum(ch))
1269 goto next_sec;
1270 p++;
1272 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1273 add_elf_sym(symtab_section,
1274 0, 0,
1275 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1276 s->sh_num, buf);
1277 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1278 add_elf_sym(symtab_section,
1279 s->data_offset, 0,
1280 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1281 s->sh_num, buf);
1283 next_sec: ;
1287 /* name of ELF interpreter */
1288 #ifdef __FreeBSD__
1289 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1290 #else
1291 #ifdef TCC_ARM_EABI
1292 static char elf_interp[] = "/lib/ld-linux.so.3";
1293 #elif defined(TCC_TARGET_X86_64)
1294 static char elf_interp[] = "/lib/ld-linux-x86-64.so.2";
1295 #else
1296 static char elf_interp[] = "/lib/ld-linux.so.2";
1297 #endif
1298 #endif
1300 static void tcc_output_binary(TCCState *s1, FILE *f,
1301 const int *section_order)
1303 Section *s;
1304 int i, offset, size;
1306 offset = 0;
1307 for(i=1;i<s1->nb_sections;i++) {
1308 s = s1->sections[section_order[i]];
1309 if (s->sh_type != SHT_NOBITS &&
1310 (s->sh_flags & SHF_ALLOC)) {
1311 while (offset < s->sh_offset) {
1312 fputc(0, f);
1313 offset++;
1315 size = s->sh_size;
1316 fwrite(s->data, 1, size, f);
1317 offset += size;
1322 /* output an ELF file */
1323 /* XXX: suppress unneeded sections */
1324 int elf_output_file(TCCState *s1, const char *filename)
1326 ElfW(Ehdr) ehdr;
1327 FILE *f;
1328 int fd, mode, ret;
1329 int *section_order;
1330 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1331 unsigned long addr;
1332 Section *strsec, *s;
1333 ElfW(Shdr) shdr, *sh;
1334 ElfW(Phdr) *phdr, *ph;
1335 Section *interp, *dynamic, *dynstr;
1336 unsigned long saved_dynamic_data_offset;
1337 ElfW(Sym) *sym;
1338 int type, file_type;
1339 unsigned long rel_addr, rel_size;
1341 file_type = s1->output_type;
1342 s1->nb_errors = 0;
1344 if (file_type != TCC_OUTPUT_OBJ) {
1345 tcc_add_runtime(s1);
1348 phdr = NULL;
1349 section_order = NULL;
1350 interp = NULL;
1351 dynamic = NULL;
1352 dynstr = NULL; /* avoid warning */
1353 saved_dynamic_data_offset = 0; /* avoid warning */
1355 if (file_type != TCC_OUTPUT_OBJ) {
1356 relocate_common_syms();
1358 tcc_add_linker_symbols(s1);
1360 if (!s1->static_link) {
1361 const char *name;
1362 int sym_index, index;
1363 ElfW(Sym) *esym, *sym_end;
1365 if (file_type == TCC_OUTPUT_EXE) {
1366 char *ptr;
1367 /* add interpreter section only if executable */
1368 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1369 interp->sh_addralign = 1;
1370 ptr = section_ptr_add(interp, sizeof(elf_interp));
1371 strcpy(ptr, elf_interp);
1374 /* add dynamic symbol table */
1375 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1376 ".dynstr",
1377 ".hash", SHF_ALLOC);
1378 dynstr = s1->dynsym->link;
1380 /* add dynamic section */
1381 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1382 SHF_ALLOC | SHF_WRITE);
1383 dynamic->link = dynstr;
1384 dynamic->sh_entsize = sizeof(ElfW(Dyn));
1386 /* add PLT */
1387 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1388 SHF_ALLOC | SHF_EXECINSTR);
1389 s1->plt->sh_entsize = 4;
1391 build_got(s1);
1393 /* scan for undefined symbols and see if they are in the
1394 dynamic symbols. If a symbol STT_FUNC is found, then we
1395 add it in the PLT. If a symbol STT_OBJECT is found, we
1396 add it in the .bss section with a suitable relocation */
1397 sym_end = (ElfW(Sym) *)(symtab_section->data +
1398 symtab_section->data_offset);
1399 if (file_type == TCC_OUTPUT_EXE) {
1400 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1401 sym < sym_end;
1402 sym++) {
1403 if (sym->st_shndx == SHN_UNDEF) {
1404 name = symtab_section->link->data + sym->st_name;
1405 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1406 if (sym_index) {
1407 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1408 type = ELFW(ST_TYPE)(esym->st_info);
1409 if (type == STT_FUNC) {
1410 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1411 esym->st_info,
1412 sym - (ElfW(Sym) *)symtab_section->data);
1413 } else if (type == STT_OBJECT) {
1414 unsigned long offset;
1415 offset = bss_section->data_offset;
1416 /* XXX: which alignment ? */
1417 offset = (offset + 16 - 1) & -16;
1418 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1419 esym->st_info, 0,
1420 bss_section->sh_num, name);
1421 put_elf_reloc(s1->dynsym, bss_section,
1422 offset, R_COPY, index);
1423 offset += esym->st_size;
1424 bss_section->data_offset = offset;
1426 } else {
1427 /* STB_WEAK undefined symbols are accepted */
1428 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1429 it */
1430 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1431 !strcmp(name, "_fp_hw")) {
1432 } else {
1433 error_noabort("undefined symbol '%s'", name);
1436 } else if (s1->rdynamic &&
1437 ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1438 /* if -rdynamic option, then export all non
1439 local symbols */
1440 name = symtab_section->link->data + sym->st_name;
1441 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1442 sym->st_info, 0,
1443 sym->st_shndx, name);
1447 if (s1->nb_errors)
1448 goto fail;
1450 /* now look at unresolved dynamic symbols and export
1451 corresponding symbol */
1452 sym_end = (ElfW(Sym) *)(s1->dynsymtab_section->data +
1453 s1->dynsymtab_section->data_offset);
1454 for(esym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1;
1455 esym < sym_end;
1456 esym++) {
1457 if (esym->st_shndx == SHN_UNDEF) {
1458 name = s1->dynsymtab_section->link->data + esym->st_name;
1459 sym_index = find_elf_sym(symtab_section, name);
1460 if (sym_index) {
1461 /* XXX: avoid adding a symbol if already
1462 present because of -rdynamic ? */
1463 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1464 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1465 sym->st_info, 0,
1466 sym->st_shndx, name);
1467 } else {
1468 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1469 /* weak symbols can stay undefined */
1470 } else {
1471 warning("undefined dynamic symbol '%s'", name);
1476 } else {
1477 int nb_syms;
1478 /* shared library case : we simply export all the global symbols */
1479 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1480 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1481 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1482 sym < sym_end;
1483 sym++) {
1484 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1485 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1486 if (ELFW(ST_TYPE)(sym->st_info) == STT_FUNC &&
1487 sym->st_shndx == SHN_UNDEF) {
1488 put_got_entry(s1, R_JMP_SLOT, sym->st_size,
1489 sym->st_info,
1490 sym - (ElfW(Sym) *)symtab_section->data);
1492 else if (ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT) {
1493 put_got_entry(s1, R_X86_64_GLOB_DAT, sym->st_size,
1494 sym->st_info,
1495 sym - (ElfW(Sym) *)symtab_section->data);
1497 else
1498 #endif
1500 name = symtab_section->link->data + sym->st_name;
1501 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1502 sym->st_info, 0,
1503 sym->st_shndx, name);
1504 s1->symtab_to_dynsym[sym -
1505 (ElfW(Sym) *)symtab_section->data] =
1506 index;
1512 build_got_entries(s1);
1514 /* add a list of needed dlls */
1515 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1516 DLLReference *dllref = s1->loaded_dlls[i];
1517 if (dllref->level == 0)
1518 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1520 /* XXX: currently, since we do not handle PIC code, we
1521 must relocate the readonly segments */
1522 if (file_type == TCC_OUTPUT_DLL) {
1523 if (s1->soname)
1524 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
1525 put_dt(dynamic, DT_TEXTREL, 0);
1528 /* add necessary space for other entries */
1529 saved_dynamic_data_offset = dynamic->data_offset;
1530 dynamic->data_offset += sizeof(ElfW(Dyn)) * 9;
1531 } else {
1532 /* still need to build got entries in case of static link */
1533 build_got_entries(s1);
1537 memset(&ehdr, 0, sizeof(ehdr));
1539 /* we add a section for symbols */
1540 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1541 put_elf_str(strsec, "");
1543 /* compute number of sections */
1544 shnum = s1->nb_sections;
1546 /* this array is used to reorder sections in the output file */
1547 section_order = tcc_malloc(sizeof(int) * shnum);
1548 section_order[0] = 0;
1549 sh_order_index = 1;
1551 /* compute number of program headers */
1552 switch(file_type) {
1553 default:
1554 case TCC_OUTPUT_OBJ:
1555 phnum = 0;
1556 break;
1557 case TCC_OUTPUT_EXE:
1558 if (!s1->static_link)
1559 phnum = 4;
1560 else
1561 phnum = 2;
1562 break;
1563 case TCC_OUTPUT_DLL:
1564 phnum = 3;
1565 break;
1568 /* allocate strings for section names and decide if an unallocated
1569 section should be output */
1570 /* NOTE: the strsec section comes last, so its size is also
1571 correct ! */
1572 for(i = 1; i < s1->nb_sections; i++) {
1573 s = s1->sections[i];
1574 s->sh_name = put_elf_str(strsec, s->name);
1575 #if 0 //gr
1576 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1577 s->sh_flags,
1578 s->sh_type,
1579 s->sh_info,
1580 s->name,
1581 s->reloc ? s->reloc->name : "n"
1583 #endif
1584 /* when generating a DLL, we include relocations but we may
1585 patch them */
1586 if (file_type == TCC_OUTPUT_DLL &&
1587 s->sh_type == SHT_RELX &&
1588 !(s->sh_flags & SHF_ALLOC)) {
1589 /* //gr: avoid bogus relocs for empty (debug) sections */
1590 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1591 prepare_dynamic_rel(s1, s);
1592 else if (do_debug)
1593 s->sh_size = s->data_offset;
1594 } else if (do_debug ||
1595 file_type == TCC_OUTPUT_OBJ ||
1596 (s->sh_flags & SHF_ALLOC) ||
1597 i == (s1->nb_sections - 1)) {
1598 /* we output all sections if debug or object file */
1599 s->sh_size = s->data_offset;
1603 /* allocate program segment headers */
1604 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
1606 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1607 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1608 } else {
1609 file_offset = 0;
1611 if (phnum > 0) {
1612 /* compute section to program header mapping */
1613 if (s1->has_text_addr) {
1614 int a_offset, p_offset;
1615 addr = s1->text_addr;
1616 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1617 ELF_PAGE_SIZE */
1618 a_offset = addr & (ELF_PAGE_SIZE - 1);
1619 p_offset = file_offset & (ELF_PAGE_SIZE - 1);
1620 if (a_offset < p_offset)
1621 a_offset += ELF_PAGE_SIZE;
1622 file_offset += (a_offset - p_offset);
1623 } else {
1624 if (file_type == TCC_OUTPUT_DLL)
1625 addr = 0;
1626 else
1627 addr = ELF_START_ADDR;
1628 /* compute address after headers */
1629 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1632 /* dynamic relocation table information, for .dynamic section */
1633 rel_size = 0;
1634 rel_addr = 0;
1636 /* leave one program header for the program interpreter */
1637 ph = &phdr[0];
1638 if (interp)
1639 ph++;
1641 for(j = 0; j < 2; j++) {
1642 ph->p_type = PT_LOAD;
1643 if (j == 0)
1644 ph->p_flags = PF_R | PF_X;
1645 else
1646 ph->p_flags = PF_R | PF_W;
1647 ph->p_align = ELF_PAGE_SIZE;
1649 /* we do the following ordering: interp, symbol tables,
1650 relocations, progbits, nobits */
1651 /* XXX: do faster and simpler sorting */
1652 for(k = 0; k < 5; k++) {
1653 for(i = 1; i < s1->nb_sections; i++) {
1654 s = s1->sections[i];
1655 /* compute if section should be included */
1656 if (j == 0) {
1657 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1658 SHF_ALLOC)
1659 continue;
1660 } else {
1661 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1662 (SHF_ALLOC | SHF_WRITE))
1663 continue;
1665 if (s == interp) {
1666 if (k != 0)
1667 continue;
1668 } else if (s->sh_type == SHT_DYNSYM ||
1669 s->sh_type == SHT_STRTAB ||
1670 s->sh_type == SHT_HASH) {
1671 if (k != 1)
1672 continue;
1673 } else if (s->sh_type == SHT_RELX) {
1674 if (k != 2)
1675 continue;
1676 } else if (s->sh_type == SHT_NOBITS) {
1677 if (k != 4)
1678 continue;
1679 } else {
1680 if (k != 3)
1681 continue;
1683 section_order[sh_order_index++] = i;
1685 /* section matches: we align it and add its size */
1686 tmp = addr;
1687 addr = (addr + s->sh_addralign - 1) &
1688 ~(s->sh_addralign - 1);
1689 file_offset += addr - tmp;
1690 s->sh_offset = file_offset;
1691 s->sh_addr = addr;
1693 /* update program header infos */
1694 if (ph->p_offset == 0) {
1695 ph->p_offset = file_offset;
1696 ph->p_vaddr = addr;
1697 ph->p_paddr = ph->p_vaddr;
1699 /* update dynamic relocation infos */
1700 if (s->sh_type == SHT_RELX) {
1701 if (rel_size == 0)
1702 rel_addr = addr;
1703 rel_size += s->sh_size;
1705 addr += s->sh_size;
1706 if (s->sh_type != SHT_NOBITS)
1707 file_offset += s->sh_size;
1710 ph->p_filesz = file_offset - ph->p_offset;
1711 ph->p_memsz = addr - ph->p_vaddr;
1712 ph++;
1713 if (j == 0) {
1714 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1715 /* if in the middle of a page, we duplicate the page in
1716 memory so that one copy is RX and the other is RW */
1717 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1718 addr += ELF_PAGE_SIZE;
1719 } else {
1720 addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
1721 file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
1722 ~(ELF_PAGE_SIZE - 1);
1727 /* if interpreter, then add corresponing program header */
1728 if (interp) {
1729 ph = &phdr[0];
1731 ph->p_type = PT_INTERP;
1732 ph->p_offset = interp->sh_offset;
1733 ph->p_vaddr = interp->sh_addr;
1734 ph->p_paddr = ph->p_vaddr;
1735 ph->p_filesz = interp->sh_size;
1736 ph->p_memsz = interp->sh_size;
1737 ph->p_flags = PF_R;
1738 ph->p_align = interp->sh_addralign;
1741 /* if dynamic section, then add corresponing program header */
1742 if (dynamic) {
1743 ElfW(Sym) *sym_end;
1745 ph = &phdr[phnum - 1];
1747 ph->p_type = PT_DYNAMIC;
1748 ph->p_offset = dynamic->sh_offset;
1749 ph->p_vaddr = dynamic->sh_addr;
1750 ph->p_paddr = ph->p_vaddr;
1751 ph->p_filesz = dynamic->sh_size;
1752 ph->p_memsz = dynamic->sh_size;
1753 ph->p_flags = PF_R | PF_W;
1754 ph->p_align = dynamic->sh_addralign;
1756 /* put GOT dynamic section address */
1757 put32(s1->got->data, dynamic->sh_addr);
1759 /* relocate the PLT */
1760 if (file_type == TCC_OUTPUT_EXE
1761 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1762 || file_type == TCC_OUTPUT_DLL
1763 #endif
1765 uint8_t *p, *p_end;
1767 p = s1->plt->data;
1768 p_end = p + s1->plt->data_offset;
1769 if (p < p_end) {
1770 #if defined(TCC_TARGET_I386)
1771 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1772 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1773 p += 16;
1774 while (p < p_end) {
1775 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1776 p += 16;
1778 #elif defined(TCC_TARGET_X86_64)
1779 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
1780 put32(p + 2, get32(p + 2) + x);
1781 put32(p + 8, get32(p + 8) + x - 6);
1782 p += 16;
1783 while (p < p_end) {
1784 put32(p + 2, get32(p + 2) + x + s1->plt->data - p);
1785 p += 16;
1787 #elif defined(TCC_TARGET_ARM)
1788 int x;
1789 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1790 p +=16;
1791 while (p < p_end) {
1792 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1793 p += 16;
1795 #elif defined(TCC_TARGET_C67)
1796 /* XXX: TODO */
1797 #else
1798 #error unsupported CPU
1799 #endif
1803 /* relocate symbols in .dynsym */
1804 sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset);
1805 for(sym = (ElfW(Sym) *)s1->dynsym->data + 1;
1806 sym < sym_end;
1807 sym++) {
1808 if (sym->st_shndx == SHN_UNDEF) {
1809 /* relocate to the PLT if the symbol corresponds
1810 to a PLT entry */
1811 if (sym->st_value)
1812 sym->st_value += s1->plt->sh_addr;
1813 } else if (sym->st_shndx < SHN_LORESERVE) {
1814 /* do symbol relocation */
1815 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1819 /* put dynamic section entries */
1820 dynamic->data_offset = saved_dynamic_data_offset;
1821 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1822 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1823 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1824 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1825 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1826 #ifdef TCC_TARGET_X86_64
1827 put_dt(dynamic, DT_RELA, rel_addr);
1828 put_dt(dynamic, DT_RELASZ, rel_size);
1829 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
1830 #else
1831 put_dt(dynamic, DT_REL, rel_addr);
1832 put_dt(dynamic, DT_RELSZ, rel_size);
1833 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1834 #endif
1835 if (do_debug)
1836 put_dt(dynamic, DT_DEBUG, 0);
1837 put_dt(dynamic, DT_NULL, 0);
1840 ehdr.e_phentsize = sizeof(ElfW(Phdr));
1841 ehdr.e_phnum = phnum;
1842 ehdr.e_phoff = sizeof(ElfW(Ehdr));
1845 /* all other sections come after */
1846 for(i = 1; i < s1->nb_sections; i++) {
1847 s = s1->sections[i];
1848 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1849 continue;
1850 section_order[sh_order_index++] = i;
1852 file_offset = (file_offset + s->sh_addralign - 1) &
1853 ~(s->sh_addralign - 1);
1854 s->sh_offset = file_offset;
1855 if (s->sh_type != SHT_NOBITS)
1856 file_offset += s->sh_size;
1859 /* if building executable or DLL, then relocate each section
1860 except the GOT which is already relocated */
1861 if (file_type != TCC_OUTPUT_OBJ) {
1862 relocate_syms(s1, 0);
1864 if (s1->nb_errors != 0) {
1865 fail:
1866 ret = -1;
1867 goto the_end;
1870 /* relocate sections */
1871 /* XXX: ignore sections with allocated relocations ? */
1872 for(i = 1; i < s1->nb_sections; i++) {
1873 s = s1->sections[i];
1874 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
1875 relocate_section(s1, s);
1878 /* relocate relocation entries if the relocation tables are
1879 allocated in the executable */
1880 for(i = 1; i < s1->nb_sections; i++) {
1881 s = s1->sections[i];
1882 if ((s->sh_flags & SHF_ALLOC) &&
1883 s->sh_type == SHT_RELX) {
1884 relocate_rel(s1, s);
1888 /* get entry point address */
1889 if (file_type == TCC_OUTPUT_EXE)
1890 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
1891 else
1892 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1895 /* write elf file */
1896 if (file_type == TCC_OUTPUT_OBJ)
1897 mode = 0666;
1898 else
1899 mode = 0777;
1900 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1901 if (fd < 0) {
1902 error_noabort("could not write '%s'", filename);
1903 goto fail;
1905 f = fdopen(fd, "wb");
1906 if (verbose)
1907 printf("<- %s\n", filename);
1909 #ifdef TCC_TARGET_COFF
1910 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1911 tcc_output_coff(s1, f);
1912 } else
1913 #endif
1914 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1915 sort_syms(s1, symtab_section);
1917 /* align to 4 */
1918 file_offset = (file_offset + 3) & -4;
1920 /* fill header */
1921 ehdr.e_ident[0] = ELFMAG0;
1922 ehdr.e_ident[1] = ELFMAG1;
1923 ehdr.e_ident[2] = ELFMAG2;
1924 ehdr.e_ident[3] = ELFMAG3;
1925 ehdr.e_ident[4] = TCC_ELFCLASS;
1926 ehdr.e_ident[5] = ELFDATA2LSB;
1927 ehdr.e_ident[6] = EV_CURRENT;
1928 #ifdef __FreeBSD__
1929 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1930 #endif
1931 #ifdef TCC_TARGET_ARM
1932 #ifdef TCC_ARM_EABI
1933 ehdr.e_ident[EI_OSABI] = 0;
1934 ehdr.e_flags = 4 << 24;
1935 #else
1936 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1937 #endif
1938 #endif
1939 switch(file_type) {
1940 default:
1941 case TCC_OUTPUT_EXE:
1942 ehdr.e_type = ET_EXEC;
1943 break;
1944 case TCC_OUTPUT_DLL:
1945 ehdr.e_type = ET_DYN;
1946 break;
1947 case TCC_OUTPUT_OBJ:
1948 ehdr.e_type = ET_REL;
1949 break;
1951 ehdr.e_machine = EM_TCC_TARGET;
1952 ehdr.e_version = EV_CURRENT;
1953 ehdr.e_shoff = file_offset;
1954 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
1955 ehdr.e_shentsize = sizeof(ElfW(Shdr));
1956 ehdr.e_shnum = shnum;
1957 ehdr.e_shstrndx = shnum - 1;
1959 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
1960 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
1961 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1963 for(i=1;i<s1->nb_sections;i++) {
1964 s = s1->sections[section_order[i]];
1965 if (s->sh_type != SHT_NOBITS) {
1966 while (offset < s->sh_offset) {
1967 fputc(0, f);
1968 offset++;
1970 size = s->sh_size;
1971 fwrite(s->data, 1, size, f);
1972 offset += size;
1976 /* output section headers */
1977 while (offset < ehdr.e_shoff) {
1978 fputc(0, f);
1979 offset++;
1982 for(i=0;i<s1->nb_sections;i++) {
1983 sh = &shdr;
1984 memset(sh, 0, sizeof(ElfW(Shdr)));
1985 s = s1->sections[i];
1986 if (s) {
1987 sh->sh_name = s->sh_name;
1988 sh->sh_type = s->sh_type;
1989 sh->sh_flags = s->sh_flags;
1990 sh->sh_entsize = s->sh_entsize;
1991 sh->sh_info = s->sh_info;
1992 if (s->link)
1993 sh->sh_link = s->link->sh_num;
1994 sh->sh_addralign = s->sh_addralign;
1995 sh->sh_addr = s->sh_addr;
1996 sh->sh_offset = s->sh_offset;
1997 sh->sh_size = s->sh_size;
1999 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2001 } else {
2002 tcc_output_binary(s1, f, section_order);
2004 fclose(f);
2006 ret = 0;
2007 the_end:
2008 tcc_free(s1->symtab_to_dynsym);
2009 tcc_free(section_order);
2010 tcc_free(phdr);
2011 tcc_free(s1->got_offsets);
2012 return ret;
2015 int tcc_output_file(TCCState *s, const char *filename)
2017 int ret;
2018 #ifdef TCC_TARGET_PE
2019 if (s->output_type != TCC_OUTPUT_OBJ) {
2020 ret = pe_output_file(s, filename);
2021 } else
2022 #endif
2024 ret = elf_output_file(s, filename);
2026 return ret;
2029 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2031 void *data;
2033 data = tcc_malloc(size);
2034 lseek(fd, file_offset, SEEK_SET);
2035 read(fd, data, size);
2036 return data;
2039 typedef struct SectionMergeInfo {
2040 Section *s; /* corresponding existing section */
2041 unsigned long offset; /* offset of the new section in the existing section */
2042 uint8_t new_section; /* true if section 's' was added */
2043 uint8_t link_once; /* true if link once section */
2044 } SectionMergeInfo;
2046 /* load an object file and merge it with current files */
2047 /* XXX: handle correctly stab (debug) info */
2048 static int tcc_load_object_file(TCCState *s1,
2049 int fd, unsigned long file_offset)
2051 ElfW(Ehdr) ehdr;
2052 ElfW(Shdr) *shdr, *sh;
2053 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2054 unsigned char *strsec, *strtab;
2055 int *old_to_new_syms;
2056 char *sh_name, *name;
2057 SectionMergeInfo *sm_table, *sm;
2058 ElfW(Sym) *sym, *symtab;
2059 ElfW_Rel *rel, *rel_end;
2060 Section *s;
2062 int stab_index;
2063 int stabstr_index;
2065 stab_index = stabstr_index = 0;
2067 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
2068 goto fail1;
2069 if (ehdr.e_ident[0] != ELFMAG0 ||
2070 ehdr.e_ident[1] != ELFMAG1 ||
2071 ehdr.e_ident[2] != ELFMAG2 ||
2072 ehdr.e_ident[3] != ELFMAG3)
2073 goto fail1;
2074 /* test if object file */
2075 if (ehdr.e_type != ET_REL)
2076 goto fail1;
2077 /* test CPU specific stuff */
2078 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2079 ehdr.e_machine != EM_TCC_TARGET) {
2080 fail1:
2081 error_noabort("invalid object file");
2082 return -1;
2084 /* read sections */
2085 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2086 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2087 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2089 /* load section names */
2090 sh = &shdr[ehdr.e_shstrndx];
2091 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2093 /* load symtab and strtab */
2094 old_to_new_syms = NULL;
2095 symtab = NULL;
2096 strtab = NULL;
2097 nb_syms = 0;
2098 for(i = 1; i < ehdr.e_shnum; i++) {
2099 sh = &shdr[i];
2100 if (sh->sh_type == SHT_SYMTAB) {
2101 if (symtab) {
2102 error_noabort("object must contain only one symtab");
2103 fail:
2104 ret = -1;
2105 goto the_end;
2107 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2108 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2109 sm_table[i].s = symtab_section;
2111 /* now load strtab */
2112 sh = &shdr[sh->sh_link];
2113 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2117 /* now examine each section and try to merge its content with the
2118 ones in memory */
2119 for(i = 1; i < ehdr.e_shnum; i++) {
2120 /* no need to examine section name strtab */
2121 if (i == ehdr.e_shstrndx)
2122 continue;
2123 sh = &shdr[i];
2124 sh_name = strsec + sh->sh_name;
2125 /* ignore sections types we do not handle */
2126 if (sh->sh_type != SHT_PROGBITS &&
2127 sh->sh_type != SHT_RELX &&
2128 #ifdef TCC_ARM_EABI
2129 sh->sh_type != SHT_ARM_EXIDX &&
2130 #endif
2131 sh->sh_type != SHT_NOBITS &&
2132 strcmp(sh_name, ".stabstr")
2134 continue;
2135 if (sh->sh_addralign < 1)
2136 sh->sh_addralign = 1;
2137 /* find corresponding section, if any */
2138 for(j = 1; j < s1->nb_sections;j++) {
2139 s = s1->sections[j];
2140 if (!strcmp(s->name, sh_name)) {
2141 if (!strncmp(sh_name, ".gnu.linkonce",
2142 sizeof(".gnu.linkonce") - 1)) {
2143 /* if a 'linkonce' section is already present, we
2144 do not add it again. It is a little tricky as
2145 symbols can still be defined in
2146 it. */
2147 sm_table[i].link_once = 1;
2148 goto next;
2149 } else {
2150 goto found;
2154 /* not found: create new section */
2155 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
2156 /* take as much info as possible from the section. sh_link and
2157 sh_info will be updated later */
2158 s->sh_addralign = sh->sh_addralign;
2159 s->sh_entsize = sh->sh_entsize;
2160 sm_table[i].new_section = 1;
2161 found:
2162 if (sh->sh_type != s->sh_type) {
2163 error_noabort("invalid section type");
2164 goto fail;
2167 /* align start of section */
2168 offset = s->data_offset;
2170 if (0 == strcmp(sh_name, ".stab")) {
2171 stab_index = i;
2172 goto no_align;
2174 if (0 == strcmp(sh_name, ".stabstr")) {
2175 stabstr_index = i;
2176 goto no_align;
2179 size = sh->sh_addralign - 1;
2180 offset = (offset + size) & ~size;
2181 if (sh->sh_addralign > s->sh_addralign)
2182 s->sh_addralign = sh->sh_addralign;
2183 s->data_offset = offset;
2184 no_align:
2185 sm_table[i].offset = offset;
2186 sm_table[i].s = s;
2187 /* concatenate sections */
2188 size = sh->sh_size;
2189 if (sh->sh_type != SHT_NOBITS) {
2190 unsigned char *ptr;
2191 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2192 ptr = section_ptr_add(s, size);
2193 read(fd, ptr, size);
2194 } else {
2195 s->data_offset += size;
2197 next: ;
2200 /* //gr relocate stab strings */
2201 if (stab_index && stabstr_index) {
2202 Stab_Sym *a, *b;
2203 unsigned o;
2204 s = sm_table[stab_index].s;
2205 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2206 b = (Stab_Sym *)(s->data + s->data_offset);
2207 o = sm_table[stabstr_index].offset;
2208 while (a < b)
2209 a->n_strx += o, a++;
2212 /* second short pass to update sh_link and sh_info fields of new
2213 sections */
2214 for(i = 1; i < ehdr.e_shnum; i++) {
2215 s = sm_table[i].s;
2216 if (!s || !sm_table[i].new_section)
2217 continue;
2218 sh = &shdr[i];
2219 if (sh->sh_link > 0)
2220 s->link = sm_table[sh->sh_link].s;
2221 if (sh->sh_type == SHT_RELX) {
2222 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2223 /* update backward link */
2224 s1->sections[s->sh_info]->reloc = s;
2227 sm = sm_table;
2229 /* resolve symbols */
2230 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2232 sym = symtab + 1;
2233 for(i = 1; i < nb_syms; i++, sym++) {
2234 if (sym->st_shndx != SHN_UNDEF &&
2235 sym->st_shndx < SHN_LORESERVE) {
2236 sm = &sm_table[sym->st_shndx];
2237 if (sm->link_once) {
2238 /* if a symbol is in a link once section, we use the
2239 already defined symbol. It is very important to get
2240 correct relocations */
2241 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2242 name = strtab + sym->st_name;
2243 sym_index = find_elf_sym(symtab_section, name);
2244 if (sym_index)
2245 old_to_new_syms[i] = sym_index;
2247 continue;
2249 /* if no corresponding section added, no need to add symbol */
2250 if (!sm->s)
2251 continue;
2252 /* convert section number */
2253 sym->st_shndx = sm->s->sh_num;
2254 /* offset value */
2255 sym->st_value += sm->offset;
2257 /* add symbol */
2258 name = strtab + sym->st_name;
2259 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
2260 sym->st_info, sym->st_other,
2261 sym->st_shndx, name);
2262 old_to_new_syms[i] = sym_index;
2265 /* third pass to patch relocation entries */
2266 for(i = 1; i < ehdr.e_shnum; i++) {
2267 s = sm_table[i].s;
2268 if (!s)
2269 continue;
2270 sh = &shdr[i];
2271 offset = sm_table[i].offset;
2272 switch(s->sh_type) {
2273 case SHT_RELX:
2274 /* take relocation offset information */
2275 offseti = sm_table[sh->sh_info].offset;
2276 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
2277 for(rel = (ElfW_Rel *)(s->data + offset);
2278 rel < rel_end;
2279 rel++) {
2280 int type;
2281 unsigned sym_index;
2282 /* convert symbol index */
2283 type = ELFW(R_TYPE)(rel->r_info);
2284 sym_index = ELFW(R_SYM)(rel->r_info);
2285 /* NOTE: only one symtab assumed */
2286 if (sym_index >= nb_syms)
2287 goto invalid_reloc;
2288 sym_index = old_to_new_syms[sym_index];
2289 /* ignore link_once in rel section. */
2290 if (!sym_index && !sm->link_once) {
2291 invalid_reloc:
2292 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2293 i, strsec + sh->sh_name, rel->r_offset);
2294 goto fail;
2296 rel->r_info = ELFW(R_INFO)(sym_index, type);
2297 /* offset the relocation offset */
2298 rel->r_offset += offseti;
2300 break;
2301 default:
2302 break;
2306 ret = 0;
2307 the_end:
2308 tcc_free(symtab);
2309 tcc_free(strtab);
2310 tcc_free(old_to_new_syms);
2311 tcc_free(sm_table);
2312 tcc_free(strsec);
2313 tcc_free(shdr);
2314 return ret;
2317 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2319 typedef struct ArchiveHeader {
2320 char ar_name[16]; /* name of this member */
2321 char ar_date[12]; /* file mtime */
2322 char ar_uid[6]; /* owner uid; printed as decimal */
2323 char ar_gid[6]; /* owner gid; printed as decimal */
2324 char ar_mode[8]; /* file mode, printed as octal */
2325 char ar_size[10]; /* file size, printed as decimal */
2326 char ar_fmag[2]; /* should contain ARFMAG */
2327 } ArchiveHeader;
2329 static int get_be32(const uint8_t *b)
2331 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2334 /* load only the objects which resolve undefined symbols */
2335 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
2337 int i, bound, nsyms, sym_index, off, ret;
2338 uint8_t *data;
2339 const char *ar_names, *p;
2340 const uint8_t *ar_index;
2341 ElfW(Sym) *sym;
2343 data = tcc_malloc(size);
2344 if (read(fd, data, size) != size)
2345 goto fail;
2346 nsyms = get_be32(data);
2347 ar_index = data + 4;
2348 ar_names = ar_index + nsyms * 4;
2350 do {
2351 bound = 0;
2352 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2353 sym_index = find_elf_sym(symtab_section, p);
2354 if(sym_index) {
2355 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2356 if(sym->st_shndx == SHN_UNDEF) {
2357 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2358 #if 0
2359 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2360 #endif
2361 ++bound;
2362 lseek(fd, off, SEEK_SET);
2363 if(tcc_load_object_file(s1, fd, off) < 0) {
2364 fail:
2365 ret = -1;
2366 goto the_end;
2371 } while(bound);
2372 ret = 0;
2373 the_end:
2374 tcc_free(data);
2375 return ret;
2378 /* load a '.a' file */
2379 static int tcc_load_archive(TCCState *s1, int fd)
2381 ArchiveHeader hdr;
2382 char ar_size[11];
2383 char ar_name[17];
2384 char magic[8];
2385 int size, len, i;
2386 unsigned long file_offset;
2388 /* skip magic which was already checked */
2389 read(fd, magic, sizeof(magic));
2391 for(;;) {
2392 len = read(fd, &hdr, sizeof(hdr));
2393 if (len == 0)
2394 break;
2395 if (len != sizeof(hdr)) {
2396 error_noabort("invalid archive");
2397 return -1;
2399 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2400 ar_size[sizeof(hdr.ar_size)] = '\0';
2401 size = strtol(ar_size, NULL, 0);
2402 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2403 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2404 if (ar_name[i] != ' ')
2405 break;
2407 ar_name[i + 1] = '\0';
2408 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2409 file_offset = lseek(fd, 0, SEEK_CUR);
2410 /* align to even */
2411 size = (size + 1) & ~1;
2412 if (!strcmp(ar_name, "/")) {
2413 /* coff symbol table : we handle it */
2414 if(s1->alacarte_link)
2415 return tcc_load_alacarte(s1, fd, size);
2416 } else if (!strcmp(ar_name, "//") ||
2417 !strcmp(ar_name, "__.SYMDEF") ||
2418 !strcmp(ar_name, "__.SYMDEF/") ||
2419 !strcmp(ar_name, "ARFILENAMES/")) {
2420 /* skip symbol table or archive names */
2421 } else {
2422 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2423 return -1;
2425 lseek(fd, file_offset + size, SEEK_SET);
2427 return 0;
2430 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2431 is referenced by the user (so it should be added as DT_NEEDED in
2432 the generated ELF file) */
2433 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2435 ElfW(Ehdr) ehdr;
2436 ElfW(Shdr) *shdr, *sh, *sh1;
2437 int i, j, nb_syms, nb_dts, sym_bind, ret;
2438 ElfW(Sym) *sym, *dynsym;
2439 ElfW(Dyn) *dt, *dynamic;
2440 unsigned char *dynstr;
2441 const char *name, *soname;
2442 DLLReference *dllref;
2444 read(fd, &ehdr, sizeof(ehdr));
2446 /* test CPU specific stuff */
2447 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2448 ehdr.e_machine != EM_TCC_TARGET) {
2449 error_noabort("bad architecture");
2450 return -1;
2453 /* read sections */
2454 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2456 /* load dynamic section and dynamic symbols */
2457 nb_syms = 0;
2458 nb_dts = 0;
2459 dynamic = NULL;
2460 dynsym = NULL; /* avoid warning */
2461 dynstr = NULL; /* avoid warning */
2462 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2463 switch(sh->sh_type) {
2464 case SHT_DYNAMIC:
2465 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2466 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2467 break;
2468 case SHT_DYNSYM:
2469 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2470 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2471 sh1 = &shdr[sh->sh_link];
2472 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2473 break;
2474 default:
2475 break;
2479 /* compute the real library name */
2480 soname = tcc_basename(filename);
2482 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2483 if (dt->d_tag == DT_SONAME) {
2484 soname = dynstr + dt->d_un.d_val;
2488 /* if the dll is already loaded, do not load it */
2489 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2490 dllref = s1->loaded_dlls[i];
2491 if (!strcmp(soname, dllref->name)) {
2492 /* but update level if needed */
2493 if (level < dllref->level)
2494 dllref->level = level;
2495 ret = 0;
2496 goto the_end;
2500 // printf("loading dll '%s'\n", soname);
2502 /* add the dll and its level */
2503 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2504 dllref->level = level;
2505 strcpy(dllref->name, soname);
2506 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2508 /* add dynamic symbols in dynsym_section */
2509 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2510 sym_bind = ELFW(ST_BIND)(sym->st_info);
2511 if (sym_bind == STB_LOCAL)
2512 continue;
2513 name = dynstr + sym->st_name;
2514 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2515 sym->st_info, sym->st_other, sym->st_shndx, name);
2518 /* load all referenced DLLs */
2519 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2520 switch(dt->d_tag) {
2521 case DT_NEEDED:
2522 name = dynstr + dt->d_un.d_val;
2523 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2524 dllref = s1->loaded_dlls[j];
2525 if (!strcmp(name, dllref->name))
2526 goto already_loaded;
2528 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2529 error_noabort("referenced dll '%s' not found", name);
2530 ret = -1;
2531 goto the_end;
2533 already_loaded:
2534 break;
2537 ret = 0;
2538 the_end:
2539 tcc_free(dynstr);
2540 tcc_free(dynsym);
2541 tcc_free(dynamic);
2542 tcc_free(shdr);
2543 return ret;
2546 #define LD_TOK_NAME 256
2547 #define LD_TOK_EOF (-1)
2549 /* return next ld script token */
2550 static int ld_next(TCCState *s1, char *name, int name_size)
2552 int c;
2553 char *q;
2555 redo:
2556 switch(ch) {
2557 case ' ':
2558 case '\t':
2559 case '\f':
2560 case '\v':
2561 case '\r':
2562 case '\n':
2563 inp();
2564 goto redo;
2565 case '/':
2566 minp();
2567 if (ch == '*') {
2568 file->buf_ptr = parse_comment(file->buf_ptr);
2569 ch = file->buf_ptr[0];
2570 goto redo;
2571 } else {
2572 q = name;
2573 *q++ = '/';
2574 goto parse_name;
2576 break;
2577 /* case 'a' ... 'z': */
2578 case 'a':
2579 case 'b':
2580 case 'c':
2581 case 'd':
2582 case 'e':
2583 case 'f':
2584 case 'g':
2585 case 'h':
2586 case 'i':
2587 case 'j':
2588 case 'k':
2589 case 'l':
2590 case 'm':
2591 case 'n':
2592 case 'o':
2593 case 'p':
2594 case 'q':
2595 case 'r':
2596 case 's':
2597 case 't':
2598 case 'u':
2599 case 'v':
2600 case 'w':
2601 case 'x':
2602 case 'y':
2603 case 'z':
2604 /* case 'A' ... 'z': */
2605 case 'A':
2606 case 'B':
2607 case 'C':
2608 case 'D':
2609 case 'E':
2610 case 'F':
2611 case 'G':
2612 case 'H':
2613 case 'I':
2614 case 'J':
2615 case 'K':
2616 case 'L':
2617 case 'M':
2618 case 'N':
2619 case 'O':
2620 case 'P':
2621 case 'Q':
2622 case 'R':
2623 case 'S':
2624 case 'T':
2625 case 'U':
2626 case 'V':
2627 case 'W':
2628 case 'X':
2629 case 'Y':
2630 case 'Z':
2631 case '_':
2632 case '\\':
2633 case '.':
2634 case '$':
2635 case '~':
2636 q = name;
2637 parse_name:
2638 for(;;) {
2639 if (!((ch >= 'a' && ch <= 'z') ||
2640 (ch >= 'A' && ch <= 'Z') ||
2641 (ch >= '0' && ch <= '9') ||
2642 strchr("/.-_+=$:\\,~", ch)))
2643 break;
2644 if ((q - name) < name_size - 1) {
2645 *q++ = ch;
2647 minp();
2649 *q = '\0';
2650 c = LD_TOK_NAME;
2651 break;
2652 case CH_EOF:
2653 c = LD_TOK_EOF;
2654 break;
2655 default:
2656 c = ch;
2657 inp();
2658 break;
2660 #if 0
2661 printf("tok=%c %d\n", c, c);
2662 if (c == LD_TOK_NAME)
2663 printf(" name=%s\n", name);
2664 #endif
2665 return c;
2668 static int ld_add_file_list(TCCState *s1, int as_needed)
2670 char filename[1024];
2671 int t, ret;
2673 t = ld_next(s1, filename, sizeof(filename));
2674 if (t != '(')
2675 expect("(");
2676 t = ld_next(s1, filename, sizeof(filename));
2677 for(;;) {
2678 if (t == LD_TOK_EOF) {
2679 error_noabort("unexpected end of file");
2680 return -1;
2681 } else if (t == ')') {
2682 break;
2683 } else if (t != LD_TOK_NAME) {
2684 error_noabort("filename expected");
2685 return -1;
2687 if (!strcmp(filename, "AS_NEEDED")) {
2688 ret = ld_add_file_list(s1, 1);
2689 if (ret)
2690 return ret;
2691 } else {
2692 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2693 if (!as_needed)
2694 tcc_add_file(s1, filename);
2696 t = ld_next(s1, filename, sizeof(filename));
2697 if (t == ',') {
2698 t = ld_next(s1, filename, sizeof(filename));
2701 return 0;
2704 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2705 files */
2706 static int tcc_load_ldscript(TCCState *s1)
2708 char cmd[64];
2709 char filename[1024];
2710 int t, ret;
2712 ch = file->buf_ptr[0];
2713 ch = handle_eob();
2714 for(;;) {
2715 t = ld_next(s1, cmd, sizeof(cmd));
2716 if (t == LD_TOK_EOF)
2717 return 0;
2718 else if (t != LD_TOK_NAME)
2719 return -1;
2720 if (!strcmp(cmd, "INPUT") ||
2721 !strcmp(cmd, "GROUP")) {
2722 ret = ld_add_file_list(s1, 0);
2723 if (ret)
2724 return ret;
2725 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2726 !strcmp(cmd, "TARGET")) {
2727 /* ignore some commands */
2728 t = ld_next(s1, cmd, sizeof(cmd));
2729 if (t != '(')
2730 expect("(");
2731 for(;;) {
2732 t = ld_next(s1, filename, sizeof(filename));
2733 if (t == LD_TOK_EOF) {
2734 error_noabort("unexpected end of file");
2735 return -1;
2736 } else if (t == ')') {
2737 break;
2740 } else {
2741 return -1;
2744 return 0;