tccpp: avoid double free with macro_ptr_allocated (after errors)
[tinycc/k1w1.git] / tccelf.c
blobb55d55a9d8c61a7f7f4fc9561f7b76c6df2f567e
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 void *tcc_get_symbol(TCCState *s, const char *name)
174 int sym_index;
175 ElfW(Sym) *sym;
176 sym_index = find_elf_sym(symtab_section, name);
177 if (!sym_index)
178 return NULL;
179 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
180 return (void*)(uplong)sym->st_value;
183 void *tcc_get_symbol_err(TCCState *s, const char *name)
185 void *sym;
186 sym = tcc_get_symbol(s, name);
187 if (!sym)
188 error("%s not defined", name);
189 return sym;
192 /* add an elf symbol : check if it is already defined and patch
193 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
194 static int add_elf_sym(Section *s, uplong value, unsigned long size,
195 int info, int other, int sh_num, const char *name)
197 ElfW(Sym) *esym;
198 int sym_bind, sym_index, sym_type, esym_bind;
199 unsigned char sym_vis, esym_vis, new_vis;
201 sym_bind = ELFW(ST_BIND)(info);
202 sym_type = ELFW(ST_TYPE)(info);
203 sym_vis = ELFW(ST_VISIBILITY)(other);
205 if (sym_bind != STB_LOCAL) {
206 /* we search global or weak symbols */
207 sym_index = find_elf_sym(s, name);
208 if (!sym_index)
209 goto do_def;
210 esym = &((ElfW(Sym) *)s->data)[sym_index];
211 if (esym->st_shndx != SHN_UNDEF) {
212 esym_bind = ELFW(ST_BIND)(esym->st_info);
213 /* propagate the most constraining visibility */
214 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
215 esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
216 if (esym_vis == STV_DEFAULT) {
217 new_vis = sym_vis;
218 } else if (sym_vis == STV_DEFAULT) {
219 new_vis = esym_vis;
220 } else {
221 new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
223 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
224 | new_vis;
225 other = esym->st_other; /* in case we have to patch esym */
226 if (sh_num == SHN_UNDEF) {
227 /* ignore adding of undefined symbol if the
228 corresponding symbol is already defined */
229 } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
230 /* global overrides weak, so patch */
231 goto do_patch;
232 } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
233 /* weak is ignored if already global */
234 } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
235 /* ignore hidden symbols after */
236 } else if (esym->st_shndx == SHN_COMMON
237 && (sh_num < SHN_LORESERVE || sh_num == SHN_COMMON)) {
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;
436 sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
437 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
438 sym < sym_end;
439 sym++) {
440 sh_num = sym->st_shndx;
441 if (sh_num == SHN_UNDEF) {
442 name = strtab_section->data + sym->st_name;
443 if (do_resolve) {
444 #ifndef _WIN32
445 void *addr;
446 name = symtab_section->link->data + sym->st_name;
447 addr = resolve_sym(s1, name);
448 if (addr) {
449 sym->st_value = (uplong)addr;
450 goto found;
452 #endif
453 } else if (s1->dynsym) {
454 /* if dynamic symbol exist, then use it */
455 sym_index = find_elf_sym(s1->dynsym, name);
456 if (sym_index) {
457 esym = &((ElfW(Sym) *)s1->dynsym->data)[sym_index];
458 sym->st_value = esym->st_value;
459 goto found;
462 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
463 it */
464 if (!strcmp(name, "_fp_hw"))
465 goto found;
466 /* only weak symbols are accepted to be undefined. Their
467 value is zero */
468 sym_bind = ELFW(ST_BIND)(sym->st_info);
469 if (sym_bind == STB_WEAK) {
470 sym->st_value = 0;
471 } else {
472 error_noabort("undefined symbol '%s'", name);
474 } else if (sh_num < SHN_LORESERVE) {
475 /* add section base */
476 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
478 found: ;
482 #ifndef TCC_TARGET_PE
483 #ifdef TCC_TARGET_X86_64
484 #define JMP_TABLE_ENTRY_SIZE 14
485 static unsigned long add_jmp_table(TCCState *s1, unsigned long val)
487 char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset;
488 s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE;
489 /* jmp *0x0(%rip) */
490 p[0] = 0xff;
491 p[1] = 0x25;
492 *(int *)(p + 2) = 0;
493 *(unsigned long *)(p + 6) = val;
494 return (unsigned long)p;
497 static unsigned long add_got_table(TCCState *s1, unsigned long val)
499 unsigned long *p =(unsigned long *)(s1->runtime_plt_and_got +
500 s1->runtime_plt_and_got_offset);
501 s1->runtime_plt_and_got_offset += sizeof(void *);
502 *p = val;
503 return (unsigned long)p;
505 #endif
506 #endif
508 /* relocate a given section (CPU dependent) */
509 static void relocate_section(TCCState *s1, Section *s)
511 Section *sr;
512 ElfW_Rel *rel, *rel_end, *qrel;
513 ElfW(Sym) *sym;
514 int type, sym_index;
515 unsigned char *ptr;
516 unsigned long val, addr;
517 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
518 int esym_index;
519 #endif
521 sr = s->reloc;
522 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
523 qrel = (ElfW_Rel *)sr->data;
524 for(rel = qrel;
525 rel < rel_end;
526 rel++) {
527 ptr = s->data + rel->r_offset;
529 sym_index = ELFW(R_SYM)(rel->r_info);
530 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
531 val = sym->st_value;
532 #ifdef TCC_TARGET_X86_64
533 /* XXX: not tested */
534 val += rel->r_addend;
535 #endif
536 type = ELFW(R_TYPE)(rel->r_info);
537 addr = s->sh_addr + rel->r_offset;
539 /* CPU specific */
540 switch(type) {
541 #if defined(TCC_TARGET_I386)
542 case R_386_32:
543 if (s1->output_type == TCC_OUTPUT_DLL) {
544 esym_index = s1->symtab_to_dynsym[sym_index];
545 qrel->r_offset = rel->r_offset;
546 if (esym_index) {
547 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
548 qrel++;
549 break;
550 } else {
551 qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
552 qrel++;
555 *(int *)ptr += val;
556 break;
557 case R_386_PC32:
558 if (s1->output_type == TCC_OUTPUT_DLL) {
559 /* DLL relocation */
560 esym_index = s1->symtab_to_dynsym[sym_index];
561 if (esym_index) {
562 qrel->r_offset = rel->r_offset;
563 qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
564 qrel++;
565 break;
568 *(int *)ptr += val - addr;
569 break;
570 case R_386_PLT32:
571 *(int *)ptr += val - addr;
572 break;
573 case R_386_GLOB_DAT:
574 case R_386_JMP_SLOT:
575 *(int *)ptr = val;
576 break;
577 case R_386_GOTPC:
578 *(int *)ptr += s1->got->sh_addr - addr;
579 break;
580 case R_386_GOTOFF:
581 *(int *)ptr += val - s1->got->sh_addr;
582 break;
583 case R_386_GOT32:
584 /* we load the got offset */
585 *(int *)ptr += s1->got_offsets[sym_index];
586 break;
587 #elif defined(TCC_TARGET_ARM)
588 case R_ARM_PC24:
589 case R_ARM_CALL:
590 case R_ARM_JUMP24:
591 case R_ARM_PLT32:
593 int x;
594 x = (*(int *)ptr)&0xffffff;
595 (*(int *)ptr) &= 0xff000000;
596 if (x & 0x800000)
597 x -= 0x1000000;
598 x *= 4;
599 x += val - addr;
600 if((x & 3) != 0 || x >= 0x4000000 || x < -0x4000000)
601 error("can't relocate value at %x",addr);
602 x >>= 2;
603 x &= 0xffffff;
604 (*(int *)ptr) |= x;
606 break;
607 case R_ARM_PREL31:
609 int x;
610 x = (*(int *)ptr) & 0x7fffffff;
611 (*(int *)ptr) &= 0x80000000;
612 x = (x * 2) / 2;
613 x += val - addr;
614 if((x^(x>>1))&0x40000000)
615 error("can't relocate value at %x",addr);
616 (*(int *)ptr) |= x & 0x7fffffff;
618 case R_ARM_ABS32:
619 *(int *)ptr += val;
620 break;
621 case R_ARM_BASE_PREL:
622 *(int *)ptr += s1->got->sh_addr - addr;
623 break;
624 case R_ARM_GOTOFF32:
625 *(int *)ptr += val - s1->got->sh_addr;
626 break;
627 case R_ARM_GOT_BREL:
628 /* we load the got offset */
629 *(int *)ptr += s1->got_offsets[sym_index];
630 break;
631 case R_ARM_COPY:
632 break;
633 default:
634 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
635 type,addr,(unsigned int)(long)ptr,val);
636 break;
637 #elif defined(TCC_TARGET_C67)
638 case R_C60_32:
639 *(int *)ptr += val;
640 break;
641 case R_C60LO16:
643 uint32_t orig;
645 /* put the low 16 bits of the absolute address */
646 // add to what is already there
648 orig = ((*(int *)(ptr )) >> 7) & 0xffff;
649 orig |= (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
651 //patch both at once - assumes always in pairs Low - High
653 *(int *) ptr = (*(int *) ptr & (~(0xffff << 7)) ) | (((val+orig) & 0xffff) << 7);
654 *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) | ((((val+orig)>>16) & 0xffff) << 7);
656 break;
657 case R_C60HI16:
658 break;
659 default:
660 fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
661 type,addr,(unsigned int)(long)ptr, val);
662 break;
663 #elif defined(TCC_TARGET_X86_64)
664 case R_X86_64_64:
665 if (s1->output_type == TCC_OUTPUT_DLL) {
666 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
667 qrel->r_addend = *(long long *)ptr + val;
668 qrel++;
670 *(long long *)ptr += val;
671 break;
672 case R_X86_64_32:
673 case R_X86_64_32S:
674 if (s1->output_type == TCC_OUTPUT_DLL) {
675 /* XXX: this logic may depend on TCC's codegen
676 now TCC uses R_X86_64_32 even for a 64bit pointer */
677 qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
678 qrel->r_addend = *(int *)ptr + val;
679 qrel++;
681 *(int *)ptr += val;
682 break;
683 case R_X86_64_PC32: {
684 long long diff;
685 if (s1->output_type == TCC_OUTPUT_DLL) {
686 /* DLL relocation */
687 esym_index = s1->symtab_to_dynsym[sym_index];
688 if (esym_index) {
689 qrel->r_offset = rel->r_offset;
690 qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
691 qrel->r_addend = *(int *)ptr;
692 qrel++;
693 break;
696 diff = (long long)val - addr;
697 if (diff <= -2147483647 || diff > 2147483647) {
698 #ifndef TCC_TARGET_PE
699 /* XXX: naive support for over 32bit jump */
700 if (s1->output_type == TCC_OUTPUT_MEMORY) {
701 val = add_jmp_table(s1, val);
702 diff = val - addr;
704 #endif
705 if (diff <= -2147483647 || diff > 2147483647) {
706 error("internal error: relocation failed");
709 *(int *)ptr += diff;
711 break;
712 case R_X86_64_PLT32:
713 *(int *)ptr += val - addr;
714 break;
715 case R_X86_64_GLOB_DAT:
716 case R_X86_64_JUMP_SLOT:
717 *(int *)ptr = val;
718 break;
719 case R_X86_64_GOTPCREL:
720 #ifndef TCC_TARGET_PE
721 if (s1->output_type == TCC_OUTPUT_MEMORY) {
722 val = add_got_table(s1, val - rel->r_addend) + rel->r_addend;
723 *(int *)ptr += val - addr;
724 break;
726 #endif
727 *(int *)ptr += (s1->got->sh_addr - addr +
728 s1->got_offsets[sym_index] - 4);
729 break;
730 case R_X86_64_GOTTPOFF:
731 *(int *)ptr += val - s1->got->sh_addr;
732 break;
733 case R_X86_64_GOT32:
734 /* we load the got offset */
735 *(int *)ptr += s1->got_offsets[sym_index];
736 break;
737 #else
738 #error unsupported processor
739 #endif
742 /* if the relocation is allocated, we change its symbol table */
743 if (sr->sh_flags & SHF_ALLOC)
744 sr->link = s1->dynsym;
747 /* relocate relocation table in 'sr' */
748 static void relocate_rel(TCCState *s1, Section *sr)
750 Section *s;
751 ElfW_Rel *rel, *rel_end;
753 s = s1->sections[sr->sh_info];
754 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
755 for(rel = (ElfW_Rel *)sr->data;
756 rel < rel_end;
757 rel++) {
758 rel->r_offset += s->sh_addr;
762 /* count the number of dynamic relocations so that we can reserve
763 their space */
764 static int prepare_dynamic_rel(TCCState *s1, Section *sr)
766 ElfW_Rel *rel, *rel_end;
767 int sym_index, esym_index, type, count;
769 count = 0;
770 rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
771 for(rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
772 sym_index = ELFW(R_SYM)(rel->r_info);
773 type = ELFW(R_TYPE)(rel->r_info);
774 switch(type) {
775 #if defined(TCC_TARGET_I386)
776 case R_386_32:
777 #elif defined(TCC_TARGET_X86_64)
778 case R_X86_64_32:
779 case R_X86_64_32S:
780 case R_X86_64_64:
781 #endif
782 count++;
783 break;
784 #if defined(TCC_TARGET_I386)
785 case R_386_PC32:
786 #elif defined(TCC_TARGET_X86_64)
787 case R_X86_64_PC32:
788 #endif
789 esym_index = s1->symtab_to_dynsym[sym_index];
790 if (esym_index)
791 count++;
792 break;
793 default:
794 break;
797 if (count) {
798 /* allocate the section */
799 sr->sh_flags |= SHF_ALLOC;
800 sr->sh_size = count * sizeof(ElfW_Rel);
802 return count;
805 static void put_got_offset(TCCState *s1, int index, unsigned long val)
807 int n;
808 unsigned long *tab;
810 if (index >= s1->nb_got_offsets) {
811 /* find immediately bigger power of 2 and reallocate array */
812 n = 1;
813 while (index >= n)
814 n *= 2;
815 tab = tcc_realloc(s1->got_offsets, n * sizeof(unsigned long));
816 if (!tab)
817 error("memory full");
818 s1->got_offsets = tab;
819 memset(s1->got_offsets + s1->nb_got_offsets, 0,
820 (n - s1->nb_got_offsets) * sizeof(unsigned long));
821 s1->nb_got_offsets = n;
823 s1->got_offsets[index] = val;
826 /* XXX: suppress that */
827 static void put32(unsigned char *p, uint32_t val)
829 p[0] = val;
830 p[1] = val >> 8;
831 p[2] = val >> 16;
832 p[3] = val >> 24;
835 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
836 defined(TCC_TARGET_X86_64)
837 static uint32_t get32(unsigned char *p)
839 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
841 #endif
843 static void build_got(TCCState *s1)
845 unsigned char *ptr;
847 /* if no got, then create it */
848 s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
849 s1->got->sh_entsize = 4;
850 add_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
851 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
852 ptr = section_ptr_add(s1->got, 3 * PTR_SIZE);
853 #if PTR_SIZE == 4
854 /* keep space for _DYNAMIC pointer, if present */
855 put32(ptr, 0);
856 /* two dummy got entries */
857 put32(ptr + 4, 0);
858 put32(ptr + 8, 0);
859 #else
860 /* keep space for _DYNAMIC pointer, if present */
861 put32(ptr, 0);
862 put32(ptr + 4, 0);
863 /* two dummy got entries */
864 put32(ptr + 8, 0);
865 put32(ptr + 12, 0);
866 put32(ptr + 16, 0);
867 put32(ptr + 20, 0);
868 #endif
871 /* put a got entry corresponding to a symbol in symtab_section. 'size'
872 and 'info' can be modifed if more precise info comes from the DLL */
873 static void put_got_entry(TCCState *s1,
874 int reloc_type, unsigned long size, int info,
875 int sym_index)
877 int index;
878 const char *name;
879 ElfW(Sym) *sym;
880 unsigned long offset;
881 int *ptr;
883 if (!s1->got)
884 build_got(s1);
886 /* if a got entry already exists for that symbol, no need to add one */
887 if (sym_index < s1->nb_got_offsets &&
888 s1->got_offsets[sym_index] != 0)
889 return;
891 put_got_offset(s1, sym_index, s1->got->data_offset);
893 if (s1->dynsym) {
894 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
895 name = symtab_section->link->data + sym->st_name;
896 offset = sym->st_value;
897 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
898 if (reloc_type ==
899 #ifdef TCC_TARGET_X86_64
900 R_X86_64_JUMP_SLOT
901 #else
902 R_386_JMP_SLOT
903 #endif
905 Section *plt;
906 uint8_t *p;
907 int modrm;
909 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
910 modrm = 0x25;
911 #else
912 /* if we build a DLL, we add a %ebx offset */
913 if (s1->output_type == TCC_OUTPUT_DLL)
914 modrm = 0xa3;
915 else
916 modrm = 0x25;
917 #endif
919 /* add a PLT entry */
920 plt = s1->plt;
921 if (plt->data_offset == 0) {
922 /* first plt entry */
923 p = section_ptr_add(plt, 16);
924 p[0] = 0xff; /* pushl got + PTR_SIZE */
925 p[1] = modrm + 0x10;
926 put32(p + 2, PTR_SIZE);
927 p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
928 p[7] = modrm;
929 put32(p + 8, PTR_SIZE * 2);
932 p = section_ptr_add(plt, 16);
933 p[0] = 0xff; /* jmp *(got + x) */
934 p[1] = modrm;
935 put32(p + 2, s1->got->data_offset);
936 p[6] = 0x68; /* push $xxx */
937 put32(p + 7, (plt->data_offset - 32) >> 1);
938 p[11] = 0xe9; /* jmp plt_start */
939 put32(p + 12, -(plt->data_offset));
941 /* the symbol is modified so that it will be relocated to
942 the PLT */
943 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
944 if (s1->output_type == TCC_OUTPUT_EXE)
945 #endif
946 offset = plt->data_offset - 16;
948 #elif defined(TCC_TARGET_ARM)
949 if (reloc_type == R_ARM_JUMP_SLOT) {
950 Section *plt;
951 uint8_t *p;
953 /* if we build a DLL, we add a %ebx offset */
954 if (s1->output_type == TCC_OUTPUT_DLL)
955 error("DLLs unimplemented!");
957 /* add a PLT entry */
958 plt = s1->plt;
959 if (plt->data_offset == 0) {
960 /* first plt entry */
961 p = section_ptr_add(plt, 16);
962 put32(p , 0xe52de004);
963 put32(p + 4, 0xe59fe010);
964 put32(p + 8, 0xe08fe00e);
965 put32(p + 12, 0xe5bef008);
968 p = section_ptr_add(plt, 16);
969 put32(p , 0xe59fc004);
970 put32(p+4, 0xe08fc00c);
971 put32(p+8, 0xe59cf000);
972 put32(p+12, s1->got->data_offset);
974 /* the symbol is modified so that it will be relocated to
975 the PLT */
976 if (s1->output_type == TCC_OUTPUT_EXE)
977 offset = plt->data_offset - 16;
979 #elif defined(TCC_TARGET_C67)
980 error("C67 got not implemented");
981 #else
982 #error unsupported CPU
983 #endif
984 index = put_elf_sym(s1->dynsym, offset,
985 size, info, 0, sym->st_shndx, name);
986 /* put a got entry */
987 put_elf_reloc(s1->dynsym, s1->got,
988 s1->got->data_offset,
989 reloc_type, index);
991 ptr = section_ptr_add(s1->got, PTR_SIZE);
992 *ptr = 0;
995 /* build GOT and PLT entries */
996 static void build_got_entries(TCCState *s1)
998 Section *s, *symtab;
999 ElfW_Rel *rel, *rel_end;
1000 ElfW(Sym) *sym;
1001 int i, type, reloc_type, sym_index;
1003 for(i = 1; i < s1->nb_sections; i++) {
1004 s = s1->sections[i];
1005 if (s->sh_type != SHT_RELX)
1006 continue;
1007 /* no need to handle got relocations */
1008 if (s->link != symtab_section)
1009 continue;
1010 symtab = s->link;
1011 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
1012 for(rel = (ElfW_Rel *)s->data;
1013 rel < rel_end;
1014 rel++) {
1015 type = ELFW(R_TYPE)(rel->r_info);
1016 switch(type) {
1017 #if defined(TCC_TARGET_I386)
1018 case R_386_GOT32:
1019 case R_386_GOTOFF:
1020 case R_386_GOTPC:
1021 case R_386_PLT32:
1022 if (!s1->got)
1023 build_got(s1);
1024 if (type == R_386_GOT32 || type == R_386_PLT32) {
1025 sym_index = ELFW(R_SYM)(rel->r_info);
1026 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1027 /* look at the symbol got offset. If none, then add one */
1028 if (type == R_386_GOT32)
1029 reloc_type = R_386_GLOB_DAT;
1030 else
1031 reloc_type = R_386_JMP_SLOT;
1032 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1033 sym_index);
1035 break;
1036 #elif defined(TCC_TARGET_ARM)
1037 case R_ARM_GOT_BREL:
1038 case R_ARM_GOTOFF32:
1039 case R_ARM_BASE_PREL:
1040 case R_ARM_PLT32:
1041 if (!s1->got)
1042 build_got(s1);
1043 if (type == R_ARM_GOT_BREL || type == R_ARM_PLT32) {
1044 sym_index = ELFW(R_SYM)(rel->r_info);
1045 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1046 /* look at the symbol got offset. If none, then add one */
1047 if (type == R_ARM_GOT_BREL)
1048 reloc_type = R_ARM_GLOB_DAT;
1049 else
1050 reloc_type = R_ARM_JUMP_SLOT;
1051 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1052 sym_index);
1054 break;
1055 #elif defined(TCC_TARGET_C67)
1056 case R_C60_GOT32:
1057 case R_C60_GOTOFF:
1058 case R_C60_GOTPC:
1059 case R_C60_PLT32:
1060 if (!s1->got)
1061 build_got(s1);
1062 if (type == R_C60_GOT32 || type == R_C60_PLT32) {
1063 sym_index = ELFW(R_SYM)(rel->r_info);
1064 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1065 /* look at the symbol got offset. If none, then add one */
1066 if (type == R_C60_GOT32)
1067 reloc_type = R_C60_GLOB_DAT;
1068 else
1069 reloc_type = R_C60_JMP_SLOT;
1070 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1071 sym_index);
1073 break;
1074 #elif defined(TCC_TARGET_X86_64)
1075 case R_X86_64_GOT32:
1076 case R_X86_64_GOTTPOFF:
1077 case R_X86_64_GOTPCREL:
1078 case R_X86_64_PLT32:
1079 if (!s1->got)
1080 build_got(s1);
1081 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
1082 type == R_X86_64_PLT32) {
1083 sym_index = ELFW(R_SYM)(rel->r_info);
1084 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1085 /* look at the symbol got offset. If none, then add one */
1086 if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL)
1087 reloc_type = R_X86_64_GLOB_DAT;
1088 else
1089 reloc_type = R_X86_64_JUMP_SLOT;
1090 put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
1091 sym_index);
1093 break;
1094 #else
1095 #error unsupported CPU
1096 #endif
1097 default:
1098 break;
1104 static Section *new_symtab(TCCState *s1,
1105 const char *symtab_name, int sh_type, int sh_flags,
1106 const char *strtab_name,
1107 const char *hash_name, int hash_sh_flags)
1109 Section *symtab, *strtab, *hash;
1110 int *ptr, nb_buckets;
1112 symtab = new_section(s1, symtab_name, sh_type, sh_flags);
1113 symtab->sh_entsize = sizeof(ElfW(Sym));
1114 strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
1115 put_elf_str(strtab, "");
1116 symtab->link = strtab;
1117 put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
1119 nb_buckets = 1;
1121 hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
1122 hash->sh_entsize = sizeof(int);
1123 symtab->hash = hash;
1124 hash->link = symtab;
1126 ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
1127 ptr[0] = nb_buckets;
1128 ptr[1] = 1;
1129 memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
1130 return symtab;
1133 /* put dynamic tag */
1134 static void put_dt(Section *dynamic, int dt, unsigned long val)
1136 ElfW(Dyn) *dyn;
1137 dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
1138 dyn->d_tag = dt;
1139 dyn->d_un.d_val = val;
1142 static void add_init_array_defines(TCCState *s1, const char *section_name)
1144 Section *s;
1145 long end_offset;
1146 char sym_start[1024];
1147 char sym_end[1024];
1149 snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
1150 snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
1152 s = find_section(s1, section_name);
1153 if (!s) {
1154 end_offset = 0;
1155 s = data_section;
1156 } else {
1157 end_offset = s->data_offset;
1160 add_elf_sym(symtab_section,
1161 0, 0,
1162 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1163 s->sh_num, sym_start);
1164 add_elf_sym(symtab_section,
1165 end_offset, 0,
1166 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1167 s->sh_num, sym_end);
1170 /* add tcc runtime libraries */
1171 static void tcc_add_runtime(TCCState *s1)
1173 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1174 char buf[1024];
1175 #endif
1177 #ifdef CONFIG_TCC_BCHECK
1178 if (s1->do_bounds_check) {
1179 unsigned long *ptr;
1180 Section *init_section;
1181 unsigned char *pinit;
1182 int sym_index;
1184 /* XXX: add an object file to do that */
1185 ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
1186 *ptr = 0;
1187 add_elf_sym(symtab_section, 0, 0,
1188 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1189 bounds_section->sh_num, "__bounds_start");
1190 /* add bound check code */
1191 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, "bcheck.o");
1192 tcc_add_file(s1, buf);
1193 #ifdef TCC_TARGET_I386
1194 if (s1->output_type != TCC_OUTPUT_MEMORY) {
1195 /* add 'call __bound_init()' in .init section */
1196 init_section = find_section(s1, ".init");
1197 pinit = section_ptr_add(init_section, 5);
1198 pinit[0] = 0xe8;
1199 put32(pinit + 1, -4);
1200 sym_index = find_elf_sym(symtab_section, "__bound_init");
1201 put_elf_reloc(symtab_section, init_section,
1202 init_section->data_offset - 4, R_386_PC32, sym_index);
1204 #endif
1206 #endif
1207 /* add libc */
1208 if (!s1->nostdlib) {
1209 tcc_add_library(s1, "c");
1211 #ifdef CONFIG_USE_LIBGCC
1212 tcc_add_file(s1, CONFIG_SYSROOT "/lib/libgcc_s.so.1");
1213 #else
1214 snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, "libtcc1.a");
1215 tcc_add_file(s1, buf);
1216 #endif
1218 /* add crt end if not memory output */
1219 if (s1->output_type != TCC_OUTPUT_MEMORY && !s1->nostdlib) {
1220 tcc_add_file(s1, CONFIG_TCC_CRT_PREFIX "/crtn.o");
1224 /* add various standard linker symbols (must be done after the
1225 sections are filled (for example after allocating common
1226 symbols)) */
1227 static void tcc_add_linker_symbols(TCCState *s1)
1229 char buf[1024];
1230 int i;
1231 Section *s;
1233 add_elf_sym(symtab_section,
1234 text_section->data_offset, 0,
1235 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1236 text_section->sh_num, "_etext");
1237 add_elf_sym(symtab_section,
1238 data_section->data_offset, 0,
1239 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1240 data_section->sh_num, "_edata");
1241 add_elf_sym(symtab_section,
1242 bss_section->data_offset, 0,
1243 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1244 bss_section->sh_num, "_end");
1245 /* horrible new standard ldscript defines */
1246 add_init_array_defines(s1, ".preinit_array");
1247 add_init_array_defines(s1, ".init_array");
1248 add_init_array_defines(s1, ".fini_array");
1250 /* add start and stop symbols for sections whose name can be
1251 expressed in C */
1252 for(i = 1; i < s1->nb_sections; i++) {
1253 s = s1->sections[i];
1254 if (s->sh_type == SHT_PROGBITS &&
1255 (s->sh_flags & SHF_ALLOC)) {
1256 const char *p;
1257 int ch;
1259 /* check if section name can be expressed in C */
1260 p = s->name;
1261 for(;;) {
1262 ch = *p;
1263 if (!ch)
1264 break;
1265 if (!isid(ch) && !isnum(ch))
1266 goto next_sec;
1267 p++;
1269 snprintf(buf, sizeof(buf), "__start_%s", s->name);
1270 add_elf_sym(symtab_section,
1271 0, 0,
1272 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1273 s->sh_num, buf);
1274 snprintf(buf, sizeof(buf), "__stop_%s", s->name);
1275 add_elf_sym(symtab_section,
1276 s->data_offset, 0,
1277 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
1278 s->sh_num, buf);
1280 next_sec: ;
1284 /* name of ELF interpreter */
1285 #if defined __FreeBSD__
1286 static const char elf_interp[] = "/usr/libexec/ld-elf.so.1";
1287 #elif defined TCC_ARM_EABI
1288 static const char elf_interp[] = "/lib/ld-linux.so.3";
1289 #elif defined(TCC_TARGET_X86_64)
1290 static const char elf_interp[] = "/lib/ld-linux-x86-64.so.2";
1291 #elif defined(TCC_UCLIBC)
1292 static const char elf_interp[] = "/lib/ld-uClibc.so.0";
1293 #else
1294 static const char elf_interp[] = "/lib/ld-linux.so.2";
1295 #endif
1297 static void tcc_output_binary(TCCState *s1, FILE *f,
1298 const int *section_order)
1300 Section *s;
1301 int i, offset, size;
1303 offset = 0;
1304 for(i=1;i<s1->nb_sections;i++) {
1305 s = s1->sections[section_order[i]];
1306 if (s->sh_type != SHT_NOBITS &&
1307 (s->sh_flags & SHF_ALLOC)) {
1308 while (offset < s->sh_offset) {
1309 fputc(0, f);
1310 offset++;
1312 size = s->sh_size;
1313 fwrite(s->data, 1, size, f);
1314 offset += size;
1319 /* output an ELF file */
1320 /* XXX: suppress unneeded sections */
1321 int elf_output_file(TCCState *s1, const char *filename)
1323 ElfW(Ehdr) ehdr;
1324 FILE *f;
1325 int fd, mode, ret;
1326 int *section_order;
1327 int shnum, i, phnum, file_offset, offset, size, j, tmp, sh_order_index, k;
1328 unsigned long addr;
1329 Section *strsec, *s;
1330 ElfW(Shdr) shdr, *sh;
1331 ElfW(Phdr) *phdr, *ph;
1332 Section *interp, *dynamic, *dynstr;
1333 unsigned long saved_dynamic_data_offset;
1334 ElfW(Sym) *sym;
1335 int type, file_type;
1336 unsigned long rel_addr, rel_size;
1338 file_type = s1->output_type;
1339 s1->nb_errors = 0;
1341 if (file_type != TCC_OUTPUT_OBJ) {
1342 tcc_add_runtime(s1);
1345 phdr = NULL;
1346 section_order = NULL;
1347 interp = NULL;
1348 dynamic = NULL;
1349 dynstr = NULL; /* avoid warning */
1350 saved_dynamic_data_offset = 0; /* avoid warning */
1352 if (file_type != TCC_OUTPUT_OBJ) {
1353 relocate_common_syms();
1355 tcc_add_linker_symbols(s1);
1357 if (!s1->static_link) {
1358 const char *name;
1359 int sym_index, index;
1360 ElfW(Sym) *esym, *sym_end;
1362 if (file_type == TCC_OUTPUT_EXE) {
1363 char *ptr;
1364 /* add interpreter section only if executable */
1365 interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
1366 interp->sh_addralign = 1;
1367 ptr = section_ptr_add(interp, sizeof(elf_interp));
1368 strcpy(ptr, elf_interp);
1371 /* add dynamic symbol table */
1372 s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
1373 ".dynstr",
1374 ".hash", SHF_ALLOC);
1375 dynstr = s1->dynsym->link;
1377 /* add dynamic section */
1378 dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
1379 SHF_ALLOC | SHF_WRITE);
1380 dynamic->link = dynstr;
1381 dynamic->sh_entsize = sizeof(ElfW(Dyn));
1383 /* add PLT */
1384 s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
1385 SHF_ALLOC | SHF_EXECINSTR);
1386 s1->plt->sh_entsize = 4;
1388 build_got(s1);
1390 /* scan for undefined symbols and see if they are in the
1391 dynamic symbols. If a symbol STT_FUNC is found, then we
1392 add it in the PLT. If a symbol STT_OBJECT is found, we
1393 add it in the .bss section with a suitable relocation */
1394 sym_end = (ElfW(Sym) *)(symtab_section->data +
1395 symtab_section->data_offset);
1396 if (file_type == TCC_OUTPUT_EXE) {
1397 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1398 sym < sym_end;
1399 sym++) {
1400 if (sym->st_shndx == SHN_UNDEF) {
1401 name = symtab_section->link->data + sym->st_name;
1402 sym_index = find_elf_sym(s1->dynsymtab_section, name);
1403 if (sym_index) {
1404 esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
1405 type = ELFW(ST_TYPE)(esym->st_info);
1406 if (type == STT_FUNC) {
1407 put_got_entry(s1, R_JMP_SLOT, esym->st_size,
1408 esym->st_info,
1409 sym - (ElfW(Sym) *)symtab_section->data);
1410 } else if (type == STT_OBJECT) {
1411 unsigned long offset;
1412 offset = bss_section->data_offset;
1413 /* XXX: which alignment ? */
1414 offset = (offset + 16 - 1) & -16;
1415 index = put_elf_sym(s1->dynsym, offset, esym->st_size,
1416 esym->st_info, 0,
1417 bss_section->sh_num, name);
1418 put_elf_reloc(s1->dynsym, bss_section,
1419 offset, R_COPY, index);
1420 offset += esym->st_size;
1421 bss_section->data_offset = offset;
1423 } else {
1424 /* STB_WEAK undefined symbols are accepted */
1425 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1426 it */
1427 if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
1428 !strcmp(name, "_fp_hw")) {
1429 } else {
1430 error_noabort("undefined symbol '%s'", name);
1433 } else if (s1->rdynamic &&
1434 ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1435 /* if -rdynamic option, then export all non
1436 local symbols */
1437 name = symtab_section->link->data + sym->st_name;
1438 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1439 sym->st_info, 0,
1440 sym->st_shndx, name);
1444 if (s1->nb_errors)
1445 goto fail;
1447 /* now look at unresolved dynamic symbols and export
1448 corresponding symbol */
1449 sym_end = (ElfW(Sym) *)(s1->dynsymtab_section->data +
1450 s1->dynsymtab_section->data_offset);
1451 for(esym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1;
1452 esym < sym_end;
1453 esym++) {
1454 if (esym->st_shndx == SHN_UNDEF) {
1455 name = s1->dynsymtab_section->link->data + esym->st_name;
1456 sym_index = find_elf_sym(symtab_section, name);
1457 if (sym_index) {
1458 /* XXX: avoid adding a symbol if already
1459 present because of -rdynamic ? */
1460 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
1461 put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1462 sym->st_info, 0,
1463 sym->st_shndx, name);
1464 } else {
1465 if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
1466 /* weak symbols can stay undefined */
1467 } else {
1468 warning("undefined dynamic symbol '%s'", name);
1473 } else {
1474 int nb_syms;
1475 /* shared library case : we simply export all the global symbols */
1476 nb_syms = symtab_section->data_offset / sizeof(ElfW(Sym));
1477 s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
1478 for(sym = (ElfW(Sym) *)symtab_section->data + 1;
1479 sym < sym_end;
1480 sym++) {
1481 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
1482 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1483 if (ELFW(ST_TYPE)(sym->st_info) == STT_FUNC &&
1484 sym->st_shndx == SHN_UNDEF) {
1485 put_got_entry(s1, R_JMP_SLOT, sym->st_size,
1486 sym->st_info,
1487 sym - (ElfW(Sym) *)symtab_section->data);
1489 else if (ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT) {
1490 put_got_entry(s1, R_X86_64_GLOB_DAT, sym->st_size,
1491 sym->st_info,
1492 sym - (ElfW(Sym) *)symtab_section->data);
1494 else
1495 #endif
1497 name = symtab_section->link->data + sym->st_name;
1498 index = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
1499 sym->st_info, 0,
1500 sym->st_shndx, name);
1501 s1->symtab_to_dynsym[sym -
1502 (ElfW(Sym) *)symtab_section->data] =
1503 index;
1509 build_got_entries(s1);
1511 /* add a list of needed dlls */
1512 for(i = 0; i < s1->nb_loaded_dlls; i++) {
1513 DLLReference *dllref = s1->loaded_dlls[i];
1514 if (dllref->level == 0)
1515 put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
1517 /* XXX: currently, since we do not handle PIC code, we
1518 must relocate the readonly segments */
1519 if (file_type == TCC_OUTPUT_DLL) {
1520 if (s1->soname)
1521 put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
1522 put_dt(dynamic, DT_TEXTREL, 0);
1525 /* add necessary space for other entries */
1526 saved_dynamic_data_offset = dynamic->data_offset;
1527 dynamic->data_offset += sizeof(ElfW(Dyn)) * 9;
1528 } else {
1529 /* still need to build got entries in case of static link */
1530 build_got_entries(s1);
1534 memset(&ehdr, 0, sizeof(ehdr));
1536 /* we add a section for symbols */
1537 strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
1538 put_elf_str(strsec, "");
1540 /* compute number of sections */
1541 shnum = s1->nb_sections;
1543 /* this array is used to reorder sections in the output file */
1544 section_order = tcc_malloc(sizeof(int) * shnum);
1545 section_order[0] = 0;
1546 sh_order_index = 1;
1548 /* compute number of program headers */
1549 switch(file_type) {
1550 default:
1551 case TCC_OUTPUT_OBJ:
1552 phnum = 0;
1553 break;
1554 case TCC_OUTPUT_EXE:
1555 if (!s1->static_link)
1556 phnum = 4;
1557 else
1558 phnum = 2;
1559 break;
1560 case TCC_OUTPUT_DLL:
1561 phnum = 3;
1562 break;
1565 /* allocate strings for section names and decide if an unallocated
1566 section should be output */
1567 /* NOTE: the strsec section comes last, so its size is also
1568 correct ! */
1569 for(i = 1; i < s1->nb_sections; i++) {
1570 s = s1->sections[i];
1571 s->sh_name = put_elf_str(strsec, s->name);
1572 #if 0 //gr
1573 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1574 s->sh_flags,
1575 s->sh_type,
1576 s->sh_info,
1577 s->name,
1578 s->reloc ? s->reloc->name : "n"
1580 #endif
1581 /* when generating a DLL, we include relocations but we may
1582 patch them */
1583 if (file_type == TCC_OUTPUT_DLL &&
1584 s->sh_type == SHT_RELX &&
1585 !(s->sh_flags & SHF_ALLOC)) {
1586 /* //gr: avoid bogus relocs for empty (debug) sections */
1587 if (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC)
1588 prepare_dynamic_rel(s1, s);
1589 else if (s1->do_debug)
1590 s->sh_size = s->data_offset;
1591 } else if (s1->do_debug ||
1592 file_type == TCC_OUTPUT_OBJ ||
1593 (s->sh_flags & SHF_ALLOC) ||
1594 i == (s1->nb_sections - 1)) {
1595 /* we output all sections if debug or object file */
1596 s->sh_size = s->data_offset;
1600 /* allocate program segment headers */
1601 phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
1603 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1604 file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1605 } else {
1606 file_offset = 0;
1608 if (phnum > 0) {
1609 /* compute section to program header mapping */
1610 if (s1->has_text_addr) {
1611 int a_offset, p_offset;
1612 addr = s1->text_addr;
1613 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1614 ELF_PAGE_SIZE */
1615 a_offset = addr & (ELF_PAGE_SIZE - 1);
1616 p_offset = file_offset & (ELF_PAGE_SIZE - 1);
1617 if (a_offset < p_offset)
1618 a_offset += ELF_PAGE_SIZE;
1619 file_offset += (a_offset - p_offset);
1620 } else {
1621 if (file_type == TCC_OUTPUT_DLL)
1622 addr = 0;
1623 else
1624 addr = ELF_START_ADDR;
1625 /* compute address after headers */
1626 addr += (file_offset & (ELF_PAGE_SIZE - 1));
1629 /* dynamic relocation table information, for .dynamic section */
1630 rel_size = 0;
1631 rel_addr = 0;
1633 /* leave one program header for the program interpreter */
1634 ph = &phdr[0];
1635 if (interp)
1636 ph++;
1638 for(j = 0; j < 2; j++) {
1639 ph->p_type = PT_LOAD;
1640 if (j == 0)
1641 ph->p_flags = PF_R | PF_X;
1642 else
1643 ph->p_flags = PF_R | PF_W;
1644 ph->p_align = ELF_PAGE_SIZE;
1646 /* we do the following ordering: interp, symbol tables,
1647 relocations, progbits, nobits */
1648 /* XXX: do faster and simpler sorting */
1649 for(k = 0; k < 5; k++) {
1650 for(i = 1; i < s1->nb_sections; i++) {
1651 s = s1->sections[i];
1652 /* compute if section should be included */
1653 if (j == 0) {
1654 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1655 SHF_ALLOC)
1656 continue;
1657 } else {
1658 if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
1659 (SHF_ALLOC | SHF_WRITE))
1660 continue;
1662 if (s == interp) {
1663 if (k != 0)
1664 continue;
1665 } else if (s->sh_type == SHT_DYNSYM ||
1666 s->sh_type == SHT_STRTAB ||
1667 s->sh_type == SHT_HASH) {
1668 if (k != 1)
1669 continue;
1670 } else if (s->sh_type == SHT_RELX) {
1671 if (k != 2)
1672 continue;
1673 } else if (s->sh_type == SHT_NOBITS) {
1674 if (k != 4)
1675 continue;
1676 } else {
1677 if (k != 3)
1678 continue;
1680 section_order[sh_order_index++] = i;
1682 /* section matches: we align it and add its size */
1683 tmp = addr;
1684 addr = (addr + s->sh_addralign - 1) &
1685 ~(s->sh_addralign - 1);
1686 file_offset += addr - tmp;
1687 s->sh_offset = file_offset;
1688 s->sh_addr = addr;
1690 /* update program header infos */
1691 if (ph->p_offset == 0) {
1692 ph->p_offset = file_offset;
1693 ph->p_vaddr = addr;
1694 ph->p_paddr = ph->p_vaddr;
1696 /* update dynamic relocation infos */
1697 if (s->sh_type == SHT_RELX) {
1698 if (rel_size == 0)
1699 rel_addr = addr;
1700 rel_size += s->sh_size;
1702 addr += s->sh_size;
1703 if (s->sh_type != SHT_NOBITS)
1704 file_offset += s->sh_size;
1707 ph->p_filesz = file_offset - ph->p_offset;
1708 ph->p_memsz = addr - ph->p_vaddr;
1709 ph++;
1710 if (j == 0) {
1711 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1712 /* if in the middle of a page, we duplicate the page in
1713 memory so that one copy is RX and the other is RW */
1714 if ((addr & (ELF_PAGE_SIZE - 1)) != 0)
1715 addr += ELF_PAGE_SIZE;
1716 } else {
1717 addr = (addr + ELF_PAGE_SIZE - 1) & ~(ELF_PAGE_SIZE - 1);
1718 file_offset = (file_offset + ELF_PAGE_SIZE - 1) &
1719 ~(ELF_PAGE_SIZE - 1);
1724 /* if interpreter, then add corresponing program header */
1725 if (interp) {
1726 ph = &phdr[0];
1728 ph->p_type = PT_INTERP;
1729 ph->p_offset = interp->sh_offset;
1730 ph->p_vaddr = interp->sh_addr;
1731 ph->p_paddr = ph->p_vaddr;
1732 ph->p_filesz = interp->sh_size;
1733 ph->p_memsz = interp->sh_size;
1734 ph->p_flags = PF_R;
1735 ph->p_align = interp->sh_addralign;
1738 /* if dynamic section, then add corresponing program header */
1739 if (dynamic) {
1740 ElfW(Sym) *sym_end;
1742 ph = &phdr[phnum - 1];
1744 ph->p_type = PT_DYNAMIC;
1745 ph->p_offset = dynamic->sh_offset;
1746 ph->p_vaddr = dynamic->sh_addr;
1747 ph->p_paddr = ph->p_vaddr;
1748 ph->p_filesz = dynamic->sh_size;
1749 ph->p_memsz = dynamic->sh_size;
1750 ph->p_flags = PF_R | PF_W;
1751 ph->p_align = dynamic->sh_addralign;
1753 /* put GOT dynamic section address */
1754 put32(s1->got->data, dynamic->sh_addr);
1756 /* relocate the PLT */
1757 if (file_type == TCC_OUTPUT_EXE
1758 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1759 || file_type == TCC_OUTPUT_DLL
1760 #endif
1762 uint8_t *p, *p_end;
1764 p = s1->plt->data;
1765 p_end = p + s1->plt->data_offset;
1766 if (p < p_end) {
1767 #if defined(TCC_TARGET_I386)
1768 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1769 put32(p + 8, get32(p + 8) + s1->got->sh_addr);
1770 p += 16;
1771 while (p < p_end) {
1772 put32(p + 2, get32(p + 2) + s1->got->sh_addr);
1773 p += 16;
1775 #elif defined(TCC_TARGET_X86_64)
1776 int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
1777 put32(p + 2, get32(p + 2) + x);
1778 put32(p + 8, get32(p + 8) + x - 6);
1779 p += 16;
1780 while (p < p_end) {
1781 put32(p + 2, get32(p + 2) + x + s1->plt->data - p);
1782 p += 16;
1784 #elif defined(TCC_TARGET_ARM)
1785 int x;
1786 x=s1->got->sh_addr - s1->plt->sh_addr - 12;
1787 p +=16;
1788 while (p < p_end) {
1789 put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
1790 p += 16;
1792 #elif defined(TCC_TARGET_C67)
1793 /* XXX: TODO */
1794 #else
1795 #error unsupported CPU
1796 #endif
1800 /* relocate symbols in .dynsym */
1801 sym_end = (ElfW(Sym) *)(s1->dynsym->data + s1->dynsym->data_offset);
1802 for(sym = (ElfW(Sym) *)s1->dynsym->data + 1;
1803 sym < sym_end;
1804 sym++) {
1805 if (sym->st_shndx == SHN_UNDEF) {
1806 /* relocate to the PLT if the symbol corresponds
1807 to a PLT entry */
1808 if (sym->st_value)
1809 sym->st_value += s1->plt->sh_addr;
1810 } else if (sym->st_shndx < SHN_LORESERVE) {
1811 /* do symbol relocation */
1812 sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
1816 /* put dynamic section entries */
1817 dynamic->data_offset = saved_dynamic_data_offset;
1818 put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
1819 put_dt(dynamic, DT_STRTAB, dynstr->sh_addr);
1820 put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
1821 put_dt(dynamic, DT_STRSZ, dynstr->data_offset);
1822 put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
1823 #ifdef TCC_TARGET_X86_64
1824 put_dt(dynamic, DT_RELA, rel_addr);
1825 put_dt(dynamic, DT_RELASZ, rel_size);
1826 put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
1827 #else
1828 put_dt(dynamic, DT_REL, rel_addr);
1829 put_dt(dynamic, DT_RELSZ, rel_size);
1830 put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
1831 #endif
1832 if (s1->do_debug)
1833 put_dt(dynamic, DT_DEBUG, 0);
1834 put_dt(dynamic, DT_NULL, 0);
1837 ehdr.e_phentsize = sizeof(ElfW(Phdr));
1838 ehdr.e_phnum = phnum;
1839 ehdr.e_phoff = sizeof(ElfW(Ehdr));
1842 /* all other sections come after */
1843 for(i = 1; i < s1->nb_sections; i++) {
1844 s = s1->sections[i];
1845 if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
1846 continue;
1847 section_order[sh_order_index++] = i;
1849 file_offset = (file_offset + s->sh_addralign - 1) &
1850 ~(s->sh_addralign - 1);
1851 s->sh_offset = file_offset;
1852 if (s->sh_type != SHT_NOBITS)
1853 file_offset += s->sh_size;
1856 /* if building executable or DLL, then relocate each section
1857 except the GOT which is already relocated */
1858 if (file_type != TCC_OUTPUT_OBJ) {
1859 relocate_syms(s1, 0);
1861 if (s1->nb_errors != 0) {
1862 fail:
1863 ret = -1;
1864 goto the_end;
1867 /* relocate sections */
1868 /* XXX: ignore sections with allocated relocations ? */
1869 for(i = 1; i < s1->nb_sections; i++) {
1870 s = s1->sections[i];
1871 if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
1872 relocate_section(s1, s);
1875 /* relocate relocation entries if the relocation tables are
1876 allocated in the executable */
1877 for(i = 1; i < s1->nb_sections; i++) {
1878 s = s1->sections[i];
1879 if ((s->sh_flags & SHF_ALLOC) &&
1880 s->sh_type == SHT_RELX) {
1881 relocate_rel(s1, s);
1885 /* get entry point address */
1886 if (file_type == TCC_OUTPUT_EXE)
1887 ehdr.e_entry = (uplong)tcc_get_symbol_err(s1, "_start");
1888 else
1889 ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
1892 /* write elf file */
1893 if (file_type == TCC_OUTPUT_OBJ)
1894 mode = 0666;
1895 else
1896 mode = 0777;
1897 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
1898 if (fd < 0) {
1899 error_noabort("could not write '%s'", filename);
1900 goto fail;
1902 f = fdopen(fd, "wb");
1903 if (s1->verbose)
1904 printf("<- %s\n", filename);
1906 #ifdef TCC_TARGET_COFF
1907 if (s1->output_format == TCC_OUTPUT_FORMAT_COFF) {
1908 tcc_output_coff(s1, f);
1909 } else
1910 #endif
1911 if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
1912 sort_syms(s1, symtab_section);
1914 /* align to 4 */
1915 file_offset = (file_offset + 3) & -4;
1917 /* fill header */
1918 ehdr.e_ident[0] = ELFMAG0;
1919 ehdr.e_ident[1] = ELFMAG1;
1920 ehdr.e_ident[2] = ELFMAG2;
1921 ehdr.e_ident[3] = ELFMAG3;
1922 ehdr.e_ident[4] = TCC_ELFCLASS;
1923 ehdr.e_ident[5] = ELFDATA2LSB;
1924 ehdr.e_ident[6] = EV_CURRENT;
1925 #ifdef __FreeBSD__
1926 ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
1927 #endif
1928 #ifdef TCC_TARGET_ARM
1929 #ifdef TCC_ARM_EABI
1930 ehdr.e_ident[EI_OSABI] = 0;
1931 ehdr.e_flags = 4 << 24;
1932 #else
1933 ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
1934 #endif
1935 #endif
1936 switch(file_type) {
1937 default:
1938 case TCC_OUTPUT_EXE:
1939 ehdr.e_type = ET_EXEC;
1940 break;
1941 case TCC_OUTPUT_DLL:
1942 ehdr.e_type = ET_DYN;
1943 break;
1944 case TCC_OUTPUT_OBJ:
1945 ehdr.e_type = ET_REL;
1946 break;
1948 ehdr.e_machine = EM_TCC_TARGET;
1949 ehdr.e_version = EV_CURRENT;
1950 ehdr.e_shoff = file_offset;
1951 ehdr.e_ehsize = sizeof(ElfW(Ehdr));
1952 ehdr.e_shentsize = sizeof(ElfW(Shdr));
1953 ehdr.e_shnum = shnum;
1954 ehdr.e_shstrndx = shnum - 1;
1956 fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
1957 fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
1958 offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
1960 for(i=1;i<s1->nb_sections;i++) {
1961 s = s1->sections[section_order[i]];
1962 if (s->sh_type != SHT_NOBITS) {
1963 while (offset < s->sh_offset) {
1964 fputc(0, f);
1965 offset++;
1967 size = s->sh_size;
1968 fwrite(s->data, 1, size, f);
1969 offset += size;
1973 /* output section headers */
1974 while (offset < ehdr.e_shoff) {
1975 fputc(0, f);
1976 offset++;
1979 for(i=0;i<s1->nb_sections;i++) {
1980 sh = &shdr;
1981 memset(sh, 0, sizeof(ElfW(Shdr)));
1982 s = s1->sections[i];
1983 if (s) {
1984 sh->sh_name = s->sh_name;
1985 sh->sh_type = s->sh_type;
1986 sh->sh_flags = s->sh_flags;
1987 sh->sh_entsize = s->sh_entsize;
1988 sh->sh_info = s->sh_info;
1989 if (s->link)
1990 sh->sh_link = s->link->sh_num;
1991 sh->sh_addralign = s->sh_addralign;
1992 sh->sh_addr = s->sh_addr;
1993 sh->sh_offset = s->sh_offset;
1994 sh->sh_size = s->sh_size;
1996 fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
1998 } else {
1999 tcc_output_binary(s1, f, section_order);
2001 fclose(f);
2003 ret = 0;
2004 the_end:
2005 tcc_free(s1->symtab_to_dynsym);
2006 tcc_free(section_order);
2007 tcc_free(phdr);
2008 tcc_free(s1->got_offsets);
2009 return ret;
2012 int tcc_output_file(TCCState *s, const char *filename)
2014 int ret;
2015 #ifdef TCC_TARGET_PE
2016 if (s->output_type != TCC_OUTPUT_OBJ) {
2017 ret = pe_output_file(s, filename);
2018 } else
2019 #endif
2021 ret = elf_output_file(s, filename);
2023 return ret;
2026 static void *load_data(int fd, unsigned long file_offset, unsigned long size)
2028 void *data;
2030 data = tcc_malloc(size);
2031 lseek(fd, file_offset, SEEK_SET);
2032 read(fd, data, size);
2033 return data;
2036 typedef struct SectionMergeInfo {
2037 Section *s; /* corresponding existing section */
2038 unsigned long offset; /* offset of the new section in the existing section */
2039 uint8_t new_section; /* true if section 's' was added */
2040 uint8_t link_once; /* true if link once section */
2041 } SectionMergeInfo;
2043 /* load an object file and merge it with current files */
2044 /* XXX: handle correctly stab (debug) info */
2045 static int tcc_load_object_file(TCCState *s1,
2046 int fd, unsigned long file_offset)
2048 ElfW(Ehdr) ehdr;
2049 ElfW(Shdr) *shdr, *sh;
2050 int size, i, j, offset, offseti, nb_syms, sym_index, ret;
2051 unsigned char *strsec, *strtab;
2052 int *old_to_new_syms;
2053 char *sh_name, *name;
2054 SectionMergeInfo *sm_table, *sm;
2055 ElfW(Sym) *sym, *symtab;
2056 ElfW_Rel *rel, *rel_end;
2057 Section *s;
2059 int stab_index;
2060 int stabstr_index;
2062 stab_index = stabstr_index = 0;
2064 if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
2065 goto fail1;
2066 if (ehdr.e_ident[0] != ELFMAG0 ||
2067 ehdr.e_ident[1] != ELFMAG1 ||
2068 ehdr.e_ident[2] != ELFMAG2 ||
2069 ehdr.e_ident[3] != ELFMAG3)
2070 goto fail1;
2071 /* test if object file */
2072 if (ehdr.e_type != ET_REL)
2073 goto fail1;
2074 /* test CPU specific stuff */
2075 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2076 ehdr.e_machine != EM_TCC_TARGET) {
2077 fail1:
2078 error_noabort("invalid object file");
2079 return -1;
2081 /* read sections */
2082 shdr = load_data(fd, file_offset + ehdr.e_shoff,
2083 sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2084 sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
2086 /* load section names */
2087 sh = &shdr[ehdr.e_shstrndx];
2088 strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2090 /* load symtab and strtab */
2091 old_to_new_syms = NULL;
2092 symtab = NULL;
2093 strtab = NULL;
2094 nb_syms = 0;
2095 for(i = 1; i < ehdr.e_shnum; i++) {
2096 sh = &shdr[i];
2097 if (sh->sh_type == SHT_SYMTAB) {
2098 if (symtab) {
2099 error_noabort("object must contain only one symtab");
2100 fail:
2101 ret = -1;
2102 goto the_end;
2104 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2105 symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2106 sm_table[i].s = symtab_section;
2108 /* now load strtab */
2109 sh = &shdr[sh->sh_link];
2110 strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
2114 /* now examine each section and try to merge its content with the
2115 ones in memory */
2116 for(i = 1; i < ehdr.e_shnum; i++) {
2117 /* no need to examine section name strtab */
2118 if (i == ehdr.e_shstrndx)
2119 continue;
2120 sh = &shdr[i];
2121 sh_name = strsec + sh->sh_name;
2122 /* ignore sections types we do not handle */
2123 if (sh->sh_type != SHT_PROGBITS &&
2124 sh->sh_type != SHT_RELX &&
2125 #ifdef TCC_ARM_EABI
2126 sh->sh_type != SHT_ARM_EXIDX &&
2127 #endif
2128 sh->sh_type != SHT_NOBITS &&
2129 strcmp(sh_name, ".stabstr")
2131 continue;
2132 if (sh->sh_addralign < 1)
2133 sh->sh_addralign = 1;
2134 /* find corresponding section, if any */
2135 for(j = 1; j < s1->nb_sections;j++) {
2136 s = s1->sections[j];
2137 if (!strcmp(s->name, sh_name)) {
2138 if (!strncmp(sh_name, ".gnu.linkonce",
2139 sizeof(".gnu.linkonce") - 1)) {
2140 /* if a 'linkonce' section is already present, we
2141 do not add it again. It is a little tricky as
2142 symbols can still be defined in
2143 it. */
2144 sm_table[i].link_once = 1;
2145 goto next;
2146 } else {
2147 goto found;
2151 /* not found: create new section */
2152 s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags);
2153 /* take as much info as possible from the section. sh_link and
2154 sh_info will be updated later */
2155 s->sh_addralign = sh->sh_addralign;
2156 s->sh_entsize = sh->sh_entsize;
2157 sm_table[i].new_section = 1;
2158 found:
2159 if (sh->sh_type != s->sh_type) {
2160 error_noabort("invalid section type");
2161 goto fail;
2164 /* align start of section */
2165 offset = s->data_offset;
2167 if (0 == strcmp(sh_name, ".stab")) {
2168 stab_index = i;
2169 goto no_align;
2171 if (0 == strcmp(sh_name, ".stabstr")) {
2172 stabstr_index = i;
2173 goto no_align;
2176 size = sh->sh_addralign - 1;
2177 offset = (offset + size) & ~size;
2178 if (sh->sh_addralign > s->sh_addralign)
2179 s->sh_addralign = sh->sh_addralign;
2180 s->data_offset = offset;
2181 no_align:
2182 sm_table[i].offset = offset;
2183 sm_table[i].s = s;
2184 /* concatenate sections */
2185 size = sh->sh_size;
2186 if (sh->sh_type != SHT_NOBITS) {
2187 unsigned char *ptr;
2188 lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
2189 ptr = section_ptr_add(s, size);
2190 read(fd, ptr, size);
2191 } else {
2192 s->data_offset += size;
2194 next: ;
2197 /* //gr relocate stab strings */
2198 if (stab_index && stabstr_index) {
2199 Stab_Sym *a, *b;
2200 unsigned o;
2201 s = sm_table[stab_index].s;
2202 a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
2203 b = (Stab_Sym *)(s->data + s->data_offset);
2204 o = sm_table[stabstr_index].offset;
2205 while (a < b)
2206 a->n_strx += o, a++;
2209 /* second short pass to update sh_link and sh_info fields of new
2210 sections */
2211 for(i = 1; i < ehdr.e_shnum; i++) {
2212 s = sm_table[i].s;
2213 if (!s || !sm_table[i].new_section)
2214 continue;
2215 sh = &shdr[i];
2216 if (sh->sh_link > 0)
2217 s->link = sm_table[sh->sh_link].s;
2218 if (sh->sh_type == SHT_RELX) {
2219 s->sh_info = sm_table[sh->sh_info].s->sh_num;
2220 /* update backward link */
2221 s1->sections[s->sh_info]->reloc = s;
2224 sm = sm_table;
2226 /* resolve symbols */
2227 old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
2229 sym = symtab + 1;
2230 for(i = 1; i < nb_syms; i++, sym++) {
2231 if (sym->st_shndx != SHN_UNDEF &&
2232 sym->st_shndx < SHN_LORESERVE) {
2233 sm = &sm_table[sym->st_shndx];
2234 if (sm->link_once) {
2235 /* if a symbol is in a link once section, we use the
2236 already defined symbol. It is very important to get
2237 correct relocations */
2238 if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
2239 name = strtab + sym->st_name;
2240 sym_index = find_elf_sym(symtab_section, name);
2241 if (sym_index)
2242 old_to_new_syms[i] = sym_index;
2244 continue;
2246 /* if no corresponding section added, no need to add symbol */
2247 if (!sm->s)
2248 continue;
2249 /* convert section number */
2250 sym->st_shndx = sm->s->sh_num;
2251 /* offset value */
2252 sym->st_value += sm->offset;
2254 /* add symbol */
2255 name = strtab + sym->st_name;
2256 sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
2257 sym->st_info, sym->st_other,
2258 sym->st_shndx, name);
2259 old_to_new_syms[i] = sym_index;
2262 /* third pass to patch relocation entries */
2263 for(i = 1; i < ehdr.e_shnum; i++) {
2264 s = sm_table[i].s;
2265 if (!s)
2266 continue;
2267 sh = &shdr[i];
2268 offset = sm_table[i].offset;
2269 switch(s->sh_type) {
2270 case SHT_RELX:
2271 /* take relocation offset information */
2272 offseti = sm_table[sh->sh_info].offset;
2273 rel_end = (ElfW_Rel *)(s->data + s->data_offset);
2274 for(rel = (ElfW_Rel *)(s->data + offset);
2275 rel < rel_end;
2276 rel++) {
2277 int type;
2278 unsigned sym_index;
2279 /* convert symbol index */
2280 type = ELFW(R_TYPE)(rel->r_info);
2281 sym_index = ELFW(R_SYM)(rel->r_info);
2282 /* NOTE: only one symtab assumed */
2283 if (sym_index >= nb_syms)
2284 goto invalid_reloc;
2285 sym_index = old_to_new_syms[sym_index];
2286 /* ignore link_once in rel section. */
2287 if (!sym_index && !sm->link_once) {
2288 invalid_reloc:
2289 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2290 i, strsec + sh->sh_name, rel->r_offset);
2291 goto fail;
2293 rel->r_info = ELFW(R_INFO)(sym_index, type);
2294 /* offset the relocation offset */
2295 rel->r_offset += offseti;
2297 break;
2298 default:
2299 break;
2303 ret = 0;
2304 the_end:
2305 tcc_free(symtab);
2306 tcc_free(strtab);
2307 tcc_free(old_to_new_syms);
2308 tcc_free(sm_table);
2309 tcc_free(strsec);
2310 tcc_free(shdr);
2311 return ret;
2314 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2316 typedef struct ArchiveHeader {
2317 char ar_name[16]; /* name of this member */
2318 char ar_date[12]; /* file mtime */
2319 char ar_uid[6]; /* owner uid; printed as decimal */
2320 char ar_gid[6]; /* owner gid; printed as decimal */
2321 char ar_mode[8]; /* file mode, printed as octal */
2322 char ar_size[10]; /* file size, printed as decimal */
2323 char ar_fmag[2]; /* should contain ARFMAG */
2324 } ArchiveHeader;
2326 static int get_be32(const uint8_t *b)
2328 return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2331 /* load only the objects which resolve undefined symbols */
2332 static int tcc_load_alacarte(TCCState *s1, int fd, int size)
2334 int i, bound, nsyms, sym_index, off, ret;
2335 uint8_t *data;
2336 const char *ar_names, *p;
2337 const uint8_t *ar_index;
2338 ElfW(Sym) *sym;
2340 data = tcc_malloc(size);
2341 if (read(fd, data, size) != size)
2342 goto fail;
2343 nsyms = get_be32(data);
2344 ar_index = data + 4;
2345 ar_names = ar_index + nsyms * 4;
2347 do {
2348 bound = 0;
2349 for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
2350 sym_index = find_elf_sym(symtab_section, p);
2351 if(sym_index) {
2352 sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
2353 if(sym->st_shndx == SHN_UNDEF) {
2354 off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
2355 #if 0
2356 printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
2357 #endif
2358 ++bound;
2359 lseek(fd, off, SEEK_SET);
2360 if(tcc_load_object_file(s1, fd, off) < 0) {
2361 fail:
2362 ret = -1;
2363 goto the_end;
2368 } while(bound);
2369 ret = 0;
2370 the_end:
2371 tcc_free(data);
2372 return ret;
2375 /* load a '.a' file */
2376 static int tcc_load_archive(TCCState *s1, int fd)
2378 ArchiveHeader hdr;
2379 char ar_size[11];
2380 char ar_name[17];
2381 char magic[8];
2382 int size, len, i;
2383 unsigned long file_offset;
2385 /* skip magic which was already checked */
2386 read(fd, magic, sizeof(magic));
2388 for(;;) {
2389 len = read(fd, &hdr, sizeof(hdr));
2390 if (len == 0)
2391 break;
2392 if (len != sizeof(hdr)) {
2393 error_noabort("invalid archive");
2394 return -1;
2396 memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
2397 ar_size[sizeof(hdr.ar_size)] = '\0';
2398 size = strtol(ar_size, NULL, 0);
2399 memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
2400 for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
2401 if (ar_name[i] != ' ')
2402 break;
2404 ar_name[i + 1] = '\0';
2405 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2406 file_offset = lseek(fd, 0, SEEK_CUR);
2407 /* align to even */
2408 size = (size + 1) & ~1;
2409 if (!strcmp(ar_name, "/")) {
2410 /* coff symbol table : we handle it */
2411 if(s1->alacarte_link)
2412 return tcc_load_alacarte(s1, fd, size);
2413 } else if (!strcmp(ar_name, "//") ||
2414 !strcmp(ar_name, "__.SYMDEF") ||
2415 !strcmp(ar_name, "__.SYMDEF/") ||
2416 !strcmp(ar_name, "ARFILENAMES/")) {
2417 /* skip symbol table or archive names */
2418 } else {
2419 if (tcc_load_object_file(s1, fd, file_offset) < 0)
2420 return -1;
2422 lseek(fd, file_offset + size, SEEK_SET);
2424 return 0;
2427 #ifndef TCC_TARGET_PE
2428 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2429 is referenced by the user (so it should be added as DT_NEEDED in
2430 the generated ELF file) */
2431 static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
2433 ElfW(Ehdr) ehdr;
2434 ElfW(Shdr) *shdr, *sh, *sh1;
2435 int i, j, nb_syms, nb_dts, sym_bind, ret;
2436 ElfW(Sym) *sym, *dynsym;
2437 ElfW(Dyn) *dt, *dynamic;
2438 unsigned char *dynstr;
2439 const char *name, *soname;
2440 DLLReference *dllref;
2442 read(fd, &ehdr, sizeof(ehdr));
2444 /* test CPU specific stuff */
2445 if (ehdr.e_ident[5] != ELFDATA2LSB ||
2446 ehdr.e_machine != EM_TCC_TARGET) {
2447 error_noabort("bad architecture");
2448 return -1;
2451 /* read sections */
2452 shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
2454 /* load dynamic section and dynamic symbols */
2455 nb_syms = 0;
2456 nb_dts = 0;
2457 dynamic = NULL;
2458 dynsym = NULL; /* avoid warning */
2459 dynstr = NULL; /* avoid warning */
2460 for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
2461 switch(sh->sh_type) {
2462 case SHT_DYNAMIC:
2463 nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
2464 dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
2465 break;
2466 case SHT_DYNSYM:
2467 nb_syms = sh->sh_size / sizeof(ElfW(Sym));
2468 dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
2469 sh1 = &shdr[sh->sh_link];
2470 dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
2471 break;
2472 default:
2473 break;
2477 /* compute the real library name */
2478 soname = tcc_basename(filename);
2480 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2481 if (dt->d_tag == DT_SONAME) {
2482 soname = dynstr + dt->d_un.d_val;
2486 /* if the dll is already loaded, do not load it */
2487 for(i = 0; i < s1->nb_loaded_dlls; i++) {
2488 dllref = s1->loaded_dlls[i];
2489 if (!strcmp(soname, dllref->name)) {
2490 /* but update level if needed */
2491 if (level < dllref->level)
2492 dllref->level = level;
2493 ret = 0;
2494 goto the_end;
2498 // printf("loading dll '%s'\n", soname);
2500 /* add the dll and its level */
2501 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
2502 dllref->level = level;
2503 strcpy(dllref->name, soname);
2504 dynarray_add((void ***)&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
2506 /* add dynamic symbols in dynsym_section */
2507 for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
2508 sym_bind = ELFW(ST_BIND)(sym->st_info);
2509 if (sym_bind == STB_LOCAL)
2510 continue;
2511 name = dynstr + sym->st_name;
2512 add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
2513 sym->st_info, sym->st_other, sym->st_shndx, name);
2516 /* load all referenced DLLs */
2517 for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
2518 switch(dt->d_tag) {
2519 case DT_NEEDED:
2520 name = dynstr + dt->d_un.d_val;
2521 for(j = 0; j < s1->nb_loaded_dlls; j++) {
2522 dllref = s1->loaded_dlls[j];
2523 if (!strcmp(name, dllref->name))
2524 goto already_loaded;
2526 if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
2527 error_noabort("referenced dll '%s' not found", name);
2528 ret = -1;
2529 goto the_end;
2531 already_loaded:
2532 break;
2535 ret = 0;
2536 the_end:
2537 tcc_free(dynstr);
2538 tcc_free(dynsym);
2539 tcc_free(dynamic);
2540 tcc_free(shdr);
2541 return ret;
2544 #define LD_TOK_NAME 256
2545 #define LD_TOK_EOF (-1)
2547 /* return next ld script token */
2548 static int ld_next(TCCState *s1, char *name, int name_size)
2550 int c;
2551 char *q;
2553 redo:
2554 switch(ch) {
2555 case ' ':
2556 case '\t':
2557 case '\f':
2558 case '\v':
2559 case '\r':
2560 case '\n':
2561 inp();
2562 goto redo;
2563 case '/':
2564 minp();
2565 if (ch == '*') {
2566 file->buf_ptr = parse_comment(file->buf_ptr);
2567 ch = file->buf_ptr[0];
2568 goto redo;
2569 } else {
2570 q = name;
2571 *q++ = '/';
2572 goto parse_name;
2574 break;
2575 /* case 'a' ... 'z': */
2576 case 'a':
2577 case 'b':
2578 case 'c':
2579 case 'd':
2580 case 'e':
2581 case 'f':
2582 case 'g':
2583 case 'h':
2584 case 'i':
2585 case 'j':
2586 case 'k':
2587 case 'l':
2588 case 'm':
2589 case 'n':
2590 case 'o':
2591 case 'p':
2592 case 'q':
2593 case 'r':
2594 case 's':
2595 case 't':
2596 case 'u':
2597 case 'v':
2598 case 'w':
2599 case 'x':
2600 case 'y':
2601 case 'z':
2602 /* case 'A' ... 'z': */
2603 case 'A':
2604 case 'B':
2605 case 'C':
2606 case 'D':
2607 case 'E':
2608 case 'F':
2609 case 'G':
2610 case 'H':
2611 case 'I':
2612 case 'J':
2613 case 'K':
2614 case 'L':
2615 case 'M':
2616 case 'N':
2617 case 'O':
2618 case 'P':
2619 case 'Q':
2620 case 'R':
2621 case 'S':
2622 case 'T':
2623 case 'U':
2624 case 'V':
2625 case 'W':
2626 case 'X':
2627 case 'Y':
2628 case 'Z':
2629 case '_':
2630 case '\\':
2631 case '.':
2632 case '$':
2633 case '~':
2634 q = name;
2635 parse_name:
2636 for(;;) {
2637 if (!((ch >= 'a' && ch <= 'z') ||
2638 (ch >= 'A' && ch <= 'Z') ||
2639 (ch >= '0' && ch <= '9') ||
2640 strchr("/.-_+=$:\\,~", ch)))
2641 break;
2642 if ((q - name) < name_size - 1) {
2643 *q++ = ch;
2645 minp();
2647 *q = '\0';
2648 c = LD_TOK_NAME;
2649 break;
2650 case CH_EOF:
2651 c = LD_TOK_EOF;
2652 break;
2653 default:
2654 c = ch;
2655 inp();
2656 break;
2658 #if 0
2659 printf("tok=%c %d\n", c, c);
2660 if (c == LD_TOK_NAME)
2661 printf(" name=%s\n", name);
2662 #endif
2663 return c;
2666 static int ld_add_file_list(TCCState *s1, int as_needed)
2668 char filename[1024];
2669 int t, ret;
2671 t = ld_next(s1, filename, sizeof(filename));
2672 if (t != '(')
2673 expect("(");
2674 t = ld_next(s1, filename, sizeof(filename));
2675 for(;;) {
2676 if (t == LD_TOK_EOF) {
2677 error_noabort("unexpected end of file");
2678 return -1;
2679 } else if (t == ')') {
2680 break;
2681 } else if (t != LD_TOK_NAME) {
2682 error_noabort("filename expected");
2683 return -1;
2685 if (!strcmp(filename, "AS_NEEDED")) {
2686 ret = ld_add_file_list(s1, 1);
2687 if (ret)
2688 return ret;
2689 } else {
2690 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2691 if (!as_needed)
2692 tcc_add_file(s1, filename);
2694 t = ld_next(s1, filename, sizeof(filename));
2695 if (t == ',') {
2696 t = ld_next(s1, filename, sizeof(filename));
2699 return 0;
2702 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2703 files */
2704 static int tcc_load_ldscript(TCCState *s1)
2706 char cmd[64];
2707 char filename[1024];
2708 int t, ret;
2710 ch = file->buf_ptr[0];
2711 ch = handle_eob();
2712 for(;;) {
2713 t = ld_next(s1, cmd, sizeof(cmd));
2714 if (t == LD_TOK_EOF)
2715 return 0;
2716 else if (t != LD_TOK_NAME)
2717 return -1;
2718 if (!strcmp(cmd, "INPUT") ||
2719 !strcmp(cmd, "GROUP")) {
2720 ret = ld_add_file_list(s1, 0);
2721 if (ret)
2722 return ret;
2723 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
2724 !strcmp(cmd, "TARGET")) {
2725 /* ignore some commands */
2726 t = ld_next(s1, cmd, sizeof(cmd));
2727 if (t != '(')
2728 expect("(");
2729 for(;;) {
2730 t = ld_next(s1, filename, sizeof(filename));
2731 if (t == LD_TOK_EOF) {
2732 error_noabort("unexpected end of file");
2733 return -1;
2734 } else if (t == ')') {
2735 break;
2738 } else {
2739 return -1;
2742 return 0;
2744 #endif