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 /* XXX: DLL with PLT would only work with x86-64 for now */
36 //#define TCC_OUTPUT_DLL_WITH_PLT
38 ST_FUNC
int put_elf_str(Section
*s
, const char *sym
)
43 len
= strlen(sym
) + 1;
44 offset
= s
->data_offset
;
45 ptr
= section_ptr_add(s
, len
);
46 memcpy(ptr
, sym
, len
);
50 /* elf symbol hashing function */
51 static unsigned long elf_hash(const unsigned char *name
)
53 unsigned long h
= 0, g
;
56 h
= (h
<< 4) + *name
++;
65 /* rebuild hash table of section s */
66 /* NOTE: we do factorize the hash table code to go faster */
67 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
70 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
73 strtab
= s
->link
->data
;
74 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
76 s
->hash
->data_offset
= 0;
77 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
82 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
83 ptr
+= nb_buckets
+ 1;
85 sym
= (ElfW(Sym
) *)s
->data
+ 1;
86 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
87 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
88 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
99 /* return the symbol number */
100 ST_FUNC
int put_elf_sym(Section
*s
, uplong value
, unsigned long size
,
101 int info
, int other
, int shndx
, const char *name
)
103 int name_offset
, sym_index
;
108 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
110 name_offset
= put_elf_str(s
->link
, name
);
113 /* XXX: endianness */
114 sym
->st_name
= name_offset
;
115 sym
->st_value
= value
;
118 sym
->st_other
= other
;
119 sym
->st_shndx
= shndx
;
120 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
124 ptr
= section_ptr_add(hs
, sizeof(int));
125 base
= (int *)hs
->data
;
126 /* only add global or weak symbols */
127 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
128 /* add another hashing entry */
130 h
= elf_hash(name
) % nbuckets
;
132 base
[2 + h
] = sym_index
;
134 /* we resize the hash table */
135 hs
->nb_hashed_syms
++;
136 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
137 rebuild_hash(s
, 2 * nbuckets
);
147 /* find global ELF symbol 'name' and return its index. Return 0 if not
149 ST_FUNC
int find_elf_sym(Section
*s
, const char *name
)
153 int nbuckets
, sym_index
, h
;
159 nbuckets
= ((int *)hs
->data
)[0];
160 h
= elf_hash(name
) % nbuckets
;
161 sym_index
= ((int *)hs
->data
)[2 + h
];
162 while (sym_index
!= 0) {
163 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
164 name1
= s
->link
->data
+ sym
->st_name
;
165 if (!strcmp(name
, name1
))
167 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
172 /* return elf symbol value, signal error if 'err' is nonzero */
173 static void *get_elf_sym_addr(TCCState
*s
, const char *name
, int err
)
178 sym_index
= find_elf_sym(symtab_section
, name
);
179 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
180 if (!sym_index
|| sym
->st_shndx
== SHN_UNDEF
) {
182 error("%s not defined", name
);
185 return (void*)(uplong
)sym
->st_value
;
188 /* return elf symbol value */
189 LIBTCCAPI
void *tcc_get_symbol(TCCState
*s
, const char *name
)
191 return get_elf_sym_addr(s
, name
, 0);
194 /* return elf symbol value or error */
195 ST_FUNC
void *tcc_get_symbol_err(TCCState
*s
, const char *name
)
197 return get_elf_sym_addr(s
, name
, 1);
200 /* add an elf symbol : check if it is already defined and patch
201 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
202 ST_FUNC
int add_elf_sym(Section
*s
, uplong value
, unsigned long size
,
203 int info
, int other
, int sh_num
, const char *name
)
206 int sym_bind
, sym_index
, sym_type
, esym_bind
;
207 unsigned char sym_vis
, esym_vis
, new_vis
;
209 sym_bind
= ELFW(ST_BIND
)(info
);
210 sym_type
= ELFW(ST_TYPE
)(info
);
211 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
213 if (sym_bind
!= STB_LOCAL
) {
214 /* we search global or weak symbols */
215 sym_index
= find_elf_sym(s
, name
);
218 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
219 if (esym
->st_shndx
!= SHN_UNDEF
) {
220 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
221 /* propagate the most constraining visibility */
222 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
223 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
224 if (esym_vis
== STV_DEFAULT
) {
226 } else if (sym_vis
== STV_DEFAULT
) {
229 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
231 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
233 other
= esym
->st_other
; /* in case we have to patch esym */
234 if (sh_num
== SHN_UNDEF
) {
235 /* ignore adding of undefined symbol if the
236 corresponding symbol is already defined */
237 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
238 /* global overrides weak, so patch */
240 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
241 /* weak is ignored if already global */
242 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
243 /* ignore hidden symbols after */
244 } else if (esym
->st_shndx
== SHN_COMMON
245 && (sh_num
< SHN_LORESERVE
|| sh_num
== SHN_COMMON
)) {
246 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
247 No idea if this is the correct solution ... */
249 } else if (s
== tcc_state
->dynsymtab_section
) {
250 /* we accept that two DLL define the same symbol */
253 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
254 sym_bind
, sh_num
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
256 error_noabort("'%s' defined twice", name
);
260 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
261 esym
->st_shndx
= sh_num
;
262 esym
->st_value
= value
;
263 esym
->st_size
= size
;
264 esym
->st_other
= other
;
268 sym_index
= put_elf_sym(s
, value
, size
,
269 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
276 ST_FUNC
void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
277 int type
, int symbol
)
285 /* if no relocation section, create it */
286 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
287 /* if the symtab is allocated, then we consider the relocation
289 sr
= new_section(tcc_state
, buf
, SHT_RELX
, symtab
->sh_flags
);
290 sr
->sh_entsize
= sizeof(ElfW_Rel
);
292 sr
->sh_info
= s
->sh_num
;
295 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
296 rel
->r_offset
= offset
;
297 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
298 #ifdef TCC_TARGET_X86_64
303 /* put stab debug information */
305 ST_FUNC
void put_stabs(const char *str
, int type
, int other
, int desc
,
310 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
312 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
317 sym
->n_other
= other
;
319 sym
->n_value
= value
;
322 ST_FUNC
void put_stabs_r(const char *str
, int type
, int other
, int desc
,
323 unsigned long value
, Section
*sec
, int sym_index
)
325 put_stabs(str
, type
, other
, desc
, value
);
326 put_elf_reloc(symtab_section
, stab_section
,
327 stab_section
->data_offset
- sizeof(unsigned int),
328 R_DATA_32
, sym_index
);
331 ST_FUNC
void put_stabn(int type
, int other
, int desc
, int value
)
333 put_stabs(NULL
, type
, other
, desc
, value
);
336 ST_FUNC
void put_stabd(int type
, int other
, int desc
)
338 put_stabs(NULL
, type
, other
, desc
, 0);
341 /* In an ELF file symbol table, the local symbols must appear below
342 the global and weak ones. Since TCC cannot sort it while generating
343 the code, we must do it after. All the relocation tables are also
344 modified to take into account the symbol table sorting */
345 static void sort_syms(TCCState
*s1
, Section
*s
)
347 int *old_to_new_syms
;
351 ElfW_Rel
*rel
, *rel_end
;
355 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
356 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
357 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
359 /* first pass for local symbols */
360 p
= (ElfW(Sym
) *)s
->data
;
362 for(i
= 0; i
< nb_syms
; i
++) {
363 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
364 old_to_new_syms
[i
] = q
- new_syms
;
369 /* save the number of local symbols in section header */
370 s
->sh_info
= q
- new_syms
;
372 /* then second pass for non local symbols */
373 p
= (ElfW(Sym
) *)s
->data
;
374 for(i
= 0; i
< nb_syms
; i
++) {
375 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
376 old_to_new_syms
[i
] = q
- new_syms
;
382 /* we copy the new symbols to the old */
383 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
386 /* now we modify all the relocations */
387 for(i
= 1; i
< s1
->nb_sections
; i
++) {
388 sr
= s1
->sections
[i
];
389 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
390 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
391 for(rel
= (ElfW_Rel
*)sr
->data
;
394 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
395 type
= ELFW(R_TYPE
)(rel
->r_info
);
396 sym_index
= old_to_new_syms
[sym_index
];
397 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
402 tcc_free(old_to_new_syms
);
405 /* relocate common symbols in the .bss section */
406 ST_FUNC
void relocate_common_syms(void)
408 ElfW(Sym
) *sym
, *sym_end
;
409 unsigned long offset
, align
;
411 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
412 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
415 if (sym
->st_shndx
== SHN_COMMON
) {
417 align
= sym
->st_value
;
418 offset
= bss_section
->data_offset
;
419 offset
= (offset
+ align
- 1) & -align
;
420 sym
->st_value
= offset
;
421 sym
->st_shndx
= bss_section
->sh_num
;
422 offset
+= sym
->st_size
;
423 bss_section
->data_offset
= offset
;
428 /* relocate symbol table, resolve undefined symbols if do_resolve is
429 true and output error if undefined symbol. */
430 ST_FUNC
void relocate_syms(TCCState
*s1
, int do_resolve
)
432 ElfW(Sym
) *sym
, *esym
, *sym_end
;
433 int sym_bind
, sh_num
, sym_index
;
436 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
437 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
440 sh_num
= sym
->st_shndx
;
441 if (sh_num
== SHN_UNDEF
) {
442 name
= strtab_section
->data
+ sym
->st_name
;
444 #if !defined TCC_TARGET_PE || !defined _WIN32
446 name
= symtab_section
->link
->data
+ sym
->st_name
;
447 addr
= resolve_sym(s1
, name
);
449 sym
->st_value
= (uplong
)addr
;
453 } else if (s1
->dynsym
) {
454 /* if dynamic symbol exist, then use it */
455 sym_index
= find_elf_sym(s1
->dynsym
, name
);
457 esym
= &((ElfW(Sym
) *)s1
->dynsym
->data
)[sym_index
];
458 sym
->st_value
= esym
->st_value
;
462 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
464 if (!strcmp(name
, "_fp_hw"))
466 /* only weak symbols are accepted to be undefined. Their
468 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
469 if (sym_bind
== STB_WEAK
) {
472 error_noabort("undefined symbol '%s'", name
);
474 } else if (sh_num
< SHN_LORESERVE
) {
475 /* add section base */
476 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
482 #ifndef TCC_TARGET_PE
483 #ifdef TCC_TARGET_X86_64
484 #define JMP_TABLE_ENTRY_SIZE 14
485 static uplong
add_jmp_table(TCCState
*s1
, uplong val
)
487 char *p
= s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
;
488 s1
->runtime_plt_and_got_offset
+= JMP_TABLE_ENTRY_SIZE
;
493 *(uplong
*)(p
+ 6) = val
;
497 static uplong
add_got_table(TCCState
*s1
, uplong val
)
499 uplong
*p
= (uplong
*)(s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
);
500 s1
->runtime_plt_and_got_offset
+= sizeof(uplong
);
507 /* relocate a given section (CPU dependent) */
508 ST_FUNC
void relocate_section(TCCState
*s1
, Section
*s
)
511 ElfW_Rel
*rel
, *rel_end
, *qrel
;
516 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
521 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
522 qrel
= (ElfW_Rel
*)sr
->data
;
526 ptr
= s
->data
+ rel
->r_offset
;
528 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
529 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
531 #ifdef TCC_TARGET_X86_64
532 /* XXX: not tested */
533 val
+= rel
->r_addend
;
535 type
= ELFW(R_TYPE
)(rel
->r_info
);
536 addr
= s
->sh_addr
+ rel
->r_offset
;
540 #if defined(TCC_TARGET_I386)
542 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
543 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
544 qrel
->r_offset
= rel
->r_offset
;
546 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_32
);
550 qrel
->r_info
= ELFW(R_INFO
)(0, R_386_RELATIVE
);
557 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
559 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
561 qrel
->r_offset
= rel
->r_offset
;
562 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_PC32
);
567 *(int *)ptr
+= val
- addr
;
570 *(int *)ptr
+= val
- addr
;
577 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
580 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
583 /* we load the got offset */
584 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
587 if (s1
->output_format
!= TCC_OUTPUT_FORMAT_BINARY
) {
589 error("can only produce 16-bit binary files");
591 *(short *)ptr
+= val
;
594 if (s1
->output_format
!= TCC_OUTPUT_FORMAT_BINARY
)
596 *(short *)ptr
+= val
- addr
;
598 #elif defined(TCC_TARGET_ARM)
605 x
= (*(int *)ptr
)&0xffffff;
606 (*(int *)ptr
) &= 0xff000000;
611 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
612 error("can't relocate value at %x",addr
);
621 x
= (*(int *)ptr
) & 0x7fffffff;
622 (*(int *)ptr
) &= 0x80000000;
625 if((x
^(x
>>1))&0x40000000)
626 error("can't relocate value at %x",addr
);
627 (*(int *)ptr
) |= x
& 0x7fffffff;
632 case R_ARM_BASE_PREL
:
633 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
636 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
639 /* we load the got offset */
640 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
645 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
646 type
,addr
,(unsigned int)(long)ptr
,val
);
648 #elif defined(TCC_TARGET_C67)
656 /* put the low 16 bits of the absolute address */
657 // add to what is already there
659 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
660 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
662 //patch both at once - assumes always in pairs Low - High
664 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
665 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
671 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
672 type
,addr
,(unsigned int)(long)ptr
, val
);
674 #elif defined(TCC_TARGET_X86_64)
676 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
677 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
678 qrel
->r_addend
= *(long long *)ptr
+ val
;
681 *(long long *)ptr
+= val
;
685 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
686 /* XXX: this logic may depend on TCC's codegen
687 now TCC uses R_X86_64_32 even for a 64bit pointer */
688 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
689 qrel
->r_addend
= *(int *)ptr
+ val
;
694 case R_X86_64_PC32
: {
696 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
698 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
700 qrel
->r_offset
= rel
->r_offset
;
701 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_X86_64_PC32
);
702 qrel
->r_addend
= *(int *)ptr
;
707 diff
= (long long)val
- addr
;
708 if (diff
<= -2147483647 || diff
> 2147483647) {
709 #ifndef TCC_TARGET_PE
710 /* XXX: naive support for over 32bit jump */
711 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
712 val
= add_jmp_table(s1
, val
);
716 if (diff
<= -2147483647 || diff
> 2147483647) {
717 error("internal error: relocation failed");
724 *(int *)ptr
+= val
- addr
;
726 case R_X86_64_GLOB_DAT
:
727 case R_X86_64_JUMP_SLOT
:
730 case R_X86_64_GOTPCREL
:
731 #ifndef TCC_TARGET_PE
732 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
733 val
= add_got_table(s1
, val
- rel
->r_addend
) + rel
->r_addend
;
734 *(int *)ptr
+= val
- addr
;
738 *(int *)ptr
+= (s1
->got
->sh_addr
- addr
+
739 s1
->got_offsets
[sym_index
] - 4);
741 case R_X86_64_GOTTPOFF
:
742 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
745 /* we load the got offset */
746 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
749 #error unsupported processor
753 /* if the relocation is allocated, we change its symbol table */
754 if (sr
->sh_flags
& SHF_ALLOC
)
755 sr
->link
= s1
->dynsym
;
758 /* relocate relocation table in 'sr' */
759 static void relocate_rel(TCCState
*s1
, Section
*sr
)
762 ElfW_Rel
*rel
, *rel_end
;
764 s
= s1
->sections
[sr
->sh_info
];
765 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
766 for(rel
= (ElfW_Rel
*)sr
->data
;
769 rel
->r_offset
+= s
->sh_addr
;
773 /* count the number of dynamic relocations so that we can reserve
775 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
777 ElfW_Rel
*rel
, *rel_end
;
778 int sym_index
, esym_index
, type
, count
;
781 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
782 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
783 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
784 type
= ELFW(R_TYPE
)(rel
->r_info
);
786 #if defined(TCC_TARGET_I386)
788 #elif defined(TCC_TARGET_X86_64)
795 #if defined(TCC_TARGET_I386)
797 #elif defined(TCC_TARGET_X86_64)
800 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
809 /* allocate the section */
810 sr
->sh_flags
|= SHF_ALLOC
;
811 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
816 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
821 if (index
>= s1
->nb_got_offsets
) {
822 /* find immediately bigger power of 2 and reallocate array */
826 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
828 error("memory full");
829 s1
->got_offsets
= tab
;
830 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
831 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
832 s1
->nb_got_offsets
= n
;
834 s1
->got_offsets
[index
] = val
;
837 /* XXX: suppress that */
838 static void put32(unsigned char *p
, uint32_t val
)
846 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
847 defined(TCC_TARGET_X86_64)
848 static uint32_t get32(unsigned char *p
)
850 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
854 static void build_got(TCCState
*s1
)
858 /* if no got, then create it */
859 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
860 s1
->got
->sh_entsize
= 4;
861 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
862 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
863 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
865 /* keep space for _DYNAMIC pointer, if present */
867 /* two dummy got entries */
871 /* keep space for _DYNAMIC pointer, if present */
874 /* two dummy got entries */
882 /* put a got entry corresponding to a symbol in symtab_section. 'size'
883 and 'info' can be modifed if more precise info comes from the DLL */
884 static void put_got_entry(TCCState
*s1
,
885 int reloc_type
, unsigned long size
, int info
,
891 unsigned long offset
;
897 /* if a got entry already exists for that symbol, no need to add one */
898 if (sym_index
< s1
->nb_got_offsets
&&
899 s1
->got_offsets
[sym_index
] != 0)
902 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
905 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
906 name
= symtab_section
->link
->data
+ sym
->st_name
;
907 offset
= sym
->st_value
;
908 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
910 #ifdef TCC_TARGET_X86_64
920 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
923 /* if we build a DLL, we add a %ebx offset */
924 if (s1
->output_type
== TCC_OUTPUT_DLL
)
930 /* add a PLT entry */
932 if (plt
->data_offset
== 0) {
933 /* first plt entry */
934 p
= section_ptr_add(plt
, 16);
935 p
[0] = 0xff; /* pushl got + PTR_SIZE */
937 put32(p
+ 2, PTR_SIZE
);
938 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
940 put32(p
+ 8, PTR_SIZE
* 2);
943 p
= section_ptr_add(plt
, 16);
944 p
[0] = 0xff; /* jmp *(got + x) */
946 put32(p
+ 2, s1
->got
->data_offset
);
947 p
[6] = 0x68; /* push $xxx */
948 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
949 p
[11] = 0xe9; /* jmp plt_start */
950 put32(p
+ 12, -(plt
->data_offset
));
952 /* the symbol is modified so that it will be relocated to
954 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
955 if (s1
->output_type
== TCC_OUTPUT_EXE
)
957 offset
= plt
->data_offset
- 16;
959 #elif defined(TCC_TARGET_ARM)
960 if (reloc_type
== R_ARM_JUMP_SLOT
) {
964 /* if we build a DLL, we add a %ebx offset */
965 if (s1
->output_type
== TCC_OUTPUT_DLL
)
966 error("DLLs unimplemented!");
968 /* add a PLT entry */
970 if (plt
->data_offset
== 0) {
971 /* first plt entry */
972 p
= section_ptr_add(plt
, 16);
973 put32(p
, 0xe52de004);
974 put32(p
+ 4, 0xe59fe010);
975 put32(p
+ 8, 0xe08fe00e);
976 put32(p
+ 12, 0xe5bef008);
979 p
= section_ptr_add(plt
, 16);
980 put32(p
, 0xe59fc004);
981 put32(p
+4, 0xe08fc00c);
982 put32(p
+8, 0xe59cf000);
983 put32(p
+12, s1
->got
->data_offset
);
985 /* the symbol is modified so that it will be relocated to
987 if (s1
->output_type
== TCC_OUTPUT_EXE
)
988 offset
= plt
->data_offset
- 16;
990 #elif defined(TCC_TARGET_C67)
991 error("C67 got not implemented");
993 #error unsupported CPU
995 index
= put_elf_sym(s1
->dynsym
, offset
,
996 size
, info
, 0, sym
->st_shndx
, name
);
997 /* put a got entry */
998 put_elf_reloc(s1
->dynsym
, s1
->got
,
999 s1
->got
->data_offset
,
1002 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
1006 /* build GOT and PLT entries */
1007 ST_FUNC
void build_got_entries(TCCState
*s1
)
1009 Section
*s
, *symtab
;
1010 ElfW_Rel
*rel
, *rel_end
;
1012 int i
, type
, reloc_type
, sym_index
;
1014 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1015 s
= s1
->sections
[i
];
1016 if (s
->sh_type
!= SHT_RELX
)
1018 /* no need to handle got relocations */
1019 if (s
->link
!= symtab_section
)
1022 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
1023 for(rel
= (ElfW_Rel
*)s
->data
;
1026 type
= ELFW(R_TYPE
)(rel
->r_info
);
1028 #if defined(TCC_TARGET_I386)
1035 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1036 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1037 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1038 /* look at the symbol got offset. If none, then add one */
1039 if (type
== R_386_GOT32
)
1040 reloc_type
= R_386_GLOB_DAT
;
1042 reloc_type
= R_386_JMP_SLOT
;
1043 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1047 #elif defined(TCC_TARGET_ARM)
1048 case R_ARM_GOT_BREL
:
1049 case R_ARM_GOTOFF32
:
1050 case R_ARM_BASE_PREL
:
1054 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1055 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1056 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1057 /* look at the symbol got offset. If none, then add one */
1058 if (type
== R_ARM_GOT_BREL
)
1059 reloc_type
= R_ARM_GLOB_DAT
;
1061 reloc_type
= R_ARM_JUMP_SLOT
;
1062 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1066 #elif defined(TCC_TARGET_C67)
1073 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1074 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1075 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1076 /* look at the symbol got offset. If none, then add one */
1077 if (type
== R_C60_GOT32
)
1078 reloc_type
= R_C60_GLOB_DAT
;
1080 reloc_type
= R_C60_JMP_SLOT
;
1081 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1085 #elif defined(TCC_TARGET_X86_64)
1086 case R_X86_64_GOT32
:
1087 case R_X86_64_GOTTPOFF
:
1088 case R_X86_64_GOTPCREL
:
1089 case R_X86_64_PLT32
:
1092 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
||
1093 type
== R_X86_64_PLT32
) {
1094 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1095 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1096 /* look at the symbol got offset. If none, then add one */
1097 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
)
1098 reloc_type
= R_X86_64_GLOB_DAT
;
1100 reloc_type
= R_X86_64_JUMP_SLOT
;
1101 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1106 #error unsupported CPU
1115 ST_FUNC Section
*new_symtab(TCCState
*s1
,
1116 const char *symtab_name
, int sh_type
, int sh_flags
,
1117 const char *strtab_name
,
1118 const char *hash_name
, int hash_sh_flags
)
1120 Section
*symtab
, *strtab
, *hash
;
1121 int *ptr
, nb_buckets
;
1123 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1124 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1125 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1126 put_elf_str(strtab
, "");
1127 symtab
->link
= strtab
;
1128 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1132 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1133 hash
->sh_entsize
= sizeof(int);
1134 symtab
->hash
= hash
;
1135 hash
->link
= symtab
;
1137 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1138 ptr
[0] = nb_buckets
;
1140 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1144 /* put dynamic tag */
1145 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1148 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1150 dyn
->d_un
.d_val
= val
;
1153 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1157 char sym_start
[1024];
1160 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1161 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1163 s
= find_section(s1
, section_name
);
1168 end_offset
= s
->data_offset
;
1171 add_elf_sym(symtab_section
,
1173 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1174 s
->sh_num
, sym_start
);
1175 add_elf_sym(symtab_section
,
1177 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1178 s
->sh_num
, sym_end
);
1181 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
1183 #ifdef CONFIG_TCC_BCHECK
1185 Section
*init_section
;
1186 unsigned char *pinit
;
1189 if (0 == s1
->do_bounds_check
)
1192 /* XXX: add an object file to do that */
1193 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1195 add_elf_sym(symtab_section
, 0, 0,
1196 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1197 bounds_section
->sh_num
, "__bounds_start");
1198 /* add bound check code */
1199 #ifndef TCC_TARGET_PE
1202 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "bcheck.o");
1203 tcc_add_file(s1
, buf
);
1206 #ifdef TCC_TARGET_I386
1207 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1208 /* add 'call __bound_init()' in .init section */
1209 init_section
= find_section(s1
, ".init");
1210 pinit
= section_ptr_add(init_section
, 5);
1212 put32(pinit
+ 1, -4);
1213 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1214 put_elf_reloc(symtab_section
, init_section
,
1215 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1221 /* add tcc runtime libraries */
1222 ST_FUNC
void tcc_add_runtime(TCCState
*s1
)
1227 if (!s1
->nostdlib
) {
1228 #ifdef CONFIG_USE_LIBGCC
1229 tcc_add_library(s1
, "c");
1230 tcc_add_file(s1
, CONFIG_SYSROOT
"/lib/libgcc_s.so.1");
1233 tcc_add_library(s1
, "c");
1234 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "libtcc1.a");
1235 tcc_add_file(s1
, buf
);
1238 /* add crt end if not memory output */
1239 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1240 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1244 /* add various standard linker symbols (must be done after the
1245 sections are filled (for example after allocating common
1247 ST_FUNC
void tcc_add_linker_symbols(TCCState
*s1
)
1253 add_elf_sym(symtab_section
,
1254 text_section
->data_offset
, 0,
1255 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1256 text_section
->sh_num
, "_etext");
1257 add_elf_sym(symtab_section
,
1258 data_section
->data_offset
, 0,
1259 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1260 data_section
->sh_num
, "_edata");
1261 add_elf_sym(symtab_section
,
1262 bss_section
->data_offset
, 0,
1263 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1264 bss_section
->sh_num
, "_end");
1265 /* horrible new standard ldscript defines */
1266 add_init_array_defines(s1
, ".preinit_array");
1267 add_init_array_defines(s1
, ".init_array");
1268 add_init_array_defines(s1
, ".fini_array");
1270 /* add start and stop symbols for sections whose name can be
1272 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1273 s
= s1
->sections
[i
];
1274 if (s
->sh_type
== SHT_PROGBITS
&&
1275 (s
->sh_flags
& SHF_ALLOC
)) {
1279 /* check if section name can be expressed in C */
1285 if (!isid(ch
) && !isnum(ch
))
1289 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1290 add_elf_sym(symtab_section
,
1292 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1294 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1295 add_elf_sym(symtab_section
,
1297 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1304 /* name of ELF interpreter */
1305 #if defined __FreeBSD__
1306 static const char elf_interp
[] = "/libexec/ld-elf.so.1";
1307 #elif defined TCC_ARM_EABI
1308 static const char elf_interp
[] = "/lib/ld-linux.so.3";
1309 #elif defined(TCC_TARGET_X86_64)
1310 # if defined(TCC_TARGET_X86_64_CENTOS)
1311 static const char elf_interp
[] = "/lib64/ld-linux-x86-64.so.2";
1313 static const char elf_interp
[] = "/lib/ld-linux-x86-64.so.2";
1314 # endif /* TCC_TARGET_X86_64_CENTOS */
1315 #elif defined(TCC_UCLIBC)
1316 static const char elf_interp
[] = "/lib/ld-uClibc.so.0";
1318 static const char elf_interp
[] = "/lib/ld-linux.so.2";
1321 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1322 const int *section_order
)
1325 int i
, offset
, size
;
1328 for(i
=1;i
<s1
->nb_sections
;i
++) {
1329 s
= s1
->sections
[section_order
[i
]];
1330 if (s
->sh_type
!= SHT_NOBITS
&&
1331 (s
->sh_flags
& SHF_ALLOC
)) {
1332 while (offset
< s
->sh_offset
) {
1337 fwrite(s
->data
, 1, size
, f
);
1343 #if defined(__FreeBSD__)
1345 #define EXTRA_RELITEMS 14
1347 /* move the relocation value from .dynsym to .got */
1348 void patch_dynsym_undef(TCCState
*s1
, Section
*s
)
1350 uint32_t *gotd
= (void *)s1
->got
->data
;
1351 ElfW(Sym
) *sym
, *sym_end
;
1353 gotd
+= 3; // dummy entries in .got
1354 /* relocate symbols in .dynsym */
1355 sym_end
= (ElfW(Sym
) *)(s
->data
+ s
->data_offset
);
1356 for (sym
= (ElfW(Sym
) *)s
->data
+ 1; sym
< sym_end
; sym
++) {
1357 if (sym
->st_shndx
== SHN_UNDEF
) {
1358 *gotd
++ = sym
->st_value
+ 6; // XXX 6 is magic ?
1365 #define EXTRA_RELITEMS 9
1368 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1370 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1371 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1372 unsigned long offset
;
1374 if (sym_index
>= s1
->nb_got_offsets
)
1376 offset
= s1
->got_offsets
[sym_index
];
1377 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1378 #ifdef TCC_TARGET_X86_64
1379 /* only works for x86-64 */
1380 put32(s1
->got
->data
+ offset
, sym
->st_value
>> 32);
1382 put32(s1
->got
->data
+ offset
, sym
->st_value
& 0xffffffff);
1385 ST_FUNC
void fill_got(TCCState
*s1
)
1388 ElfW_Rel
*rel
, *rel_end
;
1391 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1392 s
= s1
->sections
[i
];
1393 if (s
->sh_type
!= SHT_RELX
)
1395 /* no need to handle got relocations */
1396 if (s
->link
!= symtab_section
)
1398 rel_end
= (ElfW_Rel
*) (s
->data
+ s
->data_offset
);
1399 for(rel
= (ElfW_Rel
*) s
->data
; rel
< rel_end
; rel
++) {
1400 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1401 case R_X86_64_GOT32
:
1402 case R_X86_64_GOTPCREL
:
1403 case R_X86_64_PLT32
:
1404 fill_got_entry(s1
, rel
);
1412 /* output an ELF file */
1413 /* XXX: suppress unneeded sections */
1414 static int elf_output_file(TCCState
*s1
, const char *filename
)
1420 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1422 Section
*strsec
, *s
;
1423 ElfW(Shdr
) shdr
, *sh
;
1424 ElfW(Phdr
) *phdr
, *ph
;
1425 Section
*interp
, *dynamic
, *dynstr
;
1426 unsigned long saved_dynamic_data_offset
;
1428 int type
, file_type
;
1429 unsigned long rel_addr
, rel_size
;
1430 unsigned long bss_addr
, bss_size
;
1432 file_type
= s1
->output_type
;
1435 if (file_type
!= TCC_OUTPUT_OBJ
) {
1436 tcc_add_runtime(s1
);
1440 section_order
= NULL
;
1443 dynstr
= NULL
; /* avoid warning */
1444 saved_dynamic_data_offset
= 0; /* avoid warning */
1446 if (file_type
!= TCC_OUTPUT_OBJ
) {
1447 relocate_common_syms();
1449 tcc_add_linker_symbols(s1
);
1451 if (!s1
->static_link
) {
1453 int sym_index
, index
;
1454 ElfW(Sym
) *esym
, *sym_end
;
1456 if (file_type
== TCC_OUTPUT_EXE
) {
1458 /* allow override the dynamic loader */
1459 const char *elfint
= getenv("LD_SO");
1461 elfint
= elf_interp
;
1462 /* add interpreter section only if executable */
1463 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1464 interp
->sh_addralign
= 1;
1465 ptr
= section_ptr_add(interp
, 1+strlen(elfint
));
1466 strcpy(ptr
, elfint
);
1469 /* add dynamic symbol table */
1470 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1472 ".hash", SHF_ALLOC
);
1473 dynstr
= s1
->dynsym
->link
;
1475 /* add dynamic section */
1476 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1477 SHF_ALLOC
| SHF_WRITE
);
1478 dynamic
->link
= dynstr
;
1479 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1482 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1483 SHF_ALLOC
| SHF_EXECINSTR
);
1484 s1
->plt
->sh_entsize
= 4;
1488 /* scan for undefined symbols and see if they are in the
1489 dynamic symbols. If a symbol STT_FUNC is found, then we
1490 add it in the PLT. If a symbol STT_OBJECT is found, we
1491 add it in the .bss section with a suitable relocation */
1492 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1493 symtab_section
->data_offset
);
1494 if (file_type
== TCC_OUTPUT_EXE
) {
1495 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1498 if (sym
->st_shndx
== SHN_UNDEF
) {
1499 name
= symtab_section
->link
->data
+ sym
->st_name
;
1500 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1502 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1503 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1504 if (type
== STT_FUNC
) {
1505 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1507 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1508 } else if (type
== STT_OBJECT
) {
1509 unsigned long offset
;
1510 offset
= bss_section
->data_offset
;
1511 /* XXX: which alignment ? */
1512 offset
= (offset
+ 16 - 1) & -16;
1513 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1515 bss_section
->sh_num
, name
);
1516 put_elf_reloc(s1
->dynsym
, bss_section
,
1517 offset
, R_COPY
, index
);
1518 offset
+= esym
->st_size
;
1519 bss_section
->data_offset
= offset
;
1522 /* STB_WEAK undefined symbols are accepted */
1523 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1525 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1526 !strcmp(name
, "_fp_hw")) {
1528 error_noabort("undefined symbol '%s'", name
);
1531 } else if (s1
->rdynamic
&&
1532 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1533 /* if -rdynamic option, then export all non
1535 name
= symtab_section
->link
->data
+ sym
->st_name
;
1536 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1538 sym
->st_shndx
, name
);
1545 /* now look at unresolved dynamic symbols and export
1546 corresponding symbol */
1547 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1548 s1
->dynsymtab_section
->data_offset
);
1549 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1552 if (esym
->st_shndx
== SHN_UNDEF
) {
1553 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1554 sym_index
= find_elf_sym(symtab_section
, name
);
1556 /* XXX: avoid adding a symbol if already
1557 present because of -rdynamic ? */
1558 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1559 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1561 sym
->st_shndx
, name
);
1563 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1564 /* weak symbols can stay undefined */
1566 warning("undefined dynamic symbol '%s'", name
);
1573 /* shared library case : we simply export all the global symbols */
1574 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1575 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1576 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1579 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1580 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1581 if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
&&
1582 sym
->st_shndx
== SHN_UNDEF
) {
1583 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1585 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1587 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1588 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1590 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1595 name
= symtab_section
->link
->data
+ sym
->st_name
;
1596 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1598 sym
->st_shndx
, name
);
1599 s1
->symtab_to_dynsym
[sym
-
1600 (ElfW(Sym
) *)symtab_section
->data
] =
1607 build_got_entries(s1
);
1609 /* add a list of needed dlls */
1610 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1611 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1612 if (dllref
->level
== 0)
1613 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1617 put_dt(dynamic
, DT_RPATH
, put_elf_str(dynstr
, s1
->rpath
));
1619 /* XXX: currently, since we do not handle PIC code, we
1620 must relocate the readonly segments */
1621 if (file_type
== TCC_OUTPUT_DLL
) {
1623 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1624 put_dt(dynamic
, DT_TEXTREL
, 0);
1628 put_dt(dynamic
, DT_SYMBOLIC
, 0);
1630 /* add necessary space for other entries */
1631 saved_dynamic_data_offset
= dynamic
->data_offset
;
1632 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * EXTRA_RELITEMS
;
1634 /* still need to build got entries in case of static link */
1635 build_got_entries(s1
);
1639 memset(&ehdr
, 0, sizeof(ehdr
));
1641 /* we add a section for symbols */
1642 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1643 put_elf_str(strsec
, "");
1645 /* compute number of sections */
1646 shnum
= s1
->nb_sections
;
1648 /* this array is used to reorder sections in the output file */
1649 section_order
= tcc_malloc(sizeof(int) * shnum
);
1650 section_order
[0] = 0;
1653 /* compute number of program headers */
1656 case TCC_OUTPUT_OBJ
:
1659 case TCC_OUTPUT_EXE
:
1660 if (!s1
->static_link
)
1661 phnum
= 4 + HAVE_PHDR
;
1665 case TCC_OUTPUT_DLL
:
1670 /* allocate strings for section names and decide if an unallocated
1671 section should be output */
1672 /* NOTE: the strsec section comes last, so its size is also
1674 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1675 s
= s1
->sections
[i
];
1676 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1678 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1683 s
->reloc
? s
->reloc
->name
: "n"
1686 /* when generating a DLL, we include relocations but we may
1688 if (file_type
== TCC_OUTPUT_DLL
&&
1689 s
->sh_type
== SHT_RELX
&&
1690 !(s
->sh_flags
& SHF_ALLOC
)) {
1691 /* //gr: avoid bogus relocs for empty (debug) sections */
1692 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1693 prepare_dynamic_rel(s1
, s
);
1694 else if (s1
->do_debug
)
1695 s
->sh_size
= s
->data_offset
;
1696 } else if (s1
->do_debug
||
1697 file_type
== TCC_OUTPUT_OBJ
||
1698 (s
->sh_flags
& SHF_ALLOC
) ||
1699 i
== (s1
->nb_sections
- 1)) {
1700 /* we output all sections if debug or object file */
1701 s
->sh_size
= s
->data_offset
;
1705 /* allocate program segment headers */
1706 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1708 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1709 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1714 /* compute section to program header mapping */
1715 if (s1
->has_text_addr
) {
1716 int a_offset
, p_offset
;
1717 addr
= s1
->text_addr
;
1718 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1720 a_offset
= addr
& (s1
->section_align
- 1);
1721 p_offset
= file_offset
& (s1
->section_align
- 1);
1722 if (a_offset
< p_offset
)
1723 a_offset
+= s1
->section_align
;
1724 file_offset
+= (a_offset
- p_offset
);
1726 if (file_type
== TCC_OUTPUT_DLL
)
1729 addr
= ELF_START_ADDR
;
1730 /* compute address after headers */
1731 addr
+= (file_offset
& (s1
->section_align
- 1));
1734 /* dynamic relocation table information, for .dynamic section */
1738 bss_addr
= bss_size
= 0;
1739 /* leave one program header for the program interpreter */
1742 ph
+= 1 + HAVE_PHDR
;
1744 for(j
= 0; j
< 2; j
++) {
1745 ph
->p_type
= PT_LOAD
;
1747 ph
->p_flags
= PF_R
| PF_X
;
1749 ph
->p_flags
= PF_R
| PF_W
;
1750 ph
->p_align
= s1
->section_align
;
1752 /* we do the following ordering: interp, symbol tables,
1753 relocations, progbits, nobits */
1754 /* XXX: do faster and simpler sorting */
1755 for(k
= 0; k
< 5; k
++) {
1756 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1757 s
= s1
->sections
[i
];
1758 /* compute if section should be included */
1760 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1764 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1765 (SHF_ALLOC
| SHF_WRITE
))
1771 } else if (s
->sh_type
== SHT_DYNSYM
||
1772 s
->sh_type
== SHT_STRTAB
||
1773 s
->sh_type
== SHT_HASH
) {
1776 } else if (s
->sh_type
== SHT_RELX
) {
1779 } else if (s
->sh_type
== SHT_NOBITS
) {
1786 section_order
[sh_order_index
++] = i
;
1788 /* section matches: we align it and add its size */
1790 addr
= (addr
+ s
->sh_addralign
- 1) &
1791 ~(s
->sh_addralign
- 1);
1792 file_offset
+= addr
- tmp
;
1793 s
->sh_offset
= file_offset
;
1796 /* update program header infos */
1797 if (ph
->p_offset
== 0) {
1798 ph
->p_offset
= file_offset
;
1800 ph
->p_paddr
= ph
->p_vaddr
;
1802 /* update dynamic relocation infos */
1803 if (s
->sh_type
== SHT_RELX
) {
1804 #if defined(__FreeBSD__)
1805 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.got")) { // rel_size == 0) {
1807 rel_size
+= s
->sh_size
; // XXX only first rel.
1809 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.bss")) { // rel_size == 0) {
1811 bss_size
= s
->sh_size
; // XXX only first rel.
1816 rel_size
+= s
->sh_size
;
1820 if (s
->sh_type
!= SHT_NOBITS
)
1821 file_offset
+= s
->sh_size
;
1824 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1825 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1828 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1829 /* if in the middle of a page, we duplicate the page in
1830 memory so that one copy is RX and the other is RW */
1831 if ((addr
& (s1
->section_align
- 1)) != 0)
1832 addr
+= s1
->section_align
;
1834 addr
= (addr
+ s1
->section_align
- 1) & ~(s1
->section_align
- 1);
1835 file_offset
= (file_offset
+ s1
->section_align
- 1) &
1836 ~(s1
->section_align
- 1);
1841 /* if interpreter, then add corresponing program header */
1845 #if defined(__FreeBSD__)
1847 int len
= phnum
* sizeof(ElfW(Phdr
));
1849 ph
->p_type
= PT_PHDR
;
1850 ph
->p_offset
= sizeof(ElfW(Ehdr
));
1851 ph
->p_vaddr
= interp
->sh_addr
- len
;
1852 ph
->p_paddr
= ph
->p_vaddr
;
1853 ph
->p_filesz
= ph
->p_memsz
= len
;
1854 ph
->p_flags
= PF_R
| PF_X
;
1855 ph
->p_align
= 4; // interp->sh_addralign;
1860 ph
->p_type
= PT_INTERP
;
1861 ph
->p_offset
= interp
->sh_offset
;
1862 ph
->p_vaddr
= interp
->sh_addr
;
1863 ph
->p_paddr
= ph
->p_vaddr
;
1864 ph
->p_filesz
= interp
->sh_size
;
1865 ph
->p_memsz
= interp
->sh_size
;
1867 ph
->p_align
= interp
->sh_addralign
;
1870 /* if dynamic section, then add corresponing program header */
1874 ph
= &phdr
[phnum
- 1];
1876 ph
->p_type
= PT_DYNAMIC
;
1877 ph
->p_offset
= dynamic
->sh_offset
;
1878 ph
->p_vaddr
= dynamic
->sh_addr
;
1879 ph
->p_paddr
= ph
->p_vaddr
;
1880 ph
->p_filesz
= dynamic
->sh_size
;
1881 ph
->p_memsz
= dynamic
->sh_size
;
1882 ph
->p_flags
= PF_R
| PF_W
;
1883 ph
->p_align
= dynamic
->sh_addralign
;
1885 /* put GOT dynamic section address */
1886 put32(s1
->got
->data
, dynamic
->sh_addr
);
1888 /* relocate the PLT */
1889 if (file_type
== TCC_OUTPUT_EXE
1890 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1891 || file_type
== TCC_OUTPUT_DLL
1897 p_end
= p
+ s1
->plt
->data_offset
;
1899 #if defined(TCC_TARGET_I386)
1900 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1901 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1904 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1907 #elif defined(TCC_TARGET_X86_64)
1908 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1909 put32(p
+ 2, get32(p
+ 2) + x
);
1910 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1913 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1916 #elif defined(TCC_TARGET_ARM)
1918 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1921 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1924 #elif defined(TCC_TARGET_C67)
1927 #error unsupported CPU
1932 /* relocate symbols in .dynsym */
1933 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1934 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1937 if (sym
->st_shndx
== SHN_UNDEF
) {
1938 /* relocate to the PLT if the symbol corresponds
1941 sym
->st_value
+= s1
->plt
->sh_addr
;
1942 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1943 /* do symbol relocation */
1944 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1948 /* put dynamic section entries */
1949 dynamic
->data_offset
= saved_dynamic_data_offset
;
1950 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1951 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1952 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1953 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1954 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1955 #ifdef TCC_TARGET_X86_64
1956 put_dt(dynamic
, DT_RELA
, rel_addr
);
1957 put_dt(dynamic
, DT_RELASZ
, rel_size
);
1958 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1960 #if defined(__FreeBSD__)
1961 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
1962 put_dt(dynamic
, DT_PLTRELSZ
, rel_size
);
1963 put_dt(dynamic
, DT_JMPREL
, rel_addr
);
1964 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
1965 put_dt(dynamic
, DT_REL
, bss_addr
);
1966 put_dt(dynamic
, DT_RELSZ
, bss_size
);
1968 put_dt(dynamic
, DT_REL
, rel_addr
);
1969 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1970 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1974 put_dt(dynamic
, DT_DEBUG
, 0);
1975 put_dt(dynamic
, DT_NULL
, 0);
1978 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1979 ehdr
.e_phnum
= phnum
;
1980 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1983 /* all other sections come after */
1984 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1985 s
= s1
->sections
[i
];
1986 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1988 section_order
[sh_order_index
++] = i
;
1990 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1991 ~(s
->sh_addralign
- 1);
1992 s
->sh_offset
= file_offset
;
1993 if (s
->sh_type
!= SHT_NOBITS
)
1994 file_offset
+= s
->sh_size
;
1997 /* if building executable or DLL, then relocate each section
1998 except the GOT which is already relocated */
1999 if (file_type
!= TCC_OUTPUT_OBJ
) {
2000 relocate_syms(s1
, 0);
2002 if (s1
->nb_errors
!= 0) {
2008 /* relocate sections */
2009 /* XXX: ignore sections with allocated relocations ? */
2010 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2011 s
= s1
->sections
[i
];
2012 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
2013 relocate_section(s1
, s
);
2016 /* relocate relocation entries if the relocation tables are
2017 allocated in the executable */
2018 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2019 s
= s1
->sections
[i
];
2020 if ((s
->sh_flags
& SHF_ALLOC
) &&
2021 s
->sh_type
== SHT_RELX
) {
2022 relocate_rel(s1
, s
);
2026 /* get entry point address */
2027 if (file_type
== TCC_OUTPUT_EXE
)
2028 ehdr
.e_entry
= (uplong
)tcc_get_symbol_err(s1
, "_start");
2030 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
2032 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2035 /* write elf file */
2036 if (file_type
== TCC_OUTPUT_OBJ
)
2040 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2042 error_noabort("could not write '%s'", filename
);
2045 f
= fdopen(fd
, "wb");
2047 printf("<- %s\n", filename
);
2049 #ifdef TCC_TARGET_COFF
2050 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
2051 tcc_output_coff(s1
, f
);
2054 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
2055 sort_syms(s1
, symtab_section
);
2058 file_offset
= (file_offset
+ 3) & -4;
2061 ehdr
.e_ident
[0] = ELFMAG0
;
2062 ehdr
.e_ident
[1] = ELFMAG1
;
2063 ehdr
.e_ident
[2] = ELFMAG2
;
2064 ehdr
.e_ident
[3] = ELFMAG3
;
2065 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
2066 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2067 ehdr
.e_ident
[6] = EV_CURRENT
;
2069 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2071 #ifdef TCC_TARGET_ARM
2073 ehdr
.e_ident
[EI_OSABI
] = 0;
2074 ehdr
.e_flags
= 4 << 24;
2076 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2081 case TCC_OUTPUT_EXE
:
2082 ehdr
.e_type
= ET_EXEC
;
2084 case TCC_OUTPUT_DLL
:
2085 ehdr
.e_type
= ET_DYN
;
2087 case TCC_OUTPUT_OBJ
:
2088 ehdr
.e_type
= ET_REL
;
2091 ehdr
.e_machine
= EM_TCC_TARGET
;
2092 ehdr
.e_version
= EV_CURRENT
;
2093 ehdr
.e_shoff
= file_offset
;
2094 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2095 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2096 ehdr
.e_shnum
= shnum
;
2097 ehdr
.e_shstrndx
= shnum
- 1;
2099 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2100 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2101 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2103 for(i
=1;i
<s1
->nb_sections
;i
++) {
2104 s
= s1
->sections
[section_order
[i
]];
2105 if (s
->sh_type
!= SHT_NOBITS
) {
2106 #if defined(__FreeBSD__)
2107 if (s
->sh_type
== SHT_DYNSYM
)
2108 patch_dynsym_undef(s1
, s
);
2110 while (offset
< s
->sh_offset
) {
2115 fwrite(s
->data
, 1, size
, f
);
2120 /* output section headers */
2121 while (offset
< ehdr
.e_shoff
) {
2126 for(i
=0;i
<s1
->nb_sections
;i
++) {
2128 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2129 s
= s1
->sections
[i
];
2131 sh
->sh_name
= s
->sh_name
;
2132 sh
->sh_type
= s
->sh_type
;
2133 sh
->sh_flags
= s
->sh_flags
;
2134 sh
->sh_entsize
= s
->sh_entsize
;
2135 sh
->sh_info
= s
->sh_info
;
2137 sh
->sh_link
= s
->link
->sh_num
;
2138 sh
->sh_addralign
= s
->sh_addralign
;
2139 sh
->sh_addr
= s
->sh_addr
;
2140 sh
->sh_offset
= s
->sh_offset
;
2141 sh
->sh_size
= s
->sh_size
;
2143 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2146 tcc_output_binary(s1
, f
, section_order
);
2152 tcc_free(s1
->symtab_to_dynsym
);
2153 tcc_free(section_order
);
2155 tcc_free(s1
->got_offsets
);
2159 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2162 #ifdef TCC_TARGET_PE
2163 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2164 ret
= pe_output_file(s
, filename
);
2168 ret
= elf_output_file(s
, filename
);
2173 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2177 data
= tcc_malloc(size
);
2178 lseek(fd
, file_offset
, SEEK_SET
);
2179 read(fd
, data
, size
);
2183 typedef struct SectionMergeInfo
{
2184 Section
*s
; /* corresponding existing section */
2185 unsigned long offset
; /* offset of the new section in the existing section */
2186 uint8_t new_section
; /* true if section 's' was added */
2187 uint8_t link_once
; /* true if link once section */
2190 /* load an object file and merge it with current files */
2191 /* XXX: handle correctly stab (debug) info */
2192 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
2193 int fd
, unsigned long file_offset
)
2196 ElfW(Shdr
) *shdr
, *sh
;
2197 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2198 unsigned char *strsec
, *strtab
;
2199 int *old_to_new_syms
;
2200 char *sh_name
, *name
;
2201 SectionMergeInfo
*sm_table
, *sm
;
2202 ElfW(Sym
) *sym
, *symtab
;
2203 ElfW_Rel
*rel
, *rel_end
;
2209 stab_index
= stabstr_index
= 0;
2211 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2213 if (ehdr
.e_ident
[0] != ELFMAG0
||
2214 ehdr
.e_ident
[1] != ELFMAG1
||
2215 ehdr
.e_ident
[2] != ELFMAG2
||
2216 ehdr
.e_ident
[3] != ELFMAG3
)
2218 /* test if object file */
2219 if (ehdr
.e_type
!= ET_REL
)
2221 /* test CPU specific stuff */
2222 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2223 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2225 error_noabort("invalid object file");
2229 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2230 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2231 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2233 /* load section names */
2234 sh
= &shdr
[ehdr
.e_shstrndx
];
2235 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2237 /* load symtab and strtab */
2238 old_to_new_syms
= NULL
;
2242 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2244 if (sh
->sh_type
== SHT_SYMTAB
) {
2246 error_noabort("object must contain only one symtab");
2251 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2252 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2253 sm_table
[i
].s
= symtab_section
;
2255 /* now load strtab */
2256 sh
= &shdr
[sh
->sh_link
];
2257 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2261 /* now examine each section and try to merge its content with the
2263 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2264 /* no need to examine section name strtab */
2265 if (i
== ehdr
.e_shstrndx
)
2268 sh_name
= strsec
+ sh
->sh_name
;
2269 /* ignore sections types we do not handle */
2270 if (sh
->sh_type
!= SHT_PROGBITS
&&
2271 sh
->sh_type
!= SHT_RELX
&&
2273 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2275 sh
->sh_type
!= SHT_NOBITS
&&
2276 strcmp(sh_name
, ".stabstr")
2279 if (sh
->sh_addralign
< 1)
2280 sh
->sh_addralign
= 1;
2281 /* find corresponding section, if any */
2282 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2283 s
= s1
->sections
[j
];
2284 if (!strcmp(s
->name
, sh_name
)) {
2285 if (!strncmp(sh_name
, ".gnu.linkonce",
2286 sizeof(".gnu.linkonce") - 1)) {
2287 /* if a 'linkonce' section is already present, we
2288 do not add it again. It is a little tricky as
2289 symbols can still be defined in
2291 sm_table
[i
].link_once
= 1;
2298 /* not found: create new section */
2299 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2300 /* take as much info as possible from the section. sh_link and
2301 sh_info will be updated later */
2302 s
->sh_addralign
= sh
->sh_addralign
;
2303 s
->sh_entsize
= sh
->sh_entsize
;
2304 sm_table
[i
].new_section
= 1;
2306 if (sh
->sh_type
!= s
->sh_type
) {
2307 error_noabort("invalid section type");
2311 /* align start of section */
2312 offset
= s
->data_offset
;
2314 if (0 == strcmp(sh_name
, ".stab")) {
2318 if (0 == strcmp(sh_name
, ".stabstr")) {
2323 size
= sh
->sh_addralign
- 1;
2324 offset
= (offset
+ size
) & ~size
;
2325 if (sh
->sh_addralign
> s
->sh_addralign
)
2326 s
->sh_addralign
= sh
->sh_addralign
;
2327 s
->data_offset
= offset
;
2329 sm_table
[i
].offset
= offset
;
2331 /* concatenate sections */
2333 if (sh
->sh_type
!= SHT_NOBITS
) {
2335 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2336 ptr
= section_ptr_add(s
, size
);
2337 read(fd
, ptr
, size
);
2339 s
->data_offset
+= size
;
2344 /* //gr relocate stab strings */
2345 if (stab_index
&& stabstr_index
) {
2348 s
= sm_table
[stab_index
].s
;
2349 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2350 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2351 o
= sm_table
[stabstr_index
].offset
;
2353 a
->n_strx
+= o
, a
++;
2356 /* second short pass to update sh_link and sh_info fields of new
2358 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2360 if (!s
|| !sm_table
[i
].new_section
)
2363 if (sh
->sh_link
> 0)
2364 s
->link
= sm_table
[sh
->sh_link
].s
;
2365 if (sh
->sh_type
== SHT_RELX
) {
2366 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2367 /* update backward link */
2368 s1
->sections
[s
->sh_info
]->reloc
= s
;
2373 /* resolve symbols */
2374 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2377 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2378 if (sym
->st_shndx
!= SHN_UNDEF
&&
2379 sym
->st_shndx
< SHN_LORESERVE
) {
2380 sm
= &sm_table
[sym
->st_shndx
];
2381 if (sm
->link_once
) {
2382 /* if a symbol is in a link once section, we use the
2383 already defined symbol. It is very important to get
2384 correct relocations */
2385 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2386 name
= strtab
+ sym
->st_name
;
2387 sym_index
= find_elf_sym(symtab_section
, name
);
2389 old_to_new_syms
[i
] = sym_index
;
2393 /* if no corresponding section added, no need to add symbol */
2396 /* convert section number */
2397 sym
->st_shndx
= sm
->s
->sh_num
;
2399 sym
->st_value
+= sm
->offset
;
2402 name
= strtab
+ sym
->st_name
;
2403 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2404 sym
->st_info
, sym
->st_other
,
2405 sym
->st_shndx
, name
);
2406 old_to_new_syms
[i
] = sym_index
;
2409 /* third pass to patch relocation entries */
2410 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2415 offset
= sm_table
[i
].offset
;
2416 switch(s
->sh_type
) {
2418 /* take relocation offset information */
2419 offseti
= sm_table
[sh
->sh_info
].offset
;
2420 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2421 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2426 /* convert symbol index */
2427 type
= ELFW(R_TYPE
)(rel
->r_info
);
2428 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2429 /* NOTE: only one symtab assumed */
2430 if (sym_index
>= nb_syms
)
2432 sym_index
= old_to_new_syms
[sym_index
];
2433 /* ignore link_once in rel section. */
2434 if (!sym_index
&& !sm
->link_once
) {
2436 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2437 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2440 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2441 /* offset the relocation offset */
2442 rel
->r_offset
+= offseti
;
2454 tcc_free(old_to_new_syms
);
2461 typedef struct ArchiveHeader
{
2462 char ar_name
[16]; /* name of this member */
2463 char ar_date
[12]; /* file mtime */
2464 char ar_uid
[6]; /* owner uid; printed as decimal */
2465 char ar_gid
[6]; /* owner gid; printed as decimal */
2466 char ar_mode
[8]; /* file mode, printed as octal */
2467 char ar_size
[10]; /* file size, printed as decimal */
2468 char ar_fmag
[2]; /* should contain ARFMAG */
2471 static int get_be32(const uint8_t *b
)
2473 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2476 /* load only the objects which resolve undefined symbols */
2477 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2479 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2481 const char *ar_names
, *p
;
2482 const uint8_t *ar_index
;
2485 data
= tcc_malloc(size
);
2486 if (read(fd
, data
, size
) != size
)
2488 nsyms
= get_be32(data
);
2489 ar_index
= data
+ 4;
2490 ar_names
= ar_index
+ nsyms
* 4;
2494 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2495 sym_index
= find_elf_sym(symtab_section
, p
);
2497 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2498 if(sym
->st_shndx
== SHN_UNDEF
) {
2499 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2501 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2504 lseek(fd
, off
, SEEK_SET
);
2505 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2520 /* load a '.a' file */
2521 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
)
2528 unsigned long file_offset
;
2530 /* skip magic which was already checked */
2531 read(fd
, magic
, sizeof(magic
));
2534 len
= read(fd
, &hdr
, sizeof(hdr
));
2537 if (len
!= sizeof(hdr
)) {
2538 error_noabort("invalid archive");
2541 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2542 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2543 size
= strtol(ar_size
, NULL
, 0);
2544 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2545 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2546 if (ar_name
[i
] != ' ')
2549 ar_name
[i
+ 1] = '\0';
2550 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2551 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2553 size
= (size
+ 1) & ~1;
2554 if (!strcmp(ar_name
, "/")) {
2555 /* coff symbol table : we handle it */
2556 if(s1
->alacarte_link
)
2557 return tcc_load_alacarte(s1
, fd
, size
);
2558 } else if (!strcmp(ar_name
, "//") ||
2559 !strcmp(ar_name
, "__.SYMDEF") ||
2560 !strcmp(ar_name
, "__.SYMDEF/") ||
2561 !strcmp(ar_name
, "ARFILENAMES/")) {
2562 /* skip symbol table or archive names */
2564 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2567 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2572 #ifndef TCC_TARGET_PE
2573 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2574 is referenced by the user (so it should be added as DT_NEEDED in
2575 the generated ELF file) */
2576 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2579 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2580 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2581 ElfW(Sym
) *sym
, *dynsym
;
2582 ElfW(Dyn
) *dt
, *dynamic
;
2583 unsigned char *dynstr
;
2584 const char *name
, *soname
;
2585 DLLReference
*dllref
;
2587 read(fd
, &ehdr
, sizeof(ehdr
));
2589 /* test CPU specific stuff */
2590 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2591 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2592 error_noabort("bad architecture");
2597 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2599 /* load dynamic section and dynamic symbols */
2603 dynsym
= NULL
; /* avoid warning */
2604 dynstr
= NULL
; /* avoid warning */
2605 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2606 switch(sh
->sh_type
) {
2608 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2609 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2612 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2613 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2614 sh1
= &shdr
[sh
->sh_link
];
2615 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2622 /* compute the real library name */
2623 soname
= tcc_basename(filename
);
2625 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2626 if (dt
->d_tag
== DT_SONAME
) {
2627 soname
= dynstr
+ dt
->d_un
.d_val
;
2631 /* if the dll is already loaded, do not load it */
2632 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2633 dllref
= s1
->loaded_dlls
[i
];
2634 if (!strcmp(soname
, dllref
->name
)) {
2635 /* but update level if needed */
2636 if (level
< dllref
->level
)
2637 dllref
->level
= level
;
2643 // printf("loading dll '%s'\n", soname);
2645 /* add the dll and its level */
2646 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2647 dllref
->level
= level
;
2648 strcpy(dllref
->name
, soname
);
2649 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2651 /* add dynamic symbols in dynsym_section */
2652 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2653 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2654 if (sym_bind
== STB_LOCAL
)
2656 name
= dynstr
+ sym
->st_name
;
2657 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2658 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2661 /* load all referenced DLLs */
2662 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2665 name
= dynstr
+ dt
->d_un
.d_val
;
2666 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2667 dllref
= s1
->loaded_dlls
[j
];
2668 if (!strcmp(name
, dllref
->name
))
2669 goto already_loaded
;
2671 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2672 error_noabort("referenced dll '%s' not found", name
);
2689 #define LD_TOK_NAME 256
2690 #define LD_TOK_EOF (-1)
2692 /* return next ld script token */
2693 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2711 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2712 ch
= file
->buf_ptr
[0];
2720 /* case 'a' ... 'z': */
2747 /* case 'A' ... 'z': */
2782 if (!((ch
>= 'a' && ch
<= 'z') ||
2783 (ch
>= 'A' && ch
<= 'Z') ||
2784 (ch
>= '0' && ch
<= '9') ||
2785 strchr("/.-_+=$:\\,~", ch
)))
2787 if ((q
- name
) < name_size
- 1) {
2804 printf("tok=%c %d\n", c
, c
);
2805 if (c
== LD_TOK_NAME
)
2806 printf(" name=%s\n", name
);
2811 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2813 char filename
[1024];
2816 t
= ld_next(s1
, filename
, sizeof(filename
));
2819 t
= ld_next(s1
, filename
, sizeof(filename
));
2821 if (t
== LD_TOK_EOF
) {
2822 error_noabort("unexpected end of file");
2824 } else if (t
== ')') {
2826 } else if (t
!= LD_TOK_NAME
) {
2827 error_noabort("filename expected");
2830 if (!strcmp(filename
, "AS_NEEDED")) {
2831 ret
= ld_add_file_list(s1
, 1);
2835 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2837 tcc_add_file(s1
, filename
);
2839 t
= ld_next(s1
, filename
, sizeof(filename
));
2841 t
= ld_next(s1
, filename
, sizeof(filename
));
2847 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2849 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
)
2852 char filename
[1024];
2855 ch
= file
->buf_ptr
[0];
2858 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2859 if (t
== LD_TOK_EOF
)
2861 else if (t
!= LD_TOK_NAME
)
2863 if (!strcmp(cmd
, "INPUT") ||
2864 !strcmp(cmd
, "GROUP")) {
2865 ret
= ld_add_file_list(s1
, 0);
2868 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2869 !strcmp(cmd
, "TARGET")) {
2870 /* ignore some commands */
2871 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2875 t
= ld_next(s1
, filename
, sizeof(filename
));
2876 if (t
== LD_TOK_EOF
) {
2877 error_noabort("unexpected end of file");
2879 } else if (t
== ')') {