tiny_libmaker: fix function array overflow
[tinycc.git] / tccelf.c
blob093f18d014140af223505f14f2506451c7ac7c73
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 #define JMP_TABLE_ENTRY_MAX_NUM 4096
483 static unsigned long add_jmp_table(TCCState *s1, unsigned long val)
485 char *p;
486 if (!s1->jmp_table) {
487 int size = JMP_TABLE_ENTRY_SIZE * JMP_TABLE_ENTRY_MAX_NUM;
488 s1->jmp_table_num = 0;
489 s1->jmp_table = (char *)tcc_malloc(size);
490 set_pages_executable(s1->jmp_table, size);
492 if (s1->jmp_table_num == JMP_TABLE_ENTRY_MAX_NUM) {
493 error("relocating >%d symbols are not supported",
494 JMP_TABLE_ENTRY_MAX_NUM);
496 p = s1->jmp_table + s1->jmp_table_num * JMP_TABLE_ENTRY_SIZE;
497 s1->jmp_table_num++;
498 /* jmp *0x0(%rip) */
499 p[0] = 0xff;
500 p[1] = 0x25;
501 *(int *)(p + 2) = 0;
502 *(unsigned long *)(p + 6) = val;
503 return (unsigned long)p;
505 #endif
507 /* relocate a given section (CPU dependent) */
508 static void relocate_section(TCCState *s1, Section *s)
510 Section *sr;
511 ElfW_Rel *rel, *rel_end, *qrel;
512 ElfW(Sym) *sym;
513 int type, sym_index;
514 unsigned char *ptr;
515 unsigned long val, addr;
516 int esym_index;
518 sr = s->reloc;
519 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
520 qrel = (ElfW_Rel *)sr->data;
521 for(rel = qrel;
522 rel < rel_end;
523 rel++) {
524 ptr = s->data + rel->r_offset;
526 sym_index = ELFW(R_SYM)(rel->r_info);
527 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
528 val = sym->st_value;
529 #ifdef TCC_TARGET_X86_64
530 /* XXX: not tested */
531 val += rel->r_addend;
532 #endif
533 type = ELFW(R_TYPE)(rel->r_info);
534 addr = s->sh_addr + rel->r_offset;
536 /* CPU specific */
537 switch(type) {
538 #if defined(TCC_TARGET_I386)
539 case R_386_32:
540 if (s1->output_type == TCC_OUTPUT_DLL) {
541 esym_index = s1->symtab_to_dynsym[sym_index];
542 qrel->r_offset = rel->r_offset;
543 if (esym_index) {
544 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
545 qrel++;
546 break;
547 } else {
548 qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
549 qrel++;
552 *(int *)ptr += val;
553 break;
554 case R_386_PC32:
555 if (s1->output_type == TCC_OUTPUT_DLL) {
556 /* DLL relocation */
557 esym_index = s1->symtab_to_dynsym[sym_index];
558 if (esym_index) {
559 qrel->r_offset = rel->r_offset;
560 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
561 qrel++;
562 break;
565 *(int *)ptr += val - addr;
566 break;
567 case R_386_PLT32:
568 *(int *)ptr += val - addr;
569 break;
570 case R_386_GLOB_DAT:
571 case R_386_JMP_SLOT:
572 *(int *)ptr = val;
573 break;
574 case R_386_GOTPC:
575 *(int *)ptr += s1->got->sh_addr - addr;
576 break;
577 case R_386_GOTOFF:
578 *(int *)ptr += val - s1->got->sh_addr;
579 break;
580 case R_386_GOT32:
581 /* we load the got offset */
582 *(int *)ptr += s1->got_offsets[sym_index];
583 break;
584 #elif defined(TCC_TARGET_ARM)
585 case R_ARM_PC24:
586 case R_ARM_CALL:
587 case R_ARM_JUMP24:
588 case R_ARM_PLT32:
590 int x;
591 x = (*(int *)ptr)&0xffffff;
592 (*(int *)ptr) &= 0xff000000;
593 if (x & 0x800000)
594 x -= 0x1000000;
595 x *= 4;
596 x += val - addr;
597 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
598 error("can't relocate value at %x",addr);
599 x >>= 2;
600 x &= 0xffffff;
601 (*(int *)ptr) |= x;
603 break;
604 case R_ARM_PREL31:
606 int x;
607 x = (*(int *)ptr) & 0x7fffffff;
608 (*(int *)ptr) &= 0x80000000;
609 x = (x * 2) / 2;
610 x += val - addr;
611 if((x^(x>>1))&0x40000000)
612 error("can't relocate value at %x",addr);
613 (*(int *)ptr) |= x & 0x7fffffff;
615 case R_ARM_ABS32:
616 *(int *)ptr += val;
617 break;
618 case R_ARM_BASE_PREL:
619 *(int *)ptr += s1->got->sh_addr - addr;
620 break;
621 case R_ARM_GOTOFF32:
622 *(int *)ptr += val - s1->got->sh_addr;
623 break;
624 case R_ARM_GOT_BREL:
625 /* we load the got offset */
626 *(int *)ptr += s1->got_offsets[sym_index];
627 break;
628 case R_ARM_COPY:
629 break;
630 default:
631 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
632 type,addr,(unsigned int )ptr,val);
633 break;
634 #elif defined(TCC_TARGET_C67)
635 case R_C60_32:
636 *(int *)ptr += val;
637 break;
638 case R_C60LO16:
640 uint32_t orig;
642 /* put the low 16 bits of the absolute address */
643 // add to what is already there
645 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
646 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
648 //patch both at once - assumes always in pairs Low - High
650 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
651 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
653 break;
654 case R_C60HI16:
655 break;
656 default:
657 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
658 type,addr,(unsigned int )ptr,val);
659 break;
660 #elif defined(TCC_TARGET_X86_64)
661 case R_X86_64_64:
662 if (s1->output_type == TCC_OUTPUT_DLL) {
663 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
664 qrel->r_addend = *(long long *)ptr + val;
665 qrel++;
667 *(long long *)ptr += val;
668 break;
669 case R_X86_64_32:
670 case R_X86_64_32S:
671 if (s1->output_type == TCC_OUTPUT_DLL) {
672 /* XXX: this logic may depend on TCC's codegen
673 now TCC uses R_X86_64_32 even for a 64bit pointer */
674 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
675 qrel->r_addend = *(int *)ptr + val;
676 qrel++;
678 *(int *)ptr += val;
679 break;
680 case R_X86_64_PC32: {
681 if (s1->output_type == TCC_OUTPUT_DLL) {
682 /* DLL relocation */
683 esym_index = s1->symtab_to_dynsym[sym_index];
684 if (esym_index) {
685 qrel->r_offset = rel->r_offset;
686 qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
687 qrel->r_addend = *(int *)ptr;
688 qrel++;
689 break;
692 long diff = val - addr;
693 if (diff < -2147483648 || diff > 2147483647) {
694 /* XXX: naive support for over 32bit jump */
695 if (s1->output_type == TCC_OUTPUT_MEMORY) {
696 val = add_jmp_table(s1, val);
697 diff = val - addr;
699 if (diff <= -2147483647 || diff > 2147483647) {
700 #if 0
701 /* output memory map to debug easily */
702 FILE* fp;
703 char buf[4096];
704 int size;
705 Dl_info di;
706 printf("%ld - %ld = %ld\n", val, addr, diff);
707 dladdr((void *)addr, &di);
708 printf("addr = %lx = %lx+%lx(%s) ptr=%p\n",
709 addr, s->sh_addr, rel->r_offset, di.dli_sname,
710 ptr);
711 fp = fopen("/proc/self/maps", "r");
712 size = fread(buf, 1, 4095, fp);
713 buf[size] = '\0';
714 printf("%s", buf);
715 #endif
716 error("internal error: relocation failed");
719 *(int *)ptr += diff;
721 break;
722 case R_X86_64_PLT32:
723 *(int *)ptr += val - addr;
724 break;
725 case R_X86_64_GLOB_DAT:
726 case R_X86_64_JUMP_SLOT:
727 *(int *)ptr = val;
728 break;
729 case R_X86_64_GOTPCREL:
730 *(int *)ptr += s1->got->sh_addr - addr;
731 /* XXX: is this OK? */
732 if (s1->output_type == TCC_OUTPUT_DLL) {
733 *(int *)ptr += s1->got_offsets[sym_index] - 4;
735 break;
736 case R_X86_64_GOTTPOFF:
737 *(int *)ptr += val - s1->got->sh_addr;
738 break;
739 case R_X86_64_GOT32:
740 /* we load the got offset */
741 *(int *)ptr += s1->got_offsets[sym_index];
742 break;
743 #else
744 #error unsupported processor
745 #endif
748 /* if the relocation is allocated, we change its symbol table */
749 if (sr->sh_flags & SHF_ALLOC)
750 sr->link = s1->dynsym;
753 /* relocate relocation table in 'sr' */
754 static void relocate_rel(TCCState *s1, Section *sr)
756 Section *s;
757 ElfW_Rel *rel, *rel_end;
759 s = s1->sections[sr->sh_info];
760 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
761 for(rel = (ElfW_Rel *)sr->data;
762 rel < rel_end;
763 rel++) {
764 rel->r_offset += s->sh_addr;
768 /* count the number of dynamic relocations so that we can reserve
769 their space */
770 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
772 ElfW_Rel *rel, *rel_end;
773 int sym_index, esym_index, type, count;
775 count = 0;
776 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
777 for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
778 sym_index = ELFW(R_SYM)(rel->r_info);
779 type = ELFW(R_TYPE)(rel->r_info);
780 switch(type) {
781 #if defined(TCC_TARGET_I386)
782 case R_386_32:
783 #elif defined(TCC_TARGET_X86_64)
784 case R_X86_64_32:
785 case R_X86_64_32S:
786 case R_X86_64_64:
787 #endif
788 count++;
789 break;
790 #if defined(TCC_TARGET_I386)
791 case R_386_PC32:
792 #elif defined(TCC_TARGET_X86_64)
793 case R_X86_64_PC32:
794 #endif
795 esym_index = s1->symtab_to_dynsym[sym_index];
796 if (esym_index)
797 count++;
798 break;
799 default:
800 break;
803 if (count) {
804 /* allocate the section */
805 sr->sh_flags |= SHF_ALLOC;
806 sr->sh_size = count * sizeof(ElfW_Rel);
808 return count;
811 static void put_got_offset(TCCState *s1, int index, unsigned long val)
813 int n;
814 unsigned long *tab;
816 if (index >= s1->nb_got_offsets) {
817 /* find immediately bigger power of 2 and reallocate array */
818 n = 1;
819 while (index >= n)
820 n *= 2;
821 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
822 if (!tab)
823 error("memory full");
824 s1->got_offsets = tab;
825 memset(s1->got_offsets + s1->nb_got_offsets, 0,
826 (n - s1->nb_got_offsets) * sizeof(unsigned long));
827 s1->nb_got_offsets = n;
829 s1->got_offsets[index] = val;
832 /* XXX: suppress that */
833 static void put32(unsigned char *p, uint32_t val)
835 p[0] = val;
836 p[1] = val >> 8;
837 p[2] = val >> 16;
838 p[3] = val >> 24;
841 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
842 defined(TCC_TARGET_X86_64)
843 static uint32_t get32(unsigned char *p)
845 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
847 #endif
849 static void build_got(TCCState *s1)
851 unsigned char *ptr;
853 /* if no got, then create it */
854 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
855 s1->got->sh_entsize = 4;
856 add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
857 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
858 ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
859 #if PTR_SIZE == 4
860 /* keep space for _DYNAMIC pointer, if present */
861 put32(ptr, 0);
862 /* two dummy got entries */
863 put32(ptr + 4, 0);
864 put32(ptr + 8, 0);
865 #else
866 /* keep space for _DYNAMIC pointer, if present */
867 put32(ptr, 0);
868 put32(ptr + 4, 0);
869 /* two dummy got entries */
870 put32(ptr + 8, 0);
871 put32(ptr + 12, 0);
872 put32(ptr + 16, 0);
873 put32(ptr + 20, 0);
874 #endif
877 /* put a got entry corresponding to a symbol in symtab_section. 'size'
878 and 'info' can be modifed if more precise info comes from the DLL */
879 static void put_got_entry(TCCState *s1,
880 int reloc_type, unsigned long size, int info,
881 int sym_index)
883 int index;
884 const char *name;
885 ElfW(Sym) *sym;
886 unsigned long offset;
887 int *ptr;
889 if (!s1->got)
890 build_got(s1);
892 /* if a got entry already exists for that symbol, no need to add one */
893 if (sym_index < s1->nb_got_offsets &&
894 s1->got_offsets[sym_index] != 0)
895 return;
897 put_got_offset(s1, sym_index, s1->got->data_offset);
899 if (s1->dynsym) {
900 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
901 name = symtab_section->link->data + sym->st_name;
902 offset = sym->st_value;
903 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
904 if (reloc_type ==
905 #ifdef TCC_TARGET_X86_64
906 R_X86_64_JUMP_SLOT
907 #else
908 R_386_JMP_SLOT
909 #endif
911 Section *plt;
912 uint8_t *p;
913 int modrm;
915 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
916 modrm = 0x25;
917 #else
918 /* if we build a DLL, we add a %ebx offset */
919 if (s1->output_type == TCC_OUTPUT_DLL)
920 modrm = 0xa3;
921 else
922 modrm = 0x25;
923 #endif
925 /* add a PLT entry */
926 plt = s1->plt;
927 if (plt->data_offset == 0) {
928 /* first plt entry */
929 p = section_ptr_add(plt, 16);
930 p[0] = 0xff; /* pushl got + PTR_SIZE */
931 p[1] = modrm + 0x10;
932 put32(p + 2, PTR_SIZE);
933 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
934 p[7] = modrm;
935 put32(p + 8, PTR_SIZE * 2);
938 p = section_ptr_add(plt, 16);
939 p[0] = 0xff; /* jmp *(got + x) */
940 p[1] = modrm;
941 put32(p + 2, s1->got->data_offset);
942 p[6] = 0x68; /* push $xxx */
943 put32(p + 7, (plt->data_offset - 32) >> 1);
944 p[11] = 0xe9; /* jmp plt_start */
945 put32(p + 12, -(plt->data_offset));
947 /* the symbol is modified so that it will be relocated to
948 the PLT */
949 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
950 if (s1->output_type == TCC_OUTPUT_EXE)
951 #endif
952 offset = plt->data_offset - 16;
954 #elif defined(TCC_TARGET_ARM)
955 if (reloc_type == R_ARM_JUMP_SLOT) {
956 Section *plt;
957 uint8_t *p;
959 /* if we build a DLL, we add a %ebx offset */
960 if (s1->output_type == TCC_OUTPUT_DLL)
961 error("DLLs unimplemented!");
963 /* add a PLT entry */
964 plt = s1->plt;
965 if (plt->data_offset == 0) {
966 /* first plt entry */
967 p = section_ptr_add(plt, 16);
968 put32(p , 0xe52de004);
969 put32(p + 4, 0xe59fe010);
970 put32(p + 8, 0xe08fe00e);
971 put32(p + 12, 0xe5bef008);
974 p = section_ptr_add(plt, 16);
975 put32(p , 0xe59fc004);
976 put32(p+4, 0xe08fc00c);
977 put32(p+8, 0xe59cf000);
978 put32(p+12, s1->got->data_offset);
980 /* the symbol is modified so that it will be relocated to
981 the PLT */
982 if (s1->output_type == TCC_OUTPUT_EXE)
983 offset = plt->data_offset - 16;
985 #elif defined(TCC_TARGET_C67)
986 error("C67 got not implemented");
987 #else
988 #error unsupported CPU
989 #endif
990 index = put_elf_sym(s1->dynsym, offset,
991 size, info, 0, sym->st_shndx, name);
992 /* put a got entry */
993 put_elf_reloc(s1->dynsym, s1->got,
994 s1->got->data_offset,
995 reloc_type, index);
997 ptr = section_ptr_add(s1->got, PTR_SIZE);
998 *ptr = 0;
1001 /* build GOT and PLT entries */
1002 static void build_got_entries(TCCState *s1)
1004 Section *s, *symtab;
1005 ElfW_Rel *rel, *rel_end;
1006 ElfW(Sym) *sym;
1007 int i, type, reloc_type, sym_index;
1009 for(i = 1; i < s1->nb_sections; i++) {
1010 s = s1->sections[i];
1011 if (s->sh_type != SHT_RELX)
1012 continue;
1013 /* no need to handle got relocations */
1014 if (s->link != symtab_section)
1015 continue;
1016 symtab = s->link;
1017 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
1018 for(rel = (ElfW_Rel *)s->data;
1019 rel < rel_end;
1020 rel++) {
1021 type = ELFW(R_TYPE)(rel->r_info);
1022 switch(type) {
1023 #if defined(TCC_TARGET_I386)
1024 case R_386_GOT32:
1025 case R_386_GOTOFF:
1026 case R_386_GOTPC:
1027 case R_386_PLT32:
1028 if (!s1->got)
1029 build_got(s1);
1030 if (type == R_386_GOT32 || type == R_386_PLT32) {
1031 sym_index = ELFW(R_SYM)(rel->r_info);
1032 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1033 /* look at the symbol got offset. If none, then add one */
1034 if (type == R_386_GOT32)
1035 reloc_type = R_386_GLOB_DAT;
1036 else
1037 reloc_type = R_386_JMP_SLOT;
1038 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1039 sym_index);
1041 break;
1042 #elif defined(TCC_TARGET_ARM)
1043 case R_ARM_GOT_BREL:
1044 case R_ARM_GOTOFF32:
1045 case R_ARM_BASE_PREL:
1046 case R_ARM_PLT32:
1047 if (!s1->got)
1048 build_got(s1);
1049 if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) {
1050 sym_index = ELFW(R_SYM)(rel->r_info);
1051 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1052 /* look at the symbol got offset. If none, then add one */
1053 if (type == R_ARM_GOT_BREL)
1054 reloc_type = R_ARM_GLOB_DAT;
1055 else
1056 reloc_type = R_ARM_JUMP_SLOT;
1057 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1058 sym_index);
1060 break;
1061 #elif defined(TCC_TARGET_C67)
1062 case R_C60_GOT32:
1063 case R_C60_GOTOFF:
1064 case R_C60_GOTPC:
1065 case R_C60_PLT32:
1066 if (!s1->got)
1067 build_got(s1);
1068 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
1069 sym_index = ELFW(R_SYM)(rel->r_info);
1070 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1071 /* look at the symbol got offset. If none, then add one */
1072 if (type == R_C60_GOT32)
1073 reloc_type = R_C60_GLOB_DAT;
1074 else
1075 reloc_type = R_C60_JMP_SLOT;
1076 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1077 sym_index);
1079 break;
1080 #elif defined(TCC_TARGET_X86_64)
1081 case R_X86_64_GOT32:
1082 case R_X86_64_GOTTPOFF:
1083 case R_X86_64_GOTPCREL:
1084 case R_X86_64_PLT32:
1085 if (!s1->got)
1086 build_got(s1);
1087 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
1088 type == R_X86_64_PLT32) {
1089 sym_index = ELFW(R_SYM)(rel->r_info);
1090 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1091 /* look at the symbol got offset. If none, then add one */
1092 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL)
1093 reloc_type = R_X86_64_GLOB_DAT;
1094 else
1095 reloc_type = R_X86_64_JUMP_SLOT;
1096 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1097 sym_index);
1099 break;
1100 #else
1101 #error unsupported CPU
1102 #endif
1103 default:
1104 break;
1110 static Section *new_symtab(TCCState *s1,
1111 const char *symtab_name, int sh_type, int sh_flags,
1112 const char *strtab_name,
1113 const char *hash_name, int hash_sh_flags)
1115 Section *symtab, *strtab, *hash;
1116 int *ptr, nb_buckets;
1118 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1119 symtab->sh_entsize = sizeof(ElfW(Sym));
1120 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1121 put_elf_str(strtab, "");
1122 symtab->link = strtab;
1123 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1125 nb_buckets = 1;
1127 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1128 hash->sh_entsize = sizeof(int);
1129 symtab->hash = hash;
1130 hash->link = symtab;
1132 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1133 ptr[0] = nb_buckets;
1134 ptr[1] = 1;
1135 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1136 return symtab;
1139 /* put dynamic tag */
1140 static void put_dt(Section *dynamic, int dt, unsigned long val)
1142 ElfW(Dyn) *dyn;
1143 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1144 dyn->d_tag = dt;
1145 dyn->d_un.d_val = val;
1148 static void add_init_array_defines(TCCState *s1, const char *section_name)
1150 Section *s;
1151 long end_offset;
1152 char sym_start[1024];
1153 char sym_end[1024];
1155 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1156 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1158 s = find_section(s1, section_name);
1159 if (!s) {
1160 end_offset = 0;
1161 s = data_section;
1162 } else {
1163 end_offset = s->data_offset;
1166 add_elf_sym(symtab_section,
1167 0, 0,
1168 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1169 s->sh_num, sym_start);
1170 add_elf_sym(symtab_section,
1171 end_offset, 0,
1172 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1173 s->sh_num, sym_end);
1176 /* add tcc runtime libraries */
1177 static void tcc_add_runtime(TCCState *s1)
1179 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1180 char buf[1024];
1181 #endif
1183 #ifdef CONFIG_TCC_BCHECK
1184 if (do_bounds_check) {
1185 unsigned long *ptr;
1186 Section *init_section;
1187 unsigned char *pinit;
1188 int sym_index;
1190 /* XXX: add an object file to do that */
1191 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
1192 *ptr = 0;
1193 add_elf_sym(symtab_section, 0, 0,
1194 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1195 bounds_section->sh_num, "__bounds_start");
1196 /* add bound check code */
1197 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
1198 tcc_add_file(s1, buf);
1199 #ifdef TCC_TARGET_I386
1200 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1201 /* add 'call __bound_init()' in .init section */
1202 init_section = find_section(s1, ".init");
1203 pinit = section_ptr_add(init_section, 5);
1204 pinit[0] = 0xe8;
1205 put32(pinit + 1, -4);
1206 sym_index = find_elf_sym(symtab_section, "__bound_init");
1207 put_elf_reloc(symtab_section, init_section,
1208 init_section->data_offset - 4, R_386_PC32, sym_index);
1210 #endif
1212 #endif
1213 /* add libc */
1214 if (!s1->nostdlib) {
1215 tcc_add_library(s1, "c");
1217 #ifdef CONFIG_USE_LIBGCC
1218 tcc_add_file(s1, CONFIG_SYSROOT "/lib/libgcc_s.so.1");
1219 #else
1220 snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "libtcc1.a");
1221 tcc_add_file(s1, buf);
1222 #endif
1224 /* add crt end if not memory output */
1225 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
1226 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1230 /* add various standard linker symbols (must be done after the
1231 sections are filled (for example after allocating common
1232 symbols)) */
1233 static void tcc_add_linker_symbols(TCCState *s1)
1235 char buf[1024];
1236 int i;
1237 Section *s;
1239 add_elf_sym(symtab_section,
1240 text_section->data_offset, 0,
1241 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1242 text_section->sh_num, "_etext");
1243 add_elf_sym(symtab_section,
1244 data_section->data_offset, 0,
1245 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1246 data_section->sh_num, "_edata");
1247 add_elf_sym(symtab_section,
1248 bss_section->data_offset, 0,
1249 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1250 bss_section->sh_num, "_end");
1251 /* horrible new standard ldscript defines */
1252 add_init_array_defines(s1, ".preinit_array");
1253 add_init_array_defines(s1, ".init_array");
1254 add_init_array_defines(s1, ".fini_array");
1256 /* add start and stop symbols for sections whose name can be
1257 expressed in C */
1258 for(i = 1; i < s1->nb_sections; i++) {
1259 s = s1->sections[i];
1260 if (s->sh_type == SHT_PROGBITS &&
1261 (s->sh_flags & SHF_ALLOC)) {
1262 const char *p;
1263 int ch;
1265 /* check if section name can be expressed in C */
1266 p = s->name;
1267 for(;;) {
1268 ch = *p;
1269 if (!ch)
1270 break;
1271 if (!isid(ch) && !isnum(ch))
1272 goto next_sec;
1273 p++;
1275 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1276 add_elf_sym(symtab_section,
1277 0, 0,
1278 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1279 s->sh_num, buf);
1280 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1281 add_elf_sym(symtab_section,
1282 s->data_offset, 0,
1283 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1284 s->sh_num, buf);
1286 next_sec: ;
1290 /* name of ELF interpreter */
1291 #ifdef __FreeBSD__
1292 static char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1293 #else
1294 #ifdef TCC_ARM_EABI
1295 static char elf_interp[] = "/lib/ld-linux.so.3";
1296 #elif defined(TCC_TARGET_X86_64)
1297 static char elf_interp[] = "/lib/ld-linux-x86-64.so.2";
1298 #else
1299 static char elf_interp[] = "/lib/ld-linux.so.2";
1300 #endif
1301 #endif
1303 static void tcc_output_binary(TCCState *s1, FILE *f,
1304 const int *section_order)
1306 Section *s;
1307 int i, offset, size;
1309 offset = 0;
1310 for(i=1;i<s1->nb_sections;i++) {
1311 s = s1->sections[section_order[i]];
1312 if (s->sh_type != SHT_NOBITS &&
1313 (s->sh_flags & SHF_ALLOC)) {
1314 while (offset < s->sh_offset) {
1315 fputc(0, f);
1316 offset++;
1318 size = s->sh_size;
1319 fwrite(s->data, 1, size, f);
1320 offset += size;
1325 /* output an ELF file */
1326 /* XXX: suppress unneeded sections */
1327 int elf_output_file(TCCState *s1, const char *filename)
1329 ElfW(Ehdr) ehdr;
1330 FILE *f;
1331 int fd, mode, ret;
1332 int *section_order;
1333 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1334 unsigned long addr;
1335 Section *strsec, *s;
1336 ElfW(Shdr) shdr, *sh;
1337 ElfW(Phdr) *phdr, *ph;
1338 Section *interp, *dynamic, *dynstr;
1339 unsigned long saved_dynamic_data_offset;
1340 ElfW(Sym) *sym;
1341 int type, file_type;
1342 unsigned long rel_addr, rel_size;
1344 file_type = s1->output_type;
1345 s1->nb_errors = 0;
1347 if (file_type != TCC_OUTPUT_OBJ) {
1348 tcc_add_runtime(s1);
1351 phdr = NULL;
1352 section_order = NULL;
1353 interp = NULL;
1354 dynamic = NULL;
1355 dynstr = NULL; /* avoid warning */
1356 saved_dynamic_data_offset = 0; /* avoid warning */
1358 if (file_type != TCC_OUTPUT_OBJ) {
1359 relocate_common_syms();
1361 tcc_add_linker_symbols(s1);
1363 if (!s1->static_link) {
1364 const char *name;
1365 int sym_index, index;
1366 ElfW(Sym) *esym, *sym_end;
1368 if (file_type == TCC_OUTPUT_EXE) {
1369 char *ptr;
1370 /* add interpreter section only if executable */
1371 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1372 interp->sh_addralign = 1;
1373 ptr = section_ptr_add(interp, sizeof(elf_interp));
1374 strcpy(ptr, elf_interp);
1377 /* add dynamic symbol table */
1378 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1379 ".dynstr",
1380 ".hash", SHF_ALLOC);
1381 dynstr = s1->dynsym->link;
1383 /* add dynamic section */
1384 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1385 SHF_ALLOC | SHF_WRITE);
1386 dynamic->link = dynstr;
1387 dynamic->sh_entsize = sizeof(ElfW(Dyn));
1389 /* add PLT */
1390 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1391 SHF_ALLOC | SHF_EXECINSTR);
1392 s1->plt->sh_entsize = 4;
1394 build_got(s1);
1396 /* scan for undefined symbols and see if they are in the
1397 dynamic symbols. If a symbol STT_FUNC is found, then we
1398 add it in the PLT. If a symbol STT_OBJECT is found, we
1399 add it in the .bss section with a suitable relocation */
1400 sym_end = (ElfW(Sym) *)(symtab_section->data +
1401 symtab_section->data_offset);
1402 if (file_type == TCC_OUTPUT_EXE) {
1403 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1404 sym < sym_end;
1405 sym++) {
1406 if (sym->st_shndx == SHN_UNDEF) {
1407 name = symtab_section->link->data + sym->st_name;
1408 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1409 if (sym_index) {
1410 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1411 type = ELFW(ST_TYPE)(esym->st_info);
1412 if (type == STT_FUNC) {
1413 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1414 esym->st_info,
1415 sym - (ElfW(Sym) *)symtab_section->data);
1416 } else if (type == STT_OBJECT) {
1417 unsigned long offset;
1418 offset = bss_section->data_offset;
1419 /* XXX: which alignment ? */
1420 offset = (offset + 16 - 1) & -16;
1421 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1422 esym->st_info, 0,
1423 bss_section->sh_num, name);
1424 put_elf_reloc(s1->dynsym, bss_section,
1425 offset, R_COPY, index);
1426 offset += esym->st_size;
1427 bss_section->data_offset = offset;
1429 } else {
1430 /* STB_WEAK undefined symbols are accepted */
1431 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1432 it */
1433 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1434 !strcmp(name, "_fp_hw")) {
1435 } else {
1436 error_noabort("undefined symbol '%s'", name);
1439 } else if (s1->rdynamic &&
1440 ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1441 /* if -rdynamic option, then export all non
1442 local symbols */
1443 name = symtab_section->link->data + sym->st_name;
1444 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1445 sym->st_info, 0,
1446 sym->st_shndx, name);
1450 if (s1->nb_errors)
1451 goto fail;
1453 /* now look at unresolved dynamic symbols and export
1454 corresponding symbol */
1455 sym_end = (ElfW(Sym) *)(s1->dynsymtab_section->data +
1456 s1->dynsymtab_section->data_offset);
1457 for(esym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1;
1458 esym < sym_end;
1459 esym++) {
1460 if (esym->st_shndx == SHN_UNDEF) {
1461 name = s1->dynsymtab_section->link->data + esym->st_name;
1462 sym_index = find_elf_sym(symtab_section, name);
1463 if (sym_index) {
1464 /* XXX: avoid adding a symbol if already
1465 present because of -rdynamic ? */
1466 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1467 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1468 sym->st_info, 0,
1469 sym->st_shndx, name);
1470 } else {
1471 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1472 /* weak symbols can stay undefined */
1473 } else {
1474 warning("undefined dynamic symbol '%s'", name);
1479 } else {
1480 int nb_syms;
1481 /* shared library case : we simply export all the global symbols */
1482 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1483 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1484 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1485 sym < sym_end;
1486 sym++) {
1487 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1488 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1489 if (ELFW(ST_TYPE)(sym->st_info) == STT_FUNC &&
1490 sym->st_shndx == SHN_UNDEF) {
1491 put_got_entry(s1, R_JMP_SLOT, sym->st_size,
1492 sym->st_info,
1493 sym - (ElfW(Sym) *)symtab_section->data);
1495 else if (ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT) {
1496 put_got_entry(s1, R_X86_64_GLOB_DAT, sym->st_size,
1497 sym->st_info,
1498 sym - (ElfW(Sym) *)symtab_section->data);
1500 else
1501 #endif
1503 name = symtab_section->link->data + sym->st_name;
1504 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1505 sym->st_info, 0,
1506 sym->st_shndx, name);
1507 s1->symtab_to_dynsym[sym -
1508 (ElfW(Sym) *)symtab_section->data] =
1509 index;
1515 build_got_entries(s1);
1517 /* add a list of needed dlls */
1518 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1519 DLLReference *dllref = s1->loaded_dlls[i];
1520 if (dllref->level == 0)
1521 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1523 /* XXX: currently, since we do not handle PIC code, we
1524 must relocate the readonly segments */
1525 if (file_type == TCC_OUTPUT_DLL) {
1526 if (s1->soname)
1527 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
1528 put_dt(dynamic, DT_TEXTREL, 0);
1531 /* add necessary space for other entries */
1532 saved_dynamic_data_offset = dynamic->data_offset;
1533 dynamic->data_offset += sizeof(ElfW(Dyn)) * 9;
1534 } else {
1535 /* still need to build got entries in case of static link */
1536 build_got_entries(s1);
1540 memset(&ehdr, 0, sizeof(ehdr));
1542 /* we add a section for symbols */
1543 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1544 put_elf_str(strsec, "");
1546 /* compute number of sections */
1547 shnum = s1->nb_sections;
1549 /* this array is used to reorder sections in the output file */
1550 section_order = tcc_malloc(sizeof(int) * shnum);
1551 section_order[0] = 0;
1552 sh_order_index = 1;
1554 /* compute number of program headers */
1555 switch(file_type) {
1556 default:
1557 case TCC_OUTPUT_OBJ:
1558 phnum = 0;
1559 break;
1560 case TCC_OUTPUT_EXE:
1561 if (!s1->static_link)
1562 phnum = 4;
1563 else
1564 phnum = 2;
1565 break;
1566 case TCC_OUTPUT_DLL:
1567 phnum = 3;
1568 break;
1571 /* allocate strings for section names and decide if an unallocated
1572 section should be output */
1573 /* NOTE: the strsec section comes last, so its size is also
1574 correct ! */
1575 for(i = 1; i < s1->nb_sections; i++) {
1576 s = s1->sections[i];
1577 s->sh_name = put_elf_str(strsec, s->name);
1578 #if 0 //gr
1579 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1580 s->sh_flags,
1581 s->sh_type,
1582 s->sh_info,
1583 s->name,
1584 s->reloc ? s->reloc->name : "n"
1586 #endif
1587 /* when generating a DLL, we include relocations but we may
1588 patch them */
1589 if (file_type == TCC_OUTPUT_DLL &&
1590 s->sh_type == SHT_RELX &&
1591 !(s->sh_flags & SHF_ALLOC)) {
1592 /* //gr: avoid bogus relocs for empty (debug) sections */
1593 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1594 prepare_dynamic_rel(s1, s);
1595 else if (do_debug)
1596 s->sh_size = s->data_offset;
1597 } else if (do_debug ||
1598 file_type == TCC_OUTPUT_OBJ ||
1599 (s->sh_flags & SHF_ALLOC) ||
1600 i == (s1->nb_sections - 1)) {
1601 /* we output all sections if debug or object file */
1602 s->sh_size = s->data_offset;
1606 /* allocate program segment headers */
1607 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
1609 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1610 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1611 } else {
1612 file_offset = 0;
1614 if (phnum > 0) {
1615 /* compute section to program header mapping */
1616 if (s1->has_text_addr) {
1617 int a_offset, p_offset;
1618 addr = s1->text_addr;
1619 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1620 ELF_PAGE_SIZE */
1621 a_offset = addr & (ELF_PAGE_SIZE - 1);
1622 p_offset = file_offset & (ELF_PAGE_SIZE - 1);
1623 if (a_offset < p_offset)
1624 a_offset += ELF_PAGE_SIZE;
1625 file_offset += (a_offset - p_offset);
1626 } else {
1627 if (file_type == TCC_OUTPUT_DLL)
1628 addr = 0;
1629 else
1630 addr = ELF_START_ADDR;
1631 /* compute address after headers */
1632 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1635 /* dynamic relocation table information, for .dynamic section */
1636 rel_size = 0;
1637 rel_addr = 0;
1639 /* leave one program header for the program interpreter */
1640 ph = &phdr[0];
1641 if (interp)
1642 ph++;
1644 for(j = 0; j < 2; j++) {
1645 ph->p_type = PT_LOAD;
1646 if (j == 0)
1647 ph->p_flags = PF_R | PF_X;
1648 else
1649 ph->p_flags = PF_R | PF_W;
1650 ph->p_align = ELF_PAGE_SIZE;
1652 /* we do the following ordering: interp, symbol tables,
1653 relocations, progbits, nobits */
1654 /* XXX: do faster and simpler sorting */
1655 for(k = 0; k < 5; k++) {
1656 for(i = 1; i < s1->nb_sections; i++) {
1657 s = s1->sections[i];
1658 /* compute if section should be included */
1659 if (j == 0) {
1660 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1661 SHF_ALLOC)
1662 continue;
1663 } else {
1664 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1665 (SHF_ALLOC | SHF_WRITE))
1666 continue;
1668 if (s == interp) {
1669 if (k != 0)
1670 continue;
1671 } else if (s->sh_type == SHT_DYNSYM ||
1672 s->sh_type == SHT_STRTAB ||
1673 s->sh_type == SHT_HASH) {
1674 if (k != 1)
1675 continue;
1676 } else if (s->sh_type == SHT_RELX) {
1677 if (k != 2)
1678 continue;
1679 } else if (s->sh_type == SHT_NOBITS) {
1680 if (k != 4)
1681 continue;
1682 } else {
1683 if (k != 3)
1684 continue;
1686 section_order[sh_order_index++] = i;
1688 /* section matches: we align it and add its size */
1689 tmp = addr;
1690 addr = (addr + s->sh_addralign - 1) &
1691 ~(s->sh_addralign - 1);
1692 file_offset += addr - tmp;
1693 s->sh_offset = file_offset;
1694 s->sh_addr = addr;
1696 /* update program header infos */
1697 if (ph->p_offset == 0) {
1698 ph->p_offset = file_offset;
1699 ph->p_vaddr = addr;
1700 ph->p_paddr = ph->p_vaddr;
1702 /* update dynamic relocation infos */
1703 if (s->sh_type == SHT_RELX) {
1704 if (rel_size == 0)
1705 rel_addr = addr;
1706 rel_size += s->sh_size;
1708 addr += s->sh_size;
1709 if (s->sh_type != SHT_NOBITS)
1710 file_offset += s->sh_size;
1713 ph->p_filesz = file_offset - ph->p_offset;
1714 ph->p_memsz = addr - ph->p_vaddr;
1715 ph++;
1716 if (j == 0) {
1717 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1718 /* if in the middle of a page, we duplicate the page in
1719 memory so that one copy is RX and the other is RW */
1720 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1721 addr += ELF_PAGE_SIZE;
1722 } else {
1723 addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
1724 file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
1725 ~(ELF_PAGE_SIZE - 1);
1730 /* if interpreter, then add corresponing program header */
1731 if (interp) {
1732 ph = &phdr[0];
1734 ph->p_type = PT_INTERP;
1735 ph->p_offset = interp->sh_offset;
1736 ph->p_vaddr = interp->sh_addr;
1737 ph->p_paddr = ph->p_vaddr;
1738 ph->p_filesz = interp->sh_size;
1739 ph->p_memsz = interp->sh_size;
1740 ph->p_flags = PF_R;
1741 ph->p_align = interp->sh_addralign;
1744 /* if dynamic section, then add corresponing program header */
1745 if (dynamic) {
1746 ElfW(Sym) *sym_end;
1748 ph = &phdr[phnum - 1];
1750 ph->p_type = PT_DYNAMIC;
1751 ph->p_offset = dynamic->sh_offset;
1752 ph->p_vaddr = dynamic->sh_addr;
1753 ph->p_paddr = ph->p_vaddr;
1754 ph->p_filesz = dynamic->sh_size;
1755 ph->p_memsz = dynamic->sh_size;
1756 ph->p_flags = PF_R | PF_W;
1757 ph->p_align = dynamic->sh_addralign;
1759 /* put GOT dynamic section address */
1760 put32(s1->got->data, dynamic->sh_addr);
1762 /* relocate the PLT */
1763 if (file_type == TCC_OUTPUT_EXE
1764 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1765 || file_type == TCC_OUTPUT_DLL
1766 #endif
1768 uint8_t *p, *p_end;
1770 p = s1->plt->data;
1771 p_end = p + s1->plt->data_offset;
1772 if (p < p_end) {
1773 #if defined(TCC_TARGET_I386)
1774 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1775 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1776 p += 16;
1777 while (p < p_end) {
1778 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1779 p += 16;
1781 #elif defined(TCC_TARGET_X86_64)
1782 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
1783 put32(p + 2, get32(p + 2) + x);
1784 put32(p + 8, get32(p + 8) + x - 6);
1785 p += 16;
1786 while (p < p_end) {
1787 put32(p + 2, get32(p + 2) + x + s1->plt->data - p);
1788 p += 16;
1790 #elif defined(TCC_TARGET_ARM)
1791 int x;
1792 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1793 p +=16;
1794 while (p < p_end) {
1795 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1796 p += 16;
1798 #elif defined(TCC_TARGET_C67)
1799 /* XXX: TODO */
1800 #else
1801 #error unsupported CPU
1802 #endif
1806 /* relocate symbols in .dynsym */
1807 sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset);
1808 for(sym = (ElfW(Sym) *)s1->dynsym->data + 1;
1809 sym < sym_end;
1810 sym++) {
1811 if (sym->st_shndx == SHN_UNDEF) {
1812 /* relocate to the PLT if the symbol corresponds
1813 to a PLT entry */
1814 if (sym->st_value)
1815 sym->st_value += s1->plt->sh_addr;
1816 } else if (sym->st_shndx < SHN_LORESERVE) {
1817 /* do symbol relocation */
1818 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1822 /* put dynamic section entries */
1823 dynamic->data_offset = saved_dynamic_data_offset;
1824 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1825 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1826 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1827 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1828 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1829 #ifdef TCC_TARGET_X86_64
1830 put_dt(dynamic, DT_RELA, rel_addr);
1831 put_dt(dynamic, DT_RELASZ, rel_size);
1832 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
1833 #else
1834 put_dt(dynamic, DT_REL, rel_addr);
1835 put_dt(dynamic, DT_RELSZ, rel_size);
1836 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1837 #endif
1838 if (do_debug)
1839 put_dt(dynamic, DT_DEBUG, 0);
1840 put_dt(dynamic, DT_NULL, 0);
1843 ehdr.e_phentsize = sizeof(ElfW(Phdr));
1844 ehdr.e_phnum = phnum;
1845 ehdr.e_phoff = sizeof(ElfW(Ehdr));
1848 /* all other sections come after */
1849 for(i = 1; i < s1->nb_sections; i++) {
1850 s = s1->sections[i];
1851 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1852 continue;
1853 section_order[sh_order_index++] = i;
1855 file_offset = (file_offset + s->sh_addralign - 1) &
1856 ~(s->sh_addralign - 1);
1857 s->sh_offset = file_offset;
1858 if (s->sh_type != SHT_NOBITS)
1859 file_offset += s->sh_size;
1862 /* if building executable or DLL, then relocate each section
1863 except the GOT which is already relocated */
1864 if (file_type != TCC_OUTPUT_OBJ) {
1865 relocate_syms(s1, 0);
1867 if (s1->nb_errors != 0) {
1868 fail:
1869 ret = -1;
1870 goto the_end;
1873 /* relocate sections */
1874 /* XXX: ignore sections with allocated relocations ? */
1875 for(i = 1; i < s1->nb_sections; i++) {
1876 s = s1->sections[i];
1877 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
1878 relocate_section(s1, s);
1881 /* relocate relocation entries if the relocation tables are
1882 allocated in the executable */
1883 for(i = 1; i < s1->nb_sections; i++) {
1884 s = s1->sections[i];
1885 if ((s->sh_flags & SHF_ALLOC) &&
1886 s->sh_type == SHT_RELX) {
1887 relocate_rel(s1, s);
1891 /* get entry point address */
1892 if (file_type == TCC_OUTPUT_EXE)
1893 ehdr.e_entry = (unsigned long)tcc_get_symbol_err(s1, "_start");
1894 else
1895 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1898 /* write elf file */
1899 if (file_type == TCC_OUTPUT_OBJ)
1900 mode = 0666;
1901 else
1902 mode = 0777;
1903 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1904 if (fd < 0) {
1905 error_noabort("could not write '%s'", filename);
1906 goto fail;
1908 f = fdopen(fd, "wb");
1909 if (verbose)
1910 printf("<- %s\n", filename);
1912 #ifdef TCC_TARGET_COFF
1913 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1914 tcc_output_coff(s1, f);
1915 } else
1916 #endif
1917 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1918 sort_syms(s1, symtab_section);
1920 /* align to 4 */
1921 file_offset = (file_offset + 3) & -4;
1923 /* fill header */
1924 ehdr.e_ident[0] = ELFMAG0;
1925 ehdr.e_ident[1] = ELFMAG1;
1926 ehdr.e_ident[2] = ELFMAG2;
1927 ehdr.e_ident[3] = ELFMAG3;
1928 ehdr.e_ident[4] = TCC_ELFCLASS;
1929 ehdr.e_ident[5] = ELFDATA2LSB;
1930 ehdr.e_ident[6] = EV_CURRENT;
1931 #ifdef __FreeBSD__
1932 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1933 #endif
1934 #ifdef TCC_TARGET_ARM
1935 #ifdef TCC_ARM_EABI
1936 ehdr.e_ident[EI_OSABI] = 0;
1937 ehdr.e_flags = 4 << 24;
1938 #else
1939 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1940 #endif
1941 #endif
1942 switch(file_type) {
1943 default:
1944 case TCC_OUTPUT_EXE:
1945 ehdr.e_type = ET_EXEC;
1946 break;
1947 case TCC_OUTPUT_DLL:
1948 ehdr.e_type = ET_DYN;
1949 break;
1950 case TCC_OUTPUT_OBJ:
1951 ehdr.e_type = ET_REL;
1952 break;
1954 ehdr.e_machine = EM_TCC_TARGET;
1955 ehdr.e_version = EV_CURRENT;
1956 ehdr.e_shoff = file_offset;
1957 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
1958 ehdr.e_shentsize = sizeof(ElfW(Shdr));
1959 ehdr.e_shnum = shnum;
1960 ehdr.e_shstrndx = shnum - 1;
1962 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
1963 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
1964 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1966 for(i=1;i<s1->nb_sections;i++) {
1967 s = s1->sections[section_order[i]];
1968 if (s->sh_type != SHT_NOBITS) {
1969 while (offset < s->sh_offset) {
1970 fputc(0, f);
1971 offset++;
1973 size = s->sh_size;
1974 fwrite(s->data, 1, size, f);
1975 offset += size;
1979 /* output section headers */
1980 while (offset < ehdr.e_shoff) {
1981 fputc(0, f);
1982 offset++;
1985 for(i=0;i<s1->nb_sections;i++) {
1986 sh = &shdr;
1987 memset(sh, 0, sizeof(ElfW(Shdr)));
1988 s = s1->sections[i];
1989 if (s) {
1990 sh->sh_name = s->sh_name;
1991 sh->sh_type = s->sh_type;
1992 sh->sh_flags = s->sh_flags;
1993 sh->sh_entsize = s->sh_entsize;
1994 sh->sh_info = s->sh_info;
1995 if (s->link)
1996 sh->sh_link = s->link->sh_num;
1997 sh->sh_addralign = s->sh_addralign;
1998 sh->sh_addr = s->sh_addr;
1999 sh->sh_offset = s->sh_offset;
2000 sh->sh_size = s->sh_size;
2002 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
2004 } else {
2005 tcc_output_binary(s1, f, section_order);
2007 fclose(f);
2009 ret = 0;
2010 the_end:
2011 tcc_free(s1->symtab_to_dynsym);
2012 tcc_free(section_order);
2013 tcc_free(phdr);
2014 tcc_free(s1->got_offsets);
2015 return ret;
2018 int tcc_output_file(TCCState *s, const char *filename)
2020 int ret;
2021 #ifdef TCC_TARGET_PE
2022 if (s->output_type != TCC_OUTPUT_OBJ) {
2023 ret = pe_output_file(s, filename);
2024 } else
2025 #endif
2027 ret = elf_output_file(s, filename);
2029 return ret;
2032 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2034 void *data;
2036 data = tcc_malloc(size);
2037 lseek(fd, file_offset, SEEK_SET);
2038 read(fd, data, size);
2039 return data;
2042 typedef struct SectionMergeInfo {
2043 Section *s; /* corresponding existing section */
2044 unsigned long offset; /* offset of the new section in the existing section */
2045 uint8_t new_section; /* true if section 's' was added */
2046 uint8_t link_once; /* true if link once section */
2047 } SectionMergeInfo;
2049 /* load an object file and merge it with current files */
2050 /* XXX: handle correctly stab (debug) info */
2051 static int tcc_load_object_file(TCCState *s1,
2052 int fd, unsigned long file_offset)
2054 ElfW(Ehdr) ehdr;
2055 ElfW(Shdr) *shdr, *sh;
2056 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2057 unsigned char *strsec, *strtab;
2058 int *old_to_new_syms;
2059 char *sh_name, *name;
2060 SectionMergeInfo *sm_table, *sm;
2061 ElfW(Sym) *sym, *symtab;
2062 ElfW_Rel *rel, *rel_end;
2063 Section *s;
2065 int stab_index;
2066 int stabstr_index;
2068 stab_index = stabstr_index = 0;
2070 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
2071 goto fail1;
2072 if (ehdr.e_ident[0] != ELFMAG0 ||
2073 ehdr.e_ident[1] != ELFMAG1 ||
2074 ehdr.e_ident[2] != ELFMAG2 ||
2075 ehdr.e_ident[3] != ELFMAG3)
2076 goto fail1;
2077 /* test if object file */
2078 if (ehdr.e_type != ET_REL)
2079 goto fail1;
2080 /* test CPU specific stuff */
2081 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2082 ehdr.e_machine != EM_TCC_TARGET) {
2083 fail1:
2084 error_noabort("invalid object file");
2085 return -1;
2087 /* read sections */
2088 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2089 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2090 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2092 /* load section names */
2093 sh = &shdr[ehdr.e_shstrndx];
2094 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2096 /* load symtab and strtab */
2097 old_to_new_syms = NULL;
2098 symtab = NULL;
2099 strtab = NULL;
2100 nb_syms = 0;
2101 for(i = 1; i < ehdr.e_shnum; i++) {
2102 sh = &shdr[i];
2103 if (sh->sh_type == SHT_SYMTAB) {
2104 if (symtab) {
2105 error_noabort("object must contain only one symtab");
2106 fail:
2107 ret = -1;
2108 goto the_end;
2110 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2111 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2112 sm_table[i].s = symtab_section;
2114 /* now load strtab */
2115 sh = &shdr[sh->sh_link];
2116 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2120 /* now examine each section and try to merge its content with the
2121 ones in memory */
2122 for(i = 1; i < ehdr.e_shnum; i++) {
2123 /* no need to examine section name strtab */
2124 if (i == ehdr.e_shstrndx)
2125 continue;
2126 sh = &shdr[i];
2127 sh_name = strsec + sh->sh_name;
2128 /* ignore sections types we do not handle */
2129 if (sh->sh_type != SHT_PROGBITS &&
2130 sh->sh_type != SHT_RELX &&
2131 #ifdef TCC_ARM_EABI
2132 sh->sh_type != SHT_ARM_EXIDX &&
2133 #endif
2134 sh->sh_type != SHT_NOBITS &&
2135 strcmp(sh_name, ".stabstr")
2137 continue;
2138 if (sh->sh_addralign < 1)
2139 sh->sh_addralign = 1;
2140 /* find corresponding section, if any */
2141 for(j = 1; j < s1->nb_sections;j++) {
2142 s = s1->sections[j];
2143 if (!strcmp(s->name, sh_name)) {
2144 if (!strncmp(sh_name, ".gnu.linkonce",
2145 sizeof(".gnu.linkonce") - 1)) {
2146 /* if a 'linkonce' section is already present, we
2147 do not add it again. It is a little tricky as
2148 symbols can still be defined in
2149 it. */
2150 sm_table[i].link_once = 1;
2151 goto next;
2152 } else {
2153 goto found;
2157 /* not found: create new section */
2158 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
2159 /* take as much info as possible from the section. sh_link and
2160 sh_info will be updated later */
2161 s->sh_addralign = sh->sh_addralign;
2162 s->sh_entsize = sh->sh_entsize;
2163 sm_table[i].new_section = 1;
2164 found:
2165 if (sh->sh_type != s->sh_type) {
2166 error_noabort("invalid section type");
2167 goto fail;
2170 /* align start of section */
2171 offset = s->data_offset;
2173 if (0 == strcmp(sh_name, ".stab")) {
2174 stab_index = i;
2175 goto no_align;
2177 if (0 == strcmp(sh_name, ".stabstr")) {
2178 stabstr_index = i;
2179 goto no_align;
2182 size = sh->sh_addralign - 1;
2183 offset = (offset + size) & ~size;
2184 if (sh->sh_addralign > s->sh_addralign)
2185 s->sh_addralign = sh->sh_addralign;
2186 s->data_offset = offset;
2187 no_align:
2188 sm_table[i].offset = offset;
2189 sm_table[i].s = s;
2190 /* concatenate sections */
2191 size = sh->sh_size;
2192 if (sh->sh_type != SHT_NOBITS) {
2193 unsigned char *ptr;
2194 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2195 ptr = section_ptr_add(s, size);
2196 read(fd, ptr, size);
2197 } else {
2198 s->data_offset += size;
2200 next: ;
2203 /* //gr relocate stab strings */
2204 if (stab_index && stabstr_index) {
2205 Stab_Sym *a, *b;
2206 unsigned o;
2207 s = sm_table[stab_index].s;
2208 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2209 b = (Stab_Sym *)(s->data + s->data_offset);
2210 o = sm_table[stabstr_index].offset;
2211 while (a < b)
2212 a->n_strx += o, a++;
2215 /* second short pass to update sh_link and sh_info fields of new
2216 sections */
2217 for(i = 1; i < ehdr.e_shnum; i++) {
2218 s = sm_table[i].s;
2219 if (!s || !sm_table[i].new_section)
2220 continue;
2221 sh = &shdr[i];
2222 if (sh->sh_link > 0)
2223 s->link = sm_table[sh->sh_link].s;
2224 if (sh->sh_type == SHT_RELX) {
2225 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2226 /* update backward link */
2227 s1->sections[s->sh_info]->reloc = s;
2230 sm = sm_table;
2232 /* resolve symbols */
2233 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2235 sym = symtab + 1;
2236 for(i = 1; i < nb_syms; i++, sym++) {
2237 if (sym->st_shndx != SHN_UNDEF &&
2238 sym->st_shndx < SHN_LORESERVE) {
2239 sm = &sm_table[sym->st_shndx];
2240 if (sm->link_once) {
2241 /* if a symbol is in a link once section, we use the
2242 already defined symbol. It is very important to get
2243 correct relocations */
2244 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2245 name = strtab + sym->st_name;
2246 sym_index = find_elf_sym(symtab_section, name);
2247 if (sym_index)
2248 old_to_new_syms[i] = sym_index;
2250 continue;
2252 /* if no corresponding section added, no need to add symbol */
2253 if (!sm->s)
2254 continue;
2255 /* convert section number */
2256 sym->st_shndx = sm->s->sh_num;
2257 /* offset value */
2258 sym->st_value += sm->offset;
2260 /* add symbol */
2261 name = strtab + sym->st_name;
2262 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
2263 sym->st_info, sym->st_other,
2264 sym->st_shndx, name);
2265 old_to_new_syms[i] = sym_index;
2268 /* third pass to patch relocation entries */
2269 for(i = 1; i < ehdr.e_shnum; i++) {
2270 s = sm_table[i].s;
2271 if (!s)
2272 continue;
2273 sh = &shdr[i];
2274 offset = sm_table[i].offset;
2275 switch(s->sh_type) {
2276 case SHT_RELX:
2277 /* take relocation offset information */
2278 offseti = sm_table[sh->sh_info].offset;
2279 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
2280 for(rel = (ElfW_Rel *)(s->data + offset);
2281 rel < rel_end;
2282 rel++) {
2283 int type;
2284 unsigned sym_index;
2285 /* convert symbol index */
2286 type = ELFW(R_TYPE)(rel->r_info);
2287 sym_index = ELFW(R_SYM)(rel->r_info);
2288 /* NOTE: only one symtab assumed */
2289 if (sym_index >= nb_syms)
2290 goto invalid_reloc;
2291 sym_index = old_to_new_syms[sym_index];
2292 /* ignore link_once in rel section. */
2293 if (!sym_index && !sm->link_once) {
2294 invalid_reloc:
2295 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2296 i, strsec + sh->sh_name, rel->r_offset);
2297 goto fail;
2299 rel->r_info = ELFW(R_INFO)(sym_index, type);
2300 /* offset the relocation offset */
2301 rel->r_offset += offseti;
2303 break;
2304 default:
2305 break;
2309 ret = 0;
2310 the_end:
2311 tcc_free(symtab);
2312 tcc_free(strtab);
2313 tcc_free(old_to_new_syms);
2314 tcc_free(sm_table);
2315 tcc_free(strsec);
2316 tcc_free(shdr);
2317 return ret;
2320 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2322 typedef struct ArchiveHeader {
2323 char ar_name[16]; /* name of this member */
2324 char ar_date[12]; /* file mtime */
2325 char ar_uid[6]; /* owner uid; printed as decimal */
2326 char ar_gid[6]; /* owner gid; printed as decimal */
2327 char ar_mode[8]; /* file mode, printed as octal */
2328 char ar_size[10]; /* file size, printed as decimal */
2329 char ar_fmag[2]; /* should contain ARFMAG */
2330 } ArchiveHeader;
2332 static int get_be32(const uint8_t *b)
2334 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2337 /* load only the objects which resolve undefined symbols */
2338 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
2340 int i, bound, nsyms, sym_index, off, ret;
2341 uint8_t *data;
2342 const char *ar_names, *p;
2343 const uint8_t *ar_index;
2344 ElfW(Sym) *sym;
2346 data = tcc_malloc(size);
2347 if (read(fd, data, size) != size)
2348 goto fail;
2349 nsyms = get_be32(data);
2350 ar_index = data + 4;
2351 ar_names = ar_index + nsyms * 4;
2353 do {
2354 bound = 0;
2355 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2356 sym_index = find_elf_sym(symtab_section, p);
2357 if(sym_index) {
2358 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2359 if(sym->st_shndx == SHN_UNDEF) {
2360 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2361 #if 0
2362 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2363 #endif
2364 ++bound;
2365 lseek(fd, off, SEEK_SET);
2366 if(tcc_load_object_file(s1, fd, off) < 0) {
2367 fail:
2368 ret = -1;
2369 goto the_end;
2374 } while(bound);
2375 ret = 0;
2376 the_end:
2377 tcc_free(data);
2378 return ret;
2381 /* load a '.a' file */
2382 static int tcc_load_archive(TCCState *s1, int fd)
2384 ArchiveHeader hdr;
2385 char ar_size[11];
2386 char ar_name[17];
2387 char magic[8];
2388 int size, len, i;
2389 unsigned long file_offset;
2391 /* skip magic which was already checked */
2392 read(fd, magic, sizeof(magic));
2394 for(;;) {
2395 len = read(fd, &hdr, sizeof(hdr));
2396 if (len == 0)
2397 break;
2398 if (len != sizeof(hdr)) {
2399 error_noabort("invalid archive");
2400 return -1;
2402 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2403 ar_size[sizeof(hdr.ar_size)] = '\0';
2404 size = strtol(ar_size, NULL, 0);
2405 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2406 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2407 if (ar_name[i] != ' ')
2408 break;
2410 ar_name[i + 1] = '\0';
2411 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2412 file_offset = lseek(fd, 0, SEEK_CUR);
2413 /* align to even */
2414 size = (size + 1) & ~1;
2415 if (!strcmp(ar_name, "/")) {
2416 /* coff symbol table : we handle it */
2417 if(s1->alacarte_link)
2418 return tcc_load_alacarte(s1, fd, size);
2419 } else if (!strcmp(ar_name, "//") ||
2420 !strcmp(ar_name, "__.SYMDEF") ||
2421 !strcmp(ar_name, "__.SYMDEF/") ||
2422 !strcmp(ar_name, "ARFILENAMES/")) {
2423 /* skip symbol table or archive names */
2424 } else {
2425 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2426 return -1;
2428 lseek(fd, file_offset + size, SEEK_SET);
2430 return 0;
2433 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2434 is referenced by the user (so it should be added as DT_NEEDED in
2435 the generated ELF file) */
2436 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2438 ElfW(Ehdr) ehdr;
2439 ElfW(Shdr) *shdr, *sh, *sh1;
2440 int i, j, nb_syms, nb_dts, sym_bind, ret;
2441 ElfW(Sym) *sym, *dynsym;
2442 ElfW(Dyn) *dt, *dynamic;
2443 unsigned char *dynstr;
2444 const char *name, *soname;
2445 DLLReference *dllref;
2447 read(fd, &ehdr, sizeof(ehdr));
2449 /* test CPU specific stuff */
2450 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2451 ehdr.e_machine != EM_TCC_TARGET) {
2452 error_noabort("bad architecture");
2453 return -1;
2456 /* read sections */
2457 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2459 /* load dynamic section and dynamic symbols */
2460 nb_syms = 0;
2461 nb_dts = 0;
2462 dynamic = NULL;
2463 dynsym = NULL; /* avoid warning */
2464 dynstr = NULL; /* avoid warning */
2465 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2466 switch(sh->sh_type) {
2467 case SHT_DYNAMIC:
2468 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2469 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2470 break;
2471 case SHT_DYNSYM:
2472 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2473 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2474 sh1 = &shdr[sh->sh_link];
2475 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2476 break;
2477 default:
2478 break;
2482 /* compute the real library name */
2483 soname = tcc_basename(filename);
2485 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2486 if (dt->d_tag == DT_SONAME) {
2487 soname = dynstr + dt->d_un.d_val;
2491 /* if the dll is already loaded, do not load it */
2492 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2493 dllref = s1->loaded_dlls[i];
2494 if (!strcmp(soname, dllref->name)) {
2495 /* but update level if needed */
2496 if (level < dllref->level)
2497 dllref->level = level;
2498 ret = 0;
2499 goto the_end;
2503 // printf("loading dll '%s'\n", soname);
2505 /* add the dll and its level */
2506 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2507 dllref->level = level;
2508 strcpy(dllref->name, soname);
2509 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2511 /* add dynamic symbols in dynsym_section */
2512 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2513 sym_bind = ELFW(ST_BIND)(sym->st_info);
2514 if (sym_bind == STB_LOCAL)
2515 continue;
2516 name = dynstr + sym->st_name;
2517 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2518 sym->st_info, sym->st_other, sym->st_shndx, name);
2521 /* load all referenced DLLs */
2522 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2523 switch(dt->d_tag) {
2524 case DT_NEEDED:
2525 name = dynstr + dt->d_un.d_val;
2526 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2527 dllref = s1->loaded_dlls[j];
2528 if (!strcmp(name, dllref->name))
2529 goto already_loaded;
2531 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2532 error_noabort("referenced dll '%s' not found", name);
2533 ret = -1;
2534 goto the_end;
2536 already_loaded:
2537 break;
2540 ret = 0;
2541 the_end:
2542 tcc_free(dynstr);
2543 tcc_free(dynsym);
2544 tcc_free(dynamic);
2545 tcc_free(shdr);
2546 return ret;
2549 #define LD_TOK_NAME 256
2550 #define LD_TOK_EOF (-1)
2552 /* return next ld script token */
2553 static int ld_next(TCCState *s1, char *name, int name_size)
2555 int c;
2556 char *q;
2558 redo:
2559 switch(ch) {
2560 case ' ':
2561 case '\t':
2562 case '\f':
2563 case '\v':
2564 case '\r':
2565 case '\n':
2566 inp();
2567 goto redo;
2568 case '/':
2569 minp();
2570 if (ch == '*') {
2571 file->buf_ptr = parse_comment(file->buf_ptr);
2572 ch = file->buf_ptr[0];
2573 goto redo;
2574 } else {
2575 q = name;
2576 *q++ = '/';
2577 goto parse_name;
2579 break;
2580 /* case 'a' ... 'z': */
2581 case 'a':
2582 case 'b':
2583 case 'c':
2584 case 'd':
2585 case 'e':
2586 case 'f':
2587 case 'g':
2588 case 'h':
2589 case 'i':
2590 case 'j':
2591 case 'k':
2592 case 'l':
2593 case 'm':
2594 case 'n':
2595 case 'o':
2596 case 'p':
2597 case 'q':
2598 case 'r':
2599 case 's':
2600 case 't':
2601 case 'u':
2602 case 'v':
2603 case 'w':
2604 case 'x':
2605 case 'y':
2606 case 'z':
2607 /* case 'A' ... 'z': */
2608 case 'A':
2609 case 'B':
2610 case 'C':
2611 case 'D':
2612 case 'E':
2613 case 'F':
2614 case 'G':
2615 case 'H':
2616 case 'I':
2617 case 'J':
2618 case 'K':
2619 case 'L':
2620 case 'M':
2621 case 'N':
2622 case 'O':
2623 case 'P':
2624 case 'Q':
2625 case 'R':
2626 case 'S':
2627 case 'T':
2628 case 'U':
2629 case 'V':
2630 case 'W':
2631 case 'X':
2632 case 'Y':
2633 case 'Z':
2634 case '_':
2635 case '\\':
2636 case '.':
2637 case '$':
2638 case '~':
2639 q = name;
2640 parse_name:
2641 for(;;) {
2642 if (!((ch >= 'a' && ch <= 'z') ||
2643 (ch >= 'A' && ch <= 'Z') ||
2644 (ch >= '0' && ch <= '9') ||
2645 strchr("/.-_+=$:\\,~", ch)))
2646 break;
2647 if ((q - name) < name_size - 1) {
2648 *q++ = ch;
2650 minp();
2652 *q = '\0';
2653 c = LD_TOK_NAME;
2654 break;
2655 case CH_EOF:
2656 c = LD_TOK_EOF;
2657 break;
2658 default:
2659 c = ch;
2660 inp();
2661 break;
2663 #if 0
2664 printf("tok=%c %d\n", c, c);
2665 if (c == LD_TOK_NAME)
2666 printf(" name=%s\n", name);
2667 #endif
2668 return c;
2671 static int ld_add_file_list(TCCState *s1, int as_needed)
2673 char filename[1024];
2674 int t, ret;
2676 t = ld_next(s1, filename, sizeof(filename));
2677 if (t != '(')
2678 expect("(");
2679 t = ld_next(s1, filename, sizeof(filename));
2680 for(;;) {
2681 if (t == LD_TOK_EOF) {
2682 error_noabort("unexpected end of file");
2683 return -1;
2684 } else if (t == ')') {
2685 break;
2686 } else if (t != LD_TOK_NAME) {
2687 error_noabort("filename expected");
2688 return -1;
2690 if (!strcmp(filename, "AS_NEEDED")) {
2691 ret = ld_add_file_list(s1, 1);
2692 if (ret)
2693 return ret;
2694 } else {
2695 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2696 if (!as_needed)
2697 tcc_add_file(s1, filename);
2699 t = ld_next(s1, filename, sizeof(filename));
2700 if (t == ',') {
2701 t = ld_next(s1, filename, sizeof(filename));
2704 return 0;
2707 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2708 files */
2709 static int tcc_load_ldscript(TCCState *s1)
2711 char cmd[64];
2712 char filename[1024];
2713 int t, ret;
2715 ch = file->buf_ptr[0];
2716 ch = handle_eob();
2717 for(;;) {
2718 t = ld_next(s1, cmd, sizeof(cmd));
2719 if (t == LD_TOK_EOF)
2720 return 0;
2721 else if (t != LD_TOK_NAME)
2722 return -1;
2723 if (!strcmp(cmd, "INPUT") ||
2724 !strcmp(cmd, "GROUP")) {
2725 ret = ld_add_file_list(s1, 0);
2726 if (ret)
2727 return ret;
2728 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2729 !strcmp(cmd, "TARGET")) {
2730 /* ignore some commands */
2731 t = ld_next(s1, cmd, sizeof(cmd));
2732 if (t != '(')
2733 expect("(");
2734 for(;;) {
2735 t = ld_next(s1, filename, sizeof(filename));
2736 if (t == LD_TOK_EOF) {
2737 error_noabort("unexpected end of file");
2738 return -1;
2739 } else if (t == ')') {
2740 break;
2743 } else {
2744 return -1;
2747 return 0;