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);
1578 /* add necessary space for other entries */
1579 saved_dynamic_data_offset
= dynamic
->data_offset
;
1580 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * EXTRA_RELITEMS
;
1582 /* still need to build got entries in case of static link */
1583 build_got_entries(s1
);
1587 memset(&ehdr
, 0, sizeof(ehdr
));
1589 /* we add a section for symbols */
1590 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1591 put_elf_str(strsec
, "");
1593 /* compute number of sections */
1594 shnum
= s1
->nb_sections
;
1596 /* this array is used to reorder sections in the output file */
1597 section_order
= tcc_malloc(sizeof(int) * shnum
);
1598 section_order
[0] = 0;
1601 /* compute number of program headers */
1604 case TCC_OUTPUT_OBJ
:
1607 case TCC_OUTPUT_EXE
:
1608 if (!s1
->static_link
)
1609 phnum
= 4 + HAVE_PHDR
;
1613 case TCC_OUTPUT_DLL
:
1618 /* allocate strings for section names and decide if an unallocated
1619 section should be output */
1620 /* NOTE: the strsec section comes last, so its size is also
1622 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1623 s
= s1
->sections
[i
];
1624 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1626 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1631 s
->reloc
? s
->reloc
->name
: "n"
1634 /* when generating a DLL, we include relocations but we may
1636 if (file_type
== TCC_OUTPUT_DLL
&&
1637 s
->sh_type
== SHT_RELX
&&
1638 !(s
->sh_flags
& SHF_ALLOC
)) {
1639 /* //gr: avoid bogus relocs for empty (debug) sections */
1640 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1641 prepare_dynamic_rel(s1
, s
);
1642 else if (s1
->do_debug
)
1643 s
->sh_size
= s
->data_offset
;
1644 } else if (s1
->do_debug
||
1645 file_type
== TCC_OUTPUT_OBJ
||
1646 (s
->sh_flags
& SHF_ALLOC
) ||
1647 i
== (s1
->nb_sections
- 1)) {
1648 /* we output all sections if debug or object file */
1649 s
->sh_size
= s
->data_offset
;
1653 /* allocate program segment headers */
1654 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1656 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1657 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1662 /* compute section to program header mapping */
1663 if (s1
->has_text_addr
) {
1664 int a_offset
, p_offset
;
1665 addr
= s1
->text_addr
;
1666 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1668 a_offset
= addr
& (s1
->section_align
- 1);
1669 p_offset
= file_offset
& (s1
->section_align
- 1);
1670 if (a_offset
< p_offset
)
1671 a_offset
+= s1
->section_align
;
1672 file_offset
+= (a_offset
- p_offset
);
1674 if (file_type
== TCC_OUTPUT_DLL
)
1677 addr
= ELF_START_ADDR
;
1678 /* compute address after headers */
1679 addr
+= (file_offset
& (s1
->section_align
- 1));
1682 /* dynamic relocation table information, for .dynamic section */
1686 bss_addr
= bss_size
= 0;
1687 /* leave one program header for the program interpreter */
1690 ph
+= 1 + HAVE_PHDR
;
1692 for(j
= 0; j
< 2; j
++) {
1693 ph
->p_type
= PT_LOAD
;
1695 ph
->p_flags
= PF_R
| PF_X
;
1697 ph
->p_flags
= PF_R
| PF_W
;
1698 ph
->p_align
= s1
->section_align
;
1700 /* we do the following ordering: interp, symbol tables,
1701 relocations, progbits, nobits */
1702 /* XXX: do faster and simpler sorting */
1703 for(k
= 0; k
< 5; k
++) {
1704 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1705 s
= s1
->sections
[i
];
1706 /* compute if section should be included */
1708 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1712 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1713 (SHF_ALLOC
| SHF_WRITE
))
1719 } else if (s
->sh_type
== SHT_DYNSYM
||
1720 s
->sh_type
== SHT_STRTAB
||
1721 s
->sh_type
== SHT_HASH
) {
1724 } else if (s
->sh_type
== SHT_RELX
) {
1727 } else if (s
->sh_type
== SHT_NOBITS
) {
1734 section_order
[sh_order_index
++] = i
;
1736 /* section matches: we align it and add its size */
1738 addr
= (addr
+ s
->sh_addralign
- 1) &
1739 ~(s
->sh_addralign
- 1);
1740 file_offset
+= addr
- tmp
;
1741 s
->sh_offset
= file_offset
;
1744 /* update program header infos */
1745 if (ph
->p_offset
== 0) {
1746 ph
->p_offset
= file_offset
;
1748 ph
->p_paddr
= ph
->p_vaddr
;
1750 /* update dynamic relocation infos */
1751 if (s
->sh_type
== SHT_RELX
) {
1752 #if defined(__FreeBSD__)
1753 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.got")) { // rel_size == 0) {
1755 rel_size
+= s
->sh_size
; // XXX only first rel.
1757 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.bss")) { // rel_size == 0) {
1759 bss_size
= s
->sh_size
; // XXX only first rel.
1764 rel_size
+= s
->sh_size
;
1768 if (s
->sh_type
!= SHT_NOBITS
)
1769 file_offset
+= s
->sh_size
;
1772 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1773 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1776 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1777 /* if in the middle of a page, we duplicate the page in
1778 memory so that one copy is RX and the other is RW */
1779 if ((addr
& (s1
->section_align
- 1)) != 0)
1780 addr
+= s1
->section_align
;
1782 addr
= (addr
+ s1
->section_align
- 1) & ~(s1
->section_align
- 1);
1783 file_offset
= (file_offset
+ s1
->section_align
- 1) &
1784 ~(s1
->section_align
- 1);
1789 /* if interpreter, then add corresponing program header */
1793 #if defined(__FreeBSD__)
1795 int len
= phnum
* sizeof(ElfW(Phdr
));
1797 ph
->p_type
= PT_PHDR
;
1798 ph
->p_offset
= sizeof(ElfW(Ehdr
));
1799 ph
->p_vaddr
= interp
->sh_addr
- len
;
1800 ph
->p_paddr
= ph
->p_vaddr
;
1801 ph
->p_filesz
= ph
->p_memsz
= len
;
1802 ph
->p_flags
= PF_R
| PF_X
;
1803 ph
->p_align
= 4; // interp->sh_addralign;
1808 ph
->p_type
= PT_INTERP
;
1809 ph
->p_offset
= interp
->sh_offset
;
1810 ph
->p_vaddr
= interp
->sh_addr
;
1811 ph
->p_paddr
= ph
->p_vaddr
;
1812 ph
->p_filesz
= interp
->sh_size
;
1813 ph
->p_memsz
= interp
->sh_size
;
1815 ph
->p_align
= interp
->sh_addralign
;
1818 /* if dynamic section, then add corresponing program header */
1822 ph
= &phdr
[phnum
- 1];
1824 ph
->p_type
= PT_DYNAMIC
;
1825 ph
->p_offset
= dynamic
->sh_offset
;
1826 ph
->p_vaddr
= dynamic
->sh_addr
;
1827 ph
->p_paddr
= ph
->p_vaddr
;
1828 ph
->p_filesz
= dynamic
->sh_size
;
1829 ph
->p_memsz
= dynamic
->sh_size
;
1830 ph
->p_flags
= PF_R
| PF_W
;
1831 ph
->p_align
= dynamic
->sh_addralign
;
1833 /* put GOT dynamic section address */
1834 put32(s1
->got
->data
, dynamic
->sh_addr
);
1836 /* relocate the PLT */
1837 if (file_type
== TCC_OUTPUT_EXE
1838 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1839 || file_type
== TCC_OUTPUT_DLL
1845 p_end
= p
+ s1
->plt
->data_offset
;
1847 #if defined(TCC_TARGET_I386)
1848 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1849 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1852 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1855 #elif defined(TCC_TARGET_X86_64)
1856 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1857 put32(p
+ 2, get32(p
+ 2) + x
);
1858 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1861 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1864 #elif defined(TCC_TARGET_ARM)
1866 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1869 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1872 #elif defined(TCC_TARGET_C67)
1875 #error unsupported CPU
1880 /* relocate symbols in .dynsym */
1881 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1882 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1885 if (sym
->st_shndx
== SHN_UNDEF
) {
1886 /* relocate to the PLT if the symbol corresponds
1889 sym
->st_value
+= s1
->plt
->sh_addr
;
1890 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1891 /* do symbol relocation */
1892 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1896 /* put dynamic section entries */
1897 dynamic
->data_offset
= saved_dynamic_data_offset
;
1898 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1899 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1900 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1901 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1902 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1903 #ifdef TCC_TARGET_X86_64
1904 put_dt(dynamic
, DT_RELA
, rel_addr
);
1905 put_dt(dynamic
, DT_RELASZ
, rel_size
);
1906 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1908 #if defined(__FreeBSD__)
1909 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
1910 put_dt(dynamic
, DT_PLTRELSZ
, rel_size
);
1911 put_dt(dynamic
, DT_JMPREL
, rel_addr
);
1912 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
1913 put_dt(dynamic
, DT_REL
, bss_addr
);
1914 put_dt(dynamic
, DT_RELSZ
, bss_size
);
1916 put_dt(dynamic
, DT_REL
, rel_addr
);
1917 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1918 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1922 put_dt(dynamic
, DT_DEBUG
, 0);
1923 put_dt(dynamic
, DT_NULL
, 0);
1926 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1927 ehdr
.e_phnum
= phnum
;
1928 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1931 /* all other sections come after */
1932 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1933 s
= s1
->sections
[i
];
1934 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1936 section_order
[sh_order_index
++] = i
;
1938 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1939 ~(s
->sh_addralign
- 1);
1940 s
->sh_offset
= file_offset
;
1941 if (s
->sh_type
!= SHT_NOBITS
)
1942 file_offset
+= s
->sh_size
;
1945 /* if building executable or DLL, then relocate each section
1946 except the GOT which is already relocated */
1947 if (file_type
!= TCC_OUTPUT_OBJ
) {
1948 relocate_syms(s1
, 0);
1950 if (s1
->nb_errors
!= 0) {
1956 /* relocate sections */
1957 /* XXX: ignore sections with allocated relocations ? */
1958 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1959 s
= s1
->sections
[i
];
1960 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1961 relocate_section(s1
, s
);
1964 /* relocate relocation entries if the relocation tables are
1965 allocated in the executable */
1966 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1967 s
= s1
->sections
[i
];
1968 if ((s
->sh_flags
& SHF_ALLOC
) &&
1969 s
->sh_type
== SHT_RELX
) {
1970 relocate_rel(s1
, s
);
1974 /* get entry point address */
1975 if (file_type
== TCC_OUTPUT_EXE
)
1976 ehdr
.e_entry
= (uplong
)tcc_get_symbol_err(s1
, "_start");
1978 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1981 /* write elf file */
1982 if (file_type
== TCC_OUTPUT_OBJ
)
1986 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1988 error_noabort("could not write '%s'", filename
);
1991 f
= fdopen(fd
, "wb");
1993 printf("<- %s\n", filename
);
1995 #ifdef TCC_TARGET_COFF
1996 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1997 tcc_output_coff(s1
, f
);
2000 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
2001 sort_syms(s1
, symtab_section
);
2004 file_offset
= (file_offset
+ 3) & -4;
2007 ehdr
.e_ident
[0] = ELFMAG0
;
2008 ehdr
.e_ident
[1] = ELFMAG1
;
2009 ehdr
.e_ident
[2] = ELFMAG2
;
2010 ehdr
.e_ident
[3] = ELFMAG3
;
2011 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
2012 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2013 ehdr
.e_ident
[6] = EV_CURRENT
;
2015 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2017 #ifdef TCC_TARGET_ARM
2019 ehdr
.e_ident
[EI_OSABI
] = 0;
2020 ehdr
.e_flags
= 4 << 24;
2022 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2027 case TCC_OUTPUT_EXE
:
2028 ehdr
.e_type
= ET_EXEC
;
2030 case TCC_OUTPUT_DLL
:
2031 ehdr
.e_type
= ET_DYN
;
2033 case TCC_OUTPUT_OBJ
:
2034 ehdr
.e_type
= ET_REL
;
2037 ehdr
.e_machine
= EM_TCC_TARGET
;
2038 ehdr
.e_version
= EV_CURRENT
;
2039 ehdr
.e_shoff
= file_offset
;
2040 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2041 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2042 ehdr
.e_shnum
= shnum
;
2043 ehdr
.e_shstrndx
= shnum
- 1;
2045 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2046 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2047 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2049 for(i
=1;i
<s1
->nb_sections
;i
++) {
2050 s
= s1
->sections
[section_order
[i
]];
2051 if (s
->sh_type
!= SHT_NOBITS
) {
2052 #if defined(__FreeBSD__)
2053 if (s
->sh_type
== SHT_DYNSYM
)
2054 patch_dynsym_undef(s1
, s
);
2056 while (offset
< s
->sh_offset
) {
2061 fwrite(s
->data
, 1, size
, f
);
2066 /* output section headers */
2067 while (offset
< ehdr
.e_shoff
) {
2072 for(i
=0;i
<s1
->nb_sections
;i
++) {
2074 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2075 s
= s1
->sections
[i
];
2077 sh
->sh_name
= s
->sh_name
;
2078 sh
->sh_type
= s
->sh_type
;
2079 sh
->sh_flags
= s
->sh_flags
;
2080 sh
->sh_entsize
= s
->sh_entsize
;
2081 sh
->sh_info
= s
->sh_info
;
2083 sh
->sh_link
= s
->link
->sh_num
;
2084 sh
->sh_addralign
= s
->sh_addralign
;
2085 sh
->sh_addr
= s
->sh_addr
;
2086 sh
->sh_offset
= s
->sh_offset
;
2087 sh
->sh_size
= s
->sh_size
;
2089 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2092 tcc_output_binary(s1
, f
, section_order
);
2098 tcc_free(s1
->symtab_to_dynsym
);
2099 tcc_free(section_order
);
2101 tcc_free(s1
->got_offsets
);
2105 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2108 #ifdef TCC_TARGET_PE
2109 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2110 ret
= pe_output_file(s
, filename
);
2114 ret
= elf_output_file(s
, filename
);
2119 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2123 data
= tcc_malloc(size
);
2124 lseek(fd
, file_offset
, SEEK_SET
);
2125 read(fd
, data
, size
);
2129 typedef struct SectionMergeInfo
{
2130 Section
*s
; /* corresponding existing section */
2131 unsigned long offset
; /* offset of the new section in the existing section */
2132 uint8_t new_section
; /* true if section 's' was added */
2133 uint8_t link_once
; /* true if link once section */
2136 /* load an object file and merge it with current files */
2137 /* XXX: handle correctly stab (debug) info */
2138 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
2139 int fd
, unsigned long file_offset
)
2142 ElfW(Shdr
) *shdr
, *sh
;
2143 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2144 unsigned char *strsec
, *strtab
;
2145 int *old_to_new_syms
;
2146 char *sh_name
, *name
;
2147 SectionMergeInfo
*sm_table
, *sm
;
2148 ElfW(Sym
) *sym
, *symtab
;
2149 ElfW_Rel
*rel
, *rel_end
;
2155 stab_index
= stabstr_index
= 0;
2157 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2159 if (ehdr
.e_ident
[0] != ELFMAG0
||
2160 ehdr
.e_ident
[1] != ELFMAG1
||
2161 ehdr
.e_ident
[2] != ELFMAG2
||
2162 ehdr
.e_ident
[3] != ELFMAG3
)
2164 /* test if object file */
2165 if (ehdr
.e_type
!= ET_REL
)
2167 /* test CPU specific stuff */
2168 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2169 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2171 error_noabort("invalid object file");
2175 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2176 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2177 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2179 /* load section names */
2180 sh
= &shdr
[ehdr
.e_shstrndx
];
2181 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2183 /* load symtab and strtab */
2184 old_to_new_syms
= NULL
;
2188 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2190 if (sh
->sh_type
== SHT_SYMTAB
) {
2192 error_noabort("object must contain only one symtab");
2197 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2198 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2199 sm_table
[i
].s
= symtab_section
;
2201 /* now load strtab */
2202 sh
= &shdr
[sh
->sh_link
];
2203 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2207 /* now examine each section and try to merge its content with the
2209 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2210 /* no need to examine section name strtab */
2211 if (i
== ehdr
.e_shstrndx
)
2214 sh_name
= strsec
+ sh
->sh_name
;
2215 /* ignore sections types we do not handle */
2216 if (sh
->sh_type
!= SHT_PROGBITS
&&
2217 sh
->sh_type
!= SHT_RELX
&&
2219 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2221 sh
->sh_type
!= SHT_NOBITS
&&
2222 strcmp(sh_name
, ".stabstr")
2225 if (sh
->sh_addralign
< 1)
2226 sh
->sh_addralign
= 1;
2227 /* find corresponding section, if any */
2228 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2229 s
= s1
->sections
[j
];
2230 if (!strcmp(s
->name
, sh_name
)) {
2231 if (!strncmp(sh_name
, ".gnu.linkonce",
2232 sizeof(".gnu.linkonce") - 1)) {
2233 /* if a 'linkonce' section is already present, we
2234 do not add it again. It is a little tricky as
2235 symbols can still be defined in
2237 sm_table
[i
].link_once
= 1;
2244 /* not found: create new section */
2245 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2246 /* take as much info as possible from the section. sh_link and
2247 sh_info will be updated later */
2248 s
->sh_addralign
= sh
->sh_addralign
;
2249 s
->sh_entsize
= sh
->sh_entsize
;
2250 sm_table
[i
].new_section
= 1;
2252 if (sh
->sh_type
!= s
->sh_type
) {
2253 error_noabort("invalid section type");
2257 /* align start of section */
2258 offset
= s
->data_offset
;
2260 if (0 == strcmp(sh_name
, ".stab")) {
2264 if (0 == strcmp(sh_name
, ".stabstr")) {
2269 size
= sh
->sh_addralign
- 1;
2270 offset
= (offset
+ size
) & ~size
;
2271 if (sh
->sh_addralign
> s
->sh_addralign
)
2272 s
->sh_addralign
= sh
->sh_addralign
;
2273 s
->data_offset
= offset
;
2275 sm_table
[i
].offset
= offset
;
2277 /* concatenate sections */
2279 if (sh
->sh_type
!= SHT_NOBITS
) {
2281 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2282 ptr
= section_ptr_add(s
, size
);
2283 read(fd
, ptr
, size
);
2285 s
->data_offset
+= size
;
2290 /* //gr relocate stab strings */
2291 if (stab_index
&& stabstr_index
) {
2294 s
= sm_table
[stab_index
].s
;
2295 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2296 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2297 o
= sm_table
[stabstr_index
].offset
;
2299 a
->n_strx
+= o
, a
++;
2302 /* second short pass to update sh_link and sh_info fields of new
2304 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2306 if (!s
|| !sm_table
[i
].new_section
)
2309 if (sh
->sh_link
> 0)
2310 s
->link
= sm_table
[sh
->sh_link
].s
;
2311 if (sh
->sh_type
== SHT_RELX
) {
2312 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2313 /* update backward link */
2314 s1
->sections
[s
->sh_info
]->reloc
= s
;
2319 /* resolve symbols */
2320 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2323 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2324 if (sym
->st_shndx
!= SHN_UNDEF
&&
2325 sym
->st_shndx
< SHN_LORESERVE
) {
2326 sm
= &sm_table
[sym
->st_shndx
];
2327 if (sm
->link_once
) {
2328 /* if a symbol is in a link once section, we use the
2329 already defined symbol. It is very important to get
2330 correct relocations */
2331 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2332 name
= strtab
+ sym
->st_name
;
2333 sym_index
= find_elf_sym(symtab_section
, name
);
2335 old_to_new_syms
[i
] = sym_index
;
2339 /* if no corresponding section added, no need to add symbol */
2342 /* convert section number */
2343 sym
->st_shndx
= sm
->s
->sh_num
;
2345 sym
->st_value
+= sm
->offset
;
2348 name
= strtab
+ sym
->st_name
;
2349 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2350 sym
->st_info
, sym
->st_other
,
2351 sym
->st_shndx
, name
);
2352 old_to_new_syms
[i
] = sym_index
;
2355 /* third pass to patch relocation entries */
2356 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2361 offset
= sm_table
[i
].offset
;
2362 switch(s
->sh_type
) {
2364 /* take relocation offset information */
2365 offseti
= sm_table
[sh
->sh_info
].offset
;
2366 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2367 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2372 /* convert symbol index */
2373 type
= ELFW(R_TYPE
)(rel
->r_info
);
2374 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2375 /* NOTE: only one symtab assumed */
2376 if (sym_index
>= nb_syms
)
2378 sym_index
= old_to_new_syms
[sym_index
];
2379 /* ignore link_once in rel section. */
2380 if (!sym_index
&& !sm
->link_once
) {
2382 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2383 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2386 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2387 /* offset the relocation offset */
2388 rel
->r_offset
+= offseti
;
2400 tcc_free(old_to_new_syms
);
2407 typedef struct ArchiveHeader
{
2408 char ar_name
[16]; /* name of this member */
2409 char ar_date
[12]; /* file mtime */
2410 char ar_uid
[6]; /* owner uid; printed as decimal */
2411 char ar_gid
[6]; /* owner gid; printed as decimal */
2412 char ar_mode
[8]; /* file mode, printed as octal */
2413 char ar_size
[10]; /* file size, printed as decimal */
2414 char ar_fmag
[2]; /* should contain ARFMAG */
2417 static int get_be32(const uint8_t *b
)
2419 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2422 /* load only the objects which resolve undefined symbols */
2423 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2425 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2427 const char *ar_names
, *p
;
2428 const uint8_t *ar_index
;
2431 data
= tcc_malloc(size
);
2432 if (read(fd
, data
, size
) != size
)
2434 nsyms
= get_be32(data
);
2435 ar_index
= data
+ 4;
2436 ar_names
= ar_index
+ nsyms
* 4;
2440 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2441 sym_index
= find_elf_sym(symtab_section
, p
);
2443 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2444 if(sym
->st_shndx
== SHN_UNDEF
) {
2445 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2447 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2450 lseek(fd
, off
, SEEK_SET
);
2451 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2466 /* load a '.a' file */
2467 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
)
2474 unsigned long file_offset
;
2476 /* skip magic which was already checked */
2477 read(fd
, magic
, sizeof(magic
));
2480 len
= read(fd
, &hdr
, sizeof(hdr
));
2483 if (len
!= sizeof(hdr
)) {
2484 error_noabort("invalid archive");
2487 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2488 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2489 size
= strtol(ar_size
, NULL
, 0);
2490 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2491 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2492 if (ar_name
[i
] != ' ')
2495 ar_name
[i
+ 1] = '\0';
2496 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2497 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2499 size
= (size
+ 1) & ~1;
2500 if (!strcmp(ar_name
, "/")) {
2501 /* coff symbol table : we handle it */
2502 if(s1
->alacarte_link
)
2503 return tcc_load_alacarte(s1
, fd
, size
);
2504 } else if (!strcmp(ar_name
, "//") ||
2505 !strcmp(ar_name
, "__.SYMDEF") ||
2506 !strcmp(ar_name
, "__.SYMDEF/") ||
2507 !strcmp(ar_name
, "ARFILENAMES/")) {
2508 /* skip symbol table or archive names */
2510 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2513 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2518 #ifndef TCC_TARGET_PE
2519 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2520 is referenced by the user (so it should be added as DT_NEEDED in
2521 the generated ELF file) */
2522 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2525 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2526 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2527 ElfW(Sym
) *sym
, *dynsym
;
2528 ElfW(Dyn
) *dt
, *dynamic
;
2529 unsigned char *dynstr
;
2530 const char *name
, *soname
;
2531 DLLReference
*dllref
;
2533 read(fd
, &ehdr
, sizeof(ehdr
));
2535 /* test CPU specific stuff */
2536 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2537 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2538 error_noabort("bad architecture");
2543 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2545 /* load dynamic section and dynamic symbols */
2549 dynsym
= NULL
; /* avoid warning */
2550 dynstr
= NULL
; /* avoid warning */
2551 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2552 switch(sh
->sh_type
) {
2554 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2555 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2558 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2559 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2560 sh1
= &shdr
[sh
->sh_link
];
2561 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2568 /* compute the real library name */
2569 soname
= tcc_basename(filename
);
2571 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2572 if (dt
->d_tag
== DT_SONAME
) {
2573 soname
= dynstr
+ dt
->d_un
.d_val
;
2577 /* if the dll is already loaded, do not load it */
2578 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2579 dllref
= s1
->loaded_dlls
[i
];
2580 if (!strcmp(soname
, dllref
->name
)) {
2581 /* but update level if needed */
2582 if (level
< dllref
->level
)
2583 dllref
->level
= level
;
2589 // printf("loading dll '%s'\n", soname);
2591 /* add the dll and its level */
2592 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2593 dllref
->level
= level
;
2594 strcpy(dllref
->name
, soname
);
2595 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2597 /* add dynamic symbols in dynsym_section */
2598 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2599 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2600 if (sym_bind
== STB_LOCAL
)
2602 name
= dynstr
+ sym
->st_name
;
2603 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2604 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2607 /* load all referenced DLLs */
2608 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2611 name
= dynstr
+ dt
->d_un
.d_val
;
2612 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2613 dllref
= s1
->loaded_dlls
[j
];
2614 if (!strcmp(name
, dllref
->name
))
2615 goto already_loaded
;
2617 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2618 error_noabort("referenced dll '%s' not found", name
);
2635 #define LD_TOK_NAME 256
2636 #define LD_TOK_EOF (-1)
2638 /* return next ld script token */
2639 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2657 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2658 ch
= file
->buf_ptr
[0];
2666 /* case 'a' ... 'z': */
2693 /* case 'A' ... 'z': */
2728 if (!((ch
>= 'a' && ch
<= 'z') ||
2729 (ch
>= 'A' && ch
<= 'Z') ||
2730 (ch
>= '0' && ch
<= '9') ||
2731 strchr("/.-_+=$:\\,~", ch
)))
2733 if ((q
- name
) < name_size
- 1) {
2750 printf("tok=%c %d\n", c
, c
);
2751 if (c
== LD_TOK_NAME
)
2752 printf(" name=%s\n", name
);
2757 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2759 char filename
[1024];
2762 t
= ld_next(s1
, filename
, sizeof(filename
));
2765 t
= ld_next(s1
, filename
, sizeof(filename
));
2767 if (t
== LD_TOK_EOF
) {
2768 error_noabort("unexpected end of file");
2770 } else if (t
== ')') {
2772 } else if (t
!= LD_TOK_NAME
) {
2773 error_noabort("filename expected");
2776 if (!strcmp(filename
, "AS_NEEDED")) {
2777 ret
= ld_add_file_list(s1
, 1);
2781 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2783 tcc_add_file(s1
, filename
);
2785 t
= ld_next(s1
, filename
, sizeof(filename
));
2787 t
= ld_next(s1
, filename
, sizeof(filename
));
2793 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2795 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
)
2798 char filename
[1024];
2801 ch
= file
->buf_ptr
[0];
2804 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2805 if (t
== LD_TOK_EOF
)
2807 else if (t
!= LD_TOK_NAME
)
2809 if (!strcmp(cmd
, "INPUT") ||
2810 !strcmp(cmd
, "GROUP")) {
2811 ret
= ld_add_file_list(s1
, 0);
2814 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2815 !strcmp(cmd
, "TARGET")) {
2816 /* ignore some commands */
2817 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2821 t
= ld_next(s1
, filename
, sizeof(filename
));
2822 if (t
== LD_TOK_EOF
) {
2823 error_noabort("unexpected end of file");
2825 } else if (t
== ')') {