2 * ELF file handling for TCC
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 /* Define this to get some debug output during relocation processing. */
26 /********************************************************/
27 /* global variables */
29 /* elf version information */
37 #define nb_sym_versions s1->nb_sym_versions
38 #define sym_versions s1->sym_versions
39 #define nb_sym_to_version s1->nb_sym_to_version
40 #define sym_to_version s1->sym_to_version
41 #define dt_verneednum s1->dt_verneednum
42 #define versym_section s1->versym_section
43 #define verneed_section s1->verneed_section
45 /* special flag to indicate that the section should not be linked to the other ones */
46 #define SHF_PRIVATE 0x80000000
47 /* section is dynsymtab_section */
48 #define SHF_DYNSYM 0x40000000
51 #define shf_RELRO SHF_ALLOC
52 static const char rdata
[] = ".rdata";
54 #define shf_RELRO s1->shf_RELRO
55 static const char rdata
[] = ".data.ro";
58 /* ------------------------------------------------------------------------- */
60 ST_FUNC
void tccelf_new(TCCState
*s
)
65 shf_RELRO
= SHF_ALLOC
;
66 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
67 shf_RELRO
|= SHF_WRITE
; /* the ELF loader will set it to RO at runtime */
71 dynarray_add(&s
->sections
, &s
->nb_sections
, NULL
);
73 /* create standard sections */
74 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
75 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
76 /* create ro data section (make ro after relocation done with GNU_RELRO) */
77 rodata_section
= new_section(s
, rdata
, SHT_PROGBITS
, shf_RELRO
);
78 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
79 common_section
= new_section(s
, ".common", SHT_NOBITS
, SHF_PRIVATE
);
80 common_section
->sh_num
= SHN_COMMON
;
82 /* symbols are always generated for linking stage */
83 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
85 ".hashtab", SHF_PRIVATE
);
87 /* private symbol table for dynamic symbols */
88 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
|SHF_DYNSYM
,
90 ".dynhashtab", SHF_PRIVATE
);
91 get_sym_attr(s
, 0, 1);
94 /* add debug sections */
98 #ifdef CONFIG_TCC_BCHECK
99 if (s
->do_bounds_check
) {
100 /* if bound checking, then add corresponding sections */
101 /* (make ro after relocation done with GNU_RELRO) */
102 bounds_section
= new_section(s
, ".bounds", SHT_PROGBITS
, shf_RELRO
);
103 lbounds_section
= new_section(s
, ".lbounds", SHT_PROGBITS
, shf_RELRO
);
108 ST_FUNC
void free_section(Section
*s
)
114 s
->data_allocated
= s
->data_offset
= 0;
117 ST_FUNC
void tccelf_delete(TCCState
*s1
)
122 /* free symbol versions */
123 for (i
= 0; i
< nb_sym_versions
; i
++) {
124 tcc_free(sym_versions
[i
].version
);
125 tcc_free(sym_versions
[i
].lib
);
127 tcc_free(sym_versions
);
128 tcc_free(sym_to_version
);
131 /* free all sections */
132 for(i
= 1; i
< s1
->nb_sections
; i
++)
133 free_section(s1
->sections
[i
]);
134 dynarray_reset(&s1
->sections
, &s1
->nb_sections
);
136 for(i
= 0; i
< s1
->nb_priv_sections
; i
++)
137 free_section(s1
->priv_sections
[i
]);
138 dynarray_reset(&s1
->priv_sections
, &s1
->nb_priv_sections
);
140 tcc_free(s1
->sym_attrs
);
141 symtab_section
= NULL
; /* for tccrun.c:rt_printline() */
143 /* free any loaded DLLs */
145 for ( i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
146 DLLReference
*ref
= s1
->loaded_dlls
[i
];
149 FreeLibrary((HMODULE
)ref
->handle
);
151 dlclose(ref
->handle
);
155 /* free loaded dlls array */
156 dynarray_reset(&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
);
159 /* save section data state */
160 ST_FUNC
void tccelf_begin_file(TCCState
*s1
)
163 for (i
= 1; i
< s1
->nb_sections
; i
++) {
165 s
->sh_offset
= s
->data_offset
;
167 /* disable symbol hashing during compilation */
168 s
= s1
->symtab
, s
->reloc
= s
->hash
, s
->hash
= NULL
;
169 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
174 /* At the end of compilation, convert any UNDEF syms to global, and merge
175 with previously existing symbols */
176 ST_FUNC
void tccelf_end_file(TCCState
*s1
)
178 Section
*s
= s1
->symtab
;
179 int first_sym
, nb_syms
, *tr
, i
;
181 first_sym
= s
->sh_offset
/ sizeof (ElfSym
);
182 nb_syms
= s
->data_offset
/ sizeof (ElfSym
) - first_sym
;
183 s
->data_offset
= s
->sh_offset
;
184 s
->link
->data_offset
= s
->link
->sh_offset
;
185 s
->hash
= s
->reloc
, s
->reloc
= NULL
;
186 tr
= tcc_mallocz(nb_syms
* sizeof *tr
);
188 for (i
= 0; i
< nb_syms
; ++i
) {
189 ElfSym
*sym
= (ElfSym
*)s
->data
+ first_sym
+ i
;
191 if (sym
->st_shndx
== SHN_UNDEF
) {
192 int sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
193 int sym_type
= ELFW(ST_TYPE
)(sym
->st_info
);
194 if (sym_bind
== STB_LOCAL
)
195 sym_bind
= STB_GLOBAL
;
196 #ifndef TCC_TARGET_PE
197 if (sym_bind
== STB_GLOBAL
&& s1
->output_type
== TCC_OUTPUT_OBJ
) {
198 /* undefined symbols with STT_FUNC are confusing gnu ld when
199 linking statically to STT_GNU_IFUNC */
200 sym_type
= STT_NOTYPE
;
203 sym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
206 tr
[i
] = set_elf_sym(s
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
207 sym
->st_other
, sym
->st_shndx
, (char*)s
->link
->data
+ sym
->st_name
);
209 /* now update relocations */
210 for (i
= 1; i
< s1
->nb_sections
; i
++) {
211 Section
*sr
= s1
->sections
[i
];
212 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
213 ElfW_Rel
*rel
= (ElfW_Rel
*)(sr
->data
+ sr
->sh_offset
);
214 ElfW_Rel
*rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
215 for (; rel
< rel_end
; ++rel
) {
216 int n
= ELFW(R_SYM
)(rel
->r_info
) - first_sym
;
217 if (n
< 0) /* zero sym_index in reloc (can happen with asm) */
219 rel
->r_info
= ELFW(R_INFO
)(tr
[n
], ELFW(R_TYPE
)(rel
->r_info
));
225 /* record text/data/bss output for -bench info */
226 for (i
= 0; i
< 4; ++i
) {
227 s
= s1
->sections
[i
+ 1];
228 s1
->total_output
[i
] += s
->data_offset
- s
->sh_offset
;
232 ST_FUNC Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
236 sec
= tcc_mallocz(sizeof(Section
) + strlen(name
));
238 strcpy(sec
->name
, name
);
239 sec
->sh_type
= sh_type
;
240 sec
->sh_flags
= sh_flags
;
243 sec
->sh_addralign
= 2;
252 case SHT_GNU_verneed
:
254 sec
->sh_addralign
= PTR_SIZE
;
257 sec
->sh_addralign
= 1;
260 sec
->sh_addralign
= PTR_SIZE
; /* gcc/pcc default alignment */
264 if (sh_flags
& SHF_PRIVATE
) {
265 dynarray_add(&s1
->priv_sections
, &s1
->nb_priv_sections
, sec
);
267 sec
->sh_num
= s1
->nb_sections
;
268 dynarray_add(&s1
->sections
, &s1
->nb_sections
, sec
);
274 ST_FUNC
void init_symtab(Section
*s
)
276 int *ptr
, nb_buckets
= 1;
277 put_elf_str(s
->link
, "");
278 section_ptr_add(s
, sizeof (ElfW(Sym
)));
279 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ 1) * sizeof(int));
282 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
285 ST_FUNC Section
*new_symtab(TCCState
*s1
,
286 const char *symtab_name
, int sh_type
, int sh_flags
,
287 const char *strtab_name
,
288 const char *hash_name
, int hash_sh_flags
)
290 Section
*symtab
, *strtab
, *hash
;
291 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
292 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
293 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
294 symtab
->link
= strtab
;
295 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
296 hash
->sh_entsize
= sizeof(int);
303 /* realloc section and set its content to zero */
304 ST_FUNC
void section_realloc(Section
*sec
, unsigned long new_size
)
309 size
= sec
->data_allocated
;
312 while (size
< new_size
)
314 data
= tcc_realloc(sec
->data
, size
);
315 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
317 sec
->data_allocated
= size
;
320 /* reserve at least 'size' bytes aligned per 'align' in section
321 'sec' from current offset, and return the aligned offset */
322 ST_FUNC
size_t section_add(Section
*sec
, addr_t size
, int align
)
324 size_t offset
, offset1
;
326 offset
= (sec
->data_offset
+ align
- 1) & -align
;
327 offset1
= offset
+ size
;
328 if (sec
->sh_type
!= SHT_NOBITS
&& offset1
> sec
->data_allocated
)
329 section_realloc(sec
, offset1
);
330 sec
->data_offset
= offset1
;
331 if (align
> sec
->sh_addralign
)
332 sec
->sh_addralign
= align
;
336 /* reserve at least 'size' bytes in section 'sec' from
338 ST_FUNC
void *section_ptr_add(Section
*sec
, addr_t size
)
340 size_t offset
= section_add(sec
, size
, 1);
341 return sec
->data
+ offset
;
345 /* reserve at least 'size' bytes from section start */
346 static void section_reserve(Section
*sec
, unsigned long size
)
348 if (size
> sec
->data_allocated
)
349 section_realloc(sec
, size
);
350 if (size
> sec
->data_offset
)
351 sec
->data_offset
= size
;
355 static Section
*have_section(TCCState
*s1
, const char *name
)
359 for(i
= 1; i
< s1
->nb_sections
; i
++) {
360 sec
= s1
->sections
[i
];
361 if (!strcmp(name
, sec
->name
))
367 /* return a reference to a section, and create it if it does not
369 ST_FUNC Section
*find_section(TCCState
*s1
, const char *name
)
371 Section
*sec
= have_section(s1
, name
);
374 /* sections are created as PROGBITS */
375 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
378 /* ------------------------------------------------------------------------- */
380 ST_FUNC
int put_elf_str(Section
*s
, const char *sym
)
385 len
= strlen(sym
) + 1;
386 offset
= s
->data_offset
;
387 ptr
= section_ptr_add(s
, len
);
388 memmove(ptr
, sym
, len
);
392 /* elf symbol hashing function */
393 static ElfW(Word
) elf_hash(const unsigned char *name
)
398 h
= (h
<< 4) + *name
++;
407 /* rebuild hash table of section s */
408 /* NOTE: we do factorize the hash table code to go faster */
409 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
412 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
413 unsigned char *strtab
;
415 strtab
= s
->link
->data
;
416 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
419 nb_buckets
= ((int*)s
->hash
->data
)[0];
421 s
->hash
->data_offset
= 0;
422 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
427 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
428 ptr
+= nb_buckets
+ 1;
430 sym
= (ElfW(Sym
) *)s
->data
+ 1;
431 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
432 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
433 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
444 /* return the symbol number */
445 ST_FUNC
int put_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
446 int info
, int other
, int shndx
, const char *name
)
448 int name_offset
, sym_index
;
453 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
455 name_offset
= put_elf_str(s
->link
, name
);
458 /* XXX: endianness */
459 sym
->st_name
= name_offset
;
460 sym
->st_value
= value
;
463 sym
->st_other
= other
;
464 sym
->st_shndx
= shndx
;
465 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
469 ptr
= section_ptr_add(hs
, sizeof(int));
470 base
= (int *)hs
->data
;
471 /* only add global or weak symbols. */
472 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
473 /* add another hashing entry */
475 h
= elf_hash((unsigned char *)s
->link
->data
+ name_offset
) % nbuckets
;
477 base
[2 + h
] = sym_index
;
479 /* we resize the hash table */
480 hs
->nb_hashed_syms
++;
481 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
482 rebuild_hash(s
, 2 * nbuckets
);
492 ST_FUNC
int find_elf_sym(Section
*s
, const char *name
)
496 int nbuckets
, sym_index
, h
;
502 nbuckets
= ((int *)hs
->data
)[0];
503 h
= elf_hash((unsigned char *) name
) % nbuckets
;
504 sym_index
= ((int *)hs
->data
)[2 + h
];
505 while (sym_index
!= 0) {
506 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
507 name1
= (char *) s
->link
->data
+ sym
->st_name
;
508 if (!strcmp(name
, name1
))
510 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
515 /* return elf symbol value, signal error if 'err' is nonzero, decorate
517 ST_FUNC addr_t
get_sym_addr(TCCState
*s1
, const char *name
, int err
, int forc
)
522 if (forc
&& s1
->leading_underscore
524 /* win32-32bit stdcall symbols always have _ already */
525 && !strchr(name
, '@')
529 pstrcpy(buf
+ 1, sizeof(buf
) - 1, name
);
532 sym_index
= find_elf_sym(s1
->symtab
, name
);
533 sym
= &((ElfW(Sym
) *)s1
->symtab
->data
)[sym_index
];
534 if (!sym_index
|| sym
->st_shndx
== SHN_UNDEF
) {
536 tcc_error_noabort("%s not defined", name
);
539 return sym
->st_value
;
542 /* return elf symbol value */
543 LIBTCCAPI
void *tcc_get_symbol(TCCState
*s
, const char *name
)
545 addr_t addr
= get_sym_addr(s
, name
, 0, 1);
546 return addr
== -1 ? NULL
: (void*)(uintptr_t)addr
;
549 /* list elf symbol names and values */
550 ST_FUNC
void list_elf_symbols(TCCState
*s
, void *ctx
,
551 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
555 int sym_index
, end_sym
;
557 unsigned char sym_vis
, sym_bind
;
560 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
561 for (sym_index
= 0; sym_index
< end_sym
; ++sym_index
) {
562 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
564 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
565 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
566 sym_vis
= ELFW(ST_VISIBILITY
)(sym
->st_other
);
567 if (sym_bind
== STB_GLOBAL
&& sym_vis
== STV_DEFAULT
)
568 symbol_cb(ctx
, name
, (void*)(uintptr_t)sym
->st_value
);
573 /* list elf symbol names and values */
574 LIBTCCAPI
void tcc_list_symbols(TCCState
*s
, void *ctx
,
575 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
577 list_elf_symbols(s
, ctx
, symbol_cb
);
582 version_add (TCCState
*s1
)
586 ElfW(Verneed
) *vn
= NULL
;
588 int sym_index
, end_sym
, nb_versions
= 2, nb_entries
= 0;
592 if (0 == nb_sym_versions
)
594 versym_section
= new_section(s1
, ".gnu.version", SHT_GNU_versym
, SHF_ALLOC
);
595 versym_section
->sh_entsize
= sizeof(ElfW(Half
));
596 versym_section
->link
= s1
->dynsym
;
598 /* add needed symbols */
600 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
601 versym
= section_ptr_add(versym_section
, end_sym
* sizeof(ElfW(Half
)));
602 for (sym_index
= 1; sym_index
< end_sym
; ++sym_index
) {
603 int dllindex
, verndx
;
604 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
605 if (sym
->st_shndx
!= SHN_UNDEF
)
606 continue; /* defined symbol doesn't need library version */
607 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
608 dllindex
= find_elf_sym(s1
->dynsymtab_section
, name
);
609 verndx
= (dllindex
&& dllindex
< nb_sym_to_version
)
610 ? sym_to_version
[dllindex
] : -1;
612 if (!sym_versions
[verndx
].out_index
)
613 sym_versions
[verndx
].out_index
= nb_versions
++;
614 versym
[sym_index
] = sym_versions
[verndx
].out_index
;
617 /* generate verneed section, but not when it will be empty. Some
618 dynamic linkers look at their contents even when DTVERNEEDNUM and
619 section size is zero. */
620 if (nb_versions
> 2) {
621 verneed_section
= new_section(s1
, ".gnu.version_r",
622 SHT_GNU_verneed
, SHF_ALLOC
);
623 verneed_section
->link
= s1
->dynsym
->link
;
624 for (i
= nb_sym_versions
; i
-- > 0;) {
625 struct sym_version
*sv
= &sym_versions
[i
];
626 int n_same_libs
= 0, prev
;
628 ElfW(Vernaux
) *vna
= 0;
629 if (sv
->out_index
< 1)
632 /* make sure that a DT_NEEDED tag is put */
633 /* abitest-tcc fails on older i386-linux with "ld-linux.so.2" DT_NEEDED
634 ret_int_test... Inconsistency detected by ld.so: dl-minimal.c: 148:
635 realloc: Assertion `ptr == alloc_last_block' failed! */
636 if (strcmp(sv
->lib
, "ld-linux.so.2"))
637 tcc_add_dllref(s1
, sv
->lib
, 0);
639 vnofs
= section_add(verneed_section
, sizeof(*vn
), 1);
640 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
642 vn
->vn_file
= put_elf_str(verneed_section
->link
, sv
->lib
);
643 vn
->vn_aux
= sizeof (*vn
);
645 prev
= sv
->prev_same_lib
;
646 if (sv
->out_index
> 0) {
647 vna
= section_ptr_add(verneed_section
, sizeof(*vna
));
648 vna
->vna_hash
= elf_hash ((const unsigned char *)sv
->version
);
650 vna
->vna_other
= sv
->out_index
;
652 vna
->vna_name
= put_elf_str(verneed_section
->link
, sv
->version
);
653 vna
->vna_next
= sizeof (*vna
);
657 sv
= &sym_versions
[prev
];
660 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
661 vn
->vn_cnt
= n_same_libs
;
662 vn
->vn_next
= sizeof(*vn
) + n_same_libs
* sizeof(*vna
);
667 verneed_section
->sh_info
= nb_entries
;
669 dt_verneednum
= nb_entries
;
671 #endif /* ndef ELF_OBJ_ONLY */
673 /* add an elf symbol : check if it is already defined and patch
674 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
675 ST_FUNC
int set_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
676 int info
, int other
, int shndx
, const char *name
)
678 TCCState
*s1
= s
->s1
;
680 int sym_bind
, sym_index
, sym_type
, esym_bind
;
681 unsigned char sym_vis
, esym_vis
, new_vis
;
683 sym_bind
= ELFW(ST_BIND
)(info
);
684 sym_type
= ELFW(ST_TYPE
)(info
);
685 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
687 if (sym_bind
!= STB_LOCAL
) {
688 /* we search global or weak symbols */
689 sym_index
= find_elf_sym(s
, name
);
692 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
693 if (esym
->st_value
== value
&& esym
->st_size
== size
&& esym
->st_info
== info
694 && esym
->st_other
== other
&& esym
->st_shndx
== shndx
)
696 if (esym
->st_shndx
!= SHN_UNDEF
) {
697 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
698 /* propagate the most constraining visibility */
699 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
700 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
701 if (esym_vis
== STV_DEFAULT
) {
703 } else if (sym_vis
== STV_DEFAULT
) {
706 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
708 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
710 if (shndx
== SHN_UNDEF
) {
711 /* ignore adding of undefined symbol if the
712 corresponding symbol is already defined */
713 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
714 /* global overrides weak, so patch */
716 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
717 /* weak is ignored if already global */
718 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_WEAK
) {
719 /* keep first-found weak definition, ignore subsequents */
720 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
721 /* ignore hidden symbols after */
722 } else if ((esym
->st_shndx
== SHN_COMMON
723 || esym
->st_shndx
== bss_section
->sh_num
)
724 && (shndx
< SHN_LORESERVE
725 && shndx
!= bss_section
->sh_num
)) {
726 /* data symbol gets precedence over common/bss */
728 } else if (shndx
== SHN_COMMON
|| shndx
== bss_section
->sh_num
) {
729 /* data symbol keeps precedence over common/bss */
730 } else if (s
->sh_flags
& SHF_DYNSYM
) {
731 /* we accept that two DLL define the same symbol */
732 } else if (esym
->st_other
& ST_ASM_SET
) {
733 /* If the existing symbol came from an asm .set
738 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
739 sym_bind
, shndx
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
741 tcc_error_noabort("'%s' defined twice", name
);
744 esym
->st_other
= other
;
746 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
747 esym
->st_shndx
= shndx
;
748 s1
->new_undef_sym
= 1;
749 esym
->st_value
= value
;
750 esym
->st_size
= size
;
754 sym_index
= put_elf_sym(s
, value
, size
,
755 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
762 ST_FUNC
void put_elf_reloca(Section
*symtab
, Section
*s
, unsigned long offset
,
763 int type
, int symbol
, addr_t addend
)
765 TCCState
*s1
= s
->s1
;
772 /* if no relocation section, create it */
773 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
774 /* if the symtab is allocated, then we consider the relocation
776 sr
= new_section(s
->s1
, buf
, SHT_RELX
, symtab
->sh_flags
);
777 sr
->sh_entsize
= sizeof(ElfW_Rel
);
779 sr
->sh_info
= s
->sh_num
;
782 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
783 rel
->r_offset
= offset
;
784 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
785 #if SHT_RELX == SHT_RELA
786 rel
->r_addend
= addend
;
788 if (SHT_RELX
!= SHT_RELA
&& addend
)
789 tcc_error_noabort("non-zero addend on REL architecture");
792 ST_FUNC
void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
793 int type
, int symbol
)
795 put_elf_reloca(symtab
, s
, offset
, type
, symbol
, 0);
798 ST_FUNC
struct sym_attr
*get_sym_attr(TCCState
*s1
, int index
, int alloc
)
801 struct sym_attr
*tab
;
803 if (index
>= s1
->nb_sym_attrs
) {
805 return s1
->sym_attrs
;
806 /* find immediately bigger power of 2 and reallocate array */
810 tab
= tcc_realloc(s1
->sym_attrs
, n
* sizeof(*s1
->sym_attrs
));
812 memset(s1
->sym_attrs
+ s1
->nb_sym_attrs
, 0,
813 (n
- s1
->nb_sym_attrs
) * sizeof(*s1
->sym_attrs
));
814 s1
->nb_sym_attrs
= n
;
816 return &s1
->sym_attrs
[index
];
819 static void modify_reloctions_old_to_new(TCCState
*s1
, Section
*s
, int *old_to_new_syms
)
821 int i
, type
, sym_index
;
825 for(i
= 1; i
< s1
->nb_sections
; i
++) {
826 sr
= s1
->sections
[i
];
827 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
828 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
829 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
830 type
= ELFW(R_TYPE
)(rel
->r_info
);
831 sym_index
= old_to_new_syms
[sym_index
];
832 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
838 /* In an ELF file symbol table, the local symbols must appear below
839 the global and weak ones. Since TCC cannot sort it while generating
840 the code, we must do it after. All the relocation tables are also
841 modified to take into account the symbol table sorting */
842 static void sort_syms(TCCState
*s1
, Section
*s
)
844 int *old_to_new_syms
;
849 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
850 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
851 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
853 /* first pass for local symbols */
854 p
= (ElfW(Sym
) *)s
->data
;
856 for(i
= 0; i
< nb_syms
; i
++) {
857 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
858 old_to_new_syms
[i
] = q
- new_syms
;
863 /* save the number of local symbols in section header */
864 if( s
->sh_size
) /* this 'if' makes IDA happy */
865 s
->sh_info
= q
- new_syms
;
867 /* then second pass for non local symbols */
868 p
= (ElfW(Sym
) *)s
->data
;
869 for(i
= 0; i
< nb_syms
; i
++) {
870 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
871 old_to_new_syms
[i
] = q
- new_syms
;
877 /* we copy the new symbols to the old */
878 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
881 modify_reloctions_old_to_new(s1
, s
, old_to_new_syms
);
883 tcc_free(old_to_new_syms
);
887 /* See: https://flapenguin.me/elf-dt-gnu-hash */
888 #define ELFCLASS_BITS (PTR_SIZE * 8)
890 static Section
*create_gnu_hash(TCCState
*s1
)
892 int nb_syms
, i
, ndef
, nbuckets
, symoffset
, bloom_size
, bloom_shift
;
895 Section
*dynsym
= s1
->dynsym
;
898 gnu_hash
= new_section(s1
, ".gnu.hash", SHT_GNU_HASH
, SHF_ALLOC
);
899 gnu_hash
->link
= dynsym
->hash
->link
;
901 nb_syms
= dynsym
->data_offset
/ sizeof(ElfW(Sym
));
903 /* count def symbols */
905 p
= (ElfW(Sym
) *)dynsym
->data
;
906 for(i
= 0; i
< nb_syms
; i
++, p
++)
907 ndef
+= p
->st_shndx
!= SHN_UNDEF
;
909 /* calculate gnu hash sizes and fill header */
910 nbuckets
= ndef
/ 4 + 1;
911 symoffset
= nb_syms
- ndef
;
912 bloom_shift
= PTR_SIZE
== 8 ? 6 : 5;
913 bloom_size
= 1; /* must be power of two */
914 while (ndef
>= bloom_size
* (1 << (bloom_shift
- 3)))
916 ptr
= section_ptr_add(gnu_hash
, 4 * 4 +
917 PTR_SIZE
* bloom_size
+
923 ptr
[3] = bloom_shift
;
927 static Elf32_Word
elf_gnu_hash (const unsigned char *name
)
932 while ((c
= *name
++))
937 static void update_gnu_hash(TCCState
*s1
, Section
*gnu_hash
)
939 int *old_to_new_syms
;
941 int nb_syms
, i
, nbuckets
, bloom_size
, bloom_shift
;
944 Section
*dynsym
= s1
->dynsym
;
945 Elf32_Word
*ptr
, *buckets
, *chain
, *hash
;
946 unsigned int *nextbuck
;
948 unsigned char *strtab
;
949 struct { int first
, last
; } *buck
;
951 strtab
= dynsym
->link
->data
;
952 nb_syms
= dynsym
->data_offset
/ sizeof(ElfW(Sym
));
953 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
954 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
955 hash
= tcc_malloc(nb_syms
* sizeof(Elf32_Word
));
956 nextbuck
= tcc_malloc(nb_syms
* sizeof(int));
958 /* calculate hashes and copy undefs */
959 p
= (ElfW(Sym
) *)dynsym
->data
;
961 for(i
= 0; i
< nb_syms
; i
++, p
++) {
962 if (p
->st_shndx
== SHN_UNDEF
) {
963 old_to_new_syms
[i
] = q
- new_syms
;
967 hash
[i
] = elf_gnu_hash(strtab
+ p
->st_name
);
970 ptr
= (Elf32_Word
*) gnu_hash
->data
;
973 bloom_shift
= ptr
[3];
974 bloom
= (addr_t
*) (void *) &ptr
[4];
975 buckets
= (Elf32_Word
*) (void *) &bloom
[bloom_size
];
976 chain
= &buckets
[nbuckets
];
977 buck
= tcc_malloc(nbuckets
* sizeof(*buck
));
979 if (gnu_hash
->data_offset
!= 4 * 4 +
980 PTR_SIZE
* bloom_size
+
982 (nb_syms
- (q
- new_syms
)) * 4)
983 tcc_error_noabort ("gnu_hash size incorrect");
986 for(i
= 0; i
< nbuckets
; i
++)
989 p
= (ElfW(Sym
) *)dynsym
->data
;
990 for(i
= 0; i
< nb_syms
; i
++, p
++)
991 if (p
->st_shndx
!= SHN_UNDEF
) {
992 int bucket
= hash
[i
] % nbuckets
;
994 if (buck
[bucket
].first
== -1)
995 buck
[bucket
].first
= buck
[bucket
].last
= i
;
997 nextbuck
[buck
[bucket
].last
] = i
;
998 buck
[bucket
].last
= i
;
1002 /* fill buckets/chains/bloom and sort symbols */
1003 p
= (ElfW(Sym
) *)dynsym
->data
;
1004 for(i
= 0; i
< nbuckets
; i
++) {
1005 int cur
= buck
[i
].first
;
1008 buckets
[i
] = q
- new_syms
;
1010 old_to_new_syms
[cur
] = q
- new_syms
;
1012 *chain
++ = hash
[cur
] & ~1;
1013 bloom
[(hash
[cur
] / ELFCLASS_BITS
) % bloom_size
] |=
1014 (addr_t
)1 << (hash
[cur
] % ELFCLASS_BITS
) |
1015 (addr_t
)1 << ((hash
[cur
] >> bloom_shift
) % ELFCLASS_BITS
);
1016 if (cur
== buck
[i
].last
)
1018 cur
= nextbuck
[cur
];
1024 memcpy(dynsym
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
1030 modify_reloctions_old_to_new(s1
, dynsym
, old_to_new_syms
);
1032 /* modify the versions */
1033 vs
= versym_section
;
1035 ElfW(Half
) *newver
, *versym
= (ElfW(Half
) *)vs
->data
;
1038 newver
= tcc_malloc(nb_syms
* sizeof(*newver
));
1039 for (i
= 0; i
< nb_syms
; i
++)
1040 newver
[old_to_new_syms
[i
]] = versym
[i
];
1041 memcpy(vs
->data
, newver
, nb_syms
* sizeof(*newver
));
1046 tcc_free(old_to_new_syms
);
1049 ptr
= (Elf32_Word
*) dynsym
->hash
->data
;
1050 rebuild_hash(dynsym
, ptr
[0]);
1052 #endif /* ELF_OBJ_ONLY */
1054 /* relocate symbol table, resolve undefined symbols if do_resolve is
1055 true and output error if undefined symbol. */
1056 ST_FUNC
void relocate_syms(TCCState
*s1
, Section
*symtab
, int do_resolve
)
1059 int sym_bind
, sh_num
;
1062 for_each_elem(symtab
, 1, sym
, ElfW(Sym
)) {
1063 sh_num
= sym
->st_shndx
;
1064 if (sh_num
== SHN_UNDEF
) {
1065 if (do_resolve
== 2) /* relocating dynsym */
1067 name
= (char *) s1
->symtab
->link
->data
+ sym
->st_name
;
1068 /* Use ld.so to resolve symbol for us (for tcc -run) */
1070 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
1071 /* dlsym() needs the undecorated name. */
1072 void *addr
= dlsym(RTLD_DEFAULT
, &name
[s1
->leading_underscore
]);
1073 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD || TARGETOS_ANDROID
1076 for (i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
1077 if ((addr
= dlsym(s1
->loaded_dlls
[i
]->handle
, name
)))
1082 sym
->st_value
= (addr_t
) addr
;
1084 printf ("relocate_sym: %s -> 0x%lx\n", name
, sym
->st_value
);
1089 /* if dynamic symbol exist, it will be used in relocate_section */
1090 } else if (s1
->dynsym
&& find_elf_sym(s1
->dynsym
, name
))
1092 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1094 if (!strcmp(name
, "_fp_hw"))
1096 /* only weak symbols are accepted to be undefined. Their
1098 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
1099 if (sym_bind
== STB_WEAK
)
1102 tcc_error_noabort("undefined symbol '%s'", name
);
1104 } else if (sh_num
< SHN_LORESERVE
) {
1105 /* add section base */
1106 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1112 /* relocate a given section (CPU dependent) by applying the relocations
1113 in the associated relocation section */
1114 static void relocate_section(TCCState
*s1
, Section
*s
, Section
*sr
)
1118 int type
, sym_index
;
1121 int is_dwarf
= s
->sh_num
>= s1
->dwlo
&& s
->sh_num
< s1
->dwhi
;
1123 qrel
= (ElfW_Rel
*)sr
->data
;
1124 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
1125 ptr
= s
->data
+ rel
->r_offset
;
1126 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1127 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1128 type
= ELFW(R_TYPE
)(rel
->r_info
);
1129 tgt
= sym
->st_value
;
1130 #if SHT_RELX == SHT_RELA
1131 tgt
+= rel
->r_addend
;
1133 if (is_dwarf
&& type
== R_DATA_32DW
1134 && sym
->st_shndx
>= s1
->dwlo
&& sym
->st_shndx
< s1
->dwhi
) {
1135 /* dwarf section relocation to each other */
1136 add32le(ptr
, tgt
- s1
->sections
[sym
->st_shndx
]->sh_addr
);
1139 addr
= s
->sh_addr
+ rel
->r_offset
;
1140 relocate(s1
, rel
, type
, ptr
, addr
, tgt
);
1142 #ifndef ELF_OBJ_ONLY
1143 /* if the relocation is allocated, we change its symbol table */
1144 if (sr
->sh_flags
& SHF_ALLOC
) {
1145 sr
->link
= s1
->dynsym
;
1146 if (s1
->output_type
& TCC_OUTPUT_DYN
) {
1147 size_t r
= (uint8_t*)qrel
- sr
->data
;
1148 if (sizeof ((Stab_Sym
*)0)->n_value
< PTR_SIZE
1149 && 0 == strcmp(s
->name
, ".stab"))
1150 r
= 0; /* cannot apply 64bit relocation to 32bit value */
1151 sr
->data_offset
= sr
->sh_size
= r
;
1152 #ifdef CONFIG_TCC_PIE
1153 if (r
&& 0 == (s
->sh_flags
& SHF_WRITE
))
1154 tcc_warning("%d relocations to ro-section %s", (unsigned)(r
/ sizeof *qrel
), s
->name
);
1161 /* relocate all sections */
1162 ST_FUNC
void relocate_sections(TCCState
*s1
)
1167 for (i
= 1; i
< s1
->nb_sections
; ++i
) {
1168 sr
= s1
->sections
[i
];
1169 if (sr
->sh_type
!= SHT_RELX
)
1171 s
= s1
->sections
[sr
->sh_info
];
1172 #ifndef TCC_TARGET_MACHO
1175 || s1
->output_type
== TCC_OUTPUT_MEMORY
)
1178 relocate_section(s1
, s
, sr
);
1180 #ifndef ELF_OBJ_ONLY
1181 if (sr
->sh_flags
& SHF_ALLOC
) {
1183 /* relocate relocation table in 'sr' */
1184 for_each_elem(sr
, 0, rel
, ElfW_Rel
)
1185 rel
->r_offset
+= s
->sh_addr
;
1191 #ifndef ELF_OBJ_ONLY
1192 /* count the number of dynamic relocations so that we can reserve
1194 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
1197 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1198 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1199 defined(TCC_TARGET_RISCV64)
1201 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
1202 int sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1203 int type
= ELFW(R_TYPE
)(rel
->r_info
);
1205 #if defined(TCC_TARGET_I386)
1207 if (!get_sym_attr(s1
, sym_index
, 0)->dyn_index
1208 && ((ElfW(Sym
)*)symtab_section
->data
+ sym_index
)->st_shndx
== SHN_UNDEF
) {
1209 /* don't fixup unresolved (weak) symbols */
1210 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_386_RELATIVE
);
1213 #elif defined(TCC_TARGET_X86_64)
1217 #elif defined(TCC_TARGET_ARM)
1220 #elif defined(TCC_TARGET_ARM64)
1221 case R_AARCH64_ABS32
:
1222 case R_AARCH64_ABS64
:
1223 #elif defined(TCC_TARGET_RISCV64)
1229 #if defined(TCC_TARGET_I386)
1231 #elif defined(TCC_TARGET_X86_64)
1234 ElfW(Sym
) *sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1235 /* Hidden defined symbols can and must be resolved locally.
1236 We're misusing a PLT32 reloc for this, as that's always
1237 resolved to its address even in shared libs. */
1238 if (sym
->st_shndx
!= SHN_UNDEF
&&
1239 ELFW(ST_VISIBILITY
)(sym
->st_other
) == STV_HIDDEN
) {
1240 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PLT32
);
1244 #elif defined(TCC_TARGET_ARM64)
1245 case R_AARCH64_PREL32
:
1247 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1249 if (get_sym_attr(s1
, sym_index
, 0)->dyn_index
)
1261 #ifdef NEED_BUILD_GOT
1262 static int build_got(TCCState
*s1
)
1264 /* if no got, then create it */
1265 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
1266 s1
->got
->sh_entsize
= 4;
1267 /* keep space for _DYNAMIC pointer and two dummy got entries */
1268 section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
1269 return set_elf_sym(symtab_section
, 0, 0, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
1270 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
1273 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1274 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1275 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1276 Returns the offset of the GOT or (if any) PLT entry. */
1277 static struct sym_attr
* put_got_entry(TCCState
*s1
, int dyn_reloc_type
,
1283 struct sym_attr
*attr
;
1284 unsigned got_offset
;
1289 need_plt_entry
= (dyn_reloc_type
== R_JMP_SLOT
);
1290 attr
= get_sym_attr(s1
, sym_index
, 1);
1292 /* In case a function is both called and its address taken 2 GOT entries
1293 are created, one for taking the address (GOT) and the other for the PLT
1295 if (need_plt_entry
? attr
->plt_offset
: attr
->got_offset
)
1299 if (need_plt_entry
) {
1301 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
1302 s1
->plt
->sh_entsize
= 4;
1307 /* create the GOT entry */
1308 got_offset
= s1
->got
->data_offset
;
1309 section_ptr_add(s1
->got
, PTR_SIZE
);
1311 /* Create the GOT relocation that will insert the address of the object or
1312 function of interest in the GOT entry. This is a static relocation for
1313 memory output (dlsym will give us the address of symbols) and dynamic
1314 relocation otherwise (executable and DLLs). The relocation should be
1315 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1316 associated to a PLT entry) but is currently done at load time for an
1319 sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1320 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1321 //printf("sym %d %s\n", need_plt_entry, name);
1324 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
) {
1325 /* Hack alarm. We don't want to emit dynamic symbols
1326 and symbol based relocs for STB_LOCAL symbols, but rather
1327 want to resolve them directly. At this point the symbol
1328 values aren't final yet, so we must defer this. We will later
1329 have to create a RELATIVE reloc anyway, so we misuse the
1330 relocation slot to smuggle the symbol reference until
1331 fill_local_got_entries. Not that the sym_index is
1332 relative to symtab_section, not s1->dynsym! Nevertheless
1333 we use s1->dyn_sym so that if this is the first call
1334 that got->reloc is correctly created. Also note that
1335 RELATIVE relocs are not normally created for the .got,
1336 so the types serves as a marker for later (and is retained
1337 also for the final output, which is okay because then the
1338 got is just normal data). */
1339 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, R_RELATIVE
,
1342 if (0 == attr
->dyn_index
)
1343 attr
->dyn_index
= set_elf_sym(s1
->dynsym
, sym
->st_value
,
1344 sym
->st_size
, sym
->st_info
, 0,
1345 sym
->st_shndx
, name
);
1346 put_elf_reloc(s1
->dynsym
, s_rel
, got_offset
, dyn_reloc_type
,
1350 put_elf_reloc(symtab_section
, s1
->got
, got_offset
, dyn_reloc_type
,
1354 if (need_plt_entry
) {
1355 attr
->plt_offset
= create_plt_entry(s1
, got_offset
, attr
);
1357 /* create a symbol 'sym@plt' for the PLT jump vector */
1359 if (len
> sizeof plt_name
- 5)
1360 len
= sizeof plt_name
- 5;
1361 memcpy(plt_name
, name
, len
);
1362 strcpy(plt_name
+ len
, "@plt");
1363 attr
->plt_sym
= put_elf_sym(s1
->symtab
, attr
->plt_offset
, 0,
1364 ELFW(ST_INFO
)(STB_GLOBAL
, STT_FUNC
), 0, s1
->plt
->sh_num
, plt_name
);
1366 attr
->got_offset
= got_offset
;
1372 /* build GOT and PLT entries */
1373 /* Two passes because R_JMP_SLOT should become first. Some targets
1374 (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1375 ST_FUNC
void build_got_entries(TCCState
*s1
, int got_sym
)
1380 int i
, type
, gotplt_entry
, reloc_type
, sym_index
;
1381 struct sym_attr
*attr
;
1384 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1385 s
= s1
->sections
[i
];
1386 if (s
->sh_type
!= SHT_RELX
)
1388 /* no need to handle got relocations */
1389 if (s
->link
!= symtab_section
)
1391 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1392 type
= ELFW(R_TYPE
)(rel
->r_info
);
1393 gotplt_entry
= gotplt_entry_type(type
);
1394 if (gotplt_entry
== -1) {
1395 tcc_error_noabort ("Unknown relocation type for got: %d", type
);
1398 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1399 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1401 if (gotplt_entry
== NO_GOTPLT_ENTRY
) {
1405 /* Automatically create PLT/GOT [entry] if it is an undefined
1406 reference (resolved at runtime), or the symbol is absolute,
1407 probably created by tcc_add_symbol, and thus on 64-bit
1408 targets might be too far from application code. */
1409 if (gotplt_entry
== AUTO_GOTPLT_ENTRY
) {
1410 if (sym
->st_shndx
== SHN_UNDEF
) {
1413 if (!PCRELATIVE_DLLPLT
1414 && (s1
->output_type
& TCC_OUTPUT_DYN
))
1416 /* Relocations for UNDEF symbols would normally need
1417 to be transferred into the executable or shared object.
1418 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1419 But TCC doesn't do that (at least for exes), so we
1420 need to resolve all such relocs locally. And that
1421 means PLT slots for functions in DLLs and COPY relocs for
1422 data symbols. COPY relocs were generated in
1423 bind_exe_dynsyms (and the symbol adjusted to be defined),
1424 and for functions we were generated a dynamic symbol
1425 of function type. */
1427 /* dynsym isn't set for -run :-/ */
1428 dynindex
= get_sym_attr(s1
, sym_index
, 0)->dyn_index
;
1429 esym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ dynindex
;
1431 && (ELFW(ST_TYPE
)(esym
->st_info
) == STT_FUNC
1432 || (ELFW(ST_TYPE
)(esym
->st_info
) == STT_NOTYPE
1433 && ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
)))
1436 } else if (sym
->st_shndx
== SHN_ABS
) {
1437 if (sym
->st_value
== 0) /* from tcc_add_btstub() */
1439 #ifndef TCC_TARGET_ARM
1443 /* from tcc_add_symbol(): on 64 bit platforms these
1444 need to go through .got */
1449 #ifdef TCC_TARGET_X86_64
1450 if ((type
== R_X86_64_PLT32
|| type
== R_X86_64_PC32
) &&
1451 sym
->st_shndx
!= SHN_UNDEF
&&
1452 (ELFW(ST_VISIBILITY
)(sym
->st_other
) != STV_DEFAULT
||
1453 ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
||
1454 s1
->output_type
& TCC_OUTPUT_EXE
)) {
1457 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PC32
);
1461 reloc_type
= code_reloc(type
);
1462 if (reloc_type
== -1) {
1463 tcc_error_noabort ("Unknown relocation type: %d", type
);
1467 if (reloc_type
!= 0) {
1471 reloc_type
= R_JMP_SLOT
;
1475 reloc_type
= R_GLOB_DAT
;
1479 got_sym
= build_got(s1
);
1481 if (gotplt_entry
== BUILD_GOT_ONLY
)
1484 attr
= put_got_entry(s1
, reloc_type
, sym_index
);
1486 if (reloc_type
== R_JMP_SLOT
)
1487 rel
->r_info
= ELFW(R_INFO
)(attr
->plt_sym
, type
);
1492 /* .rel.plt refers to .got actually */
1493 if (s1
->plt
&& s1
->plt
->reloc
)
1494 s1
->plt
->reloc
->sh_info
= s1
->got
->sh_num
;
1495 if (got_sym
) /* set size */
1496 ((ElfW(Sym
)*)symtab_section
->data
)[got_sym
].st_size
= s1
->got
->data_offset
;
1498 #endif /* def NEED_BUILD_GOT */
1500 ST_FUNC
int set_global_sym(TCCState
*s1
, const char *name
, Section
*sec
, addr_t offs
)
1502 int shn
= sec
? sec
->sh_num
: offs
|| !name
? SHN_ABS
: SHN_UNDEF
;
1503 if (sec
&& offs
== -1)
1504 offs
= sec
->data_offset
;
1505 return set_elf_sym(symtab_section
, offs
, 0,
1506 ELFW(ST_INFO
)(name
? STB_GLOBAL
: STB_LOCAL
, STT_NOTYPE
), 0, shn
, name
);
1509 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1514 s
= have_section(s1
, section_name
);
1515 if (!s
|| !(s
->sh_flags
& SHF_ALLOC
)) {
1519 end_offset
= s
->data_offset
;
1521 snprintf(buf
, sizeof(buf
), "__%s_start", section_name
+ 1);
1522 set_global_sym(s1
, buf
, s
, 0);
1523 snprintf(buf
, sizeof(buf
), "__%s_end", section_name
+ 1);
1524 set_global_sym(s1
, buf
, s
, end_offset
);
1527 ST_FUNC
void add_array (TCCState
*s1
, const char *sec
, int c
)
1530 s
= find_section(s1
, sec
);
1531 s
->sh_flags
= shf_RELRO
;
1532 s
->sh_type
= sec
[1] == 'i' ? SHT_INIT_ARRAY
: SHT_FINI_ARRAY
;
1533 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1534 section_ptr_add(s
, PTR_SIZE
);
1537 #ifdef CONFIG_TCC_BCHECK
1538 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
1540 if (0 == s1
->do_bounds_check
)
1542 section_ptr_add(bounds_section
, sizeof(addr_t
));
1546 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1547 a dynamic symbol to allow so's to have one each with a different value. */
1548 static void set_local_sym(TCCState
*s1
, const char *name
, Section
*s
, int offset
)
1550 int c
= find_elf_sym(s1
->symtab
, name
);
1552 ElfW(Sym
) *esym
= (ElfW(Sym
)*)s1
->symtab
->data
+ c
;
1553 esym
->st_info
= ELFW(ST_INFO
)(STB_LOCAL
, STT_NOTYPE
);
1554 esym
->st_value
= offset
;
1555 esym
->st_shndx
= s
->sh_num
;
1559 /* avoid generating debug/test_coverage code for stub functions */
1560 static void tcc_compile_string_no_debug(TCCState
*s
, const char *str
)
1562 int save_do_debug
= s
->do_debug
;
1563 int save_test_coverage
= s
->test_coverage
;
1566 s
->test_coverage
= 0;
1567 tcc_compile_string(s
, str
);
1568 s
->do_debug
= save_do_debug
;
1569 s
->test_coverage
= save_test_coverage
;
1572 #ifdef CONFIG_TCC_BACKTRACE
1573 static void put_ptr(TCCState
*s1
, Section
*s
, int offs
)
1576 c
= set_global_sym(s1
, NULL
, s
, offs
);
1578 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1579 section_ptr_add(s
, PTR_SIZE
);
1582 ST_FUNC
void tcc_add_btstub(TCCState
*s1
)
1589 /* Align to PTR_SIZE */
1590 section_ptr_add(s
, -s
->data_offset
& (PTR_SIZE
- 1));
1592 /* create (part of) a struct rt_context (see tccrun.c) */
1594 put_ptr(s1
, dwarf_line_section
, 0);
1595 put_ptr(s1
, dwarf_line_section
, -1);
1597 put_ptr(s1
, dwarf_line_str_section
, 0);
1599 put_ptr(s1
, dwarf_str_section
, 0);
1603 put_ptr(s1
, stab_section
, 0);
1604 put_ptr(s1
, stab_section
, -1);
1605 put_ptr(s1
, stab_section
->link
, 0);
1607 *(addr_t
*)section_ptr_add(s
, PTR_SIZE
) = s1
->dwarf
;
1608 /* skip esym_start/esym_end/elf_str (not loaded) */
1609 section_ptr_add(s
, 3 * PTR_SIZE
);
1610 /* prog_base : local nameless symbol with offset 0 at SHN_ABS */
1611 put_ptr(s1
, NULL
, 0);
1612 #if defined TCC_TARGET_MACHO
1613 /* adjust for __PAGEZERO */
1614 if (s1
->dwarf
== 0 && s1
->output_type
== TCC_OUTPUT_EXE
)
1615 write64le(data_section
->data
+ data_section
->data_offset
- PTR_SIZE
,
1619 #ifdef CONFIG_TCC_BCHECK
1620 if (s1
->do_bounds_check
) {
1621 put_ptr(s1
, bounds_section
, 0);
1625 section_ptr_add(s
, n
);
1628 "extern void __bt_init(),__bt_exit(),__bt_init_dll();"
1629 "static void *__rt_info[];"
1630 "__attribute__((constructor)) static void __bt_init_rt(){");
1631 #ifdef TCC_TARGET_PE
1632 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1633 #ifdef CONFIG_TCC_BCHECK
1634 cstr_printf(&cstr
, "__bt_init_dll(%d);", s1
->do_bounds_check
);
1636 cstr_printf(&cstr
, "__bt_init_dll(0);");
1639 cstr_printf(&cstr
, "__bt_init(__rt_info,%d);}",
1640 s1
->output_type
== TCC_OUTPUT_DLL
? 0 : s1
->rt_num_callers
+ 1);
1641 /* In case dlcose is called by application */
1643 "__attribute__((destructor)) static void __bt_exit_rt(){"
1644 "__bt_exit(__rt_info);}");
1645 tcc_compile_string_no_debug(s1
, cstr
.data
);
1647 set_local_sym(s1
, &"___rt_info"[!s1
->leading_underscore
], s
, o
);
1649 #endif /* def CONFIG_TCC_BACKTRACE */
1651 static void tcc_tcov_add_file(TCCState
*s1
, const char *filename
)
1657 if (tcov_section
== NULL
)
1659 section_ptr_add(tcov_section
, 1);
1660 write32le (tcov_section
->data
, tcov_section
->data_offset
);
1663 if (filename
[0] == '/')
1664 cstr_printf (&cstr
, "%s.tcov", filename
);
1666 getcwd (wd
, sizeof(wd
));
1667 cstr_printf (&cstr
, "%s/%s.tcov", wd
, filename
);
1669 ptr
= section_ptr_add(tcov_section
, cstr
.size
+ 1);
1670 strcpy((char *)ptr
, cstr
.data
);
1671 unlink((char *)ptr
);
1673 normalize_slashes((char *)ptr
);
1679 "extern char *__tcov_data[];"
1680 "extern void __store_test_coverage ();"
1681 "__attribute__((destructor)) static void __tcov_exit() {"
1682 "__store_test_coverage(__tcov_data);"
1684 tcc_compile_string_no_debug(s1
, cstr
.data
);
1686 set_local_sym(s1
, &"___tcov_data"[!s1
->leading_underscore
], tcov_section
, 0);
1689 #if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO
1690 /* add libc crt1/crti objects */
1691 ST_FUNC
void tccelf_add_crtbegin(TCCState
*s1
)
1693 #if TARGETOS_OpenBSD
1694 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1695 tcc_add_crt(s1
, "crt0.o");
1696 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1697 tcc_add_crt(s1
, "crtbeginS.o");
1699 tcc_add_crt(s1
, "crtbegin.o");
1700 #elif TARGETOS_FreeBSD || TARGETOS_NetBSD
1701 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1702 #if TARGETOS_FreeBSD
1703 tcc_add_crt(s1
, "crt1.o");
1705 tcc_add_crt(s1
, "crt0.o");
1707 tcc_add_crt(s1
, "crti.o");
1708 if (s1
->static_link
)
1709 tcc_add_crt(s1
, "crtbeginT.o");
1710 else if (s1
->output_type
== TCC_OUTPUT_DLL
)
1711 tcc_add_crt(s1
, "crtbeginS.o");
1713 tcc_add_crt(s1
, "crtbegin.o");
1714 #elif TARGETOS_ANDROID
1715 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1716 tcc_add_crt(s1
, "crtbegin_so.o");
1718 tcc_add_crt(s1
, "crtbegin_dynamic.o");
1720 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1721 tcc_add_crt(s1
, "crt1.o");
1722 tcc_add_crt(s1
, "crti.o");
1726 ST_FUNC
void tccelf_add_crtend(TCCState
*s1
)
1728 #if TARGETOS_OpenBSD
1729 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1730 tcc_add_crt(s1
, "crtendS.o");
1732 tcc_add_crt(s1
, "crtend.o");
1733 #elif TARGETOS_FreeBSD || TARGETOS_NetBSD
1734 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1735 tcc_add_crt(s1
, "crtendS.o");
1737 tcc_add_crt(s1
, "crtend.o");
1738 tcc_add_crt(s1
, "crtn.o");
1739 #elif TARGETOS_ANDROID
1740 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1741 tcc_add_crt(s1
, "crtend_so.o");
1743 tcc_add_crt(s1
, "crtend_android.o");
1745 tcc_add_crt(s1
, "crtn.o");
1748 #endif /* !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO */
1750 #ifndef TCC_TARGET_PE
1751 /* add tcc runtime libraries */
1752 ST_FUNC
void tcc_add_runtime(TCCState
*s1
)
1756 #ifdef CONFIG_TCC_BCHECK
1759 tcc_add_pragma_libs(s1
);
1762 if (!s1
->nostdlib
) {
1763 int lpthread
= s1
->option_pthread
;
1765 #ifdef CONFIG_TCC_BCHECK
1766 if (s1
->do_bounds_check
&& s1
->output_type
!= TCC_OUTPUT_DLL
) {
1767 tcc_add_support(s1
, "bcheck.o");
1768 # if !(TARGETOS_OpenBSD || TARGETOS_NetBSD)
1769 tcc_add_library_err(s1
, "dl");
1774 #ifdef CONFIG_TCC_BACKTRACE
1775 if (s1
->do_backtrace
) {
1776 if (s1
->output_type
& TCC_OUTPUT_EXE
)
1777 tcc_add_support(s1
, "bt-exe.o");
1778 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1779 tcc_add_support(s1
, "bt-log.o");
1780 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1785 tcc_add_library_err(s1
, "pthread");
1786 tcc_add_library_err(s1
, "c");
1788 if (!s1
->static_link
) {
1789 if (TCC_LIBGCC
[0] == '/')
1790 tcc_add_file(s1
, TCC_LIBGCC
);
1792 tcc_add_dll(s1
, TCC_LIBGCC
, AFF_PRINT_ERROR
);
1795 #if defined TCC_TARGET_ARM && TARGETOS_FreeBSD
1796 tcc_add_library_err(s1
, "gcc_s"); // unwind code
1799 tcc_add_support(s1
, TCC_LIBTCC1
);
1800 #ifndef TCC_TARGET_MACHO
1801 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1802 tccelf_add_crtend(s1
);
1806 #endif /* ndef TCC_TARGET_PE */
1808 /* add various standard linker symbols (must be done after the
1809 sections are filled (for example after allocating common
1811 static void tcc_add_linker_symbols(TCCState
*s1
)
1817 set_global_sym(s1
, "_etext", text_section
, -1);
1818 set_global_sym(s1
, "_edata", data_section
, -1);
1819 set_global_sym(s1
, "_end", bss_section
, -1);
1820 #if TARGETOS_OpenBSD
1821 set_global_sym(s1
, "__executable_start", NULL
, ELF_START_ADDR
);
1823 #ifdef TCC_TARGET_RISCV64
1824 /* XXX should be .sdata+0x800, not .data+0x800 */
1825 set_global_sym(s1
, "__global_pointer$", data_section
, 0x800);
1827 /* horrible new standard ldscript defines */
1828 add_init_array_defines(s1
, ".preinit_array");
1829 add_init_array_defines(s1
, ".init_array");
1830 add_init_array_defines(s1
, ".fini_array");
1831 /* add start and stop symbols for sections whose name can be
1833 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1834 s
= s1
->sections
[i
];
1835 if ((s
->sh_flags
& SHF_ALLOC
)
1836 && (s
->sh_type
== SHT_PROGBITS
1837 || s
->sh_type
== SHT_STRTAB
)) {
1839 /* check if section name can be expressed in C */
1845 if (!isid(c
) && !isnum(c
))
1849 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1850 set_global_sym(s1
, buf
, s
, 0);
1851 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1852 set_global_sym(s1
, buf
, s
, -1);
1858 ST_FUNC
void resolve_common_syms(TCCState
*s1
)
1862 /* Allocate common symbols in BSS. */
1863 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1864 if (sym
->st_shndx
== SHN_COMMON
) {
1865 /* symbol alignment is in st_value for SHN_COMMONs */
1866 sym
->st_value
= section_add(bss_section
, sym
->st_size
,
1868 sym
->st_shndx
= bss_section
->sh_num
;
1872 /* Now assign linker provided symbols their value. */
1873 tcc_add_linker_symbols(s1
);
1876 #ifndef ELF_OBJ_ONLY
1877 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1879 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1880 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1881 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1882 unsigned offset
= attr
->got_offset
;
1886 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1888 write64le(s1
->got
->data
+ offset
, sym
->st_value
);
1890 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1894 /* Perform relocation to GOT or PLT entries */
1895 ST_FUNC
void fill_got(TCCState
*s1
)
1901 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1902 s
= s1
->sections
[i
];
1903 if (s
->sh_type
!= SHT_RELX
)
1905 /* no need to handle got relocations */
1906 if (s
->link
!= symtab_section
)
1908 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1909 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1910 case R_X86_64_GOT32
:
1911 case R_X86_64_GOTPCREL
:
1912 case R_X86_64_GOTPCRELX
:
1913 case R_X86_64_REX_GOTPCRELX
:
1914 case R_X86_64_PLT32
:
1915 fill_got_entry(s1
, rel
);
1922 /* See put_got_entry for a description. This is the second stage
1923 where GOT references to local defined symbols are rewritten. */
1924 static void fill_local_got_entries(TCCState
*s1
)
1927 if (!s1
->got
->reloc
)
1929 for_each_elem(s1
->got
->reloc
, 0, rel
, ElfW_Rel
) {
1930 if (ELFW(R_TYPE
)(rel
->r_info
) == R_RELATIVE
) {
1931 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1932 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1933 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1934 unsigned offset
= attr
->got_offset
;
1935 if (offset
!= rel
->r_offset
- s1
->got
->sh_addr
)
1936 tcc_error_noabort("fill_local_got_entries: huh?");
1937 rel
->r_info
= ELFW(R_INFO
)(0, R_RELATIVE
);
1938 #if SHT_RELX == SHT_RELA
1939 rel
->r_addend
= sym
->st_value
;
1941 /* All our REL architectures also happen to be 32bit LE. */
1942 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1948 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1949 in shared libraries */
1950 static void bind_exe_dynsyms(TCCState
*s1
, int is_PIE
)
1953 int sym_index
, index
;
1954 ElfW(Sym
) *sym
, *esym
;
1957 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1958 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1959 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1960 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1961 if (sym
->st_shndx
== SHN_UNDEF
) {
1962 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1963 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1967 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1968 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1969 if ((type
== STT_FUNC
) || (type
== STT_GNU_IFUNC
)) {
1970 /* Indirect functions shall have STT_FUNC type in executable
1971 * dynsym section. Indeed, a dlsym call following a lazy
1972 * resolution would pick the symbol value from the
1973 * executable dynsym entry which would contain the address
1974 * of the function wanted by the caller of dlsym instead of
1975 * the address of the function that would return that
1978 = put_elf_sym(s1
->dynsym
, 0, esym
->st_size
,
1979 ELFW(ST_INFO
)(STB_GLOBAL
,STT_FUNC
), 0, 0,
1981 int index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1982 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1983 } else if (type
== STT_OBJECT
) {
1984 unsigned long offset
;
1986 offset
= bss_section
->data_offset
;
1987 /* XXX: which alignment ? */
1988 offset
= (offset
+ 16 - 1) & -16;
1989 set_elf_sym (s1
->symtab
, offset
, esym
->st_size
,
1990 esym
->st_info
, 0, bss_section
->sh_num
, name
);
1991 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1992 esym
->st_info
, 0, bss_section
->sh_num
,
1995 /* Ensure R_COPY works for weak symbol aliases */
1996 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1997 for_each_elem(s1
->dynsymtab_section
, 1, dynsym
, ElfW(Sym
)) {
1998 if ((dynsym
->st_value
== esym
->st_value
)
1999 && (ELFW(ST_BIND
)(dynsym
->st_info
) == STB_GLOBAL
)) {
2000 char *dynname
= (char *) s1
->dynsymtab_section
->link
->data
2002 put_elf_sym(s1
->dynsym
, offset
, dynsym
->st_size
,
2004 bss_section
->sh_num
, dynname
);
2010 put_elf_reloc(s1
->dynsym
, bss_section
,
2011 offset
, R_COPY
, index
);
2012 offset
+= esym
->st_size
;
2013 bss_section
->data_offset
= offset
;
2016 /* STB_WEAK undefined symbols are accepted */
2017 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
2018 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
2019 !strcmp(name
, "_fp_hw")) {
2021 tcc_error_noabort("undefined symbol '%s'", name
);
2028 /* Bind symbols of libraries: export all non local symbols of executable that
2029 are referenced by shared libraries. The reason is that the dynamic loader
2030 search symbol first in executable and then in libraries. Therefore a
2031 reference to a symbol already defined by a library can still be resolved by
2032 a symbol in the executable. With -rdynamic, export all defined symbols */
2033 static void bind_libs_dynsyms(TCCState
*s1
)
2037 ElfW(Sym
) *sym
, *esym
;
2039 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
2040 name
= (char *)symtab_section
->link
->data
+ sym
->st_name
;
2041 dynsym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
2042 if (sym
->st_shndx
!= SHN_UNDEF
) {
2043 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
2044 && (dynsym_index
|| s1
->rdynamic
))
2045 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
2046 sym
->st_info
, 0, sym
->st_shndx
, name
);
2047 } else if (dynsym_index
) {
2048 esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ dynsym_index
;
2049 if (esym
->st_shndx
== SHN_UNDEF
) {
2050 /* weak symbols can stay undefined */
2051 if (ELFW(ST_BIND
)(esym
->st_info
) != STB_WEAK
)
2052 tcc_warning("undefined dynamic symbol '%s'", name
);
2058 /* Export all non local symbols. This is used by shared libraries so that the
2059 non local symbols they define can resolve a reference in another shared
2060 library or in the executable. Correspondingly, it allows undefined local
2061 symbols to be resolved by other shared libraries or by the executable. */
2062 static void export_global_syms(TCCState
*s1
)
2064 int dynindex
, index
;
2067 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
2068 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2069 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
2070 dynindex
= set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
2071 sym
->st_info
, 0, sym
->st_shndx
, name
);
2072 index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
2073 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
2078 /* decide if an unallocated section should be output. */
2079 static int set_sec_sizes(TCCState
*s1
)
2084 int file_type
= s1
->output_type
;
2086 /* Allocate strings for section names */
2087 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2088 s
= s1
->sections
[i
];
2089 if (s
->sh_type
== SHT_RELX
&& !(s
->sh_flags
& SHF_ALLOC
)) {
2090 /* when generating a DLL, we include relocations but
2091 we may patch them */
2092 if ((file_type
& TCC_OUTPUT_DYN
)
2093 && (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)) {
2094 int count
= prepare_dynamic_rel(s1
, s
);
2096 /* allocate the section */
2097 s
->sh_flags
|= SHF_ALLOC
;
2098 s
->sh_size
= count
* sizeof(ElfW_Rel
);
2099 if (!(s1
->sections
[s
->sh_info
]->sh_flags
& SHF_WRITE
))
2103 } else if ((s
->sh_flags
& SHF_ALLOC
)
2104 #ifdef TCC_TARGET_ARM
2105 || s
->sh_type
== SHT_ARM_ATTRIBUTES
2108 s
->sh_size
= s
->data_offset
;
2111 #ifdef TCC_TARGET_ARM
2112 /* XXX: Suppress stack unwinding section. */
2113 if (s
->sh_type
== SHT_ARM_EXIDX
) {
2123 /* various data used under elf_output_file() */
2128 /* Info to be copied in dynamic section */
2129 unsigned long data_offset
;
2140 /* read only segment mapping for GNU_RELRO */
2141 Section _roinf
, *roinf
;
2144 /* Decide the layout of sections loaded in memory. This must be done before
2145 program headers are filled since they contain info about the layout.
2146 We do the following ordering: interp, symbol tables, relocations, progbits,
2148 static int sort_sections(TCCState
*s1
, int *sec_order
, Section
*interp
)
2151 int i
, j
, k
, f
, f0
, n
;
2152 int nb_sections
= s1
->nb_sections
;
2153 int *sec_cls
= sec_order
+ nb_sections
;
2155 for (i
= 1; i
< nb_sections
; i
++) {
2156 s
= s1
->sections
[i
];
2157 if (s
->sh_flags
& SHF_ALLOC
) {
2159 if (s
->sh_flags
& SHF_WRITE
)
2161 if (s
->sh_flags
& SHF_TLS
)
2163 } else if (s
->sh_name
) {
2166 j
= 0x900; /* no sh_name: won't go to file */
2168 if (s
->sh_type
== SHT_SYMTAB
|| s
->sh_type
== SHT_DYNSYM
) {
2170 } else if (s
->sh_type
== SHT_STRTAB
&& strcmp(s
->name
, ".stabstr")) {
2172 if (i
== nb_sections
- 1) /* ".shstrtab" assumed to remain last */
2174 } else if (s
->sh_type
== SHT_HASH
|| s
->sh_type
== SHT_GNU_HASH
) {
2176 } else if (s
->sh_type
== SHT_RELX
) {
2178 if (s1
->plt
&& s
== s1
->plt
->reloc
)
2180 } else if (s
->sh_type
== SHT_PREINIT_ARRAY
) {
2182 } else if (s
->sh_type
== SHT_INIT_ARRAY
) {
2184 } else if (s
->sh_type
== SHT_FINI_ARRAY
) {
2186 #ifdef CONFIG_TCC_BCHECK
2187 } else if (s
== bounds_section
|| s
== lbounds_section
) {
2190 } else if (s
== rodata_section
|| 0 == strcmp(s
->name
, ".data.rel.ro")) {
2192 } else if (s
->sh_type
== SHT_DYNAMIC
) {
2194 } else if (s
== s1
->got
) {
2195 k
= 0x47; /* .got as RELRO needs BIND_NOW in DT_FLAGS */
2198 if (s
->sh_type
== SHT_NOTE
)
2200 if (s
->sh_flags
& SHF_EXECINSTR
)
2202 if (s
->sh_type
== SHT_NOBITS
)
2209 for (n
= i
; n
> 1 && k
< (f
= sec_cls
[n
- 1]); --n
)
2210 sec_cls
[n
] = f
, sec_order
[n
] = sec_order
[n
- 1];
2211 sec_cls
[n
] = k
, sec_order
[n
] = i
;
2215 /* count PT_LOAD headers needed */
2217 for (i
= 1; i
< nb_sections
; i
++) {
2218 s
= s1
->sections
[sec_order
[i
]];
2222 f
= s
->sh_flags
& (SHF_ALLOC
|SHF_WRITE
|SHF_EXECINSTR
|SHF_TLS
);
2224 /* NetBSD only supports 2 PT_LOAD sections.
2225 See: https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */
2226 if ((f
& SHF_WRITE
) == 0) f
|= SHF_EXECINSTR
;
2228 if ((k
& 0xfff0) == 0x240) /* RELRO sections */
2231 if (f
!= f0
) /* start new header when flags changed or relro */
2232 f0
= f
, ++n
, f
|= 1<<8;
2235 //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);
2240 static ElfW(Phdr
) *fill_phdr(ElfW(Phdr
) *ph
, int type
, Section
*s
)
2243 ph
->p_offset
= s
->sh_offset
;
2244 ph
->p_vaddr
= s
->sh_addr
;
2245 ph
->p_filesz
= s
->sh_size
;
2246 ph
->p_align
= s
->sh_addralign
;
2250 ph
->p_paddr
= ph
->p_vaddr
;
2251 ph
->p_memsz
= ph
->p_filesz
;
2255 /* Assign sections to segments and decide how are sections laid out when loaded
2256 in memory. This function also fills corresponding program headers. */
2257 static int layout_sections(TCCState
*s1
, int *sec_order
, struct dyn_inf
*d
)
2260 addr_t addr
, tmp
, align
, s_align
, base
;
2261 ElfW(Phdr
) *ph
= NULL
;
2262 int i
, f
, n
, phnum
, phfill
;
2265 /* compute number of program headers */
2266 phnum
= sort_sections(s1
, sec_order
, d
->interp
);
2267 phfill
= 0; /* set to 1 to have dll's with a PT_PHDR */
2278 d
->phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
2281 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2282 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2284 s_align
= ELF_PAGE_SIZE
;
2285 if (s1
->section_align
)
2286 s_align
= s1
->section_align
;
2288 addr
= ELF_START_ADDR
;
2289 if (s1
->output_type
& TCC_OUTPUT_DYN
)
2292 if (s1
->has_text_addr
) {
2293 addr
= s1
->text_addr
;
2295 int a_offset
, p_offset
;
2296 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
2298 a_offset
= (int) (addr
& (s_align
- 1));
2299 p_offset
= file_offset
& (s_align
- 1);
2300 if (a_offset
< p_offset
)
2301 a_offset
+= s_align
;
2302 file_offset
+= (a_offset
- p_offset
);
2306 /* compute address after headers */
2307 addr
= addr
+ (file_offset
& (s_align
- 1));
2310 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2311 s
= s1
->sections
[sec_order
[i
]];
2312 f
= sec_order
[i
+ s1
->nb_sections
];
2313 align
= s
->sh_addralign
- 1;
2315 if (f
== 0) { /* no alloc */
2316 file_offset
= (file_offset
+ align
) & ~align
;
2317 s
->sh_offset
= file_offset
;
2318 if (s
->sh_type
!= SHT_NOBITS
)
2319 file_offset
+= s
->sh_size
;
2323 if ((f
& 1<<8) && n
) {
2324 /* different rwx section flags */
2325 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
2326 /* if in the middle of a page, w e duplicate the page in
2327 memory so that one copy is RX and the other is RW */
2328 if ((addr
& (s_align
- 1)) != 0)
2331 align
= s_align
- 1;
2336 addr
= (addr
+ align
) & ~align
;
2337 file_offset
+= (int)(addr
- tmp
);
2338 s
->sh_offset
= file_offset
;
2342 /* set new program header */
2343 ph
= &d
->phdr
[phfill
+ n
];
2344 ph
->p_type
= PT_LOAD
;
2345 ph
->p_align
= s_align
;
2348 ph
->p_flags
|= PF_W
;
2349 if (f
& SHF_EXECINSTR
)
2350 ph
->p_flags
|= PF_X
;
2352 ph
->p_type
= PT_TLS
;
2353 ph
->p_align
= align
+ 1;
2356 ph
->p_offset
= file_offset
;
2359 /* Make the first PT_LOAD segment include the program
2360 headers itself (and the ELF header as well), it'll
2361 come out with same memory use but will make various
2362 tools like binutils strip work better. */
2366 ph
->p_paddr
= ph
->p_vaddr
;
2371 Section
*roinf
= &d
->_roinf
;
2372 if (roinf
->sh_size
== 0) {
2373 roinf
->sh_offset
= s
->sh_offset
;
2374 roinf
->sh_addr
= s
->sh_addr
;
2375 roinf
->sh_addralign
= 1;
2377 roinf
->sh_size
= (addr
- roinf
->sh_addr
) + s
->sh_size
;
2381 if (s
->sh_type
!= SHT_NOBITS
)
2382 file_offset
+= s
->sh_size
;
2384 ph
->p_filesz
= file_offset
- ph
->p_offset
;
2385 ph
->p_memsz
= addr
- ph
->p_vaddr
;
2388 /* Fill other headers */
2390 fill_phdr(++ph
, PT_NOTE
, d
->note
);
2392 fill_phdr(++ph
, PT_DYNAMIC
, d
->dynamic
)->p_flags
|= PF_W
;
2394 fill_phdr(++ph
, PT_GNU_RELRO
, d
->roinf
)->p_flags
|= PF_W
;
2396 fill_phdr(&d
->phdr
[1], PT_INTERP
, d
->interp
);
2399 ph
->p_offset
= sizeof(ElfW(Ehdr
));
2400 ph
->p_vaddr
= base
+ ph
->p_offset
;
2401 ph
->p_filesz
= phnum
* sizeof(ElfW(Phdr
));
2403 fill_phdr(ph
, PT_PHDR
, NULL
);
2408 /* put dynamic tag */
2409 static void put_dt(Section
*dynamic
, int dt
, addr_t val
)
2412 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
2414 dyn
->d_un
.d_val
= val
;
2417 /* Fill the dynamic section with tags describing the address and size of
2419 static void fill_dynamic(TCCState
*s1
, struct dyn_inf
*dyninf
)
2421 Section
*dynamic
= dyninf
->dynamic
;
2424 /* put dynamic section entries */
2425 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
2426 put_dt(dynamic
, DT_GNU_HASH
, dyninf
->gnu_hash
->sh_addr
);
2427 put_dt(dynamic
, DT_STRTAB
, dyninf
->dynstr
->sh_addr
);
2428 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
2429 put_dt(dynamic
, DT_STRSZ
, dyninf
->dynstr
->data_offset
);
2430 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
2432 put_dt(dynamic
, DT_RELA
, dyninf
->rel_addr
);
2433 put_dt(dynamic
, DT_RELASZ
, dyninf
->rel_size
);
2434 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
2435 if (s1
->plt
&& s1
->plt
->reloc
) {
2436 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2437 put_dt(dynamic
, DT_PLTRELSZ
, s1
->plt
->reloc
->data_offset
);
2438 put_dt(dynamic
, DT_JMPREL
, s1
->plt
->reloc
->sh_addr
);
2439 put_dt(dynamic
, DT_PLTREL
, DT_RELA
);
2441 put_dt(dynamic
, DT_RELACOUNT
, 0);
2443 put_dt(dynamic
, DT_REL
, dyninf
->rel_addr
);
2444 put_dt(dynamic
, DT_RELSZ
, dyninf
->rel_size
);
2445 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
2446 if (s1
->plt
&& s1
->plt
->reloc
) {
2447 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2448 put_dt(dynamic
, DT_PLTRELSZ
, s1
->plt
->reloc
->data_offset
);
2449 put_dt(dynamic
, DT_JMPREL
, s1
->plt
->reloc
->sh_addr
);
2450 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
2452 put_dt(dynamic
, DT_RELCOUNT
, 0);
2454 if (versym_section
&& verneed_section
) {
2455 /* The dynamic linker can not handle VERSYM without VERNEED */
2456 put_dt(dynamic
, DT_VERSYM
, versym_section
->sh_addr
);
2457 put_dt(dynamic
, DT_VERNEED
, verneed_section
->sh_addr
);
2458 put_dt(dynamic
, DT_VERNEEDNUM
, dt_verneednum
);
2460 s
= have_section(s1
, ".preinit_array");
2461 if (s
&& s
->data_offset
) {
2462 put_dt(dynamic
, DT_PREINIT_ARRAY
, s
->sh_addr
);
2463 put_dt(dynamic
, DT_PREINIT_ARRAYSZ
, s
->data_offset
);
2465 s
= have_section(s1
, ".init_array");
2466 if (s
&& s
->data_offset
) {
2467 put_dt(dynamic
, DT_INIT_ARRAY
, s
->sh_addr
);
2468 put_dt(dynamic
, DT_INIT_ARRAYSZ
, s
->data_offset
);
2470 s
= have_section(s1
, ".fini_array");
2471 if (s
&& s
->data_offset
) {
2472 put_dt(dynamic
, DT_FINI_ARRAY
, s
->sh_addr
);
2473 put_dt(dynamic
, DT_FINI_ARRAYSZ
, s
->data_offset
);
2475 s
= have_section(s1
, ".init");
2476 if (s
&& s
->data_offset
) {
2477 put_dt(dynamic
, DT_INIT
, s
->sh_addr
);
2479 s
= have_section(s1
, ".fini");
2480 if (s
&& s
->data_offset
) {
2481 put_dt(dynamic
, DT_FINI
, s
->sh_addr
);
2484 put_dt(dynamic
, DT_DEBUG
, 0);
2485 put_dt(dynamic
, DT_NULL
, 0);
2488 /* Remove gaps between RELX sections.
2489 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2490 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2491 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2492 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2493 static void update_reloc_sections(TCCState
*s1
, struct dyn_inf
*dyninf
)
2496 unsigned long file_offset
= 0;
2498 Section
*relocplt
= s1
->plt
? s1
->plt
->reloc
: NULL
;
2500 /* dynamic relocation table information, for .dynamic section */
2501 dyninf
->rel_addr
= dyninf
->rel_size
= 0;
2503 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2504 s
= s1
->sections
[i
];
2505 if (s
->sh_type
== SHT_RELX
&& s
!= relocplt
) {
2506 if (dyninf
->rel_size
== 0) {
2507 dyninf
->rel_addr
= s
->sh_addr
;
2508 file_offset
= s
->sh_offset
;
2511 s
->sh_addr
= dyninf
->rel_addr
+ dyninf
->rel_size
;
2512 s
->sh_offset
= file_offset
+ dyninf
->rel_size
;
2514 dyninf
->rel_size
+= s
->sh_size
;
2519 static int tidy_section_headers(TCCState
*s1
, int *sec_order
);
2520 #endif /* ndef ELF_OBJ_ONLY */
2522 /* Create an ELF file on disk.
2523 This function handle ELF specific layout requirements */
2524 static int tcc_output_elf(TCCState
*s1
, FILE *f
, int phnum
, ElfW(Phdr
) *phdr
,
2525 int file_offset
, int *sec_order
)
2527 int i
, shnum
, offset
, size
, file_type
;
2530 ElfW(Shdr
) shdr
, *sh
;
2532 file_type
= s1
->output_type
;
2533 shnum
= s1
->nb_sections
;
2535 memset(&ehdr
, 0, sizeof(ehdr
));
2538 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2539 ehdr
.e_phnum
= phnum
;
2540 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2541 #ifndef ELF_OBJ_ONLY
2542 shnum
= tidy_section_headers(s1
, sec_order
);
2547 file_offset
= (file_offset
+ 3) & -4;
2550 ehdr
.e_ident
[0] = ELFMAG0
;
2551 ehdr
.e_ident
[1] = ELFMAG1
;
2552 ehdr
.e_ident
[2] = ELFMAG2
;
2553 ehdr
.e_ident
[3] = ELFMAG3
;
2554 ehdr
.e_ident
[4] = ELFCLASSW
;
2555 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2556 ehdr
.e_ident
[6] = EV_CURRENT
;
2558 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2559 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2560 #elif defined TCC_TARGET_ARM && defined TCC_ARM_EABI
2561 ehdr
.e_flags
= EF_ARM_EABI_VER5
;
2562 ehdr
.e_flags
|= s1
->float_abi
== ARM_HARD_FLOAT
2563 ? EF_ARM_VFP_FLOAT
: EF_ARM_SOFT_FLOAT
;
2564 #elif defined TCC_TARGET_ARM
2565 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2566 #elif defined TCC_TARGET_RISCV64
2567 /* XXX should be configurable */
2568 ehdr
.e_flags
= EF_RISCV_FLOAT_ABI_DOUBLE
;
2571 if (file_type
== TCC_OUTPUT_OBJ
) {
2572 ehdr
.e_type
= ET_REL
;
2574 if (file_type
& TCC_OUTPUT_DYN
)
2575 ehdr
.e_type
= ET_DYN
;
2577 ehdr
.e_type
= ET_EXEC
;
2578 if (s1
->elf_entryname
)
2579 ehdr
.e_entry
= get_sym_addr(s1
, s1
->elf_entryname
, 1, 0);
2581 ehdr
.e_entry
= get_sym_addr(s1
, "_start", !!(file_type
& TCC_OUTPUT_EXE
), 0);
2582 if (ehdr
.e_entry
== (addr_t
)-1)
2583 ehdr
.e_entry
= text_section
->sh_addr
;
2588 ehdr
.e_machine
= EM_TCC_TARGET
;
2589 ehdr
.e_version
= EV_CURRENT
;
2590 ehdr
.e_shoff
= file_offset
;
2591 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2592 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2593 ehdr
.e_shnum
= shnum
;
2594 ehdr
.e_shstrndx
= shnum
- 1;
2596 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2598 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2599 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2601 sort_syms(s1
, symtab_section
);
2603 for(i
= 1; i
< shnum
; i
++) {
2604 s
= s1
->sections
[sec_order
? sec_order
[i
] : i
];
2605 if (s
->sh_type
!= SHT_NOBITS
) {
2606 while (offset
< s
->sh_offset
) {
2612 fwrite(s
->data
, 1, size
, f
);
2617 /* output section headers */
2618 while (offset
< ehdr
.e_shoff
) {
2623 for(i
= 0; i
< shnum
; i
++) {
2625 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2626 s
= s1
->sections
[i
];
2628 sh
->sh_name
= s
->sh_name
;
2629 sh
->sh_type
= s
->sh_type
;
2630 sh
->sh_flags
= s
->sh_flags
;
2631 sh
->sh_entsize
= s
->sh_entsize
;
2632 sh
->sh_info
= s
->sh_info
;
2634 sh
->sh_link
= s
->link
->sh_num
;
2635 sh
->sh_addralign
= s
->sh_addralign
;
2636 sh
->sh_addr
= s
->sh_addr
;
2637 sh
->sh_offset
= s
->sh_offset
;
2638 sh
->sh_size
= s
->sh_size
;
2640 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2645 static int tcc_output_binary(TCCState
*s1
, FILE *f
,
2646 const int *sec_order
)
2649 int i
, offset
, size
;
2652 for(i
=1;i
<s1
->nb_sections
;i
++) {
2653 s
= s1
->sections
[sec_order
[i
]];
2654 if (s
->sh_type
!= SHT_NOBITS
&&
2655 (s
->sh_flags
& SHF_ALLOC
)) {
2656 while (offset
< s
->sh_offset
) {
2661 fwrite(s
->data
, 1, size
, f
);
2668 /* Write an elf, coff or "binary" file */
2669 static int tcc_write_elf_file(TCCState
*s1
, const char *filename
, int phnum
,
2670 ElfW(Phdr
) *phdr
, int file_offset
, int *sec_order
)
2672 int fd
, mode
, file_type
, ret
;
2675 file_type
= s1
->output_type
;
2676 if (file_type
== TCC_OUTPUT_OBJ
)
2681 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2682 if (fd
< 0 || (f
= fdopen(fd
, "wb")) == NULL
)
2683 return tcc_error_noabort("could not write '%s: %s'", filename
, strerror(errno
));
2685 printf("<- %s\n", filename
);
2686 #ifdef TCC_TARGET_COFF
2687 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
)
2688 tcc_output_coff(s1
, f
);
2691 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2692 ret
= tcc_output_elf(s1
, f
, phnum
, phdr
, file_offset
, sec_order
);
2694 ret
= tcc_output_binary(s1
, f
, sec_order
);
2700 #ifndef ELF_OBJ_ONLY
2701 /* Sort section headers by assigned sh_addr, remove sections
2702 that we aren't going to output. */
2703 static int tidy_section_headers(TCCState
*s1
, int *sec_order
)
2705 int i
, nnew
, l
, *backmap
;
2709 snew
= tcc_malloc(s1
->nb_sections
* sizeof(snew
[0]));
2710 backmap
= tcc_malloc(s1
->nb_sections
* sizeof(backmap
[0]));
2711 for (i
= 0, nnew
= 0, l
= s1
->nb_sections
; i
< s1
->nb_sections
; i
++) {
2712 s
= s1
->sections
[sec_order
[i
]];
2713 if (!i
|| s
->sh_name
) {
2714 backmap
[sec_order
[i
]] = nnew
;
2718 backmap
[sec_order
[i
]] = 0;
2722 for (i
= 0; i
< nnew
; i
++) {
2726 if (s
->sh_type
== SHT_RELX
)
2727 s
->sh_info
= backmap
[s
->sh_info
];
2731 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
))
2732 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2733 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2734 if ( !s1
->static_link
) {
2735 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
))
2736 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2737 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2739 for (i
= 0; i
< s1
->nb_sections
; i
++)
2741 tcc_free(s1
->sections
);
2742 s1
->sections
= snew
;
2747 #ifdef TCC_TARGET_ARM
2748 static void create_arm_attribute_section(TCCState
*s1
)
2750 // Needed for DLL support.
2751 static const unsigned char arm_attr
[] = {
2753 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2754 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2755 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2756 0x05, 0x36, 0x00, // 'CPU_name', "6"
2757 0x06, 0x06, // 'CPU_arch', 'v6'
2758 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2759 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2760 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2761 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2762 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2763 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2764 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2765 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2766 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2767 0x1a, 0x02, // 'ABI_enum_size', 'int'
2768 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2769 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2771 Section
*attr
= new_section(s1
, ".ARM.attributes", SHT_ARM_ATTRIBUTES
, 0);
2772 unsigned char *ptr
= section_ptr_add(attr
, sizeof(arm_attr
));
2773 attr
->sh_addralign
= 1;
2774 memcpy(ptr
, arm_attr
, sizeof(arm_attr
));
2775 if (s1
->float_abi
!= ARM_HARD_FLOAT
) {
2776 ptr
[26] = 0x00; // 'FP_arch', 'No'
2777 ptr
[41] = 0x1e; // 'ABI_optimization_goals'
2778 ptr
[42] = 0x06; // 'Aggressive Debug'
2783 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2784 static Section
*create_bsd_note_section(TCCState
*s1
,
2788 Section
*s
= find_section (s1
, name
);
2790 if (s
->data_offset
== 0) {
2791 char *ptr
= section_ptr_add(s
, sizeof(ElfW(Nhdr
)) + 8 + 4);
2792 ElfW(Nhdr
) *note
= (ElfW(Nhdr
) *) ptr
;
2794 s
->sh_type
= SHT_NOTE
;
2797 note
->n_type
= ELF_NOTE_OS_GNU
;
2798 strcpy (ptr
+ sizeof(ElfW(Nhdr
)), value
);
2804 static void alloc_sec_names(TCCState
*s1
, int is_obj
);
2806 /* Output an elf, coff or binary file */
2807 /* XXX: suppress unneeded sections */
2808 static int elf_output_file(TCCState
*s1
, const char *filename
)
2810 int i
, ret
, file_type
, file_offset
, *sec_order
;
2811 struct dyn_inf dyninf
= {0};
2812 Section
*interp
, *dynstr
, *dynamic
;
2813 int textrel
, got_sym
, dt_flags_1
;
2815 file_type
= s1
->output_type
;
2818 interp
= dynstr
= dynamic
= NULL
;
2820 dyninf
.roinf
= &dyninf
._roinf
;
2822 #ifdef TCC_TARGET_ARM
2823 create_arm_attribute_section (s1
);
2826 #if TARGETOS_OpenBSD
2827 dyninf
.note
= create_bsd_note_section (s1
, ".note.openbsd.ident", "OpenBSD");
2831 dyninf
.note
= create_bsd_note_section (s1
, ".note.netbsd.ident", "NetBSD");
2834 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
2835 dyninf
.roinf
= NULL
;
2837 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2838 tcc_add_runtime(s1
);
2839 resolve_common_syms(s1
);
2841 if (!s1
->static_link
) {
2842 if (file_type
& TCC_OUTPUT_EXE
) {
2844 /* allow override the dynamic loader */
2845 const char *elfint
= getenv("LD_SO");
2847 elfint
= DEFAULT_ELFINTERP(s1
);
2848 /* add interpreter section only if executable */
2849 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
2850 interp
->sh_addralign
= 1;
2851 ptr
= section_ptr_add(interp
, 1 + strlen(elfint
));
2852 strcpy(ptr
, elfint
);
2853 dyninf
.interp
= interp
;
2856 /* add dynamic symbol table */
2857 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
2859 ".hash", SHF_ALLOC
);
2860 /* Number of local symbols (readelf complains if not set) */
2861 s1
->dynsym
->sh_info
= 1;
2862 dynstr
= s1
->dynsym
->link
;
2863 /* add dynamic section */
2864 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
2865 SHF_ALLOC
| SHF_WRITE
);
2866 dynamic
->link
= dynstr
;
2867 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
2869 got_sym
= build_got(s1
);
2870 if (file_type
& TCC_OUTPUT_EXE
) {
2871 bind_exe_dynsyms(s1
, file_type
& TCC_OUTPUT_DYN
);
2875 build_got_entries(s1
, got_sym
);
2876 if (file_type
& TCC_OUTPUT_EXE
) {
2877 bind_libs_dynsyms(s1
);
2879 /* shared library case: simply export all global symbols */
2880 export_global_syms(s1
);
2882 dyninf
.gnu_hash
= create_gnu_hash(s1
);
2884 build_got_entries(s1
, 0);
2888 textrel
= set_sec_sizes(s1
);
2889 alloc_sec_names(s1
, 0);
2891 if (!s1
->static_link
) {
2892 /* add a list of needed dlls */
2893 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2894 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
2895 if (dllref
->level
== 0)
2896 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
2900 put_dt(dynamic
, s1
->enable_new_dtags
? DT_RUNPATH
: DT_RPATH
,
2901 put_elf_str(dynstr
, s1
->rpath
));
2903 dt_flags_1
= DF_1_NOW
;
2904 if (file_type
& TCC_OUTPUT_DYN
) {
2906 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
2907 /* XXX: currently, since we do not handle PIC code, we
2908 must relocate the readonly segments */
2910 put_dt(dynamic
, DT_TEXTREL
, 0);
2911 if (file_type
& TCC_OUTPUT_EXE
)
2912 dt_flags_1
= DF_1_NOW
| DF_1_PIE
;
2914 put_dt(dynamic
, DT_FLAGS
, DF_BIND_NOW
);
2915 put_dt(dynamic
, DT_FLAGS_1
, dt_flags_1
);
2917 put_dt(dynamic
, DT_SYMBOLIC
, 0);
2919 dyninf
.dynamic
= dynamic
;
2920 dyninf
.dynstr
= dynstr
;
2921 /* remember offset and reserve space for 2nd call below */
2922 dyninf
.data_offset
= dynamic
->data_offset
;
2923 fill_dynamic(s1
, &dyninf
);
2924 dynamic
->sh_size
= dynamic
->data_offset
;
2925 dynstr
->sh_size
= dynstr
->data_offset
;
2928 /* this array is used to reorder sections in the output file */
2929 sec_order
= tcc_malloc(sizeof(int) * 2 * s1
->nb_sections
);
2930 /* compute section to program header mapping */
2931 file_offset
= layout_sections(s1
, sec_order
, &dyninf
);
2934 /* put in GOT the dynamic section address and relocate PLT */
2935 write32le(s1
->got
->data
, dynamic
->sh_addr
);
2936 if (file_type
== TCC_OUTPUT_EXE
2937 || (RELOCATE_DLLPLT
&& (file_type
& TCC_OUTPUT_DYN
)))
2939 /* relocate symbols in .dynsym now that final addresses are known */
2940 relocate_syms(s1
, s1
->dynsym
, 2);
2943 /* if building executable or DLL, then relocate each section
2944 except the GOT which is already relocated */
2945 relocate_syms(s1
, s1
->symtab
, 0);
2946 if (s1
->nb_errors
!= 0)
2948 relocate_sections(s1
);
2950 update_reloc_sections (s1
, &dyninf
);
2951 dynamic
->data_offset
= dyninf
.data_offset
;
2952 fill_dynamic(s1
, &dyninf
);
2954 /* Perform relocation to GOT or PLT entries */
2955 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2958 fill_local_got_entries(s1
);
2960 if (dyninf
.gnu_hash
)
2961 update_gnu_hash(s1
, dyninf
.gnu_hash
);
2963 /* Create the ELF file with name 'filename' */
2964 ret
= tcc_write_elf_file(s1
, filename
, dyninf
.phnum
, dyninf
.phdr
, file_offset
, sec_order
);
2966 tcc_free(sec_order
);
2967 tcc_free(dyninf
.phdr
);
2970 #endif /* ndef ELF_OBJ_ONLY */
2972 /* Allocate strings for section names */
2973 static void alloc_sec_names(TCCState
*s1
, int is_obj
)
2976 Section
*s
, *strsec
;
2978 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
2979 put_elf_str(strsec
, "");
2980 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2981 s
= s1
->sections
[i
];
2983 s
->sh_size
= s
->data_offset
;
2984 if (s
== strsec
|| s
->sh_size
|| (s
->sh_flags
& SHF_ALLOC
))
2985 s
->sh_name
= put_elf_str(strsec
, s
->name
);
2987 strsec
->sh_size
= strsec
->data_offset
;
2990 /* Output an elf .o file */
2991 static int elf_output_obj(TCCState
*s1
, const char *filename
)
2994 int i
, ret
, file_offset
;
2996 /* Allocate strings for section names */
2997 alloc_sec_names(s1
, 1);
2998 file_offset
= sizeof (ElfW(Ehdr
));
2999 for(i
= 1; i
< s1
->nb_sections
; i
++) {
3000 s
= s1
->sections
[i
];
3001 file_offset
= (file_offset
+ 15) & -16;
3002 s
->sh_offset
= file_offset
;
3003 if (s
->sh_type
!= SHT_NOBITS
)
3004 file_offset
+= s
->sh_size
;
3006 /* Create the ELF file with name 'filename' */
3007 ret
= tcc_write_elf_file(s1
, filename
, 0, NULL
, file_offset
, NULL
);
3011 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
3013 if (s
->test_coverage
)
3014 tcc_tcov_add_file(s
, filename
);
3015 if (s
->output_type
== TCC_OUTPUT_OBJ
)
3016 return elf_output_obj(s
, filename
);
3017 #ifdef TCC_TARGET_PE
3018 return pe_output_file(s
, filename
);
3019 #elif TCC_TARGET_MACHO
3020 return macho_output_file(s
, filename
);
3022 return elf_output_file(s
, filename
);
3026 ST_FUNC ssize_t
full_read(int fd
, void *buf
, size_t count
) {
3030 ssize_t num
= read(fd
, cbuf
, count
-rnum
);
3031 if (num
< 0) return num
;
3032 if (num
== 0) return rnum
;
3038 ST_FUNC
void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
3042 data
= tcc_malloc(size
);
3043 lseek(fd
, file_offset
, SEEK_SET
);
3044 full_read(fd
, data
, size
);
3048 typedef struct SectionMergeInfo
{
3049 Section
*s
; /* corresponding existing section */
3050 unsigned long offset
; /* offset of the new section in the existing section */
3051 uint8_t new_section
; /* true if section 's' was added */
3052 uint8_t link_once
; /* true if link once section */
3055 ST_FUNC
int tcc_object_type(int fd
, ElfW(Ehdr
) *h
)
3057 int size
= full_read(fd
, h
, sizeof *h
);
3058 if (size
== sizeof *h
&& 0 == memcmp(h
, ELFMAG
, 4)) {
3059 if (h
->e_type
== ET_REL
)
3060 return AFF_BINTYPE_REL
;
3061 if (h
->e_type
== ET_DYN
)
3062 return AFF_BINTYPE_DYN
;
3063 } else if (size
>= 8) {
3064 if (0 == memcmp(h
, ARMAG
, 8))
3065 return AFF_BINTYPE_AR
;
3066 #ifdef TCC_TARGET_COFF
3067 if (((struct filehdr
*)h
)->f_magic
== COFF_C67_MAGIC
)
3068 return AFF_BINTYPE_C67
;
3074 /* load an object file and merge it with current files */
3075 /* XXX: handle correctly stab (debug) info */
3076 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
3077 int fd
, unsigned long file_offset
)
3080 ElfW(Shdr
) *shdr
, *sh
;
3081 unsigned long size
, offset
, offseti
;
3082 int i
, j
, nb_syms
, sym_index
, ret
, seencompressed
;
3083 char *strsec
, *strtab
;
3084 int stab_index
, stabstr_index
;
3085 int *old_to_new_syms
;
3086 char *sh_name
, *name
;
3087 SectionMergeInfo
*sm_table
, *sm
;
3088 ElfW(Sym
) *sym
, *symtab
;
3092 lseek(fd
, file_offset
, SEEK_SET
);
3093 if (tcc_object_type(fd
, &ehdr
) != AFF_BINTYPE_REL
)
3095 /* test CPU specific stuff */
3096 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
3097 ehdr
.e_machine
!= EM_TCC_TARGET
) {
3099 return tcc_error_noabort("invalid object file");
3102 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
3103 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
3104 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
3106 /* load section names */
3107 sh
= &shdr
[ehdr
.e_shstrndx
];
3108 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
3110 /* load symtab and strtab */
3111 old_to_new_syms
= NULL
;
3116 stab_index
= stabstr_index
= 0;
3119 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3121 if (sh
->sh_type
== SHT_SYMTAB
) {
3123 tcc_error_noabort("object must contain only one symtab");
3126 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
3127 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
3128 sm_table
[i
].s
= symtab_section
;
3130 /* now load strtab */
3131 sh
= &shdr
[sh
->sh_link
];
3132 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
3134 if (sh
->sh_flags
& SHF_COMPRESSED
)
3138 /* now examine each section and try to merge its content with the
3140 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3141 /* no need to examine section name strtab */
3142 if (i
== ehdr
.e_shstrndx
)
3145 if (sh
->sh_type
== SHT_RELX
)
3146 sh
= &shdr
[sh
->sh_info
];
3147 /* ignore sections types we do not handle (plus relocs to those) */
3148 if (sh
->sh_type
!= SHT_PROGBITS
&&
3150 sh
->sh_type
!= SHT_ARM_EXIDX
&&
3152 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3153 sh
->sh_type
!= SHT_X86_64_UNWIND
&&
3155 sh
->sh_type
!= SHT_NOTE
&&
3156 sh
->sh_type
!= SHT_NOBITS
&&
3157 sh
->sh_type
!= SHT_PREINIT_ARRAY
&&
3158 sh
->sh_type
!= SHT_INIT_ARRAY
&&
3159 sh
->sh_type
!= SHT_FINI_ARRAY
&&
3160 strcmp(strsec
+ sh
->sh_name
, ".stabstr")
3163 if (seencompressed
&& 0 == strncmp(strsec
+ sh
->sh_name
, ".debug_", 7))
3167 sh_name
= strsec
+ sh
->sh_name
;
3168 if (sh
->sh_addralign
< 1)
3169 sh
->sh_addralign
= 1;
3170 /* find corresponding section, if any */
3171 for(j
= 1; j
< s1
->nb_sections
;j
++) {
3172 s
= s1
->sections
[j
];
3173 if (!strcmp(s
->name
, sh_name
)) {
3174 if (!strncmp(sh_name
, ".gnu.linkonce",
3175 sizeof(".gnu.linkonce") - 1)) {
3176 /* if a 'linkonce' section is already present, we
3177 do not add it again. It is a little tricky as
3178 symbols can still be defined in
3180 sm_table
[i
].link_once
= 1;
3184 if (s
== stab_section
)
3186 if (s
== stab_section
->link
)
3192 /* not found: create new section */
3193 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
& ~SHF_GROUP
);
3194 /* take as much info as possible from the section. sh_link and
3195 sh_info will be updated later */
3196 s
->sh_addralign
= sh
->sh_addralign
;
3197 s
->sh_entsize
= sh
->sh_entsize
;
3198 sm_table
[i
].new_section
= 1;
3200 if (sh
->sh_type
!= s
->sh_type
3201 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3202 && strcmp (s
->name
, ".eh_frame")
3205 tcc_error_noabort("invalid section type");
3208 /* align start of section */
3209 s
->data_offset
+= -s
->data_offset
& (sh
->sh_addralign
- 1);
3210 if (sh
->sh_addralign
> s
->sh_addralign
)
3211 s
->sh_addralign
= sh
->sh_addralign
;
3212 sm_table
[i
].offset
= s
->data_offset
;
3214 /* concatenate sections */
3216 if (sh
->sh_type
!= SHT_NOBITS
) {
3218 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
3219 ptr
= section_ptr_add(s
, size
);
3220 full_read(fd
, ptr
, size
);
3222 s
->data_offset
+= size
;
3227 /* gr relocate stab strings */
3228 if (stab_index
&& stabstr_index
) {
3231 s
= sm_table
[stab_index
].s
;
3232 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
3233 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
3234 o
= sm_table
[stabstr_index
].offset
;
3242 /* second short pass to update sh_link and sh_info fields of new
3244 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3246 if (!s
|| !sm_table
[i
].new_section
)
3249 if (sh
->sh_link
> 0)
3250 s
->link
= sm_table
[sh
->sh_link
].s
;
3251 if (sh
->sh_type
== SHT_RELX
) {
3252 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
3253 /* update backward link */
3254 s1
->sections
[s
->sh_info
]->reloc
= s
;
3258 /* resolve symbols */
3259 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
3262 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
3263 if (sym
->st_shndx
!= SHN_UNDEF
&&
3264 sym
->st_shndx
< SHN_LORESERVE
) {
3265 sm
= &sm_table
[sym
->st_shndx
];
3266 if (sm
->link_once
) {
3267 /* if a symbol is in a link once section, we use the
3268 already defined symbol. It is very important to get
3269 correct relocations */
3270 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
3271 name
= strtab
+ sym
->st_name
;
3272 sym_index
= find_elf_sym(symtab_section
, name
);
3274 old_to_new_syms
[i
] = sym_index
;
3278 /* if no corresponding section added, no need to add symbol */
3281 /* convert section number */
3282 sym
->st_shndx
= sm
->s
->sh_num
;
3284 sym
->st_value
+= sm
->offset
;
3287 name
= strtab
+ sym
->st_name
;
3288 sym_index
= set_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
3289 sym
->st_info
, sym
->st_other
,
3290 sym
->st_shndx
, name
);
3291 old_to_new_syms
[i
] = sym_index
;
3294 /* third pass to patch relocation entries */
3295 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3300 offset
= sm_table
[i
].offset
;
3302 switch(s
->sh_type
) {
3304 /* take relocation offset information */
3305 offseti
= sm_table
[sh
->sh_info
].offset
;
3306 for (rel
= (ElfW_Rel
*) s
->data
+ (offset
/ sizeof(*rel
));
3307 rel
< (ElfW_Rel
*) s
->data
+ ((offset
+ size
) / sizeof(*rel
));
3311 /* convert symbol index */
3312 type
= ELFW(R_TYPE
)(rel
->r_info
);
3313 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
3314 /* NOTE: only one symtab assumed */
3315 if (sym_index
>= nb_syms
)
3317 sym_index
= old_to_new_syms
[sym_index
];
3318 /* ignore link_once in rel section. */
3319 if (!sym_index
&& !sm_table
[sh
->sh_info
].link_once
3320 #ifdef TCC_TARGET_ARM
3321 && type
!= R_ARM_V4BX
3322 #elif defined TCC_TARGET_RISCV64
3323 && type
!= R_RISCV_ALIGN
3324 && type
!= R_RISCV_RELAX
3328 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3329 i
, strsec
+ sh
->sh_name
, (int)rel
->r_offset
);
3332 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
3333 /* offset the relocation offset */
3334 rel
->r_offset
+= offseti
;
3335 #ifdef TCC_TARGET_ARM
3336 /* Jumps and branches from a Thumb code to a PLT entry need
3337 special handling since PLT entries are ARM code.
3338 Unconditional bl instructions referencing PLT entries are
3339 handled by converting these instructions into blx
3340 instructions. Other case of instructions referencing a PLT
3341 entry require to add a Thumb stub before the PLT entry to
3342 switch to ARM mode. We set bit plt_thumb_stub of the
3343 attribute of a symbol to indicate such a case. */
3344 if (type
== R_ARM_THM_JUMP24
)
3345 get_sym_attr(s1
, sym_index
, 1)->plt_thumb_stub
= 1;
3358 tcc_free(old_to_new_syms
);
3365 typedef struct ArchiveHeader
{
3366 char ar_name
[16]; /* name of this member */
3367 char ar_date
[12]; /* file mtime */
3368 char ar_uid
[6]; /* owner uid; printed as decimal */
3369 char ar_gid
[6]; /* owner gid; printed as decimal */
3370 char ar_mode
[8]; /* file mode, printed as octal */
3371 char ar_size
[10]; /* file size, printed as decimal */
3372 char ar_fmag
[2]; /* should contain ARFMAG */
3375 #define ARFMAG "`\n"
3377 static unsigned long long get_be(const uint8_t *b
, int n
)
3379 unsigned long long ret
= 0;
3381 ret
= (ret
<< 8) | *b
++, --n
;
3385 static int read_ar_header(int fd
, int offset
, ArchiveHeader
*hdr
)
3389 lseek(fd
, offset
, SEEK_SET
);
3390 len
= full_read(fd
, hdr
, sizeof(ArchiveHeader
));
3391 if (len
!= sizeof(ArchiveHeader
))
3392 return len
? -1 : 0;
3394 for (e
= p
+ sizeof hdr
->ar_name
; e
> p
&& e
[-1] == ' ';)
3397 hdr
->ar_size
[sizeof hdr
->ar_size
-1] = 0;
3401 /* load only the objects which resolve undefined symbols */
3402 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
, int entrysize
)
3404 int i
, bound
, nsyms
, sym_index
, len
, ret
= -1;
3405 unsigned long long off
;
3407 const char *ar_names
, *p
;
3408 const uint8_t *ar_index
;
3412 data
= tcc_malloc(size
);
3413 if (full_read(fd
, data
, size
) != size
)
3415 nsyms
= get_be(data
, entrysize
);
3416 ar_index
= data
+ entrysize
;
3417 ar_names
= (char *) ar_index
+ nsyms
* entrysize
;
3421 for (p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
3422 Section
*s
= symtab_section
;
3423 sym_index
= find_elf_sym(s
, p
);
3426 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
3427 if(sym
->st_shndx
!= SHN_UNDEF
)
3429 off
= get_be(ar_index
+ i
* entrysize
, entrysize
);
3430 len
= read_ar_header(fd
, off
, &hdr
);
3431 if (len
<= 0 || memcmp(hdr
.ar_fmag
, ARFMAG
, 2)) {
3432 tcc_error_noabort("invalid archive");
3436 if (s1
->verbose
== 2)
3437 printf(" -> %s\n", hdr
.ar_name
);
3438 if (tcc_load_object_file(s1
, fd
, off
) < 0)
3449 /* load a '.a' file */
3450 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
, int alacarte
)
3453 /* char magic[8]; */
3455 unsigned long file_offset
;
3458 /* skip magic which was already checked */
3459 /* full_read(fd, magic, sizeof(magic)); */
3460 file_offset
= sizeof ARMAG
- 1;
3463 len
= read_ar_header(fd
, file_offset
, &hdr
);
3467 return tcc_error_noabort("invalid archive");
3469 size
= strtol(hdr
.ar_size
, NULL
, 0);
3471 size
= (size
+ 1) & ~1;
3473 /* coff symbol table : we handle it */
3474 if (!strcmp(hdr
.ar_name
, "/"))
3475 return tcc_load_alacarte(s1
, fd
, size
, 4);
3476 if (!strcmp(hdr
.ar_name
, "/SYM64/"))
3477 return tcc_load_alacarte(s1
, fd
, size
, 8);
3478 } else if (tcc_object_type(fd
, &ehdr
) == AFF_BINTYPE_REL
) {
3479 if (s1
->verbose
== 2)
3480 printf(" -> %s\n", hdr
.ar_name
);
3481 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
3484 file_offset
+= size
;
3488 #ifndef ELF_OBJ_ONLY
3489 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3490 LV, maybe create a new entry for (LIB,VERSION). */
3491 static void set_ver_to_ver(TCCState
*s1
, int *n
, int **lv
, int i
, char *lib
, char *version
)
3494 *lv
= tcc_realloc(*lv
, (*n
+ 1) * sizeof(**lv
));
3497 if ((*lv
)[i
] == -1) {
3498 int v
, prev_same_lib
= -1;
3499 for (v
= 0; v
< nb_sym_versions
; v
++) {
3500 if (strcmp(sym_versions
[v
].lib
, lib
))
3503 if (!strcmp(sym_versions
[v
].version
, version
))
3506 if (v
== nb_sym_versions
) {
3507 sym_versions
= tcc_realloc (sym_versions
,
3508 (v
+ 1) * sizeof(*sym_versions
));
3509 sym_versions
[v
].lib
= tcc_strdup(lib
);
3510 sym_versions
[v
].version
= tcc_strdup(version
);
3511 sym_versions
[v
].out_index
= 0;
3512 sym_versions
[v
].prev_same_lib
= prev_same_lib
;
3519 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3522 set_sym_version(TCCState
*s1
, int sym_index
, int verndx
)
3524 if (sym_index
>= nb_sym_to_version
) {
3525 int newelems
= sym_index
? sym_index
* 2 : 1;
3526 sym_to_version
= tcc_realloc(sym_to_version
,
3527 newelems
* sizeof(*sym_to_version
));
3528 memset(sym_to_version
+ nb_sym_to_version
, -1,
3529 (newelems
- nb_sym_to_version
) * sizeof(*sym_to_version
));
3530 nb_sym_to_version
= newelems
;
3532 if (sym_to_version
[sym_index
] < 0)
3533 sym_to_version
[sym_index
] = verndx
;
3536 struct versym_info
{
3538 ElfW(Verdef
) *verdef
;
3539 ElfW(Verneed
) *verneed
;
3541 int nb_local_ver
, *local_ver
;
3545 static void store_version(TCCState
*s1
, struct versym_info
*v
, char *dynstr
)
3547 char *lib
, *version
;
3551 #define DEBUG_VERSION 0
3553 if (v
->versym
&& v
->verdef
) {
3554 ElfW(Verdef
) *vdef
= v
->verdef
;
3557 ElfW(Verdaux
) *verdaux
=
3558 (ElfW(Verdaux
) *) (((char *) vdef
) + vdef
->vd_aux
);
3561 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3562 vdef
->vd_version
, vdef
->vd_flags
, vdef
->vd_ndx
,
3566 version
= dynstr
+ verdaux
->vda_name
;
3571 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vdef
->vd_ndx
,
3574 printf (" verdaux(%u): %s\n", vdef
->vd_ndx
, version
);
3577 next
= vdef
->vd_next
;
3578 vdef
= (ElfW(Verdef
) *) (((char *) vdef
) + next
);
3581 if (v
->versym
&& v
->verneed
) {
3582 ElfW(Verneed
) *vneed
= v
->verneed
;
3584 ElfW(Vernaux
) *vernaux
=
3585 (ElfW(Vernaux
) *) (((char *) vneed
) + vneed
->vn_aux
);
3587 lib
= dynstr
+ vneed
->vn_file
;
3589 printf ("verneed: %u %s\n", vneed
->vn_version
, lib
);
3591 for (i
= 0; i
< vneed
->vn_cnt
; i
++) {
3592 if ((vernaux
->vna_other
& 0x8000) == 0) { /* hidden */
3593 version
= dynstr
+ vernaux
->vna_name
;
3594 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vernaux
->vna_other
,
3597 printf (" vernaux(%u): %u %u %s\n",
3598 vernaux
->vna_other
, vernaux
->vna_hash
,
3599 vernaux
->vna_flags
, version
);
3602 vernaux
= (ElfW(Vernaux
) *) (((char *) vernaux
) + vernaux
->vna_next
);
3604 next
= vneed
->vn_next
;
3605 vneed
= (ElfW(Verneed
) *) (((char *) vneed
) + next
);
3610 for (i
= 0; i
< v
->nb_local_ver
; i
++) {
3611 if (v
->local_ver
[i
] > 0) {
3612 printf ("%d: lib: %s, version %s\n",
3613 i
, sym_versions
[v
->local_ver
[i
]].lib
,
3614 sym_versions
[v
->local_ver
[i
]].version
);
3620 /* load a library / DLL
3621 'level = 0' means that the DLL is referenced by the user
3622 (so it should be added as DT_NEEDED in the generated ELF file) */
3623 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
3626 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
3627 int i
, nb_syms
, nb_dts
, sym_bind
, ret
= -1;
3628 ElfW(Sym
) *sym
, *dynsym
;
3629 ElfW(Dyn
) *dt
, *dynamic
;
3633 const char *name
, *soname
;
3634 struct versym_info v
;
3636 full_read(fd
, &ehdr
, sizeof(ehdr
));
3638 /* test CPU specific stuff */
3639 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
3640 ehdr
.e_machine
!= EM_TCC_TARGET
) {
3641 return tcc_error_noabort("bad architecture");
3645 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
3647 /* load dynamic section and dynamic symbols */
3651 dynsym
= NULL
; /* avoid warning */
3652 dynstr
= NULL
; /* avoid warning */
3653 memset(&v
, 0, sizeof v
);
3655 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
3656 switch(sh
->sh_type
) {
3658 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
3659 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3662 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
3663 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3664 sh1
= &shdr
[sh
->sh_link
];
3665 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
3667 case SHT_GNU_verdef
:
3668 v
.verdef
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3670 case SHT_GNU_verneed
:
3671 v
.verneed
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3673 case SHT_GNU_versym
:
3674 v
.nb_versyms
= sh
->sh_size
/ sizeof(ElfW(Half
));
3675 v
.versym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3685 /* compute the real library name */
3686 soname
= tcc_basename(filename
);
3687 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++)
3688 if (dt
->d_tag
== DT_SONAME
)
3689 soname
= dynstr
+ dt
->d_un
.d_val
;
3691 /* if the dll is already loaded, do not load it */
3692 if (tcc_add_dllref(s1
, soname
, level
)->found
)
3695 if (v
.nb_versyms
!= nb_syms
)
3696 tcc_free (v
.versym
), v
.versym
= NULL
;
3698 store_version(s1
, &v
, dynstr
);
3700 /* add dynamic symbols in dynsym_section */
3701 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
3702 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
3703 if (sym_bind
== STB_LOCAL
)
3705 name
= dynstr
+ sym
->st_name
;
3706 sym_index
= set_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
3707 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
3709 ElfW(Half
) vsym
= v
.versym
[i
];
3710 if ((vsym
& 0x8000) == 0 && vsym
> 0 && vsym
< v
.nb_local_ver
)
3711 set_sym_version(s1
, sym_index
, v
.local_ver
[vsym
]);
3715 /* do not load all referenced libraries
3716 (recursive loading can break linking of libraries) */
3717 /* following DT_NEEDED is needed for the dynamic loader (libdl.so),
3718 but it is no longer needed, when linking a library or a program.
3719 When tcc output mode is OUTPUT_MEM,
3720 tcc calls dlopen, which handles DT_NEEDED for us */
3723 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++)
3724 if (dt
->d_tag
== DT_RPATH
)
3725 tcc_add_library_path(s1
, dynstr
+ dt
->d_un
.d_val
);
3727 /* load all referenced DLLs */
3728 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3731 name
= dynstr
+ dt
->d_un
.d_val
;
3732 if (tcc_add_dllref(s1
, name
, -1))
3734 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
3735 ret
= tcc_error_noabort("referenced dll '%s' not found", name
);
3749 tcc_free(v
.local_ver
);
3751 tcc_free(v
.verneed
);
3756 #define LD_TOK_NAME 256
3757 #define LD_TOK_EOF (-1)
3759 static int ld_inp(TCCState
*s1
)
3767 if (1 == read(s1
->fd
, &b
, 1))
3772 /* return next ld script token */
3773 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
3790 if (ch
== '*') { /* comment */
3791 for (d
= 0;; d
= ch
) {
3793 if (ch
== CH_EOF
|| (ch
== '/' && d
== '*'))
3804 /* case 'a' ... 'z': */
3831 /* case 'A' ... 'z': */
3865 if (!((ch
>= 'a' && ch
<= 'z') ||
3866 (ch
>= 'A' && ch
<= 'Z') ||
3867 (ch
>= '0' && ch
<= '9') ||
3868 strchr("/.-_+=$:\\,~", ch
)))
3870 if ((q
- name
) < name_size
- 1) {
3889 static int ld_add_file(TCCState
*s1
, const char filename
[])
3891 if (filename
[0] == '/') {
3892 if (CONFIG_SYSROOT
[0] == '\0'
3893 && tcc_add_file_internal(s1
, filename
, AFF_TYPE_BIN
) == 0)
3895 filename
= tcc_basename(filename
);
3897 return tcc_add_dll(s1
, filename
, AFF_PRINT_ERROR
);
3900 static int ld_add_file_list(TCCState
*s1
, const char *cmd
, int as_needed
)
3902 char filename
[1024], libname
[1024];
3903 int t
, group
, nblibs
= 0, ret
= 0;
3906 group
= !strcmp(cmd
, "GROUP");
3908 s1
->new_undef_sym
= 0;
3909 t
= ld_next(s1
, filename
, sizeof(filename
));
3911 ret
= tcc_error_noabort("( expected");
3912 goto lib_parse_error
;
3914 t
= ld_next(s1
, filename
, sizeof(filename
));
3917 if (t
== LD_TOK_EOF
) {
3918 ret
= tcc_error_noabort("unexpected end of file");
3919 goto lib_parse_error
;
3920 } else if (t
== ')') {
3922 } else if (t
== '-') {
3923 t
= ld_next(s1
, filename
, sizeof(filename
));
3924 if ((t
!= LD_TOK_NAME
) || (filename
[0] != 'l')) {
3925 ret
= tcc_error_noabort("library name expected");
3926 goto lib_parse_error
;
3928 pstrcpy(libname
, sizeof libname
, &filename
[1]);
3929 if (s1
->static_link
) {
3930 snprintf(filename
, sizeof filename
, "lib%s.a", libname
);
3932 snprintf(filename
, sizeof filename
, "lib%s.so", libname
);
3934 } else if (t
!= LD_TOK_NAME
) {
3935 ret
= tcc_error_noabort("filename expected");
3936 goto lib_parse_error
;
3938 if (!strcmp(filename
, "AS_NEEDED")) {
3939 ret
= ld_add_file_list(s1
, cmd
, 1);
3941 goto lib_parse_error
;
3943 /* TODO: Implement AS_NEEDED support. */
3944 /* DT_NEEDED is not used any more so ignore as_needed */
3945 if (1 || !as_needed
) {
3946 ret
= ld_add_file(s1
, filename
);
3948 goto lib_parse_error
;
3950 /* Add the filename *and* the libname to avoid future conversions */
3951 dynarray_add(&libs
, &nblibs
, tcc_strdup(filename
));
3952 if (libname
[0] != '\0')
3953 dynarray_add(&libs
, &nblibs
, tcc_strdup(libname
));
3957 t
= ld_next(s1
, filename
, sizeof(filename
));
3959 t
= ld_next(s1
, filename
, sizeof(filename
));
3962 if (group
&& !as_needed
) {
3963 while (s1
->new_undef_sym
) {
3965 s1
->new_undef_sym
= 0;
3966 for (i
= 0; i
< nblibs
; i
++)
3967 ld_add_file(s1
, libs
[i
]);
3971 dynarray_reset(&libs
, &nblibs
);
3975 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3977 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
, int fd
)
3980 char filename
[1024];
3986 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3987 if (t
== LD_TOK_EOF
)
3989 else if (t
!= LD_TOK_NAME
)
3991 if (!strcmp(cmd
, "INPUT") ||
3992 !strcmp(cmd
, "GROUP")) {
3993 ret
= ld_add_file_list(s1
, cmd
, 0);
3996 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
3997 !strcmp(cmd
, "TARGET")) {
3998 /* ignore some commands */
3999 t
= ld_next(s1
, cmd
, sizeof(cmd
));
4001 return tcc_error_noabort("( expected");
4003 t
= ld_next(s1
, filename
, sizeof(filename
));
4004 if (t
== LD_TOK_EOF
) {
4005 return tcc_error_noabort("unexpected end of file");
4006 } else if (t
== ')') {
4016 #endif /* !ELF_OBJ_ONLY */