fix "symbol not defined" if symbol has offset 0
[tinycc/k1w1.git] / tccelf.c
blobc95ecf72227887b3fde6ca7372f4fe0dd6e11c02
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, signal error if 'err' is nonzero */
172 static void *get_elf_sym_addr(TCCState *s, const char *name, int err)
174 int sym_index;
175 ElfW(Sym) *sym;
177 sym_index = find_elf_sym(symtab_section, name);
178 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
179 if (!sym_index || sym->st_shndx == SHN_UNDEF) {
180 if (err)
181 error("%s not defined", name);
182 return NULL;
184 return (void*)(uplong)sym->st_value;
187 /* return elf symbol value */
188 void *tcc_get_symbol(TCCState *s, const char *name)
190 return get_elf_sym_addr(s, name, 0);
193 /* return elf symbol value or error */
194 void *tcc_get_symbol_err(TCCState *s, const char *name)
196 return get_elf_sym_addr(s, name, 1);
199 /* add an elf symbol : check if it is already defined and patch
200 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
201 static int add_elf_sym(Section *s, uplong value, unsigned long size,
202 int info, int other, int sh_num, const char *name)
204 ElfW(Sym) *esym;
205 int sym_bind, sym_index, sym_type, esym_bind;
206 unsigned char sym_vis, esym_vis, new_vis;
208 sym_bind = ELFW(ST_BIND)(info);
209 sym_type = ELFW(ST_TYPE)(info);
210 sym_vis = ELFW(ST_VISIBILITY)(other);
212 if (sym_bind != STB_LOCAL) {
213 /* we search global or weak symbols */
214 sym_index = find_elf_sym(s, name);
215 if (!sym_index)
216 goto do_def;
217 esym = &((ElfW(Sym) *)s->data)[sym_index];
218 if (esym->st_shndx != SHN_UNDEF) {
219 esym_bind = ELFW(ST_BIND)(esym->st_info);
220 /* propagate the most constraining visibility */
221 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
222 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
223 if (esym_vis == STV_DEFAULT) {
224 new_vis = sym_vis;
225 } else if (sym_vis == STV_DEFAULT) {
226 new_vis = esym_vis;
227 } else {
228 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
230 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
231 | new_vis;
232 other = esym->st_other; /* in case we have to patch esym */
233 if (sh_num == SHN_UNDEF) {
234 /* ignore adding of undefined symbol if the
235 corresponding symbol is already defined */
236 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
237 /* global overrides weak, so patch */
238 goto do_patch;
239 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
240 /* weak is ignored if already global */
241 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
242 /* ignore hidden symbols after */
243 } else if (esym->st_shndx == SHN_COMMON
244 && (sh_num < SHN_LORESERVE || sh_num == SHN_COMMON)) {
245 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
246 No idea if this is the correct solution ... */
247 goto do_patch;
248 } else if (s == tcc_state->dynsymtab_section) {
249 /* we accept that two DLL define the same symbol */
250 } else {
251 #if 1
252 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
253 sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
254 #endif
255 error_noabort("'%s' defined twice", name);
257 } else {
258 do_patch:
259 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
260 esym->st_shndx = sh_num;
261 esym->st_value = value;
262 esym->st_size = size;
263 esym->st_other = other;
265 } else {
266 do_def:
267 sym_index = put_elf_sym(s, value, size,
268 ELFW(ST_INFO)(sym_bind, sym_type), other,
269 sh_num, name);
271 return sym_index;
274 /* put relocation */
275 static void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
276 int type, int symbol)
278 char buf[256];
279 Section *sr;
280 ElfW_Rel *rel;
282 sr = s->reloc;
283 if (!sr) {
284 /* if no relocation section, create it */
285 snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
286 /* if the symtab is allocated, then we consider the relocation
287 are also */
288 sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
289 sr->sh_entsize = sizeof(ElfW_Rel);
290 sr->link = symtab;
291 sr->sh_info = s->sh_num;
292 s->reloc = sr;
294 rel = section_ptr_add(sr, sizeof(ElfW_Rel));
295 rel->r_offset = offset;
296 rel->r_info = ELFW(R_INFO)(symbol, type);
297 #ifdef TCC_TARGET_X86_64
298 rel->r_addend = 0;
299 #endif
302 /* put stab debug information */
304 typedef struct {
305 unsigned int n_strx; /* index into string table of name */
306 unsigned char n_type; /* type of symbol */
307 unsigned char n_other; /* misc info (usually empty) */
308 unsigned short n_desc; /* description field */
309 unsigned int n_value; /* value of symbol */
310 } Stab_Sym;
312 static void put_stabs(const char *str, int type, int other, int desc,
313 unsigned long value)
315 Stab_Sym *sym;
317 sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
318 if (str) {
319 sym->n_strx = put_elf_str(stabstr_section, str);
320 } else {
321 sym->n_strx = 0;
323 sym->n_type = type;
324 sym->n_other = other;
325 sym->n_desc = desc;
326 sym->n_value = value;
329 static void put_stabs_r(const char *str, int type, int other, int desc,
330 unsigned long value, Section *sec, int sym_index)
332 put_stabs(str, type, other, desc, value);
333 put_elf_reloc(symtab_section, stab_section,
334 stab_section->data_offset - sizeof(unsigned int),
335 R_DATA_32, sym_index);
338 static void put_stabn(int type, int other, int desc, int value)
340 put_stabs(NULL, type, other, desc, value);
343 static void put_stabd(int type, int other, int desc)
345 put_stabs(NULL, type, other, desc, 0);
348 /* In an ELF file symbol table, the local symbols must appear below
349 the global and weak ones. Since TCC cannot sort it while generating
350 the code, we must do it after. All the relocation tables are also
351 modified to take into account the symbol table sorting */
352 static void sort_syms(TCCState *s1, Section *s)
354 int *old_to_new_syms;
355 ElfW(Sym) *new_syms;
356 int nb_syms, i;
357 ElfW(Sym) *p, *q;
358 ElfW_Rel *rel, *rel_end;
359 Section *sr;
360 int type, sym_index;
362 nb_syms = s->data_offset / sizeof(ElfW(Sym));
363 new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
364 old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
366 /* first pass for local symbols */
367 p = (ElfW(Sym) *)s->data;
368 q = new_syms;
369 for(i = 0; i < nb_syms; i++) {
370 if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
371 old_to_new_syms[i] = q - new_syms;
372 *q++ = *p;
374 p++;
376 /* save the number of local symbols in section header */
377 s->sh_info = q - new_syms;
379 /* then second pass for non local symbols */
380 p = (ElfW(Sym) *)s->data;
381 for(i = 0; i < nb_syms; i++) {
382 if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
383 old_to_new_syms[i] = q - new_syms;
384 *q++ = *p;
386 p++;
389 /* we copy the new symbols to the old */
390 memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
391 tcc_free(new_syms);
393 /* now we modify all the relocations */
394 for(i = 1; i < s1->nb_sections; i++) {
395 sr = s1->sections[i];
396 if (sr->sh_type == SHT_RELX && sr->link == s) {
397 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
398 for(rel = (ElfW_Rel *)sr->data;
399 rel < rel_end;
400 rel++) {
401 sym_index = ELFW(R_SYM)(rel->r_info);
402 type = ELFW(R_TYPE)(rel->r_info);
403 sym_index = old_to_new_syms[sym_index];
404 rel->r_info = ELFW(R_INFO)(sym_index, type);
409 tcc_free(old_to_new_syms);
412 /* relocate common symbols in the .bss section */
413 static void relocate_common_syms(void)
415 ElfW(Sym) *sym, *sym_end;
416 unsigned long offset, align;
418 sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
419 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
420 sym < sym_end;
421 sym++) {
422 if (sym->st_shndx == SHN_COMMON) {
423 /* align symbol */
424 align = sym->st_value;
425 offset = bss_section->data_offset;
426 offset = (offset + align - 1) & -align;
427 sym->st_value = offset;
428 sym->st_shndx = bss_section->sh_num;
429 offset += sym->st_size;
430 bss_section->data_offset = offset;
435 /* relocate symbol table, resolve undefined symbols if do_resolve is
436 true and output error if undefined symbol. */
437 static void relocate_syms(TCCState *s1, int do_resolve)
439 ElfW(Sym) *sym, *esym, *sym_end;
440 int sym_bind, sh_num, sym_index;
441 const char *name;
443 sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
444 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
445 sym < sym_end;
446 sym++) {
447 sh_num = sym->st_shndx;
448 if (sh_num == SHN_UNDEF) {
449 name = strtab_section->data + sym->st_name;
450 if (do_resolve) {
451 #ifndef _WIN32
452 void *addr;
453 name = symtab_section->link->data + sym->st_name;
454 addr = resolve_sym(s1, name);
455 if (addr) {
456 sym->st_value = (uplong)addr;
457 goto found;
459 #endif
460 } else if (s1->dynsym) {
461 /* if dynamic symbol exist, then use it */
462 sym_index = find_elf_sym(s1->dynsym, name);
463 if (sym_index) {
464 esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
465 sym->st_value = esym->st_value;
466 goto found;
469 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
470 it */
471 if (!strcmp(name, "_fp_hw"))
472 goto found;
473 /* only weak symbols are accepted to be undefined. Their
474 value is zero */
475 sym_bind = ELFW(ST_BIND)(sym->st_info);
476 if (sym_bind == STB_WEAK) {
477 sym->st_value = 0;
478 } else {
479 error_noabort("undefined symbol '%s'", name);
481 } else if (sh_num < SHN_LORESERVE) {
482 /* add section base */
483 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
485 found: ;
489 #ifndef TCC_TARGET_PE
490 #ifdef TCC_TARGET_X86_64
491 #define JMP_TABLE_ENTRY_SIZE 14
492 static unsigned long add_jmp_table(TCCState *s1, unsigned long val)
494 char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset;
495 s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE;
496 /* jmp *0x0(%rip) */
497 p[0] = 0xff;
498 p[1] = 0x25;
499 *(int *)(p + 2) = 0;
500 *(unsigned long *)(p + 6) = val;
501 return (unsigned long)p;
504 static unsigned long add_got_table(TCCState *s1, unsigned long val)
506 unsigned long *p =(unsigned long *)(s1->runtime_plt_and_got +
507 s1->runtime_plt_and_got_offset);
508 s1->runtime_plt_and_got_offset += sizeof(void *);
509 *p = val;
510 return (unsigned long)p;
512 #endif
513 #endif
515 /* relocate a given section (CPU dependent) */
516 static void relocate_section(TCCState *s1, Section *s)
518 Section *sr;
519 ElfW_Rel *rel, *rel_end, *qrel;
520 ElfW(Sym) *sym;
521 int type, sym_index;
522 unsigned char *ptr;
523 unsigned long val, addr;
524 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
525 int esym_index;
526 #endif
528 sr = s->reloc;
529 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
530 qrel = (ElfW_Rel *)sr->data;
531 for(rel = qrel;
532 rel < rel_end;
533 rel++) {
534 ptr = s->data + rel->r_offset;
536 sym_index = ELFW(R_SYM)(rel->r_info);
537 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
538 val = sym->st_value;
539 #ifdef TCC_TARGET_X86_64
540 /* XXX: not tested */
541 val += rel->r_addend;
542 #endif
543 type = ELFW(R_TYPE)(rel->r_info);
544 addr = s->sh_addr + rel->r_offset;
546 /* CPU specific */
547 switch(type) {
548 #if defined(TCC_TARGET_I386)
549 case R_386_32:
550 if (s1->output_type == TCC_OUTPUT_DLL) {
551 esym_index = s1->symtab_to_dynsym[sym_index];
552 qrel->r_offset = rel->r_offset;
553 if (esym_index) {
554 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
555 qrel++;
556 break;
557 } else {
558 qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
559 qrel++;
562 *(int *)ptr += val;
563 break;
564 case R_386_PC32:
565 if (s1->output_type == TCC_OUTPUT_DLL) {
566 /* DLL relocation */
567 esym_index = s1->symtab_to_dynsym[sym_index];
568 if (esym_index) {
569 qrel->r_offset = rel->r_offset;
570 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
571 qrel++;
572 break;
575 *(int *)ptr += val - addr;
576 break;
577 case R_386_PLT32:
578 *(int *)ptr += val - addr;
579 break;
580 case R_386_GLOB_DAT:
581 case R_386_JMP_SLOT:
582 *(int *)ptr = val;
583 break;
584 case R_386_GOTPC:
585 *(int *)ptr += s1->got->sh_addr - addr;
586 break;
587 case R_386_GOTOFF:
588 *(int *)ptr += val - s1->got->sh_addr;
589 break;
590 case R_386_GOT32:
591 /* we load the got offset */
592 *(int *)ptr += s1->got_offsets[sym_index];
593 break;
594 #elif defined(TCC_TARGET_ARM)
595 case R_ARM_PC24:
596 case R_ARM_CALL:
597 case R_ARM_JUMP24:
598 case R_ARM_PLT32:
600 int x;
601 x = (*(int *)ptr)&0xffffff;
602 (*(int *)ptr) &= 0xff000000;
603 if (x & 0x800000)
604 x -= 0x1000000;
605 x *= 4;
606 x += val - addr;
607 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
608 error("can't relocate value at %x",addr);
609 x >>= 2;
610 x &= 0xffffff;
611 (*(int *)ptr) |= x;
613 break;
614 case R_ARM_PREL31:
616 int x;
617 x = (*(int *)ptr) & 0x7fffffff;
618 (*(int *)ptr) &= 0x80000000;
619 x = (x * 2) / 2;
620 x += val - addr;
621 if((x^(x>>1))&0x40000000)
622 error("can't relocate value at %x",addr);
623 (*(int *)ptr) |= x & 0x7fffffff;
625 case R_ARM_ABS32:
626 *(int *)ptr += val;
627 break;
628 case R_ARM_BASE_PREL:
629 *(int *)ptr += s1->got->sh_addr - addr;
630 break;
631 case R_ARM_GOTOFF32:
632 *(int *)ptr += val - s1->got->sh_addr;
633 break;
634 case R_ARM_GOT_BREL:
635 /* we load the got offset */
636 *(int *)ptr += s1->got_offsets[sym_index];
637 break;
638 case R_ARM_COPY:
639 break;
640 default:
641 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
642 type,addr,(unsigned int)(long)ptr,val);
643 break;
644 #elif defined(TCC_TARGET_C67)
645 case R_C60_32:
646 *(int *)ptr += val;
647 break;
648 case R_C60LO16:
650 uint32_t orig;
652 /* put the low 16 bits of the absolute address */
653 // add to what is already there
655 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
656 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
658 //patch both at once - assumes always in pairs Low - High
660 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
661 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
663 break;
664 case R_C60HI16:
665 break;
666 default:
667 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
668 type,addr,(unsigned int)(long)ptr, val);
669 break;
670 #elif defined(TCC_TARGET_X86_64)
671 case R_X86_64_64:
672 if (s1->output_type == TCC_OUTPUT_DLL) {
673 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
674 qrel->r_addend = *(long long *)ptr + val;
675 qrel++;
677 *(long long *)ptr += val;
678 break;
679 case R_X86_64_32:
680 case R_X86_64_32S:
681 if (s1->output_type == TCC_OUTPUT_DLL) {
682 /* XXX: this logic may depend on TCC's codegen
683 now TCC uses R_X86_64_32 even for a 64bit pointer */
684 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
685 qrel->r_addend = *(int *)ptr + val;
686 qrel++;
688 *(int *)ptr += val;
689 break;
690 case R_X86_64_PC32: {
691 long long diff;
692 if (s1->output_type == TCC_OUTPUT_DLL) {
693 /* DLL relocation */
694 esym_index = s1->symtab_to_dynsym[sym_index];
695 if (esym_index) {
696 qrel->r_offset = rel->r_offset;
697 qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
698 qrel->r_addend = *(int *)ptr;
699 qrel++;
700 break;
703 diff = (long long)val - addr;
704 if (diff <= -2147483647 || diff > 2147483647) {
705 #ifndef TCC_TARGET_PE
706 /* XXX: naive support for over 32bit jump */
707 if (s1->output_type == TCC_OUTPUT_MEMORY) {
708 val = add_jmp_table(s1, val);
709 diff = val - addr;
711 #endif
712 if (diff <= -2147483647 || diff > 2147483647) {
713 error("internal error: relocation failed");
716 *(int *)ptr += diff;
718 break;
719 case R_X86_64_PLT32:
720 *(int *)ptr += val - addr;
721 break;
722 case R_X86_64_GLOB_DAT:
723 case R_X86_64_JUMP_SLOT:
724 *(int *)ptr = val;
725 break;
726 case R_X86_64_GOTPCREL:
727 #ifndef TCC_TARGET_PE
728 if (s1->output_type == TCC_OUTPUT_MEMORY) {
729 val = add_got_table(s1, val - rel->r_addend) + rel->r_addend;
730 *(int *)ptr += val - addr;
731 break;
733 #endif
734 *(int *)ptr += (s1->got->sh_addr - addr +
735 s1->got_offsets[sym_index] - 4);
736 break;
737 case R_X86_64_GOTTPOFF:
738 *(int *)ptr += val - s1->got->sh_addr;
739 break;
740 case R_X86_64_GOT32:
741 /* we load the got offset */
742 *(int *)ptr += s1->got_offsets[sym_index];
743 break;
744 #else
745 #error unsupported processor
746 #endif
749 /* if the relocation is allocated, we change its symbol table */
750 if (sr->sh_flags & SHF_ALLOC)
751 sr->link = s1->dynsym;
754 /* relocate relocation table in 'sr' */
755 static void relocate_rel(TCCState *s1, Section *sr)
757 Section *s;
758 ElfW_Rel *rel, *rel_end;
760 s = s1->sections[sr->sh_info];
761 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
762 for(rel = (ElfW_Rel *)sr->data;
763 rel < rel_end;
764 rel++) {
765 rel->r_offset += s->sh_addr;
769 /* count the number of dynamic relocations so that we can reserve
770 their space */
771 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
773 ElfW_Rel *rel, *rel_end;
774 int sym_index, esym_index, type, count;
776 count = 0;
777 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
778 for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
779 sym_index = ELFW(R_SYM)(rel->r_info);
780 type = ELFW(R_TYPE)(rel->r_info);
781 switch(type) {
782 #if defined(TCC_TARGET_I386)
783 case R_386_32:
784 #elif defined(TCC_TARGET_X86_64)
785 case R_X86_64_32:
786 case R_X86_64_32S:
787 case R_X86_64_64:
788 #endif
789 count++;
790 break;
791 #if defined(TCC_TARGET_I386)
792 case R_386_PC32:
793 #elif defined(TCC_TARGET_X86_64)
794 case R_X86_64_PC32:
795 #endif
796 esym_index = s1->symtab_to_dynsym[sym_index];
797 if (esym_index)
798 count++;
799 break;
800 default:
801 break;
804 if (count) {
805 /* allocate the section */
806 sr->sh_flags |= SHF_ALLOC;
807 sr->sh_size = count * sizeof(ElfW_Rel);
809 return count;
812 static void put_got_offset(TCCState *s1, int index, unsigned long val)
814 int n;
815 unsigned long *tab;
817 if (index >= s1->nb_got_offsets) {
818 /* find immediately bigger power of 2 and reallocate array */
819 n = 1;
820 while (index >= n)
821 n *= 2;
822 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
823 if (!tab)
824 error("memory full");
825 s1->got_offsets = tab;
826 memset(s1->got_offsets + s1->nb_got_offsets, 0,
827 (n - s1->nb_got_offsets) * sizeof(unsigned long));
828 s1->nb_got_offsets = n;
830 s1->got_offsets[index] = val;
833 /* XXX: suppress that */
834 static void put32(unsigned char *p, uint32_t val)
836 p[0] = val;
837 p[1] = val >> 8;
838 p[2] = val >> 16;
839 p[3] = val >> 24;
842 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
843 defined(TCC_TARGET_X86_64)
844 static uint32_t get32(unsigned char *p)
846 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
848 #endif
850 static void build_got(TCCState *s1)
852 unsigned char *ptr;
854 /* if no got, then create it */
855 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
856 s1->got->sh_entsize = 4;
857 add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
858 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
859 ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
860 #if PTR_SIZE == 4
861 /* keep space for _DYNAMIC pointer, if present */
862 put32(ptr, 0);
863 /* two dummy got entries */
864 put32(ptr + 4, 0);
865 put32(ptr + 8, 0);
866 #else
867 /* keep space for _DYNAMIC pointer, if present */
868 put32(ptr, 0);
869 put32(ptr + 4, 0);
870 /* two dummy got entries */
871 put32(ptr + 8, 0);
872 put32(ptr + 12, 0);
873 put32(ptr + 16, 0);
874 put32(ptr + 20, 0);
875 #endif
878 /* put a got entry corresponding to a symbol in symtab_section. 'size'
879 and 'info' can be modifed if more precise info comes from the DLL */
880 static void put_got_entry(TCCState *s1,
881 int reloc_type, unsigned long size, int info,
882 int sym_index)
884 int index;
885 const char *name;
886 ElfW(Sym) *sym;
887 unsigned long offset;
888 int *ptr;
890 if (!s1->got)
891 build_got(s1);
893 /* if a got entry already exists for that symbol, no need to add one */
894 if (sym_index < s1->nb_got_offsets &&
895 s1->got_offsets[sym_index] != 0)
896 return;
898 put_got_offset(s1, sym_index, s1->got->data_offset);
900 if (s1->dynsym) {
901 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
902 name = symtab_section->link->data + sym->st_name;
903 offset = sym->st_value;
904 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
905 if (reloc_type ==
906 #ifdef TCC_TARGET_X86_64
907 R_X86_64_JUMP_SLOT
908 #else
909 R_386_JMP_SLOT
910 #endif
912 Section *plt;
913 uint8_t *p;
914 int modrm;
916 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
917 modrm = 0x25;
918 #else
919 /* if we build a DLL, we add a %ebx offset */
920 if (s1->output_type == TCC_OUTPUT_DLL)
921 modrm = 0xa3;
922 else
923 modrm = 0x25;
924 #endif
926 /* add a PLT entry */
927 plt = s1->plt;
928 if (plt->data_offset == 0) {
929 /* first plt entry */
930 p = section_ptr_add(plt, 16);
931 p[0] = 0xff; /* pushl got + PTR_SIZE */
932 p[1] = modrm + 0x10;
933 put32(p + 2, PTR_SIZE);
934 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
935 p[7] = modrm;
936 put32(p + 8, PTR_SIZE * 2);
939 p = section_ptr_add(plt, 16);
940 p[0] = 0xff; /* jmp *(got + x) */
941 p[1] = modrm;
942 put32(p + 2, s1->got->data_offset);
943 p[6] = 0x68; /* push $xxx */
944 put32(p + 7, (plt->data_offset - 32) >> 1);
945 p[11] = 0xe9; /* jmp plt_start */
946 put32(p + 12, -(plt->data_offset));
948 /* the symbol is modified so that it will be relocated to
949 the PLT */
950 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
951 if (s1->output_type == TCC_OUTPUT_EXE)
952 #endif
953 offset = plt->data_offset - 16;
955 #elif defined(TCC_TARGET_ARM)
956 if (reloc_type == R_ARM_JUMP_SLOT) {
957 Section *plt;
958 uint8_t *p;
960 /* if we build a DLL, we add a %ebx offset */
961 if (s1->output_type == TCC_OUTPUT_DLL)
962 error("DLLs unimplemented!");
964 /* add a PLT entry */
965 plt = s1->plt;
966 if (plt->data_offset == 0) {
967 /* first plt entry */
968 p = section_ptr_add(plt, 16);
969 put32(p , 0xe52de004);
970 put32(p + 4, 0xe59fe010);
971 put32(p + 8, 0xe08fe00e);
972 put32(p + 12, 0xe5bef008);
975 p = section_ptr_add(plt, 16);
976 put32(p , 0xe59fc004);
977 put32(p+4, 0xe08fc00c);
978 put32(p+8, 0xe59cf000);
979 put32(p+12, s1->got->data_offset);
981 /* the symbol is modified so that it will be relocated to
982 the PLT */
983 if (s1->output_type == TCC_OUTPUT_EXE)
984 offset = plt->data_offset - 16;
986 #elif defined(TCC_TARGET_C67)
987 error("C67 got not implemented");
988 #else
989 #error unsupported CPU
990 #endif
991 index = put_elf_sym(s1->dynsym, offset,
992 size, info, 0, sym->st_shndx, name);
993 /* put a got entry */
994 put_elf_reloc(s1->dynsym, s1->got,
995 s1->got->data_offset,
996 reloc_type, index);
998 ptr = section_ptr_add(s1->got, PTR_SIZE);
999 *ptr = 0;
1002 /* build GOT and PLT entries */
1003 static void build_got_entries(TCCState *s1)
1005 Section *s, *symtab;
1006 ElfW_Rel *rel, *rel_end;
1007 ElfW(Sym) *sym;
1008 int i, type, reloc_type, sym_index;
1010 for(i = 1; i < s1->nb_sections; i++) {
1011 s = s1->sections[i];
1012 if (s->sh_type != SHT_RELX)
1013 continue;
1014 /* no need to handle got relocations */
1015 if (s->link != symtab_section)
1016 continue;
1017 symtab = s->link;
1018 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
1019 for(rel = (ElfW_Rel *)s->data;
1020 rel < rel_end;
1021 rel++) {
1022 type = ELFW(R_TYPE)(rel->r_info);
1023 switch(type) {
1024 #if defined(TCC_TARGET_I386)
1025 case R_386_GOT32:
1026 case R_386_GOTOFF:
1027 case R_386_GOTPC:
1028 case R_386_PLT32:
1029 if (!s1->got)
1030 build_got(s1);
1031 if (type == R_386_GOT32 || type == R_386_PLT32) {
1032 sym_index = ELFW(R_SYM)(rel->r_info);
1033 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1034 /* look at the symbol got offset. If none, then add one */
1035 if (type == R_386_GOT32)
1036 reloc_type = R_386_GLOB_DAT;
1037 else
1038 reloc_type = R_386_JMP_SLOT;
1039 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1040 sym_index);
1042 break;
1043 #elif defined(TCC_TARGET_ARM)
1044 case R_ARM_GOT_BREL:
1045 case R_ARM_GOTOFF32:
1046 case R_ARM_BASE_PREL:
1047 case R_ARM_PLT32:
1048 if (!s1->got)
1049 build_got(s1);
1050 if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) {
1051 sym_index = ELFW(R_SYM)(rel->r_info);
1052 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1053 /* look at the symbol got offset. If none, then add one */
1054 if (type == R_ARM_GOT_BREL)
1055 reloc_type = R_ARM_GLOB_DAT;
1056 else
1057 reloc_type = R_ARM_JUMP_SLOT;
1058 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1059 sym_index);
1061 break;
1062 #elif defined(TCC_TARGET_C67)
1063 case R_C60_GOT32:
1064 case R_C60_GOTOFF:
1065 case R_C60_GOTPC:
1066 case R_C60_PLT32:
1067 if (!s1->got)
1068 build_got(s1);
1069 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
1070 sym_index = ELFW(R_SYM)(rel->r_info);
1071 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1072 /* look at the symbol got offset. If none, then add one */
1073 if (type == R_C60_GOT32)
1074 reloc_type = R_C60_GLOB_DAT;
1075 else
1076 reloc_type = R_C60_JMP_SLOT;
1077 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1078 sym_index);
1080 break;
1081 #elif defined(TCC_TARGET_X86_64)
1082 case R_X86_64_GOT32:
1083 case R_X86_64_GOTTPOFF:
1084 case R_X86_64_GOTPCREL:
1085 case R_X86_64_PLT32:
1086 if (!s1->got)
1087 build_got(s1);
1088 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
1089 type == R_X86_64_PLT32) {
1090 sym_index = ELFW(R_SYM)(rel->r_info);
1091 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1092 /* look at the symbol got offset. If none, then add one */
1093 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL)
1094 reloc_type = R_X86_64_GLOB_DAT;
1095 else
1096 reloc_type = R_X86_64_JUMP_SLOT;
1097 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1098 sym_index);
1100 break;
1101 #else
1102 #error unsupported CPU
1103 #endif
1104 default:
1105 break;
1111 static Section *new_symtab(TCCState *s1,
1112 const char *symtab_name, int sh_type, int sh_flags,
1113 const char *strtab_name,
1114 const char *hash_name, int hash_sh_flags)
1116 Section *symtab, *strtab, *hash;
1117 int *ptr, nb_buckets;
1119 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1120 symtab->sh_entsize = sizeof(ElfW(Sym));
1121 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1122 put_elf_str(strtab, "");
1123 symtab->link = strtab;
1124 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1126 nb_buckets = 1;
1128 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1129 hash->sh_entsize = sizeof(int);
1130 symtab->hash = hash;
1131 hash->link = symtab;
1133 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1134 ptr[0] = nb_buckets;
1135 ptr[1] = 1;
1136 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1137 return symtab;
1140 /* put dynamic tag */
1141 static void put_dt(Section *dynamic, int dt, unsigned long val)
1143 ElfW(Dyn) *dyn;
1144 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1145 dyn->d_tag = dt;
1146 dyn->d_un.d_val = val;
1149 static void add_init_array_defines(TCCState *s1, const char *section_name)
1151 Section *s;
1152 long end_offset;
1153 char sym_start[1024];
1154 char sym_end[1024];
1156 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1157 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1159 s = find_section(s1, section_name);
1160 if (!s) {
1161 end_offset = 0;
1162 s = data_section;
1163 } else {
1164 end_offset = s->data_offset;
1167 add_elf_sym(symtab_section,
1168 0, 0,
1169 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1170 s->sh_num, sym_start);
1171 add_elf_sym(symtab_section,
1172 end_offset, 0,
1173 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1174 s->sh_num, sym_end);
1177 /* add tcc runtime libraries */
1178 static void tcc_add_runtime(TCCState *s1)
1180 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1181 char buf[1024];
1182 #endif
1184 #ifdef CONFIG_TCC_BCHECK
1185 if (s1->do_bounds_check) {
1186 unsigned long *ptr;
1187 Section *init_section;
1188 unsigned char *pinit;
1189 int sym_index;
1191 /* XXX: add an object file to do that */
1192 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
1193 *ptr = 0;
1194 add_elf_sym(symtab_section, 0, 0,
1195 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1196 bounds_section->sh_num, "__bounds_start");
1197 /* add bound check code */
1198 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, "bcheck.o");
1199 tcc_add_file(s1, buf);
1200 #ifdef TCC_TARGET_I386
1201 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1202 /* add 'call __bound_init()' in .init section */
1203 init_section = find_section(s1, ".init");
1204 pinit = section_ptr_add(init_section, 5);
1205 pinit[0] = 0xe8;
1206 put32(pinit + 1, -4);
1207 sym_index = find_elf_sym(symtab_section, "__bound_init");
1208 put_elf_reloc(symtab_section, init_section,
1209 init_section->data_offset - 4, R_386_PC32, sym_index);
1211 #endif
1213 #endif
1214 /* add libc */
1215 if (!s1->nostdlib) {
1216 tcc_add_library(s1, "c");
1218 #ifdef CONFIG_USE_LIBGCC
1219 tcc_add_file(s1, CONFIG_SYSROOT "/lib/libgcc_s.so.1");
1220 #else
1221 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, "libtcc1.a");
1222 tcc_add_file(s1, buf);
1223 #endif
1225 /* add crt end if not memory output */
1226 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
1227 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1231 /* add various standard linker symbols (must be done after the
1232 sections are filled (for example after allocating common
1233 symbols)) */
1234 static void tcc_add_linker_symbols(TCCState *s1)
1236 char buf[1024];
1237 int i;
1238 Section *s;
1240 add_elf_sym(symtab_section,
1241 text_section->data_offset, 0,
1242 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1243 text_section->sh_num, "_etext");
1244 add_elf_sym(symtab_section,
1245 data_section->data_offset, 0,
1246 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1247 data_section->sh_num, "_edata");
1248 add_elf_sym(symtab_section,
1249 bss_section->data_offset, 0,
1250 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1251 bss_section->sh_num, "_end");
1252 /* horrible new standard ldscript defines */
1253 add_init_array_defines(s1, ".preinit_array");
1254 add_init_array_defines(s1, ".init_array");
1255 add_init_array_defines(s1, ".fini_array");
1257 /* add start and stop symbols for sections whose name can be
1258 expressed in C */
1259 for(i = 1; i < s1->nb_sections; i++) {
1260 s = s1->sections[i];
1261 if (s->sh_type == SHT_PROGBITS &&
1262 (s->sh_flags & SHF_ALLOC)) {
1263 const char *p;
1264 int ch;
1266 /* check if section name can be expressed in C */
1267 p = s->name;
1268 for(;;) {
1269 ch = *p;
1270 if (!ch)
1271 break;
1272 if (!isid(ch) && !isnum(ch))
1273 goto next_sec;
1274 p++;
1276 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1277 add_elf_sym(symtab_section,
1278 0, 0,
1279 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1280 s->sh_num, buf);
1281 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1282 add_elf_sym(symtab_section,
1283 s->data_offset, 0,
1284 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1285 s->sh_num, buf);
1287 next_sec: ;
1291 /* name of ELF interpreter */
1292 #if defined __FreeBSD__
1293 static const char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1294 #elif defined TCC_ARM_EABI
1295 static const char elf_interp[] = "/lib/ld-linux.so.3";
1296 #elif defined(TCC_TARGET_X86_64)
1297 static const char elf_interp[] = "/lib/ld-linux-x86-64.so.2";
1298 #elif defined(TCC_UCLIBC)
1299 static const char elf_interp[] = "/lib/ld-uClibc.so.0";
1300 #else
1301 static const char elf_interp[] = "/lib/ld-linux.so.2";
1302 #endif
1304 static void tcc_output_binary(TCCState *s1, FILE *f,
1305 const int *section_order)
1307 Section *s;
1308 int i, offset, size;
1310 offset = 0;
1311 for(i=1;i<s1->nb_sections;i++) {
1312 s = s1->sections[section_order[i]];
1313 if (s->sh_type != SHT_NOBITS &&
1314 (s->sh_flags & SHF_ALLOC)) {
1315 while (offset < s->sh_offset) {
1316 fputc(0, f);
1317 offset++;
1319 size = s->sh_size;
1320 fwrite(s->data, 1, size, f);
1321 offset += size;
1326 /* output an ELF file */
1327 /* XXX: suppress unneeded sections */
1328 int elf_output_file(TCCState *s1, const char *filename)
1330 ElfW(Ehdr) ehdr;
1331 FILE *f;
1332 int fd, mode, ret;
1333 int *section_order;
1334 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1335 unsigned long addr;
1336 Section *strsec, *s;
1337 ElfW(Shdr) shdr, *sh;
1338 ElfW(Phdr) *phdr, *ph;
1339 Section *interp, *dynamic, *dynstr;
1340 unsigned long saved_dynamic_data_offset;
1341 ElfW(Sym) *sym;
1342 int type, file_type;
1343 unsigned long rel_addr, rel_size;
1345 file_type = s1->output_type;
1346 s1->nb_errors = 0;
1348 if (file_type != TCC_OUTPUT_OBJ) {
1349 tcc_add_runtime(s1);
1352 phdr = NULL;
1353 section_order = NULL;
1354 interp = NULL;
1355 dynamic = NULL;
1356 dynstr = NULL; /* avoid warning */
1357 saved_dynamic_data_offset = 0; /* avoid warning */
1359 if (file_type != TCC_OUTPUT_OBJ) {
1360 relocate_common_syms();
1362 tcc_add_linker_symbols(s1);
1364 if (!s1->static_link) {
1365 const char *name;
1366 int sym_index, index;
1367 ElfW(Sym) *esym, *sym_end;
1369 if (file_type == TCC_OUTPUT_EXE) {
1370 char *ptr;
1371 /* add interpreter section only if executable */
1372 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1373 interp->sh_addralign = 1;
1374 ptr = section_ptr_add(interp, sizeof(elf_interp));
1375 strcpy(ptr, elf_interp);
1378 /* add dynamic symbol table */
1379 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1380 ".dynstr",
1381 ".hash", SHF_ALLOC);
1382 dynstr = s1->dynsym->link;
1384 /* add dynamic section */
1385 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1386 SHF_ALLOC | SHF_WRITE);
1387 dynamic->link = dynstr;
1388 dynamic->sh_entsize = sizeof(ElfW(Dyn));
1390 /* add PLT */
1391 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1392 SHF_ALLOC | SHF_EXECINSTR);
1393 s1->plt->sh_entsize = 4;
1395 build_got(s1);
1397 /* scan for undefined symbols and see if they are in the
1398 dynamic symbols. If a symbol STT_FUNC is found, then we
1399 add it in the PLT. If a symbol STT_OBJECT is found, we
1400 add it in the .bss section with a suitable relocation */
1401 sym_end = (ElfW(Sym) *)(symtab_section->data +
1402 symtab_section->data_offset);
1403 if (file_type == TCC_OUTPUT_EXE) {
1404 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1405 sym < sym_end;
1406 sym++) {
1407 if (sym->st_shndx == SHN_UNDEF) {
1408 name = symtab_section->link->data + sym->st_name;
1409 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1410 if (sym_index) {
1411 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1412 type = ELFW(ST_TYPE)(esym->st_info);
1413 if (type == STT_FUNC) {
1414 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1415 esym->st_info,
1416 sym - (ElfW(Sym) *)symtab_section->data);
1417 } else if (type == STT_OBJECT) {
1418 unsigned long offset;
1419 offset = bss_section->data_offset;
1420 /* XXX: which alignment ? */
1421 offset = (offset + 16 - 1) & -16;
1422 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1423 esym->st_info, 0,
1424 bss_section->sh_num, name);
1425 put_elf_reloc(s1->dynsym, bss_section,
1426 offset, R_COPY, index);
1427 offset += esym->st_size;
1428 bss_section->data_offset = offset;
1430 } else {
1431 /* STB_WEAK undefined symbols are accepted */
1432 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1433 it */
1434 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1435 !strcmp(name, "_fp_hw")) {
1436 } else {
1437 error_noabort("undefined symbol '%s'", name);
1440 } else if (s1->rdynamic &&
1441 ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1442 /* if -rdynamic option, then export all non
1443 local symbols */
1444 name = symtab_section->link->data + sym->st_name;
1445 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1446 sym->st_info, 0,
1447 sym->st_shndx, name);
1451 if (s1->nb_errors)
1452 goto fail;
1454 /* now look at unresolved dynamic symbols and export
1455 corresponding symbol */
1456 sym_end = (ElfW(Sym) *)(s1->dynsymtab_section->data +
1457 s1->dynsymtab_section->data_offset);
1458 for(esym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1;
1459 esym < sym_end;
1460 esym++) {
1461 if (esym->st_shndx == SHN_UNDEF) {
1462 name = s1->dynsymtab_section->link->data + esym->st_name;
1463 sym_index = find_elf_sym(symtab_section, name);
1464 if (sym_index) {
1465 /* XXX: avoid adding a symbol if already
1466 present because of -rdynamic ? */
1467 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1468 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1469 sym->st_info, 0,
1470 sym->st_shndx, name);
1471 } else {
1472 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1473 /* weak symbols can stay undefined */
1474 } else {
1475 warning("undefined dynamic symbol '%s'", name);
1480 } else {
1481 int nb_syms;
1482 /* shared library case : we simply export all the global symbols */
1483 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1484 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1485 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1486 sym < sym_end;
1487 sym++) {
1488 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1489 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1490 if (ELFW(ST_TYPE)(sym->st_info) == STT_FUNC &&
1491 sym->st_shndx == SHN_UNDEF) {
1492 put_got_entry(s1, R_JMP_SLOT, sym->st_size,
1493 sym->st_info,
1494 sym - (ElfW(Sym) *)symtab_section->data);
1496 else if (ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT) {
1497 put_got_entry(s1, R_X86_64_GLOB_DAT, sym->st_size,
1498 sym->st_info,
1499 sym - (ElfW(Sym) *)symtab_section->data);
1501 else
1502 #endif
1504 name = symtab_section->link->data + sym->st_name;
1505 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1506 sym->st_info, 0,
1507 sym->st_shndx, name);
1508 s1->symtab_to_dynsym[sym -
1509 (ElfW(Sym) *)symtab_section->data] =
1510 index;
1516 build_got_entries(s1);
1518 /* add a list of needed dlls */
1519 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1520 DLLReference *dllref = s1->loaded_dlls[i];
1521 if (dllref->level == 0)
1522 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1524 /* XXX: currently, since we do not handle PIC code, we
1525 must relocate the readonly segments */
1526 if (file_type == TCC_OUTPUT_DLL) {
1527 if (s1->soname)
1528 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
1529 put_dt(dynamic, DT_TEXTREL, 0);
1532 /* add necessary space for other entries */
1533 saved_dynamic_data_offset = dynamic->data_offset;
1534 dynamic->data_offset += sizeof(ElfW(Dyn)) * 9;
1535 } else {
1536 /* still need to build got entries in case of static link */
1537 build_got_entries(s1);
1541 memset(&ehdr, 0, sizeof(ehdr));
1543 /* we add a section for symbols */
1544 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1545 put_elf_str(strsec, "");
1547 /* compute number of sections */
1548 shnum = s1->nb_sections;
1550 /* this array is used to reorder sections in the output file */
1551 section_order = tcc_malloc(sizeof(int) * shnum);
1552 section_order[0] = 0;
1553 sh_order_index = 1;
1555 /* compute number of program headers */
1556 switch(file_type) {
1557 default:
1558 case TCC_OUTPUT_OBJ:
1559 phnum = 0;
1560 break;
1561 case TCC_OUTPUT_EXE:
1562 if (!s1->static_link)
1563 phnum = 4;
1564 else
1565 phnum = 2;
1566 break;
1567 case TCC_OUTPUT_DLL:
1568 phnum = 3;
1569 break;
1572 /* allocate strings for section names and decide if an unallocated
1573 section should be output */
1574 /* NOTE: the strsec section comes last, so its size is also
1575 correct ! */
1576 for(i = 1; i < s1->nb_sections; i++) {
1577 s = s1->sections[i];
1578 s->sh_name = put_elf_str(strsec, s->name);
1579 #if 0 //gr
1580 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1581 s->sh_flags,
1582 s->sh_type,
1583 s->sh_info,
1584 s->name,
1585 s->reloc ? s->reloc->name : "n"
1587 #endif
1588 /* when generating a DLL, we include relocations but we may
1589 patch them */
1590 if (file_type == TCC_OUTPUT_DLL &&
1591 s->sh_type == SHT_RELX &&
1592 !(s->sh_flags & SHF_ALLOC)) {
1593 /* //gr: avoid bogus relocs for empty (debug) sections */
1594 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1595 prepare_dynamic_rel(s1, s);
1596 else if (s1->do_debug)
1597 s->sh_size = s->data_offset;
1598 } else if (s1->do_debug ||
1599 file_type == TCC_OUTPUT_OBJ ||
1600 (s->sh_flags & SHF_ALLOC) ||
1601 i == (s1->nb_sections - 1)) {
1602 /* we output all sections if debug or object file */
1603 s->sh_size = s->data_offset;
1607 /* allocate program segment headers */
1608 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
1610 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1611 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1612 } else {
1613 file_offset = 0;
1615 if (phnum > 0) {
1616 /* compute section to program header mapping */
1617 if (s1->has_text_addr) {
1618 int a_offset, p_offset;
1619 addr = s1->text_addr;
1620 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1621 ELF_PAGE_SIZE */
1622 a_offset = addr & (ELF_PAGE_SIZE - 1);
1623 p_offset = file_offset & (ELF_PAGE_SIZE - 1);
1624 if (a_offset < p_offset)
1625 a_offset += ELF_PAGE_SIZE;
1626 file_offset += (a_offset - p_offset);
1627 } else {
1628 if (file_type == TCC_OUTPUT_DLL)
1629 addr = 0;
1630 else
1631 addr = ELF_START_ADDR;
1632 /* compute address after headers */
1633 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1636 /* dynamic relocation table information, for .dynamic section */
1637 rel_size = 0;
1638 rel_addr = 0;
1640 /* leave one program header for the program interpreter */
1641 ph = &phdr[0];
1642 if (interp)
1643 ph++;
1645 for(j = 0; j < 2; j++) {
1646 ph->p_type = PT_LOAD;
1647 if (j == 0)
1648 ph->p_flags = PF_R | PF_X;
1649 else
1650 ph->p_flags = PF_R | PF_W;
1651 ph->p_align = ELF_PAGE_SIZE;
1653 /* we do the following ordering: interp, symbol tables,
1654 relocations, progbits, nobits */
1655 /* XXX: do faster and simpler sorting */
1656 for(k = 0; k < 5; k++) {
1657 for(i = 1; i < s1->nb_sections; i++) {
1658 s = s1->sections[i];
1659 /* compute if section should be included */
1660 if (j == 0) {
1661 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1662 SHF_ALLOC)
1663 continue;
1664 } else {
1665 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1666 (SHF_ALLOC | SHF_WRITE))
1667 continue;
1669 if (s == interp) {
1670 if (k != 0)
1671 continue;
1672 } else if (s->sh_type == SHT_DYNSYM ||
1673 s->sh_type == SHT_STRTAB ||
1674 s->sh_type == SHT_HASH) {
1675 if (k != 1)
1676 continue;
1677 } else if (s->sh_type == SHT_RELX) {
1678 if (k != 2)
1679 continue;
1680 } else if (s->sh_type == SHT_NOBITS) {
1681 if (k != 4)
1682 continue;
1683 } else {
1684 if (k != 3)
1685 continue;
1687 section_order[sh_order_index++] = i;
1689 /* section matches: we align it and add its size */
1690 tmp = addr;
1691 addr = (addr + s->sh_addralign - 1) &
1692 ~(s->sh_addralign - 1);
1693 file_offset += addr - tmp;
1694 s->sh_offset = file_offset;
1695 s->sh_addr = addr;
1697 /* update program header infos */
1698 if (ph->p_offset == 0) {
1699 ph->p_offset = file_offset;
1700 ph->p_vaddr = addr;
1701 ph->p_paddr = ph->p_vaddr;
1703 /* update dynamic relocation infos */
1704 if (s->sh_type == SHT_RELX) {
1705 if (rel_size == 0)
1706 rel_addr = addr;
1707 rel_size += s->sh_size;
1709 addr += s->sh_size;
1710 if (s->sh_type != SHT_NOBITS)
1711 file_offset += s->sh_size;
1714 ph->p_filesz = file_offset - ph->p_offset;
1715 ph->p_memsz = addr - ph->p_vaddr;
1716 ph++;
1717 if (j == 0) {
1718 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1719 /* if in the middle of a page, we duplicate the page in
1720 memory so that one copy is RX and the other is RW */
1721 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1722 addr += ELF_PAGE_SIZE;
1723 } else {
1724 addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
1725 file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
1726 ~(ELF_PAGE_SIZE - 1);
1731 /* if interpreter, then add corresponing program header */
1732 if (interp) {
1733 ph = &phdr[0];
1735 ph->p_type = PT_INTERP;
1736 ph->p_offset = interp->sh_offset;
1737 ph->p_vaddr = interp->sh_addr;
1738 ph->p_paddr = ph->p_vaddr;
1739 ph->p_filesz = interp->sh_size;
1740 ph->p_memsz = interp->sh_size;
1741 ph->p_flags = PF_R;
1742 ph->p_align = interp->sh_addralign;
1745 /* if dynamic section, then add corresponing program header */
1746 if (dynamic) {
1747 ElfW(Sym) *sym_end;
1749 ph = &phdr[phnum - 1];
1751 ph->p_type = PT_DYNAMIC;
1752 ph->p_offset = dynamic->sh_offset;
1753 ph->p_vaddr = dynamic->sh_addr;
1754 ph->p_paddr = ph->p_vaddr;
1755 ph->p_filesz = dynamic->sh_size;
1756 ph->p_memsz = dynamic->sh_size;
1757 ph->p_flags = PF_R | PF_W;
1758 ph->p_align = dynamic->sh_addralign;
1760 /* put GOT dynamic section address */
1761 put32(s1->got->data, dynamic->sh_addr);
1763 /* relocate the PLT */
1764 if (file_type == TCC_OUTPUT_EXE
1765 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1766 || file_type == TCC_OUTPUT_DLL
1767 #endif
1769 uint8_t *p, *p_end;
1771 p = s1->plt->data;
1772 p_end = p + s1->plt->data_offset;
1773 if (p < p_end) {
1774 #if defined(TCC_TARGET_I386)
1775 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1776 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1777 p += 16;
1778 while (p < p_end) {
1779 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1780 p += 16;
1782 #elif defined(TCC_TARGET_X86_64)
1783 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
1784 put32(p + 2, get32(p + 2) + x);
1785 put32(p + 8, get32(p + 8) + x - 6);
1786 p += 16;
1787 while (p < p_end) {
1788 put32(p + 2, get32(p + 2) + x + s1->plt->data - p);
1789 p += 16;
1791 #elif defined(TCC_TARGET_ARM)
1792 int x;
1793 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1794 p +=16;
1795 while (p < p_end) {
1796 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1797 p += 16;
1799 #elif defined(TCC_TARGET_C67)
1800 /* XXX: TODO */
1801 #else
1802 #error unsupported CPU
1803 #endif
1807 /* relocate symbols in .dynsym */
1808 sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset);
1809 for(sym = (ElfW(Sym) *)s1->dynsym->data + 1;
1810 sym < sym_end;
1811 sym++) {
1812 if (sym->st_shndx == SHN_UNDEF) {
1813 /* relocate to the PLT if the symbol corresponds
1814 to a PLT entry */
1815 if (sym->st_value)
1816 sym->st_value += s1->plt->sh_addr;
1817 } else if (sym->st_shndx < SHN_LORESERVE) {
1818 /* do symbol relocation */
1819 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1823 /* put dynamic section entries */
1824 dynamic->data_offset = saved_dynamic_data_offset;
1825 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1826 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1827 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1828 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1829 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1830 #ifdef TCC_TARGET_X86_64
1831 put_dt(dynamic, DT_RELA, rel_addr);
1832 put_dt(dynamic, DT_RELASZ, rel_size);
1833 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
1834 #else
1835 put_dt(dynamic, DT_REL, rel_addr);
1836 put_dt(dynamic, DT_RELSZ, rel_size);
1837 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1838 #endif
1839 if (s1->do_debug)
1840 put_dt(dynamic, DT_DEBUG, 0);
1841 put_dt(dynamic, DT_NULL, 0);
1844 ehdr.e_phentsize = sizeof(ElfW(Phdr));
1845 ehdr.e_phnum = phnum;
1846 ehdr.e_phoff = sizeof(ElfW(Ehdr));
1849 /* all other sections come after */
1850 for(i = 1; i < s1->nb_sections; i++) {
1851 s = s1->sections[i];
1852 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1853 continue;
1854 section_order[sh_order_index++] = i;
1856 file_offset = (file_offset + s->sh_addralign - 1) &
1857 ~(s->sh_addralign - 1);
1858 s->sh_offset = file_offset;
1859 if (s->sh_type != SHT_NOBITS)
1860 file_offset += s->sh_size;
1863 /* if building executable or DLL, then relocate each section
1864 except the GOT which is already relocated */
1865 if (file_type != TCC_OUTPUT_OBJ) {
1866 relocate_syms(s1, 0);
1868 if (s1->nb_errors != 0) {
1869 fail:
1870 ret = -1;
1871 goto the_end;
1874 /* relocate sections */
1875 /* XXX: ignore sections with allocated relocations ? */
1876 for(i = 1; i < s1->nb_sections; i++) {
1877 s = s1->sections[i];
1878 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
1879 relocate_section(s1, s);
1882 /* relocate relocation entries if the relocation tables are
1883 allocated in the executable */
1884 for(i = 1; i < s1->nb_sections; i++) {
1885 s = s1->sections[i];
1886 if ((s->sh_flags & SHF_ALLOC) &&
1887 s->sh_type == SHT_RELX) {
1888 relocate_rel(s1, s);
1892 /* get entry point address */
1893 if (file_type == TCC_OUTPUT_EXE)
1894 ehdr.e_entry = (uplong)tcc_get_symbol_err(s1, "_start");
1895 else
1896 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1899 /* write elf file */
1900 if (file_type == TCC_OUTPUT_OBJ)
1901 mode = 0666;
1902 else
1903 mode = 0777;
1904 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1905 if (fd < 0) {
1906 error_noabort("could not write '%s'", filename);
1907 goto fail;
1909 f = fdopen(fd, "wb");
1910 if (s1->verbose)
1911 printf("<- %s\n", filename);
1913 #ifdef TCC_TARGET_COFF
1914 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1915 tcc_output_coff(s1, f);
1916 } else
1917 #endif
1918 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1919 sort_syms(s1, symtab_section);
1921 /* align to 4 */
1922 file_offset = (file_offset + 3) & -4;
1924 /* fill header */
1925 ehdr.e_ident[0] = ELFMAG0;
1926 ehdr.e_ident[1] = ELFMAG1;
1927 ehdr.e_ident[2] = ELFMAG2;
1928 ehdr.e_ident[3] = ELFMAG3;
1929 ehdr.e_ident[4] = TCC_ELFCLASS;
1930 ehdr.e_ident[5] = ELFDATA2LSB;
1931 ehdr.e_ident[6] = EV_CURRENT;
1932 #ifdef __FreeBSD__
1933 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1934 #endif
1935 #ifdef TCC_TARGET_ARM
1936 #ifdef TCC_ARM_EABI
1937 ehdr.e_ident[EI_OSABI] = 0;
1938 ehdr.e_flags = 4 << 24;
1939 #else
1940 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1941 #endif
1942 #endif
1943 switch(file_type) {
1944 default:
1945 case TCC_OUTPUT_EXE:
1946 ehdr.e_type = ET_EXEC;
1947 break;
1948 case TCC_OUTPUT_DLL:
1949 ehdr.e_type = ET_DYN;
1950 break;
1951 case TCC_OUTPUT_OBJ:
1952 ehdr.e_type = ET_REL;
1953 break;
1955 ehdr.e_machine = EM_TCC_TARGET;
1956 ehdr.e_version = EV_CURRENT;
1957 ehdr.e_shoff = file_offset;
1958 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
1959 ehdr.e_shentsize = sizeof(ElfW(Shdr));
1960 ehdr.e_shnum = shnum;
1961 ehdr.e_shstrndx = shnum - 1;
1963 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
1964 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
1965 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1967 for(i=1;i<s1->nb_sections;i++) {
1968 s = s1->sections[section_order[i]];
1969 if (s->sh_type != SHT_NOBITS) {
1970 while (offset < s->sh_offset) {
1971 fputc(0, f);
1972 offset++;
1974 size = s->sh_size;
1975 fwrite(s->data, 1, size, f);
1976 offset += size;
1980 /* output section headers */
1981 while (offset < ehdr.e_shoff) {
1982 fputc(0, f);
1983 offset++;
1986 for(i=0;i<s1->nb_sections;i++) {
1987 sh = &shdr;
1988 memset(sh, 0, sizeof(ElfW(Shdr)));
1989 s = s1->sections[i];
1990 if (s) {
1991 sh->sh_name = s->sh_name;
1992 sh->sh_type = s->sh_type;
1993 sh->sh_flags = s->sh_flags;
1994 sh->sh_entsize = s->sh_entsize;
1995 sh->sh_info = s->sh_info;
1996 if (s->link)
1997 sh->sh_link = s->link->sh_num;
1998 sh->sh_addralign = s->sh_addralign;
1999 sh->sh_addr = s->sh_addr;
2000 sh->sh_offset = s->sh_offset;
2001 sh->sh_size = s->sh_size;
2003 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2005 } else {
2006 tcc_output_binary(s1, f, section_order);
2008 fclose(f);
2010 ret = 0;
2011 the_end:
2012 tcc_free(s1->symtab_to_dynsym);
2013 tcc_free(section_order);
2014 tcc_free(phdr);
2015 tcc_free(s1->got_offsets);
2016 return ret;
2019 int tcc_output_file(TCCState *s, const char *filename)
2021 int ret;
2022 #ifdef TCC_TARGET_PE
2023 if (s->output_type != TCC_OUTPUT_OBJ) {
2024 ret = pe_output_file(s, filename);
2025 } else
2026 #endif
2028 ret = elf_output_file(s, filename);
2030 return ret;
2033 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2035 void *data;
2037 data = tcc_malloc(size);
2038 lseek(fd, file_offset, SEEK_SET);
2039 read(fd, data, size);
2040 return data;
2043 typedef struct SectionMergeInfo {
2044 Section *s; /* corresponding existing section */
2045 unsigned long offset; /* offset of the new section in the existing section */
2046 uint8_t new_section; /* true if section 's' was added */
2047 uint8_t link_once; /* true if link once section */
2048 } SectionMergeInfo;
2050 /* load an object file and merge it with current files */
2051 /* XXX: handle correctly stab (debug) info */
2052 static int tcc_load_object_file(TCCState *s1,
2053 int fd, unsigned long file_offset)
2055 ElfW(Ehdr) ehdr;
2056 ElfW(Shdr) *shdr, *sh;
2057 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2058 unsigned char *strsec, *strtab;
2059 int *old_to_new_syms;
2060 char *sh_name, *name;
2061 SectionMergeInfo *sm_table, *sm;
2062 ElfW(Sym) *sym, *symtab;
2063 ElfW_Rel *rel, *rel_end;
2064 Section *s;
2066 int stab_index;
2067 int stabstr_index;
2069 stab_index = stabstr_index = 0;
2071 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
2072 goto fail1;
2073 if (ehdr.e_ident[0] != ELFMAG0 ||
2074 ehdr.e_ident[1] != ELFMAG1 ||
2075 ehdr.e_ident[2] != ELFMAG2 ||
2076 ehdr.e_ident[3] != ELFMAG3)
2077 goto fail1;
2078 /* test if object file */
2079 if (ehdr.e_type != ET_REL)
2080 goto fail1;
2081 /* test CPU specific stuff */
2082 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2083 ehdr.e_machine != EM_TCC_TARGET) {
2084 fail1:
2085 error_noabort("invalid object file");
2086 return -1;
2088 /* read sections */
2089 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2090 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2091 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2093 /* load section names */
2094 sh = &shdr[ehdr.e_shstrndx];
2095 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2097 /* load symtab and strtab */
2098 old_to_new_syms = NULL;
2099 symtab = NULL;
2100 strtab = NULL;
2101 nb_syms = 0;
2102 for(i = 1; i < ehdr.e_shnum; i++) {
2103 sh = &shdr[i];
2104 if (sh->sh_type == SHT_SYMTAB) {
2105 if (symtab) {
2106 error_noabort("object must contain only one symtab");
2107 fail:
2108 ret = -1;
2109 goto the_end;
2111 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2112 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2113 sm_table[i].s = symtab_section;
2115 /* now load strtab */
2116 sh = &shdr[sh->sh_link];
2117 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2121 /* now examine each section and try to merge its content with the
2122 ones in memory */
2123 for(i = 1; i < ehdr.e_shnum; i++) {
2124 /* no need to examine section name strtab */
2125 if (i == ehdr.e_shstrndx)
2126 continue;
2127 sh = &shdr[i];
2128 sh_name = strsec + sh->sh_name;
2129 /* ignore sections types we do not handle */
2130 if (sh->sh_type != SHT_PROGBITS &&
2131 sh->sh_type != SHT_RELX &&
2132 #ifdef TCC_ARM_EABI
2133 sh->sh_type != SHT_ARM_EXIDX &&
2134 #endif
2135 sh->sh_type != SHT_NOBITS &&
2136 strcmp(sh_name, ".stabstr")
2138 continue;
2139 if (sh->sh_addralign < 1)
2140 sh->sh_addralign = 1;
2141 /* find corresponding section, if any */
2142 for(j = 1; j < s1->nb_sections;j++) {
2143 s = s1->sections[j];
2144 if (!strcmp(s->name, sh_name)) {
2145 if (!strncmp(sh_name, ".gnu.linkonce",
2146 sizeof(".gnu.linkonce") - 1)) {
2147 /* if a 'linkonce' section is already present, we
2148 do not add it again. It is a little tricky as
2149 symbols can still be defined in
2150 it. */
2151 sm_table[i].link_once = 1;
2152 goto next;
2153 } else {
2154 goto found;
2158 /* not found: create new section */
2159 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
2160 /* take as much info as possible from the section. sh_link and
2161 sh_info will be updated later */
2162 s->sh_addralign = sh->sh_addralign;
2163 s->sh_entsize = sh->sh_entsize;
2164 sm_table[i].new_section = 1;
2165 found:
2166 if (sh->sh_type != s->sh_type) {
2167 error_noabort("invalid section type");
2168 goto fail;
2171 /* align start of section */
2172 offset = s->data_offset;
2174 if (0 == strcmp(sh_name, ".stab")) {
2175 stab_index = i;
2176 goto no_align;
2178 if (0 == strcmp(sh_name, ".stabstr")) {
2179 stabstr_index = i;
2180 goto no_align;
2183 size = sh->sh_addralign - 1;
2184 offset = (offset + size) & ~size;
2185 if (sh->sh_addralign > s->sh_addralign)
2186 s->sh_addralign = sh->sh_addralign;
2187 s->data_offset = offset;
2188 no_align:
2189 sm_table[i].offset = offset;
2190 sm_table[i].s = s;
2191 /* concatenate sections */
2192 size = sh->sh_size;
2193 if (sh->sh_type != SHT_NOBITS) {
2194 unsigned char *ptr;
2195 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2196 ptr = section_ptr_add(s, size);
2197 read(fd, ptr, size);
2198 } else {
2199 s->data_offset += size;
2201 next: ;
2204 /* //gr relocate stab strings */
2205 if (stab_index && stabstr_index) {
2206 Stab_Sym *a, *b;
2207 unsigned o;
2208 s = sm_table[stab_index].s;
2209 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2210 b = (Stab_Sym *)(s->data + s->data_offset);
2211 o = sm_table[stabstr_index].offset;
2212 while (a < b)
2213 a->n_strx += o, a++;
2216 /* second short pass to update sh_link and sh_info fields of new
2217 sections */
2218 for(i = 1; i < ehdr.e_shnum; i++) {
2219 s = sm_table[i].s;
2220 if (!s || !sm_table[i].new_section)
2221 continue;
2222 sh = &shdr[i];
2223 if (sh->sh_link > 0)
2224 s->link = sm_table[sh->sh_link].s;
2225 if (sh->sh_type == SHT_RELX) {
2226 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2227 /* update backward link */
2228 s1->sections[s->sh_info]->reloc = s;
2231 sm = sm_table;
2233 /* resolve symbols */
2234 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2236 sym = symtab + 1;
2237 for(i = 1; i < nb_syms; i++, sym++) {
2238 if (sym->st_shndx != SHN_UNDEF &&
2239 sym->st_shndx < SHN_LORESERVE) {
2240 sm = &sm_table[sym->st_shndx];
2241 if (sm->link_once) {
2242 /* if a symbol is in a link once section, we use the
2243 already defined symbol. It is very important to get
2244 correct relocations */
2245 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2246 name = strtab + sym->st_name;
2247 sym_index = find_elf_sym(symtab_section, name);
2248 if (sym_index)
2249 old_to_new_syms[i] = sym_index;
2251 continue;
2253 /* if no corresponding section added, no need to add symbol */
2254 if (!sm->s)
2255 continue;
2256 /* convert section number */
2257 sym->st_shndx = sm->s->sh_num;
2258 /* offset value */
2259 sym->st_value += sm->offset;
2261 /* add symbol */
2262 name = strtab + sym->st_name;
2263 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
2264 sym->st_info, sym->st_other,
2265 sym->st_shndx, name);
2266 old_to_new_syms[i] = sym_index;
2269 /* third pass to patch relocation entries */
2270 for(i = 1; i < ehdr.e_shnum; i++) {
2271 s = sm_table[i].s;
2272 if (!s)
2273 continue;
2274 sh = &shdr[i];
2275 offset = sm_table[i].offset;
2276 switch(s->sh_type) {
2277 case SHT_RELX:
2278 /* take relocation offset information */
2279 offseti = sm_table[sh->sh_info].offset;
2280 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
2281 for(rel = (ElfW_Rel *)(s->data + offset);
2282 rel < rel_end;
2283 rel++) {
2284 int type;
2285 unsigned sym_index;
2286 /* convert symbol index */
2287 type = ELFW(R_TYPE)(rel->r_info);
2288 sym_index = ELFW(R_SYM)(rel->r_info);
2289 /* NOTE: only one symtab assumed */
2290 if (sym_index >= nb_syms)
2291 goto invalid_reloc;
2292 sym_index = old_to_new_syms[sym_index];
2293 /* ignore link_once in rel section. */
2294 if (!sym_index && !sm->link_once) {
2295 invalid_reloc:
2296 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2297 i, strsec + sh->sh_name, rel->r_offset);
2298 goto fail;
2300 rel->r_info = ELFW(R_INFO)(sym_index, type);
2301 /* offset the relocation offset */
2302 rel->r_offset += offseti;
2304 break;
2305 default:
2306 break;
2310 ret = 0;
2311 the_end:
2312 tcc_free(symtab);
2313 tcc_free(strtab);
2314 tcc_free(old_to_new_syms);
2315 tcc_free(sm_table);
2316 tcc_free(strsec);
2317 tcc_free(shdr);
2318 return ret;
2321 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2323 typedef struct ArchiveHeader {
2324 char ar_name[16]; /* name of this member */
2325 char ar_date[12]; /* file mtime */
2326 char ar_uid[6]; /* owner uid; printed as decimal */
2327 char ar_gid[6]; /* owner gid; printed as decimal */
2328 char ar_mode[8]; /* file mode, printed as octal */
2329 char ar_size[10]; /* file size, printed as decimal */
2330 char ar_fmag[2]; /* should contain ARFMAG */
2331 } ArchiveHeader;
2333 static int get_be32(const uint8_t *b)
2335 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2338 /* load only the objects which resolve undefined symbols */
2339 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
2341 int i, bound, nsyms, sym_index, off, ret;
2342 uint8_t *data;
2343 const char *ar_names, *p;
2344 const uint8_t *ar_index;
2345 ElfW(Sym) *sym;
2347 data = tcc_malloc(size);
2348 if (read(fd, data, size) != size)
2349 goto fail;
2350 nsyms = get_be32(data);
2351 ar_index = data + 4;
2352 ar_names = ar_index + nsyms * 4;
2354 do {
2355 bound = 0;
2356 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2357 sym_index = find_elf_sym(symtab_section, p);
2358 if(sym_index) {
2359 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2360 if(sym->st_shndx == SHN_UNDEF) {
2361 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2362 #if 0
2363 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2364 #endif
2365 ++bound;
2366 lseek(fd, off, SEEK_SET);
2367 if(tcc_load_object_file(s1, fd, off) < 0) {
2368 fail:
2369 ret = -1;
2370 goto the_end;
2375 } while(bound);
2376 ret = 0;
2377 the_end:
2378 tcc_free(data);
2379 return ret;
2382 /* load a '.a' file */
2383 static int tcc_load_archive(TCCState *s1, int fd)
2385 ArchiveHeader hdr;
2386 char ar_size[11];
2387 char ar_name[17];
2388 char magic[8];
2389 int size, len, i;
2390 unsigned long file_offset;
2392 /* skip magic which was already checked */
2393 read(fd, magic, sizeof(magic));
2395 for(;;) {
2396 len = read(fd, &hdr, sizeof(hdr));
2397 if (len == 0)
2398 break;
2399 if (len != sizeof(hdr)) {
2400 error_noabort("invalid archive");
2401 return -1;
2403 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2404 ar_size[sizeof(hdr.ar_size)] = '\0';
2405 size = strtol(ar_size, NULL, 0);
2406 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2407 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2408 if (ar_name[i] != ' ')
2409 break;
2411 ar_name[i + 1] = '\0';
2412 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2413 file_offset = lseek(fd, 0, SEEK_CUR);
2414 /* align to even */
2415 size = (size + 1) & ~1;
2416 if (!strcmp(ar_name, "/")) {
2417 /* coff symbol table : we handle it */
2418 if(s1->alacarte_link)
2419 return tcc_load_alacarte(s1, fd, size);
2420 } else if (!strcmp(ar_name, "//") ||
2421 !strcmp(ar_name, "__.SYMDEF") ||
2422 !strcmp(ar_name, "__.SYMDEF/") ||
2423 !strcmp(ar_name, "ARFILENAMES/")) {
2424 /* skip symbol table or archive names */
2425 } else {
2426 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2427 return -1;
2429 lseek(fd, file_offset + size, SEEK_SET);
2431 return 0;
2434 #ifndef TCC_TARGET_PE
2435 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2436 is referenced by the user (so it should be added as DT_NEEDED in
2437 the generated ELF file) */
2438 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2440 ElfW(Ehdr) ehdr;
2441 ElfW(Shdr) *shdr, *sh, *sh1;
2442 int i, j, nb_syms, nb_dts, sym_bind, ret;
2443 ElfW(Sym) *sym, *dynsym;
2444 ElfW(Dyn) *dt, *dynamic;
2445 unsigned char *dynstr;
2446 const char *name, *soname;
2447 DLLReference *dllref;
2449 read(fd, &ehdr, sizeof(ehdr));
2451 /* test CPU specific stuff */
2452 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2453 ehdr.e_machine != EM_TCC_TARGET) {
2454 error_noabort("bad architecture");
2455 return -1;
2458 /* read sections */
2459 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2461 /* load dynamic section and dynamic symbols */
2462 nb_syms = 0;
2463 nb_dts = 0;
2464 dynamic = NULL;
2465 dynsym = NULL; /* avoid warning */
2466 dynstr = NULL; /* avoid warning */
2467 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2468 switch(sh->sh_type) {
2469 case SHT_DYNAMIC:
2470 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2471 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2472 break;
2473 case SHT_DYNSYM:
2474 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2475 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2476 sh1 = &shdr[sh->sh_link];
2477 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2478 break;
2479 default:
2480 break;
2484 /* compute the real library name */
2485 soname = tcc_basename(filename);
2487 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2488 if (dt->d_tag == DT_SONAME) {
2489 soname = dynstr + dt->d_un.d_val;
2493 /* if the dll is already loaded, do not load it */
2494 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2495 dllref = s1->loaded_dlls[i];
2496 if (!strcmp(soname, dllref->name)) {
2497 /* but update level if needed */
2498 if (level < dllref->level)
2499 dllref->level = level;
2500 ret = 0;
2501 goto the_end;
2505 // printf("loading dll '%s'\n", soname);
2507 /* add the dll and its level */
2508 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2509 dllref->level = level;
2510 strcpy(dllref->name, soname);
2511 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2513 /* add dynamic symbols in dynsym_section */
2514 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2515 sym_bind = ELFW(ST_BIND)(sym->st_info);
2516 if (sym_bind == STB_LOCAL)
2517 continue;
2518 name = dynstr + sym->st_name;
2519 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2520 sym->st_info, sym->st_other, sym->st_shndx, name);
2523 /* load all referenced DLLs */
2524 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2525 switch(dt->d_tag) {
2526 case DT_NEEDED:
2527 name = dynstr + dt->d_un.d_val;
2528 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2529 dllref = s1->loaded_dlls[j];
2530 if (!strcmp(name, dllref->name))
2531 goto already_loaded;
2533 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2534 error_noabort("referenced dll '%s' not found", name);
2535 ret = -1;
2536 goto the_end;
2538 already_loaded:
2539 break;
2542 ret = 0;
2543 the_end:
2544 tcc_free(dynstr);
2545 tcc_free(dynsym);
2546 tcc_free(dynamic);
2547 tcc_free(shdr);
2548 return ret;
2551 #define LD_TOK_NAME 256
2552 #define LD_TOK_EOF (-1)
2554 /* return next ld script token */
2555 static int ld_next(TCCState *s1, char *name, int name_size)
2557 int c;
2558 char *q;
2560 redo:
2561 switch(ch) {
2562 case ' ':
2563 case '\t':
2564 case '\f':
2565 case '\v':
2566 case '\r':
2567 case '\n':
2568 inp();
2569 goto redo;
2570 case '/':
2571 minp();
2572 if (ch == '*') {
2573 file->buf_ptr = parse_comment(file->buf_ptr);
2574 ch = file->buf_ptr[0];
2575 goto redo;
2576 } else {
2577 q = name;
2578 *q++ = '/';
2579 goto parse_name;
2581 break;
2582 /* case 'a' ... 'z': */
2583 case 'a':
2584 case 'b':
2585 case 'c':
2586 case 'd':
2587 case 'e':
2588 case 'f':
2589 case 'g':
2590 case 'h':
2591 case 'i':
2592 case 'j':
2593 case 'k':
2594 case 'l':
2595 case 'm':
2596 case 'n':
2597 case 'o':
2598 case 'p':
2599 case 'q':
2600 case 'r':
2601 case 's':
2602 case 't':
2603 case 'u':
2604 case 'v':
2605 case 'w':
2606 case 'x':
2607 case 'y':
2608 case 'z':
2609 /* case 'A' ... 'z': */
2610 case 'A':
2611 case 'B':
2612 case 'C':
2613 case 'D':
2614 case 'E':
2615 case 'F':
2616 case 'G':
2617 case 'H':
2618 case 'I':
2619 case 'J':
2620 case 'K':
2621 case 'L':
2622 case 'M':
2623 case 'N':
2624 case 'O':
2625 case 'P':
2626 case 'Q':
2627 case 'R':
2628 case 'S':
2629 case 'T':
2630 case 'U':
2631 case 'V':
2632 case 'W':
2633 case 'X':
2634 case 'Y':
2635 case 'Z':
2636 case '_':
2637 case '\\':
2638 case '.':
2639 case '$':
2640 case '~':
2641 q = name;
2642 parse_name:
2643 for(;;) {
2644 if (!((ch >= 'a' && ch <= 'z') ||
2645 (ch >= 'A' && ch <= 'Z') ||
2646 (ch >= '0' && ch <= '9') ||
2647 strchr("/.-_+=$:\\,~", ch)))
2648 break;
2649 if ((q - name) < name_size - 1) {
2650 *q++ = ch;
2652 minp();
2654 *q = '\0';
2655 c = LD_TOK_NAME;
2656 break;
2657 case CH_EOF:
2658 c = LD_TOK_EOF;
2659 break;
2660 default:
2661 c = ch;
2662 inp();
2663 break;
2665 #if 0
2666 printf("tok=%c %d\n", c, c);
2667 if (c == LD_TOK_NAME)
2668 printf(" name=%s\n", name);
2669 #endif
2670 return c;
2673 static int ld_add_file_list(TCCState *s1, int as_needed)
2675 char filename[1024];
2676 int t, ret;
2678 t = ld_next(s1, filename, sizeof(filename));
2679 if (t != '(')
2680 expect("(");
2681 t = ld_next(s1, filename, sizeof(filename));
2682 for(;;) {
2683 if (t == LD_TOK_EOF) {
2684 error_noabort("unexpected end of file");
2685 return -1;
2686 } else if (t == ')') {
2687 break;
2688 } else if (t != LD_TOK_NAME) {
2689 error_noabort("filename expected");
2690 return -1;
2692 if (!strcmp(filename, "AS_NEEDED")) {
2693 ret = ld_add_file_list(s1, 1);
2694 if (ret)
2695 return ret;
2696 } else {
2697 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2698 if (!as_needed)
2699 tcc_add_file(s1, filename);
2701 t = ld_next(s1, filename, sizeof(filename));
2702 if (t == ',') {
2703 t = ld_next(s1, filename, sizeof(filename));
2706 return 0;
2709 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2710 files */
2711 static int tcc_load_ldscript(TCCState *s1)
2713 char cmd[64];
2714 char filename[1024];
2715 int t, ret;
2717 ch = file->buf_ptr[0];
2718 ch = handle_eob();
2719 for(;;) {
2720 t = ld_next(s1, cmd, sizeof(cmd));
2721 if (t == LD_TOK_EOF)
2722 return 0;
2723 else if (t != LD_TOK_NAME)
2724 return -1;
2725 if (!strcmp(cmd, "INPUT") ||
2726 !strcmp(cmd, "GROUP")) {
2727 ret = ld_add_file_list(s1, 0);
2728 if (ret)
2729 return ret;
2730 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2731 !strcmp(cmd, "TARGET")) {
2732 /* ignore some commands */
2733 t = ld_next(s1, cmd, sizeof(cmd));
2734 if (t != '(')
2735 expect("(");
2736 for(;;) {
2737 t = ld_next(s1, filename, sizeof(filename));
2738 if (t == LD_TOK_EOF) {
2739 error_noabort("unexpected end of file");
2740 return -1;
2741 } else if (t == ')') {
2742 break;
2745 } else {
2746 return -1;
2749 return 0;
2751 #endif