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 static const int shf_RELRO
= SHF_ALLOC
;
52 static const char rdata
[] = ".rdata";
54 static const int shf_RELRO
= SHF_ALLOC
| SHF_WRITE
;
55 static const char rdata
[] = ".data.ro";
58 /* ------------------------------------------------------------------------- */
60 ST_FUNC
void tccelf_new(TCCState
*s
)
64 dynarray_add(&s
->sections
, &s
->nb_sections
, NULL
);
66 /* create standard sections */
67 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
68 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
69 /* create ro data section (make ro after relocation done with GNU_RELRO) */
70 rodata_section
= new_section(s
, rdata
, SHT_PROGBITS
, shf_RELRO
);
71 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
72 common_section
= new_section(s
, ".common", SHT_NOBITS
, SHF_PRIVATE
);
73 common_section
->sh_num
= SHN_COMMON
;
75 /* symbols are always generated for linking stage */
76 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
78 ".hashtab", SHF_PRIVATE
);
79 s
->symtab
= symtab_section
;
81 /* private symbol table for dynamic symbols */
82 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
|SHF_DYNSYM
,
84 ".dynhashtab", SHF_PRIVATE
);
85 get_sym_attr(s
, 0, 1);
88 #ifdef CONFIG_TCC_BCHECK
89 ST_FUNC
void tccelf_bounds_new(TCCState
*s
)
92 /* create bounds sections (make ro after relocation done with GNU_RELRO) */
93 bounds_section
= new_section(s
, ".bounds", SHT_PROGBITS
, shf_RELRO
);
94 lbounds_section
= new_section(s
, ".lbounds", SHT_PROGBITS
, shf_RELRO
);
98 static void free_section(Section
*s
)
103 ST_FUNC
void tccelf_delete(TCCState
*s1
)
108 /* free symbol versions */
109 for (i
= 0; i
< nb_sym_versions
; i
++) {
110 tcc_free(sym_versions
[i
].version
);
111 tcc_free(sym_versions
[i
].lib
);
113 tcc_free(sym_versions
);
114 tcc_free(sym_to_version
);
117 /* free all sections */
118 for(i
= 1; i
< s1
->nb_sections
; i
++)
119 free_section(s1
->sections
[i
]);
120 dynarray_reset(&s1
->sections
, &s1
->nb_sections
);
122 for(i
= 0; i
< s1
->nb_priv_sections
; i
++)
123 free_section(s1
->priv_sections
[i
]);
124 dynarray_reset(&s1
->priv_sections
, &s1
->nb_priv_sections
);
126 /* free any loaded DLLs */
128 for ( i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
129 DLLReference
*ref
= s1
->loaded_dlls
[i
];
132 FreeLibrary((HMODULE
)ref
->handle
);
134 dlclose(ref
->handle
);
138 /* free loaded dlls array */
139 dynarray_reset(&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
);
140 tcc_free(s1
->sym_attrs
);
142 symtab_section
= NULL
; /* for tccrun.c:rt_printline() */
145 /* save section data state */
146 ST_FUNC
void tccelf_begin_file(TCCState
*s1
)
149 for (i
= 1; i
< s1
->nb_sections
; i
++) {
151 s
->sh_offset
= s
->data_offset
;
153 /* disable symbol hashing during compilation */
154 s
= s1
->symtab
, s
->reloc
= s
->hash
, s
->hash
= NULL
;
155 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
160 /* At the end of compilation, convert any UNDEF syms to global, and merge
161 with previously existing symbols */
162 ST_FUNC
void tccelf_end_file(TCCState
*s1
)
164 Section
*s
= s1
->symtab
;
165 int first_sym
, nb_syms
, *tr
, i
;
167 first_sym
= s
->sh_offset
/ sizeof (ElfSym
);
168 nb_syms
= s
->data_offset
/ sizeof (ElfSym
) - first_sym
;
169 s
->data_offset
= s
->sh_offset
;
170 s
->link
->data_offset
= s
->link
->sh_offset
;
171 s
->hash
= s
->reloc
, s
->reloc
= NULL
;
172 tr
= tcc_mallocz(nb_syms
* sizeof *tr
);
174 for (i
= 0; i
< nb_syms
; ++i
) {
175 ElfSym
*sym
= (ElfSym
*)s
->data
+ first_sym
+ i
;
176 if (sym
->st_shndx
== SHN_UNDEF
177 && ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
)
178 sym
->st_info
= ELFW(ST_INFO
)(STB_GLOBAL
, ELFW(ST_TYPE
)(sym
->st_info
));
179 tr
[i
] = set_elf_sym(s
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
180 sym
->st_other
, sym
->st_shndx
, (char*)s
->link
->data
+ sym
->st_name
);
182 /* now update relocations */
183 for (i
= 1; i
< s1
->nb_sections
; i
++) {
184 Section
*sr
= s1
->sections
[i
];
185 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
186 ElfW_Rel
*rel
= (ElfW_Rel
*)(sr
->data
+ sr
->sh_offset
);
187 ElfW_Rel
*rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
188 for (; rel
< rel_end
; ++rel
) {
189 int n
= ELFW(R_SYM
)(rel
->r_info
) - first_sym
;
190 if (n
< 0) /* zero sym_index in reloc (can happen with asm) */
192 rel
->r_info
= ELFW(R_INFO
)(tr
[n
], ELFW(R_TYPE
)(rel
->r_info
));
198 /* record text/data/bss output for -bench info */
199 for (i
= 0; i
< 4; ++i
) {
200 s
= s1
->sections
[i
+ 1];
201 s1
->total_output
[i
] += s
->data_offset
- s
->sh_offset
;
205 ST_FUNC Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
209 sec
= tcc_mallocz(sizeof(Section
) + strlen(name
));
211 strcpy(sec
->name
, name
);
212 sec
->sh_type
= sh_type
;
213 sec
->sh_flags
= sh_flags
;
216 sec
->sh_addralign
= 2;
225 case SHT_GNU_verneed
:
227 sec
->sh_addralign
= PTR_SIZE
;
230 sec
->sh_addralign
= 1;
233 sec
->sh_addralign
= PTR_SIZE
; /* gcc/pcc default alignment */
237 if (sh_flags
& SHF_PRIVATE
) {
238 dynarray_add(&s1
->priv_sections
, &s1
->nb_priv_sections
, sec
);
240 sec
->sh_num
= s1
->nb_sections
;
241 dynarray_add(&s1
->sections
, &s1
->nb_sections
, sec
);
247 ST_FUNC Section
*new_symtab(TCCState
*s1
,
248 const char *symtab_name
, int sh_type
, int sh_flags
,
249 const char *strtab_name
,
250 const char *hash_name
, int hash_sh_flags
)
252 Section
*symtab
, *strtab
, *hash
;
253 int *ptr
, nb_buckets
;
255 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
256 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
257 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
258 put_elf_str(strtab
, "");
259 symtab
->link
= strtab
;
260 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
264 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
265 hash
->sh_entsize
= sizeof(int);
269 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
272 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
276 /* realloc section and set its content to zero */
277 ST_FUNC
void section_realloc(Section
*sec
, unsigned long new_size
)
282 size
= sec
->data_allocated
;
285 while (size
< new_size
)
287 data
= tcc_realloc(sec
->data
, size
);
288 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
290 sec
->data_allocated
= size
;
293 /* reserve at least 'size' bytes aligned per 'align' in section
294 'sec' from current offset, and return the aligned offset */
295 ST_FUNC
size_t section_add(Section
*sec
, addr_t size
, int align
)
297 size_t offset
, offset1
;
299 offset
= (sec
->data_offset
+ align
- 1) & -align
;
300 offset1
= offset
+ size
;
301 if (sec
->sh_type
!= SHT_NOBITS
&& offset1
> sec
->data_allocated
)
302 section_realloc(sec
, offset1
);
303 sec
->data_offset
= offset1
;
304 if (align
> sec
->sh_addralign
)
305 sec
->sh_addralign
= align
;
309 /* reserve at least 'size' bytes in section 'sec' from
311 ST_FUNC
void *section_ptr_add(Section
*sec
, addr_t size
)
313 size_t offset
= section_add(sec
, size
, 1);
314 return sec
->data
+ offset
;
318 /* reserve at least 'size' bytes from section start */
319 static void section_reserve(Section
*sec
, unsigned long size
)
321 if (size
> sec
->data_allocated
)
322 section_realloc(sec
, size
);
323 if (size
> sec
->data_offset
)
324 sec
->data_offset
= size
;
328 static Section
*have_section(TCCState
*s1
, const char *name
)
332 for(i
= 1; i
< s1
->nb_sections
; i
++) {
333 sec
= s1
->sections
[i
];
334 if (!strcmp(name
, sec
->name
))
340 /* return a reference to a section, and create it if it does not
342 ST_FUNC Section
*find_section(TCCState
*s1
, const char *name
)
344 Section
*sec
= have_section(s1
, name
);
347 /* sections are created as PROGBITS */
348 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
351 /* ------------------------------------------------------------------------- */
353 ST_FUNC
int put_elf_str(Section
*s
, const char *sym
)
358 len
= strlen(sym
) + 1;
359 offset
= s
->data_offset
;
360 ptr
= section_ptr_add(s
, len
);
361 memmove(ptr
, sym
, len
);
365 /* elf symbol hashing function */
366 static ElfW(Word
) elf_hash(const unsigned char *name
)
371 h
= (h
<< 4) + *name
++;
380 /* rebuild hash table of section s */
381 /* NOTE: we do factorize the hash table code to go faster */
382 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
385 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
386 unsigned char *strtab
;
388 strtab
= s
->link
->data
;
389 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
392 nb_buckets
= ((int*)s
->hash
->data
)[0];
394 s
->hash
->data_offset
= 0;
395 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
400 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
401 ptr
+= nb_buckets
+ 1;
403 sym
= (ElfW(Sym
) *)s
->data
+ 1;
404 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
405 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
406 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
417 /* return the symbol number */
418 ST_FUNC
int put_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
419 int info
, int other
, int shndx
, const char *name
)
421 int name_offset
, sym_index
;
426 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
428 name_offset
= put_elf_str(s
->link
, name
);
431 /* XXX: endianness */
432 sym
->st_name
= name_offset
;
433 sym
->st_value
= value
;
436 sym
->st_other
= other
;
437 sym
->st_shndx
= shndx
;
438 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
442 ptr
= section_ptr_add(hs
, sizeof(int));
443 base
= (int *)hs
->data
;
444 /* only add global or weak symbols. */
445 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
446 /* add another hashing entry */
448 h
= elf_hash((unsigned char *)s
->link
->data
+ name_offset
) % nbuckets
;
450 base
[2 + h
] = sym_index
;
452 /* we resize the hash table */
453 hs
->nb_hashed_syms
++;
454 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
455 rebuild_hash(s
, 2 * nbuckets
);
465 ST_FUNC
int find_elf_sym(Section
*s
, const char *name
)
469 int nbuckets
, sym_index
, h
;
475 nbuckets
= ((int *)hs
->data
)[0];
476 h
= elf_hash((unsigned char *) name
) % nbuckets
;
477 sym_index
= ((int *)hs
->data
)[2 + h
];
478 while (sym_index
!= 0) {
479 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
480 name1
= (char *) s
->link
->data
+ sym
->st_name
;
481 if (!strcmp(name
, name1
))
483 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
488 /* return elf symbol value, signal error if 'err' is nonzero, decorate
490 ST_FUNC addr_t
get_sym_addr(TCCState
*s1
, const char *name
, int err
, int forc
)
495 if (forc
&& s1
->leading_underscore
497 /* win32-32bit stdcall symbols always have _ already */
498 && !strchr(name
, '@')
502 pstrcpy(buf
+ 1, sizeof(buf
) - 1, name
);
505 sym_index
= find_elf_sym(s1
->symtab
, name
);
506 sym
= &((ElfW(Sym
) *)s1
->symtab
->data
)[sym_index
];
507 if (!sym_index
|| sym
->st_shndx
== SHN_UNDEF
) {
509 tcc_error("%s not defined", name
);
512 return sym
->st_value
;
515 /* return elf symbol value */
516 LIBTCCAPI
void *tcc_get_symbol(TCCState
*s
, const char *name
)
518 addr_t addr
= get_sym_addr(s
, name
, 0, 1);
519 return addr
== -1 ? NULL
: (void*)(uintptr_t)addr
;
522 /* list elf symbol names and values */
523 ST_FUNC
void list_elf_symbols(TCCState
*s
, void *ctx
,
524 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
528 int sym_index
, end_sym
;
530 unsigned char sym_vis
, sym_bind
;
533 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
534 for (sym_index
= 0; sym_index
< end_sym
; ++sym_index
) {
535 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
537 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
538 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
539 sym_vis
= ELFW(ST_VISIBILITY
)(sym
->st_other
);
540 if (sym_bind
== STB_GLOBAL
&& sym_vis
== STV_DEFAULT
)
541 symbol_cb(ctx
, name
, (void*)(uintptr_t)sym
->st_value
);
546 /* list elf symbol names and values */
547 LIBTCCAPI
void tcc_list_symbols(TCCState
*s
, void *ctx
,
548 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
550 list_elf_symbols(s
, ctx
, symbol_cb
);
555 version_add (TCCState
*s1
)
559 ElfW(Verneed
) *vn
= NULL
;
561 int sym_index
, end_sym
, nb_versions
= 2, nb_entries
= 0;
565 if (0 == nb_sym_versions
)
567 versym_section
= new_section(s1
, ".gnu.version", SHT_GNU_versym
, SHF_ALLOC
);
568 versym_section
->sh_entsize
= sizeof(ElfW(Half
));
569 versym_section
->link
= s1
->dynsym
;
571 /* add needed symbols */
573 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
574 versym
= section_ptr_add(versym_section
, end_sym
* sizeof(ElfW(Half
)));
575 for (sym_index
= 1; sym_index
< end_sym
; ++sym_index
) {
576 int dllindex
, verndx
;
577 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
578 if (sym
->st_shndx
!= SHN_UNDEF
)
579 continue; /* defined symbol doesn't need library version */
580 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
581 dllindex
= find_elf_sym(s1
->dynsymtab_section
, name
);
582 verndx
= (dllindex
&& dllindex
< nb_sym_to_version
)
583 ? sym_to_version
[dllindex
] : -1;
585 if (!sym_versions
[verndx
].out_index
)
586 sym_versions
[verndx
].out_index
= nb_versions
++;
587 versym
[sym_index
] = sym_versions
[verndx
].out_index
;
590 /* generate verneed section, but not when it will be empty. Some
591 dynamic linkers look at their contents even when DTVERNEEDNUM and
592 section size is zero. */
593 if (nb_versions
> 2) {
594 verneed_section
= new_section(s1
, ".gnu.version_r",
595 SHT_GNU_verneed
, SHF_ALLOC
);
596 verneed_section
->link
= s1
->dynsym
->link
;
597 for (i
= nb_sym_versions
; i
-- > 0;) {
598 struct sym_version
*sv
= &sym_versions
[i
];
599 int n_same_libs
= 0, prev
;
601 ElfW(Vernaux
) *vna
= 0;
602 if (sv
->out_index
< 1)
605 /* make sure that a DT_NEEDED tag is put */
606 /* abitest-tcc fails on older i386-linux with "ld-linux.so.2" DT_NEEDED
607 ret_int_test... Inconsistency detected by ld.so: dl-minimal.c: 148:
608 realloc: Assertion `ptr == alloc_last_block' failed! */
609 if (strcmp(sv
->lib
, "ld-linux.so.2"))
610 tcc_add_dllref(s1
, sv
->lib
, 0);
612 vnofs
= section_add(verneed_section
, sizeof(*vn
), 1);
613 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
615 vn
->vn_file
= put_elf_str(verneed_section
->link
, sv
->lib
);
616 vn
->vn_aux
= sizeof (*vn
);
618 prev
= sv
->prev_same_lib
;
619 if (sv
->out_index
> 0) {
620 vna
= section_ptr_add(verneed_section
, sizeof(*vna
));
621 vna
->vna_hash
= elf_hash ((const unsigned char *)sv
->version
);
623 vna
->vna_other
= sv
->out_index
;
625 vna
->vna_name
= put_elf_str(verneed_section
->link
, sv
->version
);
626 vna
->vna_next
= sizeof (*vna
);
630 sv
= &sym_versions
[prev
];
633 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
634 vn
->vn_cnt
= n_same_libs
;
635 vn
->vn_next
= sizeof(*vn
) + n_same_libs
* sizeof(*vna
);
640 verneed_section
->sh_info
= nb_entries
;
642 dt_verneednum
= nb_entries
;
644 #endif /* ndef ELF_OBJ_ONLY */
646 /* add an elf symbol : check if it is already defined and patch
647 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
648 ST_FUNC
int set_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
649 int info
, int other
, int shndx
, const char *name
)
651 TCCState
*s1
= s
->s1
;
653 int sym_bind
, sym_index
, sym_type
, esym_bind
;
654 unsigned char sym_vis
, esym_vis
, new_vis
;
656 sym_bind
= ELFW(ST_BIND
)(info
);
657 sym_type
= ELFW(ST_TYPE
)(info
);
658 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
660 if (sym_bind
!= STB_LOCAL
) {
661 /* we search global or weak symbols */
662 sym_index
= find_elf_sym(s
, name
);
665 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
666 if (esym
->st_value
== value
&& esym
->st_size
== size
&& esym
->st_info
== info
667 && esym
->st_other
== other
&& esym
->st_shndx
== shndx
)
669 if (esym
->st_shndx
!= SHN_UNDEF
) {
670 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
671 /* propagate the most constraining visibility */
672 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
673 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
674 if (esym_vis
== STV_DEFAULT
) {
676 } else if (sym_vis
== STV_DEFAULT
) {
679 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
681 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
683 if (shndx
== SHN_UNDEF
) {
684 /* ignore adding of undefined symbol if the
685 corresponding symbol is already defined */
686 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
687 /* global overrides weak, so patch */
689 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
690 /* weak is ignored if already global */
691 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_WEAK
) {
692 /* keep first-found weak definition, ignore subsequents */
693 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
694 /* ignore hidden symbols after */
695 } else if ((esym
->st_shndx
== SHN_COMMON
696 || esym
->st_shndx
== bss_section
->sh_num
)
697 && (shndx
< SHN_LORESERVE
698 && shndx
!= bss_section
->sh_num
)) {
699 /* data symbol gets precedence over common/bss */
701 } else if (shndx
== SHN_COMMON
|| shndx
== bss_section
->sh_num
) {
702 /* data symbol keeps precedence over common/bss */
703 } else if (s
->sh_flags
& SHF_DYNSYM
) {
704 /* we accept that two DLL define the same symbol */
705 } else if (esym
->st_other
& ST_ASM_SET
) {
706 /* If the existing symbol came from an asm .set
711 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
712 sym_bind
, shndx
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
714 tcc_error_noabort("'%s' defined twice", name
);
717 esym
->st_other
= other
;
719 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
720 esym
->st_shndx
= shndx
;
721 s1
->new_undef_sym
= 1;
722 esym
->st_value
= value
;
723 esym
->st_size
= size
;
727 sym_index
= put_elf_sym(s
, value
, size
,
728 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
735 ST_FUNC
void put_elf_reloca(Section
*symtab
, Section
*s
, unsigned long offset
,
736 int type
, int symbol
, addr_t addend
)
738 TCCState
*s1
= s
->s1
;
745 /* if no relocation section, create it */
746 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
747 /* if the symtab is allocated, then we consider the relocation
749 sr
= new_section(s
->s1
, buf
, SHT_RELX
, symtab
->sh_flags
);
750 sr
->sh_entsize
= sizeof(ElfW_Rel
);
752 sr
->sh_info
= s
->sh_num
;
755 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
756 rel
->r_offset
= offset
;
757 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
758 #if SHT_RELX == SHT_RELA
759 rel
->r_addend
= addend
;
761 if (SHT_RELX
!= SHT_RELA
&& addend
)
762 tcc_error("non-zero addend on REL architecture");
765 ST_FUNC
void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
766 int type
, int symbol
)
768 put_elf_reloca(symtab
, s
, offset
, type
, symbol
, 0);
771 ST_FUNC
struct sym_attr
*get_sym_attr(TCCState
*s1
, int index
, int alloc
)
774 struct sym_attr
*tab
;
776 if (index
>= s1
->nb_sym_attrs
) {
778 return s1
->sym_attrs
;
779 /* find immediately bigger power of 2 and reallocate array */
783 tab
= tcc_realloc(s1
->sym_attrs
, n
* sizeof(*s1
->sym_attrs
));
785 memset(s1
->sym_attrs
+ s1
->nb_sym_attrs
, 0,
786 (n
- s1
->nb_sym_attrs
) * sizeof(*s1
->sym_attrs
));
787 s1
->nb_sym_attrs
= n
;
789 return &s1
->sym_attrs
[index
];
792 static void modify_reloctions_old_to_new(TCCState
*s1
, Section
*s
, int *old_to_new_syms
)
794 int i
, type
, sym_index
;
798 for(i
= 1; i
< s1
->nb_sections
; i
++) {
799 sr
= s1
->sections
[i
];
800 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
801 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
802 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
803 type
= ELFW(R_TYPE
)(rel
->r_info
);
804 sym_index
= old_to_new_syms
[sym_index
];
805 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
811 /* In an ELF file symbol table, the local symbols must appear below
812 the global and weak ones. Since TCC cannot sort it while generating
813 the code, we must do it after. All the relocation tables are also
814 modified to take into account the symbol table sorting */
815 static void sort_syms(TCCState
*s1
, Section
*s
)
817 int *old_to_new_syms
;
822 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
823 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
824 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
826 /* first pass for local symbols */
827 p
= (ElfW(Sym
) *)s
->data
;
829 for(i
= 0; i
< nb_syms
; i
++) {
830 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
831 old_to_new_syms
[i
] = q
- new_syms
;
836 /* save the number of local symbols in section header */
837 if( s
->sh_size
) /* this 'if' makes IDA happy */
838 s
->sh_info
= q
- new_syms
;
840 /* then second pass for non local symbols */
841 p
= (ElfW(Sym
) *)s
->data
;
842 for(i
= 0; i
< nb_syms
; i
++) {
843 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
844 old_to_new_syms
[i
] = q
- new_syms
;
850 /* we copy the new symbols to the old */
851 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
854 modify_reloctions_old_to_new(s1
, s
, old_to_new_syms
);
856 tcc_free(old_to_new_syms
);
860 /* See: https://flapenguin.me/elf-dt-gnu-hash */
861 #define ELFCLASS_BITS (PTR_SIZE * 8)
863 static Section
*create_gnu_hash(TCCState
*s1
)
865 int nb_syms
, i
, ndef
, nbuckets
, symoffset
, bloom_size
, bloom_shift
;
868 Section
*dynsym
= s1
->dynsym
;
871 gnu_hash
= new_section(s1
, ".gnu.hash", SHT_GNU_HASH
, SHF_ALLOC
);
872 gnu_hash
->link
= dynsym
->hash
->link
;
874 nb_syms
= dynsym
->data_offset
/ sizeof(ElfW(Sym
));
876 /* count def symbols */
878 p
= (ElfW(Sym
) *)dynsym
->data
;
879 for(i
= 0; i
< nb_syms
; i
++, p
++)
880 ndef
+= p
->st_shndx
!= SHN_UNDEF
;
882 /* calculate gnu hash sizes and fill header */
883 nbuckets
= ndef
/ 4 + 1;
884 symoffset
= nb_syms
- ndef
;
885 bloom_shift
= PTR_SIZE
== 8 ? 6 : 5;
886 bloom_size
= 1; /* must be power of two */
887 while (ndef
>= bloom_size
* (1 << (bloom_shift
- 3)))
889 ptr
= section_ptr_add(gnu_hash
, 4 * 4 +
890 PTR_SIZE
* bloom_size
+
896 ptr
[3] = bloom_shift
;
900 static Elf32_Word
elf_gnu_hash (const unsigned char *name
)
905 while ((c
= *name
++))
910 static void update_gnu_hash(TCCState
*s1
, Section
*gnu_hash
)
912 int *old_to_new_syms
;
914 int nb_syms
, i
, nbuckets
, bloom_size
, bloom_shift
;
917 Section
*dynsym
= s1
->dynsym
;
918 Elf32_Word
*ptr
, *buckets
, *chain
, *hash
;
919 unsigned int *nextbuck
;
921 unsigned char *strtab
;
922 struct { int first
, last
; } *buck
;
924 strtab
= dynsym
->link
->data
;
925 nb_syms
= dynsym
->data_offset
/ sizeof(ElfW(Sym
));
926 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
927 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
928 hash
= tcc_malloc(nb_syms
* sizeof(Elf32_Word
));
929 nextbuck
= tcc_malloc(nb_syms
* sizeof(int));
931 /* calculate hashes and copy undefs */
932 p
= (ElfW(Sym
) *)dynsym
->data
;
934 for(i
= 0; i
< nb_syms
; i
++, p
++) {
935 if (p
->st_shndx
== SHN_UNDEF
) {
936 old_to_new_syms
[i
] = q
- new_syms
;
940 hash
[i
] = elf_gnu_hash(strtab
+ p
->st_name
);
943 ptr
= (Elf32_Word
*) gnu_hash
->data
;
946 bloom_shift
= ptr
[3];
947 bloom
= (addr_t
*) (void *) &ptr
[4];
948 buckets
= (Elf32_Word
*) (void *) &bloom
[bloom_size
];
949 chain
= &buckets
[nbuckets
];
950 buck
= tcc_malloc(nbuckets
* sizeof(*buck
));
952 if (gnu_hash
->data_offset
!= 4 * 4 +
953 PTR_SIZE
* bloom_size
+
955 (nb_syms
- (q
- new_syms
)) * 4)
956 tcc_error ("gnu_hash size incorrect");
959 for(i
= 0; i
< nbuckets
; i
++)
962 p
= (ElfW(Sym
) *)dynsym
->data
;
963 for(i
= 0; i
< nb_syms
; i
++, p
++)
964 if (p
->st_shndx
!= SHN_UNDEF
) {
965 int bucket
= hash
[i
] % nbuckets
;
967 if (buck
[bucket
].first
== -1)
968 buck
[bucket
].first
= buck
[bucket
].last
= i
;
970 nextbuck
[buck
[bucket
].last
] = i
;
971 buck
[bucket
].last
= i
;
975 /* fill buckets/chains/bloom and sort symbols */
976 p
= (ElfW(Sym
) *)dynsym
->data
;
977 for(i
= 0; i
< nbuckets
; i
++) {
978 int cur
= buck
[i
].first
;
981 buckets
[i
] = q
- new_syms
;
983 old_to_new_syms
[cur
] = q
- new_syms
;
985 *chain
++ = hash
[cur
] & ~1;
986 bloom
[(hash
[cur
] / ELFCLASS_BITS
) % bloom_size
] |=
987 (addr_t
)1 << (hash
[cur
] % ELFCLASS_BITS
) |
988 (addr_t
)1 << ((hash
[cur
] >> bloom_shift
) % ELFCLASS_BITS
);
989 if (cur
== buck
[i
].last
)
997 memcpy(dynsym
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
1003 modify_reloctions_old_to_new(s1
, dynsym
, old_to_new_syms
);
1005 /* modify the versions */
1006 vs
= versym_section
;
1008 ElfW(Half
) *newver
, *versym
= (ElfW(Half
) *)vs
->data
;
1011 newver
= tcc_malloc(nb_syms
* sizeof(*newver
));
1012 for (i
= 0; i
< nb_syms
; i
++)
1013 newver
[old_to_new_syms
[i
]] = versym
[i
];
1014 memcpy(vs
->data
, newver
, nb_syms
* sizeof(*newver
));
1019 tcc_free(old_to_new_syms
);
1022 ptr
= (Elf32_Word
*) dynsym
->hash
->data
;
1023 rebuild_hash(dynsym
, ptr
[0]);
1025 #endif /* ELF_OBJ_ONLY */
1027 /* relocate symbol table, resolve undefined symbols if do_resolve is
1028 true and output error if undefined symbol. */
1029 ST_FUNC
void relocate_syms(TCCState
*s1
, Section
*symtab
, int do_resolve
)
1032 int sym_bind
, sh_num
;
1035 for_each_elem(symtab
, 1, sym
, ElfW(Sym
)) {
1036 sh_num
= sym
->st_shndx
;
1037 if (sh_num
== SHN_UNDEF
) {
1038 if (do_resolve
== 2) /* relocating dynsym */
1040 name
= (char *) s1
->symtab
->link
->data
+ sym
->st_name
;
1041 /* Use ld.so to resolve symbol for us (for tcc -run) */
1043 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
1044 /* dlsym() needs the undecorated name. */
1045 void *addr
= dlsym(RTLD_DEFAULT
, &name
[s1
->leading_underscore
]);
1046 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD || TARGETOS_ANDROID
1049 for (i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
1050 if ((addr
= dlsym(s1
->loaded_dlls
[i
]->handle
, name
)))
1055 sym
->st_value
= (addr_t
) addr
;
1057 printf ("relocate_sym: %s -> 0x%lx\n", name
, sym
->st_value
);
1062 /* if dynamic symbol exist, it will be used in relocate_section */
1063 } else if (s1
->dynsym
&& find_elf_sym(s1
->dynsym
, name
))
1065 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1067 if (!strcmp(name
, "_fp_hw"))
1069 /* only weak symbols are accepted to be undefined. Their
1071 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
1072 if (sym_bind
== STB_WEAK
)
1075 tcc_error_noabort("undefined symbol '%s'", name
);
1077 } else if (sh_num
< SHN_LORESERVE
) {
1078 /* add section base */
1079 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1085 /* relocate a given section (CPU dependent) by applying the relocations
1086 in the associated relocation section */
1087 static void relocate_section(TCCState
*s1
, Section
*s
, Section
*sr
)
1091 int type
, sym_index
;
1094 int is_dwarf
= s
->sh_num
>= s1
->dwlo
&& s
->sh_num
< s1
->dwhi
;
1096 qrel
= (ElfW_Rel
*)sr
->data
;
1097 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
1098 ptr
= s
->data
+ rel
->r_offset
;
1099 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1100 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1101 type
= ELFW(R_TYPE
)(rel
->r_info
);
1102 tgt
= sym
->st_value
;
1103 #if SHT_RELX == SHT_RELA
1104 tgt
+= rel
->r_addend
;
1106 if (is_dwarf
&& type
== R_DATA_32DW
1107 && sym
->st_shndx
>= s1
->dwlo
&& sym
->st_shndx
< s1
->dwhi
) {
1108 /* dwarf section relocation to each other */
1109 add32le(ptr
, tgt
- s1
->sections
[sym
->st_shndx
]->sh_addr
);
1112 addr
= s
->sh_addr
+ rel
->r_offset
;
1113 relocate(s1
, rel
, type
, ptr
, addr
, tgt
);
1115 #ifndef ELF_OBJ_ONLY
1116 /* if the relocation is allocated, we change its symbol table */
1117 if (sr
->sh_flags
& SHF_ALLOC
) {
1118 sr
->link
= s1
->dynsym
;
1119 if (s1
->output_type
& TCC_OUTPUT_DYN
) {
1120 size_t r
= (uint8_t*)qrel
- sr
->data
;
1121 if (sizeof ((Stab_Sym
*)0)->n_value
< PTR_SIZE
1122 && 0 == strcmp(s
->name
, ".stab"))
1123 r
= 0; /* cannot apply 64bit relocation to 32bit value */
1124 sr
->data_offset
= sr
->sh_size
= r
;
1125 #ifdef CONFIG_TCC_PIE
1126 if (r
&& 0 == (s
->sh_flags
& SHF_WRITE
))
1127 tcc_warning("%d relocations to ro-section %s", (unsigned)(r
/ sizeof *qrel
), s
->name
);
1134 /* relocate all sections */
1135 ST_FUNC
void relocate_sections(TCCState
*s1
)
1140 for (i
= 1; i
< s1
->nb_sections
; ++i
) {
1141 sr
= s1
->sections
[i
];
1142 if (sr
->sh_type
!= SHT_RELX
)
1144 s
= s1
->sections
[sr
->sh_info
];
1145 #ifndef TCC_TARGET_MACHO
1148 || s1
->output_type
== TCC_OUTPUT_MEMORY
)
1151 relocate_section(s1
, s
, sr
);
1153 #ifndef ELF_OBJ_ONLY
1154 if (sr
->sh_flags
& SHF_ALLOC
) {
1156 /* relocate relocation table in 'sr' */
1157 for_each_elem(sr
, 0, rel
, ElfW_Rel
)
1158 rel
->r_offset
+= s
->sh_addr
;
1164 #ifndef ELF_OBJ_ONLY
1165 /* count the number of dynamic relocations so that we can reserve
1167 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
1170 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1171 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1172 defined(TCC_TARGET_RISCV64)
1174 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
1175 int sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1176 int type
= ELFW(R_TYPE
)(rel
->r_info
);
1178 #if defined(TCC_TARGET_I386)
1180 if (!get_sym_attr(s1
, sym_index
, 0)->dyn_index
1181 && ((ElfW(Sym
)*)symtab_section
->data
+ sym_index
)->st_shndx
== SHN_UNDEF
) {
1182 /* don't fixup unresolved (weak) symbols */
1183 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_386_RELATIVE
);
1186 #elif defined(TCC_TARGET_X86_64)
1190 #elif defined(TCC_TARGET_ARM)
1193 #elif defined(TCC_TARGET_ARM64)
1194 case R_AARCH64_ABS32
:
1195 case R_AARCH64_ABS64
:
1196 #elif defined(TCC_TARGET_RISCV64)
1202 #if defined(TCC_TARGET_I386)
1204 #elif defined(TCC_TARGET_X86_64)
1207 ElfW(Sym
) *sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1208 /* Hidden defined symbols can and must be resolved locally.
1209 We're misusing a PLT32 reloc for this, as that's always
1210 resolved to its address even in shared libs. */
1211 if (sym
->st_shndx
!= SHN_UNDEF
&&
1212 ELFW(ST_VISIBILITY
)(sym
->st_other
) == STV_HIDDEN
) {
1213 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PLT32
);
1217 #elif defined(TCC_TARGET_ARM64)
1218 case R_AARCH64_PREL32
:
1220 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1222 if (get_sym_attr(s1
, sym_index
, 0)->dyn_index
)
1234 #ifdef NEED_BUILD_GOT
1235 static int build_got(TCCState
*s1
)
1237 /* if no got, then create it */
1238 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
1239 s1
->got
->sh_entsize
= 4;
1240 /* keep space for _DYNAMIC pointer and two dummy got entries */
1241 section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
1242 return set_elf_sym(symtab_section
, 0, 0, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
1243 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
1246 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1247 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1248 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1249 Returns the offset of the GOT or (if any) PLT entry. */
1250 static struct sym_attr
* put_got_entry(TCCState
*s1
, int dyn_reloc_type
,
1256 struct sym_attr
*attr
;
1257 unsigned got_offset
;
1262 need_plt_entry
= (dyn_reloc_type
== R_JMP_SLOT
);
1263 attr
= get_sym_attr(s1
, sym_index
, 1);
1265 /* In case a function is both called and its address taken 2 GOT entries
1266 are created, one for taking the address (GOT) and the other for the PLT
1268 if (need_plt_entry
? attr
->plt_offset
: attr
->got_offset
)
1272 if (need_plt_entry
) {
1274 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
1275 s1
->plt
->sh_entsize
= 4;
1280 /* create the GOT entry */
1281 got_offset
= s1
->got
->data_offset
;
1282 section_ptr_add(s1
->got
, PTR_SIZE
);
1284 /* Create the GOT relocation that will insert the address of the object or
1285 function of interest in the GOT entry. This is a static relocation for
1286 memory output (dlsym will give us the address of symbols) and dynamic
1287 relocation otherwise (executable and DLLs). The relocation should be
1288 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1289 associated to a PLT entry) but is currently done at load time for an
1292 sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1293 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1294 //printf("sym %d %s\n", need_plt_entry, name);
1297 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
) {
1298 /* Hack alarm. We don't want to emit dynamic symbols
1299 and symbol based relocs for STB_LOCAL symbols, but rather
1300 want to resolve them directly. At this point the symbol
1301 values aren't final yet, so we must defer this. We will later
1302 have to create a RELATIVE reloc anyway, so we misuse the
1303 relocation slot to smuggle the symbol reference until
1304 fill_local_got_entries. Not that the sym_index is
1305 relative to symtab_section, not s1->dynsym! Nevertheless
1306 we use s1->dyn_sym so that if this is the first call
1307 that got->reloc is correctly created. Also note that
1308 RELATIVE relocs are not normally created for the .got,
1309 so the types serves as a marker for later (and is retained
1310 also for the final output, which is okay because then the
1311 got is just normal data). */
1312 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, R_RELATIVE
,
1315 if (0 == attr
->dyn_index
)
1316 attr
->dyn_index
= set_elf_sym(s1
->dynsym
, sym
->st_value
,
1317 sym
->st_size
, sym
->st_info
, 0,
1318 sym
->st_shndx
, name
);
1319 put_elf_reloc(s1
->dynsym
, s_rel
, got_offset
, dyn_reloc_type
,
1323 put_elf_reloc(symtab_section
, s1
->got
, got_offset
, dyn_reloc_type
,
1327 if (need_plt_entry
) {
1328 attr
->plt_offset
= create_plt_entry(s1
, got_offset
, attr
);
1330 /* create a symbol 'sym@plt' for the PLT jump vector */
1332 if (len
> sizeof plt_name
- 5)
1333 len
= sizeof plt_name
- 5;
1334 memcpy(plt_name
, name
, len
);
1335 strcpy(plt_name
+ len
, "@plt");
1336 attr
->plt_sym
= put_elf_sym(s1
->symtab
, attr
->plt_offset
, 0,
1337 ELFW(ST_INFO
)(STB_GLOBAL
, STT_FUNC
), 0, s1
->plt
->sh_num
, plt_name
);
1339 attr
->got_offset
= got_offset
;
1345 /* build GOT and PLT entries */
1346 /* Two passes because R_JMP_SLOT should become first. Some targets
1347 (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1348 ST_FUNC
void build_got_entries(TCCState
*s1
, int got_sym
)
1353 int i
, type
, gotplt_entry
, reloc_type
, sym_index
;
1354 struct sym_attr
*attr
;
1357 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1358 s
= s1
->sections
[i
];
1359 if (s
->sh_type
!= SHT_RELX
)
1361 /* no need to handle got relocations */
1362 if (s
->link
!= symtab_section
)
1364 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1365 type
= ELFW(R_TYPE
)(rel
->r_info
);
1366 gotplt_entry
= gotplt_entry_type(type
);
1367 if (gotplt_entry
== -1)
1368 tcc_error ("Unknown relocation type for got: %d", type
);
1369 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1370 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1372 if (gotplt_entry
== NO_GOTPLT_ENTRY
) {
1376 /* Automatically create PLT/GOT [entry] if it is an undefined
1377 reference (resolved at runtime), or the symbol is absolute,
1378 probably created by tcc_add_symbol, and thus on 64-bit
1379 targets might be too far from application code. */
1380 if (gotplt_entry
== AUTO_GOTPLT_ENTRY
) {
1381 if (sym
->st_shndx
== SHN_UNDEF
) {
1384 if (!PCRELATIVE_DLLPLT
1385 && (s1
->output_type
& TCC_OUTPUT_DYN
))
1387 /* Relocations for UNDEF symbols would normally need
1388 to be transferred into the executable or shared object.
1389 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1390 But TCC doesn't do that (at least for exes), so we
1391 need to resolve all such relocs locally. And that
1392 means PLT slots for functions in DLLs and COPY relocs for
1393 data symbols. COPY relocs were generated in
1394 bind_exe_dynsyms (and the symbol adjusted to be defined),
1395 and for functions we were generated a dynamic symbol
1396 of function type. */
1398 /* dynsym isn't set for -run :-/ */
1399 dynindex
= get_sym_attr(s1
, sym_index
, 0)->dyn_index
;
1400 esym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ dynindex
;
1402 && (ELFW(ST_TYPE
)(esym
->st_info
) == STT_FUNC
1403 || (ELFW(ST_TYPE
)(esym
->st_info
) == STT_NOTYPE
1404 && ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
)))
1407 } else if (sym
->st_shndx
== SHN_ABS
) {
1408 if (sym
->st_value
== 0) /* from tcc_add_btstub() */
1410 #ifndef TCC_TARGET_ARM
1414 /* from tcc_add_symbol(): on 64 bit platforms these
1415 need to go through .got */
1420 #ifdef TCC_TARGET_X86_64
1421 if ((type
== R_X86_64_PLT32
|| type
== R_X86_64_PC32
) &&
1422 sym
->st_shndx
!= SHN_UNDEF
&&
1423 (ELFW(ST_VISIBILITY
)(sym
->st_other
) != STV_DEFAULT
||
1424 ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
||
1425 s1
->output_type
& TCC_OUTPUT_EXE
)) {
1428 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PC32
);
1432 reloc_type
= code_reloc(type
);
1433 if (reloc_type
== -1)
1434 tcc_error ("Unknown relocation type: %d", type
);
1436 if (reloc_type
!= 0) {
1440 reloc_type
= R_JMP_SLOT
;
1444 reloc_type
= R_GLOB_DAT
;
1448 got_sym
= build_got(s1
);
1450 if (gotplt_entry
== BUILD_GOT_ONLY
)
1453 attr
= put_got_entry(s1
, reloc_type
, sym_index
);
1455 if (reloc_type
== R_JMP_SLOT
)
1456 rel
->r_info
= ELFW(R_INFO
)(attr
->plt_sym
, type
);
1461 /* .rel.plt refers to .got actually */
1462 if (s1
->plt
&& s1
->plt
->reloc
)
1463 s1
->plt
->reloc
->sh_info
= s1
->got
->sh_num
;
1464 if (got_sym
) /* set size */
1465 ((ElfW(Sym
)*)symtab_section
->data
)[got_sym
].st_size
= s1
->got
->data_offset
;
1467 #endif /* def NEED_BUILD_GOT */
1469 ST_FUNC
int set_global_sym(TCCState
*s1
, const char *name
, Section
*sec
, addr_t offs
)
1471 int shn
= sec
? sec
->sh_num
: offs
|| !name
? SHN_ABS
: SHN_UNDEF
;
1472 if (sec
&& offs
== -1)
1473 offs
= sec
->data_offset
;
1474 return set_elf_sym(symtab_section
, offs
, 0,
1475 ELFW(ST_INFO
)(name
? STB_GLOBAL
: STB_LOCAL
, STT_NOTYPE
), 0, shn
, name
);
1478 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1483 s
= have_section(s1
, section_name
);
1484 if (!s
|| !(s
->sh_flags
& SHF_ALLOC
)) {
1488 end_offset
= s
->data_offset
;
1490 snprintf(buf
, sizeof(buf
), "__%s_start", section_name
+ 1);
1491 set_global_sym(s1
, buf
, s
, 0);
1492 snprintf(buf
, sizeof(buf
), "__%s_end", section_name
+ 1);
1493 set_global_sym(s1
, buf
, s
, end_offset
);
1496 ST_FUNC
void add_array (TCCState
*s1
, const char *sec
, int c
)
1499 s
= find_section(s1
, sec
);
1500 s
->sh_flags
= shf_RELRO
;
1501 s
->sh_type
= sec
[1] == 'i' ? SHT_INIT_ARRAY
: SHT_FINI_ARRAY
;
1502 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1503 section_ptr_add(s
, PTR_SIZE
);
1506 #ifdef CONFIG_TCC_BCHECK
1507 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
1509 if (0 == s1
->do_bounds_check
)
1511 section_ptr_add(bounds_section
, sizeof(addr_t
));
1515 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1516 a dynamic symbol to allow so's to have one each with a different value. */
1517 static void set_local_sym(TCCState
*s1
, const char *name
, Section
*s
, int offset
)
1519 int c
= find_elf_sym(s1
->symtab
, name
);
1521 ElfW(Sym
) *esym
= (ElfW(Sym
)*)s1
->symtab
->data
+ c
;
1522 esym
->st_info
= ELFW(ST_INFO
)(STB_LOCAL
, STT_NOTYPE
);
1523 esym
->st_value
= offset
;
1524 esym
->st_shndx
= s
->sh_num
;
1528 /* avoid generating debug/test_coverage code for stub functions */
1529 static void tcc_compile_string_no_debug(TCCState
*s
, const char *str
)
1531 int save_do_debug
= s
->do_debug
;
1532 int save_test_coverage
= s
->test_coverage
;
1535 s
->test_coverage
= 0;
1536 tcc_compile_string(s
, str
);
1537 s
->do_debug
= save_do_debug
;
1538 s
->test_coverage
= save_test_coverage
;
1541 #ifdef CONFIG_TCC_BACKTRACE
1542 static void put_ptr(TCCState
*s1
, Section
*s
, int offs
)
1545 c
= set_global_sym(s1
, NULL
, s
, offs
);
1547 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1548 section_ptr_add(s
, PTR_SIZE
);
1551 ST_FUNC
void tcc_add_btstub(TCCState
*s1
)
1558 /* Align to PTR_SIZE */
1559 section_ptr_add(s
, -s
->data_offset
& (PTR_SIZE
- 1));
1561 /* create (part of) a struct rt_context (see tccrun.c) */
1563 put_ptr(s1
, dwarf_line_section
, 0);
1564 put_ptr(s1
, dwarf_line_section
, -1);
1566 put_ptr(s1
, dwarf_line_str_section
, 0);
1568 put_ptr(s1
, dwarf_str_section
, 0);
1572 put_ptr(s1
, stab_section
, 0);
1573 put_ptr(s1
, stab_section
, -1);
1574 put_ptr(s1
, stab_section
->link
, 0);
1576 *(addr_t
*)section_ptr_add(s
, PTR_SIZE
) = s1
->dwarf
;
1577 /* skip esym_start/esym_end/elf_str (not loaded) */
1578 section_ptr_add(s
, 3 * PTR_SIZE
);
1579 /* prog_base : local nameless symbol with offset 0 at SHN_ABS */
1580 put_ptr(s1
, NULL
, 0);
1581 #if defined TCC_TARGET_MACHO
1582 /* adjust for __PAGEZERO */
1583 if (s1
->dwarf
== 0 && s1
->output_type
== TCC_OUTPUT_EXE
)
1584 write64le(data_section
->data
+ data_section
->data_offset
- PTR_SIZE
,
1588 #ifdef CONFIG_TCC_BCHECK
1589 if (s1
->do_bounds_check
) {
1590 put_ptr(s1
, bounds_section
, 0);
1594 section_ptr_add(s
, n
);
1597 "extern void __bt_init(),__bt_exit(),__bt_init_dll();"
1598 "static void *__rt_info[];"
1599 "__attribute__((constructor)) static void __bt_init_rt(){");
1600 #ifdef TCC_TARGET_PE
1601 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1602 #ifdef CONFIG_TCC_BCHECK
1603 cstr_printf(&cstr
, "__bt_init_dll(%d);", s1
->do_bounds_check
);
1605 cstr_printf(&cstr
, "__bt_init_dll(0);");
1608 cstr_printf(&cstr
, "__bt_init(__rt_info,%d);}",
1609 s1
->output_type
== TCC_OUTPUT_DLL
? 0 : s1
->rt_num_callers
+ 1);
1610 /* In case dlcose is called by application */
1612 "__attribute__((destructor)) static void __bt_exit_rt(){"
1613 "__bt_exit(__rt_info);}");
1614 tcc_compile_string_no_debug(s1
, cstr
.data
);
1616 set_local_sym(s1
, &"___rt_info"[!s1
->leading_underscore
], s
, o
);
1618 #endif /* def CONFIG_TCC_BACKTRACE */
1620 static void tcc_tcov_add_file(TCCState
*s1
, const char *filename
)
1626 if (tcov_section
== NULL
)
1628 section_ptr_add(tcov_section
, 1);
1629 write32le (tcov_section
->data
, tcov_section
->data_offset
);
1632 if (filename
[0] == '/')
1633 cstr_printf (&cstr
, "%s.tcov", filename
);
1635 getcwd (wd
, sizeof(wd
));
1636 cstr_printf (&cstr
, "%s/%s.tcov", wd
, filename
);
1638 ptr
= section_ptr_add(tcov_section
, cstr
.size
+ 1);
1639 strcpy((char *)ptr
, cstr
.data
);
1640 unlink((char *)ptr
);
1642 normalize_slashes((char *)ptr
);
1648 "extern char *__tcov_data[];"
1649 "extern void __store_test_coverage ();"
1650 "__attribute__((destructor)) static void __tcov_exit() {"
1651 "__store_test_coverage(__tcov_data);"
1653 tcc_compile_string_no_debug(s1
, cstr
.data
);
1655 set_local_sym(s1
, &"___tcov_data"[!s1
->leading_underscore
], tcov_section
, 0);
1658 #ifndef TCC_TARGET_PE
1659 /* add tcc runtime libraries */
1660 ST_FUNC
void tcc_add_runtime(TCCState
*s1
)
1664 #ifdef CONFIG_TCC_BCHECK
1667 tcc_add_pragma_libs(s1
);
1670 if (!s1
->nostdlib
) {
1671 int lpthread
= s1
->option_pthread
;
1673 #ifdef CONFIG_TCC_BCHECK
1674 if (s1
->do_bounds_check
&& s1
->output_type
!= TCC_OUTPUT_DLL
) {
1675 tcc_add_support(s1
, "bcheck.o");
1676 # if !(TARGETOS_OpenBSD || TARGETOS_NetBSD)
1677 tcc_add_library_err(s1
, "dl");
1682 #ifdef CONFIG_TCC_BACKTRACE
1683 if (s1
->do_backtrace
) {
1684 if (s1
->output_type
& TCC_OUTPUT_EXE
)
1685 tcc_add_support(s1
, "bt-exe.o");
1686 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1687 tcc_add_support(s1
, "bt-log.o");
1688 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1693 tcc_add_library_err(s1
, "pthread");
1694 tcc_add_library_err(s1
, "c");
1696 if (!s1
->static_link
) {
1697 if (TCC_LIBGCC
[0] == '/')
1698 tcc_add_file(s1
, TCC_LIBGCC
);
1700 tcc_add_dll(s1
, TCC_LIBGCC
, 0);
1703 #if defined TCC_TARGET_ARM && TARGETOS_FreeBSD
1704 tcc_add_library_err(s1
, "gcc_s"); // unwind code
1707 tcc_add_support(s1
, TCC_LIBTCC1
);
1709 /* add crt end if not memory output */
1710 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1711 #if defined TCC_TARGET_MACHO
1713 #elif TARGETOS_FreeBSD || TARGETOS_NetBSD
1714 if (s1
->output_type
& TCC_OUTPUT_DYN
)
1715 tcc_add_crt(s1
, "crtendS.o");
1717 tcc_add_crt(s1
, "crtend.o");
1718 tcc_add_crt(s1
, "crtn.o");
1719 #elif TARGETOS_OpenBSD
1720 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1721 tcc_add_crt(s1
, "crtendS.o");
1723 tcc_add_crt(s1
, "crtend.o");
1724 #elif TARGETOS_ANDROID
1725 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1726 tcc_add_crt(s1
, "crtend_so.o");
1728 tcc_add_crt(s1
, "crtend_android.o");
1730 tcc_add_crt(s1
, "crtn.o");
1735 #endif /* ndef TCC_TARGET_PE */
1737 /* add various standard linker symbols (must be done after the
1738 sections are filled (for example after allocating common
1740 static void tcc_add_linker_symbols(TCCState
*s1
)
1746 set_global_sym(s1
, "_etext", text_section
, -1);
1747 set_global_sym(s1
, "_edata", data_section
, -1);
1748 set_global_sym(s1
, "_end", bss_section
, -1);
1749 #if TARGETOS_OpenBSD
1750 set_global_sym(s1
, "__executable_start", NULL
, ELF_START_ADDR
);
1752 #ifdef TCC_TARGET_RISCV64
1753 /* XXX should be .sdata+0x800, not .data+0x800 */
1754 set_global_sym(s1
, "__global_pointer$", data_section
, 0x800);
1756 /* horrible new standard ldscript defines */
1757 add_init_array_defines(s1
, ".preinit_array");
1758 add_init_array_defines(s1
, ".init_array");
1759 add_init_array_defines(s1
, ".fini_array");
1760 /* add start and stop symbols for sections whose name can be
1762 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1763 s
= s1
->sections
[i
];
1764 if ((s
->sh_flags
& SHF_ALLOC
)
1765 && (s
->sh_type
== SHT_PROGBITS
1766 || s
->sh_type
== SHT_STRTAB
)) {
1768 /* check if section name can be expressed in C */
1774 if (!isid(c
) && !isnum(c
))
1778 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1779 set_global_sym(s1
, buf
, s
, 0);
1780 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1781 set_global_sym(s1
, buf
, s
, -1);
1787 ST_FUNC
void resolve_common_syms(TCCState
*s1
)
1791 /* Allocate common symbols in BSS. */
1792 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1793 if (sym
->st_shndx
== SHN_COMMON
) {
1794 /* symbol alignment is in st_value for SHN_COMMONs */
1795 sym
->st_value
= section_add(bss_section
, sym
->st_size
,
1797 sym
->st_shndx
= bss_section
->sh_num
;
1801 /* Now assign linker provided symbols their value. */
1802 tcc_add_linker_symbols(s1
);
1805 #ifndef ELF_OBJ_ONLY
1806 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1808 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1809 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1810 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1811 unsigned offset
= attr
->got_offset
;
1815 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1817 write64le(s1
->got
->data
+ offset
, sym
->st_value
);
1819 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1823 /* Perform relocation to GOT or PLT entries */
1824 ST_FUNC
void fill_got(TCCState
*s1
)
1830 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1831 s
= s1
->sections
[i
];
1832 if (s
->sh_type
!= SHT_RELX
)
1834 /* no need to handle got relocations */
1835 if (s
->link
!= symtab_section
)
1837 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1838 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1839 case R_X86_64_GOT32
:
1840 case R_X86_64_GOTPCREL
:
1841 case R_X86_64_GOTPCRELX
:
1842 case R_X86_64_REX_GOTPCRELX
:
1843 case R_X86_64_PLT32
:
1844 fill_got_entry(s1
, rel
);
1851 /* See put_got_entry for a description. This is the second stage
1852 where GOT references to local defined symbols are rewritten. */
1853 static void fill_local_got_entries(TCCState
*s1
)
1856 if (!s1
->got
->reloc
)
1858 for_each_elem(s1
->got
->reloc
, 0, rel
, ElfW_Rel
) {
1859 if (ELFW(R_TYPE
)(rel
->r_info
) == R_RELATIVE
) {
1860 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1861 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1862 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1863 unsigned offset
= attr
->got_offset
;
1864 if (offset
!= rel
->r_offset
- s1
->got
->sh_addr
)
1865 tcc_error_noabort("huh");
1866 rel
->r_info
= ELFW(R_INFO
)(0, R_RELATIVE
);
1867 #if SHT_RELX == SHT_RELA
1868 rel
->r_addend
= sym
->st_value
;
1870 /* All our REL architectures also happen to be 32bit LE. */
1871 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1877 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1878 in shared libraries */
1879 static void bind_exe_dynsyms(TCCState
*s1
)
1882 int sym_index
, index
;
1883 ElfW(Sym
) *sym
, *esym
;
1886 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1887 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1888 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1889 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1890 if (sym
->st_shndx
== SHN_UNDEF
) {
1891 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1892 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1894 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1895 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1896 if ((type
== STT_FUNC
) || (type
== STT_GNU_IFUNC
)) {
1897 /* Indirect functions shall have STT_FUNC type in executable
1898 * dynsym section. Indeed, a dlsym call following a lazy
1899 * resolution would pick the symbol value from the
1900 * executable dynsym entry which would contain the address
1901 * of the function wanted by the caller of dlsym instead of
1902 * the address of the function that would return that
1905 = put_elf_sym(s1
->dynsym
, 0, esym
->st_size
,
1906 ELFW(ST_INFO
)(STB_GLOBAL
,STT_FUNC
), 0, 0,
1908 int index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1909 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1910 } else if (type
== STT_OBJECT
) {
1911 unsigned long offset
;
1913 offset
= bss_section
->data_offset
;
1914 /* XXX: which alignment ? */
1915 offset
= (offset
+ 16 - 1) & -16;
1916 set_elf_sym (s1
->symtab
, offset
, esym
->st_size
,
1917 esym
->st_info
, 0, bss_section
->sh_num
, name
);
1918 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1919 esym
->st_info
, 0, bss_section
->sh_num
,
1922 /* Ensure R_COPY works for weak symbol aliases */
1923 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1924 for_each_elem(s1
->dynsymtab_section
, 1, dynsym
, ElfW(Sym
)) {
1925 if ((dynsym
->st_value
== esym
->st_value
)
1926 && (ELFW(ST_BIND
)(dynsym
->st_info
) == STB_GLOBAL
)) {
1927 char *dynname
= (char *) s1
->dynsymtab_section
->link
->data
1929 put_elf_sym(s1
->dynsym
, offset
, dynsym
->st_size
,
1931 bss_section
->sh_num
, dynname
);
1937 put_elf_reloc(s1
->dynsym
, bss_section
,
1938 offset
, R_COPY
, index
);
1939 offset
+= esym
->st_size
;
1940 bss_section
->data_offset
= offset
;
1943 /* STB_WEAK undefined symbols are accepted */
1944 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1945 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1946 !strcmp(name
, "_fp_hw")) {
1948 tcc_error_noabort("undefined symbol '%s'", name
);
1955 /* Bind symbols of libraries: export all non local symbols of executable that
1956 are referenced by shared libraries. The reason is that the dynamic loader
1957 search symbol first in executable and then in libraries. Therefore a
1958 reference to a symbol already defined by a library can still be resolved by
1959 a symbol in the executable. With -rdynamic, export all defined symbols */
1960 static void bind_libs_dynsyms(TCCState
*s1
)
1964 ElfW(Sym
) *sym
, *esym
;
1966 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1967 name
= (char *)symtab_section
->link
->data
+ sym
->st_name
;
1968 dynsym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1969 if (sym
->st_shndx
!= SHN_UNDEF
1970 && ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1971 if (dynsym_index
|| s1
->rdynamic
)
1972 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1973 sym
->st_info
, 0, sym
->st_shndx
, name
);
1974 } else if (dynsym_index
) {
1975 esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ dynsym_index
;
1976 if (esym
->st_shndx
== SHN_UNDEF
) {
1977 /* weak symbols can stay undefined */
1978 if (ELFW(ST_BIND
)(esym
->st_info
) != STB_WEAK
)
1979 tcc_warning("undefined dynamic symbol '%s'", name
);
1985 /* Export all non local symbols. This is used by shared libraries so that the
1986 non local symbols they define can resolve a reference in another shared
1987 library or in the executable. Correspondingly, it allows undefined local
1988 symbols to be resolved by other shared libraries or by the executable. */
1989 static void export_global_syms(TCCState
*s1
)
1991 int dynindex
, index
;
1994 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1995 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1996 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1997 dynindex
= set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1998 sym
->st_info
, 0, sym
->st_shndx
, name
);
1999 index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
2000 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
2005 /* decide if an unallocated section should be output. */
2006 static int set_sec_sizes(TCCState
*s1
)
2011 int file_type
= s1
->output_type
;
2013 /* Allocate strings for section names */
2014 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2015 s
= s1
->sections
[i
];
2016 if (s
->sh_type
== SHT_RELX
&& !(s
->sh_flags
& SHF_ALLOC
)) {
2017 /* when generating a DLL, we include relocations but
2018 we may patch them */
2019 if ((file_type
& TCC_OUTPUT_DYN
)
2020 && (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)) {
2021 int count
= prepare_dynamic_rel(s1
, s
);
2023 /* allocate the section */
2024 s
->sh_flags
|= SHF_ALLOC
;
2025 s
->sh_size
= count
* sizeof(ElfW_Rel
);
2026 if (!(s1
->sections
[s
->sh_info
]->sh_flags
& SHF_WRITE
))
2030 } else if ((s
->sh_flags
& SHF_ALLOC
)
2031 #ifdef TCC_TARGET_ARM
2032 || s
->sh_type
== SHT_ARM_ATTRIBUTES
2035 s
->sh_size
= s
->data_offset
;
2038 #ifdef TCC_TARGET_ARM
2039 /* XXX: Suppress stack unwinding section. */
2040 if (s
->sh_type
== SHT_ARM_EXIDX
) {
2050 /* various data used under elf_output_file() */
2055 /* Info to be copied in dynamic section */
2056 unsigned long data_offset
;
2067 /* read only segment mapping for GNU_RELRO */
2068 Section _roinf
, *roinf
;
2071 /* Decide the layout of sections loaded in memory. This must be done before
2072 program headers are filled since they contain info about the layout.
2073 We do the following ordering: interp, symbol tables, relocations, progbits,
2075 static int sort_sections(TCCState
*s1
, int *sec_order
, Section
*interp
)
2078 int i
, j
, k
, f
, f0
, n
;
2079 int nb_sections
= s1
->nb_sections
;
2080 int *sec_cls
= sec_order
+ nb_sections
;
2082 for (i
= 1; i
< nb_sections
; i
++) {
2083 s
= s1
->sections
[i
];
2084 if (s
->sh_flags
& SHF_ALLOC
) {
2086 if (s
->sh_flags
& SHF_WRITE
)
2088 if (s
->sh_flags
& SHF_TLS
)
2090 } else if (s
->sh_name
) {
2093 j
= 0x900; /* no sh_name: won't go to file */
2095 if (s
->sh_type
== SHT_SYMTAB
|| s
->sh_type
== SHT_DYNSYM
) {
2097 } else if (s
->sh_type
== SHT_STRTAB
&& strcmp(s
->name
, ".stabstr")) {
2099 if (i
== nb_sections
- 1) /* ".shstrtab" assumed to remain last */
2101 } else if (s
->sh_type
== SHT_HASH
|| s
->sh_type
== SHT_GNU_HASH
) {
2103 } else if (s
->sh_type
== SHT_RELX
) {
2105 if (s1
->plt
&& s
== s1
->plt
->reloc
)
2107 } else if (s
->sh_type
== SHT_PREINIT_ARRAY
) {
2109 } else if (s
->sh_type
== SHT_INIT_ARRAY
) {
2111 } else if (s
->sh_type
== SHT_FINI_ARRAY
) {
2113 #ifdef CONFIG_TCC_BCHECK
2114 } else if (s
== bounds_section
|| s
== lbounds_section
) {
2117 } else if (s
== rodata_section
|| 0 == strcmp(s
->name
, ".data.rel.ro")) {
2119 } else if (s
->sh_type
== SHT_DYNAMIC
) {
2121 } else if (s
== s1
->got
) {
2122 k
= 0x47; /* .got as RELRO needs BIND_NOW in DT_FLAGS */
2125 if (s
->sh_type
== SHT_NOTE
)
2127 if (s
->sh_flags
& SHF_EXECINSTR
)
2129 if (s
->sh_type
== SHT_NOBITS
)
2136 for (n
= i
; n
> 1 && k
< (f
= sec_cls
[n
- 1]); --n
)
2137 sec_cls
[n
] = f
, sec_order
[n
] = sec_order
[n
- 1];
2138 sec_cls
[n
] = k
, sec_order
[n
] = i
;
2142 /* count PT_LOAD headers needed */
2144 for (i
= 1; i
< nb_sections
; i
++) {
2145 s
= s1
->sections
[sec_order
[i
]];
2149 f
= s
->sh_flags
& (SHF_ALLOC
|SHF_WRITE
|SHF_EXECINSTR
|SHF_TLS
);
2151 /* NetBSD only supports 2 PT_LOAD sections.
2152 See: https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */
2153 if ((f
& SHF_WRITE
) == 0) f
|= SHF_EXECINSTR
;
2155 if ((k
& 0xfff0) == 0x240) /* RELRO sections */
2158 if (f
!= f0
) /* start new header when flags changed or relro */
2159 f0
= f
, ++n
, f
|= 1<<8;
2162 //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);
2167 static ElfW(Phdr
) *fill_phdr(ElfW(Phdr
) *ph
, int type
, Section
*s
)
2170 ph
->p_offset
= s
->sh_offset
;
2171 ph
->p_vaddr
= s
->sh_addr
;
2172 ph
->p_filesz
= s
->sh_size
;
2173 ph
->p_align
= s
->sh_addralign
;
2177 ph
->p_paddr
= ph
->p_vaddr
;
2178 ph
->p_memsz
= ph
->p_filesz
;
2182 /* Assign sections to segments and decide how are sections laid out when loaded
2183 in memory. This function also fills corresponding program headers. */
2184 static int layout_sections(TCCState
*s1
, int *sec_order
, struct dyn_inf
*d
)
2187 addr_t addr
, tmp
, align
, s_align
, base
;
2188 ElfW(Phdr
) *ph
= NULL
;
2189 int i
, f
, n
, phnum
, phfill
;
2192 /* compute number of program headers */
2193 phnum
= sort_sections(s1
, sec_order
, d
->interp
);
2194 phfill
= 0; /* set to 1 to have dll's with a PT_PHDR */
2205 d
->phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
2208 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2209 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2211 s_align
= ELF_PAGE_SIZE
;
2212 if (s1
->section_align
)
2213 s_align
= s1
->section_align
;
2215 addr
= ELF_START_ADDR
;
2216 if (s1
->output_type
& TCC_OUTPUT_DYN
)
2219 if (s1
->has_text_addr
) {
2220 addr
= s1
->text_addr
;
2222 int a_offset
, p_offset
;
2223 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
2225 a_offset
= (int) (addr
& (s_align
- 1));
2226 p_offset
= file_offset
& (s_align
- 1);
2227 if (a_offset
< p_offset
)
2228 a_offset
+= s_align
;
2229 file_offset
+= (a_offset
- p_offset
);
2233 /* compute address after headers */
2234 addr
= addr
+ (file_offset
& (s_align
- 1));
2237 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2238 s
= s1
->sections
[sec_order
[i
]];
2239 f
= sec_order
[i
+ s1
->nb_sections
];
2240 align
= s
->sh_addralign
- 1;
2242 if (f
== 0) { /* no alloc */
2243 file_offset
= (file_offset
+ align
) & ~align
;
2244 s
->sh_offset
= file_offset
;
2245 if (s
->sh_type
!= SHT_NOBITS
)
2246 file_offset
+= s
->sh_size
;
2250 if ((f
& 1<<8) && n
) {
2251 /* different rwx section flags */
2252 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
2253 /* if in the middle of a page, w e duplicate the page in
2254 memory so that one copy is RX and the other is RW */
2255 if ((addr
& (s_align
- 1)) != 0)
2258 align
= s_align
- 1;
2263 addr
= (addr
+ align
) & ~align
;
2264 file_offset
+= (int)(addr
- tmp
);
2265 s
->sh_offset
= file_offset
;
2269 /* set new program header */
2270 ph
= &d
->phdr
[phfill
+ n
];
2271 ph
->p_type
= PT_LOAD
;
2272 ph
->p_align
= s_align
;
2275 ph
->p_flags
|= PF_W
;
2276 if (f
& SHF_EXECINSTR
)
2277 ph
->p_flags
|= PF_X
;
2279 ph
->p_type
= PT_TLS
;
2282 ph
->p_offset
= file_offset
;
2285 /* Make the first PT_LOAD segment include the program
2286 headers itself (and the ELF header as well), it'll
2287 come out with same memory use but will make various
2288 tools like binutils strip work better. */
2292 ph
->p_paddr
= ph
->p_vaddr
;
2297 Section
*roinf
= &d
->_roinf
;
2298 if (roinf
->sh_size
== 0) {
2299 roinf
->sh_offset
= s
->sh_offset
;
2300 roinf
->sh_addr
= s
->sh_addr
;
2301 roinf
->sh_addralign
= 1;
2303 roinf
->sh_size
= (addr
- roinf
->sh_addr
) + s
->sh_size
;
2307 if (s
->sh_type
!= SHT_NOBITS
)
2308 file_offset
+= s
->sh_size
;
2310 ph
->p_filesz
= file_offset
- ph
->p_offset
;
2311 ph
->p_memsz
= addr
- ph
->p_vaddr
;
2314 /* Fill other headers */
2316 fill_phdr(++ph
, PT_NOTE
, d
->note
);
2318 fill_phdr(++ph
, PT_DYNAMIC
, d
->dynamic
)->p_flags
|= PF_W
;
2320 fill_phdr(++ph
, PT_GNU_RELRO
, d
->roinf
)->p_flags
|= PF_W
;
2322 fill_phdr(&d
->phdr
[1], PT_INTERP
, d
->interp
);
2325 ph
->p_offset
= sizeof(ElfW(Ehdr
));
2326 ph
->p_vaddr
= base
+ ph
->p_offset
;
2327 ph
->p_filesz
= phnum
* sizeof(ElfW(Phdr
));
2329 fill_phdr(ph
, PT_PHDR
, NULL
);
2334 /* put dynamic tag */
2335 static void put_dt(Section
*dynamic
, int dt
, addr_t val
)
2338 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
2340 dyn
->d_un
.d_val
= val
;
2343 /* Fill the dynamic section with tags describing the address and size of
2345 static void fill_dynamic(TCCState
*s1
, struct dyn_inf
*dyninf
)
2347 Section
*dynamic
= dyninf
->dynamic
;
2350 /* put dynamic section entries */
2351 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
2352 put_dt(dynamic
, DT_GNU_HASH
, dyninf
->gnu_hash
->sh_addr
);
2353 put_dt(dynamic
, DT_STRTAB
, dyninf
->dynstr
->sh_addr
);
2354 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
2355 put_dt(dynamic
, DT_STRSZ
, dyninf
->dynstr
->data_offset
);
2356 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
2358 put_dt(dynamic
, DT_RELA
, dyninf
->rel_addr
);
2359 put_dt(dynamic
, DT_RELASZ
, dyninf
->rel_size
);
2360 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
2361 if (s1
->plt
&& s1
->plt
->reloc
) {
2362 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2363 put_dt(dynamic
, DT_PLTRELSZ
, s1
->plt
->reloc
->data_offset
);
2364 put_dt(dynamic
, DT_JMPREL
, s1
->plt
->reloc
->sh_addr
);
2365 put_dt(dynamic
, DT_PLTREL
, DT_RELA
);
2367 put_dt(dynamic
, DT_RELACOUNT
, 0);
2369 put_dt(dynamic
, DT_REL
, dyninf
->rel_addr
);
2370 put_dt(dynamic
, DT_RELSZ
, dyninf
->rel_size
);
2371 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
2372 if (s1
->plt
&& s1
->plt
->reloc
) {
2373 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2374 put_dt(dynamic
, DT_PLTRELSZ
, s1
->plt
->reloc
->data_offset
);
2375 put_dt(dynamic
, DT_JMPREL
, s1
->plt
->reloc
->sh_addr
);
2376 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
2378 put_dt(dynamic
, DT_RELCOUNT
, 0);
2380 if (versym_section
&& verneed_section
) {
2381 /* The dynamic linker can not handle VERSYM without VERNEED */
2382 put_dt(dynamic
, DT_VERSYM
, versym_section
->sh_addr
);
2383 put_dt(dynamic
, DT_VERNEED
, verneed_section
->sh_addr
);
2384 put_dt(dynamic
, DT_VERNEEDNUM
, dt_verneednum
);
2386 s
= have_section(s1
, ".preinit_array");
2387 if (s
&& s
->data_offset
) {
2388 put_dt(dynamic
, DT_PREINIT_ARRAY
, s
->sh_addr
);
2389 put_dt(dynamic
, DT_PREINIT_ARRAYSZ
, s
->data_offset
);
2391 s
= have_section(s1
, ".init_array");
2392 if (s
&& s
->data_offset
) {
2393 put_dt(dynamic
, DT_INIT_ARRAY
, s
->sh_addr
);
2394 put_dt(dynamic
, DT_INIT_ARRAYSZ
, s
->data_offset
);
2396 s
= have_section(s1
, ".fini_array");
2397 if (s
&& s
->data_offset
) {
2398 put_dt(dynamic
, DT_FINI_ARRAY
, s
->sh_addr
);
2399 put_dt(dynamic
, DT_FINI_ARRAYSZ
, s
->data_offset
);
2401 s
= have_section(s1
, ".init");
2402 if (s
&& s
->data_offset
) {
2403 put_dt(dynamic
, DT_INIT
, s
->sh_addr
);
2405 s
= have_section(s1
, ".fini");
2406 if (s
&& s
->data_offset
) {
2407 put_dt(dynamic
, DT_FINI
, s
->sh_addr
);
2410 put_dt(dynamic
, DT_DEBUG
, 0);
2411 put_dt(dynamic
, DT_NULL
, 0);
2414 /* Remove gaps between RELX sections.
2415 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2416 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2417 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2418 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2419 static void update_reloc_sections(TCCState
*s1
, struct dyn_inf
*dyninf
)
2422 unsigned long file_offset
= 0;
2424 Section
*relocplt
= s1
->plt
? s1
->plt
->reloc
: NULL
;
2426 /* dynamic relocation table information, for .dynamic section */
2427 dyninf
->rel_addr
= dyninf
->rel_size
= 0;
2429 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2430 s
= s1
->sections
[i
];
2431 if (s
->sh_type
== SHT_RELX
&& s
!= relocplt
) {
2432 if (dyninf
->rel_size
== 0) {
2433 dyninf
->rel_addr
= s
->sh_addr
;
2434 file_offset
= s
->sh_offset
;
2437 s
->sh_addr
= dyninf
->rel_addr
+ dyninf
->rel_size
;
2438 s
->sh_offset
= file_offset
+ dyninf
->rel_size
;
2440 dyninf
->rel_size
+= s
->sh_size
;
2445 static int tidy_section_headers(TCCState
*s1
, int *sec_order
);
2446 #endif /* ndef ELF_OBJ_ONLY */
2448 /* Create an ELF file on disk.
2449 This function handle ELF specific layout requirements */
2450 static void tcc_output_elf(TCCState
*s1
, FILE *f
, int phnum
, ElfW(Phdr
) *phdr
,
2451 int file_offset
, int *sec_order
)
2453 int i
, shnum
, offset
, size
, file_type
;
2456 ElfW(Shdr
) shdr
, *sh
;
2458 file_type
= s1
->output_type
;
2459 shnum
= s1
->nb_sections
;
2461 memset(&ehdr
, 0, sizeof(ehdr
));
2464 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2465 ehdr
.e_phnum
= phnum
;
2466 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2467 #ifndef ELF_OBJ_ONLY
2468 shnum
= tidy_section_headers(s1
, sec_order
);
2473 file_offset
= (file_offset
+ 3) & -4;
2476 ehdr
.e_ident
[0] = ELFMAG0
;
2477 ehdr
.e_ident
[1] = ELFMAG1
;
2478 ehdr
.e_ident
[2] = ELFMAG2
;
2479 ehdr
.e_ident
[3] = ELFMAG3
;
2480 ehdr
.e_ident
[4] = ELFCLASSW
;
2481 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2482 ehdr
.e_ident
[6] = EV_CURRENT
;
2484 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2485 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2486 #elif defined TCC_TARGET_ARM && defined TCC_ARM_EABI
2487 ehdr
.e_flags
= EF_ARM_EABI_VER5
;
2488 ehdr
.e_flags
|= s1
->float_abi
== ARM_HARD_FLOAT
2489 ? EF_ARM_VFP_FLOAT
: EF_ARM_SOFT_FLOAT
;
2490 #elif defined TCC_TARGET_ARM
2491 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2492 #elif defined TCC_TARGET_RISCV64
2493 ehdr
.e_flags
= EF_RISCV_FLOAT_ABI_DOUBLE
;
2496 if (file_type
== TCC_OUTPUT_OBJ
) {
2497 ehdr
.e_type
= ET_REL
;
2499 if (file_type
& TCC_OUTPUT_DYN
)
2500 ehdr
.e_type
= ET_DYN
;
2502 ehdr
.e_type
= ET_EXEC
;
2503 if (s1
->elf_entryname
)
2504 ehdr
.e_entry
= get_sym_addr(s1
, s1
->elf_entryname
, 1, 0);
2506 ehdr
.e_entry
= get_sym_addr(s1
, "_start", !!(file_type
& TCC_OUTPUT_EXE
), 0);
2507 if (ehdr
.e_entry
== (addr_t
)-1)
2508 ehdr
.e_entry
= text_section
->sh_addr
;
2511 ehdr
.e_machine
= EM_TCC_TARGET
;
2512 ehdr
.e_version
= EV_CURRENT
;
2513 ehdr
.e_shoff
= file_offset
;
2514 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2515 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2516 ehdr
.e_shnum
= shnum
;
2517 ehdr
.e_shstrndx
= shnum
- 1;
2519 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2521 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2522 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2524 sort_syms(s1
, symtab_section
);
2526 for(i
= 1; i
< shnum
; i
++) {
2527 s
= s1
->sections
[sec_order
? sec_order
[i
] : i
];
2528 if (s
->sh_type
!= SHT_NOBITS
) {
2529 while (offset
< s
->sh_offset
) {
2535 fwrite(s
->data
, 1, size
, f
);
2540 /* output section headers */
2541 while (offset
< ehdr
.e_shoff
) {
2546 for(i
= 0; i
< shnum
; i
++) {
2548 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2549 s
= s1
->sections
[i
];
2551 sh
->sh_name
= s
->sh_name
;
2552 sh
->sh_type
= s
->sh_type
;
2553 sh
->sh_flags
= s
->sh_flags
;
2554 sh
->sh_entsize
= s
->sh_entsize
;
2555 sh
->sh_info
= s
->sh_info
;
2557 sh
->sh_link
= s
->link
->sh_num
;
2558 sh
->sh_addralign
= s
->sh_addralign
;
2559 sh
->sh_addr
= s
->sh_addr
;
2560 sh
->sh_offset
= s
->sh_offset
;
2561 sh
->sh_size
= s
->sh_size
;
2563 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2567 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
2568 const int *sec_order
)
2571 int i
, offset
, size
;
2574 for(i
=1;i
<s1
->nb_sections
;i
++) {
2575 s
= s1
->sections
[sec_order
[i
]];
2576 if (s
->sh_type
!= SHT_NOBITS
&&
2577 (s
->sh_flags
& SHF_ALLOC
)) {
2578 while (offset
< s
->sh_offset
) {
2583 fwrite(s
->data
, 1, size
, f
);
2589 /* Write an elf, coff or "binary" file */
2590 static int tcc_write_elf_file(TCCState
*s1
, const char *filename
, int phnum
,
2591 ElfW(Phdr
) *phdr
, int file_offset
, int *sec_order
)
2593 int fd
, mode
, file_type
;
2596 file_type
= s1
->output_type
;
2597 if (file_type
== TCC_OUTPUT_OBJ
)
2602 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2603 if (fd
< 0 || (f
= fdopen(fd
, "wb")) == NULL
) {
2604 tcc_error_noabort("could not write '%s: %s'", filename
, strerror(errno
));
2608 printf("<- %s\n", filename
);
2610 #ifdef TCC_TARGET_COFF
2611 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
)
2612 tcc_output_coff(s1
, f
);
2615 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2616 tcc_output_elf(s1
, f
, phnum
, phdr
, file_offset
, sec_order
);
2618 tcc_output_binary(s1
, f
, sec_order
);
2624 #ifndef ELF_OBJ_ONLY
2625 /* Sort section headers by assigned sh_addr, remove sections
2626 that we aren't going to output. */
2627 static int tidy_section_headers(TCCState
*s1
, int *sec_order
)
2629 int i
, nnew
, l
, *backmap
;
2633 snew
= tcc_malloc(s1
->nb_sections
* sizeof(snew
[0]));
2634 backmap
= tcc_malloc(s1
->nb_sections
* sizeof(backmap
[0]));
2635 for (i
= 0, nnew
= 0, l
= s1
->nb_sections
; i
< s1
->nb_sections
; i
++) {
2636 s
= s1
->sections
[sec_order
[i
]];
2637 if (!i
|| s
->sh_name
) {
2638 backmap
[sec_order
[i
]] = nnew
;
2642 backmap
[sec_order
[i
]] = 0;
2646 for (i
= 0; i
< nnew
; i
++) {
2650 if (s
->sh_type
== SHT_RELX
)
2651 s
->sh_info
= backmap
[s
->sh_info
];
2655 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
))
2656 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2657 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2658 if ( !s1
->static_link
) {
2659 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
))
2660 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2661 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2663 for (i
= 0; i
< s1
->nb_sections
; i
++)
2665 tcc_free(s1
->sections
);
2666 s1
->sections
= snew
;
2671 #ifdef TCC_TARGET_ARM
2672 static void create_arm_attribute_section(TCCState
*s1
)
2674 // Needed for DLL support.
2675 static const unsigned char arm_attr
[] = {
2677 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2678 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2679 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2680 0x05, 0x36, 0x00, // 'CPU_name', "6"
2681 0x06, 0x06, // 'CPU_arch', 'v6'
2682 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2683 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2684 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2685 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2686 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2687 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2688 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2689 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2690 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2691 0x1a, 0x02, // 'ABI_enum_size', 'int'
2692 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2693 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2695 Section
*attr
= new_section(s1
, ".ARM.attributes", SHT_ARM_ATTRIBUTES
, 0);
2696 unsigned char *ptr
= section_ptr_add(attr
, sizeof(arm_attr
));
2697 attr
->sh_addralign
= 1;
2698 memcpy(ptr
, arm_attr
, sizeof(arm_attr
));
2699 if (s1
->float_abi
!= ARM_HARD_FLOAT
) {
2700 ptr
[26] = 0x00; // 'FP_arch', 'No'
2701 ptr
[41] = 0x1e; // 'ABI_optimization_goals'
2702 ptr
[42] = 0x06; // 'Aggressive Debug'
2707 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2708 static Section
*create_bsd_note_section(TCCState
*s1
,
2712 Section
*s
= find_section (s1
, name
);
2714 if (s
->data_offset
== 0) {
2715 char *ptr
= section_ptr_add(s
, sizeof(ElfW(Nhdr
)) + 8 + 4);
2716 ElfW(Nhdr
) *note
= (ElfW(Nhdr
) *) ptr
;
2718 s
->sh_type
= SHT_NOTE
;
2721 note
->n_type
= ELF_NOTE_OS_GNU
;
2722 strcpy (ptr
+ sizeof(ElfW(Nhdr
)), value
);
2728 static void alloc_sec_names(TCCState
*s1
, int is_obj
);
2730 /* Output an elf, coff or binary file */
2731 /* XXX: suppress unneeded sections */
2732 static int elf_output_file(TCCState
*s1
, const char *filename
)
2734 int i
, ret
, file_type
, file_offset
, *sec_order
;
2735 struct dyn_inf dyninf
= {0};
2736 Section
*interp
, *dynstr
, *dynamic
;
2737 int textrel
, got_sym
, dt_flags_1
;
2739 file_type
= s1
->output_type
;
2742 interp
= dynstr
= dynamic
= NULL
;
2744 dyninf
.roinf
= &dyninf
._roinf
;
2746 #ifdef TCC_TARGET_ARM
2747 create_arm_attribute_section (s1
);
2750 #if TARGETOS_OpenBSD
2751 dyninf
.note
= create_bsd_note_section (s1
, ".note.openbsd.ident", "OpenBSD");
2755 dyninf
.note
= create_bsd_note_section (s1
, ".note.netbsd.ident", "NetBSD");
2758 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
2759 dyninf
.roinf
= NULL
;
2761 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2762 tcc_add_runtime(s1
);
2763 resolve_common_syms(s1
);
2765 if (!s1
->static_link
) {
2766 if (file_type
& TCC_OUTPUT_EXE
) {
2768 /* allow override the dynamic loader */
2769 const char *elfint
= getenv("LD_SO");
2771 elfint
= DEFAULT_ELFINTERP(s1
);
2772 /* add interpreter section only if executable */
2773 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
2774 interp
->sh_addralign
= 1;
2775 ptr
= section_ptr_add(interp
, 1 + strlen(elfint
));
2776 strcpy(ptr
, elfint
);
2777 dyninf
.interp
= interp
;
2780 /* add dynamic symbol table */
2781 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
2783 ".hash", SHF_ALLOC
);
2784 /* Number of local symbols (readelf complains if not set) */
2785 s1
->dynsym
->sh_info
= 1;
2786 dynstr
= s1
->dynsym
->link
;
2787 /* add dynamic section */
2788 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
2789 SHF_ALLOC
| SHF_WRITE
);
2790 dynamic
->link
= dynstr
;
2791 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
2793 got_sym
= build_got(s1
);
2794 if (file_type
== TCC_OUTPUT_EXE
) {
2795 bind_exe_dynsyms(s1
);
2799 build_got_entries(s1
, got_sym
);
2800 if (file_type
& TCC_OUTPUT_EXE
) {
2801 bind_libs_dynsyms(s1
);
2803 /* shared library case: simply export all global symbols */
2804 export_global_syms(s1
);
2806 dyninf
.gnu_hash
= create_gnu_hash(s1
);
2808 build_got_entries(s1
, 0);
2812 textrel
= set_sec_sizes(s1
);
2813 alloc_sec_names(s1
, 0);
2815 if (!s1
->static_link
) {
2816 /* add a list of needed dlls */
2817 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2818 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
2819 if (dllref
->level
== 0)
2820 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
2824 put_dt(dynamic
, s1
->enable_new_dtags
? DT_RUNPATH
: DT_RPATH
,
2825 put_elf_str(dynstr
, s1
->rpath
));
2827 dt_flags_1
= DF_1_NOW
;
2828 if (file_type
& TCC_OUTPUT_DYN
) {
2830 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
2831 /* XXX: currently, since we do not handle PIC code, we
2832 must relocate the readonly segments */
2834 put_dt(dynamic
, DT_TEXTREL
, 0);
2835 if (file_type
& TCC_OUTPUT_EXE
)
2836 dt_flags_1
= DF_1_NOW
| DF_1_PIE
;
2838 put_dt(dynamic
, DT_FLAGS
, DF_BIND_NOW
);
2839 put_dt(dynamic
, DT_FLAGS_1
, dt_flags_1
);
2841 put_dt(dynamic
, DT_SYMBOLIC
, 0);
2843 dyninf
.dynamic
= dynamic
;
2844 dyninf
.dynstr
= dynstr
;
2845 /* remember offset and reserve space for 2nd call below */
2846 dyninf
.data_offset
= dynamic
->data_offset
;
2847 fill_dynamic(s1
, &dyninf
);
2848 dynamic
->sh_size
= dynamic
->data_offset
;
2849 dynstr
->sh_size
= dynstr
->data_offset
;
2852 /* this array is used to reorder sections in the output file */
2853 sec_order
= tcc_malloc(sizeof(int) * 2 * s1
->nb_sections
);
2854 /* compute section to program header mapping */
2855 file_offset
= layout_sections(s1
, sec_order
, &dyninf
);
2858 /* put in GOT the dynamic section address and relocate PLT */
2859 write32le(s1
->got
->data
, dynamic
->sh_addr
);
2860 if (file_type
== TCC_OUTPUT_EXE
2861 || (RELOCATE_DLLPLT
&& (file_type
& TCC_OUTPUT_DYN
)))
2863 /* relocate symbols in .dynsym now that final addresses are known */
2864 relocate_syms(s1
, s1
->dynsym
, 2);
2867 /* if building executable or DLL, then relocate each section
2868 except the GOT which is already relocated */
2869 relocate_syms(s1
, s1
->symtab
, 0);
2870 if (s1
->nb_errors
!= 0)
2872 relocate_sections(s1
);
2874 update_reloc_sections (s1
, &dyninf
);
2875 dynamic
->data_offset
= dyninf
.data_offset
;
2876 fill_dynamic(s1
, &dyninf
);
2878 /* Perform relocation to GOT or PLT entries */
2879 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2882 fill_local_got_entries(s1
);
2884 if (dyninf
.gnu_hash
)
2885 update_gnu_hash(s1
, dyninf
.gnu_hash
);
2887 /* Create the ELF file with name 'filename' */
2888 ret
= tcc_write_elf_file(s1
, filename
, dyninf
.phnum
, dyninf
.phdr
, file_offset
, sec_order
);
2890 tcc_free(sec_order
);
2891 tcc_free(dyninf
.phdr
);
2894 #endif /* ndef ELF_OBJ_ONLY */
2896 /* Allocate strings for section names */
2897 static void alloc_sec_names(TCCState
*s1
, int is_obj
)
2900 Section
*s
, *strsec
;
2902 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
2903 put_elf_str(strsec
, "");
2904 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2905 s
= s1
->sections
[i
];
2907 s
->sh_size
= s
->data_offset
;
2908 if (s
== strsec
|| s
->sh_size
|| (s
->sh_flags
& SHF_ALLOC
))
2909 s
->sh_name
= put_elf_str(strsec
, s
->name
);
2911 strsec
->sh_size
= strsec
->data_offset
;
2914 /* Output an elf .o file */
2915 static int elf_output_obj(TCCState
*s1
, const char *filename
)
2918 int i
, ret
, file_offset
;
2920 /* Allocate strings for section names */
2921 alloc_sec_names(s1
, 1);
2922 file_offset
= sizeof (ElfW(Ehdr
));
2923 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2924 s
= s1
->sections
[i
];
2925 file_offset
= (file_offset
+ 15) & -16;
2926 s
->sh_offset
= file_offset
;
2927 if (s
->sh_type
!= SHT_NOBITS
)
2928 file_offset
+= s
->sh_size
;
2930 /* Create the ELF file with name 'filename' */
2931 ret
= tcc_write_elf_file(s1
, filename
, 0, NULL
, file_offset
, NULL
);
2935 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2937 if (s
->test_coverage
)
2938 tcc_tcov_add_file(s
, filename
);
2939 if (s
->output_type
== TCC_OUTPUT_OBJ
)
2940 return elf_output_obj(s
, filename
);
2941 #ifdef TCC_TARGET_PE
2942 return pe_output_file(s
, filename
);
2943 #elif TCC_TARGET_MACHO
2944 return macho_output_file(s
, filename
);
2946 return elf_output_file(s
, filename
);
2950 ST_FUNC ssize_t
full_read(int fd
, void *buf
, size_t count
) {
2954 ssize_t num
= read(fd
, cbuf
, count
-rnum
);
2955 if (num
< 0) return num
;
2956 if (num
== 0) return rnum
;
2962 ST_FUNC
void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2966 data
= tcc_malloc(size
);
2967 lseek(fd
, file_offset
, SEEK_SET
);
2968 full_read(fd
, data
, size
);
2972 typedef struct SectionMergeInfo
{
2973 Section
*s
; /* corresponding existing section */
2974 unsigned long offset
; /* offset of the new section in the existing section */
2975 uint8_t new_section
; /* true if section 's' was added */
2976 uint8_t link_once
; /* true if link once section */
2979 ST_FUNC
int tcc_object_type(int fd
, ElfW(Ehdr
) *h
)
2981 int size
= full_read(fd
, h
, sizeof *h
);
2982 if (size
== sizeof *h
&& 0 == memcmp(h
, ELFMAG
, 4)) {
2983 if (h
->e_type
== ET_REL
)
2984 return AFF_BINTYPE_REL
;
2985 if (h
->e_type
== ET_DYN
)
2986 return AFF_BINTYPE_DYN
;
2987 } else if (size
>= 8) {
2988 if (0 == memcmp(h
, ARMAG
, 8))
2989 return AFF_BINTYPE_AR
;
2990 #ifdef TCC_TARGET_COFF
2991 if (((struct filehdr
*)h
)->f_magic
== COFF_C67_MAGIC
)
2992 return AFF_BINTYPE_C67
;
2998 /* load an object file and merge it with current files */
2999 /* XXX: handle correctly stab (debug) info */
3000 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
3001 int fd
, unsigned long file_offset
)
3004 ElfW(Shdr
) *shdr
, *sh
;
3005 unsigned long size
, offset
, offseti
;
3006 int i
, j
, nb_syms
, sym_index
, ret
, seencompressed
;
3007 char *strsec
, *strtab
;
3008 int stab_index
, stabstr_index
;
3009 int *old_to_new_syms
;
3010 char *sh_name
, *name
;
3011 SectionMergeInfo
*sm_table
, *sm
;
3012 ElfW(Sym
) *sym
, *symtab
;
3016 lseek(fd
, file_offset
, SEEK_SET
);
3017 if (tcc_object_type(fd
, &ehdr
) != AFF_BINTYPE_REL
)
3019 /* test CPU specific stuff */
3020 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
3021 ehdr
.e_machine
!= EM_TCC_TARGET
) {
3023 tcc_error_noabort("invalid object file");
3027 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
3028 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
3029 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
3031 /* load section names */
3032 sh
= &shdr
[ehdr
.e_shstrndx
];
3033 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
3035 /* load symtab and strtab */
3036 old_to_new_syms
= NULL
;
3041 stab_index
= stabstr_index
= 0;
3043 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3045 if (sh
->sh_type
== SHT_SYMTAB
) {
3047 tcc_error_noabort("object must contain only one symtab");
3052 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
3053 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
3054 sm_table
[i
].s
= symtab_section
;
3056 /* now load strtab */
3057 sh
= &shdr
[sh
->sh_link
];
3058 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
3060 if (sh
->sh_flags
& SHF_COMPRESSED
)
3064 /* now examine each section and try to merge its content with the
3066 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3067 /* no need to examine section name strtab */
3068 if (i
== ehdr
.e_shstrndx
)
3071 if (sh
->sh_type
== SHT_RELX
)
3072 sh
= &shdr
[sh
->sh_info
];
3073 /* ignore sections types we do not handle (plus relocs to those) */
3074 if (sh
->sh_type
!= SHT_PROGBITS
&&
3076 sh
->sh_type
!= SHT_ARM_EXIDX
&&
3078 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3079 sh
->sh_type
!= SHT_X86_64_UNWIND
&&
3081 sh
->sh_type
!= SHT_NOTE
&&
3082 sh
->sh_type
!= SHT_NOBITS
&&
3083 sh
->sh_type
!= SHT_PREINIT_ARRAY
&&
3084 sh
->sh_type
!= SHT_INIT_ARRAY
&&
3085 sh
->sh_type
!= SHT_FINI_ARRAY
&&
3086 strcmp(strsec
+ sh
->sh_name
, ".stabstr")
3089 if (seencompressed
&& 0 == strncmp(strsec
+ sh
->sh_name
, ".debug_", 7))
3093 sh_name
= strsec
+ sh
->sh_name
;
3094 if (sh
->sh_addralign
< 1)
3095 sh
->sh_addralign
= 1;
3096 /* find corresponding section, if any */
3097 for(j
= 1; j
< s1
->nb_sections
;j
++) {
3098 s
= s1
->sections
[j
];
3099 if (!strcmp(s
->name
, sh_name
)) {
3100 if (!strncmp(sh_name
, ".gnu.linkonce",
3101 sizeof(".gnu.linkonce") - 1)) {
3102 /* if a 'linkonce' section is already present, we
3103 do not add it again. It is a little tricky as
3104 symbols can still be defined in
3106 sm_table
[i
].link_once
= 1;
3110 if (s
== stab_section
)
3112 if (s
== stab_section
->link
)
3118 /* not found: create new section */
3119 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
& ~SHF_GROUP
);
3120 /* take as much info as possible from the section. sh_link and
3121 sh_info will be updated later */
3122 s
->sh_addralign
= sh
->sh_addralign
;
3123 s
->sh_entsize
= sh
->sh_entsize
;
3124 sm_table
[i
].new_section
= 1;
3126 if (sh
->sh_type
!= s
->sh_type
) {
3127 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3128 if (strcmp (s
->name
, ".eh_frame"))
3131 tcc_error_noabort("invalid section type");
3135 /* align start of section */
3136 s
->data_offset
+= -s
->data_offset
& (sh
->sh_addralign
- 1);
3137 if (sh
->sh_addralign
> s
->sh_addralign
)
3138 s
->sh_addralign
= sh
->sh_addralign
;
3139 sm_table
[i
].offset
= s
->data_offset
;
3141 /* concatenate sections */
3143 if (sh
->sh_type
!= SHT_NOBITS
) {
3145 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
3146 ptr
= section_ptr_add(s
, size
);
3147 full_read(fd
, ptr
, size
);
3149 s
->data_offset
+= size
;
3154 /* gr relocate stab strings */
3155 if (stab_index
&& stabstr_index
) {
3158 s
= sm_table
[stab_index
].s
;
3159 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
3160 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
3161 o
= sm_table
[stabstr_index
].offset
;
3169 /* second short pass to update sh_link and sh_info fields of new
3171 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3173 if (!s
|| !sm_table
[i
].new_section
)
3176 if (sh
->sh_link
> 0)
3177 s
->link
= sm_table
[sh
->sh_link
].s
;
3178 if (sh
->sh_type
== SHT_RELX
) {
3179 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
3180 /* update backward link */
3181 s1
->sections
[s
->sh_info
]->reloc
= s
;
3185 /* resolve symbols */
3186 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
3189 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
3190 if (sym
->st_shndx
!= SHN_UNDEF
&&
3191 sym
->st_shndx
< SHN_LORESERVE
) {
3192 sm
= &sm_table
[sym
->st_shndx
];
3193 if (sm
->link_once
) {
3194 /* if a symbol is in a link once section, we use the
3195 already defined symbol. It is very important to get
3196 correct relocations */
3197 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
3198 name
= strtab
+ sym
->st_name
;
3199 sym_index
= find_elf_sym(symtab_section
, name
);
3201 old_to_new_syms
[i
] = sym_index
;
3205 /* if no corresponding section added, no need to add symbol */
3208 /* convert section number */
3209 sym
->st_shndx
= sm
->s
->sh_num
;
3211 sym
->st_value
+= sm
->offset
;
3214 name
= strtab
+ sym
->st_name
;
3215 sym_index
= set_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
3216 sym
->st_info
, sym
->st_other
,
3217 sym
->st_shndx
, name
);
3218 old_to_new_syms
[i
] = sym_index
;
3221 /* third pass to patch relocation entries */
3222 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3227 offset
= sm_table
[i
].offset
;
3229 switch(s
->sh_type
) {
3231 /* take relocation offset information */
3232 offseti
= sm_table
[sh
->sh_info
].offset
;
3233 for (rel
= (ElfW_Rel
*) s
->data
+ (offset
/ sizeof(*rel
));
3234 rel
< (ElfW_Rel
*) s
->data
+ ((offset
+ size
) / sizeof(*rel
));
3238 /* convert symbol index */
3239 type
= ELFW(R_TYPE
)(rel
->r_info
);
3240 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
3241 /* NOTE: only one symtab assumed */
3242 if (sym_index
>= nb_syms
)
3244 sym_index
= old_to_new_syms
[sym_index
];
3245 /* ignore link_once in rel section. */
3246 if (!sym_index
&& !sm_table
[sh
->sh_info
].link_once
3247 #ifdef TCC_TARGET_ARM
3248 && type
!= R_ARM_V4BX
3249 #elif defined TCC_TARGET_RISCV64
3250 && type
!= R_RISCV_ALIGN
3251 && type
!= R_RISCV_RELAX
3255 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3256 i
, strsec
+ sh
->sh_name
, (int)rel
->r_offset
);
3259 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
3260 /* offset the relocation offset */
3261 rel
->r_offset
+= offseti
;
3262 #ifdef TCC_TARGET_ARM
3263 /* Jumps and branches from a Thumb code to a PLT entry need
3264 special handling since PLT entries are ARM code.
3265 Unconditional bl instructions referencing PLT entries are
3266 handled by converting these instructions into blx
3267 instructions. Other case of instructions referencing a PLT
3268 entry require to add a Thumb stub before the PLT entry to
3269 switch to ARM mode. We set bit plt_thumb_stub of the
3270 attribute of a symbol to indicate such a case. */
3271 if (type
== R_ARM_THM_JUMP24
)
3272 get_sym_attr(s1
, sym_index
, 1)->plt_thumb_stub
= 1;
3285 tcc_free(old_to_new_syms
);
3292 typedef struct ArchiveHeader
{
3293 char ar_name
[16]; /* name of this member */
3294 char ar_date
[12]; /* file mtime */
3295 char ar_uid
[6]; /* owner uid; printed as decimal */
3296 char ar_gid
[6]; /* owner gid; printed as decimal */
3297 char ar_mode
[8]; /* file mode, printed as octal */
3298 char ar_size
[10]; /* file size, printed as decimal */
3299 char ar_fmag
[2]; /* should contain ARFMAG */
3302 #define ARFMAG "`\n"
3304 static unsigned long long get_be(const uint8_t *b
, int n
)
3306 unsigned long long ret
= 0;
3308 ret
= (ret
<< 8) | *b
++, --n
;
3312 static int read_ar_header(int fd
, int offset
, ArchiveHeader
*hdr
)
3316 lseek(fd
, offset
, SEEK_SET
);
3317 len
= full_read(fd
, hdr
, sizeof(ArchiveHeader
));
3318 if (len
!= sizeof(ArchiveHeader
))
3319 return len
? -1 : 0;
3321 for (e
= p
+ sizeof hdr
->ar_name
; e
> p
&& e
[-1] == ' ';)
3324 hdr
->ar_size
[sizeof hdr
->ar_size
-1] = 0;
3328 /* load only the objects which resolve undefined symbols */
3329 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
, int entrysize
)
3331 int i
, bound
, nsyms
, sym_index
, len
, ret
= -1;
3332 unsigned long long off
;
3334 const char *ar_names
, *p
;
3335 const uint8_t *ar_index
;
3339 data
= tcc_malloc(size
);
3340 if (full_read(fd
, data
, size
) != size
)
3342 nsyms
= get_be(data
, entrysize
);
3343 ar_index
= data
+ entrysize
;
3344 ar_names
= (char *) ar_index
+ nsyms
* entrysize
;
3348 for (p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
3349 Section
*s
= symtab_section
;
3350 sym_index
= find_elf_sym(s
, p
);
3353 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
3354 if(sym
->st_shndx
!= SHN_UNDEF
)
3356 off
= get_be(ar_index
+ i
* entrysize
, entrysize
);
3357 len
= read_ar_header(fd
, off
, &hdr
);
3358 if (len
<= 0 || memcmp(hdr
.ar_fmag
, ARFMAG
, 2)) {
3359 tcc_error_noabort("invalid archive");
3363 if (s1
->verbose
== 2)
3364 printf(" -> %s\n", hdr
.ar_name
);
3365 if (tcc_load_object_file(s1
, fd
, off
) < 0)
3376 /* load a '.a' file */
3377 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
, int alacarte
)
3380 /* char magic[8]; */
3382 unsigned long file_offset
;
3385 /* skip magic which was already checked */
3386 /* full_read(fd, magic, sizeof(magic)); */
3387 file_offset
= sizeof ARMAG
- 1;
3390 len
= read_ar_header(fd
, file_offset
, &hdr
);
3394 tcc_error_noabort("invalid archive");
3398 size
= strtol(hdr
.ar_size
, NULL
, 0);
3400 size
= (size
+ 1) & ~1;
3402 /* coff symbol table : we handle it */
3403 if (!strcmp(hdr
.ar_name
, "/"))
3404 return tcc_load_alacarte(s1
, fd
, size
, 4);
3405 if (!strcmp(hdr
.ar_name
, "/SYM64/"))
3406 return tcc_load_alacarte(s1
, fd
, size
, 8);
3407 } else if (tcc_object_type(fd
, &ehdr
) == AFF_BINTYPE_REL
) {
3408 if (s1
->verbose
== 2)
3409 printf(" -> %s\n", hdr
.ar_name
);
3410 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
3413 file_offset
+= size
;
3417 #ifndef ELF_OBJ_ONLY
3418 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3419 LV, maybe create a new entry for (LIB,VERSION). */
3420 static void set_ver_to_ver(TCCState
*s1
, int *n
, int **lv
, int i
, char *lib
, char *version
)
3423 *lv
= tcc_realloc(*lv
, (*n
+ 1) * sizeof(**lv
));
3426 if ((*lv
)[i
] == -1) {
3427 int v
, prev_same_lib
= -1;
3428 for (v
= 0; v
< nb_sym_versions
; v
++) {
3429 if (strcmp(sym_versions
[v
].lib
, lib
))
3432 if (!strcmp(sym_versions
[v
].version
, version
))
3435 if (v
== nb_sym_versions
) {
3436 sym_versions
= tcc_realloc (sym_versions
,
3437 (v
+ 1) * sizeof(*sym_versions
));
3438 sym_versions
[v
].lib
= tcc_strdup(lib
);
3439 sym_versions
[v
].version
= tcc_strdup(version
);
3440 sym_versions
[v
].out_index
= 0;
3441 sym_versions
[v
].prev_same_lib
= prev_same_lib
;
3448 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3451 set_sym_version(TCCState
*s1
, int sym_index
, int verndx
)
3453 if (sym_index
>= nb_sym_to_version
) {
3454 int newelems
= sym_index
? sym_index
* 2 : 1;
3455 sym_to_version
= tcc_realloc(sym_to_version
,
3456 newelems
* sizeof(*sym_to_version
));
3457 memset(sym_to_version
+ nb_sym_to_version
, -1,
3458 (newelems
- nb_sym_to_version
) * sizeof(*sym_to_version
));
3459 nb_sym_to_version
= newelems
;
3461 if (sym_to_version
[sym_index
] < 0)
3462 sym_to_version
[sym_index
] = verndx
;
3465 struct versym_info
{
3467 ElfW(Verdef
) *verdef
;
3468 ElfW(Verneed
) *verneed
;
3470 int nb_local_ver
, *local_ver
;
3474 static void store_version(TCCState
*s1
, struct versym_info
*v
, char *dynstr
)
3476 char *lib
, *version
;
3480 #define DEBUG_VERSION 0
3482 if (v
->versym
&& v
->verdef
) {
3483 ElfW(Verdef
) *vdef
= v
->verdef
;
3486 ElfW(Verdaux
) *verdaux
=
3487 (ElfW(Verdaux
) *) (((char *) vdef
) + vdef
->vd_aux
);
3490 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3491 vdef
->vd_version
, vdef
->vd_flags
, vdef
->vd_ndx
,
3495 version
= dynstr
+ verdaux
->vda_name
;
3500 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vdef
->vd_ndx
,
3503 printf (" verdaux(%u): %s\n", vdef
->vd_ndx
, version
);
3506 next
= vdef
->vd_next
;
3507 vdef
= (ElfW(Verdef
) *) (((char *) vdef
) + next
);
3510 if (v
->versym
&& v
->verneed
) {
3511 ElfW(Verneed
) *vneed
= v
->verneed
;
3513 ElfW(Vernaux
) *vernaux
=
3514 (ElfW(Vernaux
) *) (((char *) vneed
) + vneed
->vn_aux
);
3516 lib
= dynstr
+ vneed
->vn_file
;
3518 printf ("verneed: %u %s\n", vneed
->vn_version
, lib
);
3520 for (i
= 0; i
< vneed
->vn_cnt
; i
++) {
3521 if ((vernaux
->vna_other
& 0x8000) == 0) { /* hidden */
3522 version
= dynstr
+ vernaux
->vna_name
;
3523 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vernaux
->vna_other
,
3526 printf (" vernaux(%u): %u %u %s\n",
3527 vernaux
->vna_other
, vernaux
->vna_hash
,
3528 vernaux
->vna_flags
, version
);
3531 vernaux
= (ElfW(Vernaux
) *) (((char *) vernaux
) + vernaux
->vna_next
);
3533 next
= vneed
->vn_next
;
3534 vneed
= (ElfW(Verneed
) *) (((char *) vneed
) + next
);
3539 for (i
= 0; i
< v
->nb_local_ver
; i
++) {
3540 if (v
->local_ver
[i
] > 0) {
3541 printf ("%d: lib: %s, version %s\n",
3542 i
, sym_versions
[v
->local_ver
[i
]].lib
,
3543 sym_versions
[v
->local_ver
[i
]].version
);
3549 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3550 is referenced by the user (so it should be added as DT_NEEDED in
3551 the generated ELF file) */
3552 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
3555 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
3556 int i
, nb_syms
, nb_dts
, sym_bind
, ret
= -1;
3557 ElfW(Sym
) *sym
, *dynsym
;
3558 ElfW(Dyn
) *dt
, *dynamic
;
3562 const char *name
, *soname
;
3563 struct versym_info v
;
3565 full_read(fd
, &ehdr
, sizeof(ehdr
));
3567 /* test CPU specific stuff */
3568 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
3569 ehdr
.e_machine
!= EM_TCC_TARGET
) {
3570 tcc_error_noabort("bad architecture");
3575 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
3577 /* load dynamic section and dynamic symbols */
3581 dynsym
= NULL
; /* avoid warning */
3582 dynstr
= NULL
; /* avoid warning */
3583 memset(&v
, 0, sizeof v
);
3585 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
3586 switch(sh
->sh_type
) {
3588 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
3589 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3592 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
3593 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3594 sh1
= &shdr
[sh
->sh_link
];
3595 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
3597 case SHT_GNU_verdef
:
3598 v
.verdef
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3600 case SHT_GNU_verneed
:
3601 v
.verneed
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3603 case SHT_GNU_versym
:
3604 v
.nb_versyms
= sh
->sh_size
/ sizeof(ElfW(Half
));
3605 v
.versym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3615 /* compute the real library name */
3616 soname
= tcc_basename(filename
);
3617 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++)
3618 if (dt
->d_tag
== DT_SONAME
)
3619 soname
= dynstr
+ dt
->d_un
.d_val
;
3621 /* if the dll is already loaded, do not load it */
3622 if (tcc_add_dllref(s1
, soname
, level
)->found
)
3625 if (v
.nb_versyms
!= nb_syms
)
3626 tcc_free (v
.versym
), v
.versym
= NULL
;
3628 store_version(s1
, &v
, dynstr
);
3630 /* add dynamic symbols in dynsym_section */
3631 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
3632 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
3633 if (sym_bind
== STB_LOCAL
)
3635 name
= dynstr
+ sym
->st_name
;
3636 sym_index
= set_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
3637 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
3639 ElfW(Half
) vsym
= v
.versym
[i
];
3640 if ((vsym
& 0x8000) == 0 && vsym
> 0 && vsym
< v
.nb_local_ver
)
3641 set_sym_version(s1
, sym_index
, v
.local_ver
[vsym
]);
3645 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++)
3646 if (dt
->d_tag
== DT_RPATH
)
3647 tcc_add_library_path(s1
, dynstr
+ dt
->d_un
.d_val
);
3649 /* load all referenced DLLs */
3650 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3653 name
= dynstr
+ dt
->d_un
.d_val
;
3654 if (tcc_add_dllref(s1
, name
, -1))
3656 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
3657 tcc_error_noabort("referenced dll '%s' not found", name
);
3670 tcc_free(v
.local_ver
);
3672 tcc_free(v
.verneed
);
3677 #define LD_TOK_NAME 256
3678 #define LD_TOK_EOF (-1)
3680 static int ld_inp(TCCState
*s1
)
3688 if (1 == read(s1
->fd
, &b
, 1))
3693 /* return next ld script token */
3694 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
3711 if (ch
== '*') { /* comment */
3712 for (d
= 0;; d
= ch
) {
3714 if (ch
== CH_EOF
|| (ch
== '/' && d
== '*'))
3725 /* case 'a' ... 'z': */
3752 /* case 'A' ... 'z': */
3786 if (!((ch
>= 'a' && ch
<= 'z') ||
3787 (ch
>= 'A' && ch
<= 'Z') ||
3788 (ch
>= '0' && ch
<= '9') ||
3789 strchr("/.-_+=$:\\,~", ch
)))
3791 if ((q
- name
) < name_size
- 1) {
3810 static int ld_add_file(TCCState
*s1
, const char filename
[])
3812 if (filename
[0] == '/') {
3813 if (CONFIG_SYSROOT
[0] == '\0'
3814 && tcc_add_file_internal(s1
, filename
, AFF_TYPE_BIN
) == 0)
3816 filename
= tcc_basename(filename
);
3818 return tcc_add_dll(s1
, filename
, 0);
3821 static int ld_add_file_list(TCCState
*s1
, const char *cmd
, int as_needed
)
3823 char filename
[1024], libname
[1024];
3824 int t
, group
, nblibs
= 0, ret
= 0;
3827 group
= !strcmp(cmd
, "GROUP");
3829 s1
->new_undef_sym
= 0;
3830 t
= ld_next(s1
, filename
, sizeof(filename
));
3832 tcc_error_noabort("( expected");
3834 goto lib_parse_error
;
3836 t
= ld_next(s1
, filename
, sizeof(filename
));
3839 if (t
== LD_TOK_EOF
) {
3840 tcc_error_noabort("unexpected end of file");
3842 goto lib_parse_error
;
3843 } else if (t
== ')') {
3845 } else if (t
== '-') {
3846 t
= ld_next(s1
, filename
, sizeof(filename
));
3847 if ((t
!= LD_TOK_NAME
) || (filename
[0] != 'l')) {
3848 tcc_error_noabort("library name expected");
3850 goto lib_parse_error
;
3852 pstrcpy(libname
, sizeof libname
, &filename
[1]);
3853 if (s1
->static_link
) {
3854 snprintf(filename
, sizeof filename
, "lib%s.a", libname
);
3856 snprintf(filename
, sizeof filename
, "lib%s.so", libname
);
3858 } else if (t
!= LD_TOK_NAME
) {
3859 tcc_error_noabort("filename expected");
3861 goto lib_parse_error
;
3863 if (!strcmp(filename
, "AS_NEEDED")) {
3864 ret
= ld_add_file_list(s1
, cmd
, 1);
3866 goto lib_parse_error
;
3868 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3870 ret
= ld_add_file(s1
, filename
);
3872 goto lib_parse_error
;
3874 /* Add the filename *and* the libname to avoid future conversions */
3875 dynarray_add(&libs
, &nblibs
, tcc_strdup(filename
));
3876 if (libname
[0] != '\0')
3877 dynarray_add(&libs
, &nblibs
, tcc_strdup(libname
));
3881 t
= ld_next(s1
, filename
, sizeof(filename
));
3883 t
= ld_next(s1
, filename
, sizeof(filename
));
3886 if (group
&& !as_needed
) {
3887 while (s1
->new_undef_sym
) {
3889 s1
->new_undef_sym
= 0;
3890 for (i
= 0; i
< nblibs
; i
++)
3891 ld_add_file(s1
, libs
[i
]);
3895 dynarray_reset(&libs
, &nblibs
);
3899 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3901 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
, int fd
)
3904 char filename
[1024];
3910 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3911 if (t
== LD_TOK_EOF
)
3913 else if (t
!= LD_TOK_NAME
)
3915 if (!strcmp(cmd
, "INPUT") ||
3916 !strcmp(cmd
, "GROUP")) {
3917 ret
= ld_add_file_list(s1
, cmd
, 0);
3920 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
3921 !strcmp(cmd
, "TARGET")) {
3922 /* ignore some commands */
3923 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3925 tcc_error_noabort("( expected");
3929 t
= ld_next(s1
, filename
, sizeof(filename
));
3930 if (t
== LD_TOK_EOF
) {
3931 tcc_error_noabort("unexpected end of file");
3933 } else if (t
== ')') {
3943 #endif /* !ELF_OBJ_ONLY */