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_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
245 /* ignore hidden symbols after */
246 } else if (esym
->st_shndx
== SHN_COMMON
247 && (sh_num
< SHN_LORESERVE
|| sh_num
== SHN_COMMON
)) {
248 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
249 No idea if this is the correct solution ... */
251 } else if (s
== tcc_state
->dynsymtab_section
) {
252 /* we accept that two DLL define the same symbol */
255 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
256 sym_bind
, sh_num
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
258 error_noabort("'%s' defined twice", name
);
262 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
263 esym
->st_shndx
= sh_num
;
265 esym
->st_value
= value
;
266 esym
->st_size
= size
;
267 esym
->st_other
= other
;
271 sym_index
= put_elf_sym(s
, value
, size
,
272 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
279 ST_FUNC
void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
280 int type
, int symbol
)
288 /* if no relocation section, create it */
289 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
290 /* if the symtab is allocated, then we consider the relocation
292 sr
= new_section(tcc_state
, buf
, SHT_RELX
, symtab
->sh_flags
);
293 sr
->sh_entsize
= sizeof(ElfW_Rel
);
295 sr
->sh_info
= s
->sh_num
;
298 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
299 rel
->r_offset
= offset
;
300 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
301 #ifdef TCC_TARGET_X86_64
306 /* put stab debug information */
308 ST_FUNC
void put_stabs(const char *str
, int type
, int other
, int desc
,
313 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
315 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
320 sym
->n_other
= other
;
322 sym
->n_value
= value
;
325 ST_FUNC
void put_stabs_r(const char *str
, int type
, int other
, int desc
,
326 unsigned long value
, Section
*sec
, int sym_index
)
328 put_stabs(str
, type
, other
, desc
, value
);
329 put_elf_reloc(symtab_section
, stab_section
,
330 stab_section
->data_offset
- sizeof(unsigned int),
331 R_DATA_32
, sym_index
);
334 ST_FUNC
void put_stabn(int type
, int other
, int desc
, int value
)
336 put_stabs(NULL
, type
, other
, desc
, value
);
339 ST_FUNC
void put_stabd(int type
, int other
, int desc
)
341 put_stabs(NULL
, type
, other
, desc
, 0);
344 /* In an ELF file symbol table, the local symbols must appear below
345 the global and weak ones. Since TCC cannot sort it while generating
346 the code, we must do it after. All the relocation tables are also
347 modified to take into account the symbol table sorting */
348 static void sort_syms(TCCState
*s1
, Section
*s
)
350 int *old_to_new_syms
;
354 ElfW_Rel
*rel
, *rel_end
;
358 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
359 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
360 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
362 /* first pass for local symbols */
363 p
= (ElfW(Sym
) *)s
->data
;
365 for(i
= 0; i
< nb_syms
; i
++) {
366 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
367 old_to_new_syms
[i
] = q
- new_syms
;
372 /* save the number of local symbols in section header */
373 s
->sh_info
= q
- new_syms
;
375 /* then second pass for non local symbols */
376 p
= (ElfW(Sym
) *)s
->data
;
377 for(i
= 0; i
< nb_syms
; i
++) {
378 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
379 old_to_new_syms
[i
] = q
- new_syms
;
385 /* we copy the new symbols to the old */
386 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
389 /* now we modify all the relocations */
390 for(i
= 1; i
< s1
->nb_sections
; i
++) {
391 sr
= s1
->sections
[i
];
392 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
393 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
394 for(rel
= (ElfW_Rel
*)sr
->data
;
397 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
398 type
= ELFW(R_TYPE
)(rel
->r_info
);
399 sym_index
= old_to_new_syms
[sym_index
];
400 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
405 tcc_free(old_to_new_syms
);
408 /* relocate common symbols in the .bss section */
409 ST_FUNC
void relocate_common_syms(void)
411 ElfW(Sym
) *sym
, *sym_end
;
412 unsigned long offset
, align
;
414 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
415 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
418 if (sym
->st_shndx
== SHN_COMMON
) {
420 align
= sym
->st_value
;
421 offset
= bss_section
->data_offset
;
422 offset
= (offset
+ align
- 1) & -align
;
423 sym
->st_value
= offset
;
424 sym
->st_shndx
= bss_section
->sh_num
;
425 offset
+= sym
->st_size
;
426 bss_section
->data_offset
= offset
;
431 /* relocate symbol table, resolve undefined symbols if do_resolve is
432 true and output error if undefined symbol. */
433 ST_FUNC
void relocate_syms(TCCState
*s1
, int do_resolve
)
435 ElfW(Sym
) *sym
, *esym
, *sym_end
;
436 int sym_bind
, sh_num
, sym_index
;
439 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
440 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
443 sh_num
= sym
->st_shndx
;
444 if (sh_num
== SHN_UNDEF
) {
445 name
= strtab_section
->data
+ sym
->st_name
;
447 #if !defined TCC_TARGET_PE || !defined _WIN32
449 name
= symtab_section
->link
->data
+ sym
->st_name
;
450 addr
= resolve_sym(s1
, name
);
452 sym
->st_value
= (uplong
)addr
;
456 } else if (s1
->dynsym
) {
457 /* if dynamic symbol exist, then use it */
458 sym_index
= find_elf_sym(s1
->dynsym
, name
);
460 esym
= &((ElfW(Sym
) *)s1
->dynsym
->data
)[sym_index
];
461 sym
->st_value
= esym
->st_value
;
465 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
467 if (!strcmp(name
, "_fp_hw"))
469 /* only weak symbols are accepted to be undefined. Their
471 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
472 if (sym_bind
== STB_WEAK
) {
475 error_noabort("undefined symbol '%s'", name
);
477 } else if (sh_num
< SHN_LORESERVE
) {
478 /* add section base */
479 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
485 #ifndef TCC_TARGET_PE
486 #ifdef TCC_TARGET_X86_64
487 #define JMP_TABLE_ENTRY_SIZE 14
488 static uplong
add_jmp_table(TCCState
*s1
, uplong val
)
490 char *p
= s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
;
491 s1
->runtime_plt_and_got_offset
+= JMP_TABLE_ENTRY_SIZE
;
496 *(uplong
*)(p
+ 6) = val
;
500 static uplong
add_got_table(TCCState
*s1
, uplong val
)
502 uplong
*p
= (uplong
*)(s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
);
503 s1
->runtime_plt_and_got_offset
+= sizeof(uplong
);
507 #elif defined TCC_TARGET_ARM
508 #define JMP_TABLE_ENTRY_SIZE 8
509 static uplong
add_jmp_table(TCCState
*s1
, int val
)
511 uint32_t *p
= (uint32_t *)(s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
);
512 s1
->runtime_plt_and_got_offset
+= JMP_TABLE_ENTRY_SIZE
;
513 /* ldr pc, [pc, #-4] */
521 /* relocate a given section (CPU dependent) */
522 ST_FUNC
void relocate_section(TCCState
*s1
, Section
*s
)
525 ElfW_Rel
*rel
, *rel_end
, *qrel
;
530 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
535 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
536 qrel
= (ElfW_Rel
*)sr
->data
;
540 ptr
= s
->data
+ rel
->r_offset
;
542 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
543 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
545 #ifdef TCC_TARGET_X86_64
546 val
+= rel
->r_addend
;
548 type
= ELFW(R_TYPE
)(rel
->r_info
);
549 addr
= s
->sh_addr
+ rel
->r_offset
;
553 #if defined(TCC_TARGET_I386)
555 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
556 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
557 qrel
->r_offset
= rel
->r_offset
;
559 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_32
);
563 qrel
->r_info
= ELFW(R_INFO
)(0, R_386_RELATIVE
);
570 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
572 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
574 qrel
->r_offset
= rel
->r_offset
;
575 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_PC32
);
580 *(int *)ptr
+= val
- addr
;
583 *(int *)ptr
+= val
- addr
;
590 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
593 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
596 /* we load the got offset */
597 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
600 if (s1
->output_format
!= TCC_OUTPUT_FORMAT_BINARY
) {
602 error("can only produce 16-bit binary files");
604 *(short *)ptr
+= val
;
607 if (s1
->output_format
!= TCC_OUTPUT_FORMAT_BINARY
)
609 *(short *)ptr
+= val
- addr
;
611 #elif defined(TCC_TARGET_ARM)
618 x
= (*(int *)ptr
)&0xffffff;
619 (*(int *)ptr
) &= 0xff000000;
624 #ifndef TCC_TARGET_PE
625 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
626 if (s1
->output_type
== TCC_OUTPUT_MEMORY
)
627 x
+= add_jmp_table(s1
, val
) - val
; /* add veneer */
629 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
630 error("can't relocate value at %x",addr
);
639 x
= (*(int *)ptr
) & 0x7fffffff;
640 (*(int *)ptr
) &= 0x80000000;
643 if((x
^(x
>>1))&0x40000000)
644 error("can't relocate value at %x",addr
);
645 (*(int *)ptr
) |= x
& 0x7fffffff;
650 case R_ARM_BASE_PREL
:
651 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
654 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
657 /* we load the got offset */
658 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
663 /* trade Thumb support for ARMv4 support */
664 if ((0x0ffffff0 & *(int*)ptr
) == 0x012FFF10)
665 *(int*)ptr
^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */
668 fprintf(stderr
,"FIXME: handle reloc type %x at %x [%.8x] to %x\n",
669 type
, (unsigned)addr
, (unsigned)(uplong
)ptr
, (unsigned)val
);
671 #elif defined(TCC_TARGET_C67)
679 /* put the low 16 bits of the absolute address */
680 // add to what is already there
682 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
683 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
685 //patch both at once - assumes always in pairs Low - High
687 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
688 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
694 fprintf(stderr
,"FIXME: handle reloc type %x at %x [%.8x] to %x\n",
695 type
, (unsigned)addr
, (unsigned)(uplong
)ptr
, (unsigned)val
);
697 #elif defined(TCC_TARGET_X86_64)
699 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
700 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
701 qrel
->r_addend
= *(long long *)ptr
+ val
;
704 *(long long *)ptr
+= val
;
708 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
709 /* XXX: this logic may depend on TCC's codegen
710 now TCC uses R_X86_64_32 even for a 64bit pointer */
711 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
712 qrel
->r_addend
= *(int *)ptr
+ val
;
719 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
721 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
723 qrel
->r_offset
= rel
->r_offset
;
724 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_X86_64_PC32
);
725 qrel
->r_addend
= *(int *)ptr
;
731 case R_X86_64_PLT32
: {
733 diff
= (long long)val
- addr
;
734 if (diff
<= -2147483647 || diff
> 2147483647) {
735 #ifndef TCC_TARGET_PE
736 /* XXX: naive support for over 32bit jump */
737 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
738 val
= (add_jmp_table(s1
, val
- rel
->r_addend
) +
743 if (diff
<= -2147483647 || diff
> 2147483647) {
744 error("internal error: relocation failed");
750 case R_X86_64_GLOB_DAT
:
751 case R_X86_64_JUMP_SLOT
:
752 /* They don't need addend */
753 *(int *)ptr
= val
- rel
->r_addend
;
755 case R_X86_64_GOTPCREL
:
756 #ifndef TCC_TARGET_PE
757 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
758 val
= add_got_table(s1
, val
- rel
->r_addend
) + rel
->r_addend
;
759 *(int *)ptr
+= val
- addr
;
763 *(int *)ptr
+= (s1
->got
->sh_addr
- addr
+
764 s1
->got_offsets
[sym_index
] - 4);
766 case R_X86_64_GOTTPOFF
:
767 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
770 /* we load the got offset */
771 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
774 #error unsupported processor
778 /* if the relocation is allocated, we change its symbol table */
779 if (sr
->sh_flags
& SHF_ALLOC
)
780 sr
->link
= s1
->dynsym
;
783 /* relocate relocation table in 'sr' */
784 static void relocate_rel(TCCState
*s1
, Section
*sr
)
787 ElfW_Rel
*rel
, *rel_end
;
789 s
= s1
->sections
[sr
->sh_info
];
790 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
791 for(rel
= (ElfW_Rel
*)sr
->data
;
794 rel
->r_offset
+= s
->sh_addr
;
798 /* count the number of dynamic relocations so that we can reserve
800 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
802 ElfW_Rel
*rel
, *rel_end
;
803 int sym_index
, esym_index
, type
, count
;
806 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
807 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
808 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
809 type
= ELFW(R_TYPE
)(rel
->r_info
);
811 #if defined(TCC_TARGET_I386)
813 #elif defined(TCC_TARGET_X86_64)
820 #if defined(TCC_TARGET_I386)
822 #elif defined(TCC_TARGET_X86_64)
825 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
834 /* allocate the section */
835 sr
->sh_flags
|= SHF_ALLOC
;
836 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
841 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
846 if (index
>= s1
->nb_got_offsets
) {
847 /* find immediately bigger power of 2 and reallocate array */
851 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
853 error("memory full");
854 s1
->got_offsets
= tab
;
855 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
856 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
857 s1
->nb_got_offsets
= n
;
859 s1
->got_offsets
[index
] = val
;
862 /* XXX: suppress that */
863 static void put32(unsigned char *p
, uint32_t val
)
871 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
872 defined(TCC_TARGET_X86_64)
873 static uint32_t get32(unsigned char *p
)
875 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
879 static void build_got(TCCState
*s1
)
883 /* if no got, then create it */
884 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
885 s1
->got
->sh_entsize
= 4;
886 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
887 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
888 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
890 /* keep space for _DYNAMIC pointer, if present */
892 /* two dummy got entries */
896 /* keep space for _DYNAMIC pointer, if present */
899 /* two dummy got entries */
907 /* put a got entry corresponding to a symbol in symtab_section. 'size'
908 and 'info' can be modifed if more precise info comes from the DLL */
909 static void put_got_entry(TCCState
*s1
,
910 int reloc_type
, unsigned long size
, int info
,
916 unsigned long offset
;
922 /* if a got entry already exists for that symbol, no need to add one */
923 if (sym_index
< s1
->nb_got_offsets
&&
924 s1
->got_offsets
[sym_index
] != 0)
927 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
930 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
931 name
= symtab_section
->link
->data
+ sym
->st_name
;
932 offset
= sym
->st_value
;
933 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
935 #ifdef TCC_TARGET_X86_64
945 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
948 /* if we build a DLL, we add a %ebx offset */
949 if (s1
->output_type
== TCC_OUTPUT_DLL
)
955 /* add a PLT entry */
957 if (plt
->data_offset
== 0) {
958 /* first plt entry */
959 p
= section_ptr_add(plt
, 16);
960 p
[0] = 0xff; /* pushl got + PTR_SIZE */
962 put32(p
+ 2, PTR_SIZE
);
963 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
965 put32(p
+ 8, PTR_SIZE
* 2);
968 p
= section_ptr_add(plt
, 16);
969 p
[0] = 0xff; /* jmp *(got + x) */
971 put32(p
+ 2, s1
->got
->data_offset
);
972 p
[6] = 0x68; /* push $xxx */
973 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
974 p
[11] = 0xe9; /* jmp plt_start */
975 put32(p
+ 12, -(plt
->data_offset
));
977 /* the symbol is modified so that it will be relocated to
979 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
980 if (s1
->output_type
== TCC_OUTPUT_EXE
)
982 offset
= plt
->data_offset
- 16;
984 #elif defined(TCC_TARGET_ARM)
985 if (reloc_type
== R_ARM_JUMP_SLOT
) {
989 /* if we build a DLL, we add a %ebx offset */
990 if (s1
->output_type
== TCC_OUTPUT_DLL
)
991 error("DLLs unimplemented!");
993 /* add a PLT entry */
995 if (plt
->data_offset
== 0) {
996 /* first plt entry */
997 p
= section_ptr_add(plt
, 16);
998 put32(p
, 0xe52de004);
999 put32(p
+ 4, 0xe59fe010);
1000 put32(p
+ 8, 0xe08fe00e);
1001 put32(p
+ 12, 0xe5bef008);
1004 p
= section_ptr_add(plt
, 16);
1005 put32(p
, 0xe59fc004);
1006 put32(p
+4, 0xe08fc00c);
1007 put32(p
+8, 0xe59cf000);
1008 put32(p
+12, s1
->got
->data_offset
);
1010 /* the symbol is modified so that it will be relocated to
1012 if (s1
->output_type
== TCC_OUTPUT_EXE
)
1013 offset
= plt
->data_offset
- 16;
1015 #elif defined(TCC_TARGET_C67)
1016 error("C67 got not implemented");
1018 #error unsupported CPU
1020 index
= put_elf_sym(s1
->dynsym
, offset
,
1021 size
, info
, 0, sym
->st_shndx
, name
);
1022 /* put a got entry */
1023 put_elf_reloc(s1
->dynsym
, s1
->got
,
1024 s1
->got
->data_offset
,
1027 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
1031 /* build GOT and PLT entries */
1032 ST_FUNC
void build_got_entries(TCCState
*s1
)
1034 Section
*s
, *symtab
;
1035 ElfW_Rel
*rel
, *rel_end
;
1037 int i
, type
, reloc_type
, sym_index
;
1039 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1040 s
= s1
->sections
[i
];
1041 if (s
->sh_type
!= SHT_RELX
)
1043 /* no need to handle got relocations */
1044 if (s
->link
!= symtab_section
)
1047 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
1048 for(rel
= (ElfW_Rel
*)s
->data
;
1051 type
= ELFW(R_TYPE
)(rel
->r_info
);
1053 #if defined(TCC_TARGET_I386)
1060 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1061 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1062 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1063 /* look at the symbol got offset. If none, then add one */
1064 if (type
== R_386_GOT32
)
1065 reloc_type
= R_386_GLOB_DAT
;
1067 reloc_type
= R_386_JMP_SLOT
;
1068 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1072 #elif defined(TCC_TARGET_ARM)
1073 case R_ARM_GOT_BREL
:
1074 case R_ARM_GOTOFF32
:
1075 case R_ARM_BASE_PREL
:
1079 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1080 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1081 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1082 /* look at the symbol got offset. If none, then add one */
1083 if (type
== R_ARM_GOT_BREL
)
1084 reloc_type
= R_ARM_GLOB_DAT
;
1086 reloc_type
= R_ARM_JUMP_SLOT
;
1087 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1091 #elif defined(TCC_TARGET_C67)
1098 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1099 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1100 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1101 /* look at the symbol got offset. If none, then add one */
1102 if (type
== R_C60_GOT32
)
1103 reloc_type
= R_C60_GLOB_DAT
;
1105 reloc_type
= R_C60_JMP_SLOT
;
1106 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1110 #elif defined(TCC_TARGET_X86_64)
1111 case R_X86_64_GOT32
:
1112 case R_X86_64_GOTTPOFF
:
1113 case R_X86_64_GOTPCREL
:
1114 case R_X86_64_PLT32
:
1117 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
||
1118 type
== R_X86_64_PLT32
) {
1119 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1120 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1121 /* look at the symbol got offset. If none, then add one */
1122 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
)
1123 reloc_type
= R_X86_64_GLOB_DAT
;
1125 reloc_type
= R_X86_64_JUMP_SLOT
;
1126 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1131 #error unsupported CPU
1140 ST_FUNC Section
*new_symtab(TCCState
*s1
,
1141 const char *symtab_name
, int sh_type
, int sh_flags
,
1142 const char *strtab_name
,
1143 const char *hash_name
, int hash_sh_flags
)
1145 Section
*symtab
, *strtab
, *hash
;
1146 int *ptr
, nb_buckets
;
1148 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1149 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1150 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1151 put_elf_str(strtab
, "");
1152 symtab
->link
= strtab
;
1153 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1157 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1158 hash
->sh_entsize
= sizeof(int);
1159 symtab
->hash
= hash
;
1160 hash
->link
= symtab
;
1162 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1163 ptr
[0] = nb_buckets
;
1165 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1169 /* put dynamic tag */
1170 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1173 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1175 dyn
->d_un
.d_val
= val
;
1178 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1182 char sym_start
[1024];
1185 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1186 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1188 s
= find_section(s1
, section_name
);
1193 end_offset
= s
->data_offset
;
1196 add_elf_sym(symtab_section
,
1198 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1199 s
->sh_num
, sym_start
);
1200 add_elf_sym(symtab_section
,
1202 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1203 s
->sh_num
, sym_end
);
1206 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
1208 #ifdef CONFIG_TCC_BCHECK
1210 Section
*init_section
;
1211 unsigned char *pinit
;
1214 if (0 == s1
->do_bounds_check
)
1217 /* XXX: add an object file to do that */
1218 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1220 add_elf_sym(symtab_section
, 0, 0,
1221 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1222 bounds_section
->sh_num
, "__bounds_start");
1223 /* add bound check code */
1224 #ifndef TCC_TARGET_PE
1227 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "bcheck.o");
1228 tcc_add_file(s1
, buf
);
1231 #ifdef TCC_TARGET_I386
1232 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1233 /* add 'call __bound_init()' in .init section */
1234 init_section
= find_section(s1
, ".init");
1235 pinit
= section_ptr_add(init_section
, 5);
1237 put32(pinit
+ 1, -4);
1238 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1239 put_elf_reloc(symtab_section
, init_section
,
1240 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1246 /* add tcc runtime libraries */
1247 ST_FUNC
void tcc_add_runtime(TCCState
*s1
)
1252 if (!s1
->nostdlib
) {
1253 #ifdef CONFIG_USE_LIBGCC
1254 tcc_add_library(s1
, "c");
1255 tcc_add_file(s1
, CONFIG_SYSROOT CONFIG_TCC_LDDIR
"/libgcc_s.so.1");
1257 tcc_add_library(s1
, "c");
1258 #ifndef WITHOUT_LIBTCC
1261 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "libtcc1.a");
1262 tcc_add_file(s1
, buf
);
1267 /* add crt end if not memory output */
1268 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1269 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1273 /* add various standard linker symbols (must be done after the
1274 sections are filled (for example after allocating common
1276 ST_FUNC
void tcc_add_linker_symbols(TCCState
*s1
)
1282 add_elf_sym(symtab_section
,
1283 text_section
->data_offset
, 0,
1284 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1285 text_section
->sh_num
, "_etext");
1286 add_elf_sym(symtab_section
,
1287 data_section
->data_offset
, 0,
1288 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1289 data_section
->sh_num
, "_edata");
1290 add_elf_sym(symtab_section
,
1291 bss_section
->data_offset
, 0,
1292 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1293 bss_section
->sh_num
, "_end");
1294 /* horrible new standard ldscript defines */
1295 add_init_array_defines(s1
, ".preinit_array");
1296 add_init_array_defines(s1
, ".init_array");
1297 add_init_array_defines(s1
, ".fini_array");
1299 /* add start and stop symbols for sections whose name can be
1301 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1302 s
= s1
->sections
[i
];
1303 if (s
->sh_type
== SHT_PROGBITS
&&
1304 (s
->sh_flags
& SHF_ALLOC
)) {
1308 /* check if section name can be expressed in C */
1314 if (!isid(ch
) && !isnum(ch
))
1318 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1319 add_elf_sym(symtab_section
,
1321 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1323 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1324 add_elf_sym(symtab_section
,
1326 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1333 /* name of ELF interpreter */
1334 #if defined __FreeBSD__
1335 static const char elf_interp
[] = "/libexec/ld-elf.so.1";
1336 #elif defined __FreeBSD_kernel__
1337 static char elf_interp
[] = "/lib/ld.so.1";
1338 #elif defined TCC_ARM_EABI
1339 static const char elf_interp
[] = "/lib/ld-linux.so.3";
1340 #elif defined(TCC_TARGET_X86_64)
1341 static const char elf_interp
[] = CONFIG_TCC_LDDIR
"/ld-linux-x86-64.so.2";
1342 #elif defined(TCC_UCLIBC)
1343 static const char elf_interp
[] = "/lib/ld-uClibc.so.0";
1345 static const char elf_interp
[] = "/lib/ld-linux.so.2";
1348 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1349 const int *section_order
)
1352 int i
, offset
, size
;
1355 for(i
=1;i
<s1
->nb_sections
;i
++) {
1356 s
= s1
->sections
[section_order
[i
]];
1357 if (s
->sh_type
!= SHT_NOBITS
&&
1358 (s
->sh_flags
& SHF_ALLOC
)) {
1359 while (offset
< s
->sh_offset
) {
1364 fwrite(s
->data
, 1, size
, f
);
1370 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1372 #define EXTRA_RELITEMS 14
1374 /* move the relocation value from .dynsym to .got */
1375 void patch_dynsym_undef(TCCState
*s1
, Section
*s
)
1377 uint32_t *gotd
= (void *)s1
->got
->data
;
1378 ElfW(Sym
) *sym
, *sym_end
;
1380 gotd
+= 3; // dummy entries in .got
1381 /* relocate symbols in .dynsym */
1382 sym_end
= (ElfW(Sym
) *)(s
->data
+ s
->data_offset
);
1383 for (sym
= (ElfW(Sym
) *)s
->data
+ 1; sym
< sym_end
; sym
++) {
1384 if (sym
->st_shndx
== SHN_UNDEF
) {
1385 *gotd
++ = sym
->st_value
+ 6; // XXX 6 is magic ?
1392 #define EXTRA_RELITEMS 9
1395 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1397 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1398 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1399 unsigned long offset
;
1401 if (sym_index
>= s1
->nb_got_offsets
)
1403 offset
= s1
->got_offsets
[sym_index
];
1404 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1405 #ifdef TCC_TARGET_X86_64
1406 /* only works for x86-64 */
1407 put32(s1
->got
->data
+ offset
, sym
->st_value
>> 32);
1409 put32(s1
->got
->data
+ offset
, sym
->st_value
& 0xffffffff);
1412 ST_FUNC
void fill_got(TCCState
*s1
)
1415 ElfW_Rel
*rel
, *rel_end
;
1418 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1419 s
= s1
->sections
[i
];
1420 if (s
->sh_type
!= SHT_RELX
)
1422 /* no need to handle got relocations */
1423 if (s
->link
!= symtab_section
)
1425 rel_end
= (ElfW_Rel
*) (s
->data
+ s
->data_offset
);
1426 for(rel
= (ElfW_Rel
*) s
->data
; rel
< rel_end
; rel
++) {
1427 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1428 case R_X86_64_GOT32
:
1429 case R_X86_64_GOTPCREL
:
1430 case R_X86_64_PLT32
:
1431 fill_got_entry(s1
, rel
);
1439 /* output an ELF file */
1440 /* XXX: suppress unneeded sections */
1441 static int elf_output_file(TCCState
*s1
, const char *filename
)
1447 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1449 Section
*strsec
, *s
;
1450 ElfW(Shdr
) shdr
, *sh
;
1451 ElfW(Phdr
) *phdr
, *ph
;
1452 Section
*interp
, *dynamic
, *dynstr
;
1453 unsigned long saved_dynamic_data_offset
;
1455 int type
, file_type
;
1456 unsigned long rel_addr
, rel_size
;
1457 unsigned long bss_addr
, bss_size
;
1459 file_type
= s1
->output_type
;
1462 if (file_type
!= TCC_OUTPUT_OBJ
) {
1463 tcc_add_runtime(s1
);
1467 section_order
= NULL
;
1470 dynstr
= NULL
; /* avoid warning */
1471 saved_dynamic_data_offset
= 0; /* avoid warning */
1473 if (file_type
!= TCC_OUTPUT_OBJ
) {
1474 relocate_common_syms();
1476 tcc_add_linker_symbols(s1
);
1478 if (!s1
->static_link
) {
1480 int sym_index
, index
;
1481 ElfW(Sym
) *esym
, *sym_end
;
1483 if (file_type
== TCC_OUTPUT_EXE
) {
1485 /* allow override the dynamic loader */
1486 const char *elfint
= getenv("LD_SO");
1488 elfint
= elf_interp
;
1489 /* add interpreter section only if executable */
1490 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1491 interp
->sh_addralign
= 1;
1492 ptr
= section_ptr_add(interp
, 1+strlen(elfint
));
1493 strcpy(ptr
, elfint
);
1496 /* add dynamic symbol table */
1497 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1499 ".hash", SHF_ALLOC
);
1500 dynstr
= s1
->dynsym
->link
;
1502 /* add dynamic section */
1503 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1504 SHF_ALLOC
| SHF_WRITE
);
1505 dynamic
->link
= dynstr
;
1506 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1509 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1510 SHF_ALLOC
| SHF_EXECINSTR
);
1511 s1
->plt
->sh_entsize
= 4;
1515 /* scan for undefined symbols and see if they are in the
1516 dynamic symbols. If a symbol STT_FUNC or STT_GNU_IFUNC
1517 is found, then we add it in the PLT. If a symbol
1518 STT_OBJECT is found, we add it in the .bss section with
1519 a suitable relocation */
1520 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1521 symtab_section
->data_offset
);
1522 if (file_type
== TCC_OUTPUT_EXE
) {
1523 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1526 if (sym
->st_shndx
== SHN_UNDEF
) {
1527 name
= symtab_section
->link
->data
+ sym
->st_name
;
1528 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1530 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1531 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1532 if ((type
== STT_FUNC
) || (type
== STT_GNU_IFUNC
)) {
1533 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1535 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1536 } else if (type
== STT_OBJECT
) {
1537 unsigned long offset
;
1538 ElfW(Sym
) *dynsym
, *dynsym_end
;
1539 offset
= bss_section
->data_offset
;
1540 /* XXX: which alignment ? */
1541 offset
= (offset
+ 16 - 1) & -16;
1542 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1544 bss_section
->sh_num
, name
);
1545 /* Ensure symbol aliases (that is, symbols with
1546 the same st_value) resolve to the same
1547 address in program .bss or .data section. */
1548 dynsym_end
= (ElfW(Sym
) *)
1549 (s1
->dynsymtab_section
->data
+
1550 s1
->dynsymtab_section
->data_offset
);
1551 for(dynsym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1552 dynsym
< dynsym_end
; dynsym
++) {
1553 if (dynsym
->st_value
== esym
->st_value
) {
1555 dynname
= s1
->dynsymtab_section
->link
->data
1557 put_elf_sym(s1
->dynsym
, offset
,
1560 bss_section
->sh_num
,
1564 put_elf_reloc(s1
->dynsym
, bss_section
,
1565 offset
, R_COPY
, index
);
1566 offset
+= esym
->st_size
;
1567 bss_section
->data_offset
= offset
;
1570 /* STB_WEAK undefined symbols are accepted */
1571 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1573 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1574 !strcmp(name
, "_fp_hw")) {
1576 error_noabort("undefined symbol '%s'", name
);
1579 } else if (s1
->rdynamic
&&
1580 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1581 /* if -rdynamic option, then export all non
1583 name
= symtab_section
->link
->data
+ sym
->st_name
;
1584 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1586 sym
->st_shndx
, name
);
1593 /* now look at unresolved dynamic symbols and export
1594 corresponding symbol */
1595 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1596 s1
->dynsymtab_section
->data_offset
);
1597 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1600 if (esym
->st_shndx
== SHN_UNDEF
) {
1601 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1602 sym_index
= find_elf_sym(symtab_section
, name
);
1604 /* XXX: avoid adding a symbol if already
1605 present because of -rdynamic ? */
1606 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1607 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1609 sym
->st_shndx
, name
);
1611 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1612 /* weak symbols can stay undefined */
1614 warning("undefined dynamic symbol '%s'", name
);
1621 /* shared library case : we simply export all the global symbols */
1622 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1623 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1624 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1627 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1628 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1629 if ((ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
||
1630 ELFW(ST_TYPE
)(sym
->st_info
) == STT_GNU_IFUNC
)
1631 && sym
->st_shndx
== SHN_UNDEF
) {
1632 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1634 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1636 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1637 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1639 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1644 name
= symtab_section
->link
->data
+ sym
->st_name
;
1645 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1647 sym
->st_shndx
, name
);
1648 s1
->symtab_to_dynsym
[sym
-
1649 (ElfW(Sym
) *)symtab_section
->data
] =
1656 build_got_entries(s1
);
1658 /* add a list of needed dlls */
1659 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1660 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1661 if (dllref
->level
== 0)
1662 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1666 put_dt(dynamic
, DT_RPATH
, put_elf_str(dynstr
, s1
->rpath
));
1668 /* XXX: currently, since we do not handle PIC code, we
1669 must relocate the readonly segments */
1670 if (file_type
== TCC_OUTPUT_DLL
) {
1672 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1673 put_dt(dynamic
, DT_TEXTREL
, 0);
1677 put_dt(dynamic
, DT_SYMBOLIC
, 0);
1679 /* add necessary space for other entries */
1680 saved_dynamic_data_offset
= dynamic
->data_offset
;
1681 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * EXTRA_RELITEMS
;
1683 /* still need to build got entries in case of static link */
1684 build_got_entries(s1
);
1688 memset(&ehdr
, 0, sizeof(ehdr
));
1690 /* we add a section for symbols */
1691 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1692 put_elf_str(strsec
, "");
1694 /* compute number of sections */
1695 shnum
= s1
->nb_sections
;
1697 /* this array is used to reorder sections in the output file */
1698 section_order
= tcc_malloc(sizeof(int) * shnum
);
1699 section_order
[0] = 0;
1702 /* compute number of program headers */
1705 case TCC_OUTPUT_OBJ
:
1708 case TCC_OUTPUT_EXE
:
1709 if (!s1
->static_link
)
1710 phnum
= 4 + HAVE_PHDR
;
1714 case TCC_OUTPUT_DLL
:
1719 /* allocate strings for section names and decide if an unallocated
1720 section should be output */
1721 /* NOTE: the strsec section comes last, so its size is also
1723 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1724 s
= s1
->sections
[i
];
1725 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1727 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1732 s
->reloc
? s
->reloc
->name
: "n"
1735 /* when generating a DLL, we include relocations but we may
1737 if (file_type
== TCC_OUTPUT_DLL
&&
1738 s
->sh_type
== SHT_RELX
&&
1739 !(s
->sh_flags
& SHF_ALLOC
)) {
1740 /* //gr: avoid bogus relocs for empty (debug) sections */
1741 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1742 prepare_dynamic_rel(s1
, s
);
1743 else if (s1
->do_debug
)
1744 s
->sh_size
= s
->data_offset
;
1745 } else if (s1
->do_debug
||
1746 file_type
== TCC_OUTPUT_OBJ
||
1747 (s
->sh_flags
& SHF_ALLOC
) ||
1748 i
== (s1
->nb_sections
- 1)) {
1749 /* we output all sections if debug or object file */
1750 s
->sh_size
= s
->data_offset
;
1754 /* allocate program segment headers */
1755 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1757 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1758 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1763 /* compute section to program header mapping */
1764 if (s1
->has_text_addr
) {
1765 int a_offset
, p_offset
;
1766 addr
= s1
->text_addr
;
1767 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1769 a_offset
= addr
& (s1
->section_align
- 1);
1770 p_offset
= file_offset
& (s1
->section_align
- 1);
1771 if (a_offset
< p_offset
)
1772 a_offset
+= s1
->section_align
;
1773 file_offset
+= (a_offset
- p_offset
);
1775 if (file_type
== TCC_OUTPUT_DLL
)
1778 addr
= ELF_START_ADDR
;
1779 /* compute address after headers */
1780 addr
+= (file_offset
& (s1
->section_align
- 1));
1783 /* dynamic relocation table information, for .dynamic section */
1787 bss_addr
= bss_size
= 0;
1788 /* leave one program header for the program interpreter */
1791 ph
+= 1 + HAVE_PHDR
;
1793 for(j
= 0; j
< 2; j
++) {
1794 ph
->p_type
= PT_LOAD
;
1796 ph
->p_flags
= PF_R
| PF_X
;
1798 ph
->p_flags
= PF_R
| PF_W
;
1799 ph
->p_align
= s1
->section_align
;
1801 /* we do the following ordering: interp, symbol tables,
1802 relocations, progbits, nobits */
1803 /* XXX: do faster and simpler sorting */
1804 for(k
= 0; k
< 5; k
++) {
1805 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1806 s
= s1
->sections
[i
];
1807 /* compute if section should be included */
1809 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1813 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1814 (SHF_ALLOC
| SHF_WRITE
))
1820 } else if (s
->sh_type
== SHT_DYNSYM
||
1821 s
->sh_type
== SHT_STRTAB
||
1822 s
->sh_type
== SHT_HASH
) {
1825 } else if (s
->sh_type
== SHT_RELX
) {
1828 } else if (s
->sh_type
== SHT_NOBITS
) {
1835 section_order
[sh_order_index
++] = i
;
1837 /* section matches: we align it and add its size */
1839 addr
= (addr
+ s
->sh_addralign
- 1) &
1840 ~(s
->sh_addralign
- 1);
1841 file_offset
+= addr
- tmp
;
1842 s
->sh_offset
= file_offset
;
1845 /* update program header infos */
1846 if (ph
->p_offset
== 0) {
1847 ph
->p_offset
= file_offset
;
1849 ph
->p_paddr
= ph
->p_vaddr
;
1851 /* update dynamic relocation infos */
1852 if (s
->sh_type
== SHT_RELX
) {
1853 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1854 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.got")) { // rel_size == 0) {
1856 rel_size
+= s
->sh_size
; // XXX only first rel.
1858 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.bss")) { // rel_size == 0) {
1860 bss_size
= s
->sh_size
; // XXX only first rel.
1865 rel_size
+= s
->sh_size
;
1869 if (s
->sh_type
!= SHT_NOBITS
)
1870 file_offset
+= s
->sh_size
;
1873 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1874 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1877 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1878 /* if in the middle of a page, we duplicate the page in
1879 memory so that one copy is RX and the other is RW */
1880 if ((addr
& (s1
->section_align
- 1)) != 0)
1881 addr
+= s1
->section_align
;
1883 addr
= (addr
+ s1
->section_align
- 1) & ~(s1
->section_align
- 1);
1884 file_offset
= (file_offset
+ s1
->section_align
- 1) &
1885 ~(s1
->section_align
- 1);
1890 /* if interpreter, then add corresponing program header */
1894 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1896 int len
= phnum
* sizeof(ElfW(Phdr
));
1898 ph
->p_type
= PT_PHDR
;
1899 ph
->p_offset
= sizeof(ElfW(Ehdr
));
1900 ph
->p_vaddr
= interp
->sh_addr
- len
;
1901 ph
->p_paddr
= ph
->p_vaddr
;
1902 ph
->p_filesz
= ph
->p_memsz
= len
;
1903 ph
->p_flags
= PF_R
| PF_X
;
1904 ph
->p_align
= 4; // interp->sh_addralign;
1909 ph
->p_type
= PT_INTERP
;
1910 ph
->p_offset
= interp
->sh_offset
;
1911 ph
->p_vaddr
= interp
->sh_addr
;
1912 ph
->p_paddr
= ph
->p_vaddr
;
1913 ph
->p_filesz
= interp
->sh_size
;
1914 ph
->p_memsz
= interp
->sh_size
;
1916 ph
->p_align
= interp
->sh_addralign
;
1919 /* if dynamic section, then add corresponing program header */
1923 ph
= &phdr
[phnum
- 1];
1925 ph
->p_type
= PT_DYNAMIC
;
1926 ph
->p_offset
= dynamic
->sh_offset
;
1927 ph
->p_vaddr
= dynamic
->sh_addr
;
1928 ph
->p_paddr
= ph
->p_vaddr
;
1929 ph
->p_filesz
= dynamic
->sh_size
;
1930 ph
->p_memsz
= dynamic
->sh_size
;
1931 ph
->p_flags
= PF_R
| PF_W
;
1932 ph
->p_align
= dynamic
->sh_addralign
;
1934 /* put GOT dynamic section address */
1935 put32(s1
->got
->data
, dynamic
->sh_addr
);
1937 /* relocate the PLT */
1938 if (file_type
== TCC_OUTPUT_EXE
1939 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1940 || file_type
== TCC_OUTPUT_DLL
1946 p_end
= p
+ s1
->plt
->data_offset
;
1948 #if defined(TCC_TARGET_I386)
1949 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1950 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1953 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1956 #elif defined(TCC_TARGET_X86_64)
1957 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1958 put32(p
+ 2, get32(p
+ 2) + x
);
1959 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1962 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1965 #elif defined(TCC_TARGET_ARM)
1967 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1970 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1973 #elif defined(TCC_TARGET_C67)
1976 #error unsupported CPU
1981 /* relocate symbols in .dynsym */
1982 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1983 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1986 if (sym
->st_shndx
== SHN_UNDEF
) {
1987 /* relocate to the PLT if the symbol corresponds
1990 sym
->st_value
+= s1
->plt
->sh_addr
;
1991 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1992 /* do symbol relocation */
1993 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1997 /* put dynamic section entries */
1998 dynamic
->data_offset
= saved_dynamic_data_offset
;
1999 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
2000 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
2001 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
2002 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
2003 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
2004 #ifdef TCC_TARGET_X86_64
2005 put_dt(dynamic
, DT_RELA
, rel_addr
);
2006 put_dt(dynamic
, DT_RELASZ
, rel_size
);
2007 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
2009 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2010 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2011 put_dt(dynamic
, DT_PLTRELSZ
, rel_size
);
2012 put_dt(dynamic
, DT_JMPREL
, rel_addr
);
2013 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
2014 put_dt(dynamic
, DT_REL
, bss_addr
);
2015 put_dt(dynamic
, DT_RELSZ
, bss_size
);
2017 put_dt(dynamic
, DT_REL
, rel_addr
);
2018 put_dt(dynamic
, DT_RELSZ
, rel_size
);
2019 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
2023 put_dt(dynamic
, DT_DEBUG
, 0);
2024 put_dt(dynamic
, DT_NULL
, 0);
2027 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2028 ehdr
.e_phnum
= phnum
;
2029 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2032 /* all other sections come after */
2033 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2034 s
= s1
->sections
[i
];
2035 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
2037 section_order
[sh_order_index
++] = i
;
2039 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
2040 ~(s
->sh_addralign
- 1);
2041 s
->sh_offset
= file_offset
;
2042 if (s
->sh_type
!= SHT_NOBITS
)
2043 file_offset
+= s
->sh_size
;
2046 /* if building executable or DLL, then relocate each section
2047 except the GOT which is already relocated */
2048 if (file_type
!= TCC_OUTPUT_OBJ
) {
2049 relocate_syms(s1
, 0);
2051 if (s1
->nb_errors
!= 0) {
2057 /* relocate sections */
2058 /* XXX: ignore sections with allocated relocations ? */
2059 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2060 s
= s1
->sections
[i
];
2061 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
2062 relocate_section(s1
, s
);
2065 /* relocate relocation entries if the relocation tables are
2066 allocated in the executable */
2067 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2068 s
= s1
->sections
[i
];
2069 if ((s
->sh_flags
& SHF_ALLOC
) &&
2070 s
->sh_type
== SHT_RELX
) {
2071 relocate_rel(s1
, s
);
2075 /* get entry point address */
2076 if (file_type
== TCC_OUTPUT_EXE
)
2077 ehdr
.e_entry
= (uplong
)tcc_get_symbol_err(s1
, "_start");
2079 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
2081 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2084 /* write elf file */
2085 if (file_type
== TCC_OUTPUT_OBJ
)
2089 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2091 error_noabort("could not write '%s'", filename
);
2094 f
= fdopen(fd
, "wb");
2096 printf("<- %s\n", filename
);
2098 #ifdef TCC_TARGET_COFF
2099 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
2100 tcc_output_coff(s1
, f
);
2103 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
2104 sort_syms(s1
, symtab_section
);
2107 file_offset
= (file_offset
+ 3) & -4;
2110 ehdr
.e_ident
[0] = ELFMAG0
;
2111 ehdr
.e_ident
[1] = ELFMAG1
;
2112 ehdr
.e_ident
[2] = ELFMAG2
;
2113 ehdr
.e_ident
[3] = ELFMAG3
;
2114 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
2115 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2116 ehdr
.e_ident
[6] = EV_CURRENT
;
2117 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2118 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2120 #ifdef TCC_TARGET_ARM
2122 ehdr
.e_ident
[EI_OSABI
] = 0;
2123 ehdr
.e_flags
= 4 << 24;
2125 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2130 case TCC_OUTPUT_EXE
:
2131 ehdr
.e_type
= ET_EXEC
;
2133 case TCC_OUTPUT_DLL
:
2134 ehdr
.e_type
= ET_DYN
;
2136 case TCC_OUTPUT_OBJ
:
2137 ehdr
.e_type
= ET_REL
;
2140 ehdr
.e_machine
= EM_TCC_TARGET
;
2141 ehdr
.e_version
= EV_CURRENT
;
2142 ehdr
.e_shoff
= file_offset
;
2143 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2144 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2145 ehdr
.e_shnum
= shnum
;
2146 ehdr
.e_shstrndx
= shnum
- 1;
2148 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2149 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2150 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2152 for(i
=1;i
<s1
->nb_sections
;i
++) {
2153 s
= s1
->sections
[section_order
[i
]];
2154 if (s
->sh_type
!= SHT_NOBITS
) {
2155 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2156 if (s
->sh_type
== SHT_DYNSYM
)
2157 patch_dynsym_undef(s1
, s
);
2159 while (offset
< s
->sh_offset
) {
2164 fwrite(s
->data
, 1, size
, f
);
2169 /* output section headers */
2170 while (offset
< ehdr
.e_shoff
) {
2175 for(i
=0;i
<s1
->nb_sections
;i
++) {
2177 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2178 s
= s1
->sections
[i
];
2180 sh
->sh_name
= s
->sh_name
;
2181 sh
->sh_type
= s
->sh_type
;
2182 sh
->sh_flags
= s
->sh_flags
;
2183 sh
->sh_entsize
= s
->sh_entsize
;
2184 sh
->sh_info
= s
->sh_info
;
2186 sh
->sh_link
= s
->link
->sh_num
;
2187 sh
->sh_addralign
= s
->sh_addralign
;
2188 sh
->sh_addr
= s
->sh_addr
;
2189 sh
->sh_offset
= s
->sh_offset
;
2190 sh
->sh_size
= s
->sh_size
;
2192 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2195 tcc_output_binary(s1
, f
, section_order
);
2201 tcc_free(s1
->symtab_to_dynsym
);
2202 tcc_free(section_order
);
2204 tcc_free(s1
->got_offsets
);
2208 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2211 #ifdef TCC_TARGET_PE
2212 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2213 ret
= pe_output_file(s
, filename
);
2217 ret
= elf_output_file(s
, filename
);
2222 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2226 data
= tcc_malloc(size
);
2227 lseek(fd
, file_offset
, SEEK_SET
);
2228 read(fd
, data
, size
);
2232 typedef struct SectionMergeInfo
{
2233 Section
*s
; /* corresponding existing section */
2234 unsigned long offset
; /* offset of the new section in the existing section */
2235 uint8_t new_section
; /* true if section 's' was added */
2236 uint8_t link_once
; /* true if link once section */
2239 /* load an object file and merge it with current files */
2240 /* XXX: handle correctly stab (debug) info */
2241 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
2242 int fd
, unsigned long file_offset
)
2245 ElfW(Shdr
) *shdr
, *sh
;
2246 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2247 unsigned char *strsec
, *strtab
;
2248 int *old_to_new_syms
;
2249 char *sh_name
, *name
;
2250 SectionMergeInfo
*sm_table
, *sm
;
2251 ElfW(Sym
) *sym
, *symtab
;
2252 ElfW_Rel
*rel
, *rel_end
;
2258 stab_index
= stabstr_index
= 0;
2260 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2262 if (ehdr
.e_ident
[0] != ELFMAG0
||
2263 ehdr
.e_ident
[1] != ELFMAG1
||
2264 ehdr
.e_ident
[2] != ELFMAG2
||
2265 ehdr
.e_ident
[3] != ELFMAG3
)
2267 /* test if object file */
2268 if (ehdr
.e_type
!= ET_REL
)
2270 /* test CPU specific stuff */
2271 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2272 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2274 error_noabort("invalid object file");
2278 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2279 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2280 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2282 /* load section names */
2283 sh
= &shdr
[ehdr
.e_shstrndx
];
2284 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2286 /* load symtab and strtab */
2287 old_to_new_syms
= NULL
;
2291 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2293 if (sh
->sh_type
== SHT_SYMTAB
) {
2295 error_noabort("object must contain only one symtab");
2300 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2301 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2302 sm_table
[i
].s
= symtab_section
;
2304 /* now load strtab */
2305 sh
= &shdr
[sh
->sh_link
];
2306 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2310 /* now examine each section and try to merge its content with the
2312 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2313 /* no need to examine section name strtab */
2314 if (i
== ehdr
.e_shstrndx
)
2317 sh_name
= strsec
+ sh
->sh_name
;
2318 /* ignore sections types we do not handle */
2319 if (sh
->sh_type
!= SHT_PROGBITS
&&
2320 sh
->sh_type
!= SHT_RELX
&&
2322 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2324 sh
->sh_type
!= SHT_NOBITS
&&
2325 sh
->sh_type
!= SHT_PREINIT_ARRAY
&&
2326 sh
->sh_type
!= SHT_INIT_ARRAY
&&
2327 sh
->sh_type
!= SHT_FINI_ARRAY
&&
2328 strcmp(sh_name
, ".stabstr")
2331 if (sh
->sh_addralign
< 1)
2332 sh
->sh_addralign
= 1;
2333 /* find corresponding section, if any */
2334 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2335 s
= s1
->sections
[j
];
2336 if (!strcmp(s
->name
, sh_name
)) {
2337 if (!strncmp(sh_name
, ".gnu.linkonce",
2338 sizeof(".gnu.linkonce") - 1)) {
2339 /* if a 'linkonce' section is already present, we
2340 do not add it again. It is a little tricky as
2341 symbols can still be defined in
2343 sm_table
[i
].link_once
= 1;
2350 /* not found: create new section */
2351 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2352 /* take as much info as possible from the section. sh_link and
2353 sh_info will be updated later */
2354 s
->sh_addralign
= sh
->sh_addralign
;
2355 s
->sh_entsize
= sh
->sh_entsize
;
2356 sm_table
[i
].new_section
= 1;
2358 if (sh
->sh_type
!= s
->sh_type
) {
2359 error_noabort("invalid section type");
2363 /* align start of section */
2364 offset
= s
->data_offset
;
2366 if (0 == strcmp(sh_name
, ".stab")) {
2370 if (0 == strcmp(sh_name
, ".stabstr")) {
2375 size
= sh
->sh_addralign
- 1;
2376 offset
= (offset
+ size
) & ~size
;
2377 if (sh
->sh_addralign
> s
->sh_addralign
)
2378 s
->sh_addralign
= sh
->sh_addralign
;
2379 s
->data_offset
= offset
;
2381 sm_table
[i
].offset
= offset
;
2383 /* concatenate sections */
2385 if (sh
->sh_type
!= SHT_NOBITS
) {
2387 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2388 ptr
= section_ptr_add(s
, size
);
2389 read(fd
, ptr
, size
);
2391 s
->data_offset
+= size
;
2396 /* //gr relocate stab strings */
2397 if (stab_index
&& stabstr_index
) {
2400 s
= sm_table
[stab_index
].s
;
2401 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2402 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2403 o
= sm_table
[stabstr_index
].offset
;
2405 a
->n_strx
+= o
, a
++;
2408 /* second short pass to update sh_link and sh_info fields of new
2410 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2412 if (!s
|| !sm_table
[i
].new_section
)
2415 if (sh
->sh_link
> 0)
2416 s
->link
= sm_table
[sh
->sh_link
].s
;
2417 if (sh
->sh_type
== SHT_RELX
) {
2418 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2419 /* update backward link */
2420 s1
->sections
[s
->sh_info
]->reloc
= s
;
2425 /* resolve symbols */
2426 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2429 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2430 if (sym
->st_shndx
!= SHN_UNDEF
&&
2431 sym
->st_shndx
< SHN_LORESERVE
) {
2432 sm
= &sm_table
[sym
->st_shndx
];
2433 if (sm
->link_once
) {
2434 /* if a symbol is in a link once section, we use the
2435 already defined symbol. It is very important to get
2436 correct relocations */
2437 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2438 name
= strtab
+ sym
->st_name
;
2439 sym_index
= find_elf_sym(symtab_section
, name
);
2441 old_to_new_syms
[i
] = sym_index
;
2445 /* if no corresponding section added, no need to add symbol */
2448 /* convert section number */
2449 sym
->st_shndx
= sm
->s
->sh_num
;
2451 sym
->st_value
+= sm
->offset
;
2454 name
= strtab
+ sym
->st_name
;
2455 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2456 sym
->st_info
, sym
->st_other
,
2457 sym
->st_shndx
, name
);
2458 old_to_new_syms
[i
] = sym_index
;
2461 /* third pass to patch relocation entries */
2462 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2467 offset
= sm_table
[i
].offset
;
2468 switch(s
->sh_type
) {
2470 /* take relocation offset information */
2471 offseti
= sm_table
[sh
->sh_info
].offset
;
2472 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2473 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2478 /* convert symbol index */
2479 type
= ELFW(R_TYPE
)(rel
->r_info
);
2480 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2481 /* NOTE: only one symtab assumed */
2482 if (sym_index
>= nb_syms
)
2484 sym_index
= old_to_new_syms
[sym_index
];
2485 /* ignore link_once in rel section. */
2486 if (!sym_index
&& !sm
->link_once
2487 #ifdef TCC_TARGET_ARM
2488 && type
!= R_ARM_V4BX
2492 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2493 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2496 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2497 /* offset the relocation offset */
2498 rel
->r_offset
+= offseti
;
2510 tcc_free(old_to_new_syms
);
2517 typedef struct ArchiveHeader
{
2518 char ar_name
[16]; /* name of this member */
2519 char ar_date
[12]; /* file mtime */
2520 char ar_uid
[6]; /* owner uid; printed as decimal */
2521 char ar_gid
[6]; /* owner gid; printed as decimal */
2522 char ar_mode
[8]; /* file mode, printed as octal */
2523 char ar_size
[10]; /* file size, printed as decimal */
2524 char ar_fmag
[2]; /* should contain ARFMAG */
2527 static int get_be32(const uint8_t *b
)
2529 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2532 /* load only the objects which resolve undefined symbols */
2533 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2535 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2537 const char *ar_names
, *p
;
2538 const uint8_t *ar_index
;
2541 data
= tcc_malloc(size
);
2542 if (read(fd
, data
, size
) != size
)
2544 nsyms
= get_be32(data
);
2545 ar_index
= data
+ 4;
2546 ar_names
= ar_index
+ nsyms
* 4;
2550 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2551 sym_index
= find_elf_sym(symtab_section
, p
);
2553 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2554 if(sym
->st_shndx
== SHN_UNDEF
) {
2555 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2557 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2560 lseek(fd
, off
, SEEK_SET
);
2561 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2576 /* load a '.a' file */
2577 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
)
2584 unsigned long file_offset
;
2586 /* skip magic which was already checked */
2587 read(fd
, magic
, sizeof(magic
));
2590 len
= read(fd
, &hdr
, sizeof(hdr
));
2593 if (len
!= sizeof(hdr
)) {
2594 error_noabort("invalid archive");
2597 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2598 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2599 size
= strtol(ar_size
, NULL
, 0);
2600 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2601 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2602 if (ar_name
[i
] != ' ')
2605 ar_name
[i
+ 1] = '\0';
2606 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2607 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2609 size
= (size
+ 1) & ~1;
2610 if (!strcmp(ar_name
, "/")) {
2611 /* coff symbol table : we handle it */
2612 if(s1
->alacarte_link
)
2613 return tcc_load_alacarte(s1
, fd
, size
);
2614 } else if (!strcmp(ar_name
, "//") ||
2615 !strcmp(ar_name
, "__.SYMDEF") ||
2616 !strcmp(ar_name
, "__.SYMDEF/") ||
2617 !strcmp(ar_name
, "ARFILENAMES/")) {
2618 /* skip symbol table or archive names */
2620 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2623 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2628 #ifndef TCC_TARGET_PE
2629 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2630 is referenced by the user (so it should be added as DT_NEEDED in
2631 the generated ELF file) */
2632 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2635 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2636 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2637 ElfW(Sym
) *sym
, *dynsym
;
2638 ElfW(Dyn
) *dt
, *dynamic
;
2639 unsigned char *dynstr
;
2640 const char *name
, *soname
;
2641 DLLReference
*dllref
;
2643 read(fd
, &ehdr
, sizeof(ehdr
));
2645 /* test CPU specific stuff */
2646 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2647 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2648 error_noabort("bad architecture");
2653 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2655 /* load dynamic section and dynamic symbols */
2659 dynsym
= NULL
; /* avoid warning */
2660 dynstr
= NULL
; /* avoid warning */
2661 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2662 switch(sh
->sh_type
) {
2664 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2665 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2668 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2669 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2670 sh1
= &shdr
[sh
->sh_link
];
2671 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2678 /* compute the real library name */
2679 soname
= tcc_basename(filename
);
2681 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2682 if (dt
->d_tag
== DT_SONAME
) {
2683 soname
= dynstr
+ dt
->d_un
.d_val
;
2687 /* if the dll is already loaded, do not load it */
2688 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2689 dllref
= s1
->loaded_dlls
[i
];
2690 if (!strcmp(soname
, dllref
->name
)) {
2691 /* but update level if needed */
2692 if (level
< dllref
->level
)
2693 dllref
->level
= level
;
2699 // printf("loading dll '%s'\n", soname);
2701 /* add the dll and its level */
2702 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2703 dllref
->level
= level
;
2704 strcpy(dllref
->name
, soname
);
2705 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2707 /* add dynamic symbols in dynsym_section */
2708 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2709 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2710 if (sym_bind
== STB_LOCAL
)
2712 name
= dynstr
+ sym
->st_name
;
2713 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2714 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2717 /* load all referenced DLLs */
2718 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2721 name
= dynstr
+ dt
->d_un
.d_val
;
2722 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2723 dllref
= s1
->loaded_dlls
[j
];
2724 if (!strcmp(name
, dllref
->name
))
2725 goto already_loaded
;
2727 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2728 error_noabort("referenced dll '%s' not found", name
);
2745 #define LD_TOK_NAME 256
2746 #define LD_TOK_EOF (-1)
2748 /* return next ld script token */
2749 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2767 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2768 ch
= file
->buf_ptr
[0];
2776 /* case 'a' ... 'z': */
2803 /* case 'A' ... 'z': */
2838 if (!((ch
>= 'a' && ch
<= 'z') ||
2839 (ch
>= 'A' && ch
<= 'Z') ||
2840 (ch
>= '0' && ch
<= '9') ||
2841 strchr("/.-_+=$:\\,~", ch
)))
2843 if ((q
- name
) < name_size
- 1) {
2860 printf("tok=%c %d\n", c
, c
);
2861 if (c
== LD_TOK_NAME
)
2862 printf(" name=%s\n", name
);
2867 char *tcc_strcpy_part(char *out
, const char *in
, size_t num
)
2869 memcpy(out
, in
, num
);
2875 * Extract the library name from the file name
2876 * Return 0 if the file isn't a library
2878 * /!\ No test on filename capacity, be careful
2880 static int filename_to_libname(TCCState
*s1
, const char filename
[], char libname
[])
2885 /* already converted to library name */
2886 if (libname
[0] != '\0')
2888 ext
= tcc_fileextension(filename
);
2891 libprefix
= !strncmp(filename
, "lib", 3);
2892 if (!s1
->static_link
) {
2893 #ifdef TCC_TARGET_PE
2894 if (!strcmp(ext
, ".def")) {
2895 size_t len
= ext
- filename
;
2896 tcc_strcpy_part(libname
, filename
, len
);
2900 if (libprefix
&& (!strcmp(ext
, ".so"))) {
2901 size_t len
= ext
- filename
- 3;
2902 tcc_strcpy_part(libname
, filename
+ 3, len
);
2907 if (libprefix
&& (!strcmp(ext
, ".a"))) {
2908 size_t len
= ext
- filename
- 3;
2909 tcc_strcpy_part(libname
, filename
+ 3, len
);
2917 * Extract the file name from the library name
2919 * /!\ No test on filename capacity, be careful
2921 static void libname_to_filename(TCCState
*s1
, const char libname
[], char filename
[])
2923 if (!s1
->static_link
) {
2924 #ifdef TCC_TARGET_PE
2925 sprintf(filename
, "%s.def", libname
);
2927 sprintf(filename
, "lib%s.so", libname
);
2930 sprintf(filename
, "lib%s.a", libname
);
2934 static int ld_add_file(TCCState
*s1
, const char filename
[], char libname
[])
2938 ret
= tcc_add_file_internal(s1
, filename
, 0);
2940 if (filename_to_libname(s1
, filename
, libname
))
2941 ret
= tcc_add_library(s1
, libname
);
2946 static inline int new_undef_syms(void)
2949 ret
= new_undef_sym
;
2954 static int ld_add_file_list(TCCState
*s1
, const char *cmd
, int as_needed
)
2956 char filename
[1024], libname
[1024];
2957 int t
, group
, nblibs
= 0, ret
= 0;
2960 group
= !strcmp(cmd
, "GROUP");
2963 t
= ld_next(s1
, filename
, sizeof(filename
));
2966 t
= ld_next(s1
, filename
, sizeof(filename
));
2969 if (t
== LD_TOK_EOF
) {
2970 error_noabort("unexpected end of file");
2972 goto lib_parse_error
;
2973 } else if (t
== ')') {
2975 } else if (t
== '-') {
2976 t
= ld_next(s1
, filename
, sizeof(filename
));
2977 if ((t
!= LD_TOK_NAME
) || (filename
[0] != 'l')) {
2978 error_noabort("library name expected");
2980 goto lib_parse_error
;
2982 strcpy(libname
, &filename
[1]);
2983 libname_to_filename(s1
, libname
, filename
);
2984 } else if (t
!= LD_TOK_NAME
) {
2985 error_noabort("filename expected");
2987 goto lib_parse_error
;
2989 if (!strcmp(filename
, "AS_NEEDED")) {
2990 ret
= ld_add_file_list(s1
, cmd
, 1);
2992 goto lib_parse_error
;
2994 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2996 ret
= ld_add_file(s1
, filename
, libname
);
2998 goto lib_parse_error
;
3000 /* Add the filename *and* the libname to avoid future conversions */
3001 dynarray_add((void ***) &libs
, &nblibs
, tcc_strdup(filename
));
3002 dynarray_add((void ***) &libs
, &nblibs
, tcc_strdup(libname
));
3006 t
= ld_next(s1
, filename
, sizeof(filename
));
3008 t
= ld_next(s1
, filename
, sizeof(filename
));
3011 if (group
&& !as_needed
) {
3012 while (new_undef_syms()) {
3015 for (i
= 0; i
< nblibs
; i
+= 2)
3016 ld_add_file(s1
, libs
[i
], libs
[i
+1]);
3020 dynarray_reset(&libs
, &nblibs
);
3024 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3026 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
)
3029 char filename
[1024];
3032 ch
= file
->buf_ptr
[0];
3035 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3036 if (t
== LD_TOK_EOF
)
3038 else if (t
!= LD_TOK_NAME
)
3040 if (!strcmp(cmd
, "INPUT") ||
3041 !strcmp(cmd
, "GROUP")) {
3042 ret
= ld_add_file_list(s1
, cmd
, 0);
3045 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
3046 !strcmp(cmd
, "TARGET")) {
3047 /* ignore some commands */
3048 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3052 t
= ld_next(s1
, filename
, sizeof(filename
));
3053 if (t
== LD_TOK_EOF
) {
3054 error_noabort("unexpected end of file");
3056 } else if (t
== ')') {