2 * ELF file handling for TCC
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
23 static int new_undef_sym
= 0; /* Is there a new undefined sym since last new_undef_sym() */
25 ST_FUNC
int put_elf_str(Section
*s
, const char *sym
)
30 len
= strlen(sym
) + 1;
31 offset
= s
->data_offset
;
32 ptr
= section_ptr_add(s
, len
);
33 memcpy(ptr
, sym
, len
);
37 /* elf symbol hashing function */
38 static unsigned long elf_hash(const unsigned char *name
)
40 unsigned long h
= 0, g
;
43 h
= (h
<< 4) + *name
++;
52 /* rebuild hash table of section s */
53 /* NOTE: we do factorize the hash table code to go faster */
54 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
57 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
60 strtab
= s
->link
->data
;
61 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
63 s
->hash
->data_offset
= 0;
64 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
69 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
70 ptr
+= nb_buckets
+ 1;
72 sym
= (ElfW(Sym
) *)s
->data
+ 1;
73 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
74 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
75 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
86 /* return the symbol number */
87 ST_FUNC
int put_elf_sym(Section
*s
, uplong value
, unsigned long size
,
88 int info
, int other
, int shndx
, const char *name
)
90 int name_offset
, sym_index
;
95 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
97 name_offset
= put_elf_str(s
->link
, name
);
100 /* XXX: endianness */
101 sym
->st_name
= name_offset
;
102 sym
->st_value
= value
;
105 sym
->st_other
= other
;
106 sym
->st_shndx
= shndx
;
107 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
111 ptr
= section_ptr_add(hs
, sizeof(int));
112 base
= (int *)hs
->data
;
113 /* only add global or weak symbols */
114 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
115 /* add another hashing entry */
117 h
= elf_hash(name
) % nbuckets
;
119 base
[2 + h
] = sym_index
;
121 /* we resize the hash table */
122 hs
->nb_hashed_syms
++;
123 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
124 rebuild_hash(s
, 2 * nbuckets
);
134 /* find global ELF symbol 'name' and return its index. Return 0 if not
136 ST_FUNC
int find_elf_sym(Section
*s
, const char *name
)
140 int nbuckets
, sym_index
, h
;
146 nbuckets
= ((int *)hs
->data
)[0];
147 h
= elf_hash(name
) % nbuckets
;
148 sym_index
= ((int *)hs
->data
)[2 + h
];
149 while (sym_index
!= 0) {
150 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
151 name1
= s
->link
->data
+ sym
->st_name
;
152 if (!strcmp(name
, name1
))
154 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
159 /* return elf symbol value, signal error if 'err' is nonzero */
160 static void *get_elf_sym_addr(TCCState
*s
, const char *name
, int err
)
165 sym_index
= find_elf_sym(symtab_section
, name
);
166 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
167 if (!sym_index
|| sym
->st_shndx
== SHN_UNDEF
) {
169 error("%s not defined", name
);
172 return (void*)(uplong
)sym
->st_value
;
175 /* return elf symbol value */
176 LIBTCCAPI
void *tcc_get_symbol(TCCState
*s
, const char *name
)
178 return get_elf_sym_addr(s
, name
, 0);
181 /* return elf symbol value or error */
182 ST_FUNC
void *tcc_get_symbol_err(TCCState
*s
, const char *name
)
184 return get_elf_sym_addr(s
, name
, 1);
187 /* add an elf symbol : check if it is already defined and patch
188 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
189 ST_FUNC
int add_elf_sym(Section
*s
, uplong value
, unsigned long size
,
190 int info
, int other
, int sh_num
, const char *name
)
193 int sym_bind
, sym_index
, sym_type
, esym_bind
;
194 unsigned char sym_vis
, esym_vis
, new_vis
;
196 sym_bind
= ELFW(ST_BIND
)(info
);
197 sym_type
= ELFW(ST_TYPE
)(info
);
198 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
200 if (sym_bind
!= STB_LOCAL
) {
201 /* we search global or weak symbols */
202 sym_index
= find_elf_sym(s
, name
);
205 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
206 if (esym
->st_shndx
!= SHN_UNDEF
) {
207 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
208 /* propagate the most constraining visibility */
209 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
210 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
211 if (esym_vis
== STV_DEFAULT
) {
213 } else if (sym_vis
== STV_DEFAULT
) {
216 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
218 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
220 other
= esym
->st_other
; /* in case we have to patch esym */
221 if (sh_num
== SHN_UNDEF
) {
222 /* ignore adding of undefined symbol if the
223 corresponding symbol is already defined */
224 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
225 /* global overrides weak, so patch */
227 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
228 /* weak is ignored if already global */
229 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_WEAK
) {
230 /* keep first-found weak definition, ignore subsequents */
231 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
232 /* ignore hidden symbols after */
233 } else if (esym
->st_shndx
== SHN_COMMON
234 && (sh_num
< SHN_LORESERVE
|| sh_num
== SHN_COMMON
)) {
235 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
236 No idea if this is the correct solution ... */
238 } else if (s
== tcc_state
->dynsymtab_section
) {
239 /* we accept that two DLL define the same symbol */
242 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
243 sym_bind
, sh_num
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
245 error_noabort("'%s' defined twice", name
);
249 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
250 esym
->st_shndx
= sh_num
;
252 esym
->st_value
= value
;
253 esym
->st_size
= size
;
254 esym
->st_other
= other
;
258 sym_index
= put_elf_sym(s
, value
, size
,
259 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
266 ST_FUNC
void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
267 int type
, int symbol
)
275 /* if no relocation section, create it */
276 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
277 /* if the symtab is allocated, then we consider the relocation
279 sr
= new_section(tcc_state
, buf
, SHT_RELX
, symtab
->sh_flags
);
280 sr
->sh_entsize
= sizeof(ElfW_Rel
);
282 sr
->sh_info
= s
->sh_num
;
285 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
286 rel
->r_offset
= offset
;
287 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
288 #ifdef TCC_TARGET_X86_64
293 /* put stab debug information */
295 ST_FUNC
void put_stabs(const char *str
, int type
, int other
, int desc
,
300 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
302 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
307 sym
->n_other
= other
;
309 sym
->n_value
= value
;
312 ST_FUNC
void put_stabs_r(const char *str
, int type
, int other
, int desc
,
313 unsigned long value
, Section
*sec
, int sym_index
)
315 put_stabs(str
, type
, other
, desc
, value
);
316 put_elf_reloc(symtab_section
, stab_section
,
317 stab_section
->data_offset
- sizeof(unsigned int),
318 R_DATA_32
, sym_index
);
321 ST_FUNC
void put_stabn(int type
, int other
, int desc
, int value
)
323 put_stabs(NULL
, type
, other
, desc
, value
);
326 ST_FUNC
void put_stabd(int type
, int other
, int desc
)
328 put_stabs(NULL
, type
, other
, desc
, 0);
331 /* In an ELF file symbol table, the local symbols must appear below
332 the global and weak ones. Since TCC cannot sort it while generating
333 the code, we must do it after. All the relocation tables are also
334 modified to take into account the symbol table sorting */
335 static void sort_syms(TCCState
*s1
, Section
*s
)
337 int *old_to_new_syms
;
341 ElfW_Rel
*rel
, *rel_end
;
345 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
346 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
347 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
349 /* first pass for local symbols */
350 p
= (ElfW(Sym
) *)s
->data
;
352 for(i
= 0; i
< nb_syms
; i
++) {
353 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
354 old_to_new_syms
[i
] = q
- new_syms
;
359 /* save the number of local symbols in section header */
360 s
->sh_info
= q
- new_syms
;
362 /* then second pass for non local symbols */
363 p
= (ElfW(Sym
) *)s
->data
;
364 for(i
= 0; i
< nb_syms
; i
++) {
365 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
366 old_to_new_syms
[i
] = q
- new_syms
;
372 /* we copy the new symbols to the old */
373 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
376 /* now we modify all the relocations */
377 for(i
= 1; i
< s1
->nb_sections
; i
++) {
378 sr
= s1
->sections
[i
];
379 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
380 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
381 for(rel
= (ElfW_Rel
*)sr
->data
;
384 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
385 type
= ELFW(R_TYPE
)(rel
->r_info
);
386 sym_index
= old_to_new_syms
[sym_index
];
387 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
392 tcc_free(old_to_new_syms
);
395 /* relocate common symbols in the .bss section */
396 ST_FUNC
void relocate_common_syms(void)
398 ElfW(Sym
) *sym
, *sym_end
;
399 unsigned long offset
, align
;
401 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
402 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
405 if (sym
->st_shndx
== SHN_COMMON
) {
407 align
= sym
->st_value
;
408 offset
= bss_section
->data_offset
;
409 offset
= (offset
+ align
- 1) & -align
;
410 sym
->st_value
= offset
;
411 sym
->st_shndx
= bss_section
->sh_num
;
412 offset
+= sym
->st_size
;
413 bss_section
->data_offset
= offset
;
418 /* relocate symbol table, resolve undefined symbols if do_resolve is
419 true and output error if undefined symbol. */
420 ST_FUNC
void relocate_syms(TCCState
*s1
, int do_resolve
)
422 ElfW(Sym
) *sym
, *esym
, *sym_end
;
423 int sym_bind
, sh_num
, sym_index
;
426 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
427 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
430 sh_num
= sym
->st_shndx
;
431 if (sh_num
== SHN_UNDEF
) {
432 name
= strtab_section
->data
+ sym
->st_name
;
434 #if !defined TCC_TARGET_PE || !defined _WIN32
436 name
= symtab_section
->link
->data
+ sym
->st_name
;
437 addr
= resolve_sym(s1
, name
);
439 sym
->st_value
= (uplong
)addr
;
443 } else if (s1
->dynsym
) {
444 /* if dynamic symbol exist, then use it */
445 sym_index
= find_elf_sym(s1
->dynsym
, name
);
447 esym
= &((ElfW(Sym
) *)s1
->dynsym
->data
)[sym_index
];
448 sym
->st_value
= esym
->st_value
;
452 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
454 if (!strcmp(name
, "_fp_hw"))
456 /* only weak symbols are accepted to be undefined. Their
458 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
459 if (sym_bind
== STB_WEAK
) {
462 error_noabort("undefined symbol '%s'", name
);
464 } else if (sh_num
< SHN_LORESERVE
) {
465 /* add section base */
466 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
472 #ifndef TCC_TARGET_PE
473 #ifdef TCC_TARGET_X86_64
474 #define JMP_TABLE_ENTRY_SIZE 14
475 static uplong
add_jmp_table(TCCState
*s1
, uplong val
)
477 char *p
= s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
;
478 s1
->runtime_plt_and_got_offset
+= JMP_TABLE_ENTRY_SIZE
;
483 *(uplong
*)(p
+ 6) = val
;
487 static uplong
add_got_table(TCCState
*s1
, uplong val
)
489 uplong
*p
= (uplong
*)(s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
);
490 s1
->runtime_plt_and_got_offset
+= sizeof(uplong
);
494 #elif defined TCC_TARGET_ARM
495 #define JMP_TABLE_ENTRY_SIZE 8
496 static uplong
add_jmp_table(TCCState
*s1
, int val
)
498 uint32_t *p
= (uint32_t *)(s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
);
499 s1
->runtime_plt_and_got_offset
+= JMP_TABLE_ENTRY_SIZE
;
500 /* ldr pc, [pc, #-4] */
508 /* relocate a given section (CPU dependent) */
509 ST_FUNC
void relocate_section(TCCState
*s1
, Section
*s
)
512 ElfW_Rel
*rel
, *rel_end
, *qrel
;
517 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
522 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
523 qrel
= (ElfW_Rel
*)sr
->data
;
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
];
532 #ifdef TCC_TARGET_X86_64
533 val
+= rel
->r_addend
;
535 type
= ELFW(R_TYPE
)(rel
->r_info
);
536 addr
= s
->sh_addr
+ rel
->r_offset
;
540 #if defined(TCC_TARGET_I386)
542 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
543 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
544 qrel
->r_offset
= rel
->r_offset
;
546 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_32
);
550 qrel
->r_info
= ELFW(R_INFO
)(0, R_386_RELATIVE
);
557 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
559 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
561 qrel
->r_offset
= rel
->r_offset
;
562 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_PC32
);
567 *(int *)ptr
+= val
- addr
;
570 *(int *)ptr
+= val
- addr
;
577 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
580 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
583 /* we load the got offset */
584 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
587 if (s1
->output_format
!= TCC_OUTPUT_FORMAT_BINARY
) {
589 error("can only produce 16-bit binary files");
591 *(short *)ptr
+= val
;
594 if (s1
->output_format
!= TCC_OUTPUT_FORMAT_BINARY
)
596 *(short *)ptr
+= val
- addr
;
598 #elif defined(TCC_TARGET_ARM)
605 x
= (*(int *)ptr
)&0xffffff;
606 (*(int *)ptr
) &= 0xff000000;
611 #ifndef TCC_TARGET_PE
612 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
613 if (s1
->output_type
== TCC_OUTPUT_MEMORY
)
614 x
+= add_jmp_table(s1
, val
) - val
; /* add veneer */
616 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
617 error("can't relocate value at %x",addr
);
626 x
= (*(int *)ptr
) & 0x7fffffff;
627 (*(int *)ptr
) &= 0x80000000;
630 if((x
^(x
>>1))&0x40000000)
631 error("can't relocate value at %x",addr
);
632 (*(int *)ptr
) |= x
& 0x7fffffff;
637 case R_ARM_BASE_PREL
:
638 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
641 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
644 /* we load the got offset */
645 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
650 /* trade Thumb support for ARMv4 support */
651 if ((0x0ffffff0 & *(int*)ptr
) == 0x012FFF10)
652 *(int*)ptr
^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */
655 fprintf(stderr
,"FIXME: handle reloc type %x at %x [%.8x] to %x\n",
656 type
, (unsigned)addr
, (unsigned)(uplong
)ptr
, (unsigned)val
);
658 #elif defined(TCC_TARGET_C67)
666 /* put the low 16 bits of the absolute address */
667 // add to what is already there
669 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
670 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
672 //patch both at once - assumes always in pairs Low - High
674 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
675 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
681 fprintf(stderr
,"FIXME: handle reloc type %x at %x [%.8x] to %x\n",
682 type
, (unsigned)addr
, (unsigned)(uplong
)ptr
, (unsigned)val
);
684 #elif defined(TCC_TARGET_X86_64)
686 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
687 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
688 qrel
->r_addend
= *(long long *)ptr
+ val
;
691 *(long long *)ptr
+= val
;
695 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
696 /* XXX: this logic may depend on TCC's codegen
697 now TCC uses R_X86_64_32 even for a 64bit pointer */
698 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
699 qrel
->r_addend
= *(int *)ptr
+ val
;
706 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
708 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
710 qrel
->r_offset
= rel
->r_offset
;
711 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_X86_64_PC32
);
712 qrel
->r_addend
= *(int *)ptr
;
718 case R_X86_64_PLT32
: {
720 diff
= (long long)val
- addr
;
721 if (diff
<= -2147483647 || diff
> 2147483647) {
722 #ifndef TCC_TARGET_PE
723 /* XXX: naive support for over 32bit jump */
724 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
725 val
= (add_jmp_table(s1
, val
- rel
->r_addend
) +
730 if (diff
<= -2147483647 || diff
> 2147483647) {
731 error("internal error: relocation failed");
737 case R_X86_64_GLOB_DAT
:
738 case R_X86_64_JUMP_SLOT
:
739 /* They don't need addend */
740 *(int *)ptr
= val
- rel
->r_addend
;
742 case R_X86_64_GOTPCREL
:
743 #ifndef TCC_TARGET_PE
744 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
745 val
= add_got_table(s1
, val
- rel
->r_addend
) + rel
->r_addend
;
746 *(int *)ptr
+= val
- addr
;
750 *(int *)ptr
+= (s1
->got
->sh_addr
- addr
+
751 s1
->got_offsets
[sym_index
] - 4);
753 case R_X86_64_GOTTPOFF
:
754 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
757 /* we load the got offset */
758 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
761 #error unsupported processor
765 /* if the relocation is allocated, we change its symbol table */
766 if (sr
->sh_flags
& SHF_ALLOC
)
767 sr
->link
= s1
->dynsym
;
770 /* relocate relocation table in 'sr' */
771 static void relocate_rel(TCCState
*s1
, Section
*sr
)
774 ElfW_Rel
*rel
, *rel_end
;
776 s
= s1
->sections
[sr
->sh_info
];
777 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
778 for(rel
= (ElfW_Rel
*)sr
->data
;
781 rel
->r_offset
+= s
->sh_addr
;
785 /* count the number of dynamic relocations so that we can reserve
787 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
789 ElfW_Rel
*rel
, *rel_end
;
790 int sym_index
, esym_index
, type
, count
;
793 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
794 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
795 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
796 type
= ELFW(R_TYPE
)(rel
->r_info
);
798 #if defined(TCC_TARGET_I386)
800 #elif defined(TCC_TARGET_X86_64)
807 #if defined(TCC_TARGET_I386)
809 #elif defined(TCC_TARGET_X86_64)
812 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
821 /* allocate the section */
822 sr
->sh_flags
|= SHF_ALLOC
;
823 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
828 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
833 if (index
>= s1
->nb_got_offsets
) {
834 /* find immediately bigger power of 2 and reallocate array */
838 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
840 error("memory full");
841 s1
->got_offsets
= tab
;
842 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
843 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
844 s1
->nb_got_offsets
= n
;
846 s1
->got_offsets
[index
] = val
;
849 /* XXX: suppress that */
850 static void put32(unsigned char *p
, uint32_t val
)
858 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
859 defined(TCC_TARGET_X86_64)
860 static uint32_t get32(unsigned char *p
)
862 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
866 static void build_got(TCCState
*s1
)
870 /* if no got, then create it */
871 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
872 s1
->got
->sh_entsize
= 4;
873 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
874 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
875 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
877 /* keep space for _DYNAMIC pointer, if present */
879 /* two dummy got entries */
883 /* keep space for _DYNAMIC pointer, if present */
886 /* two dummy got entries */
894 /* put a got entry corresponding to a symbol in symtab_section. 'size'
895 and 'info' can be modifed if more precise info comes from the DLL */
896 static void put_got_entry(TCCState
*s1
,
897 int reloc_type
, unsigned long size
, int info
,
903 unsigned long offset
;
909 /* if a got entry already exists for that symbol, no need to add one */
910 if (sym_index
< s1
->nb_got_offsets
&&
911 s1
->got_offsets
[sym_index
] != 0)
914 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
917 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
918 name
= symtab_section
->link
->data
+ sym
->st_name
;
919 offset
= sym
->st_value
;
920 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
922 #ifdef TCC_TARGET_X86_64
932 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
935 /* if we build a DLL, we add a %ebx offset */
936 if (s1
->output_type
== TCC_OUTPUT_DLL
)
942 /* add a PLT entry */
944 if (plt
->data_offset
== 0) {
945 /* first plt entry */
946 p
= section_ptr_add(plt
, 16);
947 p
[0] = 0xff; /* pushl got + PTR_SIZE */
949 put32(p
+ 2, PTR_SIZE
);
950 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
952 put32(p
+ 8, PTR_SIZE
* 2);
955 p
= section_ptr_add(plt
, 16);
956 p
[0] = 0xff; /* jmp *(got + x) */
958 put32(p
+ 2, s1
->got
->data_offset
);
959 p
[6] = 0x68; /* push $xxx */
960 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
961 p
[11] = 0xe9; /* jmp plt_start */
962 put32(p
+ 12, -(plt
->data_offset
));
964 /* the symbol is modified so that it will be relocated to
966 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
967 if (s1
->output_type
== TCC_OUTPUT_EXE
)
969 offset
= plt
->data_offset
- 16;
971 #elif defined(TCC_TARGET_ARM)
972 if (reloc_type
== R_ARM_JUMP_SLOT
) {
976 /* if we build a DLL, we add a %ebx offset */
977 if (s1
->output_type
== TCC_OUTPUT_DLL
)
978 error("DLLs unimplemented!");
980 /* add a PLT entry */
982 if (plt
->data_offset
== 0) {
983 /* first plt entry */
984 p
= section_ptr_add(plt
, 16);
985 put32(p
, 0xe52de004);
986 put32(p
+ 4, 0xe59fe010);
987 put32(p
+ 8, 0xe08fe00e);
988 put32(p
+ 12, 0xe5bef008);
991 p
= section_ptr_add(plt
, 16);
992 put32(p
, 0xe59fc004);
993 put32(p
+4, 0xe08fc00c);
994 put32(p
+8, 0xe59cf000);
995 put32(p
+12, s1
->got
->data_offset
);
997 /* the symbol is modified so that it will be relocated to
999 if (s1
->output_type
== TCC_OUTPUT_EXE
)
1000 offset
= plt
->data_offset
- 16;
1002 #elif defined(TCC_TARGET_C67)
1003 error("C67 got not implemented");
1005 #error unsupported CPU
1007 index
= put_elf_sym(s1
->dynsym
, offset
,
1008 size
, info
, 0, sym
->st_shndx
, name
);
1009 /* put a got entry */
1010 put_elf_reloc(s1
->dynsym
, s1
->got
,
1011 s1
->got
->data_offset
,
1014 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
1018 /* build GOT and PLT entries */
1019 ST_FUNC
void build_got_entries(TCCState
*s1
)
1022 ElfW_Rel
*rel
, *rel_end
;
1024 int i
, type
, reloc_type
, sym_index
;
1026 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1027 s
= s1
->sections
[i
];
1028 if (s
->sh_type
!= SHT_RELX
)
1030 /* no need to handle got relocations */
1031 if (s
->link
!= symtab_section
)
1033 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
1034 for(rel
= (ElfW_Rel
*)s
->data
;
1037 type
= ELFW(R_TYPE
)(rel
->r_info
);
1039 #if defined(TCC_TARGET_I386)
1046 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1047 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1048 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1049 /* look at the symbol got offset. If none, then add one */
1050 if (type
== R_386_GOT32
)
1051 reloc_type
= R_386_GLOB_DAT
;
1053 reloc_type
= R_386_JMP_SLOT
;
1054 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1058 #elif defined(TCC_TARGET_ARM)
1059 case R_ARM_GOT_BREL
:
1060 case R_ARM_GOTOFF32
:
1061 case R_ARM_BASE_PREL
:
1065 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1066 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1067 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1068 /* look at the symbol got offset. If none, then add one */
1069 if (type
== R_ARM_GOT_BREL
)
1070 reloc_type
= R_ARM_GLOB_DAT
;
1072 reloc_type
= R_ARM_JUMP_SLOT
;
1073 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1077 #elif defined(TCC_TARGET_C67)
1084 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1085 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1086 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1087 /* look at the symbol got offset. If none, then add one */
1088 if (type
== R_C60_GOT32
)
1089 reloc_type
= R_C60_GLOB_DAT
;
1091 reloc_type
= R_C60_JMP_SLOT
;
1092 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1096 #elif defined(TCC_TARGET_X86_64)
1097 case R_X86_64_GOT32
:
1098 case R_X86_64_GOTTPOFF
:
1099 case R_X86_64_GOTPCREL
:
1100 case R_X86_64_PLT32
:
1103 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
||
1104 type
== R_X86_64_PLT32
) {
1105 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1106 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1107 /* look at the symbol got offset. If none, then add one */
1108 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
)
1109 reloc_type
= R_X86_64_GLOB_DAT
;
1111 reloc_type
= R_X86_64_JUMP_SLOT
;
1112 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1117 #error unsupported CPU
1126 ST_FUNC Section
*new_symtab(TCCState
*s1
,
1127 const char *symtab_name
, int sh_type
, int sh_flags
,
1128 const char *strtab_name
,
1129 const char *hash_name
, int hash_sh_flags
)
1131 Section
*symtab
, *strtab
, *hash
;
1132 int *ptr
, nb_buckets
;
1134 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1135 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1136 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1137 put_elf_str(strtab
, "");
1138 symtab
->link
= strtab
;
1139 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1143 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1144 hash
->sh_entsize
= sizeof(int);
1145 symtab
->hash
= hash
;
1146 hash
->link
= symtab
;
1148 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1149 ptr
[0] = nb_buckets
;
1151 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1155 /* put dynamic tag */
1156 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1159 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1161 dyn
->d_un
.d_val
= val
;
1164 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1168 char sym_start
[1024];
1171 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1172 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1174 s
= find_section(s1
, section_name
);
1179 end_offset
= s
->data_offset
;
1182 add_elf_sym(symtab_section
,
1184 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1185 s
->sh_num
, sym_start
);
1186 add_elf_sym(symtab_section
,
1188 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1189 s
->sh_num
, sym_end
);
1192 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
1194 #ifdef CONFIG_TCC_BCHECK
1196 Section
*init_section
;
1197 unsigned char *pinit
;
1200 if (0 == s1
->do_bounds_check
)
1203 /* XXX: add an object file to do that */
1204 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1206 add_elf_sym(symtab_section
, 0, 0,
1207 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1208 bounds_section
->sh_num
, "__bounds_start");
1209 /* add bound check code */
1210 #ifndef TCC_TARGET_PE
1213 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "bcheck.o");
1214 tcc_add_file(s1
, buf
);
1217 #ifdef TCC_TARGET_I386
1218 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1219 /* add 'call __bound_init()' in .init section */
1220 init_section
= find_section(s1
, ".init");
1221 pinit
= section_ptr_add(init_section
, 5);
1223 put32(pinit
+ 1, -4);
1224 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1225 put_elf_reloc(symtab_section
, init_section
,
1226 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1232 /* add tcc runtime libraries */
1233 ST_FUNC
void tcc_add_runtime(TCCState
*s1
)
1238 if (!s1
->nostdlib
) {
1239 #ifdef CONFIG_USE_LIBGCC
1240 tcc_add_library(s1
, "c");
1241 #ifdef CONFIG_TCC_MULTIARCH_TRIPLET
1242 if (tcc_add_file_internal(s1
, CONFIG_SYSROOT CONFIG_TCC_LDDIR
"/" CONFIG_TCC_MULTIARCH_TRIPLET
"/libgcc_s.so.1", 0))
1244 tcc_add_file(s1
, CONFIG_SYSROOT CONFIG_TCC_LDDIR
"/libgcc_s.so.1");
1246 tcc_add_library(s1
, "c");
1247 #ifndef WITHOUT_LIBTCC
1250 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "libtcc1.a");
1251 tcc_add_file(s1
, buf
);
1256 /* add crt end if not memory output */
1257 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1258 #ifdef CONFIG_TCC_MULTIARCH_TRIPLET
1259 if (tcc_add_file_internal(s1
, CONFIG_SYSROOT CONFIG_TCC_CRT_PREFIX
"/" CONFIG_TCC_MULTIARCH_TRIPLET
"/crtn.o", 0))
1261 tcc_add_file(s1
, CONFIG_SYSROOT CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1265 /* add various standard linker symbols (must be done after the
1266 sections are filled (for example after allocating common
1268 ST_FUNC
void tcc_add_linker_symbols(TCCState
*s1
)
1274 add_elf_sym(symtab_section
,
1275 text_section
->data_offset
, 0,
1276 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1277 text_section
->sh_num
, "_etext");
1278 add_elf_sym(symtab_section
,
1279 data_section
->data_offset
, 0,
1280 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1281 data_section
->sh_num
, "_edata");
1282 add_elf_sym(symtab_section
,
1283 bss_section
->data_offset
, 0,
1284 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1285 bss_section
->sh_num
, "_end");
1286 /* horrible new standard ldscript defines */
1287 add_init_array_defines(s1
, ".preinit_array");
1288 add_init_array_defines(s1
, ".init_array");
1289 add_init_array_defines(s1
, ".fini_array");
1291 /* add start and stop symbols for sections whose name can be
1293 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1294 s
= s1
->sections
[i
];
1295 if (s
->sh_type
== SHT_PROGBITS
&&
1296 (s
->sh_flags
& SHF_ALLOC
)) {
1300 /* check if section name can be expressed in C */
1306 if (!isid(ch
) && !isnum(ch
))
1310 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1311 add_elf_sym(symtab_section
,
1313 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1315 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1316 add_elf_sym(symtab_section
,
1318 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1325 /* name of ELF interpreter */
1326 #if defined __FreeBSD__
1327 static const char elf_interp
[] = "/libexec/ld-elf.so.1";
1328 #elif defined __FreeBSD_kernel__
1329 static char elf_interp
[] = CONFIG_TCC_LDDIR
"/ld.so.1";
1330 #elif defined TCC_ARM_EABI
1331 static const char elf_interp
[] = CONFIG_TCC_LDDIR
"/ld-linux.so.3";
1332 #elif defined(TCC_TARGET_X86_64)
1333 static const char elf_interp
[] = CONFIG_TCC_LDDIR
"/ld-linux-x86-64.so.2";
1334 #elif defined(TCC_UCLIBC)
1335 static const char elf_interp
[] = CONFIG_TCC_LDDIR
"/ld-uClibc.so.0";
1337 static const char elf_interp
[] = CONFIG_TCC_LDDIR
"/ld-linux.so.2";
1340 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1341 const int *section_order
)
1344 int i
, offset
, size
;
1347 for(i
=1;i
<s1
->nb_sections
;i
++) {
1348 s
= s1
->sections
[section_order
[i
]];
1349 if (s
->sh_type
!= SHT_NOBITS
&&
1350 (s
->sh_flags
& SHF_ALLOC
)) {
1351 while (offset
< s
->sh_offset
) {
1356 fwrite(s
->data
, 1, size
, f
);
1362 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1364 #define EXTRA_RELITEMS 14
1366 /* move the relocation value from .dynsym to .got */
1367 void patch_dynsym_undef(TCCState
*s1
, Section
*s
)
1369 uint32_t *gotd
= (void *)s1
->got
->data
;
1370 ElfW(Sym
) *sym
, *sym_end
;
1372 gotd
+= 3; // dummy entries in .got
1373 /* relocate symbols in .dynsym */
1374 sym_end
= (ElfW(Sym
) *)(s
->data
+ s
->data_offset
);
1375 for (sym
= (ElfW(Sym
) *)s
->data
+ 1; sym
< sym_end
; sym
++) {
1376 if (sym
->st_shndx
== SHN_UNDEF
) {
1377 *gotd
++ = sym
->st_value
+ 6; // XXX 6 is magic ?
1384 #define EXTRA_RELITEMS 9
1387 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1389 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1390 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1391 unsigned long offset
;
1393 if (sym_index
>= s1
->nb_got_offsets
)
1395 offset
= s1
->got_offsets
[sym_index
];
1396 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1397 #ifdef TCC_TARGET_X86_64
1398 /* only works for x86-64 */
1399 put32(s1
->got
->data
+ offset
, sym
->st_value
>> 32);
1401 put32(s1
->got
->data
+ offset
, sym
->st_value
& 0xffffffff);
1404 ST_FUNC
void fill_got(TCCState
*s1
)
1407 ElfW_Rel
*rel
, *rel_end
;
1410 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1411 s
= s1
->sections
[i
];
1412 if (s
->sh_type
!= SHT_RELX
)
1414 /* no need to handle got relocations */
1415 if (s
->link
!= symtab_section
)
1417 rel_end
= (ElfW_Rel
*) (s
->data
+ s
->data_offset
);
1418 for(rel
= (ElfW_Rel
*) s
->data
; rel
< rel_end
; rel
++) {
1419 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1420 case R_X86_64_GOT32
:
1421 case R_X86_64_GOTPCREL
:
1422 case R_X86_64_PLT32
:
1423 fill_got_entry(s1
, rel
);
1431 /* output an ELF file */
1432 /* XXX: suppress unneeded sections */
1433 static int elf_output_file(TCCState
*s1
, const char *filename
)
1439 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1441 Section
*strsec
, *s
;
1442 ElfW(Shdr
) shdr
, *sh
;
1443 ElfW(Phdr
) *phdr
, *ph
;
1444 Section
*interp
, *dynamic
, *dynstr
;
1445 unsigned long saved_dynamic_data_offset
;
1447 int type
, file_type
;
1448 unsigned long rel_addr
, rel_size
;
1449 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1450 unsigned long bss_addr
, bss_size
;
1453 file_type
= s1
->output_type
;
1456 if (file_type
!= TCC_OUTPUT_OBJ
) {
1457 tcc_add_runtime(s1
);
1461 section_order
= NULL
;
1464 dynstr
= NULL
; /* avoid warning */
1465 saved_dynamic_data_offset
= 0; /* avoid warning */
1467 if (file_type
!= TCC_OUTPUT_OBJ
) {
1468 relocate_common_syms();
1470 tcc_add_linker_symbols(s1
);
1472 if (!s1
->static_link
) {
1474 int sym_index
, index
;
1475 ElfW(Sym
) *esym
, *sym_end
;
1477 if (file_type
== TCC_OUTPUT_EXE
) {
1479 /* allow override the dynamic loader */
1480 const char *elfint
= getenv("LD_SO");
1482 elfint
= elf_interp
;
1483 /* add interpreter section only if executable */
1484 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1485 interp
->sh_addralign
= 1;
1486 ptr
= section_ptr_add(interp
, 1+strlen(elfint
));
1487 strcpy(ptr
, elfint
);
1490 /* add dynamic symbol table */
1491 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1493 ".hash", SHF_ALLOC
);
1494 dynstr
= s1
->dynsym
->link
;
1496 /* add dynamic section */
1497 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1498 SHF_ALLOC
| SHF_WRITE
);
1499 dynamic
->link
= dynstr
;
1500 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1503 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1504 SHF_ALLOC
| SHF_EXECINSTR
);
1505 s1
->plt
->sh_entsize
= 4;
1509 /* scan for undefined symbols and see if they are in the
1510 dynamic symbols. If a symbol STT_FUNC or STT_GNU_IFUNC
1511 is found, then we add it in the PLT. If a symbol
1512 STT_OBJECT is found, we add it in the .bss section with
1513 a suitable relocation */
1514 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1515 symtab_section
->data_offset
);
1516 if (file_type
== TCC_OUTPUT_EXE
) {
1517 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1520 if (sym
->st_shndx
== SHN_UNDEF
) {
1521 name
= symtab_section
->link
->data
+ sym
->st_name
;
1522 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1524 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1525 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1526 if ((type
== STT_FUNC
) || (type
== STT_GNU_IFUNC
)) {
1527 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1529 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1530 } else if (type
== STT_OBJECT
) {
1531 unsigned long offset
;
1532 ElfW(Sym
) *dynsym
, *dynsym_end
;
1533 offset
= bss_section
->data_offset
;
1534 /* XXX: which alignment ? */
1535 offset
= (offset
+ 16 - 1) & -16;
1536 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1538 bss_section
->sh_num
, name
);
1539 // Ensure R_COPY works for weak symbol aliases
1540 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1541 dynsym_end
= (ElfW(Sym
) *)
1542 (s1
->dynsymtab_section
->data
+
1543 s1
->dynsymtab_section
->data_offset
);
1544 for(dynsym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1545 dynsym
< dynsym_end
; dynsym
++) {
1546 if ((dynsym
->st_value
== esym
->st_value
)
1547 && (ELFW(ST_BIND
)(dynsym
->st_info
) == STB_GLOBAL
)) {
1549 dynname
= s1
->dynsymtab_section
->link
->data
1551 put_elf_sym(s1
->dynsym
, offset
,
1554 bss_section
->sh_num
,
1560 put_elf_reloc(s1
->dynsym
, bss_section
,
1561 offset
, R_COPY
, index
);
1562 offset
+= esym
->st_size
;
1563 bss_section
->data_offset
= offset
;
1566 /* STB_WEAK undefined symbols are accepted */
1567 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1569 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1570 !strcmp(name
, "_fp_hw")) {
1572 error_noabort("undefined symbol '%s'", name
);
1575 } else if (s1
->rdynamic
&&
1576 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1577 /* if -rdynamic option, then export all non
1579 name
= symtab_section
->link
->data
+ sym
->st_name
;
1580 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1582 sym
->st_shndx
, name
);
1589 /* now look at unresolved dynamic symbols and export
1590 corresponding symbol */
1591 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1592 s1
->dynsymtab_section
->data_offset
);
1593 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1596 if (esym
->st_shndx
== SHN_UNDEF
) {
1597 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1598 sym_index
= find_elf_sym(symtab_section
, name
);
1600 /* XXX: avoid adding a symbol if already
1601 present because of -rdynamic ? */
1602 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1603 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1605 sym
->st_shndx
, name
);
1607 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1608 /* weak symbols can stay undefined */
1610 warning("undefined dynamic symbol '%s'", name
);
1617 /* shared library case : we simply export all the global symbols */
1618 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1619 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1620 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1623 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1624 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1625 if ((ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
||
1626 ELFW(ST_TYPE
)(sym
->st_info
) == STT_GNU_IFUNC
)
1627 && sym
->st_shndx
== SHN_UNDEF
) {
1628 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1630 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1632 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1633 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1635 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1640 name
= symtab_section
->link
->data
+ sym
->st_name
;
1641 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1643 sym
->st_shndx
, name
);
1644 s1
->symtab_to_dynsym
[sym
-
1645 (ElfW(Sym
) *)symtab_section
->data
] =
1652 build_got_entries(s1
);
1654 /* add a list of needed dlls */
1655 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1656 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1657 if (dllref
->level
== 0)
1658 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1662 put_dt(dynamic
, DT_RPATH
, put_elf_str(dynstr
, s1
->rpath
));
1664 /* XXX: currently, since we do not handle PIC code, we
1665 must relocate the readonly segments */
1666 if (file_type
== TCC_OUTPUT_DLL
) {
1668 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1669 put_dt(dynamic
, DT_TEXTREL
, 0);
1673 put_dt(dynamic
, DT_SYMBOLIC
, 0);
1675 /* add necessary space for other entries */
1676 saved_dynamic_data_offset
= dynamic
->data_offset
;
1677 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * EXTRA_RELITEMS
;
1679 /* still need to build got entries in case of static link */
1680 build_got_entries(s1
);
1684 memset(&ehdr
, 0, sizeof(ehdr
));
1686 /* we add a section for symbols */
1687 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1688 put_elf_str(strsec
, "");
1690 /* compute number of sections */
1691 shnum
= s1
->nb_sections
;
1693 /* this array is used to reorder sections in the output file */
1694 section_order
= tcc_malloc(sizeof(int) * shnum
);
1695 section_order
[0] = 0;
1698 /* compute number of program headers */
1701 case TCC_OUTPUT_OBJ
:
1704 case TCC_OUTPUT_EXE
:
1705 if (!s1
->static_link
)
1706 phnum
= 4 + HAVE_PHDR
;
1710 case TCC_OUTPUT_DLL
:
1715 /* allocate strings for section names and decide if an unallocated
1716 section should be output */
1717 /* NOTE: the strsec section comes last, so its size is also
1719 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1720 s
= s1
->sections
[i
];
1721 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1723 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1728 s
->reloc
? s
->reloc
->name
: "n"
1731 /* when generating a DLL, we include relocations but we may
1733 if (file_type
== TCC_OUTPUT_DLL
&&
1734 s
->sh_type
== SHT_RELX
&&
1735 !(s
->sh_flags
& SHF_ALLOC
)) {
1736 /* //gr: avoid bogus relocs for empty (debug) sections */
1737 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1738 prepare_dynamic_rel(s1
, s
);
1739 else if (s1
->do_debug
)
1740 s
->sh_size
= s
->data_offset
;
1741 } else if (s1
->do_debug
||
1742 file_type
== TCC_OUTPUT_OBJ
||
1743 (s
->sh_flags
& SHF_ALLOC
) ||
1744 i
== (s1
->nb_sections
- 1)) {
1745 /* we output all sections if debug or object file */
1746 s
->sh_size
= s
->data_offset
;
1750 /* allocate program segment headers */
1751 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1753 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1754 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1759 /* compute section to program header mapping */
1760 if (s1
->has_text_addr
) {
1761 int a_offset
, p_offset
;
1762 addr
= s1
->text_addr
;
1763 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1765 a_offset
= addr
& (s1
->section_align
- 1);
1766 p_offset
= file_offset
& (s1
->section_align
- 1);
1767 if (a_offset
< p_offset
)
1768 a_offset
+= s1
->section_align
;
1769 file_offset
+= (a_offset
- p_offset
);
1771 if (file_type
== TCC_OUTPUT_DLL
)
1774 addr
= ELF_START_ADDR
;
1775 /* compute address after headers */
1776 addr
+= (file_offset
& (s1
->section_align
- 1));
1779 /* dynamic relocation table information, for .dynamic section */
1783 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1784 bss_addr
= bss_size
= 0;
1786 /* leave one program header for the program interpreter */
1789 ph
+= 1 + HAVE_PHDR
;
1791 for(j
= 0; j
< 2; j
++) {
1792 ph
->p_type
= PT_LOAD
;
1794 ph
->p_flags
= PF_R
| PF_X
;
1796 ph
->p_flags
= PF_R
| PF_W
;
1797 ph
->p_align
= s1
->section_align
;
1799 /* we do the following ordering: interp, symbol tables,
1800 relocations, progbits, nobits */
1801 /* XXX: do faster and simpler sorting */
1802 for(k
= 0; k
< 5; k
++) {
1803 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1804 s
= s1
->sections
[i
];
1805 /* compute if section should be included */
1807 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1811 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1812 (SHF_ALLOC
| SHF_WRITE
))
1818 } else if (s
->sh_type
== SHT_DYNSYM
||
1819 s
->sh_type
== SHT_STRTAB
||
1820 s
->sh_type
== SHT_HASH
) {
1823 } else if (s
->sh_type
== SHT_RELX
) {
1826 } else if (s
->sh_type
== SHT_NOBITS
) {
1833 section_order
[sh_order_index
++] = i
;
1835 /* section matches: we align it and add its size */
1837 addr
= (addr
+ s
->sh_addralign
- 1) &
1838 ~(s
->sh_addralign
- 1);
1839 file_offset
+= addr
- tmp
;
1840 s
->sh_offset
= file_offset
;
1843 /* update program header infos */
1844 if (ph
->p_offset
== 0) {
1845 ph
->p_offset
= file_offset
;
1847 ph
->p_paddr
= ph
->p_vaddr
;
1849 /* update dynamic relocation infos */
1850 if (s
->sh_type
== SHT_RELX
) {
1851 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1852 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.got")) { // rel_size == 0) {
1854 rel_size
+= s
->sh_size
; // XXX only first rel.
1856 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.bss")) { // rel_size == 0) {
1858 bss_size
= s
->sh_size
; // XXX only first rel.
1863 rel_size
+= s
->sh_size
;
1867 if (s
->sh_type
!= SHT_NOBITS
)
1868 file_offset
+= s
->sh_size
;
1871 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1872 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1875 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1876 /* if in the middle of a page, we duplicate the page in
1877 memory so that one copy is RX and the other is RW */
1878 if ((addr
& (s1
->section_align
- 1)) != 0)
1879 addr
+= s1
->section_align
;
1881 addr
= (addr
+ s1
->section_align
- 1) & ~(s1
->section_align
- 1);
1882 file_offset
= (file_offset
+ s1
->section_align
- 1) &
1883 ~(s1
->section_align
- 1);
1888 /* if interpreter, then add corresponing program header */
1892 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1894 int len
= phnum
* sizeof(ElfW(Phdr
));
1896 ph
->p_type
= PT_PHDR
;
1897 ph
->p_offset
= sizeof(ElfW(Ehdr
));
1898 ph
->p_vaddr
= interp
->sh_addr
- len
;
1899 ph
->p_paddr
= ph
->p_vaddr
;
1900 ph
->p_filesz
= ph
->p_memsz
= len
;
1901 ph
->p_flags
= PF_R
| PF_X
;
1902 ph
->p_align
= 4; // interp->sh_addralign;
1907 ph
->p_type
= PT_INTERP
;
1908 ph
->p_offset
= interp
->sh_offset
;
1909 ph
->p_vaddr
= interp
->sh_addr
;
1910 ph
->p_paddr
= ph
->p_vaddr
;
1911 ph
->p_filesz
= interp
->sh_size
;
1912 ph
->p_memsz
= interp
->sh_size
;
1914 ph
->p_align
= interp
->sh_addralign
;
1917 /* if dynamic section, then add corresponing program header */
1921 ph
= &phdr
[phnum
- 1];
1923 ph
->p_type
= PT_DYNAMIC
;
1924 ph
->p_offset
= dynamic
->sh_offset
;
1925 ph
->p_vaddr
= dynamic
->sh_addr
;
1926 ph
->p_paddr
= ph
->p_vaddr
;
1927 ph
->p_filesz
= dynamic
->sh_size
;
1928 ph
->p_memsz
= dynamic
->sh_size
;
1929 ph
->p_flags
= PF_R
| PF_W
;
1930 ph
->p_align
= dynamic
->sh_addralign
;
1932 /* put GOT dynamic section address */
1933 put32(s1
->got
->data
, dynamic
->sh_addr
);
1935 /* relocate the PLT */
1936 if (file_type
== TCC_OUTPUT_EXE
1937 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1938 || file_type
== TCC_OUTPUT_DLL
1944 p_end
= p
+ s1
->plt
->data_offset
;
1946 #if defined(TCC_TARGET_I386)
1947 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1948 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1951 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1954 #elif defined(TCC_TARGET_X86_64)
1955 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1956 put32(p
+ 2, get32(p
+ 2) + x
);
1957 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1960 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1963 #elif defined(TCC_TARGET_ARM)
1965 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1968 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1971 #elif defined(TCC_TARGET_C67)
1974 #error unsupported CPU
1979 /* relocate symbols in .dynsym */
1980 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1981 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1984 if (sym
->st_shndx
== SHN_UNDEF
) {
1985 /* relocate to the PLT if the symbol corresponds
1988 sym
->st_value
+= s1
->plt
->sh_addr
;
1989 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1990 /* do symbol relocation */
1991 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1995 /* put dynamic section entries */
1996 dynamic
->data_offset
= saved_dynamic_data_offset
;
1997 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1998 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1999 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
2000 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
2001 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
2002 #ifdef TCC_TARGET_X86_64
2003 put_dt(dynamic
, DT_RELA
, rel_addr
);
2004 put_dt(dynamic
, DT_RELASZ
, rel_size
);
2005 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
2007 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2008 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2009 put_dt(dynamic
, DT_PLTRELSZ
, rel_size
);
2010 put_dt(dynamic
, DT_JMPREL
, rel_addr
);
2011 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
2012 put_dt(dynamic
, DT_REL
, bss_addr
);
2013 put_dt(dynamic
, DT_RELSZ
, bss_size
);
2015 put_dt(dynamic
, DT_REL
, rel_addr
);
2016 put_dt(dynamic
, DT_RELSZ
, rel_size
);
2017 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
2021 put_dt(dynamic
, DT_DEBUG
, 0);
2022 put_dt(dynamic
, DT_NULL
, 0);
2025 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2026 ehdr
.e_phnum
= phnum
;
2027 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2030 /* all other sections come after */
2031 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2032 s
= s1
->sections
[i
];
2033 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
2035 section_order
[sh_order_index
++] = i
;
2037 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
2038 ~(s
->sh_addralign
- 1);
2039 s
->sh_offset
= file_offset
;
2040 if (s
->sh_type
!= SHT_NOBITS
)
2041 file_offset
+= s
->sh_size
;
2044 /* if building executable or DLL, then relocate each section
2045 except the GOT which is already relocated */
2046 if (file_type
!= TCC_OUTPUT_OBJ
) {
2047 relocate_syms(s1
, 0);
2049 if (s1
->nb_errors
!= 0) {
2055 /* relocate sections */
2056 /* XXX: ignore sections with allocated relocations ? */
2057 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2058 s
= s1
->sections
[i
];
2059 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
2060 relocate_section(s1
, s
);
2063 /* relocate relocation entries if the relocation tables are
2064 allocated in the executable */
2065 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2066 s
= s1
->sections
[i
];
2067 if ((s
->sh_flags
& SHF_ALLOC
) &&
2068 s
->sh_type
== SHT_RELX
) {
2069 relocate_rel(s1
, s
);
2073 /* get entry point address */
2074 if (file_type
== TCC_OUTPUT_EXE
)
2075 ehdr
.e_entry
= (uplong
)tcc_get_symbol_err(s1
, "_start");
2077 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
2079 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2082 /* write elf file */
2083 if (file_type
== TCC_OUTPUT_OBJ
)
2088 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2090 error_noabort("could not write '%s'", filename
);
2093 f
= fdopen(fd
, "wb");
2095 printf("<- %s\n", filename
);
2097 #ifdef TCC_TARGET_COFF
2098 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
2099 tcc_output_coff(s1
, f
);
2102 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
2103 sort_syms(s1
, symtab_section
);
2106 file_offset
= (file_offset
+ 3) & -4;
2109 ehdr
.e_ident
[0] = ELFMAG0
;
2110 ehdr
.e_ident
[1] = ELFMAG1
;
2111 ehdr
.e_ident
[2] = ELFMAG2
;
2112 ehdr
.e_ident
[3] = ELFMAG3
;
2113 ehdr
.e_ident
[4] = ELFCLASSW
;
2114 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2115 ehdr
.e_ident
[6] = EV_CURRENT
;
2116 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2117 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2119 #ifdef TCC_TARGET_ARM
2121 ehdr
.e_ident
[EI_OSABI
] = 0;
2122 ehdr
.e_flags
= 4 << 24;
2124 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2129 case TCC_OUTPUT_EXE
:
2130 ehdr
.e_type
= ET_EXEC
;
2132 case TCC_OUTPUT_DLL
:
2133 ehdr
.e_type
= ET_DYN
;
2135 case TCC_OUTPUT_OBJ
:
2136 ehdr
.e_type
= ET_REL
;
2139 ehdr
.e_machine
= EM_TCC_TARGET
;
2140 ehdr
.e_version
= EV_CURRENT
;
2141 ehdr
.e_shoff
= file_offset
;
2142 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2143 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2144 ehdr
.e_shnum
= shnum
;
2145 ehdr
.e_shstrndx
= shnum
- 1;
2147 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2148 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2149 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2151 for(i
=1;i
<s1
->nb_sections
;i
++) {
2152 s
= s1
->sections
[section_order
[i
]];
2153 if (s
->sh_type
!= SHT_NOBITS
) {
2154 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2155 if (s
->sh_type
== SHT_DYNSYM
)
2156 patch_dynsym_undef(s1
, s
);
2158 while (offset
< s
->sh_offset
) {
2163 fwrite(s
->data
, 1, size
, f
);
2168 /* output section headers */
2169 while (offset
< ehdr
.e_shoff
) {
2174 for(i
=0;i
<s1
->nb_sections
;i
++) {
2176 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2177 s
= s1
->sections
[i
];
2179 sh
->sh_name
= s
->sh_name
;
2180 sh
->sh_type
= s
->sh_type
;
2181 sh
->sh_flags
= s
->sh_flags
;
2182 sh
->sh_entsize
= s
->sh_entsize
;
2183 sh
->sh_info
= s
->sh_info
;
2185 sh
->sh_link
= s
->link
->sh_num
;
2186 sh
->sh_addralign
= s
->sh_addralign
;
2187 sh
->sh_addr
= s
->sh_addr
;
2188 sh
->sh_offset
= s
->sh_offset
;
2189 sh
->sh_size
= s
->sh_size
;
2191 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2194 tcc_output_binary(s1
, f
, section_order
);
2200 tcc_free(s1
->symtab_to_dynsym
);
2201 tcc_free(section_order
);
2203 tcc_free(s1
->got_offsets
);
2207 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2210 #ifdef TCC_TARGET_PE
2211 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2212 ret
= pe_output_file(s
, filename
);
2216 ret
= elf_output_file(s
, filename
);
2221 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2225 data
= tcc_malloc(size
);
2226 lseek(fd
, file_offset
, SEEK_SET
);
2227 read(fd
, data
, size
);
2231 typedef struct SectionMergeInfo
{
2232 Section
*s
; /* corresponding existing section */
2233 unsigned long offset
; /* offset of the new section in the existing section */
2234 uint8_t new_section
; /* true if section 's' was added */
2235 uint8_t link_once
; /* true if link once section */
2238 /* load an object file and merge it with current files */
2239 /* XXX: handle correctly stab (debug) info */
2240 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
2241 int fd
, unsigned long file_offset
)
2244 ElfW(Shdr
) *shdr
, *sh
;
2245 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2246 unsigned char *strsec
, *strtab
;
2247 int *old_to_new_syms
;
2248 char *sh_name
, *name
;
2249 SectionMergeInfo
*sm_table
, *sm
;
2250 ElfW(Sym
) *sym
, *symtab
;
2251 ElfW_Rel
*rel
, *rel_end
;
2257 stab_index
= stabstr_index
= 0;
2259 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2261 if (ehdr
.e_ident
[0] != ELFMAG0
||
2262 ehdr
.e_ident
[1] != ELFMAG1
||
2263 ehdr
.e_ident
[2] != ELFMAG2
||
2264 ehdr
.e_ident
[3] != ELFMAG3
)
2266 /* test if object file */
2267 if (ehdr
.e_type
!= ET_REL
)
2269 /* test CPU specific stuff */
2270 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2271 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2273 error_noabort("invalid object file");
2277 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2278 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2279 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2281 /* load section names */
2282 sh
= &shdr
[ehdr
.e_shstrndx
];
2283 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2285 /* load symtab and strtab */
2286 old_to_new_syms
= NULL
;
2290 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2292 if (sh
->sh_type
== SHT_SYMTAB
) {
2294 error_noabort("object must contain only one symtab");
2299 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2300 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2301 sm_table
[i
].s
= symtab_section
;
2303 /* now load strtab */
2304 sh
= &shdr
[sh
->sh_link
];
2305 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2309 /* now examine each section and try to merge its content with the
2311 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2312 /* no need to examine section name strtab */
2313 if (i
== ehdr
.e_shstrndx
)
2316 sh_name
= strsec
+ sh
->sh_name
;
2317 /* ignore sections types we do not handle */
2318 if (sh
->sh_type
!= SHT_PROGBITS
&&
2319 sh
->sh_type
!= SHT_RELX
&&
2321 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2323 sh
->sh_type
!= SHT_NOBITS
&&
2324 sh
->sh_type
!= SHT_PREINIT_ARRAY
&&
2325 sh
->sh_type
!= SHT_INIT_ARRAY
&&
2326 sh
->sh_type
!= SHT_FINI_ARRAY
&&
2327 strcmp(sh_name
, ".stabstr")
2330 if (sh
->sh_addralign
< 1)
2331 sh
->sh_addralign
= 1;
2332 /* find corresponding section, if any */
2333 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2334 s
= s1
->sections
[j
];
2335 if (!strcmp(s
->name
, sh_name
)) {
2336 if (!strncmp(sh_name
, ".gnu.linkonce",
2337 sizeof(".gnu.linkonce") - 1)) {
2338 /* if a 'linkonce' section is already present, we
2339 do not add it again. It is a little tricky as
2340 symbols can still be defined in
2342 sm_table
[i
].link_once
= 1;
2349 /* not found: create new section */
2350 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2351 /* take as much info as possible from the section. sh_link and
2352 sh_info will be updated later */
2353 s
->sh_addralign
= sh
->sh_addralign
;
2354 s
->sh_entsize
= sh
->sh_entsize
;
2355 sm_table
[i
].new_section
= 1;
2357 if (sh
->sh_type
!= s
->sh_type
) {
2358 error_noabort("invalid section type");
2362 /* align start of section */
2363 offset
= s
->data_offset
;
2365 if (0 == strcmp(sh_name
, ".stab")) {
2369 if (0 == strcmp(sh_name
, ".stabstr")) {
2374 size
= sh
->sh_addralign
- 1;
2375 offset
= (offset
+ size
) & ~size
;
2376 if (sh
->sh_addralign
> s
->sh_addralign
)
2377 s
->sh_addralign
= sh
->sh_addralign
;
2378 s
->data_offset
= offset
;
2380 sm_table
[i
].offset
= offset
;
2382 /* concatenate sections */
2384 if (sh
->sh_type
!= SHT_NOBITS
) {
2386 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2387 ptr
= section_ptr_add(s
, size
);
2388 read(fd
, ptr
, size
);
2390 s
->data_offset
+= size
;
2395 /* //gr relocate stab strings */
2396 if (stab_index
&& stabstr_index
) {
2399 s
= sm_table
[stab_index
].s
;
2400 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2401 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2402 o
= sm_table
[stabstr_index
].offset
;
2404 a
->n_strx
+= o
, a
++;
2407 /* second short pass to update sh_link and sh_info fields of new
2409 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2411 if (!s
|| !sm_table
[i
].new_section
)
2414 if (sh
->sh_link
> 0)
2415 s
->link
= sm_table
[sh
->sh_link
].s
;
2416 if (sh
->sh_type
== SHT_RELX
) {
2417 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2418 /* update backward link */
2419 s1
->sections
[s
->sh_info
]->reloc
= s
;
2424 /* resolve symbols */
2425 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2428 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2429 if (sym
->st_shndx
!= SHN_UNDEF
&&
2430 sym
->st_shndx
< SHN_LORESERVE
) {
2431 sm
= &sm_table
[sym
->st_shndx
];
2432 if (sm
->link_once
) {
2433 /* if a symbol is in a link once section, we use the
2434 already defined symbol. It is very important to get
2435 correct relocations */
2436 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2437 name
= strtab
+ sym
->st_name
;
2438 sym_index
= find_elf_sym(symtab_section
, name
);
2440 old_to_new_syms
[i
] = sym_index
;
2444 /* if no corresponding section added, no need to add symbol */
2447 /* convert section number */
2448 sym
->st_shndx
= sm
->s
->sh_num
;
2450 sym
->st_value
+= sm
->offset
;
2453 name
= strtab
+ sym
->st_name
;
2454 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2455 sym
->st_info
, sym
->st_other
,
2456 sym
->st_shndx
, name
);
2457 old_to_new_syms
[i
] = sym_index
;
2460 /* third pass to patch relocation entries */
2461 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2466 offset
= sm_table
[i
].offset
;
2467 switch(s
->sh_type
) {
2469 /* take relocation offset information */
2470 offseti
= sm_table
[sh
->sh_info
].offset
;
2471 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2472 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2477 /* convert symbol index */
2478 type
= ELFW(R_TYPE
)(rel
->r_info
);
2479 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2480 /* NOTE: only one symtab assumed */
2481 if (sym_index
>= nb_syms
)
2483 sym_index
= old_to_new_syms
[sym_index
];
2484 /* ignore link_once in rel section. */
2485 if (!sym_index
&& !sm
->link_once
2486 #ifdef TCC_TARGET_ARM
2487 && type
!= R_ARM_V4BX
2491 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2492 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2495 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2496 /* offset the relocation offset */
2497 rel
->r_offset
+= offseti
;
2509 tcc_free(old_to_new_syms
);
2516 typedef struct ArchiveHeader
{
2517 char ar_name
[16]; /* name of this member */
2518 char ar_date
[12]; /* file mtime */
2519 char ar_uid
[6]; /* owner uid; printed as decimal */
2520 char ar_gid
[6]; /* owner gid; printed as decimal */
2521 char ar_mode
[8]; /* file mode, printed as octal */
2522 char ar_size
[10]; /* file size, printed as decimal */
2523 char ar_fmag
[2]; /* should contain ARFMAG */
2526 static int get_be32(const uint8_t *b
)
2528 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2531 /* load only the objects which resolve undefined symbols */
2532 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2534 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2536 const char *ar_names
, *p
;
2537 const uint8_t *ar_index
;
2540 data
= tcc_malloc(size
);
2541 if (read(fd
, data
, size
) != size
)
2543 nsyms
= get_be32(data
);
2544 ar_index
= data
+ 4;
2545 ar_names
= ar_index
+ nsyms
* 4;
2549 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2550 sym_index
= find_elf_sym(symtab_section
, p
);
2552 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2553 if(sym
->st_shndx
== SHN_UNDEF
) {
2554 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2556 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2559 lseek(fd
, off
, SEEK_SET
);
2560 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2575 /* load a '.a' file */
2576 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
)
2583 unsigned long file_offset
;
2585 /* skip magic which was already checked */
2586 read(fd
, magic
, sizeof(magic
));
2589 len
= read(fd
, &hdr
, sizeof(hdr
));
2592 if (len
!= sizeof(hdr
)) {
2593 error_noabort("invalid archive");
2596 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2597 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2598 size
= strtol(ar_size
, NULL
, 0);
2599 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2600 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2601 if (ar_name
[i
] != ' ')
2604 ar_name
[i
+ 1] = '\0';
2605 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2606 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2608 size
= (size
+ 1) & ~1;
2609 if (!strcmp(ar_name
, "/")) {
2610 /* coff symbol table : we handle it */
2611 if(s1
->alacarte_link
)
2612 return tcc_load_alacarte(s1
, fd
, size
);
2613 } else if (!strcmp(ar_name
, "//") ||
2614 !strcmp(ar_name
, "__.SYMDEF") ||
2615 !strcmp(ar_name
, "__.SYMDEF/") ||
2616 !strcmp(ar_name
, "ARFILENAMES/")) {
2617 /* skip symbol table or archive names */
2619 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2622 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2627 #ifndef TCC_TARGET_PE
2628 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2629 is referenced by the user (so it should be added as DT_NEEDED in
2630 the generated ELF file) */
2631 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2634 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2635 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2636 ElfW(Sym
) *sym
, *dynsym
;
2637 ElfW(Dyn
) *dt
, *dynamic
;
2638 unsigned char *dynstr
;
2639 const char *name
, *soname
;
2640 DLLReference
*dllref
;
2642 read(fd
, &ehdr
, sizeof(ehdr
));
2644 /* test CPU specific stuff */
2645 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2646 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2647 error_noabort("bad architecture");
2652 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2654 /* load dynamic section and dynamic symbols */
2658 dynsym
= NULL
; /* avoid warning */
2659 dynstr
= NULL
; /* avoid warning */
2660 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2661 switch(sh
->sh_type
) {
2663 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2664 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2667 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2668 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2669 sh1
= &shdr
[sh
->sh_link
];
2670 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2677 /* compute the real library name */
2678 soname
= tcc_basename(filename
);
2680 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2681 if (dt
->d_tag
== DT_SONAME
) {
2682 soname
= dynstr
+ dt
->d_un
.d_val
;
2686 /* if the dll is already loaded, do not load it */
2687 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2688 dllref
= s1
->loaded_dlls
[i
];
2689 if (!strcmp(soname
, dllref
->name
)) {
2690 /* but update level if needed */
2691 if (level
< dllref
->level
)
2692 dllref
->level
= level
;
2698 // printf("loading dll '%s'\n", soname);
2700 /* add the dll and its level */
2701 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2702 dllref
->level
= level
;
2703 strcpy(dllref
->name
, soname
);
2704 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2706 /* add dynamic symbols in dynsym_section */
2707 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2708 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2709 if (sym_bind
== STB_LOCAL
)
2711 name
= dynstr
+ sym
->st_name
;
2712 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2713 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2716 /* load all referenced DLLs */
2717 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2720 name
= dynstr
+ dt
->d_un
.d_val
;
2721 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2722 dllref
= s1
->loaded_dlls
[j
];
2723 if (!strcmp(name
, dllref
->name
))
2724 goto already_loaded
;
2726 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2727 error_noabort("referenced dll '%s' not found", name
);
2744 #define LD_TOK_NAME 256
2745 #define LD_TOK_EOF (-1)
2747 /* return next ld script token */
2748 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2766 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2767 ch
= file
->buf_ptr
[0];
2775 /* case 'a' ... 'z': */
2802 /* case 'A' ... 'z': */
2837 if (!((ch
>= 'a' && ch
<= 'z') ||
2838 (ch
>= 'A' && ch
<= 'Z') ||
2839 (ch
>= '0' && ch
<= '9') ||
2840 strchr("/.-_+=$:\\,~", ch
)))
2842 if ((q
- name
) < name_size
- 1) {
2859 printf("tok=%c %d\n", c
, c
);
2860 if (c
== LD_TOK_NAME
)
2861 printf(" name=%s\n", name
);
2867 * Extract the library name from the file name
2868 * Return 0 if the file isn't a library
2870 * /!\ No test on filename capacity, be careful
2872 static int filename_to_libname(TCCState
*s1
, const char filename
[], char libname
[])
2877 /* already converted to library name */
2878 if (libname
[0] != '\0')
2880 ext
= tcc_fileextension(filename
);
2883 libprefix
= !strncmp(filename
, "lib", 3);
2884 if (!s1
->static_link
) {
2885 #ifdef TCC_TARGET_PE
2886 if (!strcmp(ext
, ".def")) {
2887 size_t len
= ext
- filename
;
2888 pstrncpy(libname
, filename
, len
);
2892 if (libprefix
&& (!strcmp(ext
, ".so"))) {
2893 size_t len
= ext
- filename
- 3;
2894 pstrncpy(libname
, filename
+ 3, len
);
2899 if (libprefix
&& (!strcmp(ext
, ".a"))) {
2900 size_t len
= ext
- filename
- 3;
2901 pstrncpy(libname
, filename
+ 3, len
);
2909 * Extract the file name from the library name
2911 * /!\ No test on filename capacity, be careful
2913 static void libname_to_filename(TCCState
*s1
, const char libname
[], char filename
[])
2915 if (!s1
->static_link
) {
2916 #ifdef TCC_TARGET_PE
2917 sprintf(filename
, "%s.def", libname
);
2919 sprintf(filename
, "lib%s.so", libname
);
2922 sprintf(filename
, "lib%s.a", libname
);
2926 static int ld_add_file(TCCState
*s1
, const char filename
[], char libname
[])
2930 ret
= tcc_add_file_internal(s1
, filename
, 0);
2932 if (filename_to_libname(s1
, filename
, libname
))
2933 ret
= tcc_add_library(s1
, libname
);
2938 static inline int new_undef_syms(void)
2941 ret
= new_undef_sym
;
2946 static int ld_add_file_list(TCCState
*s1
, const char *cmd
, int as_needed
)
2948 char filename
[1024], libname
[1024];
2949 int t
, group
, nblibs
= 0, ret
= 0;
2952 group
= !strcmp(cmd
, "GROUP");
2955 t
= ld_next(s1
, filename
, sizeof(filename
));
2958 t
= ld_next(s1
, filename
, sizeof(filename
));
2961 if (t
== LD_TOK_EOF
) {
2962 error_noabort("unexpected end of file");
2964 goto lib_parse_error
;
2965 } else if (t
== ')') {
2967 } else if (t
== '-') {
2968 t
= ld_next(s1
, filename
, sizeof(filename
));
2969 if ((t
!= LD_TOK_NAME
) || (filename
[0] != 'l')) {
2970 error_noabort("library name expected");
2972 goto lib_parse_error
;
2974 strcpy(libname
, &filename
[1]);
2975 libname_to_filename(s1
, libname
, filename
);
2976 } else if (t
!= LD_TOK_NAME
) {
2977 error_noabort("filename expected");
2979 goto lib_parse_error
;
2981 if (!strcmp(filename
, "AS_NEEDED")) {
2982 ret
= ld_add_file_list(s1
, cmd
, 1);
2984 goto lib_parse_error
;
2986 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2988 ret
= ld_add_file(s1
, filename
, libname
);
2990 goto lib_parse_error
;
2992 /* Add the filename *and* the libname to avoid future conversions */
2993 dynarray_add((void ***) &libs
, &nblibs
, tcc_strdup(filename
));
2994 dynarray_add((void ***) &libs
, &nblibs
, tcc_strdup(libname
));
2998 t
= ld_next(s1
, filename
, sizeof(filename
));
3000 t
= ld_next(s1
, filename
, sizeof(filename
));
3003 if (group
&& !as_needed
) {
3004 while (new_undef_syms()) {
3007 for (i
= 0; i
< nblibs
; i
+= 2)
3008 ld_add_file(s1
, libs
[i
], libs
[i
+1]);
3012 dynarray_reset(&libs
, &nblibs
);
3016 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3018 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
)
3021 char filename
[1024];
3024 ch
= file
->buf_ptr
[0];
3027 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3028 if (t
== LD_TOK_EOF
)
3030 else if (t
!= LD_TOK_NAME
)
3032 if (!strcmp(cmd
, "INPUT") ||
3033 !strcmp(cmd
, "GROUP")) {
3034 ret
= ld_add_file_list(s1
, cmd
, 0);
3037 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
3038 !strcmp(cmd
, "TARGET")) {
3039 /* ignore some commands */
3040 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3044 t
= ld_next(s1
, filename
, sizeof(filename
));
3045 if (t
== LD_TOK_EOF
) {
3046 error_noabort("unexpected end of file");
3048 } else if (t
== ')') {