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 /* Define this to get some debug output during relocation processing. */
26 /********************************************************/
27 /* global variables */
29 ST_DATA Section
*text_section
, *data_section
, *bss_section
; /* predefined sections */
30 ST_DATA Section
*cur_text_section
; /* current section where function code is generated */
32 ST_DATA Section
*last_text_section
; /* to handle .previous asm directive */
34 #ifdef CONFIG_TCC_BCHECK
35 /* bound check related sections */
36 ST_DATA Section
*bounds_section
; /* contains global data bound description */
37 ST_DATA Section
*lbounds_section
; /* contains local data bound description */
40 ST_DATA Section
*symtab_section
, *strtab_section
;
42 ST_DATA Section
*stab_section
, *stabstr_section
;
44 /* XXX: avoid static variable */
45 static int new_undef_sym
= 0; /* Is there a new undefined sym since last new_undef_sym() */
47 /* ------------------------------------------------------------------------- */
49 ST_FUNC
void tccelf_new(TCCState
*s
)
52 dynarray_add((void ***)&s
->sections
, &s
->nb_sections
, NULL
);
54 /* create standard sections */
55 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
56 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
57 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
59 /* symbols are always generated for linking stage */
60 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
62 ".hashtab", SHF_PRIVATE
);
63 strtab_section
= symtab_section
->link
;
64 s
->symtab
= symtab_section
;
66 /* private symbol table for dynamic symbols */
67 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
,
69 ".dynhashtab", SHF_PRIVATE
);
72 #ifdef CONFIG_TCC_BCHECK
73 ST_FUNC
void tccelf_bounds_new(TCCState
*s
)
75 /* create bounds sections */
76 bounds_section
= new_section(s
, ".bounds",
77 SHT_PROGBITS
, SHF_ALLOC
);
78 lbounds_section
= new_section(s
, ".lbounds",
79 SHT_PROGBITS
, SHF_ALLOC
);
83 ST_FUNC
void tccelf_stab_new(TCCState
*s
)
85 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
86 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
87 stabstr_section
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
88 put_elf_str(stabstr_section
, "");
89 stab_section
->link
= stabstr_section
;
91 put_stabs("", 0, 0, 0, 0);
94 static void free_section(Section
*s
)
99 ST_FUNC
void tccelf_delete(TCCState
*s1
)
103 /* free all sections */
104 for(i
= 1; i
< s1
->nb_sections
; i
++)
105 free_section(s1
->sections
[i
]);
106 dynarray_reset(&s1
->sections
, &s1
->nb_sections
);
108 for(i
= 0; i
< s1
->nb_priv_sections
; i
++)
109 free_section(s1
->priv_sections
[i
]);
110 dynarray_reset(&s1
->priv_sections
, &s1
->nb_priv_sections
);
112 /* free any loaded DLLs */
114 for ( i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
115 DLLReference
*ref
= s1
->loaded_dlls
[i
];
118 FreeLibrary((HMODULE
)ref
->handle
);
120 dlclose(ref
->handle
);
124 /* free loaded dlls array */
125 dynarray_reset(&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
);
128 ST_FUNC Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
132 sec
= tcc_mallocz(sizeof(Section
) + strlen(name
));
133 strcpy(sec
->name
, name
);
134 sec
->sh_type
= sh_type
;
135 sec
->sh_flags
= sh_flags
;
143 sec
->sh_addralign
= 4;
146 sec
->sh_addralign
= 1;
149 sec
->sh_addralign
= PTR_SIZE
; /* gcc/pcc default aligment */
153 if (sh_flags
& SHF_PRIVATE
) {
154 dynarray_add((void ***)&s1
->priv_sections
, &s1
->nb_priv_sections
, sec
);
156 sec
->sh_num
= s1
->nb_sections
;
157 dynarray_add((void ***)&s1
->sections
, &s1
->nb_sections
, sec
);
163 /* realloc section and set its content to zero */
164 ST_FUNC
void section_realloc(Section
*sec
, unsigned long new_size
)
169 size
= sec
->data_allocated
;
172 while (size
< new_size
)
174 data
= tcc_realloc(sec
->data
, size
);
175 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
177 sec
->data_allocated
= size
;
180 /* reserve at least 'size' bytes in section 'sec' from
182 ST_FUNC
void *section_ptr_add(Section
*sec
, addr_t size
)
184 size_t offset
, offset1
;
186 offset
= sec
->data_offset
;
187 offset1
= offset
+ size
;
188 if (offset1
> sec
->data_allocated
)
189 section_realloc(sec
, offset1
);
190 sec
->data_offset
= offset1
;
191 return sec
->data
+ offset
;
194 /* reserve at least 'size' bytes from section start */
195 ST_FUNC
void section_reserve(Section
*sec
, unsigned long size
)
197 if (size
> sec
->data_allocated
)
198 section_realloc(sec
, size
);
199 if (size
> sec
->data_offset
)
200 sec
->data_offset
= size
;
203 /* return a reference to a section, and create it if it does not
205 ST_FUNC Section
*find_section(TCCState
*s1
, const char *name
)
209 for(i
= 1; i
< s1
->nb_sections
; i
++) {
210 sec
= s1
->sections
[i
];
211 if (!strcmp(name
, sec
->name
))
214 /* sections are created as PROGBITS */
215 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
218 /* ------------------------------------------------------------------------- */
220 ST_FUNC
int put_elf_str(Section
*s
, const char *sym
)
225 len
= strlen(sym
) + 1;
226 offset
= s
->data_offset
;
227 ptr
= section_ptr_add(s
, len
);
228 memcpy(ptr
, sym
, len
);
232 /* elf symbol hashing function */
233 static unsigned long elf_hash(const unsigned char *name
)
235 unsigned long h
= 0, g
;
238 h
= (h
<< 4) + *name
++;
247 /* rebuild hash table of section s */
248 /* NOTE: we do factorize the hash table code to go faster */
249 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
252 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
253 unsigned char *strtab
;
255 strtab
= s
->link
->data
;
256 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
258 s
->hash
->data_offset
= 0;
259 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
264 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
265 ptr
+= nb_buckets
+ 1;
267 sym
= (ElfW(Sym
) *)s
->data
+ 1;
268 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
269 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
270 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
281 /* return the symbol number */
282 ST_FUNC
int put_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
283 int info
, int other
, int shndx
, const char *name
)
285 int name_offset
, sym_index
;
290 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
292 name_offset
= put_elf_str(s
->link
, name
);
295 /* XXX: endianness */
296 sym
->st_name
= name_offset
;
297 sym
->st_value
= value
;
300 sym
->st_other
= other
;
301 sym
->st_shndx
= shndx
;
302 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
306 ptr
= section_ptr_add(hs
, sizeof(int));
307 base
= (int *)hs
->data
;
308 /* only add global or weak symbols */
309 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
310 /* add another hashing entry */
312 h
= elf_hash((unsigned char *) name
) % nbuckets
;
314 base
[2 + h
] = sym_index
;
316 /* we resize the hash table */
317 hs
->nb_hashed_syms
++;
318 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
319 rebuild_hash(s
, 2 * nbuckets
);
329 /* find global ELF symbol 'name' and return its index. Return 0 if not
331 ST_FUNC
int find_elf_sym(Section
*s
, const char *name
)
335 int nbuckets
, sym_index
, h
;
341 nbuckets
= ((int *)hs
->data
)[0];
342 h
= elf_hash((unsigned char *) name
) % nbuckets
;
343 sym_index
= ((int *)hs
->data
)[2 + h
];
344 while (sym_index
!= 0) {
345 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
346 name1
= (char *) s
->link
->data
+ sym
->st_name
;
347 if (!strcmp(name
, name1
))
349 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
354 /* return elf symbol value, signal error if 'err' is nonzero */
355 ST_FUNC addr_t
get_elf_sym_addr(TCCState
*s
, const char *name
, int err
)
360 sym_index
= find_elf_sym(s
->symtab
, name
);
361 sym
= &((ElfW(Sym
) *)s
->symtab
->data
)[sym_index
];
362 if (!sym_index
|| sym
->st_shndx
== SHN_UNDEF
) {
364 tcc_error("%s not defined", name
);
367 return sym
->st_value
;
370 /* return elf symbol value */
371 LIBTCCAPI
void *tcc_get_symbol(TCCState
*s
, const char *name
)
373 return (void*)(uintptr_t)get_elf_sym_addr(s
, name
, 0);
376 #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
377 /* return elf symbol value or error */
378 ST_FUNC
void* tcc_get_symbol_err(TCCState
*s
, const char *name
)
380 return (void*)(uintptr_t)get_elf_sym_addr(s
, name
, 1);
384 /* add an elf symbol : check if it is already defined and patch
385 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
386 ST_FUNC
int set_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
387 int info
, int other
, int shndx
, const char *name
)
390 int sym_bind
, sym_index
, sym_type
, esym_bind
;
391 unsigned char sym_vis
, esym_vis
, new_vis
;
393 sym_bind
= ELFW(ST_BIND
)(info
);
394 sym_type
= ELFW(ST_TYPE
)(info
);
395 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
397 sym_index
= find_elf_sym(s
, name
);
398 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
399 if (sym_index
&& esym
->st_value
== value
&& esym
->st_size
== size
400 && esym
->st_info
== info
&& esym
->st_other
== other
401 && esym
->st_shndx
== shndx
)
404 if (sym_bind
!= STB_LOCAL
) {
405 /* we search global or weak symbols */
408 if (esym
->st_shndx
!= SHN_UNDEF
) {
409 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
410 /* propagate the most constraining visibility */
411 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
412 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
413 if (esym_vis
== STV_DEFAULT
) {
415 } else if (sym_vis
== STV_DEFAULT
) {
418 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
420 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
422 other
= esym
->st_other
; /* in case we have to patch esym */
423 if (shndx
== SHN_UNDEF
) {
424 /* ignore adding of undefined symbol if the
425 corresponding symbol is already defined */
426 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
427 /* global overrides weak, so patch */
429 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
430 /* weak is ignored if already global */
431 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_WEAK
) {
432 /* keep first-found weak definition, ignore subsequents */
433 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
434 /* ignore hidden symbols after */
435 } else if ((esym
->st_shndx
== SHN_COMMON
436 || esym
->st_shndx
== bss_section
->sh_num
)
437 && (shndx
< SHN_LORESERVE
438 && shndx
!= bss_section
->sh_num
)) {
439 /* data symbol gets precedence over common/bss */
441 } else if (shndx
== SHN_COMMON
|| shndx
== bss_section
->sh_num
) {
442 /* data symbol keeps precedence over common/bss */
443 } else if (s
== tcc_state
->dynsymtab_section
) {
444 /* we accept that two DLL define the same symbol */
447 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
448 sym_bind
, shndx
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
450 tcc_error_noabort("'%s' defined twice", name
);
454 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
455 esym
->st_shndx
= shndx
;
457 esym
->st_value
= value
;
458 esym
->st_size
= size
;
459 esym
->st_other
= other
;
463 sym_index
= put_elf_sym(s
, value
, size
,
464 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
471 ST_FUNC
void put_elf_reloca(Section
*symtab
, Section
*s
, unsigned long offset
,
472 int type
, int symbol
, addr_t addend
)
480 /* if no relocation section, create it */
481 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
482 /* if the symtab is allocated, then we consider the relocation
484 sr
= new_section(tcc_state
, buf
, SHT_RELX
, symtab
->sh_flags
);
485 sr
->sh_entsize
= sizeof(ElfW_Rel
);
487 sr
->sh_info
= s
->sh_num
;
490 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
491 rel
->r_offset
= offset
;
492 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
493 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
494 rel
->r_addend
= addend
;
497 tcc_error("non-zero addend on REL architecture");
501 ST_FUNC
void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
502 int type
, int symbol
)
504 put_elf_reloca(symtab
, s
, offset
, type
, symbol
, 0);
507 /* put stab debug information */
509 ST_FUNC
void put_stabs(const char *str
, int type
, int other
, int desc
,
514 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
516 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
521 sym
->n_other
= other
;
523 sym
->n_value
= value
;
526 ST_FUNC
void put_stabs_r(const char *str
, int type
, int other
, int desc
,
527 unsigned long value
, Section
*sec
, int sym_index
)
529 put_stabs(str
, type
, other
, desc
, value
);
530 put_elf_reloc(symtab_section
, stab_section
,
531 stab_section
->data_offset
- sizeof(unsigned int),
532 R_DATA_32
, sym_index
);
535 ST_FUNC
void put_stabn(int type
, int other
, int desc
, int value
)
537 put_stabs(NULL
, type
, other
, desc
, value
);
540 ST_FUNC
void put_stabd(int type
, int other
, int desc
)
542 put_stabs(NULL
, type
, other
, desc
, 0);
545 /* Browse each elem of type <type> in section <sec> starting at elem <startoff>
546 using variable <elem> */
547 #define for_each_elem(sec, startoff, elem, type) \
548 for (elem = (type *) sec->data + startoff; \
549 elem < (type *) (sec->data + sec->data_offset); elem++)
551 /* In an ELF file symbol table, the local symbols must appear below
552 the global and weak ones. Since TCC cannot sort it while generating
553 the code, we must do it after. All the relocation tables are also
554 modified to take into account the symbol table sorting */
555 static void sort_syms(TCCState
*s1
, Section
*s
)
557 int *old_to_new_syms
;
565 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
566 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
567 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
569 /* first pass for local symbols */
570 p
= (ElfW(Sym
) *)s
->data
;
572 for(i
= 0; i
< nb_syms
; i
++) {
573 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
574 old_to_new_syms
[i
] = q
- new_syms
;
579 /* save the number of local symbols in section header */
580 s
->sh_info
= q
- new_syms
;
582 /* then second pass for non local symbols */
583 p
= (ElfW(Sym
) *)s
->data
;
584 for(i
= 0; i
< nb_syms
; i
++) {
585 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
586 old_to_new_syms
[i
] = q
- new_syms
;
592 /* we copy the new symbols to the old */
593 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
596 /* now we modify all the relocations */
597 for(i
= 1; i
< s1
->nb_sections
; i
++) {
598 sr
= s1
->sections
[i
];
599 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
600 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
601 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
602 type
= ELFW(R_TYPE
)(rel
->r_info
);
603 sym_index
= old_to_new_syms
[sym_index
];
604 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
609 tcc_free(old_to_new_syms
);
612 /* relocate common symbols in the .bss section */
613 ST_FUNC
void relocate_common_syms(void)
616 unsigned long offset
, align
;
618 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
619 if (sym
->st_shndx
== SHN_COMMON
) {
621 align
= sym
->st_value
;
622 offset
= bss_section
->data_offset
;
623 offset
= (offset
+ align
- 1) & -align
;
624 sym
->st_value
= offset
;
625 sym
->st_shndx
= bss_section
->sh_num
;
626 offset
+= sym
->st_size
;
627 bss_section
->data_offset
= offset
;
632 /* relocate symbol table, resolve undefined symbols if do_resolve is
633 true and output error if undefined symbol. */
634 ST_FUNC
void relocate_syms(TCCState
*s1
, int do_resolve
)
636 ElfW(Sym
) *sym
, *esym
;
637 int sym_bind
, sh_num
, sym_index
;
640 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
641 sh_num
= sym
->st_shndx
;
642 if (sh_num
== SHN_UNDEF
) {
643 name
= (char *) strtab_section
->data
+ sym
->st_name
;
644 /* Use ld.so to resolve symbol for us (for tcc -run) */
646 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
648 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
649 addr
= dlsym(RTLD_DEFAULT
, name
);
651 sym
->st_value
= (addr_t
)addr
;
653 printf ("relocate_sym: %s -> 0x%lx\n", name
, sym
->st_value
);
658 } else if (s1
->dynsym
) {
659 /* if dynamic symbol exist, then use it */
660 sym_index
= find_elf_sym(s1
->dynsym
, name
);
662 esym
= &((ElfW(Sym
) *)s1
->dynsym
->data
)[sym_index
];
663 sym
->st_value
= esym
->st_value
;
667 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
669 if (!strcmp(name
, "_fp_hw"))
671 /* only weak symbols are accepted to be undefined. Their
673 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
674 if (sym_bind
== STB_WEAK
) {
677 tcc_error_noabort("undefined symbol '%s'", name
);
679 } else if (sh_num
< SHN_LORESERVE
) {
680 /* add section base */
681 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
687 /* relocate a given section (CPU dependent) by applying the relocations
688 in the associated relocation section */
689 ST_FUNC
void relocate_section(TCCState
*s1
, Section
*s
)
691 Section
*sr
= s
->reloc
;
699 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
700 ptr
= s
->data
+ rel
->r_offset
;
702 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
703 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
705 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
706 val
+= rel
->r_addend
;
708 type
= ELFW(R_TYPE
)(rel
->r_info
);
709 addr
= s
->sh_addr
+ rel
->r_offset
;
711 relocate(s1
, rel
, type
, ptr
, addr
, val
);
713 /* if the relocation is allocated, we change its symbol table */
714 if (sr
->sh_flags
& SHF_ALLOC
)
715 sr
->link
= s1
->dynsym
;
718 /* relocate relocation table in 'sr' */
719 static void relocate_rel(TCCState
*s1
, Section
*sr
)
724 s
= s1
->sections
[sr
->sh_info
];
725 for_each_elem(sr
, 0, rel
, ElfW_Rel
)
726 rel
->r_offset
+= s
->sh_addr
;
729 /* count the number of dynamic relocations so that we can reserve
731 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
734 int sym_index
, esym_index
, type
, count
;
737 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
738 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
739 type
= ELFW(R_TYPE
)(rel
->r_info
);
741 #if defined(TCC_TARGET_I386)
743 #elif defined(TCC_TARGET_X86_64)
750 #if defined(TCC_TARGET_I386)
752 #elif defined(TCC_TARGET_X86_64)
755 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
764 /* allocate the section */
765 sr
->sh_flags
|= SHF_ALLOC
;
766 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
771 static struct sym_attr
*alloc_sym_attr(TCCState
*s1
, int index
)
774 struct sym_attr
*tab
;
776 if (index
>= s1
->nb_sym_attrs
) {
777 /* find immediately bigger power of 2 and reallocate array */
781 tab
= tcc_realloc(s1
->sym_attrs
, n
* sizeof(*s1
->sym_attrs
));
783 memset(s1
->sym_attrs
+ s1
->nb_sym_attrs
, 0,
784 (n
- s1
->nb_sym_attrs
) * sizeof(*s1
->sym_attrs
));
785 s1
->nb_sym_attrs
= n
;
787 return &s1
->sym_attrs
[index
];
790 static void build_got(TCCState
*s1
)
794 /* if no got, then create it */
795 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
796 s1
->got
->sh_entsize
= 4;
797 set_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
798 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
799 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
801 /* keep space for _DYNAMIC pointer, if present */
803 /* two dummy got entries */
804 write32le(ptr
+ 4, 0);
805 write32le(ptr
+ 8, 0);
807 /* keep space for _DYNAMIC pointer, if present */
809 write32le(ptr
+ 4, 0);
810 /* two dummy got entries */
811 write32le(ptr
+ 8, 0);
812 write32le(ptr
+ 12, 0);
813 write32le(ptr
+ 16, 0);
814 write32le(ptr
+ 20, 0);
818 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
819 in s1->symtab. When creating the dynamic symbol table entry for the GOT
820 relocation, use 'size' and 'info' for the corresponding symbol metadata.
821 Returns the offset of the GOT or (if any) PLT entry. */
822 static unsigned long put_got_entry(TCCState
*s1
,
823 int reloc_type
, unsigned long size
, int info
,
826 int index
, need_plt_entry
= 0;
829 unsigned long offset
;
832 struct sym_attr
*symattr
;
834 need_plt_entry
= (reloc_type
== R_JMP_SLOT
);
839 /* create PLT if needed */
840 if (need_plt_entry
&& !s1
->plt
) {
841 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
842 SHF_ALLOC
| SHF_EXECINSTR
);
843 s1
->plt
->sh_entsize
= 4;
846 /* already a GOT and/or PLT entry, no need to add one */
847 if (sym_index
< s1
->nb_sym_attrs
) {
848 if (need_plt_entry
&& s1
->sym_attrs
[sym_index
].plt_offset
)
849 return s1
->sym_attrs
[sym_index
].plt_offset
;
850 else if (!need_plt_entry
&& s1
->sym_attrs
[sym_index
].got_offset
)
851 return s1
->sym_attrs
[sym_index
].got_offset
;
854 symattr
= alloc_sym_attr(s1
, sym_index
);
856 /* create the GOT entry */
857 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
859 got_offset
= OFFSET_FROM_SECTION_START (s1
->got
, ptr
);
861 /* In case a function is both called and its address taken 2 GOT entries
862 are created, one for taking the address (GOT) and the other for the PLT
863 entry (PLTGOT). We don't record the offset of the PLTGOT entry in the
864 got_offset field since it might overwrite the offset of a GOT entry.
865 Besides, for PLTÂ entry the static relocation is against the PLT entry
866 and the dynamic relocation for PLTGOT is created in this function. */
868 symattr
->got_offset
= got_offset
;
870 sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
871 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
872 offset
= sym
->st_value
;
874 /* create PLT entry */
875 if (need_plt_entry
) {
876 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
880 unsigned long relofs
;
882 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
885 /* if we build a DLL, we add a %ebx offset */
886 if (s1
->output_type
== TCC_OUTPUT_DLL
)
893 /* empty PLT: create PLT0 entry that pushes the library indentifier
894 (GOT + PTR_SIZE) and jumps to ld.so resolution routine
895 (GOT + 2 * PTR_SIZE) */
896 if (plt
->data_offset
== 0) {
897 p
= section_ptr_add(plt
, 16);
898 p
[0] = 0xff; /* pushl got + PTR_SIZE */
900 write32le(p
+ 2, PTR_SIZE
);
901 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
903 write32le(p
+ 8, PTR_SIZE
* 2);
906 /* The PLT slot refers to the relocation entry it needs via offset.
907 The reloc entry is created below, so its offset is the current
909 relofs
= s1
->got
->reloc
? s1
->got
->reloc
->data_offset
: 0;
910 symattr
->plt_offset
= plt
->data_offset
;
912 /* Jump to GOT entry where ld.so initially put the address of ip + 4 */
913 p
= section_ptr_add(plt
, 16);
914 p
[0] = 0xff; /* jmp *(got + x) */
916 write32le(p
+ 2, got_offset
);
917 p
[6] = 0x68; /* push $xxx */
918 #ifdef TCC_TARGET_X86_64
919 /* On x86-64, the relocation is referred to by _index_ */
920 write32le(p
+ 7, relofs
/ sizeof (ElfW_Rel
));
922 write32le(p
+ 7, relofs
);
924 p
[11] = 0xe9; /* jmp plt_start */
925 write32le(p
+ 12, -(plt
->data_offset
));
927 /* If this was an UNDEF symbol set the offset in the dynsymtab to the
928 PLT slot, so that PC32 relocs to it can be resolved */
929 if (sym
->st_shndx
== SHN_UNDEF
)
930 offset
= plt
->data_offset
- 16;
931 #elif defined(TCC_TARGET_ARM)
935 /* when building a DLL, GOT entry accesses must be done relative to
936 start of GOT (see x86_64 examble above) */
937 if (s1
->output_type
== TCC_OUTPUT_DLL
)
938 tcc_error("DLLs unimplemented!");
941 /* empty PLT: create PLT0 entry that push address of call site and
942 jump to ld.so resolution routine (GOT + 8) */
943 if (plt
->data_offset
== 0) {
944 p
= section_ptr_add(plt
, 20);
945 write32le(p
, 0xe52de004); /* push {lr} */
946 write32le(p
+4, 0xe59fe004); /* ldr lr, [pc, #4] */
947 write32le(p
+8, 0xe08fe00e); /* add lr, pc, lr */
948 write32le(p
+12, 0xe5bef008); /* ldr pc, [lr, #8]! */
949 /* p+16 is set in relocate_plt */
952 symattr
->plt_offset
= plt
->data_offset
;
953 if (symattr
->plt_thumb_stub
) {
954 p
= section_ptr_add(plt
, 4);
955 write32le(p
, 0x4778); /* bx pc */
956 write32le(p
+2, 0x46c0); /* nop */
958 p
= section_ptr_add(plt
, 16);
959 /* Jump to GOT entry where ld.so initially put address of PLT0 */
960 write32le(p
, 0xe59fc004); /* ldr ip, [pc, #4] */
961 write32le(p
+4, 0xe08fc00c); /* add ip, pc, ip */
962 write32le(p
+8, 0xe59cf000); /* ldr pc, [ip] */
963 /* p + 12 contains offset to GOT entry once patched by relocate_plt */
964 write32le(p
+12, got_offset
);
966 /* the symbol is modified so that it will be relocated to the PLT */
967 if (sym
->st_shndx
== SHN_UNDEF
)
968 offset
= plt
->data_offset
- 16;
969 #elif defined(TCC_TARGET_ARM64)
973 if (s1
->output_type
== TCC_OUTPUT_DLL
)
974 tcc_error("DLLs unimplemented!");
977 if (plt
->data_offset
== 0)
978 section_ptr_add(plt
, 32);
979 symattr
->plt_offset
= plt
->data_offset
;
980 p
= section_ptr_add(plt
, 16);
981 write32le(p
, got_offset
);
982 write32le(p
+ 4, (uint64_t) got_offset
>> 32);
984 if (sym
->st_shndx
== SHN_UNDEF
)
985 offset
= plt
->data_offset
- 16;
986 #elif defined(TCC_TARGET_C67)
987 tcc_error("C67 got not implemented");
989 #error unsupported CPU
993 /* Create the GOT relocation that will insert the address of the object or
994 function of interest in the GOT entry. This is a static relocation for
995 memory output (dlsym will give us the address of symbols) and dynamic
996 relocation otherwise (executable and DLLs). The relocation should be
997 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
998 associated to a PLT entry) but is currently done at load time for an
1001 /* create the dynamic symbol table entry that the relocation refers to
1002 in its r_info field to identify the symbol */
1003 /* XXX This might generate multiple syms for name. */
1004 index
= put_elf_sym(s1
->dynsym
, offset
, size
, info
, 0, sym
->st_shndx
,
1006 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, reloc_type
, index
);
1008 put_elf_reloc(symtab_section
, s1
->got
, got_offset
, reloc_type
,
1013 return symattr
->plt_offset
;
1015 return symattr
->got_offset
;
1018 /* build GOT and PLT entries */
1019 ST_FUNC
void build_got_entries(TCCState
*s1
)
1024 int i
, type
, reloc_type
, sym_index
;
1026 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1027 s
= s1
->sections
[i
];
1028 if (s
->sh_type
!= SHT_RELX
)
1030 /* no need to handle got relocations */
1031 if (s
->link
!= symtab_section
)
1033 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1034 type
= ELFW(R_TYPE
)(rel
->r_info
);
1035 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1036 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1038 #if defined(TCC_TARGET_I386)
1046 if (sym
->st_shndx
!= SHN_UNDEF
&& type
!= R_386_GOT32
&&
1047 type
!= R_386_GOT32X
&& type
!= R_386_GOTOFF
&&
1048 type
!= R_386_GOTPC
&& type
!= R_386_PLT32
)
1054 if (type
!= R_386_GOTOFF
&& type
!= R_386_GOTPC
) {
1055 /* look at the symbol got offset. If none, then add one */
1056 if (type
== R_386_GOT32
|| type
== R_386_GOT32X
)
1057 reloc_type
= R_386_GLOB_DAT
;
1059 reloc_type
= R_386_JMP_SLOT
;
1060 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1064 #elif defined(TCC_TARGET_ARM)
1069 case R_ARM_THM_PC22
:
1070 case R_ARM_MOVT_ABS
:
1071 case R_ARM_MOVW_ABS_NC
:
1072 case R_ARM_THM_MOVT_ABS
:
1073 case R_ARM_THM_MOVW_ABS_NC
:
1080 if (sym
->st_shndx
!= SHN_UNDEF
&& type
!= R_ARM_GOT32
&&
1081 type
!= R_ARM_GOTOFF
&& type
!= R_ARM_GOTPC
&&
1082 type
!= R_ARM_PLT32
)
1087 if (type
!= R_ARM_GOTOFF
&& type
!= R_ARM_GOTPC
1088 && (sym
->st_shndx
== SHN_UNDEF
1089 || s1
->output_type
== TCC_OUTPUT_MEMORY
)) {
1091 /* look at the symbol got offset. If none, then add one */
1092 if (type
== R_ARM_GOT32
|| type
== R_ARM_MOVT_ABS
||
1093 type
== R_ARM_MOVW_ABS_NC
||
1094 type
== R_ARM_THM_MOVT_ABS
||
1095 type
== R_ARM_THM_MOVW_ABS_NC
|| type
== R_ARM_ABS32
||
1096 type
== R_ARM_REL32
)
1097 reloc_type
= R_ARM_GLOB_DAT
;
1099 reloc_type
= R_ARM_JUMP_SLOT
;
1100 ofs
= put_got_entry(s1
, reloc_type
, sym
->st_size
,
1101 sym
->st_info
, sym_index
);
1103 printf ("maybegot: %s, %d, %d --> ofs=0x%x\n",
1104 (char *) symtab_section
->link
->data
+ sym
->st_name
,
1105 type
, sym
->st_shndx
, ofs
);
1107 if (type
== R_ARM_PC24
|| type
== R_ARM_CALL
||
1108 type
== R_ARM_JUMP24
|| type
== R_ARM_PLT32
) {
1109 addr_t
*ptr
= (addr_t
*)(s1
->sections
[s
->sh_info
]->data
1111 /* x must be signed! */
1112 int x
= *ptr
& 0xffffff;
1118 printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr
,
1119 (*ptr
& 0xff000000) | x
, x
);
1121 *ptr
= (*ptr
& 0xff000000) | x
;
1125 case R_ARM_THM_JUMP24
:
1126 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1127 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1128 /* We are relocating a jump from thumb code to arm code */
1129 if (sym
->st_shndx
!= SHN_UNDEF
&& !(sym
->st_value
& 1)) {
1132 char *name
, buf
[1024];
1133 Section
*text_section
;
1135 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1136 text_section
= s1
->sections
[sym
->st_shndx
];
1137 /* Modify reloc to target a thumb stub to switch to ARM */
1138 snprintf(buf
, sizeof(buf
), "%s_from_thumb", name
);
1139 index
= put_elf_sym(symtab_section
,
1140 text_section
->data_offset
+ 1,
1141 sym
->st_size
, sym
->st_info
, 0,
1142 sym
->st_shndx
, buf
);
1143 rel
->r_info
= ELFW(R_INFO
)(index
, type
);
1144 /* Create a thumb stub fonction to switch to ARM mode */
1145 put_elf_reloc(symtab_section
, text_section
,
1146 text_section
->data_offset
+ 4, R_ARM_JUMP24
,
1148 p
= section_ptr_add(text_section
, 8);
1149 write32le(p
, 0x4778); /* bx pc */
1150 write32le(p
+2, 0x46c0); /* nop */
1151 write32le(p
+4, 0xeafffffe); /* b $sym */
1153 #elif defined(TCC_TARGET_ARM64)
1154 //xx Other cases may be required here:
1155 case R_AARCH64_ADR_GOT_PAGE
:
1156 case R_AARCH64_LD64_GOT_LO12_NC
:
1159 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1160 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1161 reloc_type
= R_AARCH64_GLOB_DAT
;
1162 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1166 case R_AARCH64_JUMP26
:
1167 case R_AARCH64_CALL26
:
1170 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1171 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1172 if (sym
->st_shndx
== SHN_UNDEF
||
1173 s1
->output_type
== TCC_OUTPUT_MEMORY
) {
1175 reloc_type
= R_AARCH64_JUMP_SLOT
;
1176 ofs
= put_got_entry(s1
, reloc_type
, sym
->st_size
,
1177 sym
->st_info
, sym_index
);
1178 /* We store the place of the generated PLT slot
1180 rel
->r_addend
+= ofs
;
1183 #elif defined(TCC_TARGET_C67)
1190 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1191 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1192 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1193 /* look at the symbol got offset. If none, then add one */
1194 if (type
== R_C60_GOT32
)
1195 reloc_type
= R_C60_GLOB_DAT
;
1197 reloc_type
= R_C60_JMP_SLOT
;
1198 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1202 #elif defined(TCC_TARGET_X86_64)
1207 case R_X86_64_GOT32
:
1208 case R_X86_64_GOTTPOFF
:
1209 case R_X86_64_GOTPCREL
:
1210 case R_X86_64_GOTPCRELX
:
1211 case R_X86_64_REX_GOTPCRELX
:
1212 case R_X86_64_PLT32
:
1213 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1214 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1215 if ((type
== R_X86_64_32
|| type
== R_X86_64_32S
||
1216 type
== R_X86_64_64
|| type
== R_X86_64_PC32
) &&
1217 sym
->st_shndx
!= SHN_UNDEF
)
1220 if (type
== R_X86_64_PLT32
&&
1221 ELFW(ST_VISIBILITY
)(sym
->st_other
) != STV_DEFAULT
) {
1222 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PC32
);
1228 if (type
!= R_X86_64_GOTTPOFF
) {
1230 /* look at the symbol got offset. If none, then add one */
1231 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
||
1232 type
== R_X86_64_GOTPCRELX
||
1233 type
== R_X86_64_REX_GOTPCRELX
||
1234 type
== R_X86_64_32
|| type
== R_X86_64_32S
||
1235 type
== R_X86_64_64
)
1236 reloc_type
= R_X86_64_GLOB_DAT
;
1238 reloc_type
= R_X86_64_JUMP_SLOT
;
1239 ofs
= put_got_entry(s1
, reloc_type
, sym
->st_size
,
1240 sym
->st_info
, sym_index
);
1241 if (type
== R_X86_64_PLT32
)
1242 /* We store the place of the generated PLT slot
1244 rel
->r_addend
+= ofs
;
1248 #error unsupported CPU
1257 ST_FUNC Section
*new_symtab(TCCState
*s1
,
1258 const char *symtab_name
, int sh_type
, int sh_flags
,
1259 const char *strtab_name
,
1260 const char *hash_name
, int hash_sh_flags
)
1262 Section
*symtab
, *strtab
, *hash
;
1263 int *ptr
, nb_buckets
;
1265 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1266 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1267 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1268 put_elf_str(strtab
, "");
1269 symtab
->link
= strtab
;
1270 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1274 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1275 hash
->sh_entsize
= sizeof(int);
1276 symtab
->hash
= hash
;
1277 hash
->link
= symtab
;
1279 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1280 ptr
[0] = nb_buckets
;
1282 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1286 /* put dynamic tag */
1287 static void put_dt(Section
*dynamic
, int dt
, addr_t val
)
1290 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1292 dyn
->d_un
.d_val
= val
;
1295 #ifndef TCC_TARGET_PE
1296 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1300 char sym_start
[1024];
1303 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1304 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1306 s
= find_section(s1
, section_name
);
1311 end_offset
= s
->data_offset
;
1314 set_elf_sym(symtab_section
,
1316 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1317 s
->sh_num
, sym_start
);
1318 set_elf_sym(symtab_section
,
1320 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1321 s
->sh_num
, sym_end
);
1325 static int tcc_add_support(TCCState
*s1
, const char *filename
)
1328 snprintf(buf
, sizeof(buf
), "%s/"TCC_ARCH_DIR
"%s", s1
->tcc_lib_path
, filename
);
1329 return tcc_add_file(s1
, buf
);
1332 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
1334 #ifdef CONFIG_TCC_BCHECK
1338 if (0 == s1
->do_bounds_check
)
1340 /* XXX: add an object file to do that */
1341 ptr
= section_ptr_add(bounds_section
, sizeof(*ptr
));
1343 set_elf_sym(symtab_section
, 0, 0,
1344 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1345 bounds_section
->sh_num
, "__bounds_start");
1346 /* pull bcheck.o from libtcc1.a */
1347 sym_index
= set_elf_sym(symtab_section
, 0, 0,
1348 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1349 SHN_UNDEF
, "__bound_init");
1350 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1351 /* add 'call __bound_init()' in .init section */
1352 Section
*init_section
= find_section(s1
, ".init");
1353 unsigned char *pinit
= section_ptr_add(init_section
, 5);
1355 write32le(pinit
+ 1, -4);
1356 put_elf_reloc(symtab_section
, init_section
,
1357 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1358 /* R_386_PC32 = R_X86_64_PC32 = 2 */
1363 /* add tcc runtime libraries */
1364 ST_FUNC
void tcc_add_runtime(TCCState
*s1
)
1367 tcc_add_pragma_libs(s1
);
1369 if (!s1
->nostdlib
) {
1370 tcc_add_library_err(s1
, "c");
1371 #ifdef CONFIG_USE_LIBGCC
1372 if (!s1
->static_link
) {
1373 tcc_add_file(s1
, TCC_LIBGCC
);
1376 tcc_add_support(s1
, "libtcc1.a");
1377 /* add crt end if not memory output */
1378 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1379 tcc_add_crt(s1
, "crtn.o");
1383 /* add various standard linker symbols (must be done after the
1384 sections are filled (for example after allocating common
1386 ST_FUNC
void tcc_add_linker_symbols(TCCState
*s1
)
1392 set_elf_sym(symtab_section
,
1393 text_section
->data_offset
, 0,
1394 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1395 text_section
->sh_num
, "_etext");
1396 set_elf_sym(symtab_section
,
1397 data_section
->data_offset
, 0,
1398 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1399 data_section
->sh_num
, "_edata");
1400 set_elf_sym(symtab_section
,
1401 bss_section
->data_offset
, 0,
1402 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1403 bss_section
->sh_num
, "_end");
1404 #ifndef TCC_TARGET_PE
1405 /* horrible new standard ldscript defines */
1406 add_init_array_defines(s1
, ".preinit_array");
1407 add_init_array_defines(s1
, ".init_array");
1408 add_init_array_defines(s1
, ".fini_array");
1411 /* add start and stop symbols for sections whose name can be
1413 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1414 s
= s1
->sections
[i
];
1415 if (s
->sh_type
== SHT_PROGBITS
&&
1416 (s
->sh_flags
& SHF_ALLOC
)) {
1420 /* check if section name can be expressed in C */
1426 if (!isid(ch
) && !isnum(ch
))
1430 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1431 set_elf_sym(symtab_section
,
1433 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1435 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1436 set_elf_sym(symtab_section
,
1438 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1445 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1446 const int *sec_order
)
1449 int i
, offset
, size
;
1452 for(i
=1;i
<s1
->nb_sections
;i
++) {
1453 s
= s1
->sections
[sec_order
[i
]];
1454 if (s
->sh_type
!= SHT_NOBITS
&&
1455 (s
->sh_flags
& SHF_ALLOC
)) {
1456 while (offset
< s
->sh_offset
) {
1461 fwrite(s
->data
, 1, size
, f
);
1467 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1469 #define EXTRA_RELITEMS 14
1471 /* move the relocation value from .dynsym to .got */
1472 static void patch_dynsym_undef(TCCState
*s1
, Section
*s
)
1474 uint32_t *gotd
= (void *)s1
->got
->data
;
1477 gotd
+= 3; /* dummy entries in .got */
1478 /* relocate symbols in .dynsym */
1479 for_each_elem(s
, 1, sym
, ElfW(Sym
)) {
1480 if (sym
->st_shndx
== SHN_UNDEF
) {
1481 *gotd
++ = sym
->st_value
+ 6; /* XXX 6 is magic ? */
1488 #define EXTRA_RELITEMS 9
1490 /* zero plt offsets of weak symbols in .dynsym */
1491 static void patch_dynsym_undef(TCCState
*s1
, Section
*s
)
1495 for_each_elem(s
, 1, sym
, ElfW(Sym
))
1496 if (sym
->st_shndx
== SHN_UNDEF
&& ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
)
1501 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1503 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1504 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1505 unsigned long offset
;
1507 if (sym_index
>= s1
->nb_sym_attrs
)
1509 offset
= s1
->sym_attrs
[sym_index
].got_offset
;
1510 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1511 #ifdef TCC_TARGET_X86_64
1512 /* only works for x86-64 */
1513 write32le(s1
->got
->data
+ offset
+ 4, sym
->st_value
>> 32);
1515 write32le(s1
->got
->data
+ offset
, sym
->st_value
& 0xffffffff);
1518 /* Perform relocation to GOT or PLT entries */
1519 ST_FUNC
void fill_got(TCCState
*s1
)
1525 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1526 s
= s1
->sections
[i
];
1527 if (s
->sh_type
!= SHT_RELX
)
1529 /* no need to handle got relocations */
1530 if (s
->link
!= symtab_section
)
1532 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1533 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1534 case R_X86_64_GOT32
:
1535 case R_X86_64_GOTPCREL
:
1536 case R_X86_64_GOTPCRELX
:
1537 case R_X86_64_REX_GOTPCRELX
:
1538 case R_X86_64_PLT32
:
1539 fill_got_entry(s1
, rel
);
1546 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1547 in shared libraries and export non local defined symbols to shared libraries
1548 if -rdynamic switch was given on command line */
1549 static void bind_exe_dynsyms(TCCState
*s1
)
1552 int sym_index
, index
;
1553 ElfW(Sym
) *sym
, *esym
;
1556 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1557 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1558 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1559 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1560 if (sym
->st_shndx
== SHN_UNDEF
) {
1561 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1562 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1564 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1565 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1566 if ((type
== STT_FUNC
) || (type
== STT_GNU_IFUNC
)) {
1567 /* Indirect functions shall have STT_FUNC type in executable
1568 * dynsym section. Indeed, a dlsym call following a lazy
1569 * resolution would pick the symbol value from the
1570 * executable dynsym entry which would contain the address
1571 * of the function wanted by the caller of dlsym instead of
1572 * the address of the function that would return that
1574 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1575 ELFW(ST_INFO
)(STB_GLOBAL
,STT_FUNC
),
1576 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1577 } else if (type
== STT_OBJECT
) {
1578 unsigned long offset
;
1580 offset
= bss_section
->data_offset
;
1581 /* XXX: which alignment ? */
1582 offset
= (offset
+ 16 - 1) & -16;
1583 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1584 esym
->st_info
, 0, bss_section
->sh_num
,
1586 /* Ensure R_COPY works for weak symbol aliases */
1587 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1588 for_each_elem(s1
->dynsymtab_section
, 1, dynsym
, ElfW(Sym
)) {
1589 if ((dynsym
->st_value
== esym
->st_value
)
1590 && (ELFW(ST_BIND
)(dynsym
->st_info
) == STB_GLOBAL
)) {
1591 char *dynname
= (char *) s1
->dynsymtab_section
->link
->data
1593 put_elf_sym(s1
->dynsym
, offset
, dynsym
->st_size
,
1595 bss_section
->sh_num
, dynname
);
1600 put_elf_reloc(s1
->dynsym
, bss_section
,
1601 offset
, R_COPY
, index
);
1602 offset
+= esym
->st_size
;
1603 bss_section
->data_offset
= offset
;
1606 /* STB_WEAK undefined symbols are accepted */
1607 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1608 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1609 !strcmp(name
, "_fp_hw")) {
1611 tcc_error_noabort("undefined symbol '%s'", name
);
1614 } else if (s1
->rdynamic
&& ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1615 /* if -rdynamic option, then export all non local symbols */
1616 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1617 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
1618 0, sym
->st_shndx
, name
);
1623 /* Bind symbols of libraries: export all non local symbols of executable that
1624 are referenced by shared libraries. The reason is that the dynamic loader
1625 search symbol first in executable and then in libraries. Therefore a
1626 reference to a symbol already defined by a library can still be resolved by
1627 a symbol in the executable. */
1628 static void bind_libs_dynsyms(TCCState
*s1
)
1632 ElfW(Sym
) *sym
, *esym
;
1634 for_each_elem(s1
->dynsymtab_section
, 1, esym
, ElfW(Sym
)) {
1635 name
= (char *) s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1636 sym_index
= find_elf_sym(symtab_section
, name
);
1637 /* XXX: avoid adding a symbol if already present because of
1639 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1640 if (sym_index
&& sym
->st_shndx
!= SHN_UNDEF
)
1641 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
1642 0, sym
->st_shndx
, name
);
1643 else if (esym
->st_shndx
== SHN_UNDEF
) {
1644 /* weak symbols can stay undefined */
1645 if (ELFW(ST_BIND
)(esym
->st_info
) != STB_WEAK
)
1646 tcc_warning("undefined dynamic symbol '%s'", name
);
1651 /* Export all non local symbols. This is used by shared libraries so that the
1652 non local symbols they define can resolve a reference in another shared
1653 library or in the executable. Correspondingly, it allows undefined local
1654 symbols to be resolved by other shared libraries or by the executable. */
1655 static void export_global_syms(TCCState
*s1
)
1657 int nb_syms
, dynindex
, index
;
1661 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1662 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1663 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1664 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1665 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1666 dynindex
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1667 sym
->st_info
, 0, sym
->st_shndx
, name
);
1668 index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1669 s1
->symtab_to_dynsym
[index
] = dynindex
;
1674 /* relocate the PLT: compute addresses and offsets in the PLT now that final
1675 address for PLT and GOT are known (see fill_program_header) */
1676 ST_FUNC
void relocate_plt(TCCState
*s1
)
1684 p_end
= p
+ s1
->plt
->data_offset
;
1686 #if defined(TCC_TARGET_I386)
1687 add32le(p
+ 2, s1
->got
->sh_addr
);
1688 add32le(p
+ 8, s1
->got
->sh_addr
);
1691 add32le(p
+ 2, s1
->got
->sh_addr
);
1694 #elif defined(TCC_TARGET_X86_64)
1695 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1697 add32le(p
+ 8, x
- 6);
1700 add32le(p
+ 2, x
+ s1
->plt
->data
- p
);
1703 #elif defined(TCC_TARGET_ARM)
1704 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1705 write32le(s1
->plt
->data
+ 16, x
- 16);
1708 if (read32le(p
) == 0x46c04778) /* PLT Thumb stub present */
1710 add32le(p
+ 12, x
+ s1
->plt
->data
- p
);
1713 #elif defined(TCC_TARGET_ARM64)
1714 uint64_t plt
= s1
->plt
->sh_addr
;
1715 uint64_t got
= s1
->got
->sh_addr
;
1716 uint64_t off
= (got
>> 12) - (plt
>> 12);
1717 if ((off
+ ((uint32_t)1 << 20)) >> 21)
1718 tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off
, got
, plt
);
1719 write32le(p
, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
1720 write32le(p
+ 4, (0x90000010 | // adrp x16,...
1721 (off
& 0x1ffffc) << 3 | (off
& 3) << 29));
1722 write32le(p
+ 8, (0xf9400211 | // ldr x17,[x16,#...]
1723 (got
& 0xff8) << 7));
1724 write32le(p
+ 12, (0x91000210 | // add x16,x16,#...
1725 (got
& 0xfff) << 10));
1726 write32le(p
+ 16, 0xd61f0220); // br x17
1727 write32le(p
+ 20, 0xd503201f); // nop
1728 write32le(p
+ 24, 0xd503201f); // nop
1729 write32le(p
+ 28, 0xd503201f); // nop
1732 uint64_t pc
= plt
+ (p
- s1
->plt
->data
);
1733 uint64_t addr
= got
+ read64le(p
);
1734 uint64_t off
= (addr
>> 12) - (pc
>> 12);
1735 if ((off
+ ((uint32_t)1 << 20)) >> 21)
1736 tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off
, addr
, pc
);
1737 write32le(p
, (0x90000010 | // adrp x16,...
1738 (off
& 0x1ffffc) << 3 | (off
& 3) << 29));
1739 write32le(p
+ 4, (0xf9400211 | // ldr x17,[x16,#...]
1740 (addr
& 0xff8) << 7));
1741 write32le(p
+ 8, (0x91000210 | // add x16,x16,#...
1742 (addr
& 0xfff) << 10));
1743 write32le(p
+ 12, 0xd61f0220); // br x17
1746 #elif defined(TCC_TARGET_C67)
1749 #error unsupported CPU
1754 /* Allocate strings for section names and decide if an unallocated section
1757 NOTE: the strsec section comes last, so its size is also correct ! */
1758 static void alloc_sec_names(TCCState
*s1
, int file_type
, Section
*strsec
)
1763 /* Allocate strings for section names */
1764 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1765 s
= s1
->sections
[i
];
1766 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1767 /* when generating a DLL, we include relocations but we may
1769 if (file_type
== TCC_OUTPUT_DLL
&&
1770 s
->sh_type
== SHT_RELX
&&
1771 !(s
->sh_flags
& SHF_ALLOC
)) {
1772 /* gr: avoid bogus relocs for empty (debug) sections */
1773 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1774 prepare_dynamic_rel(s1
, s
);
1775 else if (s1
->do_debug
)
1776 s
->sh_size
= s
->data_offset
;
1777 } else if (s1
->do_debug
||
1778 file_type
== TCC_OUTPUT_OBJ
||
1779 (s
->sh_flags
& SHF_ALLOC
) ||
1780 i
== (s1
->nb_sections
- 1)) {
1781 /* we output all sections if debug or object file */
1782 s
->sh_size
= s
->data_offset
;
1787 /* Info to be copied in dynamic section */
1791 unsigned long dyn_rel_off
;
1794 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1800 /* Assign sections to segments and decide how are sections laid out when loaded
1801 in memory. This function also fills corresponding program headers. */
1802 static int layout_sections(TCCState
*s1
, ElfW(Phdr
) *phdr
, int phnum
,
1803 Section
*interp
, Section
* strsec
,
1804 struct dyn_inf
*dyninf
, int *sec_order
)
1806 int i
, j
, k
, file_type
, sh_order_index
, file_offset
;
1807 unsigned long s_align
;
1813 file_type
= s1
->output_type
;
1816 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
1817 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1818 s_align
= ELF_PAGE_SIZE
;
1819 if (s1
->section_align
)
1820 s_align
= s1
->section_align
;
1823 if (s1
->has_text_addr
) {
1824 int a_offset
, p_offset
;
1825 addr
= s1
->text_addr
;
1826 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1828 a_offset
= (int) (addr
& (s_align
- 1));
1829 p_offset
= file_offset
& (s_align
- 1);
1830 if (a_offset
< p_offset
)
1831 a_offset
+= s_align
;
1832 file_offset
+= (a_offset
- p_offset
);
1834 if (file_type
== TCC_OUTPUT_DLL
)
1837 addr
= ELF_START_ADDR
;
1838 /* compute address after headers */
1839 addr
+= (file_offset
& (s_align
- 1));
1843 /* Leave one program headers for the program interpreter and one for
1844 the program header table itself if needed. These are done later as
1845 they require section layout to be done first. */
1847 ph
+= 1 + HAVE_PHDR
;
1849 /* dynamic relocation table information, for .dynamic section */
1850 dyninf
->rel_addr
= dyninf
->rel_size
= 0;
1851 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1852 dyninf
->bss_addr
= dyninf
->bss_size
= 0;
1855 for(j
= 0; j
< 2; j
++) {
1856 ph
->p_type
= PT_LOAD
;
1858 ph
->p_flags
= PF_R
| PF_X
;
1860 ph
->p_flags
= PF_R
| PF_W
;
1861 ph
->p_align
= s_align
;
1863 /* Decide the layout of sections loaded in memory. This must
1864 be done before program headers are filled since they contain
1865 info about the layout. We do the following ordering: interp,
1866 symbol tables, relocations, progbits, nobits */
1867 /* XXX: do faster and simpler sorting */
1868 for(k
= 0; k
< 5; k
++) {
1869 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1870 s
= s1
->sections
[i
];
1871 /* compute if section should be included */
1873 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1877 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1878 (SHF_ALLOC
| SHF_WRITE
))
1884 } else if (s
->sh_type
== SHT_DYNSYM
||
1885 s
->sh_type
== SHT_STRTAB
||
1886 s
->sh_type
== SHT_HASH
) {
1889 } else if (s
->sh_type
== SHT_RELX
) {
1892 } else if (s
->sh_type
== SHT_NOBITS
) {
1899 sec_order
[sh_order_index
++] = i
;
1901 /* section matches: we align it and add its size */
1903 addr
= (addr
+ s
->sh_addralign
- 1) &
1904 ~(s
->sh_addralign
- 1);
1905 file_offset
+= (int) ( addr
- tmp
);
1906 s
->sh_offset
= file_offset
;
1909 /* update program header infos */
1910 if (ph
->p_offset
== 0) {
1911 ph
->p_offset
= file_offset
;
1913 ph
->p_paddr
= ph
->p_vaddr
;
1915 /* update dynamic relocation infos */
1916 if (s
->sh_type
== SHT_RELX
) {
1917 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1918 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.got")) {
1919 dyninf
->rel_addr
= addr
;
1920 dyninf
->rel_size
+= s
->sh_size
; /* XXX only first rel. */
1922 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.bss")) {
1923 dyninf
->bss_addr
= addr
;
1924 dyninf
->bss_size
= s
->sh_size
; /* XXX only first rel. */
1927 if (dyninf
->rel_size
== 0)
1928 dyninf
->rel_addr
= addr
;
1929 dyninf
->rel_size
+= s
->sh_size
;
1933 if (s
->sh_type
!= SHT_NOBITS
)
1934 file_offset
+= s
->sh_size
;
1938 /* Make the first PT_LOAD segment include the program
1939 headers itself (and the ELF header as well), it'll
1940 come out with same memory use but will make various
1941 tools like binutils strip work better. */
1942 ph
->p_offset
&= ~(ph
->p_align
- 1);
1943 ph
->p_vaddr
&= ~(ph
->p_align
- 1);
1944 ph
->p_paddr
&= ~(ph
->p_align
- 1);
1946 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1947 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1950 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1951 /* if in the middle of a page, we duplicate the page in
1952 memory so that one copy is RX and the other is RW */
1953 if ((addr
& (s_align
- 1)) != 0)
1956 addr
= (addr
+ s_align
- 1) & ~(s_align
- 1);
1957 file_offset
= (file_offset
+ s_align
- 1) & ~(s_align
- 1);
1963 /* all other sections come after */
1964 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1965 s
= s1
->sections
[i
];
1966 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1968 sec_order
[sh_order_index
++] = i
;
1970 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1971 ~(s
->sh_addralign
- 1);
1972 s
->sh_offset
= file_offset
;
1973 if (s
->sh_type
!= SHT_NOBITS
)
1974 file_offset
+= s
->sh_size
;
1980 static void fill_unloadable_phdr(ElfW(Phdr
) *phdr
, int phnum
, Section
*interp
,
1985 /* if interpreter, then add corresponding program header */
1991 int len
= phnum
* sizeof(ElfW(Phdr
));
1993 ph
->p_type
= PT_PHDR
;
1994 ph
->p_offset
= sizeof(ElfW(Ehdr
));
1995 ph
->p_vaddr
= interp
->sh_addr
- len
;
1996 ph
->p_paddr
= ph
->p_vaddr
;
1997 ph
->p_filesz
= ph
->p_memsz
= len
;
1998 ph
->p_flags
= PF_R
| PF_X
;
1999 ph
->p_align
= 4; /* interp->sh_addralign; */
2003 ph
->p_type
= PT_INTERP
;
2004 ph
->p_offset
= interp
->sh_offset
;
2005 ph
->p_vaddr
= interp
->sh_addr
;
2006 ph
->p_paddr
= ph
->p_vaddr
;
2007 ph
->p_filesz
= interp
->sh_size
;
2008 ph
->p_memsz
= interp
->sh_size
;
2010 ph
->p_align
= interp
->sh_addralign
;
2013 /* if dynamic section, then add corresponding program header */
2015 ph
= &phdr
[phnum
- 1];
2017 ph
->p_type
= PT_DYNAMIC
;
2018 ph
->p_offset
= dynamic
->sh_offset
;
2019 ph
->p_vaddr
= dynamic
->sh_addr
;
2020 ph
->p_paddr
= ph
->p_vaddr
;
2021 ph
->p_filesz
= dynamic
->sh_size
;
2022 ph
->p_memsz
= dynamic
->sh_size
;
2023 ph
->p_flags
= PF_R
| PF_W
;
2024 ph
->p_align
= dynamic
->sh_addralign
;
2028 /* Fill the dynamic section with tags describing the address and size of
2030 static void fill_dynamic(TCCState
*s1
, struct dyn_inf
*dyninf
)
2034 dynamic
= dyninf
->dynamic
;
2036 /* put dynamic section entries */
2037 dynamic
->data_offset
= dyninf
->dyn_rel_off
;
2038 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
2039 put_dt(dynamic
, DT_STRTAB
, dyninf
->dynstr
->sh_addr
);
2040 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
2041 put_dt(dynamic
, DT_STRSZ
, dyninf
->dynstr
->data_offset
);
2042 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
2043 #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
2044 put_dt(dynamic
, DT_RELA
, dyninf
->rel_addr
);
2045 put_dt(dynamic
, DT_RELASZ
, dyninf
->rel_size
);
2046 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
2048 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2049 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2050 put_dt(dynamic
, DT_PLTRELSZ
, dyninf
->rel_size
);
2051 put_dt(dynamic
, DT_JMPREL
, dyninf
->rel_addr
);
2052 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
2053 put_dt(dynamic
, DT_REL
, dyninf
->bss_addr
);
2054 put_dt(dynamic
, DT_RELSZ
, dyninf
->bss_size
);
2056 put_dt(dynamic
, DT_REL
, dyninf
->rel_addr
);
2057 put_dt(dynamic
, DT_RELSZ
, dyninf
->rel_size
);
2058 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
2062 put_dt(dynamic
, DT_DEBUG
, 0);
2063 put_dt(dynamic
, DT_NULL
, 0);
2066 /* Relocate remaining sections and symbols (that is those not related to
2068 static int final_sections_reloc(TCCState
*s1
)
2073 relocate_syms(s1
, 0);
2075 if (s1
->nb_errors
!= 0)
2078 /* relocate sections */
2079 /* XXX: ignore sections with allocated relocations ? */
2080 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2081 s
= s1
->sections
[i
];
2082 #ifdef TCC_TARGET_I386
2083 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
2084 /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
2085 checking is removed */
2087 if (s
->reloc
&& s
!= s1
->got
)
2088 /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
2090 relocate_section(s1
, s
);
2093 /* relocate relocation entries if the relocation tables are
2094 allocated in the executable */
2095 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2096 s
= s1
->sections
[i
];
2097 if ((s
->sh_flags
& SHF_ALLOC
) &&
2098 s
->sh_type
== SHT_RELX
) {
2099 relocate_rel(s1
, s
);
2105 /* Create an ELF file on disk.
2106 This function handle ELF specific layout requirements */
2107 static void tcc_output_elf(TCCState
*s1
, FILE *f
, int phnum
, ElfW(Phdr
) *phdr
,
2108 int file_offset
, int *sec_order
)
2110 int i
, shnum
, offset
, size
, file_type
;
2113 ElfW(Shdr
) shdr
, *sh
;
2115 file_type
= s1
->output_type
;
2116 shnum
= s1
->nb_sections
;
2118 memset(&ehdr
, 0, sizeof(ehdr
));
2121 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2122 ehdr
.e_phnum
= phnum
;
2123 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2127 file_offset
= (file_offset
+ 3) & -4;
2130 ehdr
.e_ident
[0] = ELFMAG0
;
2131 ehdr
.e_ident
[1] = ELFMAG1
;
2132 ehdr
.e_ident
[2] = ELFMAG2
;
2133 ehdr
.e_ident
[3] = ELFMAG3
;
2134 ehdr
.e_ident
[4] = ELFCLASSW
;
2135 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2136 ehdr
.e_ident
[6] = EV_CURRENT
;
2137 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2138 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2140 #ifdef TCC_TARGET_ARM
2142 ehdr
.e_ident
[EI_OSABI
] = 0;
2143 ehdr
.e_flags
= EF_ARM_EABI_VER4
;
2144 if (file_type
== TCC_OUTPUT_EXE
|| file_type
== TCC_OUTPUT_DLL
)
2145 ehdr
.e_flags
|= EF_ARM_HASENTRY
;
2146 if (s1
->float_abi
== ARM_HARD_FLOAT
)
2147 ehdr
.e_flags
|= EF_ARM_VFP_FLOAT
;
2149 ehdr
.e_flags
|= EF_ARM_SOFT_FLOAT
;
2151 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2156 case TCC_OUTPUT_EXE
:
2157 ehdr
.e_type
= ET_EXEC
;
2158 ehdr
.e_entry
= get_elf_sym_addr(s1
, "_start", 1);
2160 case TCC_OUTPUT_DLL
:
2161 ehdr
.e_type
= ET_DYN
;
2162 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
2164 case TCC_OUTPUT_OBJ
:
2165 ehdr
.e_type
= ET_REL
;
2168 ehdr
.e_machine
= EM_TCC_TARGET
;
2169 ehdr
.e_version
= EV_CURRENT
;
2170 ehdr
.e_shoff
= file_offset
;
2171 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2172 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2173 ehdr
.e_shnum
= shnum
;
2174 ehdr
.e_shstrndx
= shnum
- 1;
2176 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2177 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2178 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2180 sort_syms(s1
, symtab_section
);
2181 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2182 s
= s1
->sections
[sec_order
[i
]];
2183 if (s
->sh_type
!= SHT_NOBITS
) {
2184 if (s
->sh_type
== SHT_DYNSYM
)
2185 patch_dynsym_undef(s1
, s
);
2186 while (offset
< s
->sh_offset
) {
2192 fwrite(s
->data
, 1, size
, f
);
2197 /* output section headers */
2198 while (offset
< ehdr
.e_shoff
) {
2203 for(i
= 0; i
< s1
->nb_sections
; i
++) {
2205 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2206 s
= s1
->sections
[i
];
2208 sh
->sh_name
= s
->sh_name
;
2209 sh
->sh_type
= s
->sh_type
;
2210 sh
->sh_flags
= s
->sh_flags
;
2211 sh
->sh_entsize
= s
->sh_entsize
;
2212 sh
->sh_info
= s
->sh_info
;
2214 sh
->sh_link
= s
->link
->sh_num
;
2215 sh
->sh_addralign
= s
->sh_addralign
;
2216 sh
->sh_addr
= s
->sh_addr
;
2217 sh
->sh_offset
= s
->sh_offset
;
2218 sh
->sh_size
= s
->sh_size
;
2220 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2224 /* Write an elf, coff or "binary" file */
2225 static int tcc_write_elf_file(TCCState
*s1
, const char *filename
, int phnum
,
2226 ElfW(Phdr
) *phdr
, int file_offset
, int *sec_order
)
2228 int fd
, mode
, file_type
;
2231 file_type
= s1
->output_type
;
2232 if (file_type
== TCC_OUTPUT_OBJ
)
2237 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2239 tcc_error_noabort("could not write '%s'", filename
);
2242 f
= fdopen(fd
, "wb");
2244 printf("<- %s\n", filename
);
2246 #ifdef TCC_TARGET_COFF
2247 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
)
2248 tcc_output_coff(s1
, f
);
2251 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2252 tcc_output_elf(s1
, f
, phnum
, phdr
, file_offset
, sec_order
);
2254 tcc_output_binary(s1
, f
, sec_order
);
2260 /* Output an elf, coff or binary file */
2261 /* XXX: suppress unneeded sections */
2262 static int elf_output_file(TCCState
*s1
, const char *filename
)
2264 int i
, ret
, phnum
, shnum
, file_type
, file_offset
, *sec_order
;
2265 struct dyn_inf dyninf
;
2268 Section
*strsec
, *interp
, *dynamic
, *dynstr
;
2270 file_type
= s1
->output_type
;
2273 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2274 if (file_type
!= TCC_OUTPUT_OBJ
) {
2275 tcc_add_runtime(s1
);
2280 interp
= dynamic
= dynstr
= NULL
; /* avoid warning */
2281 dyninf
.dyn_rel_off
= 0; /* avoid warning */
2283 if (file_type
!= TCC_OUTPUT_OBJ
) {
2284 relocate_common_syms();
2286 tcc_add_linker_symbols(s1
);
2288 if (!s1
->static_link
) {
2289 if (file_type
== TCC_OUTPUT_EXE
) {
2291 /* allow override the dynamic loader */
2292 const char *elfint
= getenv("LD_SO");
2294 elfint
= DEFAULT_ELFINTERP(s1
);
2295 /* add interpreter section only if executable */
2296 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
2297 interp
->sh_addralign
= 1;
2298 ptr
= section_ptr_add(interp
, 1 + strlen(elfint
));
2299 strcpy(ptr
, elfint
);
2302 /* add dynamic symbol table */
2303 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
2305 ".hash", SHF_ALLOC
);
2306 dynstr
= s1
->dynsym
->link
;
2308 /* add dynamic section */
2309 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
2310 SHF_ALLOC
| SHF_WRITE
);
2311 dynamic
->link
= dynstr
;
2312 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
2316 if (file_type
== TCC_OUTPUT_EXE
) {
2317 bind_exe_dynsyms(s1
);
2319 if (s1
->nb_errors
) {
2324 bind_libs_dynsyms(s1
);
2325 } else /* shared library case: simply export all global symbols */
2326 export_global_syms(s1
);
2328 build_got_entries(s1
);
2330 /* add a list of needed dlls */
2331 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2332 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
2333 if (dllref
->level
== 0)
2334 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
2338 put_dt(dynamic
, DT_RPATH
, put_elf_str(dynstr
, s1
->rpath
));
2340 /* XXX: currently, since we do not handle PIC code, we
2341 must relocate the readonly segments */
2342 if (file_type
== TCC_OUTPUT_DLL
) {
2344 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
2345 put_dt(dynamic
, DT_TEXTREL
, 0);
2349 put_dt(dynamic
, DT_SYMBOLIC
, 0);
2351 /* add necessary space for other entries */
2352 dyninf
.dyn_rel_off
= dynamic
->data_offset
;
2353 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * EXTRA_RELITEMS
;
2355 /* still need to build got entries in case of static link */
2356 build_got_entries(s1
);
2360 /* we add a section for symbols */
2361 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
2362 put_elf_str(strsec
, "");
2364 /* compute number of sections */
2365 shnum
= s1
->nb_sections
;
2367 /* this array is used to reorder sections in the output file */
2368 sec_order
= tcc_malloc(sizeof(int) * shnum
);
2371 /* compute number of program headers */
2374 case TCC_OUTPUT_OBJ
:
2377 case TCC_OUTPUT_EXE
:
2378 if (!s1
->static_link
)
2379 phnum
= 4 + HAVE_PHDR
;
2383 case TCC_OUTPUT_DLL
:
2388 /* Allocate strings for section names */
2389 alloc_sec_names(s1
, file_type
, strsec
);
2391 /* allocate program segment headers */
2392 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
2394 /* compute section to program header mapping */
2395 file_offset
= layout_sections(s1
, phdr
, phnum
, interp
, strsec
, &dyninf
,
2398 /* Fill remaining program header and finalize relocation related to dynamic
2401 fill_unloadable_phdr(phdr
, phnum
, interp
, dynamic
);
2403 dyninf
.dynamic
= dynamic
;
2404 dyninf
.dynstr
= dynstr
;
2406 fill_dynamic(s1
, &dyninf
);
2408 /* put in GOT the dynamic section address and relocate PLT */
2409 write32le(s1
->got
->data
, dynamic
->sh_addr
);
2410 if (file_type
== TCC_OUTPUT_EXE
2411 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
2412 || file_type
== TCC_OUTPUT_DLL
2417 /* relocate symbols in .dynsym now that final addresses are known */
2418 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
)) {
2419 if (sym
->st_shndx
== SHN_UNDEF
) {
2420 /* relocate to PLT if symbol corresponds to a PLT entry,
2421 but not if it's a weak symbol */
2422 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
)
2424 else if (sym
->st_value
)
2425 sym
->st_value
+= s1
->plt
->sh_addr
;
2426 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
2427 /* do symbol relocation */
2428 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
2434 /* if building executable or DLL, then relocate each section
2435 except the GOT which is already relocated */
2436 if (file_type
!= TCC_OUTPUT_OBJ
) {
2437 ret
= final_sections_reloc(s1
);
2442 /* Perform relocation to GOT or PLT entries */
2443 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2446 /* Create the ELF file with name 'filename' */
2447 ret
= tcc_write_elf_file(s1
, filename
, phnum
, phdr
, file_offset
, sec_order
);
2449 tcc_free(s1
->symtab_to_dynsym
);
2450 tcc_free(sec_order
);
2452 tcc_free(s1
->sym_attrs
);
2453 s1
->sym_attrs
= NULL
;
2457 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2460 #ifdef TCC_TARGET_PE
2461 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2462 ret
= pe_output_file(s
, filename
);
2465 ret
= elf_output_file(s
, filename
);
2469 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2473 data
= tcc_malloc(size
);
2474 lseek(fd
, file_offset
, SEEK_SET
);
2475 read(fd
, data
, size
);
2479 typedef struct SectionMergeInfo
{
2480 Section
*s
; /* corresponding existing section */
2481 unsigned long offset
; /* offset of the new section in the existing section */
2482 uint8_t new_section
; /* true if section 's' was added */
2483 uint8_t link_once
; /* true if link once section */
2486 ST_FUNC
int tcc_object_type(int fd
, ElfW(Ehdr
) *h
)
2488 int size
= read(fd
, h
, sizeof *h
);
2489 if (size
== sizeof *h
&& 0 == memcmp(h
, ELFMAG
, 4)) {
2490 if (h
->e_type
== ET_REL
)
2491 return AFF_BINTYPE_REL
;
2492 if (h
->e_type
== ET_DYN
)
2493 return AFF_BINTYPE_DYN
;
2494 } else if (size
>= 8) {
2495 if (0 == memcmp(h
, ARMAG
, 8))
2496 return AFF_BINTYPE_AR
;
2497 #ifdef TCC_TARGET_COFF
2498 if (((struct filehdr
*)h
)->f_magic
== COFF_C67_MAGIC
)
2499 return AFF_BINTYPE_C67
;
2505 /* load an object file and merge it with current files */
2506 /* XXX: handle correctly stab (debug) info */
2507 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
2508 int fd
, unsigned long file_offset
)
2511 ElfW(Shdr
) *shdr
, *sh
;
2512 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2513 unsigned char *strsec
, *strtab
;
2514 int *old_to_new_syms
;
2515 char *sh_name
, *name
;
2516 SectionMergeInfo
*sm_table
, *sm
;
2517 ElfW(Sym
) *sym
, *symtab
;
2524 stab_index
= stabstr_index
= 0;
2526 lseek(fd
, file_offset
, SEEK_SET
);
2527 if (tcc_object_type(fd
, &ehdr
) != AFF_BINTYPE_REL
)
2529 /* test CPU specific stuff */
2530 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2531 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2533 tcc_error_noabort("invalid object file");
2537 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2538 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2539 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2541 /* load section names */
2542 sh
= &shdr
[ehdr
.e_shstrndx
];
2543 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2545 /* load symtab and strtab */
2546 old_to_new_syms
= NULL
;
2550 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2552 if (sh
->sh_type
== SHT_SYMTAB
) {
2554 tcc_error_noabort("object must contain only one symtab");
2559 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2560 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2561 sm_table
[i
].s
= symtab_section
;
2563 /* now load strtab */
2564 sh
= &shdr
[sh
->sh_link
];
2565 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2569 /* now examine each section and try to merge its content with the
2571 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2572 /* no need to examine section name strtab */
2573 if (i
== ehdr
.e_shstrndx
)
2576 sh_name
= (char *) strsec
+ sh
->sh_name
;
2577 /* ignore sections types we do not handle */
2578 if (sh
->sh_type
!= SHT_PROGBITS
&&
2579 sh
->sh_type
!= SHT_RELX
&&
2581 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2583 sh
->sh_type
!= SHT_NOBITS
&&
2584 sh
->sh_type
!= SHT_PREINIT_ARRAY
&&
2585 sh
->sh_type
!= SHT_INIT_ARRAY
&&
2586 sh
->sh_type
!= SHT_FINI_ARRAY
&&
2587 strcmp(sh_name
, ".stabstr")
2590 if (sh
->sh_addralign
< 1)
2591 sh
->sh_addralign
= 1;
2592 /* find corresponding section, if any */
2593 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2594 s
= s1
->sections
[j
];
2595 if (!strcmp(s
->name
, sh_name
)) {
2596 if (!strncmp(sh_name
, ".gnu.linkonce",
2597 sizeof(".gnu.linkonce") - 1)) {
2598 /* if a 'linkonce' section is already present, we
2599 do not add it again. It is a little tricky as
2600 symbols can still be defined in
2602 sm_table
[i
].link_once
= 1;
2609 /* not found: create new section */
2610 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
& ~SHF_GROUP
);
2611 /* take as much info as possible from the section. sh_link and
2612 sh_info will be updated later */
2613 s
->sh_addralign
= sh
->sh_addralign
;
2614 s
->sh_entsize
= sh
->sh_entsize
;
2615 sm_table
[i
].new_section
= 1;
2617 if (sh
->sh_type
!= s
->sh_type
) {
2618 tcc_error_noabort("invalid section type");
2622 /* align start of section */
2623 offset
= s
->data_offset
;
2625 if (0 == strcmp(sh_name
, ".stab")) {
2629 if (0 == strcmp(sh_name
, ".stabstr")) {
2634 size
= sh
->sh_addralign
- 1;
2635 offset
= (offset
+ size
) & ~size
;
2636 if (sh
->sh_addralign
> s
->sh_addralign
)
2637 s
->sh_addralign
= sh
->sh_addralign
;
2638 s
->data_offset
= offset
;
2640 sm_table
[i
].offset
= offset
;
2642 /* concatenate sections */
2644 if (sh
->sh_type
!= SHT_NOBITS
) {
2646 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2647 ptr
= section_ptr_add(s
, size
);
2648 read(fd
, ptr
, size
);
2650 s
->data_offset
+= size
;
2655 /* gr relocate stab strings */
2656 if (stab_index
&& stabstr_index
) {
2659 s
= sm_table
[stab_index
].s
;
2660 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2661 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2662 o
= sm_table
[stabstr_index
].offset
;
2664 a
->n_strx
+= o
, a
++;
2667 /* second short pass to update sh_link and sh_info fields of new
2669 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2671 if (!s
|| !sm_table
[i
].new_section
)
2674 if (sh
->sh_link
> 0)
2675 s
->link
= sm_table
[sh
->sh_link
].s
;
2676 if (sh
->sh_type
== SHT_RELX
) {
2677 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2678 /* update backward link */
2679 s1
->sections
[s
->sh_info
]->reloc
= s
;
2684 /* resolve symbols */
2685 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2688 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2689 if (sym
->st_shndx
!= SHN_UNDEF
&&
2690 sym
->st_shndx
< SHN_LORESERVE
) {
2691 sm
= &sm_table
[sym
->st_shndx
];
2692 if (sm
->link_once
) {
2693 /* if a symbol is in a link once section, we use the
2694 already defined symbol. It is very important to get
2695 correct relocations */
2696 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2697 name
= (char *) strtab
+ sym
->st_name
;
2698 sym_index
= find_elf_sym(symtab_section
, name
);
2700 old_to_new_syms
[i
] = sym_index
;
2704 /* if no corresponding section added, no need to add symbol */
2707 /* convert section number */
2708 sym
->st_shndx
= sm
->s
->sh_num
;
2710 sym
->st_value
+= sm
->offset
;
2713 name
= (char *) strtab
+ sym
->st_name
;
2714 sym_index
= set_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2715 sym
->st_info
, sym
->st_other
,
2716 sym
->st_shndx
, name
);
2717 old_to_new_syms
[i
] = sym_index
;
2720 /* third pass to patch relocation entries */
2721 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2726 offset
= sm_table
[i
].offset
;
2727 switch(s
->sh_type
) {
2729 /* take relocation offset information */
2730 offseti
= sm_table
[sh
->sh_info
].offset
;
2731 for_each_elem(s
, (offset
/ sizeof(*rel
)), rel
, ElfW_Rel
) {
2734 /* convert symbol index */
2735 type
= ELFW(R_TYPE
)(rel
->r_info
);
2736 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2737 /* NOTE: only one symtab assumed */
2738 if (sym_index
>= nb_syms
)
2740 sym_index
= old_to_new_syms
[sym_index
];
2741 /* ignore link_once in rel section. */
2742 if (!sym_index
&& !sm
->link_once
2743 #ifdef TCC_TARGET_ARM
2744 && type
!= R_ARM_V4BX
2748 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2749 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2752 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2753 /* offset the relocation offset */
2754 rel
->r_offset
+= offseti
;
2755 #ifdef TCC_TARGET_ARM
2756 /* Jumps and branches from a Thumb code to a PLT entry need
2757 special handling since PLT entries are ARM code.
2758 Unconditional bl instructions referencing PLT entries are
2759 handled by converting these instructions into blx
2760 instructions. Other case of instructions referencing a PLT
2761 entry require to add a Thumb stub before the PLT entry to
2762 switch to ARM mode. We set bit plt_thumb_stub of the
2763 attribute of a symbol to indicate such a case. */
2764 if (type
== R_ARM_THM_JUMP24
)
2765 alloc_sym_attr(s1
, sym_index
)->plt_thumb_stub
= 1;
2778 tcc_free(old_to_new_syms
);
2785 typedef struct ArchiveHeader
{
2786 char ar_name
[16]; /* name of this member */
2787 char ar_date
[12]; /* file mtime */
2788 char ar_uid
[6]; /* owner uid; printed as decimal */
2789 char ar_gid
[6]; /* owner gid; printed as decimal */
2790 char ar_mode
[8]; /* file mode, printed as octal */
2791 char ar_size
[10]; /* file size, printed as decimal */
2792 char ar_fmag
[2]; /* should contain ARFMAG */
2795 static int get_be32(const uint8_t *b
)
2797 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2800 static long get_be64(const uint8_t *b
)
2802 long long ret
= get_be32(b
);
2803 ret
= (ret
<< 32) | (unsigned)get_be32(b
+4);
2807 /* load only the objects which resolve undefined symbols */
2808 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
, int entrysize
)
2810 long i
, bound
, nsyms
, sym_index
, off
, ret
;
2812 const char *ar_names
, *p
;
2813 const uint8_t *ar_index
;
2816 data
= tcc_malloc(size
);
2817 if (read(fd
, data
, size
) != size
)
2819 nsyms
= entrysize
== 4 ? get_be32(data
) : get_be64(data
);
2820 ar_index
= data
+ entrysize
;
2821 ar_names
= (char *) ar_index
+ nsyms
* entrysize
;
2825 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2826 sym_index
= find_elf_sym(symtab_section
, p
);
2828 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2829 if(sym
->st_shndx
== SHN_UNDEF
) {
2830 off
= (entrysize
== 4
2831 ? get_be32(ar_index
+ i
* 4)
2832 : get_be64(ar_index
+ i
* 8))
2833 + sizeof(ArchiveHeader
);
2835 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2850 /* load a '.a' file */
2851 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
)
2858 unsigned long file_offset
;
2860 /* skip magic which was already checked */
2861 read(fd
, magic
, sizeof(magic
));
2864 len
= read(fd
, &hdr
, sizeof(hdr
));
2867 if (len
!= sizeof(hdr
)) {
2868 tcc_error_noabort("invalid archive");
2871 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2872 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2873 size
= strtol(ar_size
, NULL
, 0);
2874 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2875 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2876 if (ar_name
[i
] != ' ')
2879 ar_name
[i
+ 1] = '\0';
2880 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2882 size
= (size
+ 1) & ~1;
2883 if (!strcmp(ar_name
, "/")) {
2884 /* coff symbol table : we handle it */
2885 if(s1
->alacarte_link
)
2886 return tcc_load_alacarte(s1
, fd
, size
, 4);
2887 } else if (!strcmp(ar_name
, "/SYM64/")) {
2888 if(s1
->alacarte_link
)
2889 return tcc_load_alacarte(s1
, fd
, size
, 8);
2892 if (tcc_object_type(fd
, &ehdr
) == AFF_BINTYPE_REL
) {
2893 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2897 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2902 #ifndef TCC_TARGET_PE
2903 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2904 is referenced by the user (so it should be added as DT_NEEDED in
2905 the generated ELF file) */
2906 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2909 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2910 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2911 ElfW(Sym
) *sym
, *dynsym
;
2912 ElfW(Dyn
) *dt
, *dynamic
;
2913 unsigned char *dynstr
;
2914 const char *name
, *soname
;
2915 DLLReference
*dllref
;
2917 read(fd
, &ehdr
, sizeof(ehdr
));
2919 /* test CPU specific stuff */
2920 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2921 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2922 tcc_error_noabort("bad architecture");
2927 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2929 /* load dynamic section and dynamic symbols */
2933 dynsym
= NULL
; /* avoid warning */
2934 dynstr
= NULL
; /* avoid warning */
2935 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2936 switch(sh
->sh_type
) {
2938 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2939 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2942 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2943 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2944 sh1
= &shdr
[sh
->sh_link
];
2945 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2952 /* compute the real library name */
2953 soname
= tcc_basename(filename
);
2955 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2956 if (dt
->d_tag
== DT_SONAME
) {
2957 soname
= (char *) dynstr
+ dt
->d_un
.d_val
;
2961 /* if the dll is already loaded, do not load it */
2962 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2963 dllref
= s1
->loaded_dlls
[i
];
2964 if (!strcmp(soname
, dllref
->name
)) {
2965 /* but update level if needed */
2966 if (level
< dllref
->level
)
2967 dllref
->level
= level
;
2973 /* add the dll and its level */
2974 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2975 dllref
->level
= level
;
2976 strcpy(dllref
->name
, soname
);
2977 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2979 /* add dynamic symbols in dynsym_section */
2980 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2981 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2982 if (sym_bind
== STB_LOCAL
)
2984 name
= (char *) dynstr
+ sym
->st_name
;
2985 set_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2986 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2989 /* load all referenced DLLs */
2990 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2993 name
= (char *) dynstr
+ dt
->d_un
.d_val
;
2994 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2995 dllref
= s1
->loaded_dlls
[j
];
2996 if (!strcmp(name
, dllref
->name
))
2997 goto already_loaded
;
2999 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
3000 tcc_error_noabort("referenced dll '%s' not found", name
);
3017 #define LD_TOK_NAME 256
3018 #define LD_TOK_EOF (-1)
3020 /* return next ld script token */
3021 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
3039 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
3040 ch
= file
->buf_ptr
[0];
3053 /* case 'a' ... 'z': */
3080 /* case 'A' ... 'z': */
3114 if (!((ch
>= 'a' && ch
<= 'z') ||
3115 (ch
>= 'A' && ch
<= 'Z') ||
3116 (ch
>= '0' && ch
<= '9') ||
3117 strchr("/.-_+=$:\\,~", ch
)))
3119 if ((q
- name
) < name_size
- 1) {
3138 static int ld_add_file(TCCState
*s1
, const char filename
[])
3142 ret
= tcc_add_file_internal(s1
, filename
, AFF_TYPE_BIN
);
3144 ret
= tcc_add_dll(s1
, filename
, 0);
3148 static inline int new_undef_syms(void)
3151 ret
= new_undef_sym
;
3156 static int ld_add_file_list(TCCState
*s1
, const char *cmd
, int as_needed
)
3158 char filename
[1024], libname
[1024];
3159 int t
, group
, nblibs
= 0, ret
= 0;
3162 group
= !strcmp(cmd
, "GROUP");
3165 t
= ld_next(s1
, filename
, sizeof(filename
));
3168 t
= ld_next(s1
, filename
, sizeof(filename
));
3171 if (t
== LD_TOK_EOF
) {
3172 tcc_error_noabort("unexpected end of file");
3174 goto lib_parse_error
;
3175 } else if (t
== ')') {
3177 } else if (t
== '-') {
3178 t
= ld_next(s1
, filename
, sizeof(filename
));
3179 if ((t
!= LD_TOK_NAME
) || (filename
[0] != 'l')) {
3180 tcc_error_noabort("library name expected");
3182 goto lib_parse_error
;
3184 pstrcpy(libname
, sizeof libname
, &filename
[1]);
3185 if (s1
->static_link
) {
3186 snprintf(filename
, sizeof filename
, "lib%s.a", libname
);
3188 snprintf(filename
, sizeof filename
, "lib%s.so", libname
);
3190 } else if (t
!= LD_TOK_NAME
) {
3191 tcc_error_noabort("filename expected");
3193 goto lib_parse_error
;
3195 if (!strcmp(filename
, "AS_NEEDED")) {
3196 ret
= ld_add_file_list(s1
, cmd
, 1);
3198 goto lib_parse_error
;
3200 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3202 ret
= ld_add_file(s1
, filename
);
3204 goto lib_parse_error
;
3206 /* Add the filename *and* the libname to avoid future conversions */
3207 dynarray_add((void ***) &libs
, &nblibs
, tcc_strdup(filename
));
3208 if (libname
[0] != '\0')
3209 dynarray_add((void ***) &libs
, &nblibs
, tcc_strdup(libname
));
3213 t
= ld_next(s1
, filename
, sizeof(filename
));
3215 t
= ld_next(s1
, filename
, sizeof(filename
));
3218 if (group
&& !as_needed
) {
3219 while (new_undef_syms()) {
3222 for (i
= 0; i
< nblibs
; i
++)
3223 ld_add_file(s1
, libs
[i
]);
3227 dynarray_reset(&libs
, &nblibs
);
3231 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3233 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
)
3236 char filename
[1024];
3241 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3242 if (t
== LD_TOK_EOF
)
3244 else if (t
!= LD_TOK_NAME
)
3246 if (!strcmp(cmd
, "INPUT") ||
3247 !strcmp(cmd
, "GROUP")) {
3248 ret
= ld_add_file_list(s1
, cmd
, 0);
3251 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
3252 !strcmp(cmd
, "TARGET")) {
3253 /* ignore some commands */
3254 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3258 t
= ld_next(s1
, filename
, sizeof(filename
));
3259 if (t
== LD_TOK_EOF
) {
3260 tcc_error_noabort("unexpected end of file");
3262 } else if (t
== ')') {
3272 #endif /* !TCC_TARGET_PE */