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 static const char elf_interp
[] = "/lib/ld-linux-x86-64.so.2";
1311 #elif defined(TCC_UCLIBC)
1312 static const char elf_interp
[] = "/lib/ld-uClibc.so.0";
1314 static const char elf_interp
[] = "/lib/ld-linux.so.2";
1317 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1318 const int *section_order
)
1321 int i
, offset
, size
;
1324 for(i
=1;i
<s1
->nb_sections
;i
++) {
1325 s
= s1
->sections
[section_order
[i
]];
1326 if (s
->sh_type
!= SHT_NOBITS
&&
1327 (s
->sh_flags
& SHF_ALLOC
)) {
1328 while (offset
< s
->sh_offset
) {
1333 fwrite(s
->data
, 1, size
, f
);
1339 #if defined(__FreeBSD__)
1341 #define EXTRA_RELITEMS 14
1343 /* move the relocation value from .dynsym to .got */
1344 void patch_dynsym_undef(TCCState
*s1
, Section
*s
)
1346 uint32_t *gotd
= (void *)s1
->got
->data
;
1347 ElfW(Sym
) *sym
, *sym_end
;
1349 gotd
+= 3; // dummy entries in .got
1350 /* relocate symbols in .dynsym */
1351 sym_end
= (ElfW(Sym
) *)(s
->data
+ s
->data_offset
);
1352 for (sym
= (ElfW(Sym
) *)s
->data
+ 1; sym
< sym_end
; sym
++) {
1353 if (sym
->st_shndx
== SHN_UNDEF
) {
1354 *gotd
++ = sym
->st_value
+ 6; // XXX 6 is magic ?
1361 #define EXTRA_RELITEMS 9
1364 /* output an ELF file */
1365 /* XXX: suppress unneeded sections */
1366 static int elf_output_file(TCCState
*s1
, const char *filename
)
1372 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1374 Section
*strsec
, *s
;
1375 ElfW(Shdr
) shdr
, *sh
;
1376 ElfW(Phdr
) *phdr
, *ph
;
1377 Section
*interp
, *dynamic
, *dynstr
;
1378 unsigned long saved_dynamic_data_offset
;
1380 int type
, file_type
;
1381 unsigned long rel_addr
, rel_size
;
1382 unsigned long bss_addr
, bss_size
;
1384 file_type
= s1
->output_type
;
1387 if (file_type
!= TCC_OUTPUT_OBJ
) {
1388 tcc_add_runtime(s1
);
1392 section_order
= NULL
;
1395 dynstr
= NULL
; /* avoid warning */
1396 saved_dynamic_data_offset
= 0; /* avoid warning */
1398 if (file_type
!= TCC_OUTPUT_OBJ
) {
1399 relocate_common_syms();
1401 tcc_add_linker_symbols(s1
);
1403 if (!s1
->static_link
) {
1405 int sym_index
, index
;
1406 ElfW(Sym
) *esym
, *sym_end
;
1408 if (file_type
== TCC_OUTPUT_EXE
) {
1410 /* allow override the dynamic loader */
1411 const char *elfint
= getenv("LD_SO");
1413 elfint
= elf_interp
;
1414 /* add interpreter section only if executable */
1415 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1416 interp
->sh_addralign
= 1;
1417 ptr
= section_ptr_add(interp
, 1+strlen(elfint
));
1418 strcpy(ptr
, elfint
);
1421 /* add dynamic symbol table */
1422 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1424 ".hash", SHF_ALLOC
);
1425 dynstr
= s1
->dynsym
->link
;
1427 /* add dynamic section */
1428 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1429 SHF_ALLOC
| SHF_WRITE
);
1430 dynamic
->link
= dynstr
;
1431 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1434 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1435 SHF_ALLOC
| SHF_EXECINSTR
);
1436 s1
->plt
->sh_entsize
= 4;
1440 /* scan for undefined symbols and see if they are in the
1441 dynamic symbols. If a symbol STT_FUNC is found, then we
1442 add it in the PLT. If a symbol STT_OBJECT is found, we
1443 add it in the .bss section with a suitable relocation */
1444 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1445 symtab_section
->data_offset
);
1446 if (file_type
== TCC_OUTPUT_EXE
) {
1447 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1450 if (sym
->st_shndx
== SHN_UNDEF
) {
1451 name
= symtab_section
->link
->data
+ sym
->st_name
;
1452 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1454 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1455 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1456 if (type
== STT_FUNC
) {
1457 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1459 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1460 } else if (type
== STT_OBJECT
) {
1461 unsigned long offset
;
1462 offset
= bss_section
->data_offset
;
1463 /* XXX: which alignment ? */
1464 offset
= (offset
+ 16 - 1) & -16;
1465 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1467 bss_section
->sh_num
, name
);
1468 put_elf_reloc(s1
->dynsym
, bss_section
,
1469 offset
, R_COPY
, index
);
1470 offset
+= esym
->st_size
;
1471 bss_section
->data_offset
= offset
;
1474 /* STB_WEAK undefined symbols are accepted */
1475 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1477 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1478 !strcmp(name
, "_fp_hw")) {
1480 error_noabort("undefined symbol '%s'", name
);
1483 } else if (s1
->rdynamic
&&
1484 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1485 /* if -rdynamic option, then export all non
1487 name
= symtab_section
->link
->data
+ sym
->st_name
;
1488 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1490 sym
->st_shndx
, name
);
1497 /* now look at unresolved dynamic symbols and export
1498 corresponding symbol */
1499 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1500 s1
->dynsymtab_section
->data_offset
);
1501 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1504 if (esym
->st_shndx
== SHN_UNDEF
) {
1505 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1506 sym_index
= find_elf_sym(symtab_section
, name
);
1508 /* XXX: avoid adding a symbol if already
1509 present because of -rdynamic ? */
1510 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1511 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1513 sym
->st_shndx
, name
);
1515 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1516 /* weak symbols can stay undefined */
1518 warning("undefined dynamic symbol '%s'", name
);
1525 /* shared library case : we simply export all the global symbols */
1526 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1527 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1528 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1531 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1532 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1533 if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
&&
1534 sym
->st_shndx
== SHN_UNDEF
) {
1535 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1537 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1539 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1540 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1542 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1547 name
= symtab_section
->link
->data
+ sym
->st_name
;
1548 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1550 sym
->st_shndx
, name
);
1551 s1
->symtab_to_dynsym
[sym
-
1552 (ElfW(Sym
) *)symtab_section
->data
] =
1559 build_got_entries(s1
);
1561 /* add a list of needed dlls */
1562 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1563 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1564 if (dllref
->level
== 0)
1565 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1569 put_dt(dynamic
, DT_RPATH
, put_elf_str(dynstr
, s1
->rpath
));
1571 /* XXX: currently, since we do not handle PIC code, we
1572 must relocate the readonly segments */
1573 if (file_type
== TCC_OUTPUT_DLL
) {
1575 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1576 put_dt(dynamic
, DT_TEXTREL
, 0);
1580 put_dt(dynamic
, DT_SYMBOLIC
, 0);
1582 /* add necessary space for other entries */
1583 saved_dynamic_data_offset
= dynamic
->data_offset
;
1584 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * EXTRA_RELITEMS
;
1586 /* still need to build got entries in case of static link */
1587 build_got_entries(s1
);
1591 memset(&ehdr
, 0, sizeof(ehdr
));
1593 /* we add a section for symbols */
1594 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1595 put_elf_str(strsec
, "");
1597 /* compute number of sections */
1598 shnum
= s1
->nb_sections
;
1600 /* this array is used to reorder sections in the output file */
1601 section_order
= tcc_malloc(sizeof(int) * shnum
);
1602 section_order
[0] = 0;
1605 /* compute number of program headers */
1608 case TCC_OUTPUT_OBJ
:
1611 case TCC_OUTPUT_EXE
:
1612 if (!s1
->static_link
)
1613 phnum
= 4 + HAVE_PHDR
;
1617 case TCC_OUTPUT_DLL
:
1622 /* allocate strings for section names and decide if an unallocated
1623 section should be output */
1624 /* NOTE: the strsec section comes last, so its size is also
1626 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1627 s
= s1
->sections
[i
];
1628 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1630 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1635 s
->reloc
? s
->reloc
->name
: "n"
1638 /* when generating a DLL, we include relocations but we may
1640 if (file_type
== TCC_OUTPUT_DLL
&&
1641 s
->sh_type
== SHT_RELX
&&
1642 !(s
->sh_flags
& SHF_ALLOC
)) {
1643 /* //gr: avoid bogus relocs for empty (debug) sections */
1644 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1645 prepare_dynamic_rel(s1
, s
);
1646 else if (s1
->do_debug
)
1647 s
->sh_size
= s
->data_offset
;
1648 } else if (s1
->do_debug
||
1649 file_type
== TCC_OUTPUT_OBJ
||
1650 (s
->sh_flags
& SHF_ALLOC
) ||
1651 i
== (s1
->nb_sections
- 1)) {
1652 /* we output all sections if debug or object file */
1653 s
->sh_size
= s
->data_offset
;
1657 /* allocate program segment headers */
1658 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1660 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1661 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1666 /* compute section to program header mapping */
1667 if (s1
->has_text_addr
) {
1668 int a_offset
, p_offset
;
1669 addr
= s1
->text_addr
;
1670 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1672 a_offset
= addr
& (s1
->section_align
- 1);
1673 p_offset
= file_offset
& (s1
->section_align
- 1);
1674 if (a_offset
< p_offset
)
1675 a_offset
+= s1
->section_align
;
1676 file_offset
+= (a_offset
- p_offset
);
1678 if (file_type
== TCC_OUTPUT_DLL
)
1681 addr
= ELF_START_ADDR
;
1682 /* compute address after headers */
1683 addr
+= (file_offset
& (s1
->section_align
- 1));
1686 /* dynamic relocation table information, for .dynamic section */
1690 bss_addr
= bss_size
= 0;
1691 /* leave one program header for the program interpreter */
1694 ph
+= 1 + HAVE_PHDR
;
1696 for(j
= 0; j
< 2; j
++) {
1697 ph
->p_type
= PT_LOAD
;
1699 ph
->p_flags
= PF_R
| PF_X
;
1701 ph
->p_flags
= PF_R
| PF_W
;
1702 ph
->p_align
= s1
->section_align
;
1704 /* we do the following ordering: interp, symbol tables,
1705 relocations, progbits, nobits */
1706 /* XXX: do faster and simpler sorting */
1707 for(k
= 0; k
< 5; k
++) {
1708 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1709 s
= s1
->sections
[i
];
1710 /* compute if section should be included */
1712 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1716 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1717 (SHF_ALLOC
| SHF_WRITE
))
1723 } else if (s
->sh_type
== SHT_DYNSYM
||
1724 s
->sh_type
== SHT_STRTAB
||
1725 s
->sh_type
== SHT_HASH
) {
1728 } else if (s
->sh_type
== SHT_RELX
) {
1731 } else if (s
->sh_type
== SHT_NOBITS
) {
1738 section_order
[sh_order_index
++] = i
;
1740 /* section matches: we align it and add its size */
1742 addr
= (addr
+ s
->sh_addralign
- 1) &
1743 ~(s
->sh_addralign
- 1);
1744 file_offset
+= addr
- tmp
;
1745 s
->sh_offset
= file_offset
;
1748 /* update program header infos */
1749 if (ph
->p_offset
== 0) {
1750 ph
->p_offset
= file_offset
;
1752 ph
->p_paddr
= ph
->p_vaddr
;
1754 /* update dynamic relocation infos */
1755 if (s
->sh_type
== SHT_RELX
) {
1756 #if defined(__FreeBSD__)
1757 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.got")) { // rel_size == 0) {
1759 rel_size
+= s
->sh_size
; // XXX only first rel.
1761 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.bss")) { // rel_size == 0) {
1763 bss_size
= s
->sh_size
; // XXX only first rel.
1768 rel_size
+= s
->sh_size
;
1772 if (s
->sh_type
!= SHT_NOBITS
)
1773 file_offset
+= s
->sh_size
;
1776 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1777 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1780 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1781 /* if in the middle of a page, we duplicate the page in
1782 memory so that one copy is RX and the other is RW */
1783 if ((addr
& (s1
->section_align
- 1)) != 0)
1784 addr
+= s1
->section_align
;
1786 addr
= (addr
+ s1
->section_align
- 1) & ~(s1
->section_align
- 1);
1787 file_offset
= (file_offset
+ s1
->section_align
- 1) &
1788 ~(s1
->section_align
- 1);
1793 /* if interpreter, then add corresponing program header */
1797 #if defined(__FreeBSD__)
1799 int len
= phnum
* sizeof(ElfW(Phdr
));
1801 ph
->p_type
= PT_PHDR
;
1802 ph
->p_offset
= sizeof(ElfW(Ehdr
));
1803 ph
->p_vaddr
= interp
->sh_addr
- len
;
1804 ph
->p_paddr
= ph
->p_vaddr
;
1805 ph
->p_filesz
= ph
->p_memsz
= len
;
1806 ph
->p_flags
= PF_R
| PF_X
;
1807 ph
->p_align
= 4; // interp->sh_addralign;
1812 ph
->p_type
= PT_INTERP
;
1813 ph
->p_offset
= interp
->sh_offset
;
1814 ph
->p_vaddr
= interp
->sh_addr
;
1815 ph
->p_paddr
= ph
->p_vaddr
;
1816 ph
->p_filesz
= interp
->sh_size
;
1817 ph
->p_memsz
= interp
->sh_size
;
1819 ph
->p_align
= interp
->sh_addralign
;
1822 /* if dynamic section, then add corresponing program header */
1826 ph
= &phdr
[phnum
- 1];
1828 ph
->p_type
= PT_DYNAMIC
;
1829 ph
->p_offset
= dynamic
->sh_offset
;
1830 ph
->p_vaddr
= dynamic
->sh_addr
;
1831 ph
->p_paddr
= ph
->p_vaddr
;
1832 ph
->p_filesz
= dynamic
->sh_size
;
1833 ph
->p_memsz
= dynamic
->sh_size
;
1834 ph
->p_flags
= PF_R
| PF_W
;
1835 ph
->p_align
= dynamic
->sh_addralign
;
1837 /* put GOT dynamic section address */
1838 put32(s1
->got
->data
, dynamic
->sh_addr
);
1840 /* relocate the PLT */
1841 if (file_type
== TCC_OUTPUT_EXE
1842 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1843 || file_type
== TCC_OUTPUT_DLL
1849 p_end
= p
+ s1
->plt
->data_offset
;
1851 #if defined(TCC_TARGET_I386)
1852 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1853 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1856 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1859 #elif defined(TCC_TARGET_X86_64)
1860 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1861 put32(p
+ 2, get32(p
+ 2) + x
);
1862 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1865 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1868 #elif defined(TCC_TARGET_ARM)
1870 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1873 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1876 #elif defined(TCC_TARGET_C67)
1879 #error unsupported CPU
1884 /* relocate symbols in .dynsym */
1885 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1886 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1889 if (sym
->st_shndx
== SHN_UNDEF
) {
1890 /* relocate to the PLT if the symbol corresponds
1893 sym
->st_value
+= s1
->plt
->sh_addr
;
1894 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1895 /* do symbol relocation */
1896 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1900 /* put dynamic section entries */
1901 dynamic
->data_offset
= saved_dynamic_data_offset
;
1902 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1903 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1904 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1905 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1906 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1907 #ifdef TCC_TARGET_X86_64
1908 put_dt(dynamic
, DT_RELA
, rel_addr
);
1909 put_dt(dynamic
, DT_RELASZ
, rel_size
);
1910 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1912 #if defined(__FreeBSD__)
1913 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
1914 put_dt(dynamic
, DT_PLTRELSZ
, rel_size
);
1915 put_dt(dynamic
, DT_JMPREL
, rel_addr
);
1916 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
1917 put_dt(dynamic
, DT_REL
, bss_addr
);
1918 put_dt(dynamic
, DT_RELSZ
, bss_size
);
1920 put_dt(dynamic
, DT_REL
, rel_addr
);
1921 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1922 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1926 put_dt(dynamic
, DT_DEBUG
, 0);
1927 put_dt(dynamic
, DT_NULL
, 0);
1930 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1931 ehdr
.e_phnum
= phnum
;
1932 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1935 /* all other sections come after */
1936 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1937 s
= s1
->sections
[i
];
1938 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1940 section_order
[sh_order_index
++] = i
;
1942 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1943 ~(s
->sh_addralign
- 1);
1944 s
->sh_offset
= file_offset
;
1945 if (s
->sh_type
!= SHT_NOBITS
)
1946 file_offset
+= s
->sh_size
;
1949 /* if building executable or DLL, then relocate each section
1950 except the GOT which is already relocated */
1951 if (file_type
!= TCC_OUTPUT_OBJ
) {
1952 relocate_syms(s1
, 0);
1954 if (s1
->nb_errors
!= 0) {
1960 /* relocate sections */
1961 /* XXX: ignore sections with allocated relocations ? */
1962 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1963 s
= s1
->sections
[i
];
1964 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1965 relocate_section(s1
, s
);
1968 /* relocate relocation entries if the relocation tables are
1969 allocated in the executable */
1970 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1971 s
= s1
->sections
[i
];
1972 if ((s
->sh_flags
& SHF_ALLOC
) &&
1973 s
->sh_type
== SHT_RELX
) {
1974 relocate_rel(s1
, s
);
1978 /* get entry point address */
1979 if (file_type
== TCC_OUTPUT_EXE
)
1980 ehdr
.e_entry
= (uplong
)tcc_get_symbol_err(s1
, "_start");
1982 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1985 /* write elf file */
1986 if (file_type
== TCC_OUTPUT_OBJ
)
1990 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1992 error_noabort("could not write '%s'", filename
);
1995 f
= fdopen(fd
, "wb");
1997 printf("<- %s\n", filename
);
1999 #ifdef TCC_TARGET_COFF
2000 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
2001 tcc_output_coff(s1
, f
);
2004 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
2005 sort_syms(s1
, symtab_section
);
2008 file_offset
= (file_offset
+ 3) & -4;
2011 ehdr
.e_ident
[0] = ELFMAG0
;
2012 ehdr
.e_ident
[1] = ELFMAG1
;
2013 ehdr
.e_ident
[2] = ELFMAG2
;
2014 ehdr
.e_ident
[3] = ELFMAG3
;
2015 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
2016 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2017 ehdr
.e_ident
[6] = EV_CURRENT
;
2019 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2021 #ifdef TCC_TARGET_ARM
2023 ehdr
.e_ident
[EI_OSABI
] = 0;
2024 ehdr
.e_flags
= 4 << 24;
2026 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2031 case TCC_OUTPUT_EXE
:
2032 ehdr
.e_type
= ET_EXEC
;
2034 case TCC_OUTPUT_DLL
:
2035 ehdr
.e_type
= ET_DYN
;
2037 case TCC_OUTPUT_OBJ
:
2038 ehdr
.e_type
= ET_REL
;
2041 ehdr
.e_machine
= EM_TCC_TARGET
;
2042 ehdr
.e_version
= EV_CURRENT
;
2043 ehdr
.e_shoff
= file_offset
;
2044 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2045 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2046 ehdr
.e_shnum
= shnum
;
2047 ehdr
.e_shstrndx
= shnum
- 1;
2049 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2050 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2051 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2053 for(i
=1;i
<s1
->nb_sections
;i
++) {
2054 s
= s1
->sections
[section_order
[i
]];
2055 if (s
->sh_type
!= SHT_NOBITS
) {
2056 #if defined(__FreeBSD__)
2057 if (s
->sh_type
== SHT_DYNSYM
)
2058 patch_dynsym_undef(s1
, s
);
2060 while (offset
< s
->sh_offset
) {
2065 fwrite(s
->data
, 1, size
, f
);
2070 /* output section headers */
2071 while (offset
< ehdr
.e_shoff
) {
2076 for(i
=0;i
<s1
->nb_sections
;i
++) {
2078 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2079 s
= s1
->sections
[i
];
2081 sh
->sh_name
= s
->sh_name
;
2082 sh
->sh_type
= s
->sh_type
;
2083 sh
->sh_flags
= s
->sh_flags
;
2084 sh
->sh_entsize
= s
->sh_entsize
;
2085 sh
->sh_info
= s
->sh_info
;
2087 sh
->sh_link
= s
->link
->sh_num
;
2088 sh
->sh_addralign
= s
->sh_addralign
;
2089 sh
->sh_addr
= s
->sh_addr
;
2090 sh
->sh_offset
= s
->sh_offset
;
2091 sh
->sh_size
= s
->sh_size
;
2093 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2096 tcc_output_binary(s1
, f
, section_order
);
2102 tcc_free(s1
->symtab_to_dynsym
);
2103 tcc_free(section_order
);
2105 tcc_free(s1
->got_offsets
);
2109 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2112 #ifdef TCC_TARGET_PE
2113 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2114 ret
= pe_output_file(s
, filename
);
2118 ret
= elf_output_file(s
, filename
);
2123 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2127 data
= tcc_malloc(size
);
2128 lseek(fd
, file_offset
, SEEK_SET
);
2129 read(fd
, data
, size
);
2133 typedef struct SectionMergeInfo
{
2134 Section
*s
; /* corresponding existing section */
2135 unsigned long offset
; /* offset of the new section in the existing section */
2136 uint8_t new_section
; /* true if section 's' was added */
2137 uint8_t link_once
; /* true if link once section */
2140 /* load an object file and merge it with current files */
2141 /* XXX: handle correctly stab (debug) info */
2142 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
2143 int fd
, unsigned long file_offset
)
2146 ElfW(Shdr
) *shdr
, *sh
;
2147 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2148 unsigned char *strsec
, *strtab
;
2149 int *old_to_new_syms
;
2150 char *sh_name
, *name
;
2151 SectionMergeInfo
*sm_table
, *sm
;
2152 ElfW(Sym
) *sym
, *symtab
;
2153 ElfW_Rel
*rel
, *rel_end
;
2159 stab_index
= stabstr_index
= 0;
2161 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2163 if (ehdr
.e_ident
[0] != ELFMAG0
||
2164 ehdr
.e_ident
[1] != ELFMAG1
||
2165 ehdr
.e_ident
[2] != ELFMAG2
||
2166 ehdr
.e_ident
[3] != ELFMAG3
)
2168 /* test if object file */
2169 if (ehdr
.e_type
!= ET_REL
)
2171 /* test CPU specific stuff */
2172 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2173 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2175 error_noabort("invalid object file");
2179 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2180 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2181 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2183 /* load section names */
2184 sh
= &shdr
[ehdr
.e_shstrndx
];
2185 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2187 /* load symtab and strtab */
2188 old_to_new_syms
= NULL
;
2192 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2194 if (sh
->sh_type
== SHT_SYMTAB
) {
2196 error_noabort("object must contain only one symtab");
2201 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2202 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2203 sm_table
[i
].s
= symtab_section
;
2205 /* now load strtab */
2206 sh
= &shdr
[sh
->sh_link
];
2207 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2211 /* now examine each section and try to merge its content with the
2213 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2214 /* no need to examine section name strtab */
2215 if (i
== ehdr
.e_shstrndx
)
2218 sh_name
= strsec
+ sh
->sh_name
;
2219 /* ignore sections types we do not handle */
2220 if (sh
->sh_type
!= SHT_PROGBITS
&&
2221 sh
->sh_type
!= SHT_RELX
&&
2223 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2225 sh
->sh_type
!= SHT_NOBITS
&&
2226 strcmp(sh_name
, ".stabstr")
2229 if (sh
->sh_addralign
< 1)
2230 sh
->sh_addralign
= 1;
2231 /* find corresponding section, if any */
2232 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2233 s
= s1
->sections
[j
];
2234 if (!strcmp(s
->name
, sh_name
)) {
2235 if (!strncmp(sh_name
, ".gnu.linkonce",
2236 sizeof(".gnu.linkonce") - 1)) {
2237 /* if a 'linkonce' section is already present, we
2238 do not add it again. It is a little tricky as
2239 symbols can still be defined in
2241 sm_table
[i
].link_once
= 1;
2248 /* not found: create new section */
2249 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2250 /* take as much info as possible from the section. sh_link and
2251 sh_info will be updated later */
2252 s
->sh_addralign
= sh
->sh_addralign
;
2253 s
->sh_entsize
= sh
->sh_entsize
;
2254 sm_table
[i
].new_section
= 1;
2256 if (sh
->sh_type
!= s
->sh_type
) {
2257 error_noabort("invalid section type");
2261 /* align start of section */
2262 offset
= s
->data_offset
;
2264 if (0 == strcmp(sh_name
, ".stab")) {
2268 if (0 == strcmp(sh_name
, ".stabstr")) {
2273 size
= sh
->sh_addralign
- 1;
2274 offset
= (offset
+ size
) & ~size
;
2275 if (sh
->sh_addralign
> s
->sh_addralign
)
2276 s
->sh_addralign
= sh
->sh_addralign
;
2277 s
->data_offset
= offset
;
2279 sm_table
[i
].offset
= offset
;
2281 /* concatenate sections */
2283 if (sh
->sh_type
!= SHT_NOBITS
) {
2285 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2286 ptr
= section_ptr_add(s
, size
);
2287 read(fd
, ptr
, size
);
2289 s
->data_offset
+= size
;
2294 /* //gr relocate stab strings */
2295 if (stab_index
&& stabstr_index
) {
2298 s
= sm_table
[stab_index
].s
;
2299 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2300 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2301 o
= sm_table
[stabstr_index
].offset
;
2303 a
->n_strx
+= o
, a
++;
2306 /* second short pass to update sh_link and sh_info fields of new
2308 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2310 if (!s
|| !sm_table
[i
].new_section
)
2313 if (sh
->sh_link
> 0)
2314 s
->link
= sm_table
[sh
->sh_link
].s
;
2315 if (sh
->sh_type
== SHT_RELX
) {
2316 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2317 /* update backward link */
2318 s1
->sections
[s
->sh_info
]->reloc
= s
;
2323 /* resolve symbols */
2324 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2327 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2328 if (sym
->st_shndx
!= SHN_UNDEF
&&
2329 sym
->st_shndx
< SHN_LORESERVE
) {
2330 sm
= &sm_table
[sym
->st_shndx
];
2331 if (sm
->link_once
) {
2332 /* if a symbol is in a link once section, we use the
2333 already defined symbol. It is very important to get
2334 correct relocations */
2335 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2336 name
= strtab
+ sym
->st_name
;
2337 sym_index
= find_elf_sym(symtab_section
, name
);
2339 old_to_new_syms
[i
] = sym_index
;
2343 /* if no corresponding section added, no need to add symbol */
2346 /* convert section number */
2347 sym
->st_shndx
= sm
->s
->sh_num
;
2349 sym
->st_value
+= sm
->offset
;
2352 name
= strtab
+ sym
->st_name
;
2353 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2354 sym
->st_info
, sym
->st_other
,
2355 sym
->st_shndx
, name
);
2356 old_to_new_syms
[i
] = sym_index
;
2359 /* third pass to patch relocation entries */
2360 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2365 offset
= sm_table
[i
].offset
;
2366 switch(s
->sh_type
) {
2368 /* take relocation offset information */
2369 offseti
= sm_table
[sh
->sh_info
].offset
;
2370 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2371 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2376 /* convert symbol index */
2377 type
= ELFW(R_TYPE
)(rel
->r_info
);
2378 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2379 /* NOTE: only one symtab assumed */
2380 if (sym_index
>= nb_syms
)
2382 sym_index
= old_to_new_syms
[sym_index
];
2383 /* ignore link_once in rel section. */
2384 if (!sym_index
&& !sm
->link_once
) {
2386 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2387 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2390 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2391 /* offset the relocation offset */
2392 rel
->r_offset
+= offseti
;
2404 tcc_free(old_to_new_syms
);
2411 typedef struct ArchiveHeader
{
2412 char ar_name
[16]; /* name of this member */
2413 char ar_date
[12]; /* file mtime */
2414 char ar_uid
[6]; /* owner uid; printed as decimal */
2415 char ar_gid
[6]; /* owner gid; printed as decimal */
2416 char ar_mode
[8]; /* file mode, printed as octal */
2417 char ar_size
[10]; /* file size, printed as decimal */
2418 char ar_fmag
[2]; /* should contain ARFMAG */
2421 static int get_be32(const uint8_t *b
)
2423 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2426 /* load only the objects which resolve undefined symbols */
2427 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2429 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2431 const char *ar_names
, *p
;
2432 const uint8_t *ar_index
;
2435 data
= tcc_malloc(size
);
2436 if (read(fd
, data
, size
) != size
)
2438 nsyms
= get_be32(data
);
2439 ar_index
= data
+ 4;
2440 ar_names
= ar_index
+ nsyms
* 4;
2444 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2445 sym_index
= find_elf_sym(symtab_section
, p
);
2447 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2448 if(sym
->st_shndx
== SHN_UNDEF
) {
2449 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2451 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2454 lseek(fd
, off
, SEEK_SET
);
2455 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2470 /* load a '.a' file */
2471 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
)
2478 unsigned long file_offset
;
2480 /* skip magic which was already checked */
2481 read(fd
, magic
, sizeof(magic
));
2484 len
= read(fd
, &hdr
, sizeof(hdr
));
2487 if (len
!= sizeof(hdr
)) {
2488 error_noabort("invalid archive");
2491 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2492 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2493 size
= strtol(ar_size
, NULL
, 0);
2494 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2495 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2496 if (ar_name
[i
] != ' ')
2499 ar_name
[i
+ 1] = '\0';
2500 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2501 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2503 size
= (size
+ 1) & ~1;
2504 if (!strcmp(ar_name
, "/")) {
2505 /* coff symbol table : we handle it */
2506 if(s1
->alacarte_link
)
2507 return tcc_load_alacarte(s1
, fd
, size
);
2508 } else if (!strcmp(ar_name
, "//") ||
2509 !strcmp(ar_name
, "__.SYMDEF") ||
2510 !strcmp(ar_name
, "__.SYMDEF/") ||
2511 !strcmp(ar_name
, "ARFILENAMES/")) {
2512 /* skip symbol table or archive names */
2514 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2517 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2522 #ifndef TCC_TARGET_PE
2523 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2524 is referenced by the user (so it should be added as DT_NEEDED in
2525 the generated ELF file) */
2526 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2529 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2530 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2531 ElfW(Sym
) *sym
, *dynsym
;
2532 ElfW(Dyn
) *dt
, *dynamic
;
2533 unsigned char *dynstr
;
2534 const char *name
, *soname
;
2535 DLLReference
*dllref
;
2537 read(fd
, &ehdr
, sizeof(ehdr
));
2539 /* test CPU specific stuff */
2540 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2541 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2542 error_noabort("bad architecture");
2547 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2549 /* load dynamic section and dynamic symbols */
2553 dynsym
= NULL
; /* avoid warning */
2554 dynstr
= NULL
; /* avoid warning */
2555 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2556 switch(sh
->sh_type
) {
2558 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2559 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2562 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2563 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2564 sh1
= &shdr
[sh
->sh_link
];
2565 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2572 /* compute the real library name */
2573 soname
= tcc_basename(filename
);
2575 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2576 if (dt
->d_tag
== DT_SONAME
) {
2577 soname
= dynstr
+ dt
->d_un
.d_val
;
2581 /* if the dll is already loaded, do not load it */
2582 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2583 dllref
= s1
->loaded_dlls
[i
];
2584 if (!strcmp(soname
, dllref
->name
)) {
2585 /* but update level if needed */
2586 if (level
< dllref
->level
)
2587 dllref
->level
= level
;
2593 // printf("loading dll '%s'\n", soname);
2595 /* add the dll and its level */
2596 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2597 dllref
->level
= level
;
2598 strcpy(dllref
->name
, soname
);
2599 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2601 /* add dynamic symbols in dynsym_section */
2602 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2603 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2604 if (sym_bind
== STB_LOCAL
)
2606 name
= dynstr
+ sym
->st_name
;
2607 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2608 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2611 /* load all referenced DLLs */
2612 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2615 name
= dynstr
+ dt
->d_un
.d_val
;
2616 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2617 dllref
= s1
->loaded_dlls
[j
];
2618 if (!strcmp(name
, dllref
->name
))
2619 goto already_loaded
;
2621 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2622 error_noabort("referenced dll '%s' not found", name
);
2639 #define LD_TOK_NAME 256
2640 #define LD_TOK_EOF (-1)
2642 /* return next ld script token */
2643 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2661 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2662 ch
= file
->buf_ptr
[0];
2670 /* case 'a' ... 'z': */
2697 /* case 'A' ... 'z': */
2732 if (!((ch
>= 'a' && ch
<= 'z') ||
2733 (ch
>= 'A' && ch
<= 'Z') ||
2734 (ch
>= '0' && ch
<= '9') ||
2735 strchr("/.-_+=$:\\,~", ch
)))
2737 if ((q
- name
) < name_size
- 1) {
2754 printf("tok=%c %d\n", c
, c
);
2755 if (c
== LD_TOK_NAME
)
2756 printf(" name=%s\n", name
);
2761 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2763 char filename
[1024];
2766 t
= ld_next(s1
, filename
, sizeof(filename
));
2769 t
= ld_next(s1
, filename
, sizeof(filename
));
2771 if (t
== LD_TOK_EOF
) {
2772 error_noabort("unexpected end of file");
2774 } else if (t
== ')') {
2776 } else if (t
!= LD_TOK_NAME
) {
2777 error_noabort("filename expected");
2780 if (!strcmp(filename
, "AS_NEEDED")) {
2781 ret
= ld_add_file_list(s1
, 1);
2785 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2787 tcc_add_file(s1
, filename
);
2789 t
= ld_next(s1
, filename
, sizeof(filename
));
2791 t
= ld_next(s1
, filename
, sizeof(filename
));
2797 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2799 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
)
2802 char filename
[1024];
2805 ch
= file
->buf_ptr
[0];
2808 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2809 if (t
== LD_TOK_EOF
)
2811 else if (t
!= LD_TOK_NAME
)
2813 if (!strcmp(cmd
, "INPUT") ||
2814 !strcmp(cmd
, "GROUP")) {
2815 ret
= ld_add_file_list(s1
, 0);
2818 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2819 !strcmp(cmd
, "TARGET")) {
2820 /* ignore some commands */
2821 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2825 t
= ld_next(s1
, filename
, sizeof(filename
));
2826 if (t
== LD_TOK_EOF
) {
2827 error_noabort("unexpected end of file");
2829 } else if (t
== ')') {