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
159 /* At the end of compilation, convert any UNDEF syms to global, and merge
160 with previously existing symbols */
161 ST_FUNC
void tccelf_end_file(TCCState
*s1
)
163 Section
*s
= s1
->symtab
;
164 int first_sym
, nb_syms
, *tr
, i
;
166 first_sym
= s
->sh_offset
/ sizeof (ElfSym
);
167 nb_syms
= s
->data_offset
/ sizeof (ElfSym
) - first_sym
;
168 s
->data_offset
= s
->sh_offset
;
169 s
->link
->data_offset
= s
->link
->sh_offset
;
170 s
->hash
= s
->reloc
, s
->reloc
= NULL
;
171 tr
= tcc_mallocz(nb_syms
* sizeof *tr
);
173 for (i
= 0; i
< nb_syms
; ++i
) {
174 ElfSym
*sym
= (ElfSym
*)s
->data
+ first_sym
+ i
;
176 if (sym
->st_shndx
== SHN_UNDEF
) {
177 int sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
178 int sym_type
= ELFW(ST_TYPE
)(sym
->st_info
);
179 if (sym_bind
== STB_LOCAL
)
180 sym_bind
= STB_GLOBAL
;
181 #ifndef TCC_TARGET_PE
182 if (sym_bind
== STB_GLOBAL
&& s1
->output_type
== TCC_OUTPUT_OBJ
) {
183 /* undefined symbols with STT_FUNC are confusing gnu ld when
184 linking statically to STT_GNU_IFUNC */
185 sym_type
= STT_NOTYPE
;
188 sym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
191 tr
[i
] = set_elf_sym(s
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
192 sym
->st_other
, sym
->st_shndx
, (char*)s
->link
->data
+ sym
->st_name
);
194 /* now update relocations */
195 for (i
= 1; i
< s1
->nb_sections
; i
++) {
196 Section
*sr
= s1
->sections
[i
];
197 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
198 ElfW_Rel
*rel
= (ElfW_Rel
*)(sr
->data
+ sr
->sh_offset
);
199 ElfW_Rel
*rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
200 for (; rel
< rel_end
; ++rel
) {
201 int n
= ELFW(R_SYM
)(rel
->r_info
) - first_sym
;
202 if (n
< 0) /* zero sym_index in reloc (can happen with asm) */
204 rel
->r_info
= ELFW(R_INFO
)(tr
[n
], ELFW(R_TYPE
)(rel
->r_info
));
210 /* record text/data/bss output for -bench info */
211 for (i
= 0; i
< 4; ++i
) {
212 s
= s1
->sections
[i
+ 1];
213 s1
->total_output
[i
] += s
->data_offset
- s
->sh_offset
;
217 ST_FUNC Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
221 sec
= tcc_mallocz(sizeof(Section
) + strlen(name
));
223 strcpy(sec
->name
, name
);
224 sec
->sh_type
= sh_type
;
225 sec
->sh_flags
= sh_flags
;
228 sec
->sh_addralign
= 2;
237 case SHT_GNU_verneed
:
239 sec
->sh_addralign
= PTR_SIZE
;
242 sec
->sh_addralign
= 1;
245 sec
->sh_addralign
= PTR_SIZE
; /* gcc/pcc default alignment */
249 if (sh_flags
& SHF_PRIVATE
) {
250 dynarray_add(&s1
->priv_sections
, &s1
->nb_priv_sections
, sec
);
252 sec
->sh_num
= s1
->nb_sections
;
253 dynarray_add(&s1
->sections
, &s1
->nb_sections
, sec
);
259 ST_FUNC
void init_symtab(Section
*s
)
261 int *ptr
, nb_buckets
= 1;
262 put_elf_str(s
->link
, "");
263 section_ptr_add(s
, sizeof (ElfW(Sym
)));
264 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ 1) * sizeof(int));
267 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
270 ST_FUNC Section
*new_symtab(TCCState
*s1
,
271 const char *symtab_name
, int sh_type
, int sh_flags
,
272 const char *strtab_name
,
273 const char *hash_name
, int hash_sh_flags
)
275 Section
*symtab
, *strtab
, *hash
;
276 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
277 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
278 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
279 symtab
->link
= strtab
;
280 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
281 hash
->sh_entsize
= sizeof(int);
288 /* realloc section and set its content to zero */
289 ST_FUNC
void section_realloc(Section
*sec
, unsigned long new_size
)
294 size
= sec
->data_allocated
;
297 while (size
< new_size
)
299 data
= tcc_realloc(sec
->data
, size
);
300 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
302 sec
->data_allocated
= size
;
305 /* reserve at least 'size' bytes aligned per 'align' in section
306 'sec' from current offset, and return the aligned offset */
307 ST_FUNC
size_t section_add(Section
*sec
, addr_t size
, int align
)
309 size_t offset
, offset1
;
311 offset
= (sec
->data_offset
+ align
- 1) & -align
;
312 offset1
= offset
+ size
;
313 if (sec
->sh_type
!= SHT_NOBITS
&& offset1
> sec
->data_allocated
)
314 section_realloc(sec
, offset1
);
315 sec
->data_offset
= offset1
;
316 if (align
> sec
->sh_addralign
)
317 sec
->sh_addralign
= align
;
321 /* reserve at least 'size' bytes in section 'sec' from
323 ST_FUNC
void *section_ptr_add(Section
*sec
, addr_t size
)
325 size_t offset
= section_add(sec
, size
, 1);
326 return sec
->data
+ offset
;
330 /* reserve at least 'size' bytes from section start */
331 static void section_reserve(Section
*sec
, unsigned long size
)
333 if (size
> sec
->data_allocated
)
334 section_realloc(sec
, size
);
335 if (size
> sec
->data_offset
)
336 sec
->data_offset
= size
;
340 static Section
*have_section(TCCState
*s1
, const char *name
)
344 for(i
= 1; i
< s1
->nb_sections
; i
++) {
345 sec
= s1
->sections
[i
];
346 if (!strcmp(name
, sec
->name
))
352 /* return a reference to a section, and create it if it does not
354 ST_FUNC Section
*find_section(TCCState
*s1
, const char *name
)
356 Section
*sec
= have_section(s1
, name
);
359 /* sections are created as PROGBITS */
360 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
363 /* ------------------------------------------------------------------------- */
365 ST_FUNC
int put_elf_str(Section
*s
, const char *sym
)
370 len
= strlen(sym
) + 1;
371 offset
= s
->data_offset
;
372 ptr
= section_ptr_add(s
, len
);
373 memmove(ptr
, sym
, len
);
377 /* elf symbol hashing function */
378 static ElfW(Word
) elf_hash(const unsigned char *name
)
383 h
= (h
<< 4) + *name
++;
392 /* rebuild hash table of section s */
393 /* NOTE: we do factorize the hash table code to go faster */
394 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
397 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
398 unsigned char *strtab
;
400 strtab
= s
->link
->data
;
401 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
404 nb_buckets
= ((int*)s
->hash
->data
)[0];
406 s
->hash
->data_offset
= 0;
407 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
412 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
413 ptr
+= nb_buckets
+ 1;
415 sym
= (ElfW(Sym
) *)s
->data
+ 1;
416 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
417 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
418 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
429 /* return the symbol number */
430 ST_FUNC
int put_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
431 int info
, int other
, int shndx
, const char *name
)
433 int name_offset
, sym_index
;
438 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
440 name_offset
= put_elf_str(s
->link
, name
);
443 /* XXX: endianness */
444 sym
->st_name
= name_offset
;
445 sym
->st_value
= value
;
448 sym
->st_other
= other
;
449 sym
->st_shndx
= shndx
;
450 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
454 ptr
= section_ptr_add(hs
, sizeof(int));
455 base
= (int *)hs
->data
;
456 /* only add global or weak symbols. */
457 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
458 /* add another hashing entry */
460 h
= elf_hash((unsigned char *)s
->link
->data
+ name_offset
) % nbuckets
;
462 base
[2 + h
] = sym_index
;
464 /* we resize the hash table */
465 hs
->nb_hashed_syms
++;
466 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
467 rebuild_hash(s
, 2 * nbuckets
);
477 ST_FUNC
int find_elf_sym(Section
*s
, const char *name
)
481 int nbuckets
, sym_index
, h
;
487 nbuckets
= ((int *)hs
->data
)[0];
488 h
= elf_hash((unsigned char *) name
) % nbuckets
;
489 sym_index
= ((int *)hs
->data
)[2 + h
];
490 while (sym_index
!= 0) {
491 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
492 name1
= (char *) s
->link
->data
+ sym
->st_name
;
493 if (!strcmp(name
, name1
))
495 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
500 /* return elf symbol value, signal error if 'err' is nonzero, decorate
502 ST_FUNC addr_t
get_sym_addr(TCCState
*s1
, const char *name
, int err
, int forc
)
507 if (forc
&& s1
->leading_underscore
509 /* win32-32bit stdcall symbols always have _ already */
510 && !strchr(name
, '@')
514 pstrcpy(buf
+ 1, sizeof(buf
) - 1, name
);
517 sym_index
= find_elf_sym(s1
->symtab
, name
);
518 sym
= &((ElfW(Sym
) *)s1
->symtab
->data
)[sym_index
];
519 if (!sym_index
|| sym
->st_shndx
== SHN_UNDEF
) {
521 tcc_error_noabort("%s not defined", name
);
524 return sym
->st_value
;
527 /* return elf symbol value */
528 LIBTCCAPI
void *tcc_get_symbol(TCCState
*s
, const char *name
)
530 addr_t addr
= get_sym_addr(s
, name
, 0, 1);
531 return addr
== -1 ? NULL
: (void*)(uintptr_t)addr
;
534 /* list elf symbol names and values */
535 ST_FUNC
void list_elf_symbols(TCCState
*s
, void *ctx
,
536 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
540 int sym_index
, end_sym
;
542 unsigned char sym_vis
, sym_bind
;
545 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
546 for (sym_index
= 0; sym_index
< end_sym
; ++sym_index
) {
547 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
549 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
550 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
551 sym_vis
= ELFW(ST_VISIBILITY
)(sym
->st_other
);
552 if (sym_bind
== STB_GLOBAL
&& sym_vis
== STV_DEFAULT
)
553 symbol_cb(ctx
, name
, (void*)(uintptr_t)sym
->st_value
);
558 /* list elf symbol names and values */
559 LIBTCCAPI
void tcc_list_symbols(TCCState
*s
, void *ctx
,
560 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
562 list_elf_symbols(s
, ctx
, symbol_cb
);
567 version_add (TCCState
*s1
)
571 ElfW(Verneed
) *vn
= NULL
;
573 int sym_index
, end_sym
, nb_versions
= 2, nb_entries
= 0;
577 if (0 == nb_sym_versions
)
579 versym_section
= new_section(s1
, ".gnu.version", SHT_GNU_versym
, SHF_ALLOC
);
580 versym_section
->sh_entsize
= sizeof(ElfW(Half
));
581 versym_section
->link
= s1
->dynsym
;
583 /* add needed symbols */
585 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
586 versym
= section_ptr_add(versym_section
, end_sym
* sizeof(ElfW(Half
)));
587 for (sym_index
= 1; sym_index
< end_sym
; ++sym_index
) {
588 int dllindex
, verndx
;
589 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
590 if (sym
->st_shndx
!= SHN_UNDEF
)
591 continue; /* defined symbol doesn't need library version */
592 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
593 dllindex
= find_elf_sym(s1
->dynsymtab_section
, name
);
594 verndx
= (dllindex
&& dllindex
< nb_sym_to_version
)
595 ? sym_to_version
[dllindex
] : -1;
597 if (!sym_versions
[verndx
].out_index
)
598 sym_versions
[verndx
].out_index
= nb_versions
++;
599 versym
[sym_index
] = sym_versions
[verndx
].out_index
;
602 /* generate verneed section, but not when it will be empty. Some
603 dynamic linkers look at their contents even when DTVERNEEDNUM and
604 section size is zero. */
605 if (nb_versions
> 2) {
606 verneed_section
= new_section(s1
, ".gnu.version_r",
607 SHT_GNU_verneed
, SHF_ALLOC
);
608 verneed_section
->link
= s1
->dynsym
->link
;
609 for (i
= nb_sym_versions
; i
-- > 0;) {
610 struct sym_version
*sv
= &sym_versions
[i
];
611 int n_same_libs
= 0, prev
;
613 ElfW(Vernaux
) *vna
= 0;
614 if (sv
->out_index
< 1)
617 /* make sure that a DT_NEEDED tag is put */
618 /* abitest-tcc fails on older i386-linux with "ld-linux.so.2" DT_NEEDED
619 ret_int_test... Inconsistency detected by ld.so: dl-minimal.c: 148:
620 realloc: Assertion `ptr == alloc_last_block' failed! */
621 if (strcmp(sv
->lib
, "ld-linux.so.2"))
622 tcc_add_dllref(s1
, sv
->lib
, 0);
624 vnofs
= section_add(verneed_section
, sizeof(*vn
), 1);
625 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
627 vn
->vn_file
= put_elf_str(verneed_section
->link
, sv
->lib
);
628 vn
->vn_aux
= sizeof (*vn
);
630 prev
= sv
->prev_same_lib
;
631 if (sv
->out_index
> 0) {
632 vna
= section_ptr_add(verneed_section
, sizeof(*vna
));
633 vna
->vna_hash
= elf_hash ((const unsigned char *)sv
->version
);
635 vna
->vna_other
= sv
->out_index
;
637 vna
->vna_name
= put_elf_str(verneed_section
->link
, sv
->version
);
638 vna
->vna_next
= sizeof (*vna
);
642 sv
= &sym_versions
[prev
];
645 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
646 vn
->vn_cnt
= n_same_libs
;
647 vn
->vn_next
= sizeof(*vn
) + n_same_libs
* sizeof(*vna
);
652 verneed_section
->sh_info
= nb_entries
;
654 dt_verneednum
= nb_entries
;
656 #endif /* ndef ELF_OBJ_ONLY */
658 /* add an elf symbol : check if it is already defined and patch
659 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
660 ST_FUNC
int set_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
661 int info
, int other
, int shndx
, const char *name
)
663 TCCState
*s1
= s
->s1
;
665 int sym_bind
, sym_index
, sym_type
, esym_bind
;
666 unsigned char sym_vis
, esym_vis
, new_vis
;
668 sym_bind
= ELFW(ST_BIND
)(info
);
669 sym_type
= ELFW(ST_TYPE
)(info
);
670 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
672 if (sym_bind
!= STB_LOCAL
) {
673 /* we search global or weak symbols */
674 sym_index
= find_elf_sym(s
, name
);
677 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
678 if (esym
->st_value
== value
&& esym
->st_size
== size
&& esym
->st_info
== info
679 && esym
->st_other
== other
&& esym
->st_shndx
== shndx
)
681 if (esym
->st_shndx
!= SHN_UNDEF
) {
682 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
683 /* propagate the most constraining visibility */
684 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
685 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
686 if (esym_vis
== STV_DEFAULT
) {
688 } else if (sym_vis
== STV_DEFAULT
) {
691 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
693 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
695 if (shndx
== SHN_UNDEF
) {
696 /* ignore adding of undefined symbol if the
697 corresponding symbol is already defined */
698 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
699 /* global overrides weak, so patch */
701 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
702 /* weak is ignored if already global */
703 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_WEAK
) {
704 /* keep first-found weak definition, ignore subsequents */
705 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
706 /* ignore hidden symbols after */
707 } else if ((esym
->st_shndx
== SHN_COMMON
708 || esym
->st_shndx
== bss_section
->sh_num
)
709 && (shndx
< SHN_LORESERVE
710 && shndx
!= bss_section
->sh_num
)) {
711 /* data symbol gets precedence over common/bss */
713 } else if (shndx
== SHN_COMMON
|| shndx
== bss_section
->sh_num
) {
714 /* data symbol keeps precedence over common/bss */
715 } else if (s
->sh_flags
& SHF_DYNSYM
) {
716 /* we accept that two DLL define the same symbol */
717 } else if (esym
->st_other
& ST_ASM_SET
) {
718 /* If the existing symbol came from an asm .set
723 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
724 sym_bind
, shndx
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
726 tcc_error_noabort("'%s' defined twice", name
);
729 esym
->st_other
= other
;
731 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
732 esym
->st_shndx
= shndx
;
733 s1
->new_undef_sym
= 1;
734 esym
->st_value
= value
;
735 esym
->st_size
= size
;
739 sym_index
= put_elf_sym(s
, value
, size
,
740 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
747 ST_FUNC
void put_elf_reloca(Section
*symtab
, Section
*s
, unsigned long offset
,
748 int type
, int symbol
, addr_t addend
)
750 TCCState
*s1
= s
->s1
;
757 /* if no relocation section, create it */
758 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
759 /* if the symtab is allocated, then we consider the relocation
761 sr
= new_section(s
->s1
, buf
, SHT_RELX
, symtab
->sh_flags
);
762 sr
->sh_entsize
= sizeof(ElfW_Rel
);
764 sr
->sh_info
= s
->sh_num
;
767 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
768 rel
->r_offset
= offset
;
769 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
770 #if SHT_RELX == SHT_RELA
771 rel
->r_addend
= addend
;
773 if (SHT_RELX
!= SHT_RELA
&& addend
)
774 tcc_error_noabort("non-zero addend on REL architecture");
777 ST_FUNC
void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
778 int type
, int symbol
)
780 put_elf_reloca(symtab
, s
, offset
, type
, symbol
, 0);
783 ST_FUNC
struct sym_attr
*get_sym_attr(TCCState
*s1
, int index
, int alloc
)
786 struct sym_attr
*tab
;
788 if (index
>= s1
->nb_sym_attrs
) {
790 return s1
->sym_attrs
;
791 /* find immediately bigger power of 2 and reallocate array */
795 tab
= tcc_realloc(s1
->sym_attrs
, n
* sizeof(*s1
->sym_attrs
));
797 memset(s1
->sym_attrs
+ s1
->nb_sym_attrs
, 0,
798 (n
- s1
->nb_sym_attrs
) * sizeof(*s1
->sym_attrs
));
799 s1
->nb_sym_attrs
= n
;
801 return &s1
->sym_attrs
[index
];
804 static void modify_reloctions_old_to_new(TCCState
*s1
, Section
*s
, int *old_to_new_syms
)
806 int i
, type
, sym_index
;
810 for(i
= 1; i
< s1
->nb_sections
; i
++) {
811 sr
= s1
->sections
[i
];
812 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
813 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
814 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
815 type
= ELFW(R_TYPE
)(rel
->r_info
);
816 sym_index
= old_to_new_syms
[sym_index
];
817 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
823 /* In an ELF file symbol table, the local symbols must appear below
824 the global and weak ones. Since TCC cannot sort it while generating
825 the code, we must do it after. All the relocation tables are also
826 modified to take into account the symbol table sorting */
827 static void sort_syms(TCCState
*s1
, Section
*s
)
829 int *old_to_new_syms
;
834 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
835 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
836 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
838 /* first pass for local symbols */
839 p
= (ElfW(Sym
) *)s
->data
;
841 for(i
= 0; i
< nb_syms
; i
++) {
842 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
843 old_to_new_syms
[i
] = q
- new_syms
;
848 /* save the number of local symbols in section header */
849 if( s
->sh_size
) /* this 'if' makes IDA happy */
850 s
->sh_info
= q
- new_syms
;
852 /* then second pass for non local symbols */
853 p
= (ElfW(Sym
) *)s
->data
;
854 for(i
= 0; i
< nb_syms
; i
++) {
855 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
856 old_to_new_syms
[i
] = q
- new_syms
;
862 /* we copy the new symbols to the old */
863 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
866 modify_reloctions_old_to_new(s1
, s
, old_to_new_syms
);
868 tcc_free(old_to_new_syms
);
872 /* See: https://flapenguin.me/elf-dt-gnu-hash */
873 #define ELFCLASS_BITS (PTR_SIZE * 8)
875 static Section
*create_gnu_hash(TCCState
*s1
)
877 int nb_syms
, i
, ndef
, nbuckets
, symoffset
, bloom_size
, bloom_shift
;
880 Section
*dynsym
= s1
->dynsym
;
883 gnu_hash
= new_section(s1
, ".gnu.hash", SHT_GNU_HASH
, SHF_ALLOC
);
884 gnu_hash
->link
= dynsym
->hash
->link
;
886 nb_syms
= dynsym
->data_offset
/ sizeof(ElfW(Sym
));
888 /* count def symbols */
890 p
= (ElfW(Sym
) *)dynsym
->data
;
891 for(i
= 0; i
< nb_syms
; i
++, p
++)
892 ndef
+= p
->st_shndx
!= SHN_UNDEF
;
894 /* calculate gnu hash sizes and fill header */
895 nbuckets
= ndef
/ 4 + 1;
896 symoffset
= nb_syms
- ndef
;
897 bloom_shift
= PTR_SIZE
== 8 ? 6 : 5;
898 bloom_size
= 1; /* must be power of two */
899 while (ndef
>= bloom_size
* (1 << (bloom_shift
- 3)))
901 ptr
= section_ptr_add(gnu_hash
, 4 * 4 +
902 PTR_SIZE
* bloom_size
+
908 ptr
[3] = bloom_shift
;
912 static Elf32_Word
elf_gnu_hash (const unsigned char *name
)
917 while ((c
= *name
++))
922 static void update_gnu_hash(TCCState
*s1
, Section
*gnu_hash
)
924 int *old_to_new_syms
;
926 int nb_syms
, i
, nbuckets
, bloom_size
, bloom_shift
;
929 Section
*dynsym
= s1
->dynsym
;
930 Elf32_Word
*ptr
, *buckets
, *chain
, *hash
;
931 unsigned int *nextbuck
;
933 unsigned char *strtab
;
934 struct { int first
, last
; } *buck
;
936 strtab
= dynsym
->link
->data
;
937 nb_syms
= dynsym
->data_offset
/ sizeof(ElfW(Sym
));
938 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
939 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
940 hash
= tcc_malloc(nb_syms
* sizeof(Elf32_Word
));
941 nextbuck
= tcc_malloc(nb_syms
* sizeof(int));
943 /* calculate hashes and copy undefs */
944 p
= (ElfW(Sym
) *)dynsym
->data
;
946 for(i
= 0; i
< nb_syms
; i
++, p
++) {
947 if (p
->st_shndx
== SHN_UNDEF
) {
948 old_to_new_syms
[i
] = q
- new_syms
;
952 hash
[i
] = elf_gnu_hash(strtab
+ p
->st_name
);
955 ptr
= (Elf32_Word
*) gnu_hash
->data
;
958 bloom_shift
= ptr
[3];
959 bloom
= (addr_t
*) (void *) &ptr
[4];
960 buckets
= (Elf32_Word
*) (void *) &bloom
[bloom_size
];
961 chain
= &buckets
[nbuckets
];
962 buck
= tcc_malloc(nbuckets
* sizeof(*buck
));
964 if (gnu_hash
->data_offset
!= 4 * 4 +
965 PTR_SIZE
* bloom_size
+
967 (nb_syms
- (q
- new_syms
)) * 4)
968 tcc_error_noabort ("gnu_hash size incorrect");
971 for(i
= 0; i
< nbuckets
; i
++)
974 p
= (ElfW(Sym
) *)dynsym
->data
;
975 for(i
= 0; i
< nb_syms
; i
++, p
++)
976 if (p
->st_shndx
!= SHN_UNDEF
) {
977 int bucket
= hash
[i
] % nbuckets
;
979 if (buck
[bucket
].first
== -1)
980 buck
[bucket
].first
= buck
[bucket
].last
= i
;
982 nextbuck
[buck
[bucket
].last
] = i
;
983 buck
[bucket
].last
= i
;
987 /* fill buckets/chains/bloom and sort symbols */
988 p
= (ElfW(Sym
) *)dynsym
->data
;
989 for(i
= 0; i
< nbuckets
; i
++) {
990 int cur
= buck
[i
].first
;
993 buckets
[i
] = q
- new_syms
;
995 old_to_new_syms
[cur
] = q
- new_syms
;
997 *chain
++ = hash
[cur
] & ~1;
998 bloom
[(hash
[cur
] / ELFCLASS_BITS
) % bloom_size
] |=
999 (addr_t
)1 << (hash
[cur
] % ELFCLASS_BITS
) |
1000 (addr_t
)1 << ((hash
[cur
] >> bloom_shift
) % ELFCLASS_BITS
);
1001 if (cur
== buck
[i
].last
)
1003 cur
= nextbuck
[cur
];
1009 memcpy(dynsym
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
1015 modify_reloctions_old_to_new(s1
, dynsym
, old_to_new_syms
);
1017 /* modify the versions */
1018 vs
= versym_section
;
1020 ElfW(Half
) *newver
, *versym
= (ElfW(Half
) *)vs
->data
;
1023 newver
= tcc_malloc(nb_syms
* sizeof(*newver
));
1024 for (i
= 0; i
< nb_syms
; i
++)
1025 newver
[old_to_new_syms
[i
]] = versym
[i
];
1026 memcpy(vs
->data
, newver
, nb_syms
* sizeof(*newver
));
1031 tcc_free(old_to_new_syms
);
1034 ptr
= (Elf32_Word
*) dynsym
->hash
->data
;
1035 rebuild_hash(dynsym
, ptr
[0]);
1037 #endif /* ELF_OBJ_ONLY */
1039 /* relocate symbol table, resolve undefined symbols if do_resolve is
1040 true and output error if undefined symbol. */
1041 ST_FUNC
void relocate_syms(TCCState
*s1
, Section
*symtab
, int do_resolve
)
1044 int sym_bind
, sh_num
;
1047 for_each_elem(symtab
, 1, sym
, ElfW(Sym
)) {
1048 sh_num
= sym
->st_shndx
;
1049 if (sh_num
== SHN_UNDEF
) {
1050 if (do_resolve
== 2) /* relocating dynsym */
1052 name
= (char *) s1
->symtab
->link
->data
+ sym
->st_name
;
1053 /* Use ld.so to resolve symbol for us (for tcc -run) */
1055 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
1056 /* dlsym() needs the undecorated name. */
1057 void *addr
= dlsym(RTLD_DEFAULT
, &name
[s1
->leading_underscore
]);
1058 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD || TARGETOS_ANDROID
1061 for (i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
1062 if ((addr
= dlsym(s1
->loaded_dlls
[i
]->handle
, name
)))
1067 sym
->st_value
= (addr_t
) addr
;
1069 printf ("relocate_sym: %s -> 0x%lx\n", name
, sym
->st_value
);
1074 /* if dynamic symbol exist, it will be used in relocate_section */
1075 } else if (s1
->dynsym
&& find_elf_sym(s1
->dynsym
, name
))
1077 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1079 if (!strcmp(name
, "_fp_hw"))
1081 /* only weak symbols are accepted to be undefined. Their
1083 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
1084 if (sym_bind
== STB_WEAK
)
1087 tcc_error_noabort("undefined symbol '%s'", name
);
1089 } else if (sh_num
< SHN_LORESERVE
) {
1090 /* add section base */
1091 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1097 /* relocate a given section (CPU dependent) by applying the relocations
1098 in the associated relocation section */
1099 static void relocate_section(TCCState
*s1
, Section
*s
, Section
*sr
)
1103 int type
, sym_index
;
1106 int is_dwarf
= s
->sh_num
>= s1
->dwlo
&& s
->sh_num
< s1
->dwhi
;
1108 qrel
= (ElfW_Rel
*)sr
->data
;
1109 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
1110 ptr
= s
->data
+ rel
->r_offset
;
1111 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1112 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1113 type
= ELFW(R_TYPE
)(rel
->r_info
);
1114 tgt
= sym
->st_value
;
1115 #if SHT_RELX == SHT_RELA
1116 tgt
+= rel
->r_addend
;
1118 if (is_dwarf
&& type
== R_DATA_32DW
1119 && sym
->st_shndx
>= s1
->dwlo
&& sym
->st_shndx
< s1
->dwhi
) {
1120 /* dwarf section relocation to each other */
1121 add32le(ptr
, tgt
- s1
->sections
[sym
->st_shndx
]->sh_addr
);
1124 addr
= s
->sh_addr
+ rel
->r_offset
;
1125 relocate(s1
, rel
, type
, ptr
, addr
, tgt
);
1127 #ifndef ELF_OBJ_ONLY
1128 /* if the relocation is allocated, we change its symbol table */
1129 if (sr
->sh_flags
& SHF_ALLOC
) {
1130 sr
->link
= s1
->dynsym
;
1131 if (s1
->output_type
& TCC_OUTPUT_DYN
) {
1132 size_t r
= (uint8_t*)qrel
- sr
->data
;
1133 if (sizeof ((Stab_Sym
*)0)->n_value
< PTR_SIZE
1134 && 0 == strcmp(s
->name
, ".stab"))
1135 r
= 0; /* cannot apply 64bit relocation to 32bit value */
1136 sr
->data_offset
= sr
->sh_size
= r
;
1137 #ifdef CONFIG_TCC_PIE
1138 if (r
&& 0 == (s
->sh_flags
& SHF_WRITE
))
1139 tcc_warning("%d relocations to ro-section %s", (unsigned)(r
/ sizeof *qrel
), s
->name
);
1146 /* relocate all sections */
1147 ST_FUNC
void relocate_sections(TCCState
*s1
)
1152 for (i
= 1; i
< s1
->nb_sections
; ++i
) {
1153 sr
= s1
->sections
[i
];
1154 if (sr
->sh_type
!= SHT_RELX
)
1156 s
= s1
->sections
[sr
->sh_info
];
1157 #ifndef TCC_TARGET_MACHO
1160 || s1
->output_type
== TCC_OUTPUT_MEMORY
)
1163 relocate_section(s1
, s
, sr
);
1165 #ifndef ELF_OBJ_ONLY
1166 if (sr
->sh_flags
& SHF_ALLOC
) {
1168 /* relocate relocation table in 'sr' */
1169 for_each_elem(sr
, 0, rel
, ElfW_Rel
)
1170 rel
->r_offset
+= s
->sh_addr
;
1176 #ifndef ELF_OBJ_ONLY
1177 /* count the number of dynamic relocations so that we can reserve
1179 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
1182 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1183 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1184 defined(TCC_TARGET_RISCV64)
1186 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
1187 int sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1188 int type
= ELFW(R_TYPE
)(rel
->r_info
);
1190 #if defined(TCC_TARGET_I386)
1192 if (!get_sym_attr(s1
, sym_index
, 0)->dyn_index
1193 && ((ElfW(Sym
)*)symtab_section
->data
+ sym_index
)->st_shndx
== SHN_UNDEF
) {
1194 /* don't fixup unresolved (weak) symbols */
1195 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_386_RELATIVE
);
1198 #elif defined(TCC_TARGET_X86_64)
1202 #elif defined(TCC_TARGET_ARM)
1205 #elif defined(TCC_TARGET_ARM64)
1206 case R_AARCH64_ABS32
:
1207 case R_AARCH64_ABS64
:
1208 #elif defined(TCC_TARGET_RISCV64)
1214 #if defined(TCC_TARGET_I386)
1216 #elif defined(TCC_TARGET_X86_64)
1219 ElfW(Sym
) *sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1220 /* Hidden defined symbols can and must be resolved locally.
1221 We're misusing a PLT32 reloc for this, as that's always
1222 resolved to its address even in shared libs. */
1223 if (sym
->st_shndx
!= SHN_UNDEF
&&
1224 ELFW(ST_VISIBILITY
)(sym
->st_other
) == STV_HIDDEN
) {
1225 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PLT32
);
1229 #elif defined(TCC_TARGET_ARM64)
1230 case R_AARCH64_PREL32
:
1232 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1234 if (get_sym_attr(s1
, sym_index
, 0)->dyn_index
)
1246 #ifdef NEED_BUILD_GOT
1247 static int build_got(TCCState
*s1
)
1249 /* if no got, then create it */
1250 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
1251 s1
->got
->sh_entsize
= 4;
1252 /* keep space for _DYNAMIC pointer and two dummy got entries */
1253 section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
1254 return set_elf_sym(symtab_section
, 0, 0, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
1255 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
1258 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1259 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1260 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1261 Returns the offset of the GOT or (if any) PLT entry. */
1262 static struct sym_attr
* put_got_entry(TCCState
*s1
, int dyn_reloc_type
,
1268 struct sym_attr
*attr
;
1269 unsigned got_offset
;
1274 need_plt_entry
= (dyn_reloc_type
== R_JMP_SLOT
);
1275 attr
= get_sym_attr(s1
, sym_index
, 1);
1277 /* In case a function is both called and its address taken 2 GOT entries
1278 are created, one for taking the address (GOT) and the other for the PLT
1280 if (need_plt_entry
? attr
->plt_offset
: attr
->got_offset
)
1284 if (need_plt_entry
) {
1286 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
1287 s1
->plt
->sh_entsize
= 4;
1292 /* create the GOT entry */
1293 got_offset
= s1
->got
->data_offset
;
1294 section_ptr_add(s1
->got
, PTR_SIZE
);
1296 /* Create the GOT relocation that will insert the address of the object or
1297 function of interest in the GOT entry. This is a static relocation for
1298 memory output (dlsym will give us the address of symbols) and dynamic
1299 relocation otherwise (executable and DLLs). The relocation should be
1300 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1301 associated to a PLT entry) but is currently done at load time for an
1304 sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1305 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1306 //printf("sym %d %s\n", need_plt_entry, name);
1309 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
) {
1310 /* Hack alarm. We don't want to emit dynamic symbols
1311 and symbol based relocs for STB_LOCAL symbols, but rather
1312 want to resolve them directly. At this point the symbol
1313 values aren't final yet, so we must defer this. We will later
1314 have to create a RELATIVE reloc anyway, so we misuse the
1315 relocation slot to smuggle the symbol reference until
1316 fill_local_got_entries. Not that the sym_index is
1317 relative to symtab_section, not s1->dynsym! Nevertheless
1318 we use s1->dyn_sym so that if this is the first call
1319 that got->reloc is correctly created. Also note that
1320 RELATIVE relocs are not normally created for the .got,
1321 so the types serves as a marker for later (and is retained
1322 also for the final output, which is okay because then the
1323 got is just normal data). */
1324 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, R_RELATIVE
,
1327 if (0 == attr
->dyn_index
)
1328 attr
->dyn_index
= set_elf_sym(s1
->dynsym
, sym
->st_value
,
1329 sym
->st_size
, sym
->st_info
, 0,
1330 sym
->st_shndx
, name
);
1331 put_elf_reloc(s1
->dynsym
, s_rel
, got_offset
, dyn_reloc_type
,
1335 put_elf_reloc(symtab_section
, s1
->got
, got_offset
, dyn_reloc_type
,
1339 if (need_plt_entry
) {
1340 attr
->plt_offset
= create_plt_entry(s1
, got_offset
, attr
);
1342 /* create a symbol 'sym@plt' for the PLT jump vector */
1344 if (len
> sizeof plt_name
- 5)
1345 len
= sizeof plt_name
- 5;
1346 memcpy(plt_name
, name
, len
);
1347 strcpy(plt_name
+ len
, "@plt");
1348 attr
->plt_sym
= put_elf_sym(s1
->symtab
, attr
->plt_offset
, 0,
1349 ELFW(ST_INFO
)(STB_GLOBAL
, STT_FUNC
), 0, s1
->plt
->sh_num
, plt_name
);
1351 attr
->got_offset
= got_offset
;
1357 /* build GOT and PLT entries */
1358 /* Two passes because R_JMP_SLOT should become first. Some targets
1359 (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1360 ST_FUNC
void build_got_entries(TCCState
*s1
, int got_sym
)
1365 int i
, type
, gotplt_entry
, reloc_type
, sym_index
;
1366 struct sym_attr
*attr
;
1369 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1370 s
= s1
->sections
[i
];
1371 if (s
->sh_type
!= SHT_RELX
)
1373 /* no need to handle got relocations */
1374 if (s
->link
!= symtab_section
)
1376 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1377 type
= ELFW(R_TYPE
)(rel
->r_info
);
1378 gotplt_entry
= gotplt_entry_type(type
);
1379 if (gotplt_entry
== -1) {
1380 tcc_error_noabort ("Unknown relocation type for got: %d", type
);
1383 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1384 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1386 if (gotplt_entry
== NO_GOTPLT_ENTRY
) {
1390 /* Automatically create PLT/GOT [entry] if it is an undefined
1391 reference (resolved at runtime), or the symbol is absolute,
1392 probably created by tcc_add_symbol, and thus on 64-bit
1393 targets might be too far from application code. */
1394 if (gotplt_entry
== AUTO_GOTPLT_ENTRY
) {
1395 if (sym
->st_shndx
== SHN_UNDEF
) {
1398 if (!PCRELATIVE_DLLPLT
1399 && (s1
->output_type
& TCC_OUTPUT_DYN
))
1401 /* Relocations for UNDEF symbols would normally need
1402 to be transferred into the executable or shared object.
1403 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1404 But TCC doesn't do that (at least for exes), so we
1405 need to resolve all such relocs locally. And that
1406 means PLT slots for functions in DLLs and COPY relocs for
1407 data symbols. COPY relocs were generated in
1408 bind_exe_dynsyms (and the symbol adjusted to be defined),
1409 and for functions we were generated a dynamic symbol
1410 of function type. */
1412 /* dynsym isn't set for -run :-/ */
1413 dynindex
= get_sym_attr(s1
, sym_index
, 0)->dyn_index
;
1414 esym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ dynindex
;
1416 && (ELFW(ST_TYPE
)(esym
->st_info
) == STT_FUNC
1417 || (ELFW(ST_TYPE
)(esym
->st_info
) == STT_NOTYPE
1418 && ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
)))
1421 } else if (sym
->st_shndx
== SHN_ABS
) {
1422 if (sym
->st_value
== 0) /* from tcc_add_btstub() */
1424 #ifndef TCC_TARGET_ARM
1428 /* from tcc_add_symbol(): on 64 bit platforms these
1429 need to go through .got */
1434 #ifdef TCC_TARGET_X86_64
1435 if ((type
== R_X86_64_PLT32
|| type
== R_X86_64_PC32
) &&
1436 sym
->st_shndx
!= SHN_UNDEF
&&
1437 (ELFW(ST_VISIBILITY
)(sym
->st_other
) != STV_DEFAULT
||
1438 ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
||
1439 s1
->output_type
& TCC_OUTPUT_EXE
)) {
1442 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PC32
);
1446 reloc_type
= code_reloc(type
);
1447 if (reloc_type
== -1) {
1448 tcc_error_noabort ("Unknown relocation type: %d", type
);
1452 if (reloc_type
!= 0) {
1456 reloc_type
= R_JMP_SLOT
;
1460 reloc_type
= R_GLOB_DAT
;
1464 got_sym
= build_got(s1
);
1466 if (gotplt_entry
== BUILD_GOT_ONLY
)
1469 attr
= put_got_entry(s1
, reloc_type
, sym_index
);
1471 if (reloc_type
== R_JMP_SLOT
)
1472 rel
->r_info
= ELFW(R_INFO
)(attr
->plt_sym
, type
);
1477 /* .rel.plt refers to .got actually */
1478 if (s1
->plt
&& s1
->plt
->reloc
)
1479 s1
->plt
->reloc
->sh_info
= s1
->got
->sh_num
;
1480 if (got_sym
) /* set size */
1481 ((ElfW(Sym
)*)symtab_section
->data
)[got_sym
].st_size
= s1
->got
->data_offset
;
1483 #endif /* def NEED_BUILD_GOT */
1485 ST_FUNC
int set_global_sym(TCCState
*s1
, const char *name
, Section
*sec
, addr_t offs
)
1487 int shn
= sec
? sec
->sh_num
: offs
|| !name
? SHN_ABS
: SHN_UNDEF
;
1488 if (sec
&& offs
== -1)
1489 offs
= sec
->data_offset
;
1490 return set_elf_sym(symtab_section
, offs
, 0,
1491 ELFW(ST_INFO
)(name
? STB_GLOBAL
: STB_LOCAL
, STT_NOTYPE
), 0, shn
, name
);
1494 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1499 s
= have_section(s1
, section_name
);
1500 if (!s
|| !(s
->sh_flags
& SHF_ALLOC
)) {
1504 end_offset
= s
->data_offset
;
1506 snprintf(buf
, sizeof(buf
), "__%s_start", section_name
+ 1);
1507 set_global_sym(s1
, buf
, s
, 0);
1508 snprintf(buf
, sizeof(buf
), "__%s_end", section_name
+ 1);
1509 set_global_sym(s1
, buf
, s
, end_offset
);
1512 ST_FUNC
void add_array (TCCState
*s1
, const char *sec
, int c
)
1515 s
= find_section(s1
, sec
);
1516 s
->sh_flags
= shf_RELRO
;
1517 s
->sh_type
= sec
[1] == 'i' ? SHT_INIT_ARRAY
: SHT_FINI_ARRAY
;
1518 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1519 section_ptr_add(s
, PTR_SIZE
);
1522 #ifdef CONFIG_TCC_BCHECK
1523 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
1525 if (0 == s1
->do_bounds_check
)
1527 section_ptr_add(bounds_section
, sizeof(addr_t
));
1531 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1532 a dynamic symbol to allow so's to have one each with a different value. */
1533 static void set_local_sym(TCCState
*s1
, const char *name
, Section
*s
, int offset
)
1535 int c
= find_elf_sym(s1
->symtab
, name
);
1537 ElfW(Sym
) *esym
= (ElfW(Sym
)*)s1
->symtab
->data
+ c
;
1538 esym
->st_info
= ELFW(ST_INFO
)(STB_LOCAL
, STT_NOTYPE
);
1539 esym
->st_value
= offset
;
1540 esym
->st_shndx
= s
->sh_num
;
1544 /* avoid generating debug/test_coverage code for stub functions */
1545 static void tcc_compile_string_no_debug(TCCState
*s
, const char *str
)
1547 int save_do_debug
= s
->do_debug
;
1548 int save_test_coverage
= s
->test_coverage
;
1551 s
->test_coverage
= 0;
1552 tcc_compile_string(s
, str
);
1553 s
->do_debug
= save_do_debug
;
1554 s
->test_coverage
= save_test_coverage
;
1557 #ifdef CONFIG_TCC_BACKTRACE
1558 static void put_ptr(TCCState
*s1
, Section
*s
, int offs
)
1561 c
= set_global_sym(s1
, NULL
, s
, offs
);
1563 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1564 section_ptr_add(s
, PTR_SIZE
);
1567 ST_FUNC
void tcc_add_btstub(TCCState
*s1
)
1572 const char *__rt_info
= &"___rt_info"[!s1
->leading_underscore
];
1575 /* Align to PTR_SIZE */
1576 section_ptr_add(s
, -s
->data_offset
& (PTR_SIZE
- 1));
1578 /* create a struct rt_context (see tccrun.c) */
1580 put_ptr(s1
, dwarf_line_section
, 0);
1581 put_ptr(s1
, dwarf_line_section
, -1);
1583 put_ptr(s1
, dwarf_line_str_section
, 0);
1585 put_ptr(s1
, dwarf_str_section
, 0);
1589 put_ptr(s1
, stab_section
, 0);
1590 put_ptr(s1
, stab_section
, -1);
1591 put_ptr(s1
, stab_section
->link
, 0);
1594 /* skip esym_start/esym_end/elf_str (not loaded) */
1595 section_ptr_add(s
, 3 * PTR_SIZE
);
1597 if (s1
->output_type
== TCC_OUTPUT_MEMORY
&& 0 == s1
->dwarf
) {
1598 put_ptr(s1
, text_section
, 0);
1600 /* prog_base : local nameless symbol with offset 0 at SHN_ABS */
1601 put_ptr(s1
, NULL
, 0);
1602 #if defined TCC_TARGET_MACHO
1603 /* adjust for __PAGEZERO */
1604 if (s1
->dwarf
== 0 && s1
->output_type
== TCC_OUTPUT_EXE
)
1605 write64le(data_section
->data
+ data_section
->data_offset
- PTR_SIZE
,
1610 #ifdef CONFIG_TCC_BCHECK
1611 if (s1
->do_bounds_check
) {
1612 put_ptr(s1
, bounds_section
, 0);
1616 section_ptr_add(s
, n
);
1617 p
= section_ptr_add(s
, 2 * sizeof (int));
1618 p
[0] = s1
->rt_num_callers
;
1620 // if (s->data_offset - o != 10*PTR_SIZE + 2*sizeof (int)) exit(99);
1622 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
1623 set_global_sym(s1
, __rt_info
, s
, o
);
1629 "extern void __bt_init(),__bt_exit(),__bt_init_dll();"
1630 "static void *__rt_info[];"
1631 "__attribute__((constructor)) static void __bt_init_rt(){");
1632 #ifdef TCC_TARGET_PE
1633 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1634 #ifdef CONFIG_TCC_BCHECK
1635 cstr_printf(&cstr
, "__bt_init_dll(%d);", s1
->do_bounds_check
);
1637 cstr_printf(&cstr
, "__bt_init_dll(0);");
1640 cstr_printf(&cstr
, "__bt_init(__rt_info,%d);}",
1641 s1
->output_type
!= TCC_OUTPUT_DLL
);
1642 /* In case dlcose is called by application */
1644 "__attribute__((destructor)) static void __bt_exit_rt(){"
1645 "__bt_exit(__rt_info);}");
1646 tcc_compile_string_no_debug(s1
, cstr
.data
);
1648 set_local_sym(s1
, __rt_info
, s
, o
);
1650 #endif /* def CONFIG_TCC_BACKTRACE */
1652 static void tcc_tcov_add_file(TCCState
*s1
, const char *filename
)
1658 if (tcov_section
== NULL
)
1660 section_ptr_add(tcov_section
, 1);
1661 write32le (tcov_section
->data
, tcov_section
->data_offset
);
1664 if (filename
[0] == '/')
1665 cstr_printf (&cstr
, "%s.tcov", filename
);
1667 getcwd (wd
, sizeof(wd
));
1668 cstr_printf (&cstr
, "%s/%s.tcov", wd
, filename
);
1670 ptr
= section_ptr_add(tcov_section
, cstr
.size
+ 1);
1671 strcpy((char *)ptr
, cstr
.data
);
1672 unlink((char *)ptr
);
1674 normalize_slashes((char *)ptr
);
1680 "extern char *__tcov_data[];"
1681 "extern void __store_test_coverage ();"
1682 "__attribute__((destructor)) static void __tcov_exit() {"
1683 "__store_test_coverage(__tcov_data);"
1685 tcc_compile_string_no_debug(s1
, cstr
.data
);
1687 set_local_sym(s1
, &"___tcov_data"[!s1
->leading_underscore
], tcov_section
, 0);
1690 #if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO
1691 /* add libc crt1/crti objects */
1692 ST_FUNC
void tccelf_add_crtbegin(TCCState
*s1
)
1694 #if TARGETOS_OpenBSD
1695 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1696 tcc_add_crt(s1
, "crt0.o");
1697 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1698 tcc_add_crt(s1
, "crtbeginS.o");
1700 tcc_add_crt(s1
, "crtbegin.o");
1701 #elif TARGETOS_FreeBSD || TARGETOS_NetBSD
1702 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1703 #if TARGETOS_FreeBSD
1704 tcc_add_crt(s1
, "crt1.o");
1706 tcc_add_crt(s1
, "crt0.o");
1708 tcc_add_crt(s1
, "crti.o");
1709 if (s1
->static_link
)
1710 tcc_add_crt(s1
, "crtbeginT.o");
1711 else if (s1
->output_type
== TCC_OUTPUT_DLL
)
1712 tcc_add_crt(s1
, "crtbeginS.o");
1714 tcc_add_crt(s1
, "crtbegin.o");
1715 #elif TARGETOS_ANDROID
1716 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1717 tcc_add_crt(s1
, "crtbegin_so.o");
1719 tcc_add_crt(s1
, "crtbegin_dynamic.o");
1721 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1722 tcc_add_crt(s1
, "crt1.o");
1723 tcc_add_crt(s1
, "crti.o");
1727 ST_FUNC
void tccelf_add_crtend(TCCState
*s1
)
1729 #if TARGETOS_OpenBSD
1730 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1731 tcc_add_crt(s1
, "crtendS.o");
1733 tcc_add_crt(s1
, "crtend.o");
1734 #elif TARGETOS_FreeBSD || TARGETOS_NetBSD
1735 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1736 tcc_add_crt(s1
, "crtendS.o");
1738 tcc_add_crt(s1
, "crtend.o");
1739 tcc_add_crt(s1
, "crtn.o");
1740 #elif TARGETOS_ANDROID
1741 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1742 tcc_add_crt(s1
, "crtend_so.o");
1744 tcc_add_crt(s1
, "crtend_android.o");
1746 tcc_add_crt(s1
, "crtn.o");
1749 #endif /* !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO */
1751 #ifndef TCC_TARGET_PE
1752 /* add tcc runtime libraries */
1753 ST_FUNC
void tcc_add_runtime(TCCState
*s1
)
1757 #ifdef CONFIG_TCC_BCHECK
1760 tcc_add_pragma_libs(s1
);
1763 if (!s1
->nostdlib
) {
1764 int lpthread
= s1
->option_pthread
;
1766 #ifdef CONFIG_TCC_BCHECK
1767 if (s1
->do_bounds_check
&& s1
->output_type
!= TCC_OUTPUT_DLL
) {
1768 tcc_add_support(s1
, "bcheck.o");
1769 # if !(TARGETOS_OpenBSD || TARGETOS_NetBSD)
1770 tcc_add_library_err(s1
, "dl");
1775 #ifdef CONFIG_TCC_BACKTRACE
1776 if (s1
->do_backtrace
) {
1777 if (s1
->output_type
& TCC_OUTPUT_EXE
)
1778 tcc_add_support(s1
, "bt-exe.o");
1779 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1780 tcc_add_support(s1
, "bt-log.o");
1786 tcc_add_library_err(s1
, "pthread");
1787 tcc_add_library_err(s1
, "c");
1789 if (!s1
->static_link
) {
1790 if (TCC_LIBGCC
[0] == '/')
1791 tcc_add_file(s1
, TCC_LIBGCC
);
1793 tcc_add_dll(s1
, TCC_LIBGCC
, AFF_PRINT_ERROR
);
1796 #if defined TCC_TARGET_ARM && TARGETOS_FreeBSD
1797 tcc_add_library_err(s1
, "gcc_s"); // unwind code
1800 tcc_add_support(s1
, TCC_LIBTCC1
);
1801 #ifndef TCC_TARGET_MACHO
1802 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1803 tccelf_add_crtend(s1
);
1807 #endif /* ndef TCC_TARGET_PE */
1809 /* add various standard linker symbols (must be done after the
1810 sections are filled (for example after allocating common
1812 static void tcc_add_linker_symbols(TCCState
*s1
)
1818 set_global_sym(s1
, "_etext", text_section
, -1);
1819 set_global_sym(s1
, "_edata", data_section
, -1);
1820 set_global_sym(s1
, "_end", bss_section
, -1);
1821 #if TARGETOS_OpenBSD
1822 set_global_sym(s1
, "__executable_start", NULL
, ELF_START_ADDR
);
1824 #ifdef TCC_TARGET_RISCV64
1825 /* XXX should be .sdata+0x800, not .data+0x800 */
1826 set_global_sym(s1
, "__global_pointer$", data_section
, 0x800);
1828 /* horrible new standard ldscript defines */
1829 add_init_array_defines(s1
, ".preinit_array");
1830 add_init_array_defines(s1
, ".init_array");
1831 add_init_array_defines(s1
, ".fini_array");
1832 /* add start and stop symbols for sections whose name can be
1834 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1835 s
= s1
->sections
[i
];
1836 if ((s
->sh_flags
& SHF_ALLOC
)
1837 && (s
->sh_type
== SHT_PROGBITS
1838 || s
->sh_type
== SHT_STRTAB
)) {
1840 /* check if section name can be expressed in C */
1846 if (!isid(c
) && !isnum(c
))
1850 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1851 set_global_sym(s1
, buf
, s
, 0);
1852 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1853 set_global_sym(s1
, buf
, s
, -1);
1859 ST_FUNC
void resolve_common_syms(TCCState
*s1
)
1863 /* Allocate common symbols in BSS. */
1864 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1865 if (sym
->st_shndx
== SHN_COMMON
) {
1866 /* symbol alignment is in st_value for SHN_COMMONs */
1867 sym
->st_value
= section_add(bss_section
, sym
->st_size
,
1869 sym
->st_shndx
= bss_section
->sh_num
;
1873 /* Now assign linker provided symbols their value. */
1874 tcc_add_linker_symbols(s1
);
1877 #ifndef ELF_OBJ_ONLY
1878 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1880 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1881 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1882 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1883 unsigned offset
= attr
->got_offset
;
1887 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1889 write64le(s1
->got
->data
+ offset
, sym
->st_value
);
1891 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1895 /* Perform relocation to GOT or PLT entries */
1896 ST_FUNC
void fill_got(TCCState
*s1
)
1902 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1903 s
= s1
->sections
[i
];
1904 if (s
->sh_type
!= SHT_RELX
)
1906 /* no need to handle got relocations */
1907 if (s
->link
!= symtab_section
)
1909 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1910 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1911 case R_X86_64_GOT32
:
1912 case R_X86_64_GOTPCREL
:
1913 case R_X86_64_GOTPCRELX
:
1914 case R_X86_64_REX_GOTPCRELX
:
1915 case R_X86_64_PLT32
:
1916 fill_got_entry(s1
, rel
);
1923 /* See put_got_entry for a description. This is the second stage
1924 where GOT references to local defined symbols are rewritten. */
1925 static void fill_local_got_entries(TCCState
*s1
)
1928 if (!s1
->got
->reloc
)
1930 for_each_elem(s1
->got
->reloc
, 0, rel
, ElfW_Rel
) {
1931 if (ELFW(R_TYPE
)(rel
->r_info
) == R_RELATIVE
) {
1932 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1933 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1934 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1935 unsigned offset
= attr
->got_offset
;
1936 if (offset
!= rel
->r_offset
- s1
->got
->sh_addr
)
1937 tcc_error_noabort("fill_local_got_entries: huh?");
1938 rel
->r_info
= ELFW(R_INFO
)(0, R_RELATIVE
);
1939 #if SHT_RELX == SHT_RELA
1940 rel
->r_addend
= sym
->st_value
;
1942 /* All our REL architectures also happen to be 32bit LE. */
1943 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1949 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1950 in shared libraries */
1951 static void bind_exe_dynsyms(TCCState
*s1
, int is_PIE
)
1954 int sym_index
, index
;
1955 ElfW(Sym
) *sym
, *esym
;
1958 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1959 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1960 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1961 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1962 if (sym
->st_shndx
== SHN_UNDEF
) {
1963 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1964 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1968 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1969 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1970 if ((type
== STT_FUNC
) || (type
== STT_GNU_IFUNC
)) {
1971 /* Indirect functions shall have STT_FUNC type in executable
1972 * dynsym section. Indeed, a dlsym call following a lazy
1973 * resolution would pick the symbol value from the
1974 * executable dynsym entry which would contain the address
1975 * of the function wanted by the caller of dlsym instead of
1976 * the address of the function that would return that
1979 = put_elf_sym(s1
->dynsym
, 0, esym
->st_size
,
1980 ELFW(ST_INFO
)(STB_GLOBAL
,STT_FUNC
), 0, 0,
1982 int index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1983 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1984 } else if (type
== STT_OBJECT
) {
1985 unsigned long offset
;
1987 offset
= bss_section
->data_offset
;
1988 /* XXX: which alignment ? */
1989 offset
= (offset
+ 16 - 1) & -16;
1990 set_elf_sym (s1
->symtab
, offset
, esym
->st_size
,
1991 esym
->st_info
, 0, bss_section
->sh_num
, name
);
1992 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1993 esym
->st_info
, 0, bss_section
->sh_num
,
1996 /* Ensure R_COPY works for weak symbol aliases */
1997 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1998 for_each_elem(s1
->dynsymtab_section
, 1, dynsym
, ElfW(Sym
)) {
1999 if ((dynsym
->st_value
== esym
->st_value
)
2000 && (ELFW(ST_BIND
)(dynsym
->st_info
) == STB_GLOBAL
)) {
2001 char *dynname
= (char *) s1
->dynsymtab_section
->link
->data
2003 put_elf_sym(s1
->dynsym
, offset
, dynsym
->st_size
,
2005 bss_section
->sh_num
, dynname
);
2011 put_elf_reloc(s1
->dynsym
, bss_section
,
2012 offset
, R_COPY
, index
);
2013 offset
+= esym
->st_size
;
2014 bss_section
->data_offset
= offset
;
2017 /* STB_WEAK undefined symbols are accepted */
2018 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
2019 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
2020 !strcmp(name
, "_fp_hw")) {
2022 tcc_error_noabort("undefined symbol '%s'", name
);
2029 /* Bind symbols of libraries: export all non local symbols of executable that
2030 are referenced by shared libraries. The reason is that the dynamic loader
2031 search symbol first in executable and then in libraries. Therefore a
2032 reference to a symbol already defined by a library can still be resolved by
2033 a symbol in the executable. With -rdynamic, export all defined symbols */
2034 static void bind_libs_dynsyms(TCCState
*s1
)
2038 ElfW(Sym
) *sym
, *esym
;
2040 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
2041 name
= (char *)symtab_section
->link
->data
+ sym
->st_name
;
2042 dynsym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
2043 if (sym
->st_shndx
!= SHN_UNDEF
) {
2044 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
2045 && (dynsym_index
|| s1
->rdynamic
))
2046 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
2047 sym
->st_info
, 0, sym
->st_shndx
, name
);
2048 } else if (dynsym_index
) {
2049 esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ dynsym_index
;
2050 if (esym
->st_shndx
== SHN_UNDEF
) {
2051 /* weak symbols can stay undefined */
2052 if (ELFW(ST_BIND
)(esym
->st_info
) != STB_WEAK
)
2053 tcc_warning("undefined dynamic symbol '%s'", name
);
2059 /* Export all non local symbols. This is used by shared libraries so that the
2060 non local symbols they define can resolve a reference in another shared
2061 library or in the executable. Correspondingly, it allows undefined local
2062 symbols to be resolved by other shared libraries or by the executable. */
2063 static void export_global_syms(TCCState
*s1
)
2065 int dynindex
, index
;
2068 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
2069 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2070 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
2071 dynindex
= set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
2072 sym
->st_info
, 0, sym
->st_shndx
, name
);
2073 index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
2074 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
2079 /* decide if an unallocated section should be output. */
2080 static int set_sec_sizes(TCCState
*s1
)
2085 int file_type
= s1
->output_type
;
2087 /* Allocate strings for section names */
2088 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2089 s
= s1
->sections
[i
];
2090 if (s
->sh_type
== SHT_RELX
&& !(s
->sh_flags
& SHF_ALLOC
)) {
2091 /* when generating a DLL, we include relocations but
2092 we may patch them */
2093 if ((file_type
& TCC_OUTPUT_DYN
)
2094 && (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)) {
2095 int count
= prepare_dynamic_rel(s1
, s
);
2097 /* allocate the section */
2098 s
->sh_flags
|= SHF_ALLOC
;
2099 s
->sh_size
= count
* sizeof(ElfW_Rel
);
2100 if (!(s1
->sections
[s
->sh_info
]->sh_flags
& SHF_WRITE
))
2104 } else if ((s
->sh_flags
& SHF_ALLOC
)
2105 #ifdef TCC_TARGET_ARM
2106 || s
->sh_type
== SHT_ARM_ATTRIBUTES
2109 s
->sh_size
= s
->data_offset
;
2112 #ifdef TCC_TARGET_ARM
2113 /* XXX: Suppress stack unwinding section. */
2114 if (s
->sh_type
== SHT_ARM_EXIDX
) {
2124 /* various data used under elf_output_file() */
2129 /* Info to be copied in dynamic section */
2130 unsigned long data_offset
;
2141 /* read only segment mapping for GNU_RELRO */
2142 Section _roinf
, *roinf
;
2145 /* Decide the layout of sections loaded in memory. This must be done before
2146 program headers are filled since they contain info about the layout.
2147 We do the following ordering: interp, symbol tables, relocations, progbits,
2149 static int sort_sections(TCCState
*s1
, int *sec_order
, Section
*interp
)
2152 int i
, j
, k
, f
, f0
, n
;
2153 int nb_sections
= s1
->nb_sections
;
2154 int *sec_cls
= sec_order
+ nb_sections
;
2156 for (i
= 1; i
< nb_sections
; i
++) {
2157 s
= s1
->sections
[i
];
2158 if (s
->sh_flags
& SHF_ALLOC
) {
2160 if (s
->sh_flags
& SHF_WRITE
)
2162 if (s
->sh_flags
& SHF_TLS
)
2164 } else if (s
->sh_name
) {
2167 j
= 0x900; /* no sh_name: won't go to file */
2169 if (s
->sh_type
== SHT_SYMTAB
|| s
->sh_type
== SHT_DYNSYM
) {
2171 } else if (s
->sh_type
== SHT_STRTAB
&& strcmp(s
->name
, ".stabstr")) {
2173 if (i
== nb_sections
- 1) /* ".shstrtab" assumed to remain last */
2175 } else if (s
->sh_type
== SHT_HASH
|| s
->sh_type
== SHT_GNU_HASH
) {
2177 } else if (s
->sh_type
== SHT_RELX
) {
2179 if (s1
->plt
&& s
== s1
->plt
->reloc
)
2181 } else if (s
->sh_type
== SHT_PREINIT_ARRAY
) {
2183 } else if (s
->sh_type
== SHT_INIT_ARRAY
) {
2185 } else if (s
->sh_type
== SHT_FINI_ARRAY
) {
2187 #ifdef CONFIG_TCC_BCHECK
2188 } else if (s
== bounds_section
|| s
== lbounds_section
) {
2191 } else if (s
== rodata_section
|| 0 == strcmp(s
->name
, ".data.rel.ro")) {
2193 } else if (s
->sh_type
== SHT_DYNAMIC
) {
2195 } else if (s
== s1
->got
) {
2196 k
= 0x47; /* .got as RELRO needs BIND_NOW in DT_FLAGS */
2199 if (s
->sh_type
== SHT_NOTE
)
2201 if (s
->sh_flags
& SHF_EXECINSTR
)
2203 if (s
->sh_type
== SHT_NOBITS
)
2210 for (n
= i
; n
> 1 && k
< (f
= sec_cls
[n
- 1]); --n
)
2211 sec_cls
[n
] = f
, sec_order
[n
] = sec_order
[n
- 1];
2212 sec_cls
[n
] = k
, sec_order
[n
] = i
;
2216 /* count PT_LOAD headers needed */
2218 for (i
= 1; i
< nb_sections
; i
++) {
2219 s
= s1
->sections
[sec_order
[i
]];
2223 f
= s
->sh_flags
& (SHF_ALLOC
|SHF_WRITE
|SHF_EXECINSTR
|SHF_TLS
);
2225 /* NetBSD only supports 2 PT_LOAD sections.
2226 See: https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */
2227 if ((f
& SHF_WRITE
) == 0) f
|= SHF_EXECINSTR
;
2229 if ((k
& 0xfff0) == 0x240) /* RELRO sections */
2232 if (f
!= f0
) /* start new header when flags changed or relro */
2233 f0
= f
, ++n
, f
|= 1<<8;
2236 //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);
2241 static ElfW(Phdr
) *fill_phdr(ElfW(Phdr
) *ph
, int type
, Section
*s
)
2244 ph
->p_offset
= s
->sh_offset
;
2245 ph
->p_vaddr
= s
->sh_addr
;
2246 ph
->p_filesz
= s
->sh_size
;
2247 ph
->p_align
= s
->sh_addralign
;
2251 ph
->p_paddr
= ph
->p_vaddr
;
2252 ph
->p_memsz
= ph
->p_filesz
;
2256 /* Assign sections to segments and decide how are sections laid out when loaded
2257 in memory. This function also fills corresponding program headers. */
2258 static int layout_sections(TCCState
*s1
, int *sec_order
, struct dyn_inf
*d
)
2261 addr_t addr
, tmp
, align
, s_align
, base
;
2262 ElfW(Phdr
) *ph
= NULL
;
2263 int i
, f
, n
, phnum
, phfill
;
2266 /* compute number of program headers */
2267 phnum
= sort_sections(s1
, sec_order
, d
->interp
);
2268 phfill
= 0; /* set to 1 to have dll's with a PT_PHDR */
2279 d
->phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
2282 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2283 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2285 s_align
= ELF_PAGE_SIZE
;
2286 if (s1
->section_align
)
2287 s_align
= s1
->section_align
;
2289 addr
= ELF_START_ADDR
;
2290 if (s1
->output_type
& TCC_OUTPUT_DYN
)
2293 if (s1
->has_text_addr
) {
2294 addr
= s1
->text_addr
;
2296 int a_offset
, p_offset
;
2297 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
2299 a_offset
= (int) (addr
& (s_align
- 1));
2300 p_offset
= file_offset
& (s_align
- 1);
2301 if (a_offset
< p_offset
)
2302 a_offset
+= s_align
;
2303 file_offset
+= (a_offset
- p_offset
);
2307 /* compute address after headers */
2308 addr
= addr
+ (file_offset
& (s_align
- 1));
2311 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2312 s
= s1
->sections
[sec_order
[i
]];
2313 f
= sec_order
[i
+ s1
->nb_sections
];
2314 align
= s
->sh_addralign
- 1;
2316 if (f
== 0) { /* no alloc */
2317 file_offset
= (file_offset
+ align
) & ~align
;
2318 s
->sh_offset
= file_offset
;
2319 if (s
->sh_type
!= SHT_NOBITS
)
2320 file_offset
+= s
->sh_size
;
2324 if ((f
& 1<<8) && n
) {
2325 /* different rwx section flags */
2326 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
2327 /* if in the middle of a page, w e duplicate the page in
2328 memory so that one copy is RX and the other is RW */
2329 if ((addr
& (s_align
- 1)) != 0)
2332 align
= s_align
- 1;
2337 addr
= (addr
+ align
) & ~align
;
2338 file_offset
+= (int)(addr
- tmp
);
2339 s
->sh_offset
= file_offset
;
2343 /* set new program header */
2344 ph
= &d
->phdr
[phfill
+ n
];
2345 ph
->p_type
= PT_LOAD
;
2346 ph
->p_align
= s_align
;
2349 ph
->p_flags
|= PF_W
;
2350 if (f
& SHF_EXECINSTR
)
2351 ph
->p_flags
|= PF_X
;
2353 ph
->p_type
= PT_TLS
;
2354 ph
->p_align
= align
+ 1;
2357 ph
->p_offset
= file_offset
;
2360 /* Make the first PT_LOAD segment include the program
2361 headers itself (and the ELF header as well), it'll
2362 come out with same memory use but will make various
2363 tools like binutils strip work better. */
2367 ph
->p_paddr
= ph
->p_vaddr
;
2372 Section
*roinf
= &d
->_roinf
;
2373 if (roinf
->sh_size
== 0) {
2374 roinf
->sh_offset
= s
->sh_offset
;
2375 roinf
->sh_addr
= s
->sh_addr
;
2376 roinf
->sh_addralign
= 1;
2378 roinf
->sh_size
= (addr
- roinf
->sh_addr
) + s
->sh_size
;
2382 if (s
->sh_type
!= SHT_NOBITS
)
2383 file_offset
+= s
->sh_size
;
2385 ph
->p_filesz
= file_offset
- ph
->p_offset
;
2386 ph
->p_memsz
= addr
- ph
->p_vaddr
;
2389 /* Fill other headers */
2391 fill_phdr(++ph
, PT_NOTE
, d
->note
);
2393 fill_phdr(++ph
, PT_DYNAMIC
, d
->dynamic
)->p_flags
|= PF_W
;
2395 fill_phdr(++ph
, PT_GNU_RELRO
, d
->roinf
)->p_flags
|= PF_W
;
2397 fill_phdr(&d
->phdr
[1], PT_INTERP
, d
->interp
);
2400 ph
->p_offset
= sizeof(ElfW(Ehdr
));
2401 ph
->p_vaddr
= base
+ ph
->p_offset
;
2402 ph
->p_filesz
= phnum
* sizeof(ElfW(Phdr
));
2404 fill_phdr(ph
, PT_PHDR
, NULL
);
2409 /* put dynamic tag */
2410 static void put_dt(Section
*dynamic
, int dt
, addr_t val
)
2413 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
2415 dyn
->d_un
.d_val
= val
;
2418 /* Fill the dynamic section with tags describing the address and size of
2420 static void fill_dynamic(TCCState
*s1
, struct dyn_inf
*dyninf
)
2422 Section
*dynamic
= dyninf
->dynamic
;
2425 /* put dynamic section entries */
2426 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
2427 put_dt(dynamic
, DT_GNU_HASH
, dyninf
->gnu_hash
->sh_addr
);
2428 put_dt(dynamic
, DT_STRTAB
, dyninf
->dynstr
->sh_addr
);
2429 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
2430 put_dt(dynamic
, DT_STRSZ
, dyninf
->dynstr
->data_offset
);
2431 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
2433 put_dt(dynamic
, DT_RELA
, dyninf
->rel_addr
);
2434 put_dt(dynamic
, DT_RELASZ
, dyninf
->rel_size
);
2435 put_dt(dynamic
, DT_RELAENT
, 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_RELA
);
2442 put_dt(dynamic
, DT_RELACOUNT
, 0);
2444 put_dt(dynamic
, DT_REL
, dyninf
->rel_addr
);
2445 put_dt(dynamic
, DT_RELSZ
, dyninf
->rel_size
);
2446 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
2447 if (s1
->plt
&& s1
->plt
->reloc
) {
2448 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2449 put_dt(dynamic
, DT_PLTRELSZ
, s1
->plt
->reloc
->data_offset
);
2450 put_dt(dynamic
, DT_JMPREL
, s1
->plt
->reloc
->sh_addr
);
2451 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
2453 put_dt(dynamic
, DT_RELCOUNT
, 0);
2455 if (versym_section
&& verneed_section
) {
2456 /* The dynamic linker can not handle VERSYM without VERNEED */
2457 put_dt(dynamic
, DT_VERSYM
, versym_section
->sh_addr
);
2458 put_dt(dynamic
, DT_VERNEED
, verneed_section
->sh_addr
);
2459 put_dt(dynamic
, DT_VERNEEDNUM
, dt_verneednum
);
2461 s
= have_section(s1
, ".preinit_array");
2462 if (s
&& s
->data_offset
) {
2463 put_dt(dynamic
, DT_PREINIT_ARRAY
, s
->sh_addr
);
2464 put_dt(dynamic
, DT_PREINIT_ARRAYSZ
, s
->data_offset
);
2466 s
= have_section(s1
, ".init_array");
2467 if (s
&& s
->data_offset
) {
2468 put_dt(dynamic
, DT_INIT_ARRAY
, s
->sh_addr
);
2469 put_dt(dynamic
, DT_INIT_ARRAYSZ
, s
->data_offset
);
2471 s
= have_section(s1
, ".fini_array");
2472 if (s
&& s
->data_offset
) {
2473 put_dt(dynamic
, DT_FINI_ARRAY
, s
->sh_addr
);
2474 put_dt(dynamic
, DT_FINI_ARRAYSZ
, s
->data_offset
);
2476 s
= have_section(s1
, ".init");
2477 if (s
&& s
->data_offset
) {
2478 put_dt(dynamic
, DT_INIT
, s
->sh_addr
);
2480 s
= have_section(s1
, ".fini");
2481 if (s
&& s
->data_offset
) {
2482 put_dt(dynamic
, DT_FINI
, s
->sh_addr
);
2485 put_dt(dynamic
, DT_DEBUG
, 0);
2486 put_dt(dynamic
, DT_NULL
, 0);
2489 /* Remove gaps between RELX sections.
2490 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2491 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2492 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2493 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2494 static void update_reloc_sections(TCCState
*s1
, struct dyn_inf
*dyninf
)
2497 unsigned long file_offset
= 0;
2499 Section
*relocplt
= s1
->plt
? s1
->plt
->reloc
: NULL
;
2501 /* dynamic relocation table information, for .dynamic section */
2502 dyninf
->rel_addr
= dyninf
->rel_size
= 0;
2504 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2505 s
= s1
->sections
[i
];
2506 if (s
->sh_type
== SHT_RELX
&& s
!= relocplt
) {
2507 if (dyninf
->rel_size
== 0) {
2508 dyninf
->rel_addr
= s
->sh_addr
;
2509 file_offset
= s
->sh_offset
;
2512 s
->sh_addr
= dyninf
->rel_addr
+ dyninf
->rel_size
;
2513 s
->sh_offset
= file_offset
+ dyninf
->rel_size
;
2515 dyninf
->rel_size
+= s
->sh_size
;
2520 static int tidy_section_headers(TCCState
*s1
, int *sec_order
);
2521 #endif /* ndef ELF_OBJ_ONLY */
2523 /* Create an ELF file on disk.
2524 This function handle ELF specific layout requirements */
2525 static int tcc_output_elf(TCCState
*s1
, FILE *f
, int phnum
, ElfW(Phdr
) *phdr
,
2526 int file_offset
, int *sec_order
)
2528 int i
, shnum
, offset
, size
, file_type
;
2531 ElfW(Shdr
) shdr
, *sh
;
2533 file_type
= s1
->output_type
;
2534 shnum
= s1
->nb_sections
;
2536 memset(&ehdr
, 0, sizeof(ehdr
));
2539 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2540 ehdr
.e_phnum
= phnum
;
2541 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2542 #ifndef ELF_OBJ_ONLY
2543 shnum
= tidy_section_headers(s1
, sec_order
);
2548 file_offset
= (file_offset
+ 3) & -4;
2551 ehdr
.e_ident
[0] = ELFMAG0
;
2552 ehdr
.e_ident
[1] = ELFMAG1
;
2553 ehdr
.e_ident
[2] = ELFMAG2
;
2554 ehdr
.e_ident
[3] = ELFMAG3
;
2555 ehdr
.e_ident
[4] = ELFCLASSW
;
2556 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2557 ehdr
.e_ident
[6] = EV_CURRENT
;
2559 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2560 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2561 #elif defined TCC_TARGET_ARM && defined TCC_ARM_EABI
2562 ehdr
.e_flags
= EF_ARM_EABI_VER5
;
2563 ehdr
.e_flags
|= s1
->float_abi
== ARM_HARD_FLOAT
2564 ? EF_ARM_VFP_FLOAT
: EF_ARM_SOFT_FLOAT
;
2565 #elif defined TCC_TARGET_ARM
2566 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2567 #elif defined TCC_TARGET_RISCV64
2568 /* XXX should be configurable */
2569 ehdr
.e_flags
= EF_RISCV_FLOAT_ABI_DOUBLE
;
2572 if (file_type
== TCC_OUTPUT_OBJ
) {
2573 ehdr
.e_type
= ET_REL
;
2575 if (file_type
& TCC_OUTPUT_DYN
)
2576 ehdr
.e_type
= ET_DYN
;
2578 ehdr
.e_type
= ET_EXEC
;
2579 if (s1
->elf_entryname
)
2580 ehdr
.e_entry
= get_sym_addr(s1
, s1
->elf_entryname
, 1, 0);
2582 ehdr
.e_entry
= get_sym_addr(s1
, "_start", !!(file_type
& TCC_OUTPUT_EXE
), 0);
2583 if (ehdr
.e_entry
== (addr_t
)-1)
2584 ehdr
.e_entry
= text_section
->sh_addr
;
2589 ehdr
.e_machine
= EM_TCC_TARGET
;
2590 ehdr
.e_version
= EV_CURRENT
;
2591 ehdr
.e_shoff
= file_offset
;
2592 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2593 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2594 ehdr
.e_shnum
= shnum
;
2595 ehdr
.e_shstrndx
= shnum
- 1;
2597 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2599 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2600 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2602 sort_syms(s1
, symtab_section
);
2604 for(i
= 1; i
< shnum
; i
++) {
2605 s
= s1
->sections
[sec_order
? sec_order
[i
] : i
];
2606 if (s
->sh_type
!= SHT_NOBITS
) {
2607 while (offset
< s
->sh_offset
) {
2613 fwrite(s
->data
, 1, size
, f
);
2618 /* output section headers */
2619 while (offset
< ehdr
.e_shoff
) {
2624 for(i
= 0; i
< shnum
; i
++) {
2626 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2627 s
= s1
->sections
[i
];
2629 sh
->sh_name
= s
->sh_name
;
2630 sh
->sh_type
= s
->sh_type
;
2631 sh
->sh_flags
= s
->sh_flags
;
2632 sh
->sh_entsize
= s
->sh_entsize
;
2633 sh
->sh_info
= s
->sh_info
;
2635 sh
->sh_link
= s
->link
->sh_num
;
2636 sh
->sh_addralign
= s
->sh_addralign
;
2637 sh
->sh_addr
= s
->sh_addr
;
2638 sh
->sh_offset
= s
->sh_offset
;
2639 sh
->sh_size
= s
->sh_size
;
2641 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2646 static int tcc_output_binary(TCCState
*s1
, FILE *f
,
2647 const int *sec_order
)
2650 int i
, offset
, size
;
2653 for(i
=1;i
<s1
->nb_sections
;i
++) {
2654 s
= s1
->sections
[sec_order
[i
]];
2655 if (s
->sh_type
!= SHT_NOBITS
&&
2656 (s
->sh_flags
& SHF_ALLOC
)) {
2657 while (offset
< s
->sh_offset
) {
2662 fwrite(s
->data
, 1, size
, f
);
2669 /* Write an elf, coff or "binary" file */
2670 static int tcc_write_elf_file(TCCState
*s1
, const char *filename
, int phnum
,
2671 ElfW(Phdr
) *phdr
, int file_offset
, int *sec_order
)
2673 int fd
, mode
, file_type
, ret
;
2676 file_type
= s1
->output_type
;
2677 if (file_type
== TCC_OUTPUT_OBJ
)
2682 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2683 if (fd
< 0 || (f
= fdopen(fd
, "wb")) == NULL
)
2684 return tcc_error_noabort("could not write '%s: %s'", filename
, strerror(errno
));
2686 printf("<- %s\n", filename
);
2687 #ifdef TCC_TARGET_COFF
2688 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
)
2689 tcc_output_coff(s1
, f
);
2692 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2693 ret
= tcc_output_elf(s1
, f
, phnum
, phdr
, file_offset
, sec_order
);
2695 ret
= tcc_output_binary(s1
, f
, sec_order
);
2701 #ifndef ELF_OBJ_ONLY
2702 /* Sort section headers by assigned sh_addr, remove sections
2703 that we aren't going to output. */
2704 static int tidy_section_headers(TCCState
*s1
, int *sec_order
)
2706 int i
, nnew
, l
, *backmap
;
2710 snew
= tcc_malloc(s1
->nb_sections
* sizeof(snew
[0]));
2711 backmap
= tcc_malloc(s1
->nb_sections
* sizeof(backmap
[0]));
2712 for (i
= 0, nnew
= 0, l
= s1
->nb_sections
; i
< s1
->nb_sections
; i
++) {
2713 s
= s1
->sections
[sec_order
[i
]];
2714 if (!i
|| s
->sh_name
) {
2715 backmap
[sec_order
[i
]] = nnew
;
2719 backmap
[sec_order
[i
]] = 0;
2723 for (i
= 0; i
< nnew
; i
++) {
2727 if (s
->sh_type
== SHT_RELX
)
2728 s
->sh_info
= backmap
[s
->sh_info
];
2732 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
))
2733 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2734 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2735 if ( !s1
->static_link
) {
2736 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
))
2737 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2738 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2740 for (i
= 0; i
< s1
->nb_sections
; i
++)
2742 tcc_free(s1
->sections
);
2743 s1
->sections
= snew
;
2748 #ifdef TCC_TARGET_ARM
2749 static void create_arm_attribute_section(TCCState
*s1
)
2751 // Needed for DLL support.
2752 static const unsigned char arm_attr
[] = {
2754 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2755 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2756 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2757 0x05, 0x36, 0x00, // 'CPU_name', "6"
2758 0x06, 0x06, // 'CPU_arch', 'v6'
2759 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2760 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2761 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2762 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2763 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2764 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2765 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2766 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2767 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2768 0x1a, 0x02, // 'ABI_enum_size', 'int'
2769 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2770 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2772 Section
*attr
= new_section(s1
, ".ARM.attributes", SHT_ARM_ATTRIBUTES
, 0);
2773 unsigned char *ptr
= section_ptr_add(attr
, sizeof(arm_attr
));
2774 attr
->sh_addralign
= 1;
2775 memcpy(ptr
, arm_attr
, sizeof(arm_attr
));
2776 if (s1
->float_abi
!= ARM_HARD_FLOAT
) {
2777 ptr
[26] = 0x00; // 'FP_arch', 'No'
2778 ptr
[41] = 0x1e; // 'ABI_optimization_goals'
2779 ptr
[42] = 0x06; // 'Aggressive Debug'
2784 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2785 static Section
*create_bsd_note_section(TCCState
*s1
,
2789 Section
*s
= find_section (s1
, name
);
2791 if (s
->data_offset
== 0) {
2792 char *ptr
= section_ptr_add(s
, sizeof(ElfW(Nhdr
)) + 8 + 4);
2793 ElfW(Nhdr
) *note
= (ElfW(Nhdr
) *) ptr
;
2795 s
->sh_type
= SHT_NOTE
;
2798 note
->n_type
= ELF_NOTE_OS_GNU
;
2799 strcpy (ptr
+ sizeof(ElfW(Nhdr
)), value
);
2805 static void alloc_sec_names(TCCState
*s1
, int is_obj
);
2807 /* Output an elf, coff or binary file */
2808 /* XXX: suppress unneeded sections */
2809 static int elf_output_file(TCCState
*s1
, const char *filename
)
2811 int i
, ret
, file_type
, file_offset
, *sec_order
;
2812 struct dyn_inf dyninf
= {0};
2813 Section
*interp
, *dynstr
, *dynamic
;
2814 int textrel
, got_sym
, dt_flags_1
;
2816 file_type
= s1
->output_type
;
2819 interp
= dynstr
= dynamic
= NULL
;
2821 dyninf
.roinf
= &dyninf
._roinf
;
2823 #ifdef TCC_TARGET_ARM
2824 create_arm_attribute_section (s1
);
2827 #if TARGETOS_OpenBSD
2828 dyninf
.note
= create_bsd_note_section (s1
, ".note.openbsd.ident", "OpenBSD");
2832 dyninf
.note
= create_bsd_note_section (s1
, ".note.netbsd.ident", "NetBSD");
2835 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
2836 dyninf
.roinf
= NULL
;
2838 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2839 tcc_add_runtime(s1
);
2840 resolve_common_syms(s1
);
2842 if (!s1
->static_link
) {
2843 if (file_type
& TCC_OUTPUT_EXE
) {
2845 /* allow override the dynamic loader */
2846 const char *elfint
= getenv("LD_SO");
2848 elfint
= DEFAULT_ELFINTERP(s1
);
2849 /* add interpreter section only if executable */
2850 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
2851 interp
->sh_addralign
= 1;
2852 ptr
= section_ptr_add(interp
, 1 + strlen(elfint
));
2853 strcpy(ptr
, elfint
);
2854 dyninf
.interp
= interp
;
2857 /* add dynamic symbol table */
2858 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
2860 ".hash", SHF_ALLOC
);
2861 /* Number of local symbols (readelf complains if not set) */
2862 s1
->dynsym
->sh_info
= 1;
2863 dynstr
= s1
->dynsym
->link
;
2864 /* add dynamic section */
2865 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
2866 SHF_ALLOC
| SHF_WRITE
);
2867 dynamic
->link
= dynstr
;
2868 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
2870 got_sym
= build_got(s1
);
2871 if (file_type
& TCC_OUTPUT_EXE
) {
2872 bind_exe_dynsyms(s1
, file_type
& TCC_OUTPUT_DYN
);
2876 build_got_entries(s1
, got_sym
);
2877 if (file_type
& TCC_OUTPUT_EXE
) {
2878 bind_libs_dynsyms(s1
);
2880 /* shared library case: simply export all global symbols */
2881 export_global_syms(s1
);
2883 dyninf
.gnu_hash
= create_gnu_hash(s1
);
2885 build_got_entries(s1
, 0);
2889 textrel
= set_sec_sizes(s1
);
2890 alloc_sec_names(s1
, 0);
2892 if (!s1
->static_link
) {
2893 /* add a list of needed dlls */
2894 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2895 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
2896 if (dllref
->level
== 0)
2897 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
2901 put_dt(dynamic
, s1
->enable_new_dtags
? DT_RUNPATH
: DT_RPATH
,
2902 put_elf_str(dynstr
, s1
->rpath
));
2904 dt_flags_1
= DF_1_NOW
;
2905 if (file_type
& TCC_OUTPUT_DYN
) {
2907 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
2908 /* XXX: currently, since we do not handle PIC code, we
2909 must relocate the readonly segments */
2911 put_dt(dynamic
, DT_TEXTREL
, 0);
2912 if (file_type
& TCC_OUTPUT_EXE
)
2913 dt_flags_1
= DF_1_NOW
| DF_1_PIE
;
2915 put_dt(dynamic
, DT_FLAGS
, DF_BIND_NOW
);
2916 put_dt(dynamic
, DT_FLAGS_1
, dt_flags_1
);
2918 put_dt(dynamic
, DT_SYMBOLIC
, 0);
2920 dyninf
.dynamic
= dynamic
;
2921 dyninf
.dynstr
= dynstr
;
2922 /* remember offset and reserve space for 2nd call below */
2923 dyninf
.data_offset
= dynamic
->data_offset
;
2924 fill_dynamic(s1
, &dyninf
);
2925 dynamic
->sh_size
= dynamic
->data_offset
;
2926 dynstr
->sh_size
= dynstr
->data_offset
;
2929 /* this array is used to reorder sections in the output file */
2930 sec_order
= tcc_malloc(sizeof(int) * 2 * s1
->nb_sections
);
2931 /* compute section to program header mapping */
2932 file_offset
= layout_sections(s1
, sec_order
, &dyninf
);
2935 /* put in GOT the dynamic section address and relocate PLT */
2936 write32le(s1
->got
->data
, dynamic
->sh_addr
);
2937 if (file_type
== TCC_OUTPUT_EXE
2938 || (RELOCATE_DLLPLT
&& (file_type
& TCC_OUTPUT_DYN
)))
2940 /* relocate symbols in .dynsym now that final addresses are known */
2941 relocate_syms(s1
, s1
->dynsym
, 2);
2944 /* if building executable or DLL, then relocate each section
2945 except the GOT which is already relocated */
2946 relocate_syms(s1
, s1
->symtab
, 0);
2947 if (s1
->nb_errors
!= 0)
2949 relocate_sections(s1
);
2951 update_reloc_sections (s1
, &dyninf
);
2952 dynamic
->data_offset
= dyninf
.data_offset
;
2953 fill_dynamic(s1
, &dyninf
);
2955 /* Perform relocation to GOT or PLT entries */
2956 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2959 fill_local_got_entries(s1
);
2961 if (dyninf
.gnu_hash
)
2962 update_gnu_hash(s1
, dyninf
.gnu_hash
);
2964 /* Create the ELF file with name 'filename' */
2965 ret
= tcc_write_elf_file(s1
, filename
, dyninf
.phnum
, dyninf
.phdr
, file_offset
, sec_order
);
2967 tcc_free(sec_order
);
2968 tcc_free(dyninf
.phdr
);
2971 #endif /* ndef ELF_OBJ_ONLY */
2973 /* Allocate strings for section names */
2974 static void alloc_sec_names(TCCState
*s1
, int is_obj
)
2977 Section
*s
, *strsec
;
2979 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
2980 put_elf_str(strsec
, "");
2981 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2982 s
= s1
->sections
[i
];
2984 s
->sh_size
= s
->data_offset
;
2985 if (s
== strsec
|| s
->sh_size
|| (s
->sh_flags
& SHF_ALLOC
))
2986 s
->sh_name
= put_elf_str(strsec
, s
->name
);
2988 strsec
->sh_size
= strsec
->data_offset
;
2991 /* Output an elf .o file */
2992 static int elf_output_obj(TCCState
*s1
, const char *filename
)
2995 int i
, ret
, file_offset
;
2997 /* Allocate strings for section names */
2998 alloc_sec_names(s1
, 1);
2999 file_offset
= sizeof (ElfW(Ehdr
));
3000 for(i
= 1; i
< s1
->nb_sections
; i
++) {
3001 s
= s1
->sections
[i
];
3002 file_offset
= (file_offset
+ 15) & -16;
3003 s
->sh_offset
= file_offset
;
3004 if (s
->sh_type
!= SHT_NOBITS
)
3005 file_offset
+= s
->sh_size
;
3007 /* Create the ELF file with name 'filename' */
3008 ret
= tcc_write_elf_file(s1
, filename
, 0, NULL
, file_offset
, NULL
);
3012 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
3014 if (s
->test_coverage
)
3015 tcc_tcov_add_file(s
, filename
);
3016 if (s
->output_type
== TCC_OUTPUT_OBJ
)
3017 return elf_output_obj(s
, filename
);
3018 #ifdef TCC_TARGET_PE
3019 return pe_output_file(s
, filename
);
3020 #elif TCC_TARGET_MACHO
3021 return macho_output_file(s
, filename
);
3023 return elf_output_file(s
, filename
);
3027 ST_FUNC ssize_t
full_read(int fd
, void *buf
, size_t count
) {
3031 ssize_t num
= read(fd
, cbuf
, count
-rnum
);
3032 if (num
< 0) return num
;
3033 if (num
== 0) return rnum
;
3039 ST_FUNC
void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
3043 data
= tcc_malloc(size
);
3044 lseek(fd
, file_offset
, SEEK_SET
);
3045 full_read(fd
, data
, size
);
3049 typedef struct SectionMergeInfo
{
3050 Section
*s
; /* corresponding existing section */
3051 unsigned long offset
; /* offset of the new section in the existing section */
3052 uint8_t new_section
; /* true if section 's' was added */
3053 uint8_t link_once
; /* true if link once section */
3056 ST_FUNC
int tcc_object_type(int fd
, ElfW(Ehdr
) *h
)
3058 int size
= full_read(fd
, h
, sizeof *h
);
3059 if (size
== sizeof *h
&& 0 == memcmp(h
, ELFMAG
, 4)) {
3060 if (h
->e_type
== ET_REL
)
3061 return AFF_BINTYPE_REL
;
3062 if (h
->e_type
== ET_DYN
)
3063 return AFF_BINTYPE_DYN
;
3064 } else if (size
>= 8) {
3065 if (0 == memcmp(h
, ARMAG
, 8))
3066 return AFF_BINTYPE_AR
;
3067 #ifdef TCC_TARGET_COFF
3068 if (((struct filehdr
*)h
)->f_magic
== COFF_C67_MAGIC
)
3069 return AFF_BINTYPE_C67
;
3075 /* load an object file and merge it with current files */
3076 /* XXX: handle correctly stab (debug) info */
3077 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
3078 int fd
, unsigned long file_offset
)
3081 ElfW(Shdr
) *shdr
, *sh
;
3082 unsigned long size
, offset
, offseti
;
3083 int i
, j
, nb_syms
, sym_index
, ret
, seencompressed
;
3084 char *strsec
, *strtab
;
3085 int stab_index
, stabstr_index
;
3086 int *old_to_new_syms
;
3087 char *sh_name
, *name
;
3088 SectionMergeInfo
*sm_table
, *sm
;
3089 ElfW(Sym
) *sym
, *symtab
;
3093 lseek(fd
, file_offset
, SEEK_SET
);
3094 if (tcc_object_type(fd
, &ehdr
) != AFF_BINTYPE_REL
)
3096 /* test CPU specific stuff */
3097 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
3098 ehdr
.e_machine
!= EM_TCC_TARGET
) {
3100 return tcc_error_noabort("invalid object file");
3103 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
3104 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
3105 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
3107 /* load section names */
3108 sh
= &shdr
[ehdr
.e_shstrndx
];
3109 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
3111 /* load symtab and strtab */
3112 old_to_new_syms
= NULL
;
3117 stab_index
= stabstr_index
= 0;
3120 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3122 if (sh
->sh_type
== SHT_SYMTAB
) {
3124 tcc_error_noabort("object must contain only one symtab");
3127 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
3128 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
3129 sm_table
[i
].s
= symtab_section
;
3131 /* now load strtab */
3132 sh
= &shdr
[sh
->sh_link
];
3133 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
3135 if (sh
->sh_flags
& SHF_COMPRESSED
)
3139 /* now examine each section and try to merge its content with the
3141 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3142 /* no need to examine section name strtab */
3143 if (i
== ehdr
.e_shstrndx
)
3146 if (sh
->sh_type
== SHT_RELX
)
3147 sh
= &shdr
[sh
->sh_info
];
3148 /* ignore sections types we do not handle (plus relocs to those) */
3149 if (sh
->sh_type
!= SHT_PROGBITS
&&
3151 sh
->sh_type
!= SHT_ARM_EXIDX
&&
3153 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3154 sh
->sh_type
!= SHT_X86_64_UNWIND
&&
3156 sh
->sh_type
!= SHT_NOTE
&&
3157 sh
->sh_type
!= SHT_NOBITS
&&
3158 sh
->sh_type
!= SHT_PREINIT_ARRAY
&&
3159 sh
->sh_type
!= SHT_INIT_ARRAY
&&
3160 sh
->sh_type
!= SHT_FINI_ARRAY
&&
3161 strcmp(strsec
+ sh
->sh_name
, ".stabstr")
3164 if (seencompressed
&& 0 == strncmp(strsec
+ sh
->sh_name
, ".debug_", 7))
3168 sh_name
= strsec
+ sh
->sh_name
;
3169 if (sh
->sh_addralign
< 1)
3170 sh
->sh_addralign
= 1;
3171 /* find corresponding section, if any */
3172 for(j
= 1; j
< s1
->nb_sections
;j
++) {
3173 s
= s1
->sections
[j
];
3174 if (!strcmp(s
->name
, sh_name
)) {
3175 if (!strncmp(sh_name
, ".gnu.linkonce",
3176 sizeof(".gnu.linkonce") - 1)) {
3177 /* if a 'linkonce' section is already present, we
3178 do not add it again. It is a little tricky as
3179 symbols can still be defined in
3181 sm_table
[i
].link_once
= 1;
3185 if (s
== stab_section
)
3187 if (s
== stab_section
->link
)
3193 /* not found: create new section */
3194 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
& ~SHF_GROUP
);
3195 /* take as much info as possible from the section. sh_link and
3196 sh_info will be updated later */
3197 s
->sh_addralign
= sh
->sh_addralign
;
3198 s
->sh_entsize
= sh
->sh_entsize
;
3199 sm_table
[i
].new_section
= 1;
3201 if (sh
->sh_type
!= s
->sh_type
3202 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3203 && strcmp (s
->name
, ".eh_frame")
3206 tcc_error_noabort("invalid section type");
3209 /* align start of section */
3210 s
->data_offset
+= -s
->data_offset
& (sh
->sh_addralign
- 1);
3211 if (sh
->sh_addralign
> s
->sh_addralign
)
3212 s
->sh_addralign
= sh
->sh_addralign
;
3213 sm_table
[i
].offset
= s
->data_offset
;
3215 /* concatenate sections */
3217 if (sh
->sh_type
!= SHT_NOBITS
) {
3219 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
3220 ptr
= section_ptr_add(s
, size
);
3221 full_read(fd
, ptr
, size
);
3223 s
->data_offset
+= size
;
3228 /* gr relocate stab strings */
3229 if (stab_index
&& stabstr_index
) {
3232 s
= sm_table
[stab_index
].s
;
3233 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
3234 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
3235 o
= sm_table
[stabstr_index
].offset
;
3243 /* second short pass to update sh_link and sh_info fields of new
3245 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3247 if (!s
|| !sm_table
[i
].new_section
)
3250 if (sh
->sh_link
> 0)
3251 s
->link
= sm_table
[sh
->sh_link
].s
;
3252 if (sh
->sh_type
== SHT_RELX
) {
3253 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
3254 /* update backward link */
3255 s1
->sections
[s
->sh_info
]->reloc
= s
;
3259 /* resolve symbols */
3260 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
3263 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
3264 if (sym
->st_shndx
!= SHN_UNDEF
&&
3265 sym
->st_shndx
< SHN_LORESERVE
) {
3266 sm
= &sm_table
[sym
->st_shndx
];
3267 if (sm
->link_once
) {
3268 /* if a symbol is in a link once section, we use the
3269 already defined symbol. It is very important to get
3270 correct relocations */
3271 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
3272 name
= strtab
+ sym
->st_name
;
3273 sym_index
= find_elf_sym(symtab_section
, name
);
3275 old_to_new_syms
[i
] = sym_index
;
3279 /* if no corresponding section added, no need to add symbol */
3282 /* convert section number */
3283 sym
->st_shndx
= sm
->s
->sh_num
;
3285 sym
->st_value
+= sm
->offset
;
3288 name
= strtab
+ sym
->st_name
;
3289 sym_index
= set_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
3290 sym
->st_info
, sym
->st_other
,
3291 sym
->st_shndx
, name
);
3292 old_to_new_syms
[i
] = sym_index
;
3295 /* third pass to patch relocation entries */
3296 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3301 offset
= sm_table
[i
].offset
;
3303 switch(s
->sh_type
) {
3305 /* take relocation offset information */
3306 offseti
= sm_table
[sh
->sh_info
].offset
;
3307 for (rel
= (ElfW_Rel
*) s
->data
+ (offset
/ sizeof(*rel
));
3308 rel
< (ElfW_Rel
*) s
->data
+ ((offset
+ size
) / sizeof(*rel
));
3312 /* convert symbol index */
3313 type
= ELFW(R_TYPE
)(rel
->r_info
);
3314 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
3315 /* NOTE: only one symtab assumed */
3316 if (sym_index
>= nb_syms
)
3318 sym_index
= old_to_new_syms
[sym_index
];
3319 /* ignore link_once in rel section. */
3320 if (!sym_index
&& !sm_table
[sh
->sh_info
].link_once
3321 #ifdef TCC_TARGET_ARM
3322 && type
!= R_ARM_V4BX
3323 #elif defined TCC_TARGET_RISCV64
3324 && type
!= R_RISCV_ALIGN
3325 && type
!= R_RISCV_RELAX
3329 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3330 i
, strsec
+ sh
->sh_name
, (int)rel
->r_offset
);
3333 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
3334 /* offset the relocation offset */
3335 rel
->r_offset
+= offseti
;
3336 #ifdef TCC_TARGET_ARM
3337 /* Jumps and branches from a Thumb code to a PLT entry need
3338 special handling since PLT entries are ARM code.
3339 Unconditional bl instructions referencing PLT entries are
3340 handled by converting these instructions into blx
3341 instructions. Other case of instructions referencing a PLT
3342 entry require to add a Thumb stub before the PLT entry to
3343 switch to ARM mode. We set bit plt_thumb_stub of the
3344 attribute of a symbol to indicate such a case. */
3345 if (type
== R_ARM_THM_JUMP24
)
3346 get_sym_attr(s1
, sym_index
, 1)->plt_thumb_stub
= 1;
3359 tcc_free(old_to_new_syms
);
3366 typedef struct ArchiveHeader
{
3367 char ar_name
[16]; /* name of this member */
3368 char ar_date
[12]; /* file mtime */
3369 char ar_uid
[6]; /* owner uid; printed as decimal */
3370 char ar_gid
[6]; /* owner gid; printed as decimal */
3371 char ar_mode
[8]; /* file mode, printed as octal */
3372 char ar_size
[10]; /* file size, printed as decimal */
3373 char ar_fmag
[2]; /* should contain ARFMAG */
3376 #define ARFMAG "`\n"
3378 static unsigned long long get_be(const uint8_t *b
, int n
)
3380 unsigned long long ret
= 0;
3382 ret
= (ret
<< 8) | *b
++, --n
;
3386 static int read_ar_header(int fd
, int offset
, ArchiveHeader
*hdr
)
3390 lseek(fd
, offset
, SEEK_SET
);
3391 len
= full_read(fd
, hdr
, sizeof(ArchiveHeader
));
3392 if (len
!= sizeof(ArchiveHeader
))
3393 return len
? -1 : 0;
3395 for (e
= p
+ sizeof hdr
->ar_name
; e
> p
&& e
[-1] == ' ';)
3398 hdr
->ar_size
[sizeof hdr
->ar_size
-1] = 0;
3402 /* load only the objects which resolve undefined symbols */
3403 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
, int entrysize
)
3405 int i
, bound
, nsyms
, sym_index
, len
, ret
= -1;
3406 unsigned long long off
;
3408 const char *ar_names
, *p
;
3409 const uint8_t *ar_index
;
3413 data
= tcc_malloc(size
);
3414 if (full_read(fd
, data
, size
) != size
)
3416 nsyms
= get_be(data
, entrysize
);
3417 ar_index
= data
+ entrysize
;
3418 ar_names
= (char *) ar_index
+ nsyms
* entrysize
;
3422 for (p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
3423 Section
*s
= symtab_section
;
3424 sym_index
= find_elf_sym(s
, p
);
3427 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
3428 if(sym
->st_shndx
!= SHN_UNDEF
)
3430 off
= get_be(ar_index
+ i
* entrysize
, entrysize
);
3431 len
= read_ar_header(fd
, off
, &hdr
);
3432 if (len
<= 0 || memcmp(hdr
.ar_fmag
, ARFMAG
, 2)) {
3433 tcc_error_noabort("invalid archive");
3437 if (s1
->verbose
== 2)
3438 printf(" -> %s\n", hdr
.ar_name
);
3439 if (tcc_load_object_file(s1
, fd
, off
) < 0)
3450 /* load a '.a' file */
3451 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
, int alacarte
)
3454 /* char magic[8]; */
3456 unsigned long file_offset
;
3459 /* skip magic which was already checked */
3460 /* full_read(fd, magic, sizeof(magic)); */
3461 file_offset
= sizeof ARMAG
- 1;
3464 len
= read_ar_header(fd
, file_offset
, &hdr
);
3468 return tcc_error_noabort("invalid archive");
3470 size
= strtol(hdr
.ar_size
, NULL
, 0);
3472 size
= (size
+ 1) & ~1;
3474 /* coff symbol table : we handle it */
3475 if (!strcmp(hdr
.ar_name
, "/"))
3476 return tcc_load_alacarte(s1
, fd
, size
, 4);
3477 if (!strcmp(hdr
.ar_name
, "/SYM64/"))
3478 return tcc_load_alacarte(s1
, fd
, size
, 8);
3479 } else if (tcc_object_type(fd
, &ehdr
) == AFF_BINTYPE_REL
) {
3480 if (s1
->verbose
== 2)
3481 printf(" -> %s\n", hdr
.ar_name
);
3482 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
3485 file_offset
+= size
;
3489 #ifndef ELF_OBJ_ONLY
3490 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3491 LV, maybe create a new entry for (LIB,VERSION). */
3492 static void set_ver_to_ver(TCCState
*s1
, int *n
, int **lv
, int i
, char *lib
, char *version
)
3495 *lv
= tcc_realloc(*lv
, (*n
+ 1) * sizeof(**lv
));
3498 if ((*lv
)[i
] == -1) {
3499 int v
, prev_same_lib
= -1;
3500 for (v
= 0; v
< nb_sym_versions
; v
++) {
3501 if (strcmp(sym_versions
[v
].lib
, lib
))
3504 if (!strcmp(sym_versions
[v
].version
, version
))
3507 if (v
== nb_sym_versions
) {
3508 sym_versions
= tcc_realloc (sym_versions
,
3509 (v
+ 1) * sizeof(*sym_versions
));
3510 sym_versions
[v
].lib
= tcc_strdup(lib
);
3511 sym_versions
[v
].version
= tcc_strdup(version
);
3512 sym_versions
[v
].out_index
= 0;
3513 sym_versions
[v
].prev_same_lib
= prev_same_lib
;
3520 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3523 set_sym_version(TCCState
*s1
, int sym_index
, int verndx
)
3525 if (sym_index
>= nb_sym_to_version
) {
3526 int newelems
= sym_index
? sym_index
* 2 : 1;
3527 sym_to_version
= tcc_realloc(sym_to_version
,
3528 newelems
* sizeof(*sym_to_version
));
3529 memset(sym_to_version
+ nb_sym_to_version
, -1,
3530 (newelems
- nb_sym_to_version
) * sizeof(*sym_to_version
));
3531 nb_sym_to_version
= newelems
;
3533 if (sym_to_version
[sym_index
] < 0)
3534 sym_to_version
[sym_index
] = verndx
;
3537 struct versym_info
{
3539 ElfW(Verdef
) *verdef
;
3540 ElfW(Verneed
) *verneed
;
3542 int nb_local_ver
, *local_ver
;
3546 static void store_version(TCCState
*s1
, struct versym_info
*v
, char *dynstr
)
3548 char *lib
, *version
;
3552 #define DEBUG_VERSION 0
3554 if (v
->versym
&& v
->verdef
) {
3555 ElfW(Verdef
) *vdef
= v
->verdef
;
3558 ElfW(Verdaux
) *verdaux
=
3559 (ElfW(Verdaux
) *) (((char *) vdef
) + vdef
->vd_aux
);
3562 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3563 vdef
->vd_version
, vdef
->vd_flags
, vdef
->vd_ndx
,
3567 version
= dynstr
+ verdaux
->vda_name
;
3572 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vdef
->vd_ndx
,
3575 printf (" verdaux(%u): %s\n", vdef
->vd_ndx
, version
);
3578 next
= vdef
->vd_next
;
3579 vdef
= (ElfW(Verdef
) *) (((char *) vdef
) + next
);
3582 if (v
->versym
&& v
->verneed
) {
3583 ElfW(Verneed
) *vneed
= v
->verneed
;
3585 ElfW(Vernaux
) *vernaux
=
3586 (ElfW(Vernaux
) *) (((char *) vneed
) + vneed
->vn_aux
);
3588 lib
= dynstr
+ vneed
->vn_file
;
3590 printf ("verneed: %u %s\n", vneed
->vn_version
, lib
);
3592 for (i
= 0; i
< vneed
->vn_cnt
; i
++) {
3593 if ((vernaux
->vna_other
& 0x8000) == 0) { /* hidden */
3594 version
= dynstr
+ vernaux
->vna_name
;
3595 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vernaux
->vna_other
,
3598 printf (" vernaux(%u): %u %u %s\n",
3599 vernaux
->vna_other
, vernaux
->vna_hash
,
3600 vernaux
->vna_flags
, version
);
3603 vernaux
= (ElfW(Vernaux
) *) (((char *) vernaux
) + vernaux
->vna_next
);
3605 next
= vneed
->vn_next
;
3606 vneed
= (ElfW(Verneed
) *) (((char *) vneed
) + next
);
3611 for (i
= 0; i
< v
->nb_local_ver
; i
++) {
3612 if (v
->local_ver
[i
] > 0) {
3613 printf ("%d: lib: %s, version %s\n",
3614 i
, sym_versions
[v
->local_ver
[i
]].lib
,
3615 sym_versions
[v
->local_ver
[i
]].version
);
3621 /* load a library / DLL
3622 'level = 0' means that the DLL is referenced by the user
3623 (so it should be added as DT_NEEDED in the generated ELF file) */
3624 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
3627 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
3628 int i
, nb_syms
, nb_dts
, sym_bind
, ret
= -1;
3629 ElfW(Sym
) *sym
, *dynsym
;
3630 ElfW(Dyn
) *dt
, *dynamic
;
3634 const char *name
, *soname
;
3635 struct versym_info v
;
3637 full_read(fd
, &ehdr
, sizeof(ehdr
));
3639 /* test CPU specific stuff */
3640 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
3641 ehdr
.e_machine
!= EM_TCC_TARGET
) {
3642 return tcc_error_noabort("bad architecture");
3646 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
3648 /* load dynamic section and dynamic symbols */
3652 dynsym
= NULL
; /* avoid warning */
3653 dynstr
= NULL
; /* avoid warning */
3654 memset(&v
, 0, sizeof v
);
3656 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
3657 switch(sh
->sh_type
) {
3659 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
3660 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3663 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
3664 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3665 sh1
= &shdr
[sh
->sh_link
];
3666 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
3668 case SHT_GNU_verdef
:
3669 v
.verdef
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3671 case SHT_GNU_verneed
:
3672 v
.verneed
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3674 case SHT_GNU_versym
:
3675 v
.nb_versyms
= sh
->sh_size
/ sizeof(ElfW(Half
));
3676 v
.versym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3686 /* compute the real library name */
3687 soname
= tcc_basename(filename
);
3688 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++)
3689 if (dt
->d_tag
== DT_SONAME
)
3690 soname
= dynstr
+ dt
->d_un
.d_val
;
3692 /* if the dll is already loaded, do not load it */
3693 if (tcc_add_dllref(s1
, soname
, level
)->found
)
3696 if (v
.nb_versyms
!= nb_syms
)
3697 tcc_free (v
.versym
), v
.versym
= NULL
;
3699 store_version(s1
, &v
, dynstr
);
3701 /* add dynamic symbols in dynsym_section */
3702 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
3703 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
3704 if (sym_bind
== STB_LOCAL
)
3706 name
= dynstr
+ sym
->st_name
;
3707 sym_index
= set_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
3708 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
3710 ElfW(Half
) vsym
= v
.versym
[i
];
3711 if ((vsym
& 0x8000) == 0 && vsym
> 0 && vsym
< v
.nb_local_ver
)
3712 set_sym_version(s1
, sym_index
, v
.local_ver
[vsym
]);
3716 /* do not load all referenced libraries
3717 (recursive loading can break linking of libraries) */
3718 /* following DT_NEEDED is needed for the dynamic loader (libdl.so),
3719 but it is no longer needed, when linking a library or a program.
3720 When tcc output mode is OUTPUT_MEM,
3721 tcc calls dlopen, which handles DT_NEEDED for us */
3724 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++)
3725 if (dt
->d_tag
== DT_RPATH
)
3726 tcc_add_library_path(s1
, dynstr
+ dt
->d_un
.d_val
);
3728 /* load all referenced DLLs */
3729 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3732 name
= dynstr
+ dt
->d_un
.d_val
;
3733 if (tcc_add_dllref(s1
, name
, -1))
3735 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
3736 ret
= tcc_error_noabort("referenced dll '%s' not found", name
);
3750 tcc_free(v
.local_ver
);
3752 tcc_free(v
.verneed
);
3757 #define LD_TOK_NAME 256
3758 #define LD_TOK_EOF (-1)
3760 static int ld_inp(TCCState
*s1
)
3768 if (1 == read(s1
->fd
, &b
, 1))
3773 /* return next ld script token */
3774 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
3791 if (ch
== '*') { /* comment */
3792 for (d
= 0;; d
= ch
) {
3794 if (ch
== CH_EOF
|| (ch
== '/' && d
== '*'))
3805 /* case 'a' ... 'z': */
3832 /* case 'A' ... 'z': */
3866 if (!((ch
>= 'a' && ch
<= 'z') ||
3867 (ch
>= 'A' && ch
<= 'Z') ||
3868 (ch
>= '0' && ch
<= '9') ||
3869 strchr("/.-_+=$:\\,~", ch
)))
3871 if ((q
- name
) < name_size
- 1) {
3890 static int ld_add_file(TCCState
*s1
, const char filename
[])
3892 if (filename
[0] == '/') {
3893 if (CONFIG_SYSROOT
[0] == '\0'
3894 && tcc_add_file_internal(s1
, filename
, AFF_TYPE_BIN
) == 0)
3896 filename
= tcc_basename(filename
);
3898 return tcc_add_dll(s1
, filename
, AFF_PRINT_ERROR
);
3901 static int ld_add_file_list(TCCState
*s1
, const char *cmd
, int as_needed
)
3903 char filename
[1024], libname
[1024];
3904 int t
, group
, nblibs
= 0, ret
= 0;
3907 group
= !strcmp(cmd
, "GROUP");
3909 s1
->new_undef_sym
= 0;
3910 t
= ld_next(s1
, filename
, sizeof(filename
));
3912 ret
= tcc_error_noabort("( expected");
3913 goto lib_parse_error
;
3915 t
= ld_next(s1
, filename
, sizeof(filename
));
3918 if (t
== LD_TOK_EOF
) {
3919 ret
= tcc_error_noabort("unexpected end of file");
3920 goto lib_parse_error
;
3921 } else if (t
== ')') {
3923 } else if (t
== '-') {
3924 t
= ld_next(s1
, filename
, sizeof(filename
));
3925 if ((t
!= LD_TOK_NAME
) || (filename
[0] != 'l')) {
3926 ret
= tcc_error_noabort("library name expected");
3927 goto lib_parse_error
;
3929 pstrcpy(libname
, sizeof libname
, &filename
[1]);
3930 if (s1
->static_link
) {
3931 snprintf(filename
, sizeof filename
, "lib%s.a", libname
);
3933 snprintf(filename
, sizeof filename
, "lib%s.so", libname
);
3935 } else if (t
!= LD_TOK_NAME
) {
3936 ret
= tcc_error_noabort("filename expected");
3937 goto lib_parse_error
;
3939 if (!strcmp(filename
, "AS_NEEDED")) {
3940 ret
= ld_add_file_list(s1
, cmd
, 1);
3942 goto lib_parse_error
;
3944 /* TODO: Implement AS_NEEDED support. */
3945 /* DT_NEEDED is not used any more so ignore as_needed */
3946 if (1 || !as_needed
) {
3947 ret
= ld_add_file(s1
, filename
);
3949 goto lib_parse_error
;
3951 /* Add the filename *and* the libname to avoid future conversions */
3952 dynarray_add(&libs
, &nblibs
, tcc_strdup(filename
));
3953 if (libname
[0] != '\0')
3954 dynarray_add(&libs
, &nblibs
, tcc_strdup(libname
));
3958 t
= ld_next(s1
, filename
, sizeof(filename
));
3960 t
= ld_next(s1
, filename
, sizeof(filename
));
3963 if (group
&& !as_needed
) {
3964 while (s1
->new_undef_sym
) {
3966 s1
->new_undef_sym
= 0;
3967 for (i
= 0; i
< nblibs
; i
++)
3968 ld_add_file(s1
, libs
[i
]);
3972 dynarray_reset(&libs
, &nblibs
);
3976 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3978 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
, int fd
)
3981 char filename
[1024];
3987 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3988 if (t
== LD_TOK_EOF
)
3990 else if (t
!= LD_TOK_NAME
)
3992 if (!strcmp(cmd
, "INPUT") ||
3993 !strcmp(cmd
, "GROUP")) {
3994 ret
= ld_add_file_list(s1
, cmd
, 0);
3997 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
3998 !strcmp(cmd
, "TARGET")) {
3999 /* ignore some commands */
4000 t
= ld_next(s1
, cmd
, sizeof(cmd
));
4002 return tcc_error_noabort("( expected");
4004 t
= ld_next(s1
, filename
, sizeof(filename
));
4005 if (t
== LD_TOK_EOF
) {
4006 return tcc_error_noabort("unexpected end of file");
4007 } else if (t
== ')') {
4017 #endif /* !ELF_OBJ_ONLY */