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
,
101 unsigned long value
, unsigned long size
,
102 int info
, int other
, int shndx
, const char *name
)
104 int name_offset
, sym_index
;
109 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
111 name_offset
= put_elf_str(s
->link
, name
);
114 /* XXX: endianness */
115 sym
->st_name
= name_offset
;
116 sym
->st_value
= value
;
119 sym
->st_other
= other
;
120 sym
->st_shndx
= shndx
;
121 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
125 ptr
= section_ptr_add(hs
, sizeof(int));
126 base
= (int *)hs
->data
;
127 /* only add global or weak symbols */
128 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
129 /* add another hashing entry */
131 h
= elf_hash(name
) % nbuckets
;
133 base
[2 + h
] = sym_index
;
135 /* we resize the hash table */
136 hs
->nb_hashed_syms
++;
137 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
138 rebuild_hash(s
, 2 * nbuckets
);
148 /* find global ELF symbol 'name' and return its index. Return 0 if not
150 ST_FUNC
int find_elf_sym(Section
*s
, const char *name
)
154 int nbuckets
, sym_index
, h
;
160 nbuckets
= ((int *)hs
->data
)[0];
161 h
= elf_hash(name
) % nbuckets
;
162 sym_index
= ((int *)hs
->data
)[2 + h
];
163 while (sym_index
!= 0) {
164 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
165 name1
= s
->link
->data
+ sym
->st_name
;
166 if (!strcmp(name
, name1
))
168 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
173 /* return elf symbol value, signal error if 'err' is nonzero */
174 static void *get_elf_sym_addr(TCCState
*s
, const char *name
, int err
)
179 sym_index
= find_elf_sym(symtab_section
, name
);
180 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
181 if (!sym_index
|| sym
->st_shndx
== SHN_UNDEF
) {
183 error("%s not defined", name
);
186 return (void*)(uplong
)sym
->st_value
;
189 /* return elf symbol value */
190 LIBTCCAPI
void *tcc_get_symbol(TCCState
*s
, const char *name
)
192 return get_elf_sym_addr(s
, name
, 0);
195 /* return elf symbol value or error */
196 ST_FUNC
void *tcc_get_symbol_err(TCCState
*s
, const char *name
)
198 return get_elf_sym_addr(s
, name
, 1);
201 /* add an elf symbol : check if it is already defined and patch
202 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
203 ST_FUNC
int add_elf_sym(Section
*s
, uplong value
, unsigned long size
,
204 int info
, int other
, int sh_num
, const char *name
)
207 int sym_bind
, sym_index
, sym_type
, esym_bind
;
208 unsigned char sym_vis
, esym_vis
, new_vis
;
210 sym_bind
= ELFW(ST_BIND
)(info
);
211 sym_type
= ELFW(ST_TYPE
)(info
);
212 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
214 if (sym_bind
!= STB_LOCAL
) {
215 /* we search global or weak symbols */
216 sym_index
= find_elf_sym(s
, name
);
219 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
220 if (esym
->st_shndx
!= SHN_UNDEF
) {
221 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
222 /* propagate the most constraining visibility */
223 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
224 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
225 if (esym_vis
== STV_DEFAULT
) {
227 } else if (sym_vis
== STV_DEFAULT
) {
230 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
232 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
234 other
= esym
->st_other
; /* in case we have to patch esym */
235 if (sh_num
== SHN_UNDEF
) {
236 /* ignore adding of undefined symbol if the
237 corresponding symbol is already defined */
238 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
239 /* global overrides weak, so patch */
241 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
242 /* weak is ignored if already global */
243 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
244 /* ignore hidden symbols after */
245 } else if (esym
->st_shndx
== SHN_COMMON
246 && (sh_num
< SHN_LORESERVE
|| sh_num
== SHN_COMMON
)) {
247 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
248 No idea if this is the correct solution ... */
250 } else if (s
== tcc_state
->dynsymtab_section
) {
251 /* we accept that two DLL define the same symbol */
254 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
255 sym_bind
, sh_num
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
257 error_noabort("'%s' defined twice", name
);
261 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
262 esym
->st_shndx
= sh_num
;
263 esym
->st_value
= value
;
264 esym
->st_size
= size
;
265 esym
->st_other
= other
;
269 sym_index
= put_elf_sym(s
, value
, size
,
270 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
277 ST_FUNC
void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
278 int type
, int symbol
)
286 /* if no relocation section, create it */
287 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
288 /* if the symtab is allocated, then we consider the relocation
290 sr
= new_section(tcc_state
, buf
, SHT_RELX
, symtab
->sh_flags
);
291 sr
->sh_entsize
= sizeof(ElfW_Rel
);
293 sr
->sh_info
= s
->sh_num
;
296 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
297 rel
->r_offset
= offset
;
298 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
299 #ifdef TCC_TARGET_X86_64
304 /* put stab debug information */
306 ST_FUNC
void put_stabs(const char *str
, int type
, int other
, int desc
,
311 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
313 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
318 sym
->n_other
= other
;
320 sym
->n_value
= value
;
323 ST_FUNC
void put_stabs_r(const char *str
, int type
, int other
, int desc
,
324 unsigned long value
, Section
*sec
, int sym_index
)
326 put_stabs(str
, type
, other
, desc
, value
);
327 put_elf_reloc(symtab_section
, stab_section
,
328 stab_section
->data_offset
- sizeof(unsigned int),
329 R_DATA_32
, sym_index
);
332 ST_FUNC
void put_stabn(int type
, int other
, int desc
, int value
)
334 put_stabs(NULL
, type
, other
, desc
, value
);
337 ST_FUNC
void put_stabd(int type
, int other
, int desc
)
339 put_stabs(NULL
, type
, other
, desc
, 0);
342 /* In an ELF file symbol table, the local symbols must appear below
343 the global and weak ones. Since TCC cannot sort it while generating
344 the code, we must do it after. All the relocation tables are also
345 modified to take into account the symbol table sorting */
346 static void sort_syms(TCCState
*s1
, Section
*s
)
348 int *old_to_new_syms
;
352 ElfW_Rel
*rel
, *rel_end
;
356 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
357 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
358 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
360 /* first pass for local symbols */
361 p
= (ElfW(Sym
) *)s
->data
;
363 for(i
= 0; i
< nb_syms
; i
++) {
364 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
365 old_to_new_syms
[i
] = q
- new_syms
;
370 /* save the number of local symbols in section header */
371 s
->sh_info
= q
- new_syms
;
373 /* then second pass for non local symbols */
374 p
= (ElfW(Sym
) *)s
->data
;
375 for(i
= 0; i
< nb_syms
; i
++) {
376 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
377 old_to_new_syms
[i
] = q
- new_syms
;
383 /* we copy the new symbols to the old */
384 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
387 /* now we modify all the relocations */
388 for(i
= 1; i
< s1
->nb_sections
; i
++) {
389 sr
= s1
->sections
[i
];
390 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
391 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
392 for(rel
= (ElfW_Rel
*)sr
->data
;
395 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
396 type
= ELFW(R_TYPE
)(rel
->r_info
);
397 sym_index
= old_to_new_syms
[sym_index
];
398 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
403 tcc_free(old_to_new_syms
);
406 /* relocate common symbols in the .bss section */
407 ST_FUNC
void relocate_common_syms(void)
409 ElfW(Sym
) *sym
, *sym_end
;
410 unsigned long offset
, align
;
412 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
413 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
416 if (sym
->st_shndx
== SHN_COMMON
) {
418 align
= sym
->st_value
;
419 offset
= bss_section
->data_offset
;
420 offset
= (offset
+ align
- 1) & -align
;
421 sym
->st_value
= offset
;
422 sym
->st_shndx
= bss_section
->sh_num
;
423 offset
+= sym
->st_size
;
424 bss_section
->data_offset
= offset
;
429 /* relocate symbol table, resolve undefined symbols if do_resolve is
430 true and output error if undefined symbol. */
431 ST_FUNC
void relocate_syms(TCCState
*s1
, int do_resolve
)
433 ElfW(Sym
) *sym
, *esym
, *sym_end
;
434 int sym_bind
, sh_num
, sym_index
;
437 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
438 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
441 sh_num
= sym
->st_shndx
;
442 if (sh_num
== SHN_UNDEF
) {
443 name
= strtab_section
->data
+ sym
->st_name
;
445 #if !defined TCC_TARGET_PE || !defined _WIN32
447 name
= symtab_section
->link
->data
+ sym
->st_name
;
448 addr
= resolve_sym(s1
, name
);
450 sym
->st_value
= (uplong
)addr
;
454 } else if (s1
->dynsym
) {
455 /* if dynamic symbol exist, then use it */
456 sym_index
= find_elf_sym(s1
->dynsym
, name
);
458 esym
= &((ElfW(Sym
) *)s1
->dynsym
->data
)[sym_index
];
459 sym
->st_value
= esym
->st_value
;
463 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
465 if (!strcmp(name
, "_fp_hw"))
467 /* only weak symbols are accepted to be undefined. Their
469 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
470 if (sym_bind
== STB_WEAK
) {
473 error_noabort("undefined symbol '%s'", name
);
475 } else if (sh_num
< SHN_LORESERVE
) {
476 /* add section base */
477 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
483 #ifndef TCC_TARGET_PE
484 #ifdef TCC_TARGET_X86_64
485 #define JMP_TABLE_ENTRY_SIZE 14
486 static unsigned long add_jmp_table(TCCState
*s1
, unsigned long val
)
488 char *p
= s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
;
489 s1
->runtime_plt_and_got_offset
+= JMP_TABLE_ENTRY_SIZE
;
494 *(unsigned long *)(p
+ 6) = val
;
495 return (unsigned long)p
;
498 static unsigned long add_got_table(TCCState
*s1
, unsigned long val
)
500 unsigned long *p
=(unsigned long *)(s1
->runtime_plt_and_got
+
501 s1
->runtime_plt_and_got_offset
);
502 s1
->runtime_plt_and_got_offset
+= sizeof(void *);
504 return (unsigned long)p
;
509 /* relocate a given section (CPU dependent) */
510 ST_FUNC
void relocate_section(TCCState
*s1
, Section
*s
)
513 ElfW_Rel
*rel
, *rel_end
, *qrel
;
517 unsigned long val
, addr
;
518 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
523 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
524 qrel
= (ElfW_Rel
*)sr
->data
;
528 ptr
= s
->data
+ rel
->r_offset
;
530 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
531 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
533 #ifdef TCC_TARGET_X86_64
534 /* XXX: not tested */
535 val
+= rel
->r_addend
;
537 type
= ELFW(R_TYPE
)(rel
->r_info
);
538 addr
= s
->sh_addr
+ rel
->r_offset
;
542 #if defined(TCC_TARGET_I386)
544 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
545 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
546 qrel
->r_offset
= rel
->r_offset
;
548 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_32
);
552 qrel
->r_info
= ELFW(R_INFO
)(0, R_386_RELATIVE
);
559 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
561 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
563 qrel
->r_offset
= rel
->r_offset
;
564 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_PC32
);
569 *(int *)ptr
+= val
- addr
;
572 *(int *)ptr
+= val
- addr
;
579 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
582 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
585 /* we load the got offset */
586 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
589 if (s1
->output_format
!= TCC_OUTPUT_FORMAT_BINARY
) {
591 error("can only produce 16-bit binary files");
593 *(short *)ptr
+= val
;
596 if (s1
->output_format
!= TCC_OUTPUT_FORMAT_BINARY
)
598 *(short *)ptr
+= val
- addr
;
600 #elif defined(TCC_TARGET_ARM)
607 x
= (*(int *)ptr
)&0xffffff;
608 (*(int *)ptr
) &= 0xff000000;
613 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
614 error("can't relocate value at %x",addr
);
623 x
= (*(int *)ptr
) & 0x7fffffff;
624 (*(int *)ptr
) &= 0x80000000;
627 if((x
^(x
>>1))&0x40000000)
628 error("can't relocate value at %x",addr
);
629 (*(int *)ptr
) |= x
& 0x7fffffff;
634 case R_ARM_BASE_PREL
:
635 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
638 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
641 /* we load the got offset */
642 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
647 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
648 type
,addr
,(unsigned int)(long)ptr
,val
);
650 #elif defined(TCC_TARGET_C67)
658 /* put the low 16 bits of the absolute address */
659 // add to what is already there
661 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
662 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
664 //patch both at once - assumes always in pairs Low - High
666 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
667 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
673 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
674 type
,addr
,(unsigned int)(long)ptr
, val
);
676 #elif defined(TCC_TARGET_X86_64)
678 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
679 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
680 qrel
->r_addend
= *(long long *)ptr
+ val
;
683 *(long long *)ptr
+= val
;
687 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
688 /* XXX: this logic may depend on TCC's codegen
689 now TCC uses R_X86_64_32 even for a 64bit pointer */
690 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
691 qrel
->r_addend
= *(int *)ptr
+ val
;
696 case R_X86_64_PC32
: {
698 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
700 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
702 qrel
->r_offset
= rel
->r_offset
;
703 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_X86_64_PC32
);
704 qrel
->r_addend
= *(int *)ptr
;
709 diff
= (long long)val
- addr
;
710 if (diff
<= -2147483647 || diff
> 2147483647) {
711 #ifndef TCC_TARGET_PE
712 /* XXX: naive support for over 32bit jump */
713 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
714 val
= add_jmp_table(s1
, val
);
718 if (diff
<= -2147483647 || diff
> 2147483647) {
719 error("internal error: relocation failed");
726 *(int *)ptr
+= val
- addr
;
728 case R_X86_64_GLOB_DAT
:
729 case R_X86_64_JUMP_SLOT
:
732 case R_X86_64_GOTPCREL
:
733 #ifndef TCC_TARGET_PE
734 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
735 val
= add_got_table(s1
, val
- rel
->r_addend
) + rel
->r_addend
;
736 *(int *)ptr
+= val
- addr
;
740 *(int *)ptr
+= (s1
->got
->sh_addr
- addr
+
741 s1
->got_offsets
[sym_index
] - 4);
743 case R_X86_64_GOTTPOFF
:
744 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
747 /* we load the got offset */
748 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
751 #error unsupported processor
755 /* if the relocation is allocated, we change its symbol table */
756 if (sr
->sh_flags
& SHF_ALLOC
)
757 sr
->link
= s1
->dynsym
;
760 /* relocate relocation table in 'sr' */
761 static void relocate_rel(TCCState
*s1
, Section
*sr
)
764 ElfW_Rel
*rel
, *rel_end
;
766 s
= s1
->sections
[sr
->sh_info
];
767 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
768 for(rel
= (ElfW_Rel
*)sr
->data
;
771 rel
->r_offset
+= s
->sh_addr
;
775 /* count the number of dynamic relocations so that we can reserve
777 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
779 ElfW_Rel
*rel
, *rel_end
;
780 int sym_index
, esym_index
, type
, count
;
783 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
784 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
785 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
786 type
= ELFW(R_TYPE
)(rel
->r_info
);
788 #if defined(TCC_TARGET_I386)
790 #elif defined(TCC_TARGET_X86_64)
797 #if defined(TCC_TARGET_I386)
799 #elif defined(TCC_TARGET_X86_64)
802 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
811 /* allocate the section */
812 sr
->sh_flags
|= SHF_ALLOC
;
813 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
818 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
823 if (index
>= s1
->nb_got_offsets
) {
824 /* find immediately bigger power of 2 and reallocate array */
828 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
830 error("memory full");
831 s1
->got_offsets
= tab
;
832 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
833 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
834 s1
->nb_got_offsets
= n
;
836 s1
->got_offsets
[index
] = val
;
839 /* XXX: suppress that */
840 static void put32(unsigned char *p
, uint32_t val
)
848 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
849 defined(TCC_TARGET_X86_64)
850 static uint32_t get32(unsigned char *p
)
852 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
856 static void build_got(TCCState
*s1
)
860 /* if no got, then create it */
861 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
862 s1
->got
->sh_entsize
= 4;
863 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
864 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
865 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
867 /* keep space for _DYNAMIC pointer, if present */
869 /* two dummy got entries */
873 /* keep space for _DYNAMIC pointer, if present */
876 /* two dummy got entries */
884 /* put a got entry corresponding to a symbol in symtab_section. 'size'
885 and 'info' can be modifed if more precise info comes from the DLL */
886 static void put_got_entry(TCCState
*s1
,
887 int reloc_type
, unsigned long size
, int info
,
893 unsigned long offset
;
899 /* if a got entry already exists for that symbol, no need to add one */
900 if (sym_index
< s1
->nb_got_offsets
&&
901 s1
->got_offsets
[sym_index
] != 0)
904 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
907 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
908 name
= symtab_section
->link
->data
+ sym
->st_name
;
909 offset
= sym
->st_value
;
910 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
912 #ifdef TCC_TARGET_X86_64
922 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
925 /* if we build a DLL, we add a %ebx offset */
926 if (s1
->output_type
== TCC_OUTPUT_DLL
)
932 /* add a PLT entry */
934 if (plt
->data_offset
== 0) {
935 /* first plt entry */
936 p
= section_ptr_add(plt
, 16);
937 p
[0] = 0xff; /* pushl got + PTR_SIZE */
939 put32(p
+ 2, PTR_SIZE
);
940 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
942 put32(p
+ 8, PTR_SIZE
* 2);
945 p
= section_ptr_add(plt
, 16);
946 p
[0] = 0xff; /* jmp *(got + x) */
948 put32(p
+ 2, s1
->got
->data_offset
);
949 p
[6] = 0x68; /* push $xxx */
950 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
951 p
[11] = 0xe9; /* jmp plt_start */
952 put32(p
+ 12, -(plt
->data_offset
));
954 /* the symbol is modified so that it will be relocated to
956 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
957 if (s1
->output_type
== TCC_OUTPUT_EXE
)
959 offset
= plt
->data_offset
- 16;
961 #elif defined(TCC_TARGET_ARM)
962 if (reloc_type
== R_ARM_JUMP_SLOT
) {
966 /* if we build a DLL, we add a %ebx offset */
967 if (s1
->output_type
== TCC_OUTPUT_DLL
)
968 error("DLLs unimplemented!");
970 /* add a PLT entry */
972 if (plt
->data_offset
== 0) {
973 /* first plt entry */
974 p
= section_ptr_add(plt
, 16);
975 put32(p
, 0xe52de004);
976 put32(p
+ 4, 0xe59fe010);
977 put32(p
+ 8, 0xe08fe00e);
978 put32(p
+ 12, 0xe5bef008);
981 p
= section_ptr_add(plt
, 16);
982 put32(p
, 0xe59fc004);
983 put32(p
+4, 0xe08fc00c);
984 put32(p
+8, 0xe59cf000);
985 put32(p
+12, s1
->got
->data_offset
);
987 /* the symbol is modified so that it will be relocated to
989 if (s1
->output_type
== TCC_OUTPUT_EXE
)
990 offset
= plt
->data_offset
- 16;
992 #elif defined(TCC_TARGET_C67)
993 error("C67 got not implemented");
995 #error unsupported CPU
997 index
= put_elf_sym(s1
->dynsym
, offset
,
998 size
, info
, 0, sym
->st_shndx
, name
);
999 /* put a got entry */
1000 put_elf_reloc(s1
->dynsym
, s1
->got
,
1001 s1
->got
->data_offset
,
1004 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
1008 /* build GOT and PLT entries */
1009 ST_FUNC
void build_got_entries(TCCState
*s1
)
1011 Section
*s
, *symtab
;
1012 ElfW_Rel
*rel
, *rel_end
;
1014 int i
, type
, reloc_type
, sym_index
;
1016 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1017 s
= s1
->sections
[i
];
1018 if (s
->sh_type
!= SHT_RELX
)
1020 /* no need to handle got relocations */
1021 if (s
->link
!= symtab_section
)
1024 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
1025 for(rel
= (ElfW_Rel
*)s
->data
;
1028 type
= ELFW(R_TYPE
)(rel
->r_info
);
1030 #if defined(TCC_TARGET_I386)
1037 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1038 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1039 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1040 /* look at the symbol got offset. If none, then add one */
1041 if (type
== R_386_GOT32
)
1042 reloc_type
= R_386_GLOB_DAT
;
1044 reloc_type
= R_386_JMP_SLOT
;
1045 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1049 #elif defined(TCC_TARGET_ARM)
1050 case R_ARM_GOT_BREL
:
1051 case R_ARM_GOTOFF32
:
1052 case R_ARM_BASE_PREL
:
1056 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1057 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1058 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1059 /* look at the symbol got offset. If none, then add one */
1060 if (type
== R_ARM_GOT_BREL
)
1061 reloc_type
= R_ARM_GLOB_DAT
;
1063 reloc_type
= R_ARM_JUMP_SLOT
;
1064 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1068 #elif defined(TCC_TARGET_C67)
1075 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1076 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1077 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1078 /* look at the symbol got offset. If none, then add one */
1079 if (type
== R_C60_GOT32
)
1080 reloc_type
= R_C60_GLOB_DAT
;
1082 reloc_type
= R_C60_JMP_SLOT
;
1083 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1087 #elif defined(TCC_TARGET_X86_64)
1088 case R_X86_64_GOT32
:
1089 case R_X86_64_GOTTPOFF
:
1090 case R_X86_64_GOTPCREL
:
1091 case R_X86_64_PLT32
:
1094 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
||
1095 type
== R_X86_64_PLT32
) {
1096 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1097 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1098 /* look at the symbol got offset. If none, then add one */
1099 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
)
1100 reloc_type
= R_X86_64_GLOB_DAT
;
1102 reloc_type
= R_X86_64_JUMP_SLOT
;
1103 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1108 #error unsupported CPU
1117 ST_FUNC Section
*new_symtab(TCCState
*s1
,
1118 const char *symtab_name
, int sh_type
, int sh_flags
,
1119 const char *strtab_name
,
1120 const char *hash_name
, int hash_sh_flags
)
1122 Section
*symtab
, *strtab
, *hash
;
1123 int *ptr
, nb_buckets
;
1125 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1126 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1127 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1128 put_elf_str(strtab
, "");
1129 symtab
->link
= strtab
;
1130 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1134 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1135 hash
->sh_entsize
= sizeof(int);
1136 symtab
->hash
= hash
;
1137 hash
->link
= symtab
;
1139 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1140 ptr
[0] = nb_buckets
;
1142 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1146 /* put dynamic tag */
1147 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1150 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1152 dyn
->d_un
.d_val
= val
;
1155 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1159 char sym_start
[1024];
1162 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1163 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1165 s
= find_section(s1
, section_name
);
1170 end_offset
= s
->data_offset
;
1173 add_elf_sym(symtab_section
,
1175 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1176 s
->sh_num
, sym_start
);
1177 add_elf_sym(symtab_section
,
1179 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1180 s
->sh_num
, sym_end
);
1183 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
1185 #ifdef CONFIG_TCC_BCHECK
1187 Section
*init_section
;
1188 unsigned char *pinit
;
1191 if (0 == s1
->do_bounds_check
)
1194 /* XXX: add an object file to do that */
1195 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1197 add_elf_sym(symtab_section
, 0, 0,
1198 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1199 bounds_section
->sh_num
, "__bounds_start");
1200 /* add bound check code */
1201 #ifndef TCC_TARGET_PE
1204 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "bcheck.o");
1205 tcc_add_file(s1
, buf
);
1208 #ifdef TCC_TARGET_I386
1209 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1210 /* add 'call __bound_init()' in .init section */
1211 init_section
= find_section(s1
, ".init");
1212 pinit
= section_ptr_add(init_section
, 5);
1214 put32(pinit
+ 1, -4);
1215 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1216 put_elf_reloc(symtab_section
, init_section
,
1217 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1223 /* add tcc runtime libraries */
1224 ST_FUNC
void tcc_add_runtime(TCCState
*s1
)
1229 if (!s1
->nostdlib
) {
1230 #ifdef CONFIG_USE_LIBGCC
1231 tcc_add_library(s1
, "c");
1232 tcc_add_file(s1
, CONFIG_SYSROOT
"/lib/libgcc_s.so.1");
1235 tcc_add_library(s1
, "c");
1236 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "libtcc1.a");
1237 tcc_add_file(s1
, buf
);
1240 /* add crt end if not memory output */
1241 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1242 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1246 /* add various standard linker symbols (must be done after the
1247 sections are filled (for example after allocating common
1249 ST_FUNC
void tcc_add_linker_symbols(TCCState
*s1
)
1255 add_elf_sym(symtab_section
,
1256 text_section
->data_offset
, 0,
1257 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1258 text_section
->sh_num
, "_etext");
1259 add_elf_sym(symtab_section
,
1260 data_section
->data_offset
, 0,
1261 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1262 data_section
->sh_num
, "_edata");
1263 add_elf_sym(symtab_section
,
1264 bss_section
->data_offset
, 0,
1265 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1266 bss_section
->sh_num
, "_end");
1267 /* horrible new standard ldscript defines */
1268 add_init_array_defines(s1
, ".preinit_array");
1269 add_init_array_defines(s1
, ".init_array");
1270 add_init_array_defines(s1
, ".fini_array");
1272 /* add start and stop symbols for sections whose name can be
1274 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1275 s
= s1
->sections
[i
];
1276 if (s
->sh_type
== SHT_PROGBITS
&&
1277 (s
->sh_flags
& SHF_ALLOC
)) {
1281 /* check if section name can be expressed in C */
1287 if (!isid(ch
) && !isnum(ch
))
1291 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1292 add_elf_sym(symtab_section
,
1294 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1296 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1297 add_elf_sym(symtab_section
,
1299 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1306 /* name of ELF interpreter */
1307 #if defined __FreeBSD__
1308 static const char elf_interp
[] = "/libexec/ld-elf.so.1";
1309 #elif defined TCC_ARM_EABI
1310 static const char elf_interp
[] = "/lib/ld-linux.so.3";
1311 #elif defined(TCC_TARGET_X86_64)
1312 static const char elf_interp
[] = "/lib/ld-linux-x86-64.so.2";
1313 #elif defined(TCC_UCLIBC)
1314 static const char elf_interp
[] = "/lib/ld-uClibc.so.0";
1316 static const char elf_interp
[] = "/lib/ld-linux.so.2";
1319 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1320 const int *section_order
)
1323 int i
, offset
, size
;
1326 for(i
=1;i
<s1
->nb_sections
;i
++) {
1327 s
= s1
->sections
[section_order
[i
]];
1328 if (s
->sh_type
!= SHT_NOBITS
&&
1329 (s
->sh_flags
& SHF_ALLOC
)) {
1330 while (offset
< s
->sh_offset
) {
1335 fwrite(s
->data
, 1, size
, f
);
1341 #if defined(__FreeBSD__)
1343 #define EXTRA_RELITEMS 14
1345 /* move the relocation value from .dynsym to .got */
1346 void patch_dynsym_undef(TCCState
*s1
, Section
*s
)
1348 uint32_t *gotd
= (void *)s1
->got
->data
;
1349 ElfW(Sym
) *sym
, *sym_end
;
1351 gotd
+= 3; // dummy entries in .got
1352 /* relocate symbols in .dynsym */
1353 sym_end
= (ElfW(Sym
) *)(s
->data
+ s
->data_offset
);
1354 for (sym
= (ElfW(Sym
) *)s
->data
+ 1; sym
< sym_end
; sym
++) {
1355 if (sym
->st_shndx
== SHN_UNDEF
) {
1356 *gotd
++ = sym
->st_value
+ 6; // XXX 6 is magic ?
1363 #define EXTRA_RELITEMS 9
1366 /* output an ELF file */
1367 /* XXX: suppress unneeded sections */
1368 static int elf_output_file(TCCState
*s1
, const char *filename
)
1374 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1376 Section
*strsec
, *s
;
1377 ElfW(Shdr
) shdr
, *sh
;
1378 ElfW(Phdr
) *phdr
, *ph
;
1379 Section
*interp
, *dynamic
, *dynstr
;
1380 unsigned long saved_dynamic_data_offset
;
1382 int type
, file_type
;
1383 unsigned long rel_addr
, rel_size
;
1384 unsigned long bss_addr
, bss_size
;
1386 file_type
= s1
->output_type
;
1389 if (file_type
!= TCC_OUTPUT_OBJ
) {
1390 tcc_add_runtime(s1
);
1394 section_order
= NULL
;
1397 dynstr
= NULL
; /* avoid warning */
1398 saved_dynamic_data_offset
= 0; /* avoid warning */
1400 if (file_type
!= TCC_OUTPUT_OBJ
) {
1401 relocate_common_syms();
1403 tcc_add_linker_symbols(s1
);
1405 if (!s1
->static_link
) {
1407 int sym_index
, index
;
1408 ElfW(Sym
) *esym
, *sym_end
;
1410 if (file_type
== TCC_OUTPUT_EXE
) {
1412 /* allow override the dynamic loader */
1413 const char *elfint
= getenv("LD_SO");
1415 elfint
= elf_interp
;
1416 /* add interpreter section only if executable */
1417 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1418 interp
->sh_addralign
= 1;
1419 ptr
= section_ptr_add(interp
, 1+strlen(elfint
));
1420 strcpy(ptr
, elfint
);
1423 /* add dynamic symbol table */
1424 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1426 ".hash", SHF_ALLOC
);
1427 dynstr
= s1
->dynsym
->link
;
1429 /* add dynamic section */
1430 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1431 SHF_ALLOC
| SHF_WRITE
);
1432 dynamic
->link
= dynstr
;
1433 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1436 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1437 SHF_ALLOC
| SHF_EXECINSTR
);
1438 s1
->plt
->sh_entsize
= 4;
1442 /* scan for undefined symbols and see if they are in the
1443 dynamic symbols. If a symbol STT_FUNC is found, then we
1444 add it in the PLT. If a symbol STT_OBJECT is found, we
1445 add it in the .bss section with a suitable relocation */
1446 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1447 symtab_section
->data_offset
);
1448 if (file_type
== TCC_OUTPUT_EXE
) {
1449 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1452 if (sym
->st_shndx
== SHN_UNDEF
) {
1453 name
= symtab_section
->link
->data
+ sym
->st_name
;
1454 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1456 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1457 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1458 if (type
== STT_FUNC
) {
1459 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1461 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1462 } else if (type
== STT_OBJECT
) {
1463 unsigned long offset
;
1464 offset
= bss_section
->data_offset
;
1465 /* XXX: which alignment ? */
1466 offset
= (offset
+ 16 - 1) & -16;
1467 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1469 bss_section
->sh_num
, name
);
1470 put_elf_reloc(s1
->dynsym
, bss_section
,
1471 offset
, R_COPY
, index
);
1472 offset
+= esym
->st_size
;
1473 bss_section
->data_offset
= offset
;
1476 /* STB_WEAK undefined symbols are accepted */
1477 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1479 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1480 !strcmp(name
, "_fp_hw")) {
1482 error_noabort("undefined symbol '%s'", name
);
1485 } else if (s1
->rdynamic
&&
1486 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1487 /* if -rdynamic option, then export all non
1489 name
= symtab_section
->link
->data
+ sym
->st_name
;
1490 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1492 sym
->st_shndx
, name
);
1499 /* now look at unresolved dynamic symbols and export
1500 corresponding symbol */
1501 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1502 s1
->dynsymtab_section
->data_offset
);
1503 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1506 if (esym
->st_shndx
== SHN_UNDEF
) {
1507 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1508 sym_index
= find_elf_sym(symtab_section
, name
);
1510 /* XXX: avoid adding a symbol if already
1511 present because of -rdynamic ? */
1512 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1513 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1515 sym
->st_shndx
, name
);
1517 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1518 /* weak symbols can stay undefined */
1520 warning("undefined dynamic symbol '%s'", name
);
1527 /* shared library case : we simply export all the global symbols */
1528 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1529 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1530 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1533 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1534 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1535 if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
&&
1536 sym
->st_shndx
== SHN_UNDEF
) {
1537 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1539 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1541 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1542 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1544 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1549 name
= symtab_section
->link
->data
+ sym
->st_name
;
1550 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1552 sym
->st_shndx
, name
);
1553 s1
->symtab_to_dynsym
[sym
-
1554 (ElfW(Sym
) *)symtab_section
->data
] =
1561 build_got_entries(s1
);
1563 /* add a list of needed dlls */
1564 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1565 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1566 if (dllref
->level
== 0)
1567 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1571 put_dt(dynamic
, DT_RPATH
, put_elf_str(dynstr
, s1
->rpath
));
1573 /* XXX: currently, since we do not handle PIC code, we
1574 must relocate the readonly segments */
1575 if (file_type
== TCC_OUTPUT_DLL
) {
1577 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1578 put_dt(dynamic
, DT_TEXTREL
, 0);
1580 /* add necessary space for other entries */
1581 saved_dynamic_data_offset
= dynamic
->data_offset
;
1582 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * EXTRA_RELITEMS
;
1584 /* still need to build got entries in case of static link */
1585 build_got_entries(s1
);
1589 memset(&ehdr
, 0, sizeof(ehdr
));
1591 /* we add a section for symbols */
1592 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1593 put_elf_str(strsec
, "");
1595 /* compute number of sections */
1596 shnum
= s1
->nb_sections
;
1598 /* this array is used to reorder sections in the output file */
1599 section_order
= tcc_malloc(sizeof(int) * shnum
);
1600 section_order
[0] = 0;
1603 /* compute number of program headers */
1606 case TCC_OUTPUT_OBJ
:
1609 case TCC_OUTPUT_EXE
:
1610 if (!s1
->static_link
)
1611 phnum
= 4 + HAVE_PHDR
;
1615 case TCC_OUTPUT_DLL
:
1620 /* allocate strings for section names and decide if an unallocated
1621 section should be output */
1622 /* NOTE: the strsec section comes last, so its size is also
1624 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1625 s
= s1
->sections
[i
];
1626 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1628 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1633 s
->reloc
? s
->reloc
->name
: "n"
1636 /* when generating a DLL, we include relocations but we may
1638 if (file_type
== TCC_OUTPUT_DLL
&&
1639 s
->sh_type
== SHT_RELX
&&
1640 !(s
->sh_flags
& SHF_ALLOC
)) {
1641 /* //gr: avoid bogus relocs for empty (debug) sections */
1642 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1643 prepare_dynamic_rel(s1
, s
);
1644 else if (s1
->do_debug
)
1645 s
->sh_size
= s
->data_offset
;
1646 } else if (s1
->do_debug
||
1647 file_type
== TCC_OUTPUT_OBJ
||
1648 (s
->sh_flags
& SHF_ALLOC
) ||
1649 i
== (s1
->nb_sections
- 1)) {
1650 /* we output all sections if debug or object file */
1651 s
->sh_size
= s
->data_offset
;
1655 /* allocate program segment headers */
1656 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1658 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1659 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1664 /* compute section to program header mapping */
1665 if (s1
->has_text_addr
) {
1666 int a_offset
, p_offset
;
1667 addr
= s1
->text_addr
;
1668 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1670 a_offset
= addr
& (s1
->section_align
- 1);
1671 p_offset
= file_offset
& (s1
->section_align
- 1);
1672 if (a_offset
< p_offset
)
1673 a_offset
+= s1
->section_align
;
1674 file_offset
+= (a_offset
- p_offset
);
1676 if (file_type
== TCC_OUTPUT_DLL
)
1679 addr
= ELF_START_ADDR
;
1680 /* compute address after headers */
1681 addr
+= (file_offset
& (s1
->section_align
- 1));
1684 /* dynamic relocation table information, for .dynamic section */
1688 bss_addr
= bss_size
= 0;
1689 /* leave one program header for the program interpreter */
1692 ph
+= 1 + HAVE_PHDR
;
1694 for(j
= 0; j
< 2; j
++) {
1695 ph
->p_type
= PT_LOAD
;
1697 ph
->p_flags
= PF_R
| PF_X
;
1699 ph
->p_flags
= PF_R
| PF_W
;
1700 ph
->p_align
= s1
->section_align
;
1702 /* we do the following ordering: interp, symbol tables,
1703 relocations, progbits, nobits */
1704 /* XXX: do faster and simpler sorting */
1705 for(k
= 0; k
< 5; k
++) {
1706 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1707 s
= s1
->sections
[i
];
1708 /* compute if section should be included */
1710 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1714 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1715 (SHF_ALLOC
| SHF_WRITE
))
1721 } else if (s
->sh_type
== SHT_DYNSYM
||
1722 s
->sh_type
== SHT_STRTAB
||
1723 s
->sh_type
== SHT_HASH
) {
1726 } else if (s
->sh_type
== SHT_RELX
) {
1729 } else if (s
->sh_type
== SHT_NOBITS
) {
1736 section_order
[sh_order_index
++] = i
;
1738 /* section matches: we align it and add its size */
1740 addr
= (addr
+ s
->sh_addralign
- 1) &
1741 ~(s
->sh_addralign
- 1);
1742 file_offset
+= addr
- tmp
;
1743 s
->sh_offset
= file_offset
;
1746 /* update program header infos */
1747 if (ph
->p_offset
== 0) {
1748 ph
->p_offset
= file_offset
;
1750 ph
->p_paddr
= ph
->p_vaddr
;
1752 /* update dynamic relocation infos */
1753 if (s
->sh_type
== SHT_RELX
) {
1754 #if defined(__FreeBSD__)
1755 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.got")) { // rel_size == 0) {
1757 rel_size
+= s
->sh_size
; // XXX only first rel.
1759 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.bss")) { // rel_size == 0) {
1761 bss_size
= s
->sh_size
; // XXX only first rel.
1766 rel_size
+= s
->sh_size
;
1770 if (s
->sh_type
!= SHT_NOBITS
)
1771 file_offset
+= s
->sh_size
;
1774 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1775 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1778 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1779 /* if in the middle of a page, we duplicate the page in
1780 memory so that one copy is RX and the other is RW */
1781 if ((addr
& (s1
->section_align
- 1)) != 0)
1782 addr
+= s1
->section_align
;
1784 addr
= (addr
+ s1
->section_align
- 1) & ~(s1
->section_align
- 1);
1785 file_offset
= (file_offset
+ s1
->section_align
- 1) &
1786 ~(s1
->section_align
- 1);
1791 /* if interpreter, then add corresponing program header */
1795 #if defined(__FreeBSD__)
1797 int len
= phnum
* sizeof(ElfW(Phdr
));
1799 ph
->p_type
= PT_PHDR
;
1800 ph
->p_offset
= sizeof(ElfW(Ehdr
));
1801 ph
->p_vaddr
= interp
->sh_addr
- len
;
1802 ph
->p_paddr
= ph
->p_vaddr
;
1803 ph
->p_filesz
= ph
->p_memsz
= len
;
1804 ph
->p_flags
= PF_R
| PF_X
;
1805 ph
->p_align
= 4; // interp->sh_addralign;
1810 ph
->p_type
= PT_INTERP
;
1811 ph
->p_offset
= interp
->sh_offset
;
1812 ph
->p_vaddr
= interp
->sh_addr
;
1813 ph
->p_paddr
= ph
->p_vaddr
;
1814 ph
->p_filesz
= interp
->sh_size
;
1815 ph
->p_memsz
= interp
->sh_size
;
1817 ph
->p_align
= interp
->sh_addralign
;
1820 /* if dynamic section, then add corresponing program header */
1824 ph
= &phdr
[phnum
- 1];
1826 ph
->p_type
= PT_DYNAMIC
;
1827 ph
->p_offset
= dynamic
->sh_offset
;
1828 ph
->p_vaddr
= dynamic
->sh_addr
;
1829 ph
->p_paddr
= ph
->p_vaddr
;
1830 ph
->p_filesz
= dynamic
->sh_size
;
1831 ph
->p_memsz
= dynamic
->sh_size
;
1832 ph
->p_flags
= PF_R
| PF_W
;
1833 ph
->p_align
= dynamic
->sh_addralign
;
1835 /* put GOT dynamic section address */
1836 put32(s1
->got
->data
, dynamic
->sh_addr
);
1838 /* relocate the PLT */
1839 if (file_type
== TCC_OUTPUT_EXE
1840 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1841 || file_type
== TCC_OUTPUT_DLL
1847 p_end
= p
+ s1
->plt
->data_offset
;
1849 #if defined(TCC_TARGET_I386)
1850 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1851 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1854 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1857 #elif defined(TCC_TARGET_X86_64)
1858 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1859 put32(p
+ 2, get32(p
+ 2) + x
);
1860 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1863 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1866 #elif defined(TCC_TARGET_ARM)
1868 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1871 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1874 #elif defined(TCC_TARGET_C67)
1877 #error unsupported CPU
1882 /* relocate symbols in .dynsym */
1883 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1884 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1887 if (sym
->st_shndx
== SHN_UNDEF
) {
1888 /* relocate to the PLT if the symbol corresponds
1891 sym
->st_value
+= s1
->plt
->sh_addr
;
1892 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1893 /* do symbol relocation */
1894 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1898 /* put dynamic section entries */
1899 dynamic
->data_offset
= saved_dynamic_data_offset
;
1900 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1901 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1902 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1903 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1904 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1905 #ifdef TCC_TARGET_X86_64
1906 put_dt(dynamic
, DT_RELA
, rel_addr
);
1907 put_dt(dynamic
, DT_RELASZ
, rel_size
);
1908 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1910 #if defined(__FreeBSD__)
1911 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
1912 put_dt(dynamic
, DT_PLTRELSZ
, rel_size
);
1913 put_dt(dynamic
, DT_JMPREL
, rel_addr
);
1914 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
1915 put_dt(dynamic
, DT_REL
, bss_addr
);
1916 put_dt(dynamic
, DT_RELSZ
, bss_size
);
1918 put_dt(dynamic
, DT_REL
, rel_addr
);
1919 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1920 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1924 put_dt(dynamic
, DT_DEBUG
, 0);
1925 put_dt(dynamic
, DT_NULL
, 0);
1928 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1929 ehdr
.e_phnum
= phnum
;
1930 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1933 /* all other sections come after */
1934 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1935 s
= s1
->sections
[i
];
1936 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1938 section_order
[sh_order_index
++] = i
;
1940 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1941 ~(s
->sh_addralign
- 1);
1942 s
->sh_offset
= file_offset
;
1943 if (s
->sh_type
!= SHT_NOBITS
)
1944 file_offset
+= s
->sh_size
;
1947 /* if building executable or DLL, then relocate each section
1948 except the GOT which is already relocated */
1949 if (file_type
!= TCC_OUTPUT_OBJ
) {
1950 relocate_syms(s1
, 0);
1952 if (s1
->nb_errors
!= 0) {
1958 /* relocate sections */
1959 /* XXX: ignore sections with allocated relocations ? */
1960 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1961 s
= s1
->sections
[i
];
1962 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1963 relocate_section(s1
, s
);
1966 /* relocate relocation entries if the relocation tables are
1967 allocated in the executable */
1968 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1969 s
= s1
->sections
[i
];
1970 if ((s
->sh_flags
& SHF_ALLOC
) &&
1971 s
->sh_type
== SHT_RELX
) {
1972 relocate_rel(s1
, s
);
1976 /* get entry point address */
1977 if (file_type
== TCC_OUTPUT_EXE
)
1978 ehdr
.e_entry
= (uplong
)tcc_get_symbol_err(s1
, "_start");
1980 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1983 /* write elf file */
1984 if (file_type
== TCC_OUTPUT_OBJ
)
1988 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1990 error_noabort("could not write '%s'", filename
);
1993 f
= fdopen(fd
, "wb");
1995 printf("<- %s\n", filename
);
1997 #ifdef TCC_TARGET_COFF
1998 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1999 tcc_output_coff(s1
, f
);
2002 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
2003 sort_syms(s1
, symtab_section
);
2006 file_offset
= (file_offset
+ 3) & -4;
2009 ehdr
.e_ident
[0] = ELFMAG0
;
2010 ehdr
.e_ident
[1] = ELFMAG1
;
2011 ehdr
.e_ident
[2] = ELFMAG2
;
2012 ehdr
.e_ident
[3] = ELFMAG3
;
2013 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
2014 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2015 ehdr
.e_ident
[6] = EV_CURRENT
;
2017 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2019 #ifdef TCC_TARGET_ARM
2021 ehdr
.e_ident
[EI_OSABI
] = 0;
2022 ehdr
.e_flags
= 4 << 24;
2024 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2029 case TCC_OUTPUT_EXE
:
2030 ehdr
.e_type
= ET_EXEC
;
2032 case TCC_OUTPUT_DLL
:
2033 ehdr
.e_type
= ET_DYN
;
2035 case TCC_OUTPUT_OBJ
:
2036 ehdr
.e_type
= ET_REL
;
2039 ehdr
.e_machine
= EM_TCC_TARGET
;
2040 ehdr
.e_version
= EV_CURRENT
;
2041 ehdr
.e_shoff
= file_offset
;
2042 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2043 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2044 ehdr
.e_shnum
= shnum
;
2045 ehdr
.e_shstrndx
= shnum
- 1;
2047 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2048 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2049 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2051 for(i
=1;i
<s1
->nb_sections
;i
++) {
2052 s
= s1
->sections
[section_order
[i
]];
2053 if (s
->sh_type
!= SHT_NOBITS
) {
2054 #if defined(__FreeBSD__)
2055 if (s
->sh_type
== SHT_DYNSYM
)
2056 patch_dynsym_undef(s1
, s
);
2058 while (offset
< s
->sh_offset
) {
2063 fwrite(s
->data
, 1, size
, f
);
2068 /* output section headers */
2069 while (offset
< ehdr
.e_shoff
) {
2074 for(i
=0;i
<s1
->nb_sections
;i
++) {
2076 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2077 s
= s1
->sections
[i
];
2079 sh
->sh_name
= s
->sh_name
;
2080 sh
->sh_type
= s
->sh_type
;
2081 sh
->sh_flags
= s
->sh_flags
;
2082 sh
->sh_entsize
= s
->sh_entsize
;
2083 sh
->sh_info
= s
->sh_info
;
2085 sh
->sh_link
= s
->link
->sh_num
;
2086 sh
->sh_addralign
= s
->sh_addralign
;
2087 sh
->sh_addr
= s
->sh_addr
;
2088 sh
->sh_offset
= s
->sh_offset
;
2089 sh
->sh_size
= s
->sh_size
;
2091 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2094 tcc_output_binary(s1
, f
, section_order
);
2100 tcc_free(s1
->symtab_to_dynsym
);
2101 tcc_free(section_order
);
2103 tcc_free(s1
->got_offsets
);
2107 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2110 #ifdef TCC_TARGET_PE
2111 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2112 ret
= pe_output_file(s
, filename
);
2116 ret
= elf_output_file(s
, filename
);
2121 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2125 data
= tcc_malloc(size
);
2126 lseek(fd
, file_offset
, SEEK_SET
);
2127 read(fd
, data
, size
);
2131 typedef struct SectionMergeInfo
{
2132 Section
*s
; /* corresponding existing section */
2133 unsigned long offset
; /* offset of the new section in the existing section */
2134 uint8_t new_section
; /* true if section 's' was added */
2135 uint8_t link_once
; /* true if link once section */
2138 /* load an object file and merge it with current files */
2139 /* XXX: handle correctly stab (debug) info */
2140 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
2141 int fd
, unsigned long file_offset
)
2144 ElfW(Shdr
) *shdr
, *sh
;
2145 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2146 unsigned char *strsec
, *strtab
;
2147 int *old_to_new_syms
;
2148 char *sh_name
, *name
;
2149 SectionMergeInfo
*sm_table
, *sm
;
2150 ElfW(Sym
) *sym
, *symtab
;
2151 ElfW_Rel
*rel
, *rel_end
;
2157 stab_index
= stabstr_index
= 0;
2159 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2161 if (ehdr
.e_ident
[0] != ELFMAG0
||
2162 ehdr
.e_ident
[1] != ELFMAG1
||
2163 ehdr
.e_ident
[2] != ELFMAG2
||
2164 ehdr
.e_ident
[3] != ELFMAG3
)
2166 /* test if object file */
2167 if (ehdr
.e_type
!= ET_REL
)
2169 /* test CPU specific stuff */
2170 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2171 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2173 error_noabort("invalid object file");
2177 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2178 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2179 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2181 /* load section names */
2182 sh
= &shdr
[ehdr
.e_shstrndx
];
2183 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2185 /* load symtab and strtab */
2186 old_to_new_syms
= NULL
;
2190 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2192 if (sh
->sh_type
== SHT_SYMTAB
) {
2194 error_noabort("object must contain only one symtab");
2199 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2200 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2201 sm_table
[i
].s
= symtab_section
;
2203 /* now load strtab */
2204 sh
= &shdr
[sh
->sh_link
];
2205 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2209 /* now examine each section and try to merge its content with the
2211 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2212 /* no need to examine section name strtab */
2213 if (i
== ehdr
.e_shstrndx
)
2216 sh_name
= strsec
+ sh
->sh_name
;
2217 /* ignore sections types we do not handle */
2218 if (sh
->sh_type
!= SHT_PROGBITS
&&
2219 sh
->sh_type
!= SHT_RELX
&&
2221 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2223 sh
->sh_type
!= SHT_NOBITS
&&
2224 strcmp(sh_name
, ".stabstr")
2227 if (sh
->sh_addralign
< 1)
2228 sh
->sh_addralign
= 1;
2229 /* find corresponding section, if any */
2230 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2231 s
= s1
->sections
[j
];
2232 if (!strcmp(s
->name
, sh_name
)) {
2233 if (!strncmp(sh_name
, ".gnu.linkonce",
2234 sizeof(".gnu.linkonce") - 1)) {
2235 /* if a 'linkonce' section is already present, we
2236 do not add it again. It is a little tricky as
2237 symbols can still be defined in
2239 sm_table
[i
].link_once
= 1;
2246 /* not found: create new section */
2247 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2248 /* take as much info as possible from the section. sh_link and
2249 sh_info will be updated later */
2250 s
->sh_addralign
= sh
->sh_addralign
;
2251 s
->sh_entsize
= sh
->sh_entsize
;
2252 sm_table
[i
].new_section
= 1;
2254 if (sh
->sh_type
!= s
->sh_type
) {
2255 error_noabort("invalid section type");
2259 /* align start of section */
2260 offset
= s
->data_offset
;
2262 if (0 == strcmp(sh_name
, ".stab")) {
2266 if (0 == strcmp(sh_name
, ".stabstr")) {
2271 size
= sh
->sh_addralign
- 1;
2272 offset
= (offset
+ size
) & ~size
;
2273 if (sh
->sh_addralign
> s
->sh_addralign
)
2274 s
->sh_addralign
= sh
->sh_addralign
;
2275 s
->data_offset
= offset
;
2277 sm_table
[i
].offset
= offset
;
2279 /* concatenate sections */
2281 if (sh
->sh_type
!= SHT_NOBITS
) {
2283 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2284 ptr
= section_ptr_add(s
, size
);
2285 read(fd
, ptr
, size
);
2287 s
->data_offset
+= size
;
2292 /* //gr relocate stab strings */
2293 if (stab_index
&& stabstr_index
) {
2296 s
= sm_table
[stab_index
].s
;
2297 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2298 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2299 o
= sm_table
[stabstr_index
].offset
;
2301 a
->n_strx
+= o
, a
++;
2304 /* second short pass to update sh_link and sh_info fields of new
2306 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2308 if (!s
|| !sm_table
[i
].new_section
)
2311 if (sh
->sh_link
> 0)
2312 s
->link
= sm_table
[sh
->sh_link
].s
;
2313 if (sh
->sh_type
== SHT_RELX
) {
2314 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2315 /* update backward link */
2316 s1
->sections
[s
->sh_info
]->reloc
= s
;
2321 /* resolve symbols */
2322 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2325 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2326 if (sym
->st_shndx
!= SHN_UNDEF
&&
2327 sym
->st_shndx
< SHN_LORESERVE
) {
2328 sm
= &sm_table
[sym
->st_shndx
];
2329 if (sm
->link_once
) {
2330 /* if a symbol is in a link once section, we use the
2331 already defined symbol. It is very important to get
2332 correct relocations */
2333 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2334 name
= strtab
+ sym
->st_name
;
2335 sym_index
= find_elf_sym(symtab_section
, name
);
2337 old_to_new_syms
[i
] = sym_index
;
2341 /* if no corresponding section added, no need to add symbol */
2344 /* convert section number */
2345 sym
->st_shndx
= sm
->s
->sh_num
;
2347 sym
->st_value
+= sm
->offset
;
2350 name
= strtab
+ sym
->st_name
;
2351 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2352 sym
->st_info
, sym
->st_other
,
2353 sym
->st_shndx
, name
);
2354 old_to_new_syms
[i
] = sym_index
;
2357 /* third pass to patch relocation entries */
2358 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2363 offset
= sm_table
[i
].offset
;
2364 switch(s
->sh_type
) {
2366 /* take relocation offset information */
2367 offseti
= sm_table
[sh
->sh_info
].offset
;
2368 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2369 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2374 /* convert symbol index */
2375 type
= ELFW(R_TYPE
)(rel
->r_info
);
2376 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2377 /* NOTE: only one symtab assumed */
2378 if (sym_index
>= nb_syms
)
2380 sym_index
= old_to_new_syms
[sym_index
];
2381 /* ignore link_once in rel section. */
2382 if (!sym_index
&& !sm
->link_once
) {
2384 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2385 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2388 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2389 /* offset the relocation offset */
2390 rel
->r_offset
+= offseti
;
2402 tcc_free(old_to_new_syms
);
2409 typedef struct ArchiveHeader
{
2410 char ar_name
[16]; /* name of this member */
2411 char ar_date
[12]; /* file mtime */
2412 char ar_uid
[6]; /* owner uid; printed as decimal */
2413 char ar_gid
[6]; /* owner gid; printed as decimal */
2414 char ar_mode
[8]; /* file mode, printed as octal */
2415 char ar_size
[10]; /* file size, printed as decimal */
2416 char ar_fmag
[2]; /* should contain ARFMAG */
2419 static int get_be32(const uint8_t *b
)
2421 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2424 /* load only the objects which resolve undefined symbols */
2425 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2427 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2429 const char *ar_names
, *p
;
2430 const uint8_t *ar_index
;
2433 data
= tcc_malloc(size
);
2434 if (read(fd
, data
, size
) != size
)
2436 nsyms
= get_be32(data
);
2437 ar_index
= data
+ 4;
2438 ar_names
= ar_index
+ nsyms
* 4;
2442 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2443 sym_index
= find_elf_sym(symtab_section
, p
);
2445 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2446 if(sym
->st_shndx
== SHN_UNDEF
) {
2447 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2449 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2452 lseek(fd
, off
, SEEK_SET
);
2453 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2468 /* load a '.a' file */
2469 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
)
2476 unsigned long file_offset
;
2478 /* skip magic which was already checked */
2479 read(fd
, magic
, sizeof(magic
));
2482 len
= read(fd
, &hdr
, sizeof(hdr
));
2485 if (len
!= sizeof(hdr
)) {
2486 error_noabort("invalid archive");
2489 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2490 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2491 size
= strtol(ar_size
, NULL
, 0);
2492 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2493 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2494 if (ar_name
[i
] != ' ')
2497 ar_name
[i
+ 1] = '\0';
2498 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2499 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2501 size
= (size
+ 1) & ~1;
2502 if (!strcmp(ar_name
, "/")) {
2503 /* coff symbol table : we handle it */
2504 if(s1
->alacarte_link
)
2505 return tcc_load_alacarte(s1
, fd
, size
);
2506 } else if (!strcmp(ar_name
, "//") ||
2507 !strcmp(ar_name
, "__.SYMDEF") ||
2508 !strcmp(ar_name
, "__.SYMDEF/") ||
2509 !strcmp(ar_name
, "ARFILENAMES/")) {
2510 /* skip symbol table or archive names */
2512 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2515 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2520 #ifndef TCC_TARGET_PE
2521 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2522 is referenced by the user (so it should be added as DT_NEEDED in
2523 the generated ELF file) */
2524 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2527 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2528 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2529 ElfW(Sym
) *sym
, *dynsym
;
2530 ElfW(Dyn
) *dt
, *dynamic
;
2531 unsigned char *dynstr
;
2532 const char *name
, *soname
;
2533 DLLReference
*dllref
;
2535 read(fd
, &ehdr
, sizeof(ehdr
));
2537 /* test CPU specific stuff */
2538 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2539 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2540 error_noabort("bad architecture");
2545 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2547 /* load dynamic section and dynamic symbols */
2551 dynsym
= NULL
; /* avoid warning */
2552 dynstr
= NULL
; /* avoid warning */
2553 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2554 switch(sh
->sh_type
) {
2556 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2557 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2560 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2561 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2562 sh1
= &shdr
[sh
->sh_link
];
2563 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2570 /* compute the real library name */
2571 soname
= tcc_basename(filename
);
2573 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2574 if (dt
->d_tag
== DT_SONAME
) {
2575 soname
= dynstr
+ dt
->d_un
.d_val
;
2579 /* if the dll is already loaded, do not load it */
2580 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2581 dllref
= s1
->loaded_dlls
[i
];
2582 if (!strcmp(soname
, dllref
->name
)) {
2583 /* but update level if needed */
2584 if (level
< dllref
->level
)
2585 dllref
->level
= level
;
2591 // printf("loading dll '%s'\n", soname);
2593 /* add the dll and its level */
2594 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2595 dllref
->level
= level
;
2596 strcpy(dllref
->name
, soname
);
2597 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2599 /* add dynamic symbols in dynsym_section */
2600 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2601 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2602 if (sym_bind
== STB_LOCAL
)
2604 name
= dynstr
+ sym
->st_name
;
2605 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2606 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2609 /* load all referenced DLLs */
2610 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2613 name
= dynstr
+ dt
->d_un
.d_val
;
2614 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2615 dllref
= s1
->loaded_dlls
[j
];
2616 if (!strcmp(name
, dllref
->name
))
2617 goto already_loaded
;
2619 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2620 error_noabort("referenced dll '%s' not found", name
);
2637 #define LD_TOK_NAME 256
2638 #define LD_TOK_EOF (-1)
2640 /* return next ld script token */
2641 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2659 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2660 ch
= file
->buf_ptr
[0];
2668 /* case 'a' ... 'z': */
2695 /* case 'A' ... 'z': */
2730 if (!((ch
>= 'a' && ch
<= 'z') ||
2731 (ch
>= 'A' && ch
<= 'Z') ||
2732 (ch
>= '0' && ch
<= '9') ||
2733 strchr("/.-_+=$:\\,~", ch
)))
2735 if ((q
- name
) < name_size
- 1) {
2752 printf("tok=%c %d\n", c
, c
);
2753 if (c
== LD_TOK_NAME
)
2754 printf(" name=%s\n", name
);
2759 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2761 char filename
[1024];
2764 t
= ld_next(s1
, filename
, sizeof(filename
));
2767 t
= ld_next(s1
, filename
, sizeof(filename
));
2769 if (t
== LD_TOK_EOF
) {
2770 error_noabort("unexpected end of file");
2772 } else if (t
== ')') {
2774 } else if (t
!= LD_TOK_NAME
) {
2775 error_noabort("filename expected");
2778 if (!strcmp(filename
, "AS_NEEDED")) {
2779 ret
= ld_add_file_list(s1
, 1);
2783 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2785 tcc_add_file(s1
, filename
);
2787 t
= ld_next(s1
, filename
, sizeof(filename
));
2789 t
= ld_next(s1
, filename
, sizeof(filename
));
2795 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2797 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
)
2800 char filename
[1024];
2803 ch
= file
->buf_ptr
[0];
2806 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2807 if (t
== LD_TOK_EOF
)
2809 else if (t
!= LD_TOK_NAME
)
2811 if (!strcmp(cmd
, "INPUT") ||
2812 !strcmp(cmd
, "GROUP")) {
2813 ret
= ld_add_file_list(s1
, 0);
2816 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2817 !strcmp(cmd
, "TARGET")) {
2818 /* ignore some commands */
2819 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2823 t
= ld_next(s1
, filename
, sizeof(filename
));
2824 if (t
== LD_TOK_EOF
) {
2825 error_noabort("unexpected end of file");
2827 } else if (t
== ')') {