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 /* elf version information */
37 #define nb_sym_versions s1->nb_sym_versions
38 #define sym_versions s1->sym_versions
39 #define nb_sym_to_version s1->nb_sym_to_version
40 #define sym_to_version s1->sym_to_version
41 #define dt_verneednum s1->dt_verneednum
42 #define versym_section s1->versym_section
43 #define verneed_section s1->verneed_section
45 /* special flag to indicate that the section should not be linked to the other ones */
46 #define SHF_PRIVATE 0x80000000
47 /* section is dynsymtab_section */
48 #define SHF_DYNSYM 0x40000000
51 #define shf_RELRO SHF_ALLOC
52 static const char rdata
[] = ".rdata";
54 #define shf_RELRO s1->shf_RELRO
55 static const char rdata
[] = ".data.ro";
58 /* ------------------------------------------------------------------------- */
60 ST_FUNC
void tccelf_new(TCCState
*s
)
65 shf_RELRO
= SHF_ALLOC
;
66 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
67 shf_RELRO
|= SHF_WRITE
; /* the ELF loader will set it to RO at runtime */
71 dynarray_add(&s
->sections
, &s
->nb_sections
, NULL
);
73 /* create standard sections */
74 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
75 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
76 /* create ro data section (make ro after relocation done with GNU_RELRO) */
77 rodata_section
= new_section(s
, rdata
, SHT_PROGBITS
, shf_RELRO
);
78 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
79 common_section
= new_section(s
, ".common", SHT_NOBITS
, SHF_PRIVATE
);
80 common_section
->sh_num
= SHN_COMMON
;
82 /* symbols are always generated for linking stage */
83 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
85 ".hashtab", SHF_PRIVATE
);
87 /* private symbol table for dynamic symbols */
88 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
|SHF_DYNSYM
,
90 ".dynhashtab", SHF_PRIVATE
);
91 get_sym_attr(s
, 0, 1);
94 /* add debug sections */
98 #ifdef CONFIG_TCC_BCHECK
99 if (s
->do_bounds_check
) {
100 /* if bound checking, then add corresponding sections */
101 /* (make ro after relocation done with GNU_RELRO) */
102 bounds_section
= new_section(s
, ".bounds", SHT_PROGBITS
, shf_RELRO
);
103 lbounds_section
= new_section(s
, ".lbounds", SHT_PROGBITS
, shf_RELRO
);
108 ST_FUNC
void free_section(Section
*s
)
114 s
->data_allocated
= s
->data_offset
= 0;
117 ST_FUNC
void tccelf_delete(TCCState
*s1
)
122 /* free symbol versions */
123 for (i
= 0; i
< nb_sym_versions
; i
++) {
124 tcc_free(sym_versions
[i
].version
);
125 tcc_free(sym_versions
[i
].lib
);
127 tcc_free(sym_versions
);
128 tcc_free(sym_to_version
);
131 /* free all sections */
132 for(i
= 1; i
< s1
->nb_sections
; i
++)
133 free_section(s1
->sections
[i
]);
134 dynarray_reset(&s1
->sections
, &s1
->nb_sections
);
136 for(i
= 0; i
< s1
->nb_priv_sections
; i
++)
137 free_section(s1
->priv_sections
[i
]);
138 dynarray_reset(&s1
->priv_sections
, &s1
->nb_priv_sections
);
140 tcc_free(s1
->sym_attrs
);
141 symtab_section
= NULL
; /* for tccrun.c:rt_printline() */
144 /* save section data state */
145 ST_FUNC
void tccelf_begin_file(TCCState
*s1
)
148 for (i
= 1; i
< s1
->nb_sections
; i
++) {
150 s
->sh_offset
= s
->data_offset
;
152 /* disable symbol hashing during compilation */
153 s
= s1
->symtab
, s
->reloc
= s
->hash
, s
->hash
= NULL
;
154 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
160 static void update_relocs(TCCState
*s1
, Section
*s
, int *old_to_new_syms
, int first_sym
);
162 /* At the end of compilation, convert any UNDEF syms to global, and merge
163 with previously existing symbols */
164 ST_FUNC
void tccelf_end_file(TCCState
*s1
)
166 Section
*s
= s1
->symtab
;
167 int first_sym
, nb_syms
, *tr
, i
;
169 first_sym
= s
->sh_offset
/ sizeof (ElfSym
);
170 nb_syms
= s
->data_offset
/ sizeof (ElfSym
) - first_sym
;
171 s
->data_offset
= s
->sh_offset
;
172 s
->link
->data_offset
= s
->link
->sh_offset
;
173 s
->hash
= s
->reloc
, s
->reloc
= NULL
;
174 tr
= tcc_mallocz(nb_syms
* sizeof *tr
);
176 for (i
= 0; i
< nb_syms
; ++i
) {
177 ElfSym
*sym
= (ElfSym
*)s
->data
+ first_sym
+ i
;
178 if (sym
->st_shndx
== SHN_UNDEF
) {
179 int sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
180 int sym_type
= ELFW(ST_TYPE
)(sym
->st_info
);
181 if (sym_bind
== STB_LOCAL
)
182 sym_bind
= STB_GLOBAL
;
183 #ifndef TCC_TARGET_PE
184 if (sym_bind
== STB_GLOBAL
&& s1
->output_type
== TCC_OUTPUT_OBJ
) {
185 /* undefined symbols with STT_FUNC are confusing gnu ld when
186 linking statically to STT_GNU_IFUNC */
187 sym_type
= STT_NOTYPE
;
190 sym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
192 tr
[i
] = set_elf_sym(s
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
193 sym
->st_other
, sym
->st_shndx
, (char*)s
->link
->data
+ sym
->st_name
);
195 /* now update relocations */
196 update_relocs(s1
, s
, tr
, first_sym
);
198 /* record text/data/bss output for -bench info */
199 for (i
= 0; i
< 4; ++i
) {
200 s
= s1
->sections
[i
+ 1];
201 s1
->total_output
[i
] += s
->data_offset
- s
->sh_offset
;
205 ST_FUNC Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
209 sec
= tcc_mallocz(sizeof(Section
) + strlen(name
));
211 strcpy(sec
->name
, name
);
212 sec
->sh_type
= sh_type
;
213 sec
->sh_flags
= sh_flags
;
216 sec
->sh_addralign
= 2;
225 case SHT_GNU_verneed
:
227 sec
->sh_addralign
= PTR_SIZE
;
230 sec
->sh_addralign
= 1;
233 sec
->sh_addralign
= PTR_SIZE
; /* gcc/pcc default alignment */
237 if (sh_flags
& SHF_PRIVATE
) {
238 dynarray_add(&s1
->priv_sections
, &s1
->nb_priv_sections
, sec
);
240 sec
->sh_num
= s1
->nb_sections
;
241 dynarray_add(&s1
->sections
, &s1
->nb_sections
, sec
);
247 ST_FUNC
void init_symtab(Section
*s
)
249 int *ptr
, nb_buckets
= 1;
250 put_elf_str(s
->link
, "");
251 section_ptr_add(s
, sizeof (ElfW(Sym
)));
252 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ 1) * sizeof(int));
255 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
258 ST_FUNC Section
*new_symtab(TCCState
*s1
,
259 const char *symtab_name
, int sh_type
, int sh_flags
,
260 const char *strtab_name
,
261 const char *hash_name
, int hash_sh_flags
)
263 Section
*symtab
, *strtab
, *hash
;
264 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
265 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
266 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
267 symtab
->link
= strtab
;
268 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
269 hash
->sh_entsize
= sizeof(int);
276 /* realloc section and set its content to zero */
277 ST_FUNC
void section_realloc(Section
*sec
, unsigned long new_size
)
282 size
= sec
->data_allocated
;
285 while (size
< new_size
)
287 data
= tcc_realloc(sec
->data
, size
);
288 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
290 sec
->data_allocated
= size
;
293 /* reserve at least 'size' bytes aligned per 'align' in section
294 'sec' from current offset, and return the aligned offset */
295 ST_FUNC
size_t section_add(Section
*sec
, addr_t size
, int align
)
297 size_t offset
, offset1
;
299 offset
= (sec
->data_offset
+ align
- 1) & -align
;
300 offset1
= offset
+ size
;
301 if (sec
->sh_type
!= SHT_NOBITS
&& offset1
> sec
->data_allocated
)
302 section_realloc(sec
, offset1
);
303 sec
->data_offset
= offset1
;
304 if (align
> sec
->sh_addralign
)
305 sec
->sh_addralign
= align
;
309 /* reserve at least 'size' bytes in section 'sec' from
311 ST_FUNC
void *section_ptr_add(Section
*sec
, addr_t size
)
313 size_t offset
= section_add(sec
, size
, 1);
314 return sec
->data
+ offset
;
318 /* reserve at least 'size' bytes from section start */
319 static void section_reserve(Section
*sec
, unsigned long size
)
321 if (size
> sec
->data_allocated
)
322 section_realloc(sec
, size
);
323 if (size
> sec
->data_offset
)
324 sec
->data_offset
= size
;
328 static Section
*have_section(TCCState
*s1
, const char *name
)
332 for(i
= 1; i
< s1
->nb_sections
; i
++) {
333 sec
= s1
->sections
[i
];
334 if (!strcmp(name
, sec
->name
))
340 /* return a reference to a section, and create it if it does not
342 ST_FUNC Section
*find_section(TCCState
*s1
, const char *name
)
344 Section
*sec
= have_section(s1
, name
);
347 /* sections are created as PROGBITS */
348 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
351 /* ------------------------------------------------------------------------- */
353 ST_FUNC
int put_elf_str(Section
*s
, const char *sym
)
358 len
= strlen(sym
) + 1;
359 offset
= s
->data_offset
;
360 ptr
= section_ptr_add(s
, len
);
361 memmove(ptr
, sym
, len
);
365 /* elf symbol hashing function */
366 static ElfW(Word
) elf_hash(const unsigned char *name
)
371 h
= (h
<< 4) + *name
++;
380 /* rebuild hash table of section s */
381 /* NOTE: we do factorize the hash table code to go faster */
382 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
385 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
386 unsigned char *strtab
;
388 strtab
= s
->link
->data
;
389 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
392 nb_buckets
= ((int*)s
->hash
->data
)[0];
394 s
->hash
->data_offset
= 0;
395 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
400 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
401 ptr
+= nb_buckets
+ 1;
403 sym
= (ElfW(Sym
) *)s
->data
+ 1;
404 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
405 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
406 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
417 /* return the symbol number */
418 ST_FUNC
int put_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
419 int info
, int other
, int shndx
, const char *name
)
421 int name_offset
, sym_index
;
426 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
428 name_offset
= put_elf_str(s
->link
, name
);
431 /* XXX: endianness */
432 sym
->st_name
= name_offset
;
433 sym
->st_value
= value
;
436 sym
->st_other
= other
;
437 sym
->st_shndx
= shndx
;
438 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
442 ptr
= section_ptr_add(hs
, sizeof(int));
443 base
= (int *)hs
->data
;
444 /* only add global or weak symbols. */
445 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
446 /* add another hashing entry */
448 h
= elf_hash((unsigned char *)s
->link
->data
+ name_offset
) % nbuckets
;
450 base
[2 + h
] = sym_index
;
452 /* we resize the hash table */
453 hs
->nb_hashed_syms
++;
454 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
455 rebuild_hash(s
, 2 * nbuckets
);
465 ST_FUNC
int find_elf_sym(Section
*s
, const char *name
)
469 int nbuckets
, sym_index
, h
;
475 nbuckets
= ((int *)hs
->data
)[0];
476 h
= elf_hash((unsigned char *) name
) % nbuckets
;
477 sym_index
= ((int *)hs
->data
)[2 + h
];
478 while (sym_index
!= 0) {
479 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
480 name1
= (char *) s
->link
->data
+ sym
->st_name
;
481 if (!strcmp(name
, name1
))
483 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
488 /* return elf symbol value, signal error if 'err' is nonzero, decorate
490 ST_FUNC addr_t
get_sym_addr(TCCState
*s1
, const char *name
, int err
, int forc
)
495 if (forc
&& s1
->leading_underscore
497 /* win32-32bit stdcall symbols always have _ already */
498 && !strchr(name
, '@')
502 pstrcpy(buf
+ 1, sizeof(buf
) - 1, name
);
505 sym_index
= find_elf_sym(s1
->symtab
, name
);
506 sym
= &((ElfW(Sym
) *)s1
->symtab
->data
)[sym_index
];
507 if (!sym_index
|| sym
->st_shndx
== SHN_UNDEF
) {
509 tcc_error_noabort("%s not defined", name
);
512 return sym
->st_value
;
515 /* return elf symbol value */
516 LIBTCCAPI
void *tcc_get_symbol(TCCState
*s
, const char *name
)
518 addr_t addr
= get_sym_addr(s
, name
, 0, 1);
519 return addr
== -1 ? NULL
: (void*)(uintptr_t)addr
;
522 /* list elf symbol names and values */
523 ST_FUNC
void list_elf_symbols(TCCState
*s
, void *ctx
,
524 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
528 int sym_index
, end_sym
;
530 unsigned char sym_vis
, sym_bind
;
533 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
534 for (sym_index
= 0; sym_index
< end_sym
; ++sym_index
) {
535 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
537 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
538 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
539 sym_vis
= ELFW(ST_VISIBILITY
)(sym
->st_other
);
540 if (sym_bind
== STB_GLOBAL
&& sym_vis
== STV_DEFAULT
)
541 symbol_cb(ctx
, name
, (void*)(uintptr_t)sym
->st_value
);
546 /* list elf symbol names and values */
547 LIBTCCAPI
void tcc_list_symbols(TCCState
*s
, void *ctx
,
548 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
550 list_elf_symbols(s
, ctx
, symbol_cb
);
555 version_add (TCCState
*s1
)
559 ElfW(Verneed
) *vn
= NULL
;
561 int sym_index
, end_sym
, nb_versions
= 2, nb_entries
= 0;
565 if (0 == nb_sym_versions
)
567 versym_section
= new_section(s1
, ".gnu.version", SHT_GNU_versym
, SHF_ALLOC
);
568 versym_section
->sh_entsize
= sizeof(ElfW(Half
));
569 versym_section
->link
= s1
->dynsym
;
571 /* add needed symbols */
573 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
574 versym
= section_ptr_add(versym_section
, end_sym
* sizeof(ElfW(Half
)));
575 for (sym_index
= 1; sym_index
< end_sym
; ++sym_index
) {
576 int dllindex
, verndx
;
577 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
578 if (sym
->st_shndx
!= SHN_UNDEF
)
579 continue; /* defined symbol doesn't need library version */
580 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
581 dllindex
= find_elf_sym(s1
->dynsymtab_section
, name
);
582 verndx
= (dllindex
&& dllindex
< nb_sym_to_version
)
583 ? sym_to_version
[dllindex
] : -1;
585 if (!sym_versions
[verndx
].out_index
)
586 sym_versions
[verndx
].out_index
= nb_versions
++;
587 versym
[sym_index
] = sym_versions
[verndx
].out_index
;
590 /* generate verneed section, but not when it will be empty. Some
591 dynamic linkers look at their contents even when DTVERNEEDNUM and
592 section size is zero. */
593 if (nb_versions
> 2) {
594 verneed_section
= new_section(s1
, ".gnu.version_r",
595 SHT_GNU_verneed
, SHF_ALLOC
);
596 verneed_section
->link
= s1
->dynsym
->link
;
597 for (i
= nb_sym_versions
; i
-- > 0;) {
598 struct sym_version
*sv
= &sym_versions
[i
];
599 int n_same_libs
= 0, prev
;
601 ElfW(Vernaux
) *vna
= 0;
602 if (sv
->out_index
< 1)
605 /* make sure that a DT_NEEDED tag is put */
606 /* abitest-tcc fails on older i386-linux with "ld-linux.so.2" DT_NEEDED
607 ret_int_test... Inconsistency detected by ld.so: dl-minimal.c: 148:
608 realloc: Assertion `ptr == alloc_last_block' failed! */
609 if (strcmp(sv
->lib
, "ld-linux.so.2"))
610 tcc_add_dllref(s1
, sv
->lib
, 0);
612 vnofs
= section_add(verneed_section
, sizeof(*vn
), 1);
613 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
615 vn
->vn_file
= put_elf_str(verneed_section
->link
, sv
->lib
);
616 vn
->vn_aux
= sizeof (*vn
);
618 prev
= sv
->prev_same_lib
;
619 if (sv
->out_index
> 0) {
620 vna
= section_ptr_add(verneed_section
, sizeof(*vna
));
621 vna
->vna_hash
= elf_hash ((const unsigned char *)sv
->version
);
623 vna
->vna_other
= sv
->out_index
;
625 vna
->vna_name
= put_elf_str(verneed_section
->link
, sv
->version
);
626 vna
->vna_next
= sizeof (*vna
);
630 sv
= &sym_versions
[prev
];
633 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
634 vn
->vn_cnt
= n_same_libs
;
635 vn
->vn_next
= sizeof(*vn
) + n_same_libs
* sizeof(*vna
);
640 verneed_section
->sh_info
= nb_entries
;
642 dt_verneednum
= nb_entries
;
644 #endif /* ndef ELF_OBJ_ONLY */
646 /* add an elf symbol : check if it is already defined and patch
647 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
648 ST_FUNC
int set_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
649 int info
, int other
, int shndx
, const char *name
)
651 TCCState
*s1
= s
->s1
;
653 int sym_bind
, sym_index
, sym_type
, esym_bind
;
654 unsigned char sym_vis
, esym_vis
, new_vis
;
656 sym_bind
= ELFW(ST_BIND
)(info
);
657 sym_type
= ELFW(ST_TYPE
)(info
);
658 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
660 if (sym_bind
!= STB_LOCAL
) {
661 /* we search global or weak symbols */
662 sym_index
= find_elf_sym(s
, name
);
665 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
666 if (esym
->st_value
== value
&& esym
->st_size
== size
&& esym
->st_info
== info
667 && esym
->st_other
== other
&& esym
->st_shndx
== shndx
)
669 if (esym
->st_shndx
!= SHN_UNDEF
) {
670 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
671 /* propagate the most constraining visibility */
672 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
673 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
674 if (esym_vis
== STV_DEFAULT
) {
676 } else if (sym_vis
== STV_DEFAULT
) {
679 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
681 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
683 if (shndx
== SHN_UNDEF
) {
684 /* ignore adding of undefined symbol if the
685 corresponding symbol is already defined */
686 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
687 /* global overrides weak, so patch */
689 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
690 /* weak is ignored if already global */
691 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_WEAK
) {
692 /* keep first-found weak definition, ignore subsequents */
693 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
694 /* ignore hidden symbols after */
695 } else if ((esym
->st_shndx
== SHN_COMMON
696 || esym
->st_shndx
== bss_section
->sh_num
)
697 && (shndx
< SHN_LORESERVE
698 && shndx
!= bss_section
->sh_num
)) {
699 /* data symbol gets precedence over common/bss */
701 } else if (shndx
== SHN_COMMON
|| shndx
== bss_section
->sh_num
) {
702 /* data symbol keeps precedence over common/bss */
703 } else if (s
->sh_flags
& SHF_DYNSYM
) {
704 /* we accept that two DLL define the same symbol */
705 } else if (esym
->st_other
& ST_ASM_SET
) {
706 /* If the existing symbol came from an asm .set
711 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
712 sym_bind
, shndx
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
714 tcc_error_noabort("'%s' defined twice", name
);
717 esym
->st_other
= other
;
719 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
720 esym
->st_shndx
= shndx
;
721 s1
->new_undef_sym
= 1;
722 esym
->st_value
= value
;
723 esym
->st_size
= size
;
727 sym_index
= put_elf_sym(s
, value
, size
,
728 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
735 ST_FUNC
void put_elf_reloca(Section
*symtab
, Section
*s
, unsigned long offset
,
736 int type
, int symbol
, addr_t addend
)
738 TCCState
*s1
= s
->s1
;
745 /* if no relocation section, create it */
746 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
747 /* if the symtab is allocated, then we consider the relocation
749 sr
= new_section(s
->s1
, buf
, SHT_RELX
, symtab
->sh_flags
);
750 sr
->sh_entsize
= sizeof(ElfW_Rel
);
752 sr
->sh_info
= s
->sh_num
;
755 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
756 rel
->r_offset
= offset
;
757 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
758 #if SHT_RELX == SHT_RELA
759 rel
->r_addend
= addend
;
761 if (SHT_RELX
!= SHT_RELA
&& addend
)
762 tcc_error_noabort("non-zero addend on REL architecture");
765 ST_FUNC
void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
766 int type
, int symbol
)
768 put_elf_reloca(symtab
, s
, offset
, type
, symbol
, 0);
771 ST_FUNC
struct sym_attr
*get_sym_attr(TCCState
*s1
, int index
, int alloc
)
774 struct sym_attr
*tab
;
776 if (index
>= s1
->nb_sym_attrs
) {
778 return s1
->sym_attrs
;
779 /* find immediately bigger power of 2 and reallocate array */
783 tab
= tcc_realloc(s1
->sym_attrs
, n
* sizeof(*s1
->sym_attrs
));
785 memset(s1
->sym_attrs
+ s1
->nb_sym_attrs
, 0,
786 (n
- s1
->nb_sym_attrs
) * sizeof(*s1
->sym_attrs
));
787 s1
->nb_sym_attrs
= n
;
789 return &s1
->sym_attrs
[index
];
792 static void update_relocs(TCCState
*s1
, Section
*s
, int *old_to_new_syms
, int first_sym
)
794 int i
, type
, sym_index
;
798 for(i
= 1; i
< s1
->nb_sections
; i
++) {
799 sr
= s1
->sections
[i
];
800 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
801 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
802 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
803 type
= ELFW(R_TYPE
)(rel
->r_info
);
804 if ((sym_index
-= first_sym
) < 0)
805 continue; /* zero sym_index in reloc (can happen with asm) */
806 sym_index
= old_to_new_syms
[sym_index
];
807 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
813 /* In an ELF file symbol table, the local symbols must appear below
814 the global and weak ones. Since TCC cannot sort it while generating
815 the code, we must do it after. All the relocation tables are also
816 modified to take into account the symbol table sorting */
817 static void sort_syms(TCCState
*s1
, Section
*s
)
819 int *old_to_new_syms
;
824 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
825 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
826 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
828 /* first pass for local symbols */
829 p
= (ElfW(Sym
) *)s
->data
;
831 for(i
= 0; i
< nb_syms
; i
++) {
832 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
833 old_to_new_syms
[i
] = q
- new_syms
;
838 /* save the number of local symbols in section header */
839 if( s
->sh_size
) /* this 'if' makes IDA happy */
840 s
->sh_info
= q
- new_syms
;
842 /* then second pass for non local symbols */
843 p
= (ElfW(Sym
) *)s
->data
;
844 for(i
= 0; i
< nb_syms
; i
++) {
845 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
846 old_to_new_syms
[i
] = q
- new_syms
;
852 /* we copy the new symbols to the old */
853 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
856 update_relocs(s1
, s
, old_to_new_syms
, 0);
857 tcc_free(old_to_new_syms
);
861 /* See: https://flapenguin.me/elf-dt-gnu-hash */
862 #define ELFCLASS_BITS (PTR_SIZE * 8)
864 static Section
*create_gnu_hash(TCCState
*s1
)
866 int nb_syms
, i
, ndef
, nbuckets
, symoffset
, bloom_size
, bloom_shift
;
869 Section
*dynsym
= s1
->dynsym
;
872 gnu_hash
= new_section(s1
, ".gnu.hash", SHT_GNU_HASH
, SHF_ALLOC
);
873 gnu_hash
->link
= dynsym
->hash
->link
;
875 nb_syms
= dynsym
->data_offset
/ sizeof(ElfW(Sym
));
877 /* count def symbols */
879 p
= (ElfW(Sym
) *)dynsym
->data
;
880 for(i
= 0; i
< nb_syms
; i
++, p
++)
881 ndef
+= p
->st_shndx
!= SHN_UNDEF
;
883 /* calculate gnu hash sizes and fill header */
884 nbuckets
= ndef
/ 4 + 1;
885 symoffset
= nb_syms
- ndef
;
886 bloom_shift
= PTR_SIZE
== 8 ? 6 : 5;
887 bloom_size
= 1; /* must be power of two */
888 while (ndef
>= bloom_size
* (1 << (bloom_shift
- 3)))
890 ptr
= section_ptr_add(gnu_hash
, 4 * 4 +
891 PTR_SIZE
* bloom_size
+
897 ptr
[3] = bloom_shift
;
901 static Elf32_Word
elf_gnu_hash (const unsigned char *name
)
906 while ((c
= *name
++))
911 static void update_gnu_hash(TCCState
*s1
, Section
*gnu_hash
)
913 int *old_to_new_syms
;
915 int nb_syms
, i
, nbuckets
, bloom_size
, bloom_shift
;
918 Section
*dynsym
= s1
->dynsym
;
919 Elf32_Word
*ptr
, *buckets
, *chain
, *hash
;
920 unsigned int *nextbuck
;
922 unsigned char *strtab
;
923 struct { int first
, last
; } *buck
;
925 strtab
= dynsym
->link
->data
;
926 nb_syms
= dynsym
->data_offset
/ sizeof(ElfW(Sym
));
927 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
928 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
929 hash
= tcc_malloc(nb_syms
* sizeof(Elf32_Word
));
930 nextbuck
= tcc_malloc(nb_syms
* sizeof(int));
932 /* calculate hashes and copy undefs */
933 p
= (ElfW(Sym
) *)dynsym
->data
;
935 for(i
= 0; i
< nb_syms
; i
++, p
++) {
936 if (p
->st_shndx
== SHN_UNDEF
) {
937 old_to_new_syms
[i
] = q
- new_syms
;
941 hash
[i
] = elf_gnu_hash(strtab
+ p
->st_name
);
944 ptr
= (Elf32_Word
*) gnu_hash
->data
;
947 bloom_shift
= ptr
[3];
948 bloom
= (addr_t
*) (void *) &ptr
[4];
949 buckets
= (Elf32_Word
*) (void *) &bloom
[bloom_size
];
950 chain
= &buckets
[nbuckets
];
951 buck
= tcc_malloc(nbuckets
* sizeof(*buck
));
953 if (gnu_hash
->data_offset
!= 4 * 4 +
954 PTR_SIZE
* bloom_size
+
956 (nb_syms
- (q
- new_syms
)) * 4)
957 tcc_error_noabort ("gnu_hash size incorrect");
960 for(i
= 0; i
< nbuckets
; i
++)
963 p
= (ElfW(Sym
) *)dynsym
->data
;
964 for(i
= 0; i
< nb_syms
; i
++, p
++)
965 if (p
->st_shndx
!= SHN_UNDEF
) {
966 int bucket
= hash
[i
] % nbuckets
;
968 if (buck
[bucket
].first
== -1)
969 buck
[bucket
].first
= buck
[bucket
].last
= i
;
971 nextbuck
[buck
[bucket
].last
] = i
;
972 buck
[bucket
].last
= i
;
976 /* fill buckets/chains/bloom and sort symbols */
977 p
= (ElfW(Sym
) *)dynsym
->data
;
978 for(i
= 0; i
< nbuckets
; i
++) {
979 int cur
= buck
[i
].first
;
982 buckets
[i
] = q
- new_syms
;
984 old_to_new_syms
[cur
] = q
- new_syms
;
986 *chain
++ = hash
[cur
] & ~1;
987 bloom
[(hash
[cur
] / ELFCLASS_BITS
) % bloom_size
] |=
988 (addr_t
)1 << (hash
[cur
] % ELFCLASS_BITS
) |
989 (addr_t
)1 << ((hash
[cur
] >> bloom_shift
) % ELFCLASS_BITS
);
990 if (cur
== buck
[i
].last
)
998 memcpy(dynsym
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
1004 update_relocs(s1
, dynsym
, old_to_new_syms
, 0);
1006 /* modify the versions */
1007 vs
= versym_section
;
1009 ElfW(Half
) *newver
, *versym
= (ElfW(Half
) *)vs
->data
;
1012 newver
= tcc_malloc(nb_syms
* sizeof(*newver
));
1013 for (i
= 0; i
< nb_syms
; i
++)
1014 newver
[old_to_new_syms
[i
]] = versym
[i
];
1015 memcpy(vs
->data
, newver
, nb_syms
* sizeof(*newver
));
1020 tcc_free(old_to_new_syms
);
1023 ptr
= (Elf32_Word
*) dynsym
->hash
->data
;
1024 rebuild_hash(dynsym
, ptr
[0]);
1026 #endif /* ELF_OBJ_ONLY */
1028 /* relocate symbol table, resolve undefined symbols if do_resolve is
1029 true and output error if undefined symbol. */
1030 ST_FUNC
void relocate_syms(TCCState
*s1
, Section
*symtab
, int do_resolve
)
1033 int sym_bind
, sh_num
;
1036 for_each_elem(symtab
, 1, sym
, ElfW(Sym
)) {
1037 sh_num
= sym
->st_shndx
;
1038 if (sh_num
== SHN_UNDEF
) {
1039 if (do_resolve
== 2) /* relocating dynsym */
1041 name
= (char *) s1
->symtab
->link
->data
+ sym
->st_name
;
1042 /* Use ld.so to resolve symbol for us (for tcc -run) */
1044 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
1045 /* dlsym() needs the undecorated name. */
1046 void *addr
= dlsym(RTLD_DEFAULT
, &name
[s1
->leading_underscore
]);
1047 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD || TARGETOS_ANDROID
1050 for (i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
1051 if ((addr
= dlsym(s1
->loaded_dlls
[i
]->handle
, name
)))
1056 sym
->st_value
= (addr_t
) addr
;
1058 printf ("relocate_sym: %s -> 0x%lx\n", name
, sym
->st_value
);
1063 /* if dynamic symbol exist, it will be used in relocate_section */
1064 } else if (s1
->dynsym
&& find_elf_sym(s1
->dynsym
, name
))
1066 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1068 if (!strcmp(name
, "_fp_hw"))
1070 /* only weak symbols are accepted to be undefined. Their
1072 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
1073 if (sym_bind
== STB_WEAK
)
1076 tcc_error_noabort("undefined symbol '%s'", name
);
1078 } else if (sh_num
< SHN_LORESERVE
) {
1079 /* add section base */
1080 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1086 /* relocate a given section (CPU dependent) by applying the relocations
1087 in the associated relocation section */
1088 static void relocate_section(TCCState
*s1
, Section
*s
, Section
*sr
)
1092 int type
, sym_index
;
1095 int is_dwarf
= s
->sh_num
>= s1
->dwlo
&& s
->sh_num
< s1
->dwhi
;
1097 qrel
= (ElfW_Rel
*)sr
->data
;
1098 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
1099 ptr
= s
->data
+ rel
->r_offset
;
1100 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1101 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1102 type
= ELFW(R_TYPE
)(rel
->r_info
);
1103 tgt
= sym
->st_value
;
1104 #if SHT_RELX == SHT_RELA
1105 tgt
+= rel
->r_addend
;
1107 if (is_dwarf
&& type
== R_DATA_32DW
1108 && sym
->st_shndx
>= s1
->dwlo
&& sym
->st_shndx
< s1
->dwhi
) {
1109 /* dwarf section relocation to each other */
1110 add32le(ptr
, tgt
- s1
->sections
[sym
->st_shndx
]->sh_addr
);
1113 addr
= s
->sh_addr
+ rel
->r_offset
;
1114 relocate(s1
, rel
, type
, ptr
, addr
, tgt
);
1116 #ifndef ELF_OBJ_ONLY
1117 /* if the relocation is allocated, we change its symbol table */
1118 if (sr
->sh_flags
& SHF_ALLOC
) {
1119 sr
->link
= s1
->dynsym
;
1120 if (s1
->output_type
& TCC_OUTPUT_DYN
) {
1121 size_t r
= (uint8_t*)qrel
- sr
->data
;
1122 if (sizeof ((Stab_Sym
*)0)->n_value
< PTR_SIZE
1123 && 0 == strcmp(s
->name
, ".stab"))
1124 r
= 0; /* cannot apply 64bit relocation to 32bit value */
1125 sr
->data_offset
= sr
->sh_size
= r
;
1126 #ifdef CONFIG_TCC_PIE
1127 if (r
&& 0 == (s
->sh_flags
& SHF_WRITE
))
1128 tcc_warning("%d relocations to ro-section %s", (unsigned)(r
/ sizeof *qrel
), s
->name
);
1135 /* relocate all sections */
1136 ST_FUNC
void relocate_sections(TCCState
*s1
)
1141 for (i
= 1; i
< s1
->nb_sections
; ++i
) {
1142 sr
= s1
->sections
[i
];
1143 if (sr
->sh_type
!= SHT_RELX
)
1145 s
= s1
->sections
[sr
->sh_info
];
1146 #ifndef TCC_TARGET_MACHO
1149 || s1
->output_type
== TCC_OUTPUT_MEMORY
)
1152 relocate_section(s1
, s
, sr
);
1154 #ifndef ELF_OBJ_ONLY
1155 if (sr
->sh_flags
& SHF_ALLOC
) {
1157 /* relocate relocation table in 'sr' */
1158 for_each_elem(sr
, 0, rel
, ElfW_Rel
)
1159 rel
->r_offset
+= s
->sh_addr
;
1165 #ifndef ELF_OBJ_ONLY
1166 /* count the number of dynamic relocations so that we can reserve
1168 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
1171 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1172 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1173 defined(TCC_TARGET_RISCV64)
1175 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
1176 int sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1177 int type
= ELFW(R_TYPE
)(rel
->r_info
);
1179 #if defined(TCC_TARGET_I386)
1181 if (!get_sym_attr(s1
, sym_index
, 0)->dyn_index
1182 && ((ElfW(Sym
)*)symtab_section
->data
+ sym_index
)->st_shndx
== SHN_UNDEF
) {
1183 /* don't fixup unresolved (weak) symbols */
1184 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_386_RELATIVE
);
1187 #elif defined(TCC_TARGET_X86_64)
1191 #elif defined(TCC_TARGET_ARM)
1194 #elif defined(TCC_TARGET_ARM64)
1195 case R_AARCH64_ABS32
:
1196 case R_AARCH64_ABS64
:
1197 #elif defined(TCC_TARGET_RISCV64)
1203 #if defined(TCC_TARGET_I386)
1205 #elif defined(TCC_TARGET_X86_64)
1208 ElfW(Sym
) *sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1209 /* Hidden defined symbols can and must be resolved locally.
1210 We're misusing a PLT32 reloc for this, as that's always
1211 resolved to its address even in shared libs. */
1212 if (sym
->st_shndx
!= SHN_UNDEF
&&
1213 ELFW(ST_VISIBILITY
)(sym
->st_other
) == STV_HIDDEN
) {
1214 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PLT32
);
1218 #elif defined(TCC_TARGET_ARM64)
1219 case R_AARCH64_PREL32
:
1221 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1223 if (get_sym_attr(s1
, sym_index
, 0)->dyn_index
)
1235 #ifdef NEED_BUILD_GOT
1236 static int build_got(TCCState
*s1
)
1238 /* if no got, then create it */
1239 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
1240 s1
->got
->sh_entsize
= 4;
1241 /* keep space for _DYNAMIC pointer and two dummy got entries */
1242 section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
1243 return set_elf_sym(symtab_section
, 0, 0, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
1244 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
1247 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1248 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1249 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1250 Returns the offset of the GOT or (if any) PLT entry. */
1251 static struct sym_attr
* put_got_entry(TCCState
*s1
, int dyn_reloc_type
,
1257 struct sym_attr
*attr
;
1258 unsigned got_offset
;
1263 need_plt_entry
= (dyn_reloc_type
== R_JMP_SLOT
);
1264 attr
= get_sym_attr(s1
, sym_index
, 1);
1266 /* In case a function is both called and its address taken 2 GOT entries
1267 are created, one for taking the address (GOT) and the other for the PLT
1269 if (need_plt_entry
? attr
->plt_offset
: attr
->got_offset
)
1273 if (need_plt_entry
) {
1275 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
1276 s1
->plt
->sh_entsize
= 4;
1281 /* create the GOT entry */
1282 got_offset
= s1
->got
->data_offset
;
1283 section_ptr_add(s1
->got
, PTR_SIZE
);
1285 /* Create the GOT relocation that will insert the address of the object or
1286 function of interest in the GOT entry. This is a static relocation for
1287 memory output (dlsym will give us the address of symbols) and dynamic
1288 relocation otherwise (executable and DLLs). The relocation should be
1289 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1290 associated to a PLT entry) but is currently done at load time for an
1293 sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1294 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1295 //printf("sym %d %s\n", need_plt_entry, name);
1298 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
) {
1299 /* Hack alarm. We don't want to emit dynamic symbols
1300 and symbol based relocs for STB_LOCAL symbols, but rather
1301 want to resolve them directly. At this point the symbol
1302 values aren't final yet, so we must defer this. We will later
1303 have to create a RELATIVE reloc anyway, so we misuse the
1304 relocation slot to smuggle the symbol reference until
1305 fill_local_got_entries. Not that the sym_index is
1306 relative to symtab_section, not s1->dynsym! Nevertheless
1307 we use s1->dyn_sym so that if this is the first call
1308 that got->reloc is correctly created. Also note that
1309 RELATIVE relocs are not normally created for the .got,
1310 so the types serves as a marker for later (and is retained
1311 also for the final output, which is okay because then the
1312 got is just normal data). */
1313 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, R_RELATIVE
,
1316 if (0 == attr
->dyn_index
)
1317 attr
->dyn_index
= set_elf_sym(s1
->dynsym
, sym
->st_value
,
1318 sym
->st_size
, sym
->st_info
, 0,
1319 sym
->st_shndx
, name
);
1320 put_elf_reloc(s1
->dynsym
, s_rel
, got_offset
, dyn_reloc_type
,
1324 put_elf_reloc(symtab_section
, s1
->got
, got_offset
, dyn_reloc_type
,
1328 if (need_plt_entry
) {
1329 attr
->plt_offset
= create_plt_entry(s1
, got_offset
, attr
);
1331 /* create a symbol 'sym@plt' for the PLT jump vector */
1333 if (len
> sizeof plt_name
- 5)
1334 len
= sizeof plt_name
- 5;
1335 memcpy(plt_name
, name
, len
);
1336 strcpy(plt_name
+ len
, "@plt");
1337 attr
->plt_sym
= put_elf_sym(s1
->symtab
, attr
->plt_offset
, 0,
1338 ELFW(ST_INFO
)(STB_GLOBAL
, STT_FUNC
), 0, s1
->plt
->sh_num
, plt_name
);
1340 attr
->got_offset
= got_offset
;
1346 /* build GOT and PLT entries */
1347 /* Two passes because R_JMP_SLOT should become first. Some targets
1348 (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1349 ST_FUNC
void build_got_entries(TCCState
*s1
, int got_sym
)
1354 int i
, type
, gotplt_entry
, reloc_type
, sym_index
;
1355 struct sym_attr
*attr
;
1358 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1359 s
= s1
->sections
[i
];
1360 if (s
->sh_type
!= SHT_RELX
)
1362 /* no need to handle got relocations */
1363 if (s
->link
!= symtab_section
)
1365 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1366 type
= ELFW(R_TYPE
)(rel
->r_info
);
1367 gotplt_entry
= gotplt_entry_type(type
);
1368 if (gotplt_entry
== -1) {
1369 tcc_error_noabort ("Unknown relocation type for got: %d", type
);
1372 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1373 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1375 if (gotplt_entry
== NO_GOTPLT_ENTRY
) {
1379 /* Automatically create PLT/GOT [entry] if it is an undefined
1380 reference (resolved at runtime), or the symbol is absolute,
1381 probably created by tcc_add_symbol, and thus on 64-bit
1382 targets might be too far from application code. */
1383 if (gotplt_entry
== AUTO_GOTPLT_ENTRY
) {
1384 if (sym
->st_shndx
== SHN_UNDEF
) {
1387 if (!PCRELATIVE_DLLPLT
1388 && (s1
->output_type
& TCC_OUTPUT_DYN
))
1390 /* Relocations for UNDEF symbols would normally need
1391 to be transferred into the executable or shared object.
1392 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1393 But TCC doesn't do that (at least for exes), so we
1394 need to resolve all such relocs locally. And that
1395 means PLT slots for functions in DLLs and COPY relocs for
1396 data symbols. COPY relocs were generated in
1397 bind_exe_dynsyms (and the symbol adjusted to be defined),
1398 and for functions we were generated a dynamic symbol
1399 of function type. */
1401 /* dynsym isn't set for -run :-/ */
1402 dynindex
= get_sym_attr(s1
, sym_index
, 0)->dyn_index
;
1403 esym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ dynindex
;
1405 && (ELFW(ST_TYPE
)(esym
->st_info
) == STT_FUNC
1406 || (ELFW(ST_TYPE
)(esym
->st_info
) == STT_NOTYPE
1407 && ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
)))
1410 } else if (sym
->st_shndx
== SHN_ABS
) {
1411 if (sym
->st_value
== 0) /* from tcc_add_btstub() */
1413 #ifndef TCC_TARGET_ARM
1417 /* from tcc_add_symbol(): on 64 bit platforms these
1418 need to go through .got */
1423 #ifdef TCC_TARGET_X86_64
1424 if ((type
== R_X86_64_PLT32
|| type
== R_X86_64_PC32
) &&
1425 sym
->st_shndx
!= SHN_UNDEF
&&
1426 (ELFW(ST_VISIBILITY
)(sym
->st_other
) != STV_DEFAULT
||
1427 ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
||
1428 s1
->output_type
& TCC_OUTPUT_EXE
)) {
1431 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PC32
);
1435 reloc_type
= code_reloc(type
);
1436 if (reloc_type
== -1) {
1437 tcc_error_noabort ("Unknown relocation type: %d", type
);
1441 if (reloc_type
!= 0) {
1445 reloc_type
= R_JMP_SLOT
;
1449 reloc_type
= R_GLOB_DAT
;
1453 got_sym
= build_got(s1
);
1455 if (gotplt_entry
== BUILD_GOT_ONLY
)
1458 attr
= put_got_entry(s1
, reloc_type
, sym_index
);
1460 if (reloc_type
== R_JMP_SLOT
)
1461 rel
->r_info
= ELFW(R_INFO
)(attr
->plt_sym
, type
);
1466 /* .rel.plt refers to .got actually */
1467 if (s1
->plt
&& s1
->plt
->reloc
)
1468 s1
->plt
->reloc
->sh_info
= s1
->got
->sh_num
;
1469 if (got_sym
) /* set size */
1470 ((ElfW(Sym
)*)symtab_section
->data
)[got_sym
].st_size
= s1
->got
->data_offset
;
1472 #endif /* def NEED_BUILD_GOT */
1474 ST_FUNC
int set_global_sym(TCCState
*s1
, const char *name
, Section
*sec
, addr_t offs
)
1476 int shn
= sec
? sec
->sh_num
: offs
|| !name
? SHN_ABS
: SHN_UNDEF
;
1477 if (sec
&& offs
== -1)
1478 offs
= sec
->data_offset
;
1479 return set_elf_sym(symtab_section
, offs
, 0,
1480 ELFW(ST_INFO
)(name
? STB_GLOBAL
: STB_LOCAL
, STT_NOTYPE
), 0, shn
, name
);
1483 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1488 s
= have_section(s1
, section_name
);
1489 if (!s
|| !(s
->sh_flags
& SHF_ALLOC
)) {
1493 end_offset
= s
->data_offset
;
1495 snprintf(buf
, sizeof(buf
), "__%s_start", section_name
+ 1);
1496 set_global_sym(s1
, buf
, s
, 0);
1497 snprintf(buf
, sizeof(buf
), "__%s_end", section_name
+ 1);
1498 set_global_sym(s1
, buf
, s
, end_offset
);
1501 ST_FUNC
void add_array (TCCState
*s1
, const char *sec
, int c
)
1504 s
= find_section(s1
, sec
);
1505 s
->sh_flags
= shf_RELRO
;
1506 s
->sh_type
= sec
[1] == 'i' ? SHT_INIT_ARRAY
: SHT_FINI_ARRAY
;
1507 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1508 section_ptr_add(s
, PTR_SIZE
);
1511 #ifdef CONFIG_TCC_BCHECK
1512 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
1514 if (0 == s1
->do_bounds_check
)
1516 section_ptr_add(bounds_section
, sizeof(addr_t
));
1520 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1521 a dynamic symbol to allow so's to have one each with a different value. */
1522 static void set_local_sym(TCCState
*s1
, const char *name
, Section
*s
, int offset
)
1524 int c
= find_elf_sym(s1
->symtab
, name
);
1526 ElfW(Sym
) *esym
= (ElfW(Sym
)*)s1
->symtab
->data
+ c
;
1527 esym
->st_info
= ELFW(ST_INFO
)(STB_LOCAL
, STT_NOTYPE
);
1528 esym
->st_value
= offset
;
1529 esym
->st_shndx
= s
->sh_num
;
1533 /* avoid generating debug/test_coverage code for stub functions */
1534 static void tcc_compile_string_no_debug(TCCState
*s
, const char *str
)
1536 int save_do_debug
= s
->do_debug
;
1537 int save_test_coverage
= s
->test_coverage
;
1540 s
->test_coverage
= 0;
1541 tcc_compile_string(s
, str
);
1542 s
->do_debug
= save_do_debug
;
1543 s
->test_coverage
= save_test_coverage
;
1546 #ifdef CONFIG_TCC_BACKTRACE
1547 static void put_ptr(TCCState
*s1
, Section
*s
, int offs
)
1550 c
= set_global_sym(s1
, NULL
, s
, offs
);
1552 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1553 section_ptr_add(s
, PTR_SIZE
);
1556 ST_FUNC
void tcc_add_btstub(TCCState
*s1
)
1561 const char *__rt_info
= &"___rt_info"[!s1
->leading_underscore
];
1564 /* Align to PTR_SIZE */
1565 section_ptr_add(s
, -s
->data_offset
& (PTR_SIZE
- 1));
1567 /* create a struct rt_context (see tccrun.c) */
1569 put_ptr(s1
, dwarf_line_section
, 0);
1570 put_ptr(s1
, dwarf_line_section
, -1);
1572 put_ptr(s1
, dwarf_line_str_section
, 0);
1574 put_ptr(s1
, dwarf_str_section
, 0);
1578 put_ptr(s1
, stab_section
, 0);
1579 put_ptr(s1
, stab_section
, -1);
1580 put_ptr(s1
, stab_section
->link
, 0);
1583 /* skip esym_start/esym_end/elf_str (not loaded) */
1584 section_ptr_add(s
, 3 * PTR_SIZE
);
1586 if (s1
->output_type
== TCC_OUTPUT_MEMORY
&& 0 == s1
->dwarf
) {
1587 put_ptr(s1
, text_section
, 0);
1589 /* prog_base : local nameless symbol with offset 0 at SHN_ABS */
1590 put_ptr(s1
, NULL
, 0);
1591 #if defined TCC_TARGET_MACHO
1592 /* adjust for __PAGEZERO */
1593 if (s1
->dwarf
== 0 && s1
->output_type
== TCC_OUTPUT_EXE
)
1594 write64le(data_section
->data
+ data_section
->data_offset
- PTR_SIZE
,
1599 #ifdef CONFIG_TCC_BCHECK
1600 if (s1
->do_bounds_check
) {
1601 put_ptr(s1
, bounds_section
, 0);
1605 section_ptr_add(s
, n
);
1606 p
= section_ptr_add(s
, 2 * sizeof (int));
1607 p
[0] = s1
->rt_num_callers
;
1609 // if (s->data_offset - o != 10*PTR_SIZE + 2*sizeof (int)) exit(99);
1611 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
1612 set_global_sym(s1
, __rt_info
, s
, o
);
1618 "extern void __bt_init(),__bt_exit(),__bt_init_dll();"
1619 "static void *__rt_info[];"
1620 "__attribute__((constructor)) static void __bt_init_rt(){");
1621 #ifdef TCC_TARGET_PE
1622 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1623 #ifdef CONFIG_TCC_BCHECK
1624 cstr_printf(&cstr
, "__bt_init_dll(%d);", s1
->do_bounds_check
);
1626 cstr_printf(&cstr
, "__bt_init_dll(0);");
1629 cstr_printf(&cstr
, "__bt_init(__rt_info,%d);}",
1630 s1
->output_type
!= TCC_OUTPUT_DLL
);
1631 /* In case dlcose is called by application */
1633 "__attribute__((destructor)) static void __bt_exit_rt(){"
1634 "__bt_exit(__rt_info);}");
1635 tcc_compile_string_no_debug(s1
, cstr
.data
);
1637 set_local_sym(s1
, __rt_info
, s
, o
);
1639 #endif /* def CONFIG_TCC_BACKTRACE */
1641 static void tcc_tcov_add_file(TCCState
*s1
, const char *filename
)
1647 if (tcov_section
== NULL
)
1649 section_ptr_add(tcov_section
, 1);
1650 write32le (tcov_section
->data
, tcov_section
->data_offset
);
1653 if (filename
[0] == '/')
1654 cstr_printf (&cstr
, "%s.tcov", filename
);
1656 getcwd (wd
, sizeof(wd
));
1657 cstr_printf (&cstr
, "%s/%s.tcov", wd
, filename
);
1659 ptr
= section_ptr_add(tcov_section
, cstr
.size
+ 1);
1660 strcpy((char *)ptr
, cstr
.data
);
1661 unlink((char *)ptr
);
1663 normalize_slashes((char *)ptr
);
1669 "extern char *__tcov_data[];"
1670 "extern void __store_test_coverage ();"
1671 "__attribute__((destructor)) static void __tcov_exit() {"
1672 "__store_test_coverage(__tcov_data);"
1674 tcc_compile_string_no_debug(s1
, cstr
.data
);
1676 set_local_sym(s1
, &"___tcov_data"[!s1
->leading_underscore
], tcov_section
, 0);
1679 #if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO
1680 /* add libc crt1/crti objects */
1681 ST_FUNC
void tccelf_add_crtbegin(TCCState
*s1
)
1683 #if TARGETOS_OpenBSD
1684 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1685 tcc_add_crt(s1
, "crt0.o");
1686 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1687 tcc_add_crt(s1
, "crtbeginS.o");
1689 tcc_add_crt(s1
, "crtbegin.o");
1690 #elif TARGETOS_FreeBSD || TARGETOS_NetBSD
1691 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1692 #if TARGETOS_FreeBSD
1693 tcc_add_crt(s1
, "crt1.o");
1695 tcc_add_crt(s1
, "crt0.o");
1697 tcc_add_crt(s1
, "crti.o");
1698 if (s1
->static_link
)
1699 tcc_add_crt(s1
, "crtbeginT.o");
1700 else if (s1
->output_type
== TCC_OUTPUT_DLL
)
1701 tcc_add_crt(s1
, "crtbeginS.o");
1703 tcc_add_crt(s1
, "crtbegin.o");
1704 #elif TARGETOS_ANDROID
1705 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1706 tcc_add_crt(s1
, "crtbegin_so.o");
1708 tcc_add_crt(s1
, "crtbegin_dynamic.o");
1710 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1711 tcc_add_crt(s1
, "crt1.o");
1712 tcc_add_crt(s1
, "crti.o");
1716 ST_FUNC
void tccelf_add_crtend(TCCState
*s1
)
1718 #if TARGETOS_OpenBSD
1719 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1720 tcc_add_crt(s1
, "crtendS.o");
1722 tcc_add_crt(s1
, "crtend.o");
1723 #elif TARGETOS_FreeBSD || TARGETOS_NetBSD
1724 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1725 tcc_add_crt(s1
, "crtendS.o");
1727 tcc_add_crt(s1
, "crtend.o");
1728 tcc_add_crt(s1
, "crtn.o");
1729 #elif TARGETOS_ANDROID
1730 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1731 tcc_add_crt(s1
, "crtend_so.o");
1733 tcc_add_crt(s1
, "crtend_android.o");
1735 tcc_add_crt(s1
, "crtn.o");
1738 #endif /* !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO */
1740 #ifndef TCC_TARGET_PE
1741 /* add tcc runtime libraries */
1742 ST_FUNC
void tcc_add_runtime(TCCState
*s1
)
1746 #ifdef CONFIG_TCC_BCHECK
1749 tcc_add_pragma_libs(s1
);
1752 if (!s1
->nostdlib
) {
1753 int lpthread
= s1
->option_pthread
;
1755 #ifdef CONFIG_TCC_BCHECK
1756 if (s1
->do_bounds_check
&& s1
->output_type
!= TCC_OUTPUT_DLL
) {
1757 tcc_add_support(s1
, "bcheck.o");
1758 # if !(TARGETOS_OpenBSD || TARGETOS_NetBSD)
1759 tcc_add_library_err(s1
, "dl");
1764 #ifdef CONFIG_TCC_BACKTRACE
1765 if (s1
->do_backtrace
) {
1766 if (s1
->output_type
& TCC_OUTPUT_EXE
)
1767 tcc_add_support(s1
, "bt-exe.o");
1768 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1769 tcc_add_support(s1
, "bt-log.o");
1775 tcc_add_library_err(s1
, "pthread");
1776 tcc_add_library_err(s1
, "c");
1778 if (!s1
->static_link
) {
1779 if (TCC_LIBGCC
[0] == '/')
1780 tcc_add_file(s1
, TCC_LIBGCC
);
1782 tcc_add_dll(s1
, TCC_LIBGCC
, AFF_PRINT_ERROR
);
1785 #if defined TCC_TARGET_ARM && TARGETOS_FreeBSD
1786 tcc_add_library_err(s1
, "gcc_s"); // unwind code
1789 tcc_add_support(s1
, TCC_LIBTCC1
);
1790 #ifndef TCC_TARGET_MACHO
1791 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1792 tccelf_add_crtend(s1
);
1796 #endif /* ndef TCC_TARGET_PE */
1798 /* add various standard linker symbols (must be done after the
1799 sections are filled (for example after allocating common
1801 static void tcc_add_linker_symbols(TCCState
*s1
)
1807 set_global_sym(s1
, "_etext", text_section
, -1);
1808 set_global_sym(s1
, "_edata", data_section
, -1);
1809 set_global_sym(s1
, "_end", bss_section
, -1);
1810 #if TARGETOS_OpenBSD
1811 set_global_sym(s1
, "__executable_start", NULL
, ELF_START_ADDR
);
1813 #ifdef TCC_TARGET_RISCV64
1814 /* XXX should be .sdata+0x800, not .data+0x800 */
1815 set_global_sym(s1
, "__global_pointer$", data_section
, 0x800);
1817 /* horrible new standard ldscript defines */
1818 add_init_array_defines(s1
, ".preinit_array");
1819 add_init_array_defines(s1
, ".init_array");
1820 add_init_array_defines(s1
, ".fini_array");
1821 /* add start and stop symbols for sections whose name can be
1823 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1824 s
= s1
->sections
[i
];
1825 if ((s
->sh_flags
& SHF_ALLOC
)
1826 && (s
->sh_type
== SHT_PROGBITS
1827 || s
->sh_type
== SHT_STRTAB
)) {
1829 /* check if section name can be expressed in C */
1835 if (!isid(c
) && !isnum(c
))
1839 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1840 set_global_sym(s1
, buf
, s
, 0);
1841 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1842 set_global_sym(s1
, buf
, s
, -1);
1848 ST_FUNC
void resolve_common_syms(TCCState
*s1
)
1852 /* Allocate common symbols in BSS. */
1853 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1854 if (sym
->st_shndx
== SHN_COMMON
) {
1855 /* symbol alignment is in st_value for SHN_COMMONs */
1856 sym
->st_value
= section_add(bss_section
, sym
->st_size
,
1858 sym
->st_shndx
= bss_section
->sh_num
;
1862 /* Now assign linker provided symbols their value. */
1863 tcc_add_linker_symbols(s1
);
1866 #ifndef ELF_OBJ_ONLY
1867 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1869 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1870 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1871 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1872 unsigned offset
= attr
->got_offset
;
1876 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1878 write64le(s1
->got
->data
+ offset
, sym
->st_value
);
1880 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1884 /* Perform relocation to GOT or PLT entries */
1885 ST_FUNC
void fill_got(TCCState
*s1
)
1891 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1892 s
= s1
->sections
[i
];
1893 if (s
->sh_type
!= SHT_RELX
)
1895 /* no need to handle got relocations */
1896 if (s
->link
!= symtab_section
)
1898 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1899 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1900 case R_X86_64_GOT32
:
1901 case R_X86_64_GOTPCREL
:
1902 case R_X86_64_GOTPCRELX
:
1903 case R_X86_64_REX_GOTPCRELX
:
1904 case R_X86_64_PLT32
:
1905 fill_got_entry(s1
, rel
);
1912 /* See put_got_entry for a description. This is the second stage
1913 where GOT references to local defined symbols are rewritten. */
1914 static void fill_local_got_entries(TCCState
*s1
)
1917 if (!s1
->got
->reloc
)
1919 for_each_elem(s1
->got
->reloc
, 0, rel
, ElfW_Rel
) {
1920 if (ELFW(R_TYPE
)(rel
->r_info
) == R_RELATIVE
) {
1921 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1922 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1923 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1924 unsigned offset
= attr
->got_offset
;
1925 if (offset
!= rel
->r_offset
- s1
->got
->sh_addr
)
1926 tcc_error_noabort("fill_local_got_entries: huh?");
1927 rel
->r_info
= ELFW(R_INFO
)(0, R_RELATIVE
);
1928 #if SHT_RELX == SHT_RELA
1929 rel
->r_addend
= sym
->st_value
;
1931 /* All our REL architectures also happen to be 32bit LE. */
1932 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1938 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1939 in shared libraries */
1940 static void bind_exe_dynsyms(TCCState
*s1
, int is_PIE
)
1943 int sym_index
, index
;
1944 ElfW(Sym
) *sym
, *esym
;
1947 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1948 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1949 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1950 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1951 if (sym
->st_shndx
== SHN_UNDEF
) {
1952 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1953 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1957 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1958 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1959 if ((type
== STT_FUNC
) || (type
== STT_GNU_IFUNC
)) {
1960 /* Indirect functions shall have STT_FUNC type in executable
1961 * dynsym section. Indeed, a dlsym call following a lazy
1962 * resolution would pick the symbol value from the
1963 * executable dynsym entry which would contain the address
1964 * of the function wanted by the caller of dlsym instead of
1965 * the address of the function that would return that
1968 = put_elf_sym(s1
->dynsym
, 0, esym
->st_size
,
1969 ELFW(ST_INFO
)(STB_GLOBAL
,STT_FUNC
), 0, 0,
1971 int index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1972 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1973 } else if (type
== STT_OBJECT
) {
1974 unsigned long offset
;
1976 offset
= bss_section
->data_offset
;
1977 /* XXX: which alignment ? */
1978 offset
= (offset
+ 16 - 1) & -16;
1979 set_elf_sym (s1
->symtab
, offset
, esym
->st_size
,
1980 esym
->st_info
, 0, bss_section
->sh_num
, name
);
1981 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1982 esym
->st_info
, 0, bss_section
->sh_num
,
1985 /* Ensure R_COPY works for weak symbol aliases */
1986 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1987 for_each_elem(s1
->dynsymtab_section
, 1, dynsym
, ElfW(Sym
)) {
1988 if ((dynsym
->st_value
== esym
->st_value
)
1989 && (ELFW(ST_BIND
)(dynsym
->st_info
) == STB_GLOBAL
)) {
1990 char *dynname
= (char *) s1
->dynsymtab_section
->link
->data
1992 put_elf_sym(s1
->dynsym
, offset
, dynsym
->st_size
,
1994 bss_section
->sh_num
, dynname
);
2000 put_elf_reloc(s1
->dynsym
, bss_section
,
2001 offset
, R_COPY
, index
);
2002 offset
+= esym
->st_size
;
2003 bss_section
->data_offset
= offset
;
2006 /* STB_WEAK undefined symbols are accepted */
2007 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
2008 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
2009 !strcmp(name
, "_fp_hw")) {
2011 tcc_error_noabort("undefined symbol '%s'", name
);
2018 /* Bind symbols of libraries: export all non local symbols of executable that
2019 are referenced by shared libraries. The reason is that the dynamic loader
2020 search symbol first in executable and then in libraries. Therefore a
2021 reference to a symbol already defined by a library can still be resolved by
2022 a symbol in the executable. With -rdynamic, export all defined symbols */
2023 static void bind_libs_dynsyms(TCCState
*s1
)
2027 ElfW(Sym
) *sym
, *esym
;
2029 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
2030 name
= (char *)symtab_section
->link
->data
+ sym
->st_name
;
2031 dynsym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
2032 if (sym
->st_shndx
!= SHN_UNDEF
) {
2033 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
2034 && (dynsym_index
|| s1
->rdynamic
))
2035 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
2036 sym
->st_info
, 0, sym
->st_shndx
, name
);
2037 } else if (dynsym_index
) {
2038 esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ dynsym_index
;
2039 if (esym
->st_shndx
== SHN_UNDEF
) {
2040 /* weak symbols can stay undefined */
2041 if (ELFW(ST_BIND
)(esym
->st_info
) != STB_WEAK
)
2042 tcc_warning("undefined dynamic symbol '%s'", name
);
2048 /* Export all non local symbols. This is used by shared libraries so that the
2049 non local symbols they define can resolve a reference in another shared
2050 library or in the executable. Correspondingly, it allows undefined local
2051 symbols to be resolved by other shared libraries or by the executable. */
2052 static void export_global_syms(TCCState
*s1
)
2054 int dynindex
, index
;
2057 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
2058 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2059 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
2060 dynindex
= set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
2061 sym
->st_info
, 0, sym
->st_shndx
, name
);
2062 index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
2063 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
2068 /* decide if an unallocated section should be output. */
2069 static int set_sec_sizes(TCCState
*s1
)
2074 int file_type
= s1
->output_type
;
2076 /* Allocate strings for section names */
2077 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2078 s
= s1
->sections
[i
];
2079 if (s
->sh_type
== SHT_RELX
&& !(s
->sh_flags
& SHF_ALLOC
)) {
2080 /* when generating a DLL, we include relocations but
2081 we may patch them */
2082 if ((file_type
& TCC_OUTPUT_DYN
)
2083 && (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)) {
2084 int count
= prepare_dynamic_rel(s1
, s
);
2086 /* allocate the section */
2087 s
->sh_flags
|= SHF_ALLOC
;
2088 s
->sh_size
= count
* sizeof(ElfW_Rel
);
2089 if (!(s1
->sections
[s
->sh_info
]->sh_flags
& SHF_WRITE
))
2093 } else if ((s
->sh_flags
& SHF_ALLOC
)
2094 #ifdef TCC_TARGET_ARM
2095 || s
->sh_type
== SHT_ARM_ATTRIBUTES
2098 s
->sh_size
= s
->data_offset
;
2101 #ifdef TCC_TARGET_ARM
2102 /* XXX: Suppress stack unwinding section. */
2103 if (s
->sh_type
== SHT_ARM_EXIDX
) {
2113 /* various data used under elf_output_file() */
2118 /* Info to be copied in dynamic section */
2119 unsigned long data_offset
;
2130 /* read only segment mapping for GNU_RELRO */
2131 Section _roinf
, *roinf
;
2134 /* Decide the layout of sections loaded in memory. This must be done before
2135 program headers are filled since they contain info about the layout.
2136 We do the following ordering: interp, symbol tables, relocations, progbits,
2138 static int sort_sections(TCCState
*s1
, int *sec_order
, Section
*interp
)
2141 int i
, j
, k
, f
, f0
, n
;
2142 int nb_sections
= s1
->nb_sections
;
2143 int *sec_cls
= sec_order
+ nb_sections
;
2145 for (i
= 1; i
< nb_sections
; i
++) {
2146 s
= s1
->sections
[i
];
2147 if (s
->sh_flags
& SHF_ALLOC
) {
2149 if (s
->sh_flags
& SHF_WRITE
)
2151 if (s
->sh_flags
& SHF_TLS
)
2153 } else if (s
->sh_name
) {
2156 j
= 0x900; /* no sh_name: won't go to file */
2158 if (s
->sh_type
== SHT_SYMTAB
|| s
->sh_type
== SHT_DYNSYM
) {
2160 } else if (s
->sh_type
== SHT_STRTAB
&& strcmp(s
->name
, ".stabstr")) {
2162 if (i
== nb_sections
- 1) /* ".shstrtab" assumed to remain last */
2164 } else if (s
->sh_type
== SHT_HASH
|| s
->sh_type
== SHT_GNU_HASH
) {
2166 } else if (s
->sh_type
== SHT_RELX
) {
2168 if (s1
->plt
&& s
== s1
->plt
->reloc
)
2170 } else if (s
->sh_type
== SHT_PREINIT_ARRAY
) {
2172 } else if (s
->sh_type
== SHT_INIT_ARRAY
) {
2174 } else if (s
->sh_type
== SHT_FINI_ARRAY
) {
2176 #ifdef CONFIG_TCC_BCHECK
2177 } else if (s
== bounds_section
|| s
== lbounds_section
) {
2180 } else if (s
== rodata_section
|| 0 == strcmp(s
->name
, ".data.rel.ro")) {
2182 } else if (s
->sh_type
== SHT_DYNAMIC
) {
2184 } else if (s
== s1
->got
) {
2185 k
= 0x47; /* .got as RELRO needs BIND_NOW in DT_FLAGS */
2188 if (s
->sh_type
== SHT_NOTE
)
2190 if (s
->sh_flags
& SHF_EXECINSTR
)
2192 if (s
->sh_type
== SHT_NOBITS
)
2199 for (n
= i
; n
> 1 && k
< (f
= sec_cls
[n
- 1]); --n
)
2200 sec_cls
[n
] = f
, sec_order
[n
] = sec_order
[n
- 1];
2201 sec_cls
[n
] = k
, sec_order
[n
] = i
;
2205 /* count PT_LOAD headers needed */
2207 for (i
= 1; i
< nb_sections
; i
++) {
2208 s
= s1
->sections
[sec_order
[i
]];
2212 f
= s
->sh_flags
& (SHF_ALLOC
|SHF_WRITE
|SHF_EXECINSTR
|SHF_TLS
);
2214 /* NetBSD only supports 2 PT_LOAD sections.
2215 See: https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */
2216 if ((f
& SHF_WRITE
) == 0) f
|= SHF_EXECINSTR
;
2218 if ((k
& 0xfff0) == 0x240) /* RELRO sections */
2221 if (f
!= f0
) /* start new header when flags changed or relro */
2222 f0
= f
, ++n
, f
|= 1<<8;
2225 //printf("ph %d sec %02d : %3X %3X %8.2X %04X %s\n", !!f * n, i, f, k, s->sh_type, s->sh_size, s->name);
2230 static ElfW(Phdr
) *fill_phdr(ElfW(Phdr
) *ph
, int type
, Section
*s
)
2233 ph
->p_offset
= s
->sh_offset
;
2234 ph
->p_vaddr
= s
->sh_addr
;
2235 ph
->p_filesz
= s
->sh_size
;
2236 ph
->p_align
= s
->sh_addralign
;
2240 ph
->p_paddr
= ph
->p_vaddr
;
2241 ph
->p_memsz
= ph
->p_filesz
;
2245 /* Assign sections to segments and decide how are sections laid out when loaded
2246 in memory. This function also fills corresponding program headers. */
2247 static int layout_sections(TCCState
*s1
, int *sec_order
, struct dyn_inf
*d
)
2250 addr_t addr
, tmp
, align
, s_align
, base
;
2251 ElfW(Phdr
) *ph
= NULL
;
2252 int i
, f
, n
, phnum
, phfill
;
2255 /* compute number of program headers */
2256 phnum
= sort_sections(s1
, sec_order
, d
->interp
);
2257 phfill
= 0; /* set to 1 to have dll's with a PT_PHDR */
2268 d
->phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
2271 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2272 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2274 s_align
= ELF_PAGE_SIZE
;
2275 if (s1
->section_align
)
2276 s_align
= s1
->section_align
;
2278 addr
= ELF_START_ADDR
;
2279 if (s1
->output_type
& TCC_OUTPUT_DYN
)
2282 if (s1
->has_text_addr
) {
2283 addr
= s1
->text_addr
;
2285 int a_offset
, p_offset
;
2286 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
2288 a_offset
= (int) (addr
& (s_align
- 1));
2289 p_offset
= file_offset
& (s_align
- 1);
2290 if (a_offset
< p_offset
)
2291 a_offset
+= s_align
;
2292 file_offset
+= (a_offset
- p_offset
);
2296 /* compute address after headers */
2297 addr
= addr
+ (file_offset
& (s_align
- 1));
2300 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2301 s
= s1
->sections
[sec_order
[i
]];
2302 f
= sec_order
[i
+ s1
->nb_sections
];
2303 align
= s
->sh_addralign
- 1;
2305 if (f
== 0) { /* no alloc */
2306 file_offset
= (file_offset
+ align
) & ~align
;
2307 s
->sh_offset
= file_offset
;
2308 if (s
->sh_type
!= SHT_NOBITS
)
2309 file_offset
+= s
->sh_size
;
2313 if ((f
& 1<<8) && n
) {
2314 /* different rwx section flags */
2315 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
2316 /* if in the middle of a page, w e duplicate the page in
2317 memory so that one copy is RX and the other is RW */
2318 if ((addr
& (s_align
- 1)) != 0)
2321 align
= s_align
- 1;
2326 addr
= (addr
+ align
) & ~align
;
2327 file_offset
+= (int)(addr
- tmp
);
2328 s
->sh_offset
= file_offset
;
2332 /* set new program header */
2333 ph
= &d
->phdr
[phfill
+ n
];
2334 ph
->p_type
= PT_LOAD
;
2335 ph
->p_align
= s_align
;
2338 ph
->p_flags
|= PF_W
;
2339 if (f
& SHF_EXECINSTR
)
2340 ph
->p_flags
|= PF_X
;
2342 ph
->p_type
= PT_TLS
;
2343 ph
->p_align
= align
+ 1;
2346 ph
->p_offset
= file_offset
;
2349 /* Make the first PT_LOAD segment include the program
2350 headers itself (and the ELF header as well), it'll
2351 come out with same memory use but will make various
2352 tools like binutils strip work better. */
2356 ph
->p_paddr
= ph
->p_vaddr
;
2361 Section
*roinf
= &d
->_roinf
;
2362 if (roinf
->sh_size
== 0) {
2363 roinf
->sh_offset
= s
->sh_offset
;
2364 roinf
->sh_addr
= s
->sh_addr
;
2365 roinf
->sh_addralign
= 1;
2367 roinf
->sh_size
= (addr
- roinf
->sh_addr
) + s
->sh_size
;
2371 if (s
->sh_type
!= SHT_NOBITS
)
2372 file_offset
+= s
->sh_size
;
2374 ph
->p_filesz
= file_offset
- ph
->p_offset
;
2375 ph
->p_memsz
= addr
- ph
->p_vaddr
;
2378 /* Fill other headers */
2380 fill_phdr(++ph
, PT_NOTE
, d
->note
);
2382 fill_phdr(++ph
, PT_DYNAMIC
, d
->dynamic
)->p_flags
|= PF_W
;
2384 fill_phdr(++ph
, PT_GNU_RELRO
, d
->roinf
)->p_flags
|= PF_W
;
2386 fill_phdr(&d
->phdr
[1], PT_INTERP
, d
->interp
);
2389 ph
->p_offset
= sizeof(ElfW(Ehdr
));
2390 ph
->p_vaddr
= base
+ ph
->p_offset
;
2391 ph
->p_filesz
= phnum
* sizeof(ElfW(Phdr
));
2393 fill_phdr(ph
, PT_PHDR
, NULL
);
2398 /* put dynamic tag */
2399 static void put_dt(Section
*dynamic
, int dt
, addr_t val
)
2402 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
2404 dyn
->d_un
.d_val
= val
;
2407 /* Fill the dynamic section with tags describing the address and size of
2409 static void fill_dynamic(TCCState
*s1
, struct dyn_inf
*dyninf
)
2411 Section
*dynamic
= dyninf
->dynamic
;
2414 /* put dynamic section entries */
2415 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
2416 put_dt(dynamic
, DT_GNU_HASH
, dyninf
->gnu_hash
->sh_addr
);
2417 put_dt(dynamic
, DT_STRTAB
, dyninf
->dynstr
->sh_addr
);
2418 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
2419 put_dt(dynamic
, DT_STRSZ
, dyninf
->dynstr
->data_offset
);
2420 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
2422 put_dt(dynamic
, DT_RELA
, dyninf
->rel_addr
);
2423 put_dt(dynamic
, DT_RELASZ
, dyninf
->rel_size
);
2424 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
2425 if (s1
->plt
&& s1
->plt
->reloc
) {
2426 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2427 put_dt(dynamic
, DT_PLTRELSZ
, s1
->plt
->reloc
->data_offset
);
2428 put_dt(dynamic
, DT_JMPREL
, s1
->plt
->reloc
->sh_addr
);
2429 put_dt(dynamic
, DT_PLTREL
, DT_RELA
);
2431 put_dt(dynamic
, DT_RELACOUNT
, 0);
2433 put_dt(dynamic
, DT_REL
, dyninf
->rel_addr
);
2434 put_dt(dynamic
, DT_RELSZ
, dyninf
->rel_size
);
2435 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
2436 if (s1
->plt
&& s1
->plt
->reloc
) {
2437 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2438 put_dt(dynamic
, DT_PLTRELSZ
, s1
->plt
->reloc
->data_offset
);
2439 put_dt(dynamic
, DT_JMPREL
, s1
->plt
->reloc
->sh_addr
);
2440 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
2442 put_dt(dynamic
, DT_RELCOUNT
, 0);
2444 if (versym_section
&& verneed_section
) {
2445 /* The dynamic linker can not handle VERSYM without VERNEED */
2446 put_dt(dynamic
, DT_VERSYM
, versym_section
->sh_addr
);
2447 put_dt(dynamic
, DT_VERNEED
, verneed_section
->sh_addr
);
2448 put_dt(dynamic
, DT_VERNEEDNUM
, dt_verneednum
);
2450 s
= have_section(s1
, ".preinit_array");
2451 if (s
&& s
->data_offset
) {
2452 put_dt(dynamic
, DT_PREINIT_ARRAY
, s
->sh_addr
);
2453 put_dt(dynamic
, DT_PREINIT_ARRAYSZ
, s
->data_offset
);
2455 s
= have_section(s1
, ".init_array");
2456 if (s
&& s
->data_offset
) {
2457 put_dt(dynamic
, DT_INIT_ARRAY
, s
->sh_addr
);
2458 put_dt(dynamic
, DT_INIT_ARRAYSZ
, s
->data_offset
);
2460 s
= have_section(s1
, ".fini_array");
2461 if (s
&& s
->data_offset
) {
2462 put_dt(dynamic
, DT_FINI_ARRAY
, s
->sh_addr
);
2463 put_dt(dynamic
, DT_FINI_ARRAYSZ
, s
->data_offset
);
2465 s
= have_section(s1
, ".init");
2466 if (s
&& s
->data_offset
) {
2467 put_dt(dynamic
, DT_INIT
, s
->sh_addr
);
2469 s
= have_section(s1
, ".fini");
2470 if (s
&& s
->data_offset
) {
2471 put_dt(dynamic
, DT_FINI
, s
->sh_addr
);
2474 put_dt(dynamic
, DT_DEBUG
, 0);
2475 put_dt(dynamic
, DT_NULL
, 0);
2478 /* Remove gaps between RELX sections.
2479 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2480 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2481 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2482 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2483 static void update_reloc_sections(TCCState
*s1
, struct dyn_inf
*dyninf
)
2486 unsigned long file_offset
= 0;
2488 Section
*relocplt
= s1
->plt
? s1
->plt
->reloc
: NULL
;
2490 /* dynamic relocation table information, for .dynamic section */
2491 dyninf
->rel_addr
= dyninf
->rel_size
= 0;
2493 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2494 s
= s1
->sections
[i
];
2495 if (s
->sh_type
== SHT_RELX
&& s
!= relocplt
) {
2496 if (dyninf
->rel_size
== 0) {
2497 dyninf
->rel_addr
= s
->sh_addr
;
2498 file_offset
= s
->sh_offset
;
2501 s
->sh_addr
= dyninf
->rel_addr
+ dyninf
->rel_size
;
2502 s
->sh_offset
= file_offset
+ dyninf
->rel_size
;
2504 dyninf
->rel_size
+= s
->sh_size
;
2509 static int tidy_section_headers(TCCState
*s1
, int *sec_order
);
2510 #endif /* ndef ELF_OBJ_ONLY */
2512 /* Create an ELF file on disk.
2513 This function handle ELF specific layout requirements */
2514 static int tcc_output_elf(TCCState
*s1
, FILE *f
, int phnum
, ElfW(Phdr
) *phdr
,
2515 int file_offset
, int *sec_order
)
2517 int i
, shnum
, offset
, size
, file_type
;
2520 ElfW(Shdr
) shdr
, *sh
;
2522 file_type
= s1
->output_type
;
2523 shnum
= s1
->nb_sections
;
2525 memset(&ehdr
, 0, sizeof(ehdr
));
2528 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2529 ehdr
.e_phnum
= phnum
;
2530 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2531 #ifndef ELF_OBJ_ONLY
2532 shnum
= tidy_section_headers(s1
, sec_order
);
2537 file_offset
= (file_offset
+ 3) & -4;
2540 ehdr
.e_ident
[0] = ELFMAG0
;
2541 ehdr
.e_ident
[1] = ELFMAG1
;
2542 ehdr
.e_ident
[2] = ELFMAG2
;
2543 ehdr
.e_ident
[3] = ELFMAG3
;
2544 ehdr
.e_ident
[4] = ELFCLASSW
;
2545 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2546 ehdr
.e_ident
[6] = EV_CURRENT
;
2548 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2549 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2550 #elif defined TCC_TARGET_ARM && defined TCC_ARM_EABI
2551 ehdr
.e_flags
= EF_ARM_EABI_VER5
;
2552 ehdr
.e_flags
|= s1
->float_abi
== ARM_HARD_FLOAT
2553 ? EF_ARM_VFP_FLOAT
: EF_ARM_SOFT_FLOAT
;
2554 #elif defined TCC_TARGET_ARM
2555 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2556 #elif defined TCC_TARGET_RISCV64
2557 /* XXX should be configurable */
2558 ehdr
.e_flags
= EF_RISCV_FLOAT_ABI_DOUBLE
;
2561 if (file_type
== TCC_OUTPUT_OBJ
) {
2562 ehdr
.e_type
= ET_REL
;
2564 if (file_type
& TCC_OUTPUT_DYN
)
2565 ehdr
.e_type
= ET_DYN
;
2567 ehdr
.e_type
= ET_EXEC
;
2568 if (s1
->elf_entryname
)
2569 ehdr
.e_entry
= get_sym_addr(s1
, s1
->elf_entryname
, 1, 0);
2571 ehdr
.e_entry
= get_sym_addr(s1
, "_start", !!(file_type
& TCC_OUTPUT_EXE
), 0);
2572 if (ehdr
.e_entry
== (addr_t
)-1)
2573 ehdr
.e_entry
= text_section
->sh_addr
;
2578 ehdr
.e_machine
= EM_TCC_TARGET
;
2579 ehdr
.e_version
= EV_CURRENT
;
2580 ehdr
.e_shoff
= file_offset
;
2581 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2582 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2583 ehdr
.e_shnum
= shnum
;
2584 ehdr
.e_shstrndx
= shnum
- 1;
2586 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2588 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2589 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2591 sort_syms(s1
, symtab_section
);
2593 for(i
= 1; i
< shnum
; i
++) {
2594 s
= s1
->sections
[sec_order
? sec_order
[i
] : i
];
2595 if (s
->sh_type
!= SHT_NOBITS
) {
2596 while (offset
< s
->sh_offset
) {
2602 fwrite(s
->data
, 1, size
, f
);
2607 /* output section headers */
2608 while (offset
< ehdr
.e_shoff
) {
2613 for(i
= 0; i
< shnum
; i
++) {
2615 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2616 s
= s1
->sections
[i
];
2618 sh
->sh_name
= s
->sh_name
;
2619 sh
->sh_type
= s
->sh_type
;
2620 sh
->sh_flags
= s
->sh_flags
;
2621 sh
->sh_entsize
= s
->sh_entsize
;
2622 sh
->sh_info
= s
->sh_info
;
2624 sh
->sh_link
= s
->link
->sh_num
;
2625 sh
->sh_addralign
= s
->sh_addralign
;
2626 sh
->sh_addr
= s
->sh_addr
;
2627 sh
->sh_offset
= s
->sh_offset
;
2628 sh
->sh_size
= s
->sh_size
;
2630 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2635 static int tcc_output_binary(TCCState
*s1
, FILE *f
,
2636 const int *sec_order
)
2639 int i
, offset
, size
;
2642 for(i
=1;i
<s1
->nb_sections
;i
++) {
2643 s
= s1
->sections
[sec_order
[i
]];
2644 if (s
->sh_type
!= SHT_NOBITS
&&
2645 (s
->sh_flags
& SHF_ALLOC
)) {
2646 while (offset
< s
->sh_offset
) {
2651 fwrite(s
->data
, 1, size
, f
);
2658 /* Write an elf, coff or "binary" file */
2659 static int tcc_write_elf_file(TCCState
*s1
, const char *filename
, int phnum
,
2660 ElfW(Phdr
) *phdr
, int file_offset
, int *sec_order
)
2662 int fd
, mode
, file_type
, ret
;
2665 file_type
= s1
->output_type
;
2666 if (file_type
== TCC_OUTPUT_OBJ
)
2671 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2672 if (fd
< 0 || (f
= fdopen(fd
, "wb")) == NULL
)
2673 return tcc_error_noabort("could not write '%s: %s'", filename
, strerror(errno
));
2675 printf("<- %s\n", filename
);
2676 #ifdef TCC_TARGET_COFF
2677 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
)
2678 tcc_output_coff(s1
, f
);
2681 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2682 ret
= tcc_output_elf(s1
, f
, phnum
, phdr
, file_offset
, sec_order
);
2684 ret
= tcc_output_binary(s1
, f
, sec_order
);
2690 #ifndef ELF_OBJ_ONLY
2691 /* Sort section headers by assigned sh_addr, remove sections
2692 that we aren't going to output. */
2693 static int tidy_section_headers(TCCState
*s1
, int *sec_order
)
2695 int i
, nnew
, l
, *backmap
;
2699 snew
= tcc_malloc(s1
->nb_sections
* sizeof(snew
[0]));
2700 backmap
= tcc_malloc(s1
->nb_sections
* sizeof(backmap
[0]));
2701 for (i
= 0, nnew
= 0, l
= s1
->nb_sections
; i
< s1
->nb_sections
; i
++) {
2702 s
= s1
->sections
[sec_order
[i
]];
2703 if (!i
|| s
->sh_name
) {
2704 backmap
[sec_order
[i
]] = nnew
;
2708 backmap
[sec_order
[i
]] = 0;
2712 for (i
= 0; i
< nnew
; i
++) {
2716 if (s
->sh_type
== SHT_RELX
)
2717 s
->sh_info
= backmap
[s
->sh_info
];
2721 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
))
2722 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2723 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2724 if ( !s1
->static_link
) {
2725 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
))
2726 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2727 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2729 for (i
= 0; i
< s1
->nb_sections
; i
++)
2731 tcc_free(s1
->sections
);
2732 s1
->sections
= snew
;
2737 #ifdef TCC_TARGET_ARM
2738 static void create_arm_attribute_section(TCCState
*s1
)
2740 // Needed for DLL support.
2741 static const unsigned char arm_attr
[] = {
2743 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2744 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2745 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2746 0x05, 0x36, 0x00, // 'CPU_name', "6"
2747 0x06, 0x06, // 'CPU_arch', 'v6'
2748 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2749 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2750 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2751 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2752 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2753 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2754 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2755 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2756 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2757 0x1a, 0x02, // 'ABI_enum_size', 'int'
2758 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2759 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2761 Section
*attr
= new_section(s1
, ".ARM.attributes", SHT_ARM_ATTRIBUTES
, 0);
2762 unsigned char *ptr
= section_ptr_add(attr
, sizeof(arm_attr
));
2763 attr
->sh_addralign
= 1;
2764 memcpy(ptr
, arm_attr
, sizeof(arm_attr
));
2765 if (s1
->float_abi
!= ARM_HARD_FLOAT
) {
2766 ptr
[26] = 0x00; // 'FP_arch', 'No'
2767 ptr
[41] = 0x1e; // 'ABI_optimization_goals'
2768 ptr
[42] = 0x06; // 'Aggressive Debug'
2773 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2774 static Section
*create_bsd_note_section(TCCState
*s1
,
2778 Section
*s
= find_section (s1
, name
);
2780 if (s
->data_offset
== 0) {
2781 char *ptr
= section_ptr_add(s
, sizeof(ElfW(Nhdr
)) + 8 + 4);
2782 ElfW(Nhdr
) *note
= (ElfW(Nhdr
) *) ptr
;
2784 s
->sh_type
= SHT_NOTE
;
2787 note
->n_type
= ELF_NOTE_OS_GNU
;
2788 strcpy (ptr
+ sizeof(ElfW(Nhdr
)), value
);
2794 static void alloc_sec_names(TCCState
*s1
, int is_obj
);
2796 /* Output an elf, coff or binary file */
2797 /* XXX: suppress unneeded sections */
2798 static int elf_output_file(TCCState
*s1
, const char *filename
)
2800 int i
, ret
, file_type
, file_offset
, *sec_order
;
2801 struct dyn_inf dyninf
= {0};
2802 Section
*interp
, *dynstr
, *dynamic
;
2803 int textrel
, got_sym
, dt_flags_1
;
2805 file_type
= s1
->output_type
;
2808 interp
= dynstr
= dynamic
= NULL
;
2810 dyninf
.roinf
= &dyninf
._roinf
;
2812 #ifdef TCC_TARGET_ARM
2813 create_arm_attribute_section (s1
);
2816 #if TARGETOS_OpenBSD
2817 dyninf
.note
= create_bsd_note_section (s1
, ".note.openbsd.ident", "OpenBSD");
2821 dyninf
.note
= create_bsd_note_section (s1
, ".note.netbsd.ident", "NetBSD");
2824 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
2825 dyninf
.roinf
= NULL
;
2827 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2828 tcc_add_runtime(s1
);
2829 resolve_common_syms(s1
);
2831 if (!s1
->static_link
) {
2832 if (file_type
& TCC_OUTPUT_EXE
) {
2834 /* allow override the dynamic loader */
2835 const char *elfint
= getenv("LD_SO");
2837 elfint
= DEFAULT_ELFINTERP(s1
);
2838 /* add interpreter section only if executable */
2839 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
2840 interp
->sh_addralign
= 1;
2841 ptr
= section_ptr_add(interp
, 1 + strlen(elfint
));
2842 strcpy(ptr
, elfint
);
2843 dyninf
.interp
= interp
;
2846 /* add dynamic symbol table */
2847 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
2849 ".hash", SHF_ALLOC
);
2850 /* Number of local symbols (readelf complains if not set) */
2851 s1
->dynsym
->sh_info
= 1;
2852 dynstr
= s1
->dynsym
->link
;
2853 /* add dynamic section */
2854 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
2855 SHF_ALLOC
| SHF_WRITE
);
2856 dynamic
->link
= dynstr
;
2857 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
2859 got_sym
= build_got(s1
);
2860 if (file_type
& TCC_OUTPUT_EXE
) {
2861 bind_exe_dynsyms(s1
, file_type
& TCC_OUTPUT_DYN
);
2865 build_got_entries(s1
, got_sym
);
2866 if (file_type
& TCC_OUTPUT_EXE
) {
2867 bind_libs_dynsyms(s1
);
2869 /* shared library case: simply export all global symbols */
2870 export_global_syms(s1
);
2872 dyninf
.gnu_hash
= create_gnu_hash(s1
);
2874 build_got_entries(s1
, 0);
2878 textrel
= set_sec_sizes(s1
);
2879 alloc_sec_names(s1
, 0);
2881 if (!s1
->static_link
) {
2882 /* add a list of needed dlls */
2883 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2884 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
2885 if (dllref
->level
== 0)
2886 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
2890 put_dt(dynamic
, s1
->enable_new_dtags
? DT_RUNPATH
: DT_RPATH
,
2891 put_elf_str(dynstr
, s1
->rpath
));
2893 dt_flags_1
= DF_1_NOW
;
2894 if (file_type
& TCC_OUTPUT_DYN
) {
2896 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
2897 /* XXX: currently, since we do not handle PIC code, we
2898 must relocate the readonly segments */
2900 put_dt(dynamic
, DT_TEXTREL
, 0);
2901 if (file_type
& TCC_OUTPUT_EXE
)
2902 dt_flags_1
= DF_1_NOW
| DF_1_PIE
;
2904 put_dt(dynamic
, DT_FLAGS
, DF_BIND_NOW
);
2905 put_dt(dynamic
, DT_FLAGS_1
, dt_flags_1
);
2907 put_dt(dynamic
, DT_SYMBOLIC
, 0);
2909 dyninf
.dynamic
= dynamic
;
2910 dyninf
.dynstr
= dynstr
;
2911 /* remember offset and reserve space for 2nd call below */
2912 dyninf
.data_offset
= dynamic
->data_offset
;
2913 fill_dynamic(s1
, &dyninf
);
2914 dynamic
->sh_size
= dynamic
->data_offset
;
2915 dynstr
->sh_size
= dynstr
->data_offset
;
2918 /* this array is used to reorder sections in the output file */
2919 sec_order
= tcc_malloc(sizeof(int) * 2 * s1
->nb_sections
);
2920 /* compute section to program header mapping */
2921 file_offset
= layout_sections(s1
, sec_order
, &dyninf
);
2924 /* put in GOT the dynamic section address and relocate PLT */
2925 write32le(s1
->got
->data
, dynamic
->sh_addr
);
2926 if (file_type
== TCC_OUTPUT_EXE
2927 || (RELOCATE_DLLPLT
&& (file_type
& TCC_OUTPUT_DYN
)))
2929 /* relocate symbols in .dynsym now that final addresses are known */
2930 relocate_syms(s1
, s1
->dynsym
, 2);
2933 /* if building executable or DLL, then relocate each section
2934 except the GOT which is already relocated */
2935 relocate_syms(s1
, s1
->symtab
, 0);
2936 if (s1
->nb_errors
!= 0)
2938 relocate_sections(s1
);
2940 update_reloc_sections (s1
, &dyninf
);
2941 dynamic
->data_offset
= dyninf
.data_offset
;
2942 fill_dynamic(s1
, &dyninf
);
2944 /* Perform relocation to GOT or PLT entries */
2945 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2948 fill_local_got_entries(s1
);
2950 if (dyninf
.gnu_hash
)
2951 update_gnu_hash(s1
, dyninf
.gnu_hash
);
2953 /* Create the ELF file with name 'filename' */
2954 ret
= tcc_write_elf_file(s1
, filename
, dyninf
.phnum
, dyninf
.phdr
, file_offset
, sec_order
);
2956 tcc_free(sec_order
);
2957 tcc_free(dyninf
.phdr
);
2960 #endif /* ndef ELF_OBJ_ONLY */
2962 /* Allocate strings for section names */
2963 static void alloc_sec_names(TCCState
*s1
, int is_obj
)
2966 Section
*s
, *strsec
;
2968 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
2969 put_elf_str(strsec
, "");
2970 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2971 s
= s1
->sections
[i
];
2973 s
->sh_size
= s
->data_offset
;
2974 if (s
== strsec
|| s
->sh_size
|| (s
->sh_flags
& SHF_ALLOC
))
2975 s
->sh_name
= put_elf_str(strsec
, s
->name
);
2977 strsec
->sh_size
= strsec
->data_offset
;
2980 /* Output an elf .o file */
2981 static int elf_output_obj(TCCState
*s1
, const char *filename
)
2984 int i
, ret
, file_offset
;
2986 /* Allocate strings for section names */
2987 alloc_sec_names(s1
, 1);
2988 file_offset
= sizeof (ElfW(Ehdr
));
2989 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2990 s
= s1
->sections
[i
];
2991 file_offset
= (file_offset
+ 15) & -16;
2992 s
->sh_offset
= file_offset
;
2993 if (s
->sh_type
!= SHT_NOBITS
)
2994 file_offset
+= s
->sh_size
;
2996 /* Create the ELF file with name 'filename' */
2997 ret
= tcc_write_elf_file(s1
, filename
, 0, NULL
, file_offset
, NULL
);
3001 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
3003 if (s
->test_coverage
)
3004 tcc_tcov_add_file(s
, filename
);
3005 if (s
->output_type
== TCC_OUTPUT_OBJ
)
3006 return elf_output_obj(s
, filename
);
3007 #ifdef TCC_TARGET_PE
3008 return pe_output_file(s
, filename
);
3009 #elif TCC_TARGET_MACHO
3010 return macho_output_file(s
, filename
);
3012 return elf_output_file(s
, filename
);
3016 ST_FUNC ssize_t
full_read(int fd
, void *buf
, size_t count
) {
3020 ssize_t num
= read(fd
, cbuf
, count
-rnum
);
3021 if (num
< 0) return num
;
3022 if (num
== 0) return rnum
;
3028 ST_FUNC
void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
3032 data
= tcc_malloc(size
);
3033 lseek(fd
, file_offset
, SEEK_SET
);
3034 full_read(fd
, data
, size
);
3038 typedef struct SectionMergeInfo
{
3039 Section
*s
; /* corresponding existing section */
3040 unsigned long offset
; /* offset of the new section in the existing section */
3041 uint8_t new_section
; /* true if section 's' was added */
3042 uint8_t link_once
; /* true if link once section */
3045 ST_FUNC
int tcc_object_type(int fd
, ElfW(Ehdr
) *h
)
3047 int size
= full_read(fd
, h
, sizeof *h
);
3048 if (size
== sizeof *h
&& 0 == memcmp(h
, ELFMAG
, 4)) {
3049 if (h
->e_type
== ET_REL
)
3050 return AFF_BINTYPE_REL
;
3051 if (h
->e_type
== ET_DYN
)
3052 return AFF_BINTYPE_DYN
;
3053 } else if (size
>= 8) {
3054 if (0 == memcmp(h
, ARMAG
, 8))
3055 return AFF_BINTYPE_AR
;
3056 #ifdef TCC_TARGET_COFF
3057 if (((struct filehdr
*)h
)->f_magic
== COFF_C67_MAGIC
)
3058 return AFF_BINTYPE_C67
;
3064 /* load an object file and merge it with current files */
3065 /* XXX: handle correctly stab (debug) info */
3066 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
3067 int fd
, unsigned long file_offset
)
3070 ElfW(Shdr
) *shdr
, *sh
;
3071 unsigned long size
, offset
, offseti
;
3072 int i
, j
, nb_syms
, sym_index
, ret
, seencompressed
;
3073 char *strsec
, *strtab
;
3074 int stab_index
, stabstr_index
;
3075 int *old_to_new_syms
;
3076 char *sh_name
, *name
;
3077 SectionMergeInfo
*sm_table
, *sm
;
3078 ElfW(Sym
) *sym
, *symtab
;
3082 lseek(fd
, file_offset
, SEEK_SET
);
3083 if (tcc_object_type(fd
, &ehdr
) != AFF_BINTYPE_REL
)
3085 /* test CPU specific stuff */
3086 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
3087 ehdr
.e_machine
!= EM_TCC_TARGET
) {
3089 return tcc_error_noabort("invalid object file");
3092 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
3093 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
3094 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
3096 /* load section names */
3097 sh
= &shdr
[ehdr
.e_shstrndx
];
3098 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
3100 /* load symtab and strtab */
3101 old_to_new_syms
= NULL
;
3106 stab_index
= stabstr_index
= 0;
3109 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3111 if (sh
->sh_type
== SHT_SYMTAB
) {
3113 tcc_error_noabort("object must contain only one symtab");
3116 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
3117 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
3118 sm_table
[i
].s
= symtab_section
;
3120 /* now load strtab */
3121 sh
= &shdr
[sh
->sh_link
];
3122 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
3124 if (sh
->sh_flags
& SHF_COMPRESSED
)
3128 /* now examine each section and try to merge its content with the
3130 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3131 /* no need to examine section name strtab */
3132 if (i
== ehdr
.e_shstrndx
)
3135 if (sh
->sh_type
== SHT_RELX
)
3136 sh
= &shdr
[sh
->sh_info
];
3137 /* ignore sections types we do not handle (plus relocs to those) */
3138 if (sh
->sh_type
!= SHT_PROGBITS
&&
3140 sh
->sh_type
!= SHT_ARM_EXIDX
&&
3142 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3143 sh
->sh_type
!= SHT_X86_64_UNWIND
&&
3145 sh
->sh_type
!= SHT_NOTE
&&
3146 sh
->sh_type
!= SHT_NOBITS
&&
3147 sh
->sh_type
!= SHT_PREINIT_ARRAY
&&
3148 sh
->sh_type
!= SHT_INIT_ARRAY
&&
3149 sh
->sh_type
!= SHT_FINI_ARRAY
&&
3150 strcmp(strsec
+ sh
->sh_name
, ".stabstr")
3153 if (seencompressed
&& 0 == strncmp(strsec
+ sh
->sh_name
, ".debug_", 7))
3157 sh_name
= strsec
+ sh
->sh_name
;
3158 if (sh
->sh_addralign
< 1)
3159 sh
->sh_addralign
= 1;
3160 /* find corresponding section, if any */
3161 for(j
= 1; j
< s1
->nb_sections
;j
++) {
3162 s
= s1
->sections
[j
];
3163 if (!strcmp(s
->name
, sh_name
)) {
3164 if (!strncmp(sh_name
, ".gnu.linkonce",
3165 sizeof(".gnu.linkonce") - 1)) {
3166 /* if a 'linkonce' section is already present, we
3167 do not add it again. It is a little tricky as
3168 symbols can still be defined in
3170 sm_table
[i
].link_once
= 1;
3174 if (s
== stab_section
)
3176 if (s
== stab_section
->link
)
3182 /* not found: create new section */
3183 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
& ~SHF_GROUP
);
3184 /* take as much info as possible from the section. sh_link and
3185 sh_info will be updated later */
3186 s
->sh_addralign
= sh
->sh_addralign
;
3187 s
->sh_entsize
= sh
->sh_entsize
;
3188 sm_table
[i
].new_section
= 1;
3190 if (sh
->sh_type
!= s
->sh_type
3191 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3192 && strcmp (s
->name
, ".eh_frame")
3195 tcc_error_noabort("invalid section type");
3198 /* align start of section */
3199 s
->data_offset
+= -s
->data_offset
& (sh
->sh_addralign
- 1);
3200 if (sh
->sh_addralign
> s
->sh_addralign
)
3201 s
->sh_addralign
= sh
->sh_addralign
;
3202 sm_table
[i
].offset
= s
->data_offset
;
3204 /* concatenate sections */
3206 if (sh
->sh_type
!= SHT_NOBITS
) {
3208 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
3209 ptr
= section_ptr_add(s
, size
);
3210 full_read(fd
, ptr
, size
);
3212 s
->data_offset
+= size
;
3217 /* gr relocate stab strings */
3218 if (stab_index
&& stabstr_index
) {
3221 s
= sm_table
[stab_index
].s
;
3222 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
3223 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
3224 o
= sm_table
[stabstr_index
].offset
;
3232 /* second short pass to update sh_link and sh_info fields of new
3234 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3236 if (!s
|| !sm_table
[i
].new_section
)
3239 if (sh
->sh_link
> 0)
3240 s
->link
= sm_table
[sh
->sh_link
].s
;
3241 if (sh
->sh_type
== SHT_RELX
) {
3242 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
3243 /* update backward link */
3244 s1
->sections
[s
->sh_info
]->reloc
= s
;
3248 /* resolve symbols */
3249 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
3252 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
3253 if (sym
->st_shndx
!= SHN_UNDEF
&&
3254 sym
->st_shndx
< SHN_LORESERVE
) {
3255 sm
= &sm_table
[sym
->st_shndx
];
3256 if (sm
->link_once
) {
3257 /* if a symbol is in a link once section, we use the
3258 already defined symbol. It is very important to get
3259 correct relocations */
3260 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
3261 name
= strtab
+ sym
->st_name
;
3262 sym_index
= find_elf_sym(symtab_section
, name
);
3264 old_to_new_syms
[i
] = sym_index
;
3268 /* if no corresponding section added, no need to add symbol */
3271 /* convert section number */
3272 sym
->st_shndx
= sm
->s
->sh_num
;
3274 sym
->st_value
+= sm
->offset
;
3277 name
= strtab
+ sym
->st_name
;
3278 sym_index
= set_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
3279 sym
->st_info
, sym
->st_other
,
3280 sym
->st_shndx
, name
);
3281 old_to_new_syms
[i
] = sym_index
;
3284 /* third pass to patch relocation entries */
3285 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3290 offset
= sm_table
[i
].offset
;
3292 switch(s
->sh_type
) {
3294 /* take relocation offset information */
3295 offseti
= sm_table
[sh
->sh_info
].offset
;
3296 for (rel
= (ElfW_Rel
*) s
->data
+ (offset
/ sizeof(*rel
));
3297 rel
< (ElfW_Rel
*) s
->data
+ ((offset
+ size
) / sizeof(*rel
));
3301 /* convert symbol index */
3302 type
= ELFW(R_TYPE
)(rel
->r_info
);
3303 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
3304 /* NOTE: only one symtab assumed */
3305 if (sym_index
>= nb_syms
)
3307 sym_index
= old_to_new_syms
[sym_index
];
3308 /* ignore link_once in rel section. */
3309 if (!sym_index
&& !sm_table
[sh
->sh_info
].link_once
3310 #ifdef TCC_TARGET_ARM
3311 && type
!= R_ARM_V4BX
3312 #elif defined TCC_TARGET_RISCV64
3313 && type
!= R_RISCV_ALIGN
3314 && type
!= R_RISCV_RELAX
3318 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3319 i
, strsec
+ sh
->sh_name
, (int)rel
->r_offset
);
3322 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
3323 /* offset the relocation offset */
3324 rel
->r_offset
+= offseti
;
3325 #ifdef TCC_TARGET_ARM
3326 /* Jumps and branches from a Thumb code to a PLT entry need
3327 special handling since PLT entries are ARM code.
3328 Unconditional bl instructions referencing PLT entries are
3329 handled by converting these instructions into blx
3330 instructions. Other case of instructions referencing a PLT
3331 entry require to add a Thumb stub before the PLT entry to
3332 switch to ARM mode. We set bit plt_thumb_stub of the
3333 attribute of a symbol to indicate such a case. */
3334 if (type
== R_ARM_THM_JUMP24
)
3335 get_sym_attr(s1
, sym_index
, 1)->plt_thumb_stub
= 1;
3348 tcc_free(old_to_new_syms
);
3355 typedef struct ArchiveHeader
{
3356 char ar_name
[16]; /* name of this member */
3357 char ar_date
[12]; /* file mtime */
3358 char ar_uid
[6]; /* owner uid; printed as decimal */
3359 char ar_gid
[6]; /* owner gid; printed as decimal */
3360 char ar_mode
[8]; /* file mode, printed as octal */
3361 char ar_size
[10]; /* file size, printed as decimal */
3362 char ar_fmag
[2]; /* should contain ARFMAG */
3365 #define ARFMAG "`\n"
3367 static unsigned long long get_be(const uint8_t *b
, int n
)
3369 unsigned long long ret
= 0;
3371 ret
= (ret
<< 8) | *b
++, --n
;
3375 static int read_ar_header(int fd
, int offset
, ArchiveHeader
*hdr
)
3379 lseek(fd
, offset
, SEEK_SET
);
3380 len
= full_read(fd
, hdr
, sizeof(ArchiveHeader
));
3381 if (len
!= sizeof(ArchiveHeader
))
3382 return len
? -1 : 0;
3384 for (e
= p
+ sizeof hdr
->ar_name
; e
> p
&& e
[-1] == ' ';)
3387 hdr
->ar_size
[sizeof hdr
->ar_size
-1] = 0;
3391 /* load only the objects which resolve undefined symbols */
3392 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
, int entrysize
)
3394 int i
, bound
, nsyms
, sym_index
, len
, ret
= -1;
3395 unsigned long long off
;
3397 const char *ar_names
, *p
;
3398 const uint8_t *ar_index
;
3402 data
= tcc_malloc(size
);
3403 if (full_read(fd
, data
, size
) != size
)
3405 nsyms
= get_be(data
, entrysize
);
3406 ar_index
= data
+ entrysize
;
3407 ar_names
= (char *) ar_index
+ nsyms
* entrysize
;
3411 for (p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
3412 Section
*s
= symtab_section
;
3413 sym_index
= find_elf_sym(s
, p
);
3416 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
3417 if(sym
->st_shndx
!= SHN_UNDEF
)
3419 off
= get_be(ar_index
+ i
* entrysize
, entrysize
);
3420 len
= read_ar_header(fd
, off
, &hdr
);
3421 if (len
<= 0 || memcmp(hdr
.ar_fmag
, ARFMAG
, 2)) {
3422 tcc_error_noabort("invalid archive");
3426 if (s1
->verbose
== 2)
3427 printf(" -> %s\n", hdr
.ar_name
);
3428 if (tcc_load_object_file(s1
, fd
, off
) < 0)
3439 /* load a '.a' file */
3440 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
, int alacarte
)
3443 /* char magic[8]; */
3445 unsigned long file_offset
;
3448 /* skip magic which was already checked */
3449 /* full_read(fd, magic, sizeof(magic)); */
3450 file_offset
= sizeof ARMAG
- 1;
3453 len
= read_ar_header(fd
, file_offset
, &hdr
);
3457 return tcc_error_noabort("invalid archive");
3459 size
= strtol(hdr
.ar_size
, NULL
, 0);
3461 size
= (size
+ 1) & ~1;
3463 /* coff symbol table : we handle it */
3464 if (!strcmp(hdr
.ar_name
, "/"))
3465 return tcc_load_alacarte(s1
, fd
, size
, 4);
3466 if (!strcmp(hdr
.ar_name
, "/SYM64/"))
3467 return tcc_load_alacarte(s1
, fd
, size
, 8);
3468 } else if (tcc_object_type(fd
, &ehdr
) == AFF_BINTYPE_REL
) {
3469 if (s1
->verbose
== 2)
3470 printf(" -> %s\n", hdr
.ar_name
);
3471 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
3474 file_offset
+= size
;
3478 #ifndef ELF_OBJ_ONLY
3479 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3480 LV, maybe create a new entry for (LIB,VERSION). */
3481 static void set_ver_to_ver(TCCState
*s1
, int *n
, int **lv
, int i
, char *lib
, char *version
)
3484 *lv
= tcc_realloc(*lv
, (*n
+ 1) * sizeof(**lv
));
3487 if ((*lv
)[i
] == -1) {
3488 int v
, prev_same_lib
= -1;
3489 for (v
= 0; v
< nb_sym_versions
; v
++) {
3490 if (strcmp(sym_versions
[v
].lib
, lib
))
3493 if (!strcmp(sym_versions
[v
].version
, version
))
3496 if (v
== nb_sym_versions
) {
3497 sym_versions
= tcc_realloc (sym_versions
,
3498 (v
+ 1) * sizeof(*sym_versions
));
3499 sym_versions
[v
].lib
= tcc_strdup(lib
);
3500 sym_versions
[v
].version
= tcc_strdup(version
);
3501 sym_versions
[v
].out_index
= 0;
3502 sym_versions
[v
].prev_same_lib
= prev_same_lib
;
3509 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3512 set_sym_version(TCCState
*s1
, int sym_index
, int verndx
)
3514 if (sym_index
>= nb_sym_to_version
) {
3515 int newelems
= sym_index
? sym_index
* 2 : 1;
3516 sym_to_version
= tcc_realloc(sym_to_version
,
3517 newelems
* sizeof(*sym_to_version
));
3518 memset(sym_to_version
+ nb_sym_to_version
, -1,
3519 (newelems
- nb_sym_to_version
) * sizeof(*sym_to_version
));
3520 nb_sym_to_version
= newelems
;
3522 if (sym_to_version
[sym_index
] < 0)
3523 sym_to_version
[sym_index
] = verndx
;
3526 struct versym_info
{
3528 ElfW(Verdef
) *verdef
;
3529 ElfW(Verneed
) *verneed
;
3531 int nb_local_ver
, *local_ver
;
3535 static void store_version(TCCState
*s1
, struct versym_info
*v
, char *dynstr
)
3537 char *lib
, *version
;
3541 #define DEBUG_VERSION 0
3543 if (v
->versym
&& v
->verdef
) {
3544 ElfW(Verdef
) *vdef
= v
->verdef
;
3547 ElfW(Verdaux
) *verdaux
=
3548 (ElfW(Verdaux
) *) (((char *) vdef
) + vdef
->vd_aux
);
3551 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3552 vdef
->vd_version
, vdef
->vd_flags
, vdef
->vd_ndx
,
3556 version
= dynstr
+ verdaux
->vda_name
;
3561 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vdef
->vd_ndx
,
3564 printf (" verdaux(%u): %s\n", vdef
->vd_ndx
, version
);
3567 next
= vdef
->vd_next
;
3568 vdef
= (ElfW(Verdef
) *) (((char *) vdef
) + next
);
3571 if (v
->versym
&& v
->verneed
) {
3572 ElfW(Verneed
) *vneed
= v
->verneed
;
3574 ElfW(Vernaux
) *vernaux
=
3575 (ElfW(Vernaux
) *) (((char *) vneed
) + vneed
->vn_aux
);
3577 lib
= dynstr
+ vneed
->vn_file
;
3579 printf ("verneed: %u %s\n", vneed
->vn_version
, lib
);
3581 for (i
= 0; i
< vneed
->vn_cnt
; i
++) {
3582 if ((vernaux
->vna_other
& 0x8000) == 0) { /* hidden */
3583 version
= dynstr
+ vernaux
->vna_name
;
3584 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vernaux
->vna_other
,
3587 printf (" vernaux(%u): %u %u %s\n",
3588 vernaux
->vna_other
, vernaux
->vna_hash
,
3589 vernaux
->vna_flags
, version
);
3592 vernaux
= (ElfW(Vernaux
) *) (((char *) vernaux
) + vernaux
->vna_next
);
3594 next
= vneed
->vn_next
;
3595 vneed
= (ElfW(Verneed
) *) (((char *) vneed
) + next
);
3600 for (i
= 0; i
< v
->nb_local_ver
; i
++) {
3601 if (v
->local_ver
[i
] > 0) {
3602 printf ("%d: lib: %s, version %s\n",
3603 i
, sym_versions
[v
->local_ver
[i
]].lib
,
3604 sym_versions
[v
->local_ver
[i
]].version
);
3610 /* load a library / DLL
3611 'level = 0' means that the DLL is referenced by the user
3612 (so it should be added as DT_NEEDED in the generated ELF file) */
3613 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
3616 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
3617 int i
, nb_syms
, nb_dts
, sym_bind
, ret
= -1;
3618 ElfW(Sym
) *sym
, *dynsym
;
3619 ElfW(Dyn
) *dt
, *dynamic
;
3623 const char *name
, *soname
;
3624 struct versym_info v
;
3626 full_read(fd
, &ehdr
, sizeof(ehdr
));
3628 /* test CPU specific stuff */
3629 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
3630 ehdr
.e_machine
!= EM_TCC_TARGET
) {
3631 return tcc_error_noabort("bad architecture");
3635 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
3637 /* load dynamic section and dynamic symbols */
3641 dynsym
= NULL
; /* avoid warning */
3642 dynstr
= NULL
; /* avoid warning */
3643 memset(&v
, 0, sizeof v
);
3645 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
3646 switch(sh
->sh_type
) {
3648 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
3649 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3652 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
3653 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3654 sh1
= &shdr
[sh
->sh_link
];
3655 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
3657 case SHT_GNU_verdef
:
3658 v
.verdef
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3660 case SHT_GNU_verneed
:
3661 v
.verneed
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3663 case SHT_GNU_versym
:
3664 v
.nb_versyms
= sh
->sh_size
/ sizeof(ElfW(Half
));
3665 v
.versym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3675 /* compute the real library name */
3676 soname
= tcc_basename(filename
);
3677 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++)
3678 if (dt
->d_tag
== DT_SONAME
)
3679 soname
= dynstr
+ dt
->d_un
.d_val
;
3681 /* if the dll is already loaded, do not load it */
3682 if (tcc_add_dllref(s1
, soname
, level
)->found
)
3685 if (v
.nb_versyms
!= nb_syms
)
3686 tcc_free (v
.versym
), v
.versym
= NULL
;
3688 store_version(s1
, &v
, dynstr
);
3690 /* add dynamic symbols in dynsym_section */
3691 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
3692 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
3693 if (sym_bind
== STB_LOCAL
)
3695 name
= dynstr
+ sym
->st_name
;
3696 sym_index
= set_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
3697 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
3699 ElfW(Half
) vsym
= v
.versym
[i
];
3700 if ((vsym
& 0x8000) == 0 && vsym
> 0 && vsym
< v
.nb_local_ver
)
3701 set_sym_version(s1
, sym_index
, v
.local_ver
[vsym
]);
3705 /* do not load all referenced libraries
3706 (recursive loading can break linking of libraries) */
3707 /* following DT_NEEDED is needed for the dynamic loader (libdl.so),
3708 but it is no longer needed, when linking a library or a program.
3709 When tcc output mode is OUTPUT_MEM,
3710 tcc calls dlopen, which handles DT_NEEDED for us */
3713 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++)
3714 if (dt
->d_tag
== DT_RPATH
)
3715 tcc_add_library_path(s1
, dynstr
+ dt
->d_un
.d_val
);
3717 /* load all referenced DLLs */
3718 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3721 name
= dynstr
+ dt
->d_un
.d_val
;
3722 if (tcc_add_dllref(s1
, name
, -1))
3724 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
3725 ret
= tcc_error_noabort("referenced dll '%s' not found", name
);
3739 tcc_free(v
.local_ver
);
3741 tcc_free(v
.verneed
);
3746 #define LD_TOK_NAME 256
3747 #define LD_TOK_EOF (-1)
3749 static int ld_inp(TCCState
*s1
)
3757 if (1 == read(s1
->fd
, &b
, 1))
3762 /* return next ld script token */
3763 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
3780 if (ch
== '*') { /* comment */
3781 for (d
= 0;; d
= ch
) {
3783 if (ch
== CH_EOF
|| (ch
== '/' && d
== '*'))
3794 /* case 'a' ... 'z': */
3821 /* case 'A' ... 'z': */
3855 if (!((ch
>= 'a' && ch
<= 'z') ||
3856 (ch
>= 'A' && ch
<= 'Z') ||
3857 (ch
>= '0' && ch
<= '9') ||
3858 strchr("/.-_+=$:\\,~", ch
)))
3860 if ((q
- name
) < name_size
- 1) {
3879 static int ld_add_file(TCCState
*s1
, const char filename
[])
3881 if (filename
[0] == '/') {
3882 if (CONFIG_SYSROOT
[0] == '\0'
3883 && tcc_add_file_internal(s1
, filename
, AFF_TYPE_BIN
) == 0)
3885 filename
= tcc_basename(filename
);
3887 return tcc_add_dll(s1
, filename
, AFF_PRINT_ERROR
);
3890 static int ld_add_file_list(TCCState
*s1
, const char *cmd
, int as_needed
)
3892 char filename
[1024], libname
[1024];
3893 int t
, group
, nblibs
= 0, ret
= 0;
3896 group
= !strcmp(cmd
, "GROUP");
3898 s1
->new_undef_sym
= 0;
3899 t
= ld_next(s1
, filename
, sizeof(filename
));
3901 ret
= tcc_error_noabort("( expected");
3902 goto lib_parse_error
;
3904 t
= ld_next(s1
, filename
, sizeof(filename
));
3907 if (t
== LD_TOK_EOF
) {
3908 ret
= tcc_error_noabort("unexpected end of file");
3909 goto lib_parse_error
;
3910 } else if (t
== ')') {
3912 } else if (t
== '-') {
3913 t
= ld_next(s1
, filename
, sizeof(filename
));
3914 if ((t
!= LD_TOK_NAME
) || (filename
[0] != 'l')) {
3915 ret
= tcc_error_noabort("library name expected");
3916 goto lib_parse_error
;
3918 pstrcpy(libname
, sizeof libname
, &filename
[1]);
3919 if (s1
->static_link
) {
3920 snprintf(filename
, sizeof filename
, "lib%s.a", libname
);
3922 snprintf(filename
, sizeof filename
, "lib%s.so", libname
);
3924 } else if (t
!= LD_TOK_NAME
) {
3925 ret
= tcc_error_noabort("filename expected");
3926 goto lib_parse_error
;
3928 if (!strcmp(filename
, "AS_NEEDED")) {
3929 ret
= ld_add_file_list(s1
, cmd
, 1);
3931 goto lib_parse_error
;
3933 /* TODO: Implement AS_NEEDED support. */
3934 /* DT_NEEDED is not used any more so ignore as_needed */
3935 if (1 || !as_needed
) {
3936 ret
= ld_add_file(s1
, filename
);
3938 goto lib_parse_error
;
3940 /* Add the filename *and* the libname to avoid future conversions */
3941 dynarray_add(&libs
, &nblibs
, tcc_strdup(filename
));
3942 if (libname
[0] != '\0')
3943 dynarray_add(&libs
, &nblibs
, tcc_strdup(libname
));
3947 t
= ld_next(s1
, filename
, sizeof(filename
));
3949 t
= ld_next(s1
, filename
, sizeof(filename
));
3952 if (group
&& !as_needed
) {
3953 while (s1
->new_undef_sym
) {
3955 s1
->new_undef_sym
= 0;
3956 for (i
= 0; i
< nblibs
; i
++)
3957 ld_add_file(s1
, libs
[i
]);
3961 dynarray_reset(&libs
, &nblibs
);
3965 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3967 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
, int fd
)
3970 char filename
[1024];
3976 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3977 if (t
== LD_TOK_EOF
)
3979 else if (t
!= LD_TOK_NAME
)
3981 if (!strcmp(cmd
, "INPUT") ||
3982 !strcmp(cmd
, "GROUP")) {
3983 ret
= ld_add_file_list(s1
, cmd
, 0);
3986 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
3987 !strcmp(cmd
, "TARGET")) {
3988 /* ignore some commands */
3989 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3991 return tcc_error_noabort("( expected");
3993 t
= ld_next(s1
, filename
, sizeof(filename
));
3994 if (t
== LD_TOK_EOF
) {
3995 return tcc_error_noabort("unexpected end of file");
3996 } else if (t
== ')') {
4006 #endif /* !ELF_OBJ_ONLY */