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 #ifdef TCC_TARGET_X86_64
24 #define ElfW_Rel ElfW(Rela)
25 #define SHT_RELX SHT_RELA
26 #define REL_SECTION_FMT ".rela%s"
27 /* x86-64 requires PLT for DLLs */
28 #define TCC_OUTPUT_DLL_WITH_PLT
30 #define ElfW_Rel ElfW(Rel)
31 #define SHT_RELX SHT_REL
32 #define REL_SECTION_FMT ".rel%s"
35 static int new_undef_sym
= 0; /* Is there a new undefined sym since last new_undef_sym() */
37 /* XXX: DLL with PLT would only work with x86-64 for now */
38 //#define TCC_OUTPUT_DLL_WITH_PLT
40 ST_FUNC
int put_elf_str(Section
*s
, const char *sym
)
45 len
= strlen(sym
) + 1;
46 offset
= s
->data_offset
;
47 ptr
= section_ptr_add(s
, len
);
48 memcpy(ptr
, sym
, len
);
52 /* elf symbol hashing function */
53 static unsigned long elf_hash(const unsigned char *name
)
55 unsigned long h
= 0, g
;
58 h
= (h
<< 4) + *name
++;
67 /* rebuild hash table of section s */
68 /* NOTE: we do factorize the hash table code to go faster */
69 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
72 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
75 strtab
= s
->link
->data
;
76 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
78 s
->hash
->data_offset
= 0;
79 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
84 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
85 ptr
+= nb_buckets
+ 1;
87 sym
= (ElfW(Sym
) *)s
->data
+ 1;
88 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
89 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
90 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
101 /* return the symbol number */
102 ST_FUNC
int put_elf_sym(Section
*s
, uplong value
, unsigned long size
,
103 int info
, int other
, int shndx
, const char *name
)
105 int name_offset
, sym_index
;
110 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
112 name_offset
= put_elf_str(s
->link
, name
);
115 /* XXX: endianness */
116 sym
->st_name
= name_offset
;
117 sym
->st_value
= value
;
120 sym
->st_other
= other
;
121 sym
->st_shndx
= shndx
;
122 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
126 ptr
= section_ptr_add(hs
, sizeof(int));
127 base
= (int *)hs
->data
;
128 /* only add global or weak symbols */
129 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
130 /* add another hashing entry */
132 h
= elf_hash(name
) % nbuckets
;
134 base
[2 + h
] = sym_index
;
136 /* we resize the hash table */
137 hs
->nb_hashed_syms
++;
138 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
139 rebuild_hash(s
, 2 * nbuckets
);
149 /* find global ELF symbol 'name' and return its index. Return 0 if not
151 ST_FUNC
int find_elf_sym(Section
*s
, const char *name
)
155 int nbuckets
, sym_index
, h
;
161 nbuckets
= ((int *)hs
->data
)[0];
162 h
= elf_hash(name
) % nbuckets
;
163 sym_index
= ((int *)hs
->data
)[2 + h
];
164 while (sym_index
!= 0) {
165 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
166 name1
= s
->link
->data
+ sym
->st_name
;
167 if (!strcmp(name
, name1
))
169 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
174 /* return elf symbol value, signal error if 'err' is nonzero */
175 static void *get_elf_sym_addr(TCCState
*s
, const char *name
, int err
)
180 sym_index
= find_elf_sym(symtab_section
, name
);
181 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
182 if (!sym_index
|| sym
->st_shndx
== SHN_UNDEF
) {
184 error("%s not defined", name
);
187 return (void*)(uplong
)sym
->st_value
;
190 /* return elf symbol value */
191 LIBTCCAPI
void *tcc_get_symbol(TCCState
*s
, const char *name
)
193 return get_elf_sym_addr(s
, name
, 0);
196 /* return elf symbol value or error */
197 ST_FUNC
void *tcc_get_symbol_err(TCCState
*s
, const char *name
)
199 return get_elf_sym_addr(s
, name
, 1);
202 /* add an elf symbol : check if it is already defined and patch
203 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
204 ST_FUNC
int add_elf_sym(Section
*s
, uplong value
, unsigned long size
,
205 int info
, int other
, int sh_num
, const char *name
)
208 int sym_bind
, sym_index
, sym_type
, esym_bind
;
209 unsigned char sym_vis
, esym_vis
, new_vis
;
211 sym_bind
= ELFW(ST_BIND
)(info
);
212 sym_type
= ELFW(ST_TYPE
)(info
);
213 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
215 if (sym_bind
!= STB_LOCAL
) {
216 /* we search global or weak symbols */
217 sym_index
= find_elf_sym(s
, name
);
220 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
221 if (esym
->st_shndx
!= SHN_UNDEF
) {
222 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
223 /* propagate the most constraining visibility */
224 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
225 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
226 if (esym_vis
== STV_DEFAULT
) {
228 } else if (sym_vis
== STV_DEFAULT
) {
231 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
233 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
235 other
= esym
->st_other
; /* in case we have to patch esym */
236 if (sh_num
== SHN_UNDEF
) {
237 /* ignore adding of undefined symbol if the
238 corresponding symbol is already defined */
239 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
240 /* global overrides weak, so patch */
242 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
243 /* weak is ignored if already global */
244 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_WEAK
) {
245 /* keep first-found weak definition, ignore subsequents */
246 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
247 /* ignore hidden symbols after */
248 } else if (esym
->st_shndx
== SHN_COMMON
249 && (sh_num
< SHN_LORESERVE
|| sh_num
== SHN_COMMON
)) {
250 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
251 No idea if this is the correct solution ... */
253 } else if (s
== tcc_state
->dynsymtab_section
) {
254 /* we accept that two DLL define the same symbol */
257 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
258 sym_bind
, sh_num
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
260 error_noabort("'%s' defined twice", name
);
264 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
265 esym
->st_shndx
= sh_num
;
267 esym
->st_value
= value
;
268 esym
->st_size
= size
;
269 esym
->st_other
= other
;
273 sym_index
= put_elf_sym(s
, value
, size
,
274 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
281 ST_FUNC
void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
282 int type
, int symbol
)
290 /* if no relocation section, create it */
291 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
292 /* if the symtab is allocated, then we consider the relocation
294 sr
= new_section(tcc_state
, buf
, SHT_RELX
, symtab
->sh_flags
);
295 sr
->sh_entsize
= sizeof(ElfW_Rel
);
297 sr
->sh_info
= s
->sh_num
;
300 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
301 rel
->r_offset
= offset
;
302 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
303 #ifdef TCC_TARGET_X86_64
308 /* put stab debug information */
310 ST_FUNC
void put_stabs(const char *str
, int type
, int other
, int desc
,
315 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
317 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
322 sym
->n_other
= other
;
324 sym
->n_value
= value
;
327 ST_FUNC
void put_stabs_r(const char *str
, int type
, int other
, int desc
,
328 unsigned long value
, Section
*sec
, int sym_index
)
330 put_stabs(str
, type
, other
, desc
, value
);
331 put_elf_reloc(symtab_section
, stab_section
,
332 stab_section
->data_offset
- sizeof(unsigned int),
333 R_DATA_32
, sym_index
);
336 ST_FUNC
void put_stabn(int type
, int other
, int desc
, int value
)
338 put_stabs(NULL
, type
, other
, desc
, value
);
341 ST_FUNC
void put_stabd(int type
, int other
, int desc
)
343 put_stabs(NULL
, type
, other
, desc
, 0);
346 /* In an ELF file symbol table, the local symbols must appear below
347 the global and weak ones. Since TCC cannot sort it while generating
348 the code, we must do it after. All the relocation tables are also
349 modified to take into account the symbol table sorting */
350 static void sort_syms(TCCState
*s1
, Section
*s
)
352 int *old_to_new_syms
;
356 ElfW_Rel
*rel
, *rel_end
;
360 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
361 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
362 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
364 /* first pass for local symbols */
365 p
= (ElfW(Sym
) *)s
->data
;
367 for(i
= 0; i
< nb_syms
; i
++) {
368 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
369 old_to_new_syms
[i
] = q
- new_syms
;
374 /* save the number of local symbols in section header */
375 s
->sh_info
= q
- new_syms
;
377 /* then second pass for non local symbols */
378 p
= (ElfW(Sym
) *)s
->data
;
379 for(i
= 0; i
< nb_syms
; i
++) {
380 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
381 old_to_new_syms
[i
] = q
- new_syms
;
387 /* we copy the new symbols to the old */
388 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
391 /* now we modify all the relocations */
392 for(i
= 1; i
< s1
->nb_sections
; i
++) {
393 sr
= s1
->sections
[i
];
394 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
395 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
396 for(rel
= (ElfW_Rel
*)sr
->data
;
399 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
400 type
= ELFW(R_TYPE
)(rel
->r_info
);
401 sym_index
= old_to_new_syms
[sym_index
];
402 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
407 tcc_free(old_to_new_syms
);
410 /* relocate common symbols in the .bss section */
411 ST_FUNC
void relocate_common_syms(void)
413 ElfW(Sym
) *sym
, *sym_end
;
414 unsigned long offset
, align
;
416 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
417 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
420 if (sym
->st_shndx
== SHN_COMMON
) {
422 align
= sym
->st_value
;
423 offset
= bss_section
->data_offset
;
424 offset
= (offset
+ align
- 1) & -align
;
425 sym
->st_value
= offset
;
426 sym
->st_shndx
= bss_section
->sh_num
;
427 offset
+= sym
->st_size
;
428 bss_section
->data_offset
= offset
;
433 /* relocate symbol table, resolve undefined symbols if do_resolve is
434 true and output error if undefined symbol. */
435 ST_FUNC
void relocate_syms(TCCState
*s1
, int do_resolve
)
437 ElfW(Sym
) *sym
, *esym
, *sym_end
;
438 int sym_bind
, sh_num
, sym_index
;
441 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
442 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
445 sh_num
= sym
->st_shndx
;
446 if (sh_num
== SHN_UNDEF
) {
447 name
= strtab_section
->data
+ sym
->st_name
;
449 #if !defined TCC_TARGET_PE || !defined _WIN32
451 name
= symtab_section
->link
->data
+ sym
->st_name
;
452 addr
= resolve_sym(s1
, name
);
454 sym
->st_value
= (uplong
)addr
;
458 } else if (s1
->dynsym
) {
459 /* if dynamic symbol exist, then use it */
460 sym_index
= find_elf_sym(s1
->dynsym
, name
);
462 esym
= &((ElfW(Sym
) *)s1
->dynsym
->data
)[sym_index
];
463 sym
->st_value
= esym
->st_value
;
467 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
469 if (!strcmp(name
, "_fp_hw"))
471 /* only weak symbols are accepted to be undefined. Their
473 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
474 if (sym_bind
== STB_WEAK
) {
477 error_noabort("undefined symbol '%s'", name
);
479 } else if (sh_num
< SHN_LORESERVE
) {
480 /* add section base */
481 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
487 #ifndef TCC_TARGET_PE
488 #ifdef TCC_TARGET_X86_64
489 #define JMP_TABLE_ENTRY_SIZE 14
490 static uplong
add_jmp_table(TCCState
*s1
, uplong val
)
492 char *p
= s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
;
493 s1
->runtime_plt_and_got_offset
+= JMP_TABLE_ENTRY_SIZE
;
498 *(uplong
*)(p
+ 6) = val
;
502 static uplong
add_got_table(TCCState
*s1
, uplong val
)
504 uplong
*p
= (uplong
*)(s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
);
505 s1
->runtime_plt_and_got_offset
+= sizeof(uplong
);
509 #elif defined TCC_TARGET_ARM
510 #define JMP_TABLE_ENTRY_SIZE 8
511 static uplong
add_jmp_table(TCCState
*s1
, int val
)
513 uint32_t *p
= (uint32_t *)(s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
);
514 s1
->runtime_plt_and_got_offset
+= JMP_TABLE_ENTRY_SIZE
;
515 /* ldr pc, [pc, #-4] */
523 /* relocate a given section (CPU dependent) */
524 ST_FUNC
void relocate_section(TCCState
*s1
, Section
*s
)
527 ElfW_Rel
*rel
, *rel_end
, *qrel
;
532 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
537 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
538 qrel
= (ElfW_Rel
*)sr
->data
;
542 ptr
= s
->data
+ rel
->r_offset
;
544 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
545 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
547 #ifdef TCC_TARGET_X86_64
548 val
+= rel
->r_addend
;
550 type
= ELFW(R_TYPE
)(rel
->r_info
);
551 addr
= s
->sh_addr
+ rel
->r_offset
;
555 #if defined(TCC_TARGET_I386)
557 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
558 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
559 qrel
->r_offset
= rel
->r_offset
;
561 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_32
);
565 qrel
->r_info
= ELFW(R_INFO
)(0, R_386_RELATIVE
);
572 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
574 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
576 qrel
->r_offset
= rel
->r_offset
;
577 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_PC32
);
582 *(int *)ptr
+= val
- addr
;
585 *(int *)ptr
+= val
- addr
;
592 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
595 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
598 /* we load the got offset */
599 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
602 if (s1
->output_format
!= TCC_OUTPUT_FORMAT_BINARY
) {
604 error("can only produce 16-bit binary files");
606 *(short *)ptr
+= val
;
609 if (s1
->output_format
!= TCC_OUTPUT_FORMAT_BINARY
)
611 *(short *)ptr
+= val
- addr
;
613 #elif defined(TCC_TARGET_ARM)
620 x
= (*(int *)ptr
)&0xffffff;
621 (*(int *)ptr
) &= 0xff000000;
626 #ifndef TCC_TARGET_PE
627 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
628 if (s1
->output_type
== TCC_OUTPUT_MEMORY
)
629 x
+= add_jmp_table(s1
, val
) - val
; /* add veneer */
631 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
632 error("can't relocate value at %x",addr
);
641 x
= (*(int *)ptr
) & 0x7fffffff;
642 (*(int *)ptr
) &= 0x80000000;
645 if((x
^(x
>>1))&0x40000000)
646 error("can't relocate value at %x",addr
);
647 (*(int *)ptr
) |= x
& 0x7fffffff;
652 case R_ARM_BASE_PREL
:
653 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
656 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
659 /* we load the got offset */
660 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
665 /* trade Thumb support for ARMv4 support */
666 if ((0x0ffffff0 & *(int*)ptr
) == 0x012FFF10)
667 *(int*)ptr
^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */
670 fprintf(stderr
,"FIXME: handle reloc type %x at %x [%.8x] to %x\n",
671 type
, (unsigned)addr
, (unsigned)(uplong
)ptr
, (unsigned)val
);
673 #elif defined(TCC_TARGET_C67)
681 /* put the low 16 bits of the absolute address */
682 // add to what is already there
684 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
685 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
687 //patch both at once - assumes always in pairs Low - High
689 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
690 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
696 fprintf(stderr
,"FIXME: handle reloc type %x at %x [%.8x] to %x\n",
697 type
, (unsigned)addr
, (unsigned)(uplong
)ptr
, (unsigned)val
);
699 #elif defined(TCC_TARGET_X86_64)
701 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
702 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
703 qrel
->r_addend
= *(long long *)ptr
+ val
;
706 *(long long *)ptr
+= val
;
710 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
711 /* XXX: this logic may depend on TCC's codegen
712 now TCC uses R_X86_64_32 even for a 64bit pointer */
713 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
714 qrel
->r_addend
= *(int *)ptr
+ val
;
721 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
723 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
725 qrel
->r_offset
= rel
->r_offset
;
726 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_X86_64_PC32
);
727 qrel
->r_addend
= *(int *)ptr
;
733 case R_X86_64_PLT32
: {
735 diff
= (long long)val
- addr
;
736 if (diff
<= -2147483647 || diff
> 2147483647) {
737 #ifndef TCC_TARGET_PE
738 /* XXX: naive support for over 32bit jump */
739 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
740 val
= (add_jmp_table(s1
, val
- rel
->r_addend
) +
745 if (diff
<= -2147483647 || diff
> 2147483647) {
746 error("internal error: relocation failed");
752 case R_X86_64_GLOB_DAT
:
753 case R_X86_64_JUMP_SLOT
:
754 /* They don't need addend */
755 *(int *)ptr
= val
- rel
->r_addend
;
757 case R_X86_64_GOTPCREL
:
758 #ifndef TCC_TARGET_PE
759 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
760 val
= add_got_table(s1
, val
- rel
->r_addend
) + rel
->r_addend
;
761 *(int *)ptr
+= val
- addr
;
765 *(int *)ptr
+= (s1
->got
->sh_addr
- addr
+
766 s1
->got_offsets
[sym_index
] - 4);
768 case R_X86_64_GOTTPOFF
:
769 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
772 /* we load the got offset */
773 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
776 #error unsupported processor
780 /* if the relocation is allocated, we change its symbol table */
781 if (sr
->sh_flags
& SHF_ALLOC
)
782 sr
->link
= s1
->dynsym
;
785 /* relocate relocation table in 'sr' */
786 static void relocate_rel(TCCState
*s1
, Section
*sr
)
789 ElfW_Rel
*rel
, *rel_end
;
791 s
= s1
->sections
[sr
->sh_info
];
792 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
793 for(rel
= (ElfW_Rel
*)sr
->data
;
796 rel
->r_offset
+= s
->sh_addr
;
800 /* count the number of dynamic relocations so that we can reserve
802 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
804 ElfW_Rel
*rel
, *rel_end
;
805 int sym_index
, esym_index
, type
, count
;
808 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
809 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
810 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
811 type
= ELFW(R_TYPE
)(rel
->r_info
);
813 #if defined(TCC_TARGET_I386)
815 #elif defined(TCC_TARGET_X86_64)
822 #if defined(TCC_TARGET_I386)
824 #elif defined(TCC_TARGET_X86_64)
827 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
836 /* allocate the section */
837 sr
->sh_flags
|= SHF_ALLOC
;
838 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
843 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
848 if (index
>= s1
->nb_got_offsets
) {
849 /* find immediately bigger power of 2 and reallocate array */
853 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
855 error("memory full");
856 s1
->got_offsets
= tab
;
857 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
858 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
859 s1
->nb_got_offsets
= n
;
861 s1
->got_offsets
[index
] = val
;
864 /* XXX: suppress that */
865 static void put32(unsigned char *p
, uint32_t val
)
873 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
874 defined(TCC_TARGET_X86_64)
875 static uint32_t get32(unsigned char *p
)
877 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
881 static void build_got(TCCState
*s1
)
885 /* if no got, then create it */
886 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
887 s1
->got
->sh_entsize
= 4;
888 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
889 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
890 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
892 /* keep space for _DYNAMIC pointer, if present */
894 /* two dummy got entries */
898 /* keep space for _DYNAMIC pointer, if present */
901 /* two dummy got entries */
909 /* put a got entry corresponding to a symbol in symtab_section. 'size'
910 and 'info' can be modifed if more precise info comes from the DLL */
911 static void put_got_entry(TCCState
*s1
,
912 int reloc_type
, unsigned long size
, int info
,
918 unsigned long offset
;
924 /* if a got entry already exists for that symbol, no need to add one */
925 if (sym_index
< s1
->nb_got_offsets
&&
926 s1
->got_offsets
[sym_index
] != 0)
929 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
932 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
933 name
= symtab_section
->link
->data
+ sym
->st_name
;
934 offset
= sym
->st_value
;
935 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
937 #ifdef TCC_TARGET_X86_64
947 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
950 /* if we build a DLL, we add a %ebx offset */
951 if (s1
->output_type
== TCC_OUTPUT_DLL
)
957 /* add a PLT entry */
959 if (plt
->data_offset
== 0) {
960 /* first plt entry */
961 p
= section_ptr_add(plt
, 16);
962 p
[0] = 0xff; /* pushl got + PTR_SIZE */
964 put32(p
+ 2, PTR_SIZE
);
965 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
967 put32(p
+ 8, PTR_SIZE
* 2);
970 p
= section_ptr_add(plt
, 16);
971 p
[0] = 0xff; /* jmp *(got + x) */
973 put32(p
+ 2, s1
->got
->data_offset
);
974 p
[6] = 0x68; /* push $xxx */
975 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
976 p
[11] = 0xe9; /* jmp plt_start */
977 put32(p
+ 12, -(plt
->data_offset
));
979 /* the symbol is modified so that it will be relocated to
981 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
982 if (s1
->output_type
== TCC_OUTPUT_EXE
)
984 offset
= plt
->data_offset
- 16;
986 #elif defined(TCC_TARGET_ARM)
987 if (reloc_type
== R_ARM_JUMP_SLOT
) {
991 /* if we build a DLL, we add a %ebx offset */
992 if (s1
->output_type
== TCC_OUTPUT_DLL
)
993 error("DLLs unimplemented!");
995 /* add a PLT entry */
997 if (plt
->data_offset
== 0) {
998 /* first plt entry */
999 p
= section_ptr_add(plt
, 16);
1000 put32(p
, 0xe52de004);
1001 put32(p
+ 4, 0xe59fe010);
1002 put32(p
+ 8, 0xe08fe00e);
1003 put32(p
+ 12, 0xe5bef008);
1006 p
= section_ptr_add(plt
, 16);
1007 put32(p
, 0xe59fc004);
1008 put32(p
+4, 0xe08fc00c);
1009 put32(p
+8, 0xe59cf000);
1010 put32(p
+12, s1
->got
->data_offset
);
1012 /* the symbol is modified so that it will be relocated to
1014 if (s1
->output_type
== TCC_OUTPUT_EXE
)
1015 offset
= plt
->data_offset
- 16;
1017 #elif defined(TCC_TARGET_C67)
1018 error("C67 got not implemented");
1020 #error unsupported CPU
1022 index
= put_elf_sym(s1
->dynsym
, offset
,
1023 size
, info
, 0, sym
->st_shndx
, name
);
1024 /* put a got entry */
1025 put_elf_reloc(s1
->dynsym
, s1
->got
,
1026 s1
->got
->data_offset
,
1029 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
1033 /* build GOT and PLT entries */
1034 ST_FUNC
void build_got_entries(TCCState
*s1
)
1037 ElfW_Rel
*rel
, *rel_end
;
1039 int i
, type
, reloc_type
, sym_index
;
1041 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1042 s
= s1
->sections
[i
];
1043 if (s
->sh_type
!= SHT_RELX
)
1045 /* no need to handle got relocations */
1046 if (s
->link
!= symtab_section
)
1048 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
1049 for(rel
= (ElfW_Rel
*)s
->data
;
1052 type
= ELFW(R_TYPE
)(rel
->r_info
);
1054 #if defined(TCC_TARGET_I386)
1061 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1062 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1063 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1064 /* look at the symbol got offset. If none, then add one */
1065 if (type
== R_386_GOT32
)
1066 reloc_type
= R_386_GLOB_DAT
;
1068 reloc_type
= R_386_JMP_SLOT
;
1069 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1073 #elif defined(TCC_TARGET_ARM)
1074 case R_ARM_GOT_BREL
:
1075 case R_ARM_GOTOFF32
:
1076 case R_ARM_BASE_PREL
:
1080 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1081 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1082 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1083 /* look at the symbol got offset. If none, then add one */
1084 if (type
== R_ARM_GOT_BREL
)
1085 reloc_type
= R_ARM_GLOB_DAT
;
1087 reloc_type
= R_ARM_JUMP_SLOT
;
1088 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1092 #elif defined(TCC_TARGET_C67)
1099 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1100 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1101 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1102 /* look at the symbol got offset. If none, then add one */
1103 if (type
== R_C60_GOT32
)
1104 reloc_type
= R_C60_GLOB_DAT
;
1106 reloc_type
= R_C60_JMP_SLOT
;
1107 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1111 #elif defined(TCC_TARGET_X86_64)
1112 case R_X86_64_GOT32
:
1113 case R_X86_64_GOTTPOFF
:
1114 case R_X86_64_GOTPCREL
:
1115 case R_X86_64_PLT32
:
1118 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
||
1119 type
== R_X86_64_PLT32
) {
1120 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1121 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1122 /* look at the symbol got offset. If none, then add one */
1123 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
)
1124 reloc_type
= R_X86_64_GLOB_DAT
;
1126 reloc_type
= R_X86_64_JUMP_SLOT
;
1127 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1132 #error unsupported CPU
1141 ST_FUNC Section
*new_symtab(TCCState
*s1
,
1142 const char *symtab_name
, int sh_type
, int sh_flags
,
1143 const char *strtab_name
,
1144 const char *hash_name
, int hash_sh_flags
)
1146 Section
*symtab
, *strtab
, *hash
;
1147 int *ptr
, nb_buckets
;
1149 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1150 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1151 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1152 put_elf_str(strtab
, "");
1153 symtab
->link
= strtab
;
1154 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1158 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1159 hash
->sh_entsize
= sizeof(int);
1160 symtab
->hash
= hash
;
1161 hash
->link
= symtab
;
1163 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1164 ptr
[0] = nb_buckets
;
1166 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1170 /* put dynamic tag */
1171 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1174 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1176 dyn
->d_un
.d_val
= val
;
1179 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1183 char sym_start
[1024];
1186 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1187 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1189 s
= find_section(s1
, section_name
);
1194 end_offset
= s
->data_offset
;
1197 add_elf_sym(symtab_section
,
1199 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1200 s
->sh_num
, sym_start
);
1201 add_elf_sym(symtab_section
,
1203 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1204 s
->sh_num
, sym_end
);
1207 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
1209 #ifdef CONFIG_TCC_BCHECK
1211 Section
*init_section
;
1212 unsigned char *pinit
;
1215 if (0 == s1
->do_bounds_check
)
1218 /* XXX: add an object file to do that */
1219 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1221 add_elf_sym(symtab_section
, 0, 0,
1222 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1223 bounds_section
->sh_num
, "__bounds_start");
1224 /* add bound check code */
1225 #ifndef TCC_TARGET_PE
1228 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "bcheck.o");
1229 tcc_add_file(s1
, buf
);
1232 #ifdef TCC_TARGET_I386
1233 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1234 /* add 'call __bound_init()' in .init section */
1235 init_section
= find_section(s1
, ".init");
1236 pinit
= section_ptr_add(init_section
, 5);
1238 put32(pinit
+ 1, -4);
1239 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1240 put_elf_reloc(symtab_section
, init_section
,
1241 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1247 /* add tcc runtime libraries */
1248 ST_FUNC
void tcc_add_runtime(TCCState
*s1
)
1253 if (!s1
->nostdlib
) {
1254 #ifdef CONFIG_USE_LIBGCC
1255 tcc_add_library(s1
, "c");
1256 tcc_add_file(s1
, CONFIG_SYSROOT CONFIG_TCC_LDDIR
"/libgcc_s.so.1");
1258 tcc_add_library(s1
, "c");
1259 #ifndef WITHOUT_LIBTCC
1262 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "libtcc1.a");
1263 tcc_add_file(s1
, buf
);
1268 /* add crt end if not memory output */
1269 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1270 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1274 /* add various standard linker symbols (must be done after the
1275 sections are filled (for example after allocating common
1277 ST_FUNC
void tcc_add_linker_symbols(TCCState
*s1
)
1283 add_elf_sym(symtab_section
,
1284 text_section
->data_offset
, 0,
1285 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1286 text_section
->sh_num
, "_etext");
1287 add_elf_sym(symtab_section
,
1288 data_section
->data_offset
, 0,
1289 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1290 data_section
->sh_num
, "_edata");
1291 add_elf_sym(symtab_section
,
1292 bss_section
->data_offset
, 0,
1293 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1294 bss_section
->sh_num
, "_end");
1295 /* horrible new standard ldscript defines */
1296 add_init_array_defines(s1
, ".preinit_array");
1297 add_init_array_defines(s1
, ".init_array");
1298 add_init_array_defines(s1
, ".fini_array");
1300 /* add start and stop symbols for sections whose name can be
1302 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1303 s
= s1
->sections
[i
];
1304 if (s
->sh_type
== SHT_PROGBITS
&&
1305 (s
->sh_flags
& SHF_ALLOC
)) {
1309 /* check if section name can be expressed in C */
1315 if (!isid(ch
) && !isnum(ch
))
1319 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1320 add_elf_sym(symtab_section
,
1322 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1324 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1325 add_elf_sym(symtab_section
,
1327 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1334 /* name of ELF interpreter */
1335 #if defined __FreeBSD__
1336 static const char elf_interp
[] = "/libexec/ld-elf.so.1";
1337 #elif defined __FreeBSD_kernel__
1338 static char elf_interp
[] = "/lib/ld.so.1";
1339 #elif defined TCC_ARM_EABI
1340 static const char elf_interp
[] = "/lib/ld-linux.so.3";
1341 #elif defined(TCC_TARGET_X86_64)
1342 static const char elf_interp
[] = CONFIG_TCC_LDDIR
"/ld-linux-x86-64.so.2";
1343 #elif defined(TCC_UCLIBC)
1344 static const char elf_interp
[] = "/lib/ld-uClibc.so.0";
1346 static const char elf_interp
[] = "/lib/ld-linux.so.2";
1349 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1350 const int *section_order
)
1353 int i
, offset
, size
;
1356 for(i
=1;i
<s1
->nb_sections
;i
++) {
1357 s
= s1
->sections
[section_order
[i
]];
1358 if (s
->sh_type
!= SHT_NOBITS
&&
1359 (s
->sh_flags
& SHF_ALLOC
)) {
1360 while (offset
< s
->sh_offset
) {
1365 fwrite(s
->data
, 1, size
, f
);
1371 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1373 #define EXTRA_RELITEMS 14
1375 /* move the relocation value from .dynsym to .got */
1376 void patch_dynsym_undef(TCCState
*s1
, Section
*s
)
1378 uint32_t *gotd
= (void *)s1
->got
->data
;
1379 ElfW(Sym
) *sym
, *sym_end
;
1381 gotd
+= 3; // dummy entries in .got
1382 /* relocate symbols in .dynsym */
1383 sym_end
= (ElfW(Sym
) *)(s
->data
+ s
->data_offset
);
1384 for (sym
= (ElfW(Sym
) *)s
->data
+ 1; sym
< sym_end
; sym
++) {
1385 if (sym
->st_shndx
== SHN_UNDEF
) {
1386 *gotd
++ = sym
->st_value
+ 6; // XXX 6 is magic ?
1393 #define EXTRA_RELITEMS 9
1396 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1398 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1399 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1400 unsigned long offset
;
1402 if (sym_index
>= s1
->nb_got_offsets
)
1404 offset
= s1
->got_offsets
[sym_index
];
1405 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1406 #ifdef TCC_TARGET_X86_64
1407 /* only works for x86-64 */
1408 put32(s1
->got
->data
+ offset
, sym
->st_value
>> 32);
1410 put32(s1
->got
->data
+ offset
, sym
->st_value
& 0xffffffff);
1413 ST_FUNC
void fill_got(TCCState
*s1
)
1416 ElfW_Rel
*rel
, *rel_end
;
1419 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1420 s
= s1
->sections
[i
];
1421 if (s
->sh_type
!= SHT_RELX
)
1423 /* no need to handle got relocations */
1424 if (s
->link
!= symtab_section
)
1426 rel_end
= (ElfW_Rel
*) (s
->data
+ s
->data_offset
);
1427 for(rel
= (ElfW_Rel
*) s
->data
; rel
< rel_end
; rel
++) {
1428 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1429 case R_X86_64_GOT32
:
1430 case R_X86_64_GOTPCREL
:
1431 case R_X86_64_PLT32
:
1432 fill_got_entry(s1
, rel
);
1440 /* output an ELF file */
1441 /* XXX: suppress unneeded sections */
1442 static int elf_output_file(TCCState
*s1
, const char *filename
)
1448 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1450 Section
*strsec
, *s
;
1451 ElfW(Shdr
) shdr
, *sh
;
1452 ElfW(Phdr
) *phdr
, *ph
;
1453 Section
*interp
, *dynamic
, *dynstr
;
1454 unsigned long saved_dynamic_data_offset
;
1456 int type
, file_type
;
1457 unsigned long rel_addr
, rel_size
;
1458 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1459 unsigned long bss_addr
, bss_size
;
1462 file_type
= s1
->output_type
;
1465 if (file_type
!= TCC_OUTPUT_OBJ
) {
1466 tcc_add_runtime(s1
);
1470 section_order
= NULL
;
1473 dynstr
= NULL
; /* avoid warning */
1474 saved_dynamic_data_offset
= 0; /* avoid warning */
1476 if (file_type
!= TCC_OUTPUT_OBJ
) {
1477 relocate_common_syms();
1479 tcc_add_linker_symbols(s1
);
1481 if (!s1
->static_link
) {
1483 int sym_index
, index
;
1484 ElfW(Sym
) *esym
, *sym_end
;
1486 if (file_type
== TCC_OUTPUT_EXE
) {
1488 /* allow override the dynamic loader */
1489 const char *elfint
= getenv("LD_SO");
1491 elfint
= elf_interp
;
1492 /* add interpreter section only if executable */
1493 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1494 interp
->sh_addralign
= 1;
1495 ptr
= section_ptr_add(interp
, 1+strlen(elfint
));
1496 strcpy(ptr
, elfint
);
1499 /* add dynamic symbol table */
1500 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1502 ".hash", SHF_ALLOC
);
1503 dynstr
= s1
->dynsym
->link
;
1505 /* add dynamic section */
1506 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1507 SHF_ALLOC
| SHF_WRITE
);
1508 dynamic
->link
= dynstr
;
1509 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1512 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1513 SHF_ALLOC
| SHF_EXECINSTR
);
1514 s1
->plt
->sh_entsize
= 4;
1518 /* scan for undefined symbols and see if they are in the
1519 dynamic symbols. If a symbol STT_FUNC or STT_GNU_IFUNC
1520 is found, then we add it in the PLT. If a symbol
1521 STT_OBJECT is found, we add it in the .bss section with
1522 a suitable relocation */
1523 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1524 symtab_section
->data_offset
);
1525 if (file_type
== TCC_OUTPUT_EXE
) {
1526 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1529 if (sym
->st_shndx
== SHN_UNDEF
) {
1530 name
= symtab_section
->link
->data
+ sym
->st_name
;
1531 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1533 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1534 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1535 if ((type
== STT_FUNC
) || (type
== STT_GNU_IFUNC
)) {
1536 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1538 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1539 } else if (type
== STT_OBJECT
) {
1540 unsigned long offset
;
1541 ElfW(Sym
) *dynsym
, *dynsym_end
;
1542 offset
= bss_section
->data_offset
;
1543 /* XXX: which alignment ? */
1544 offset
= (offset
+ 16 - 1) & -16;
1545 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1547 bss_section
->sh_num
, name
);
1548 // Ensure R_COPY works for weak symbol aliases
1549 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1550 dynsym_end
= (ElfW(Sym
) *)
1551 (s1
->dynsymtab_section
->data
+
1552 s1
->dynsymtab_section
->data_offset
);
1553 for(dynsym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1554 dynsym
< dynsym_end
; dynsym
++) {
1555 if ((dynsym
->st_value
== esym
->st_value
)
1556 && (ELFW(ST_BIND
)(dynsym
->st_info
) == STB_GLOBAL
)) {
1558 dynname
= s1
->dynsymtab_section
->link
->data
1560 put_elf_sym(s1
->dynsym
, offset
,
1563 bss_section
->sh_num
,
1569 put_elf_reloc(s1
->dynsym
, bss_section
,
1570 offset
, R_COPY
, index
);
1571 offset
+= esym
->st_size
;
1572 bss_section
->data_offset
= offset
;
1575 /* STB_WEAK undefined symbols are accepted */
1576 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1578 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1579 !strcmp(name
, "_fp_hw")) {
1581 error_noabort("undefined symbol '%s'", name
);
1584 } else if (s1
->rdynamic
&&
1585 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1586 /* if -rdynamic option, then export all non
1588 name
= symtab_section
->link
->data
+ sym
->st_name
;
1589 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1591 sym
->st_shndx
, name
);
1598 /* now look at unresolved dynamic symbols and export
1599 corresponding symbol */
1600 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1601 s1
->dynsymtab_section
->data_offset
);
1602 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1605 if (esym
->st_shndx
== SHN_UNDEF
) {
1606 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1607 sym_index
= find_elf_sym(symtab_section
, name
);
1609 /* XXX: avoid adding a symbol if already
1610 present because of -rdynamic ? */
1611 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1612 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1614 sym
->st_shndx
, name
);
1616 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1617 /* weak symbols can stay undefined */
1619 warning("undefined dynamic symbol '%s'", name
);
1626 /* shared library case : we simply export all the global symbols */
1627 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1628 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1629 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1632 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1633 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1634 if ((ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
||
1635 ELFW(ST_TYPE
)(sym
->st_info
) == STT_GNU_IFUNC
)
1636 && sym
->st_shndx
== SHN_UNDEF
) {
1637 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1639 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1641 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1642 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1644 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1649 name
= symtab_section
->link
->data
+ sym
->st_name
;
1650 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1652 sym
->st_shndx
, name
);
1653 s1
->symtab_to_dynsym
[sym
-
1654 (ElfW(Sym
) *)symtab_section
->data
] =
1661 build_got_entries(s1
);
1663 /* add a list of needed dlls */
1664 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1665 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1666 if (dllref
->level
== 0)
1667 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1671 put_dt(dynamic
, DT_RPATH
, put_elf_str(dynstr
, s1
->rpath
));
1673 /* XXX: currently, since we do not handle PIC code, we
1674 must relocate the readonly segments */
1675 if (file_type
== TCC_OUTPUT_DLL
) {
1677 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1678 put_dt(dynamic
, DT_TEXTREL
, 0);
1682 put_dt(dynamic
, DT_SYMBOLIC
, 0);
1684 /* add necessary space for other entries */
1685 saved_dynamic_data_offset
= dynamic
->data_offset
;
1686 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * EXTRA_RELITEMS
;
1688 /* still need to build got entries in case of static link */
1689 build_got_entries(s1
);
1693 memset(&ehdr
, 0, sizeof(ehdr
));
1695 /* we add a section for symbols */
1696 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1697 put_elf_str(strsec
, "");
1699 /* compute number of sections */
1700 shnum
= s1
->nb_sections
;
1702 /* this array is used to reorder sections in the output file */
1703 section_order
= tcc_malloc(sizeof(int) * shnum
);
1704 section_order
[0] = 0;
1707 /* compute number of program headers */
1710 case TCC_OUTPUT_OBJ
:
1713 case TCC_OUTPUT_EXE
:
1714 if (!s1
->static_link
)
1715 phnum
= 4 + HAVE_PHDR
;
1719 case TCC_OUTPUT_DLL
:
1724 /* allocate strings for section names and decide if an unallocated
1725 section should be output */
1726 /* NOTE: the strsec section comes last, so its size is also
1728 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1729 s
= s1
->sections
[i
];
1730 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1732 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1737 s
->reloc
? s
->reloc
->name
: "n"
1740 /* when generating a DLL, we include relocations but we may
1742 if (file_type
== TCC_OUTPUT_DLL
&&
1743 s
->sh_type
== SHT_RELX
&&
1744 !(s
->sh_flags
& SHF_ALLOC
)) {
1745 /* //gr: avoid bogus relocs for empty (debug) sections */
1746 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1747 prepare_dynamic_rel(s1
, s
);
1748 else if (s1
->do_debug
)
1749 s
->sh_size
= s
->data_offset
;
1750 } else if (s1
->do_debug
||
1751 file_type
== TCC_OUTPUT_OBJ
||
1752 (s
->sh_flags
& SHF_ALLOC
) ||
1753 i
== (s1
->nb_sections
- 1)) {
1754 /* we output all sections if debug or object file */
1755 s
->sh_size
= s
->data_offset
;
1759 /* allocate program segment headers */
1760 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1762 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1763 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1768 /* compute section to program header mapping */
1769 if (s1
->has_text_addr
) {
1770 int a_offset
, p_offset
;
1771 addr
= s1
->text_addr
;
1772 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1774 a_offset
= addr
& (s1
->section_align
- 1);
1775 p_offset
= file_offset
& (s1
->section_align
- 1);
1776 if (a_offset
< p_offset
)
1777 a_offset
+= s1
->section_align
;
1778 file_offset
+= (a_offset
- p_offset
);
1780 if (file_type
== TCC_OUTPUT_DLL
)
1783 addr
= ELF_START_ADDR
;
1784 /* compute address after headers */
1785 addr
+= (file_offset
& (s1
->section_align
- 1));
1788 /* dynamic relocation table information, for .dynamic section */
1792 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1793 bss_addr
= bss_size
= 0;
1795 /* leave one program header for the program interpreter */
1798 ph
+= 1 + HAVE_PHDR
;
1800 for(j
= 0; j
< 2; j
++) {
1801 ph
->p_type
= PT_LOAD
;
1803 ph
->p_flags
= PF_R
| PF_X
;
1805 ph
->p_flags
= PF_R
| PF_W
;
1806 ph
->p_align
= s1
->section_align
;
1808 /* we do the following ordering: interp, symbol tables,
1809 relocations, progbits, nobits */
1810 /* XXX: do faster and simpler sorting */
1811 for(k
= 0; k
< 5; k
++) {
1812 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1813 s
= s1
->sections
[i
];
1814 /* compute if section should be included */
1816 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1820 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1821 (SHF_ALLOC
| SHF_WRITE
))
1827 } else if (s
->sh_type
== SHT_DYNSYM
||
1828 s
->sh_type
== SHT_STRTAB
||
1829 s
->sh_type
== SHT_HASH
) {
1832 } else if (s
->sh_type
== SHT_RELX
) {
1835 } else if (s
->sh_type
== SHT_NOBITS
) {
1842 section_order
[sh_order_index
++] = i
;
1844 /* section matches: we align it and add its size */
1846 addr
= (addr
+ s
->sh_addralign
- 1) &
1847 ~(s
->sh_addralign
- 1);
1848 file_offset
+= addr
- tmp
;
1849 s
->sh_offset
= file_offset
;
1852 /* update program header infos */
1853 if (ph
->p_offset
== 0) {
1854 ph
->p_offset
= file_offset
;
1856 ph
->p_paddr
= ph
->p_vaddr
;
1858 /* update dynamic relocation infos */
1859 if (s
->sh_type
== SHT_RELX
) {
1860 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1861 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.got")) { // rel_size == 0) {
1863 rel_size
+= s
->sh_size
; // XXX only first rel.
1865 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.bss")) { // rel_size == 0) {
1867 bss_size
= s
->sh_size
; // XXX only first rel.
1872 rel_size
+= s
->sh_size
;
1876 if (s
->sh_type
!= SHT_NOBITS
)
1877 file_offset
+= s
->sh_size
;
1880 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1881 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1884 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1885 /* if in the middle of a page, we duplicate the page in
1886 memory so that one copy is RX and the other is RW */
1887 if ((addr
& (s1
->section_align
- 1)) != 0)
1888 addr
+= s1
->section_align
;
1890 addr
= (addr
+ s1
->section_align
- 1) & ~(s1
->section_align
- 1);
1891 file_offset
= (file_offset
+ s1
->section_align
- 1) &
1892 ~(s1
->section_align
- 1);
1897 /* if interpreter, then add corresponing program header */
1901 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1903 int len
= phnum
* sizeof(ElfW(Phdr
));
1905 ph
->p_type
= PT_PHDR
;
1906 ph
->p_offset
= sizeof(ElfW(Ehdr
));
1907 ph
->p_vaddr
= interp
->sh_addr
- len
;
1908 ph
->p_paddr
= ph
->p_vaddr
;
1909 ph
->p_filesz
= ph
->p_memsz
= len
;
1910 ph
->p_flags
= PF_R
| PF_X
;
1911 ph
->p_align
= 4; // interp->sh_addralign;
1916 ph
->p_type
= PT_INTERP
;
1917 ph
->p_offset
= interp
->sh_offset
;
1918 ph
->p_vaddr
= interp
->sh_addr
;
1919 ph
->p_paddr
= ph
->p_vaddr
;
1920 ph
->p_filesz
= interp
->sh_size
;
1921 ph
->p_memsz
= interp
->sh_size
;
1923 ph
->p_align
= interp
->sh_addralign
;
1926 /* if dynamic section, then add corresponing program header */
1930 ph
= &phdr
[phnum
- 1];
1932 ph
->p_type
= PT_DYNAMIC
;
1933 ph
->p_offset
= dynamic
->sh_offset
;
1934 ph
->p_vaddr
= dynamic
->sh_addr
;
1935 ph
->p_paddr
= ph
->p_vaddr
;
1936 ph
->p_filesz
= dynamic
->sh_size
;
1937 ph
->p_memsz
= dynamic
->sh_size
;
1938 ph
->p_flags
= PF_R
| PF_W
;
1939 ph
->p_align
= dynamic
->sh_addralign
;
1941 /* put GOT dynamic section address */
1942 put32(s1
->got
->data
, dynamic
->sh_addr
);
1944 /* relocate the PLT */
1945 if (file_type
== TCC_OUTPUT_EXE
1946 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1947 || file_type
== TCC_OUTPUT_DLL
1953 p_end
= p
+ s1
->plt
->data_offset
;
1955 #if defined(TCC_TARGET_I386)
1956 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1957 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1960 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1963 #elif defined(TCC_TARGET_X86_64)
1964 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1965 put32(p
+ 2, get32(p
+ 2) + x
);
1966 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1969 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1972 #elif defined(TCC_TARGET_ARM)
1974 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1977 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1980 #elif defined(TCC_TARGET_C67)
1983 #error unsupported CPU
1988 /* relocate symbols in .dynsym */
1989 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1990 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1993 if (sym
->st_shndx
== SHN_UNDEF
) {
1994 /* relocate to the PLT if the symbol corresponds
1997 sym
->st_value
+= s1
->plt
->sh_addr
;
1998 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1999 /* do symbol relocation */
2000 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
2004 /* put dynamic section entries */
2005 dynamic
->data_offset
= saved_dynamic_data_offset
;
2006 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
2007 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
2008 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
2009 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
2010 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
2011 #ifdef TCC_TARGET_X86_64
2012 put_dt(dynamic
, DT_RELA
, rel_addr
);
2013 put_dt(dynamic
, DT_RELASZ
, rel_size
);
2014 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
2016 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2017 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2018 put_dt(dynamic
, DT_PLTRELSZ
, rel_size
);
2019 put_dt(dynamic
, DT_JMPREL
, rel_addr
);
2020 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
2021 put_dt(dynamic
, DT_REL
, bss_addr
);
2022 put_dt(dynamic
, DT_RELSZ
, bss_size
);
2024 put_dt(dynamic
, DT_REL
, rel_addr
);
2025 put_dt(dynamic
, DT_RELSZ
, rel_size
);
2026 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
2030 put_dt(dynamic
, DT_DEBUG
, 0);
2031 put_dt(dynamic
, DT_NULL
, 0);
2034 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2035 ehdr
.e_phnum
= phnum
;
2036 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2039 /* all other sections come after */
2040 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2041 s
= s1
->sections
[i
];
2042 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
2044 section_order
[sh_order_index
++] = i
;
2046 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
2047 ~(s
->sh_addralign
- 1);
2048 s
->sh_offset
= file_offset
;
2049 if (s
->sh_type
!= SHT_NOBITS
)
2050 file_offset
+= s
->sh_size
;
2053 /* if building executable or DLL, then relocate each section
2054 except the GOT which is already relocated */
2055 if (file_type
!= TCC_OUTPUT_OBJ
) {
2056 relocate_syms(s1
, 0);
2058 if (s1
->nb_errors
!= 0) {
2064 /* relocate sections */
2065 /* XXX: ignore sections with allocated relocations ? */
2066 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2067 s
= s1
->sections
[i
];
2068 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
2069 relocate_section(s1
, s
);
2072 /* relocate relocation entries if the relocation tables are
2073 allocated in the executable */
2074 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2075 s
= s1
->sections
[i
];
2076 if ((s
->sh_flags
& SHF_ALLOC
) &&
2077 s
->sh_type
== SHT_RELX
) {
2078 relocate_rel(s1
, s
);
2082 /* get entry point address */
2083 if (file_type
== TCC_OUTPUT_EXE
)
2084 ehdr
.e_entry
= (uplong
)tcc_get_symbol_err(s1
, "_start");
2086 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
2088 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2091 /* write elf file */
2092 if (file_type
== TCC_OUTPUT_OBJ
)
2097 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2099 error_noabort("could not write '%s'", filename
);
2102 f
= fdopen(fd
, "wb");
2104 printf("<- %s\n", filename
);
2106 #ifdef TCC_TARGET_COFF
2107 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
2108 tcc_output_coff(s1
, f
);
2111 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
2112 sort_syms(s1
, symtab_section
);
2115 file_offset
= (file_offset
+ 3) & -4;
2118 ehdr
.e_ident
[0] = ELFMAG0
;
2119 ehdr
.e_ident
[1] = ELFMAG1
;
2120 ehdr
.e_ident
[2] = ELFMAG2
;
2121 ehdr
.e_ident
[3] = ELFMAG3
;
2122 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
2123 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2124 ehdr
.e_ident
[6] = EV_CURRENT
;
2125 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2126 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2128 #ifdef TCC_TARGET_ARM
2130 ehdr
.e_ident
[EI_OSABI
] = 0;
2131 ehdr
.e_flags
= 4 << 24;
2133 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2138 case TCC_OUTPUT_EXE
:
2139 ehdr
.e_type
= ET_EXEC
;
2141 case TCC_OUTPUT_DLL
:
2142 ehdr
.e_type
= ET_DYN
;
2144 case TCC_OUTPUT_OBJ
:
2145 ehdr
.e_type
= ET_REL
;
2148 ehdr
.e_machine
= EM_TCC_TARGET
;
2149 ehdr
.e_version
= EV_CURRENT
;
2150 ehdr
.e_shoff
= file_offset
;
2151 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2152 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2153 ehdr
.e_shnum
= shnum
;
2154 ehdr
.e_shstrndx
= shnum
- 1;
2156 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2157 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2158 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2160 for(i
=1;i
<s1
->nb_sections
;i
++) {
2161 s
= s1
->sections
[section_order
[i
]];
2162 if (s
->sh_type
!= SHT_NOBITS
) {
2163 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2164 if (s
->sh_type
== SHT_DYNSYM
)
2165 patch_dynsym_undef(s1
, s
);
2167 while (offset
< s
->sh_offset
) {
2172 fwrite(s
->data
, 1, size
, f
);
2177 /* output section headers */
2178 while (offset
< ehdr
.e_shoff
) {
2183 for(i
=0;i
<s1
->nb_sections
;i
++) {
2185 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2186 s
= s1
->sections
[i
];
2188 sh
->sh_name
= s
->sh_name
;
2189 sh
->sh_type
= s
->sh_type
;
2190 sh
->sh_flags
= s
->sh_flags
;
2191 sh
->sh_entsize
= s
->sh_entsize
;
2192 sh
->sh_info
= s
->sh_info
;
2194 sh
->sh_link
= s
->link
->sh_num
;
2195 sh
->sh_addralign
= s
->sh_addralign
;
2196 sh
->sh_addr
= s
->sh_addr
;
2197 sh
->sh_offset
= s
->sh_offset
;
2198 sh
->sh_size
= s
->sh_size
;
2200 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2203 tcc_output_binary(s1
, f
, section_order
);
2209 tcc_free(s1
->symtab_to_dynsym
);
2210 tcc_free(section_order
);
2212 tcc_free(s1
->got_offsets
);
2216 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2219 #ifdef TCC_TARGET_PE
2220 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2221 ret
= pe_output_file(s
, filename
);
2225 ret
= elf_output_file(s
, filename
);
2230 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2234 data
= tcc_malloc(size
);
2235 lseek(fd
, file_offset
, SEEK_SET
);
2236 read(fd
, data
, size
);
2240 typedef struct SectionMergeInfo
{
2241 Section
*s
; /* corresponding existing section */
2242 unsigned long offset
; /* offset of the new section in the existing section */
2243 uint8_t new_section
; /* true if section 's' was added */
2244 uint8_t link_once
; /* true if link once section */
2247 /* load an object file and merge it with current files */
2248 /* XXX: handle correctly stab (debug) info */
2249 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
2250 int fd
, unsigned long file_offset
)
2253 ElfW(Shdr
) *shdr
, *sh
;
2254 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2255 unsigned char *strsec
, *strtab
;
2256 int *old_to_new_syms
;
2257 char *sh_name
, *name
;
2258 SectionMergeInfo
*sm_table
, *sm
;
2259 ElfW(Sym
) *sym
, *symtab
;
2260 ElfW_Rel
*rel
, *rel_end
;
2266 stab_index
= stabstr_index
= 0;
2268 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2270 if (ehdr
.e_ident
[0] != ELFMAG0
||
2271 ehdr
.e_ident
[1] != ELFMAG1
||
2272 ehdr
.e_ident
[2] != ELFMAG2
||
2273 ehdr
.e_ident
[3] != ELFMAG3
)
2275 /* test if object file */
2276 if (ehdr
.e_type
!= ET_REL
)
2278 /* test CPU specific stuff */
2279 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2280 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2282 error_noabort("invalid object file");
2286 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2287 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2288 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2290 /* load section names */
2291 sh
= &shdr
[ehdr
.e_shstrndx
];
2292 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2294 /* load symtab and strtab */
2295 old_to_new_syms
= NULL
;
2299 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2301 if (sh
->sh_type
== SHT_SYMTAB
) {
2303 error_noabort("object must contain only one symtab");
2308 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2309 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2310 sm_table
[i
].s
= symtab_section
;
2312 /* now load strtab */
2313 sh
= &shdr
[sh
->sh_link
];
2314 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2318 /* now examine each section and try to merge its content with the
2320 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2321 /* no need to examine section name strtab */
2322 if (i
== ehdr
.e_shstrndx
)
2325 sh_name
= strsec
+ sh
->sh_name
;
2326 /* ignore sections types we do not handle */
2327 if (sh
->sh_type
!= SHT_PROGBITS
&&
2328 sh
->sh_type
!= SHT_RELX
&&
2330 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2332 sh
->sh_type
!= SHT_NOBITS
&&
2333 sh
->sh_type
!= SHT_PREINIT_ARRAY
&&
2334 sh
->sh_type
!= SHT_INIT_ARRAY
&&
2335 sh
->sh_type
!= SHT_FINI_ARRAY
&&
2336 strcmp(sh_name
, ".stabstr")
2339 if (sh
->sh_addralign
< 1)
2340 sh
->sh_addralign
= 1;
2341 /* find corresponding section, if any */
2342 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2343 s
= s1
->sections
[j
];
2344 if (!strcmp(s
->name
, sh_name
)) {
2345 if (!strncmp(sh_name
, ".gnu.linkonce",
2346 sizeof(".gnu.linkonce") - 1)) {
2347 /* if a 'linkonce' section is already present, we
2348 do not add it again. It is a little tricky as
2349 symbols can still be defined in
2351 sm_table
[i
].link_once
= 1;
2358 /* not found: create new section */
2359 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2360 /* take as much info as possible from the section. sh_link and
2361 sh_info will be updated later */
2362 s
->sh_addralign
= sh
->sh_addralign
;
2363 s
->sh_entsize
= sh
->sh_entsize
;
2364 sm_table
[i
].new_section
= 1;
2366 if (sh
->sh_type
!= s
->sh_type
) {
2367 error_noabort("invalid section type");
2371 /* align start of section */
2372 offset
= s
->data_offset
;
2374 if (0 == strcmp(sh_name
, ".stab")) {
2378 if (0 == strcmp(sh_name
, ".stabstr")) {
2383 size
= sh
->sh_addralign
- 1;
2384 offset
= (offset
+ size
) & ~size
;
2385 if (sh
->sh_addralign
> s
->sh_addralign
)
2386 s
->sh_addralign
= sh
->sh_addralign
;
2387 s
->data_offset
= offset
;
2389 sm_table
[i
].offset
= offset
;
2391 /* concatenate sections */
2393 if (sh
->sh_type
!= SHT_NOBITS
) {
2395 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2396 ptr
= section_ptr_add(s
, size
);
2397 read(fd
, ptr
, size
);
2399 s
->data_offset
+= size
;
2404 /* //gr relocate stab strings */
2405 if (stab_index
&& stabstr_index
) {
2408 s
= sm_table
[stab_index
].s
;
2409 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2410 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2411 o
= sm_table
[stabstr_index
].offset
;
2413 a
->n_strx
+= o
, a
++;
2416 /* second short pass to update sh_link and sh_info fields of new
2418 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2420 if (!s
|| !sm_table
[i
].new_section
)
2423 if (sh
->sh_link
> 0)
2424 s
->link
= sm_table
[sh
->sh_link
].s
;
2425 if (sh
->sh_type
== SHT_RELX
) {
2426 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2427 /* update backward link */
2428 s1
->sections
[s
->sh_info
]->reloc
= s
;
2433 /* resolve symbols */
2434 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2437 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2438 if (sym
->st_shndx
!= SHN_UNDEF
&&
2439 sym
->st_shndx
< SHN_LORESERVE
) {
2440 sm
= &sm_table
[sym
->st_shndx
];
2441 if (sm
->link_once
) {
2442 /* if a symbol is in a link once section, we use the
2443 already defined symbol. It is very important to get
2444 correct relocations */
2445 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2446 name
= strtab
+ sym
->st_name
;
2447 sym_index
= find_elf_sym(symtab_section
, name
);
2449 old_to_new_syms
[i
] = sym_index
;
2453 /* if no corresponding section added, no need to add symbol */
2456 /* convert section number */
2457 sym
->st_shndx
= sm
->s
->sh_num
;
2459 sym
->st_value
+= sm
->offset
;
2462 name
= strtab
+ sym
->st_name
;
2463 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2464 sym
->st_info
, sym
->st_other
,
2465 sym
->st_shndx
, name
);
2466 old_to_new_syms
[i
] = sym_index
;
2469 /* third pass to patch relocation entries */
2470 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2475 offset
= sm_table
[i
].offset
;
2476 switch(s
->sh_type
) {
2478 /* take relocation offset information */
2479 offseti
= sm_table
[sh
->sh_info
].offset
;
2480 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2481 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2486 /* convert symbol index */
2487 type
= ELFW(R_TYPE
)(rel
->r_info
);
2488 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2489 /* NOTE: only one symtab assumed */
2490 if (sym_index
>= nb_syms
)
2492 sym_index
= old_to_new_syms
[sym_index
];
2493 /* ignore link_once in rel section. */
2494 if (!sym_index
&& !sm
->link_once
2495 #ifdef TCC_TARGET_ARM
2496 && type
!= R_ARM_V4BX
2500 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2501 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2504 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2505 /* offset the relocation offset */
2506 rel
->r_offset
+= offseti
;
2518 tcc_free(old_to_new_syms
);
2525 typedef struct ArchiveHeader
{
2526 char ar_name
[16]; /* name of this member */
2527 char ar_date
[12]; /* file mtime */
2528 char ar_uid
[6]; /* owner uid; printed as decimal */
2529 char ar_gid
[6]; /* owner gid; printed as decimal */
2530 char ar_mode
[8]; /* file mode, printed as octal */
2531 char ar_size
[10]; /* file size, printed as decimal */
2532 char ar_fmag
[2]; /* should contain ARFMAG */
2535 static int get_be32(const uint8_t *b
)
2537 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2540 /* load only the objects which resolve undefined symbols */
2541 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2543 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2545 const char *ar_names
, *p
;
2546 const uint8_t *ar_index
;
2549 data
= tcc_malloc(size
);
2550 if (read(fd
, data
, size
) != size
)
2552 nsyms
= get_be32(data
);
2553 ar_index
= data
+ 4;
2554 ar_names
= ar_index
+ nsyms
* 4;
2558 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2559 sym_index
= find_elf_sym(symtab_section
, p
);
2561 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2562 if(sym
->st_shndx
== SHN_UNDEF
) {
2563 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2565 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2568 lseek(fd
, off
, SEEK_SET
);
2569 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2584 /* load a '.a' file */
2585 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
)
2592 unsigned long file_offset
;
2594 /* skip magic which was already checked */
2595 read(fd
, magic
, sizeof(magic
));
2598 len
= read(fd
, &hdr
, sizeof(hdr
));
2601 if (len
!= sizeof(hdr
)) {
2602 error_noabort("invalid archive");
2605 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2606 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2607 size
= strtol(ar_size
, NULL
, 0);
2608 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2609 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2610 if (ar_name
[i
] != ' ')
2613 ar_name
[i
+ 1] = '\0';
2614 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2615 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2617 size
= (size
+ 1) & ~1;
2618 if (!strcmp(ar_name
, "/")) {
2619 /* coff symbol table : we handle it */
2620 if(s1
->alacarte_link
)
2621 return tcc_load_alacarte(s1
, fd
, size
);
2622 } else if (!strcmp(ar_name
, "//") ||
2623 !strcmp(ar_name
, "__.SYMDEF") ||
2624 !strcmp(ar_name
, "__.SYMDEF/") ||
2625 !strcmp(ar_name
, "ARFILENAMES/")) {
2626 /* skip symbol table or archive names */
2628 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2631 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2636 #ifndef TCC_TARGET_PE
2637 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2638 is referenced by the user (so it should be added as DT_NEEDED in
2639 the generated ELF file) */
2640 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2643 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2644 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2645 ElfW(Sym
) *sym
, *dynsym
;
2646 ElfW(Dyn
) *dt
, *dynamic
;
2647 unsigned char *dynstr
;
2648 const char *name
, *soname
;
2649 DLLReference
*dllref
;
2651 read(fd
, &ehdr
, sizeof(ehdr
));
2653 /* test CPU specific stuff */
2654 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2655 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2656 error_noabort("bad architecture");
2661 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2663 /* load dynamic section and dynamic symbols */
2667 dynsym
= NULL
; /* avoid warning */
2668 dynstr
= NULL
; /* avoid warning */
2669 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2670 switch(sh
->sh_type
) {
2672 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2673 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2676 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2677 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2678 sh1
= &shdr
[sh
->sh_link
];
2679 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2686 /* compute the real library name */
2687 soname
= tcc_basename(filename
);
2689 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2690 if (dt
->d_tag
== DT_SONAME
) {
2691 soname
= dynstr
+ dt
->d_un
.d_val
;
2695 /* if the dll is already loaded, do not load it */
2696 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2697 dllref
= s1
->loaded_dlls
[i
];
2698 if (!strcmp(soname
, dllref
->name
)) {
2699 /* but update level if needed */
2700 if (level
< dllref
->level
)
2701 dllref
->level
= level
;
2707 // printf("loading dll '%s'\n", soname);
2709 /* add the dll and its level */
2710 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2711 dllref
->level
= level
;
2712 strcpy(dllref
->name
, soname
);
2713 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2715 /* add dynamic symbols in dynsym_section */
2716 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2717 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2718 if (sym_bind
== STB_LOCAL
)
2720 name
= dynstr
+ sym
->st_name
;
2721 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2722 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2725 /* load all referenced DLLs */
2726 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2729 name
= dynstr
+ dt
->d_un
.d_val
;
2730 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2731 dllref
= s1
->loaded_dlls
[j
];
2732 if (!strcmp(name
, dllref
->name
))
2733 goto already_loaded
;
2735 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2736 error_noabort("referenced dll '%s' not found", name
);
2753 #define LD_TOK_NAME 256
2754 #define LD_TOK_EOF (-1)
2756 /* return next ld script token */
2757 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2775 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2776 ch
= file
->buf_ptr
[0];
2784 /* case 'a' ... 'z': */
2811 /* case 'A' ... 'z': */
2846 if (!((ch
>= 'a' && ch
<= 'z') ||
2847 (ch
>= 'A' && ch
<= 'Z') ||
2848 (ch
>= '0' && ch
<= '9') ||
2849 strchr("/.-_+=$:\\,~", ch
)))
2851 if ((q
- name
) < name_size
- 1) {
2868 printf("tok=%c %d\n", c
, c
);
2869 if (c
== LD_TOK_NAME
)
2870 printf(" name=%s\n", name
);
2875 char *tcc_strcpy_part(char *out
, const char *in
, size_t num
)
2877 memcpy(out
, in
, num
);
2883 * Extract the library name from the file name
2884 * Return 0 if the file isn't a library
2886 * /!\ No test on filename capacity, be careful
2888 static int filename_to_libname(TCCState
*s1
, const char filename
[], char libname
[])
2893 /* already converted to library name */
2894 if (libname
[0] != '\0')
2896 ext
= tcc_fileextension(filename
);
2899 libprefix
= !strncmp(filename
, "lib", 3);
2900 if (!s1
->static_link
) {
2901 #ifdef TCC_TARGET_PE
2902 if (!strcmp(ext
, ".def")) {
2903 size_t len
= ext
- filename
;
2904 tcc_strcpy_part(libname
, filename
, len
);
2908 if (libprefix
&& (!strcmp(ext
, ".so"))) {
2909 size_t len
= ext
- filename
- 3;
2910 tcc_strcpy_part(libname
, filename
+ 3, len
);
2915 if (libprefix
&& (!strcmp(ext
, ".a"))) {
2916 size_t len
= ext
- filename
- 3;
2917 tcc_strcpy_part(libname
, filename
+ 3, len
);
2925 * Extract the file name from the library name
2927 * /!\ No test on filename capacity, be careful
2929 static void libname_to_filename(TCCState
*s1
, const char libname
[], char filename
[])
2931 if (!s1
->static_link
) {
2932 #ifdef TCC_TARGET_PE
2933 sprintf(filename
, "%s.def", libname
);
2935 sprintf(filename
, "lib%s.so", libname
);
2938 sprintf(filename
, "lib%s.a", libname
);
2942 static int ld_add_file(TCCState
*s1
, const char filename
[], char libname
[])
2946 ret
= tcc_add_file_internal(s1
, filename
, 0);
2948 if (filename_to_libname(s1
, filename
, libname
))
2949 ret
= tcc_add_library(s1
, libname
);
2954 static inline int new_undef_syms(void)
2957 ret
= new_undef_sym
;
2962 static int ld_add_file_list(TCCState
*s1
, const char *cmd
, int as_needed
)
2964 char filename
[1024], libname
[1024];
2965 int t
, group
, nblibs
= 0, ret
= 0;
2968 group
= !strcmp(cmd
, "GROUP");
2971 t
= ld_next(s1
, filename
, sizeof(filename
));
2974 t
= ld_next(s1
, filename
, sizeof(filename
));
2977 if (t
== LD_TOK_EOF
) {
2978 error_noabort("unexpected end of file");
2980 goto lib_parse_error
;
2981 } else if (t
== ')') {
2983 } else if (t
== '-') {
2984 t
= ld_next(s1
, filename
, sizeof(filename
));
2985 if ((t
!= LD_TOK_NAME
) || (filename
[0] != 'l')) {
2986 error_noabort("library name expected");
2988 goto lib_parse_error
;
2990 strcpy(libname
, &filename
[1]);
2991 libname_to_filename(s1
, libname
, filename
);
2992 } else if (t
!= LD_TOK_NAME
) {
2993 error_noabort("filename expected");
2995 goto lib_parse_error
;
2997 if (!strcmp(filename
, "AS_NEEDED")) {
2998 ret
= ld_add_file_list(s1
, cmd
, 1);
3000 goto lib_parse_error
;
3002 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3004 ret
= ld_add_file(s1
, filename
, libname
);
3006 goto lib_parse_error
;
3008 /* Add the filename *and* the libname to avoid future conversions */
3009 dynarray_add((void ***) &libs
, &nblibs
, tcc_strdup(filename
));
3010 dynarray_add((void ***) &libs
, &nblibs
, tcc_strdup(libname
));
3014 t
= ld_next(s1
, filename
, sizeof(filename
));
3016 t
= ld_next(s1
, filename
, sizeof(filename
));
3019 if (group
&& !as_needed
) {
3020 while (new_undef_syms()) {
3023 for (i
= 0; i
< nblibs
; i
+= 2)
3024 ld_add_file(s1
, libs
[i
], libs
[i
+1]);
3028 dynarray_reset(&libs
, &nblibs
);
3032 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3034 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
)
3037 char filename
[1024];
3040 ch
= file
->buf_ptr
[0];
3043 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3044 if (t
== LD_TOK_EOF
)
3046 else if (t
!= LD_TOK_NAME
)
3048 if (!strcmp(cmd
, "INPUT") ||
3049 !strcmp(cmd
, "GROUP")) {
3050 ret
= ld_add_file_list(s1
, cmd
, 0);
3053 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
3054 !strcmp(cmd
, "TARGET")) {
3055 /* ignore some commands */
3056 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3060 t
= ld_next(s1
, filename
, sizeof(filename
));
3061 if (t
== LD_TOK_EOF
) {
3062 error_noabort("unexpected end of file");
3064 } else if (t
== ')') {