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
50 /* ------------------------------------------------------------------------- */
52 ST_FUNC
void tccelf_new(TCCState
*s
)
56 dynarray_add(&s
->sections
, &s
->nb_sections
, NULL
);
58 /* create standard sections */
59 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
60 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
62 rodata_section
= new_section(s
, ".rdata", SHT_PROGBITS
, SHF_ALLOC
);
64 /* create ro data section (make ro after relocation done with GNU_RELRO) */
65 rodata_section
= new_section(s
, ".data.ro", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
67 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
68 common_section
= new_section(s
, ".common", SHT_NOBITS
, SHF_PRIVATE
);
69 common_section
->sh_num
= SHN_COMMON
;
71 /* symbols are always generated for linking stage */
72 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
74 ".hashtab", SHF_PRIVATE
);
75 s
->symtab
= symtab_section
;
77 /* private symbol table for dynamic symbols */
78 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
|SHF_DYNSYM
,
80 ".dynhashtab", SHF_PRIVATE
);
81 get_sym_attr(s
, 0, 1);
84 #ifdef CONFIG_TCC_BCHECK
85 ST_FUNC
void tccelf_bounds_new(TCCState
*s
)
88 /* create bounds sections (make ro after relocation done with GNU_RELRO) */
89 bounds_section
= new_section(s
, ".bounds",
90 SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
91 lbounds_section
= new_section(s
, ".lbounds",
92 SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
96 ST_FUNC
void tccelf_stab_new(TCCState
*s
)
100 #ifdef CONFIG_TCC_BACKTRACE
101 /* include stab info with standalone backtrace support */
102 if (s
->do_backtrace
&& s
->output_type
!= TCC_OUTPUT_MEMORY
)
103 shf
= SHF_ALLOC
| SHF_WRITE
; // SHF_WRITE needed for musl/SELINUX
105 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, shf
);
106 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
107 stab_section
->sh_addralign
= sizeof ((Stab_Sym
*)0)->n_value
;
108 stab_section
->link
= new_section(s
, ".stabstr", SHT_STRTAB
, shf
);
109 /* put first entry */
110 put_stabs(s
, "", 0, 0, 0, 0);
113 static void free_section(Section
*s
)
118 ST_FUNC
void tccelf_delete(TCCState
*s1
)
123 /* free symbol versions */
124 for (i
= 0; i
< nb_sym_versions
; i
++) {
125 tcc_free(sym_versions
[i
].version
);
126 tcc_free(sym_versions
[i
].lib
);
128 tcc_free(sym_versions
);
129 tcc_free(sym_to_version
);
132 /* free all sections */
133 for(i
= 1; i
< s1
->nb_sections
; i
++)
134 free_section(s1
->sections
[i
]);
135 dynarray_reset(&s1
->sections
, &s1
->nb_sections
);
137 for(i
= 0; i
< s1
->nb_priv_sections
; i
++)
138 free_section(s1
->priv_sections
[i
]);
139 dynarray_reset(&s1
->priv_sections
, &s1
->nb_priv_sections
);
141 /* free any loaded DLLs */
143 for ( i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
144 DLLReference
*ref
= s1
->loaded_dlls
[i
];
147 FreeLibrary((HMODULE
)ref
->handle
);
149 dlclose(ref
->handle
);
153 /* free loaded dlls array */
154 dynarray_reset(&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
);
155 tcc_free(s1
->sym_attrs
);
157 symtab_section
= NULL
; /* for tccrun.c:rt_printline() */
160 /* save section data state */
161 ST_FUNC
void tccelf_begin_file(TCCState
*s1
)
164 for (i
= 1; i
< s1
->nb_sections
; i
++) {
166 s
->sh_offset
= s
->data_offset
;
168 /* disable symbol hashing during compilation */
169 s
= s1
->symtab
, s
->reloc
= s
->hash
, s
->hash
= NULL
;
170 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
175 /* At the end of compilation, convert any UNDEF syms to global, and merge
176 with previously existing symbols */
177 ST_FUNC
void tccelf_end_file(TCCState
*s1
)
179 Section
*s
= s1
->symtab
;
180 int first_sym
, nb_syms
, *tr
, i
;
182 first_sym
= s
->sh_offset
/ sizeof (ElfSym
);
183 nb_syms
= s
->data_offset
/ sizeof (ElfSym
) - first_sym
;
184 s
->data_offset
= s
->sh_offset
;
185 s
->link
->data_offset
= s
->link
->sh_offset
;
186 s
->hash
= s
->reloc
, s
->reloc
= NULL
;
187 tr
= tcc_mallocz(nb_syms
* sizeof *tr
);
189 for (i
= 0; i
< nb_syms
; ++i
) {
190 ElfSym
*sym
= (ElfSym
*)s
->data
+ first_sym
+ i
;
191 if (sym
->st_shndx
== SHN_UNDEF
192 && ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
)
193 sym
->st_info
= ELFW(ST_INFO
)(STB_GLOBAL
, ELFW(ST_TYPE
)(sym
->st_info
));
194 tr
[i
] = set_elf_sym(s
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
195 sym
->st_other
, sym
->st_shndx
, (char*)s
->link
->data
+ sym
->st_name
);
197 /* now update relocations */
198 for (i
= 1; i
< s1
->nb_sections
; i
++) {
199 Section
*sr
= s1
->sections
[i
];
200 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
201 ElfW_Rel
*rel
= (ElfW_Rel
*)(sr
->data
+ sr
->sh_offset
);
202 ElfW_Rel
*rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
203 for (; rel
< rel_end
; ++rel
) {
204 int n
= ELFW(R_SYM
)(rel
->r_info
) - first_sym
;
205 //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
206 rel
->r_info
= ELFW(R_INFO
)(tr
[n
], ELFW(R_TYPE
)(rel
->r_info
));
212 /* record text/data/bss output for -bench info */
213 for (i
= 0; i
< 4; ++i
) {
214 s
= s1
->sections
[i
+ 1];
215 s1
->total_output
[i
] += s
->data_offset
- s
->sh_offset
;
219 ST_FUNC Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
223 sec
= tcc_mallocz(sizeof(Section
) + strlen(name
));
225 strcpy(sec
->name
, name
);
226 sec
->sh_type
= sh_type
;
227 sec
->sh_flags
= sh_flags
;
230 sec
->sh_addralign
= 2;
238 case SHT_GNU_verneed
:
240 sec
->sh_addralign
= PTR_SIZE
;
243 sec
->sh_addralign
= 1;
246 sec
->sh_addralign
= PTR_SIZE
; /* gcc/pcc default alignment */
250 if (sh_flags
& SHF_PRIVATE
) {
251 dynarray_add(&s1
->priv_sections
, &s1
->nb_priv_sections
, sec
);
253 sec
->sh_num
= s1
->nb_sections
;
254 dynarray_add(&s1
->sections
, &s1
->nb_sections
, sec
);
260 ST_FUNC Section
*new_symtab(TCCState
*s1
,
261 const char *symtab_name
, int sh_type
, int sh_flags
,
262 const char *strtab_name
,
263 const char *hash_name
, int hash_sh_flags
)
265 Section
*symtab
, *strtab
, *hash
;
266 int *ptr
, nb_buckets
;
268 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
269 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
270 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
271 put_elf_str(strtab
, "");
272 symtab
->link
= strtab
;
273 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
277 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
278 hash
->sh_entsize
= sizeof(int);
282 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
285 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
289 /* realloc section and set its content to zero */
290 ST_FUNC
void section_realloc(Section
*sec
, unsigned long new_size
)
295 size
= sec
->data_allocated
;
298 while (size
< new_size
)
300 data
= tcc_realloc(sec
->data
, size
);
301 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
303 sec
->data_allocated
= size
;
306 /* reserve at least 'size' bytes aligned per 'align' in section
307 'sec' from current offset, and return the aligned offset */
308 ST_FUNC
size_t section_add(Section
*sec
, addr_t size
, int align
)
310 size_t offset
, offset1
;
312 offset
= (sec
->data_offset
+ align
- 1) & -align
;
313 offset1
= offset
+ size
;
314 if (sec
->sh_type
!= SHT_NOBITS
&& offset1
> sec
->data_allocated
)
315 section_realloc(sec
, offset1
);
316 sec
->data_offset
= offset1
;
317 if (align
> sec
->sh_addralign
)
318 sec
->sh_addralign
= align
;
322 /* reserve at least 'size' bytes in section 'sec' from
324 ST_FUNC
void *section_ptr_add(Section
*sec
, addr_t size
)
326 size_t offset
= section_add(sec
, size
, 1);
327 return sec
->data
+ offset
;
331 /* reserve at least 'size' bytes from section start */
332 static void section_reserve(Section
*sec
, unsigned long size
)
334 if (size
> sec
->data_allocated
)
335 section_realloc(sec
, size
);
336 if (size
> sec
->data_offset
)
337 sec
->data_offset
= size
;
341 static Section
*find_section_create (TCCState
*s1
, const char *name
, int create
)
345 for(i
= 1; i
< s1
->nb_sections
; i
++) {
346 sec
= s1
->sections
[i
];
347 if (!strcmp(name
, sec
->name
))
350 /* sections are created as PROGBITS */
351 return create
? new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
) : NULL
;
354 /* return a reference to a section, and create it if it does not
356 ST_FUNC Section
*find_section(TCCState
*s1
, const char *name
)
358 return find_section_create (s1
, name
, 1);
361 /* ------------------------------------------------------------------------- */
363 ST_FUNC
int put_elf_str(Section
*s
, const char *sym
)
368 len
= strlen(sym
) + 1;
369 offset
= s
->data_offset
;
370 ptr
= section_ptr_add(s
, len
);
371 memmove(ptr
, sym
, len
);
375 /* elf symbol hashing function */
376 static unsigned long elf_hash(const unsigned char *name
)
378 unsigned long h
= 0, g
;
381 h
= (h
<< 4) + *name
++;
390 /* rebuild hash table of section s */
391 /* NOTE: we do factorize the hash table code to go faster */
392 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
395 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
396 unsigned char *strtab
;
398 strtab
= s
->link
->data
;
399 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
402 nb_buckets
= ((int*)s
->hash
->data
)[0];
404 s
->hash
->data_offset
= 0;
405 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
410 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
411 ptr
+= nb_buckets
+ 1;
413 sym
= (ElfW(Sym
) *)s
->data
+ 1;
414 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
415 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
416 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
427 /* return the symbol number */
428 ST_FUNC
int put_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
429 int info
, int other
, int shndx
, const char *name
)
431 int name_offset
, sym_index
;
436 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
438 name_offset
= put_elf_str(s
->link
, name
);
441 /* XXX: endianness */
442 sym
->st_name
= name_offset
;
443 sym
->st_value
= value
;
446 sym
->st_other
= other
;
447 sym
->st_shndx
= shndx
;
448 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
452 ptr
= section_ptr_add(hs
, sizeof(int));
453 base
= (int *)hs
->data
;
454 /* only add global or weak symbols. */
455 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
456 /* add another hashing entry */
458 h
= elf_hash((unsigned char *)s
->link
->data
+ name_offset
) % nbuckets
;
460 base
[2 + h
] = sym_index
;
462 /* we resize the hash table */
463 hs
->nb_hashed_syms
++;
464 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
465 rebuild_hash(s
, 2 * nbuckets
);
475 ST_FUNC
int find_elf_sym(Section
*s
, const char *name
)
479 int nbuckets
, sym_index
, h
;
485 nbuckets
= ((int *)hs
->data
)[0];
486 h
= elf_hash((unsigned char *) name
) % nbuckets
;
487 sym_index
= ((int *)hs
->data
)[2 + h
];
488 while (sym_index
!= 0) {
489 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
490 name1
= (char *) s
->link
->data
+ sym
->st_name
;
491 if (!strcmp(name
, name1
))
493 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
498 /* return elf symbol value, signal error if 'err' is nonzero, decorate
500 ST_FUNC addr_t
get_sym_addr(TCCState
*s1
, const char *name
, int err
, int forc
)
505 if (forc
&& s1
->leading_underscore
507 /* win32-32bit stdcall symbols always have _ already */
508 && !strchr(name
, '@')
512 pstrcpy(buf
+ 1, sizeof(buf
) - 1, name
);
515 sym_index
= find_elf_sym(s1
->symtab
, name
);
516 sym
= &((ElfW(Sym
) *)s1
->symtab
->data
)[sym_index
];
517 if (!sym_index
|| sym
->st_shndx
== SHN_UNDEF
) {
519 tcc_error("%s not defined", name
);
522 return sym
->st_value
;
525 /* return elf symbol value */
526 LIBTCCAPI
void *tcc_get_symbol(TCCState
*s
, const char *name
)
528 addr_t addr
= get_sym_addr(s
, name
, 0, 1);
529 return addr
== -1 ? NULL
: (void*)(uintptr_t)addr
;
532 /* list elf symbol names and values */
533 ST_FUNC
void list_elf_symbols(TCCState
*s
, void *ctx
,
534 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
538 int sym_index
, end_sym
;
540 unsigned char sym_vis
, sym_bind
;
543 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
544 for (sym_index
= 0; sym_index
< end_sym
; ++sym_index
) {
545 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
547 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
548 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
549 sym_vis
= ELFW(ST_VISIBILITY
)(sym
->st_other
);
550 if (sym_bind
== STB_GLOBAL
&& sym_vis
== STV_DEFAULT
)
551 symbol_cb(ctx
, name
, (void*)(uintptr_t)sym
->st_value
);
556 /* list elf symbol names and values */
557 LIBTCCAPI
void tcc_list_symbols(TCCState
*s
, void *ctx
,
558 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
560 list_elf_symbols(s
, ctx
, symbol_cb
);
565 version_add (TCCState
*s1
)
569 ElfW(Verneed
) *vn
= NULL
;
571 int sym_index
, end_sym
, nb_versions
= 2, nb_entries
= 0;
575 if (0 == nb_sym_versions
)
577 versym_section
= new_section(s1
, ".gnu.version", SHT_GNU_versym
, SHF_ALLOC
);
578 versym_section
->sh_entsize
= sizeof(ElfW(Half
));
579 versym_section
->link
= s1
->dynsym
;
581 /* add needed symbols */
583 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
584 versym
= section_ptr_add(versym_section
, end_sym
* sizeof(ElfW(Half
)));
585 for (sym_index
= 0; sym_index
< end_sym
; ++sym_index
) {
586 int dllindex
, verndx
;
587 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
588 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
589 dllindex
= find_elf_sym(s1
->dynsymtab_section
, name
);
590 verndx
= (dllindex
&& dllindex
< nb_sym_to_version
)
591 ? sym_to_version
[dllindex
] : -1;
593 if (!sym_versions
[verndx
].out_index
)
594 sym_versions
[verndx
].out_index
= nb_versions
++;
595 versym
[sym_index
] = sym_versions
[verndx
].out_index
;
597 versym
[sym_index
] = 0;
599 /* generate verneed section, but not when it will be empty. Some
600 dynamic linkers look at their contents even when DTVERNEEDNUM and
601 section size is zero. */
602 if (nb_versions
> 2) {
603 verneed_section
= new_section(s1
, ".gnu.version_r",
604 SHT_GNU_verneed
, SHF_ALLOC
);
605 verneed_section
->link
= s1
->dynsym
->link
;
606 for (i
= nb_sym_versions
; i
-- > 0;) {
607 struct sym_version
*sv
= &sym_versions
[i
];
608 int n_same_libs
= 0, prev
;
610 ElfW(Vernaux
) *vna
= 0;
611 if (sv
->out_index
< 1)
613 vnofs
= section_add(verneed_section
, sizeof(*vn
), 1);
614 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
616 vn
->vn_file
= put_elf_str(verneed_section
->link
, sv
->lib
);
617 vn
->vn_aux
= sizeof (*vn
);
619 prev
= sv
->prev_same_lib
;
620 if (sv
->out_index
> 0) {
621 vna
= section_ptr_add(verneed_section
, sizeof(*vna
));
622 vna
->vna_hash
= elf_hash ((const unsigned char *)sv
->version
);
624 vna
->vna_other
= sv
->out_index
;
626 vna
->vna_name
= put_elf_str(verneed_section
->link
, sv
->version
);
627 vna
->vna_next
= sizeof (*vna
);
631 sv
= &sym_versions
[prev
];
634 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
635 vn
->vn_cnt
= n_same_libs
;
636 vn
->vn_next
= sizeof(*vn
) + n_same_libs
* sizeof(*vna
);
641 verneed_section
->sh_info
= nb_entries
;
643 dt_verneednum
= nb_entries
;
647 /* add an elf symbol : check if it is already defined and patch
648 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
649 ST_FUNC
int set_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
650 int info
, int other
, int shndx
, const char *name
)
652 TCCState
*s1
= s
->s1
;
654 int sym_bind
, sym_index
, sym_type
, esym_bind
;
655 unsigned char sym_vis
, esym_vis
, new_vis
;
657 sym_bind
= ELFW(ST_BIND
)(info
);
658 sym_type
= ELFW(ST_TYPE
)(info
);
659 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
661 if (sym_bind
!= STB_LOCAL
) {
662 /* we search global or weak symbols */
663 sym_index
= find_elf_sym(s
, name
);
666 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
667 if (esym
->st_value
== value
&& esym
->st_size
== size
&& esym
->st_info
== info
668 && esym
->st_other
== other
&& esym
->st_shndx
== shndx
)
670 if (esym
->st_shndx
!= SHN_UNDEF
) {
671 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
672 /* propagate the most constraining visibility */
673 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
674 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
675 if (esym_vis
== STV_DEFAULT
) {
677 } else if (sym_vis
== STV_DEFAULT
) {
680 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
682 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
684 other
= esym
->st_other
; /* in case we have to patch esym */
685 if (shndx
== SHN_UNDEF
) {
686 /* ignore adding of undefined symbol if the
687 corresponding symbol is already defined */
688 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
689 /* global overrides weak, so patch */
691 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
692 /* weak is ignored if already global */
693 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_WEAK
) {
694 /* keep first-found weak definition, ignore subsequents */
695 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
696 /* ignore hidden symbols after */
697 } else if ((esym
->st_shndx
== SHN_COMMON
698 || esym
->st_shndx
== bss_section
->sh_num
)
699 && (shndx
< SHN_LORESERVE
700 && shndx
!= bss_section
->sh_num
)) {
701 /* data symbol gets precedence over common/bss */
703 } else if (shndx
== SHN_COMMON
|| shndx
== bss_section
->sh_num
) {
704 /* data symbol keeps precedence over common/bss */
705 } else if (s
->sh_flags
& SHF_DYNSYM
) {
706 /* we accept that two DLL define the same symbol */
707 } else if (esym
->st_other
& ST_ASM_SET
) {
708 /* If the existing symbol came from an asm .set
713 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
714 sym_bind
, shndx
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
716 tcc_error_noabort("'%s' defined twice", name
);
720 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
721 esym
->st_shndx
= shndx
;
722 s1
->new_undef_sym
= 1;
723 esym
->st_value
= value
;
724 esym
->st_size
= size
;
725 esym
->st_other
= other
;
729 sym_index
= put_elf_sym(s
, value
, size
,
730 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
737 ST_FUNC
void put_elf_reloca(Section
*symtab
, Section
*s
, unsigned long offset
,
738 int type
, int symbol
, addr_t addend
)
740 TCCState
*s1
= s
->s1
;
747 /* if no relocation section, create it */
748 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
749 /* if the symtab is allocated, then we consider the relocation
751 sr
= new_section(s
->s1
, buf
, SHT_RELX
, symtab
->sh_flags
);
752 sr
->sh_entsize
= sizeof(ElfW_Rel
);
754 sr
->sh_info
= s
->sh_num
;
757 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
758 rel
->r_offset
= offset
;
759 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
760 #if SHT_RELX == SHT_RELA
761 rel
->r_addend
= addend
;
763 if (SHT_RELX
!= SHT_RELA
&& addend
)
764 tcc_error("non-zero addend on REL architecture");
767 ST_FUNC
void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
768 int type
, int symbol
)
770 put_elf_reloca(symtab
, s
, offset
, type
, symbol
, 0);
773 /* put stab debug information */
774 ST_FUNC
void put_stabs(TCCState
*s1
, const char *str
, int type
, int other
, int desc
,
781 && (offset
= stab_section
->data_offset
)
782 && (sym
= (Stab_Sym
*)(stab_section
->data
+ offset
) - 1)
783 && sym
->n_type
== type
784 && sym
->n_value
== value
) {
785 /* just update line_number in previous entry */
790 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
792 sym
->n_strx
= put_elf_str(stab_section
->link
, str
);
797 sym
->n_other
= other
;
799 sym
->n_value
= value
;
802 ST_FUNC
void put_stabs_r(TCCState
*s1
, const char *str
, int type
, int other
, int desc
,
803 unsigned long value
, Section
*sec
, int sym_index
)
805 put_elf_reloc(symtab_section
, stab_section
,
806 stab_section
->data_offset
+ 8,
807 sizeof ((Stab_Sym
*)0)->n_value
== PTR_SIZE
? R_DATA_PTR
: R_DATA_32
,
809 put_stabs(s1
, str
, type
, other
, desc
, value
);
812 ST_FUNC
void put_stabn(TCCState
*s1
, int type
, int other
, int desc
, int value
)
814 put_stabs(s1
, NULL
, type
, other
, desc
, value
);
817 ST_FUNC
struct sym_attr
*get_sym_attr(TCCState
*s1
, int index
, int alloc
)
820 struct sym_attr
*tab
;
822 if (index
>= s1
->nb_sym_attrs
) {
824 return s1
->sym_attrs
;
825 /* find immediately bigger power of 2 and reallocate array */
829 tab
= tcc_realloc(s1
->sym_attrs
, n
* sizeof(*s1
->sym_attrs
));
831 memset(s1
->sym_attrs
+ s1
->nb_sym_attrs
, 0,
832 (n
- s1
->nb_sym_attrs
) * sizeof(*s1
->sym_attrs
));
833 s1
->nb_sym_attrs
= n
;
835 return &s1
->sym_attrs
[index
];
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
;
852 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
853 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
854 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
856 /* first pass for local symbols */
857 p
= (ElfW(Sym
) *)s
->data
;
859 for(i
= 0; i
< nb_syms
; i
++) {
860 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
861 old_to_new_syms
[i
] = q
- new_syms
;
866 /* save the number of local symbols in section header */
867 if( s
->sh_size
) /* this 'if' makes IDA happy */
868 s
->sh_info
= q
- new_syms
;
870 /* then second pass for non local symbols */
871 p
= (ElfW(Sym
) *)s
->data
;
872 for(i
= 0; i
< nb_syms
; i
++) {
873 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
874 old_to_new_syms
[i
] = q
- new_syms
;
880 /* we copy the new symbols to the old */
881 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
884 /* now we modify all the relocations */
885 for(i
= 1; i
< s1
->nb_sections
; i
++) {
886 sr
= s1
->sections
[i
];
887 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
888 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
889 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
890 type
= ELFW(R_TYPE
)(rel
->r_info
);
891 sym_index
= old_to_new_syms
[sym_index
];
892 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
897 tcc_free(old_to_new_syms
);
900 /* relocate symbol table, resolve undefined symbols if do_resolve is
901 true and output error if undefined symbol. */
902 ST_FUNC
void relocate_syms(TCCState
*s1
, Section
*symtab
, int do_resolve
)
905 int sym_bind
, sh_num
;
908 for_each_elem(symtab
, 1, sym
, ElfW(Sym
)) {
909 sh_num
= sym
->st_shndx
;
910 if (sh_num
== SHN_UNDEF
) {
911 name
= (char *) s1
->symtab
->link
->data
+ sym
->st_name
;
912 /* Use ld.so to resolve symbol for us (for tcc -run) */
914 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
915 /* dlsym() needs the undecorated name. */
916 void *addr
= dlsym(RTLD_DEFAULT
, &name
[s1
->leading_underscore
]);
917 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
920 for (i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
921 if ((addr
= dlsym(s1
->loaded_dlls
[i
]->handle
, name
)))
926 sym
->st_value
= (addr_t
) addr
;
928 printf ("relocate_sym: %s -> 0x%lx\n", name
, sym
->st_value
);
933 /* if dynamic symbol exist, it will be used in relocate_section */
934 } else if (s1
->dynsym
&& find_elf_sym(s1
->dynsym
, name
))
936 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
938 if (!strcmp(name
, "_fp_hw"))
940 /* only weak symbols are accepted to be undefined. Their
942 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
943 if (sym_bind
== STB_WEAK
)
946 tcc_error_noabort("undefined symbol '%s'", name
);
947 } else if (sh_num
< SHN_LORESERVE
) {
948 /* add section base */
949 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
955 /* relocate a given section (CPU dependent) by applying the relocations
956 in the associated relocation section */
957 static void relocate_section(TCCState
*s1
, Section
*s
, Section
*sr
)
965 qrel
= (ElfW_Rel
*)sr
->data
;
966 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
967 ptr
= s
->data
+ rel
->r_offset
;
968 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
969 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
970 type
= ELFW(R_TYPE
)(rel
->r_info
);
972 #if SHT_RELX == SHT_RELA
973 tgt
+= rel
->r_addend
;
975 addr
= s
->sh_addr
+ rel
->r_offset
;
976 relocate(s1
, rel
, type
, ptr
, addr
, tgt
);
979 /* if the relocation is allocated, we change its symbol table */
980 if (sr
->sh_flags
& SHF_ALLOC
) {
981 sr
->link
= s1
->dynsym
;
982 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
983 size_t r
= (uint8_t*)qrel
- sr
->data
;
984 if (sizeof ((Stab_Sym
*)0)->n_value
< PTR_SIZE
985 && 0 == strcmp(s
->name
, ".stab"))
986 r
= 0; /* cannot apply 64bit relocation to 32bit value */
987 sr
->data_offset
= sr
->sh_size
= r
;
993 /* relocate all sections */
994 ST_FUNC
void relocate_sections(TCCState
*s1
)
999 for (i
= 1; i
< s1
->nb_sections
; ++i
) {
1000 sr
= s1
->sections
[i
];
1001 if (sr
->sh_type
!= SHT_RELX
)
1003 s
= s1
->sections
[sr
->sh_info
];
1004 #ifndef TCC_TARGET_MACHO
1007 || s1
->output_type
== TCC_OUTPUT_MEMORY
)
1010 relocate_section(s1
, s
, sr
);
1012 #ifndef ELF_OBJ_ONLY
1013 if (sr
->sh_flags
& SHF_ALLOC
) {
1015 /* relocate relocation table in 'sr' */
1016 for_each_elem(sr
, 0, rel
, ElfW_Rel
)
1017 rel
->r_offset
+= s
->sh_addr
;
1023 #ifndef ELF_OBJ_ONLY
1024 /* count the number of dynamic relocations so that we can reserve
1026 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
1029 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1030 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1031 defined(TCC_TARGET_RISCV64)
1033 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
1034 int sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1035 int type
= ELFW(R_TYPE
)(rel
->r_info
);
1037 #if defined(TCC_TARGET_I386)
1039 if (!get_sym_attr(s1
, sym_index
, 0)->dyn_index
1040 && ((ElfW(Sym
)*)symtab_section
->data
+ sym_index
)->st_shndx
== SHN_UNDEF
) {
1041 /* don't fixup unresolved (weak) symbols */
1042 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_386_RELATIVE
);
1045 #elif defined(TCC_TARGET_X86_64)
1049 #elif defined(TCC_TARGET_ARM)
1052 #elif defined(TCC_TARGET_ARM64)
1053 case R_AARCH64_ABS32
:
1054 case R_AARCH64_ABS64
:
1055 #elif defined(TCC_TARGET_RISCV64)
1061 #if defined(TCC_TARGET_I386)
1063 #elif defined(TCC_TARGET_X86_64)
1066 ElfW(Sym
) *sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1068 /* Hidden defined symbols can and must be resolved locally.
1069 We're misusing a PLT32 reloc for this, as that's always
1070 resolved to its address even in shared libs. */
1071 if (sym
->st_shndx
!= SHN_UNDEF
&&
1072 ELFW(ST_VISIBILITY
)(sym
->st_other
) == STV_HIDDEN
) {
1073 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PLT32
);
1077 #elif defined(TCC_TARGET_ARM64)
1078 case R_AARCH64_PREL32
:
1080 if (get_sym_attr(s1
, sym_index
, 0)->dyn_index
)
1092 #if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE)
1093 static void build_got(TCCState
*s1
)
1095 /* if no got, then create it */
1096 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
1097 s1
->got
->sh_entsize
= 4;
1098 set_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
1099 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
1100 /* keep space for _DYNAMIC pointer and two dummy got entries */
1101 section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
1104 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1105 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1106 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1107 Returns the offset of the GOT or (if any) PLT entry. */
1108 static struct sym_attr
* put_got_entry(TCCState
*s1
, int dyn_reloc_type
,
1114 struct sym_attr
*attr
;
1115 unsigned got_offset
;
1120 need_plt_entry
= (dyn_reloc_type
== R_JMP_SLOT
);
1121 attr
= get_sym_attr(s1
, sym_index
, 1);
1123 /* In case a function is both called and its address taken 2 GOT entries
1124 are created, one for taking the address (GOT) and the other for the PLT
1126 if (need_plt_entry
? attr
->plt_offset
: attr
->got_offset
)
1130 if (need_plt_entry
) {
1132 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
1133 s1
->plt
->sh_entsize
= 4;
1138 /* create the GOT entry */
1139 got_offset
= s1
->got
->data_offset
;
1140 section_ptr_add(s1
->got
, PTR_SIZE
);
1142 /* Create the GOT relocation that will insert the address of the object or
1143 function of interest in the GOT entry. This is a static relocation for
1144 memory output (dlsym will give us the address of symbols) and dynamic
1145 relocation otherwise (executable and DLLs). The relocation should be
1146 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1147 associated to a PLT entry) but is currently done at load time for an
1150 sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1151 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1152 //printf("sym %d %s\n", need_plt_entry, name);
1155 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
) {
1156 /* Hack alarm. We don't want to emit dynamic symbols
1157 and symbol based relocs for STB_LOCAL symbols, but rather
1158 want to resolve them directly. At this point the symbol
1159 values aren't final yet, so we must defer this. We will later
1160 have to create a RELATIVE reloc anyway, so we misuse the
1161 relocation slot to smuggle the symbol reference until
1162 fill_local_got_entries. Not that the sym_index is
1163 relative to symtab_section, not s1->dynsym! Nevertheless
1164 we use s1->dyn_sym so that if this is the first call
1165 that got->reloc is correctly created. Also note that
1166 RELATIVE relocs are not normally created for the .got,
1167 so the types serves as a marker for later (and is retained
1168 also for the final output, which is okay because then the
1169 got is just normal data). */
1170 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, R_RELATIVE
,
1173 if (0 == attr
->dyn_index
)
1174 attr
->dyn_index
= set_elf_sym(s1
->dynsym
, sym
->st_value
,
1175 sym
->st_size
, sym
->st_info
, 0,
1176 sym
->st_shndx
, name
);
1177 put_elf_reloc(s1
->dynsym
, s_rel
, got_offset
, dyn_reloc_type
,
1181 put_elf_reloc(symtab_section
, s1
->got
, got_offset
, dyn_reloc_type
,
1185 if (need_plt_entry
) {
1186 attr
->plt_offset
= create_plt_entry(s1
, got_offset
, attr
);
1188 /* create a symbol 'sym@plt' for the PLT jump vector */
1190 if (len
> sizeof plt_name
- 5)
1191 len
= sizeof plt_name
- 5;
1192 memcpy(plt_name
, name
, len
);
1193 strcpy(plt_name
+ len
, "@plt");
1194 attr
->plt_sym
= put_elf_sym(s1
->symtab
, attr
->plt_offset
, sym
->st_size
,
1195 ELFW(ST_INFO
)(STB_GLOBAL
, STT_FUNC
), 0, s1
->plt
->sh_num
, plt_name
);
1197 attr
->got_offset
= got_offset
;
1203 /* build GOT and PLT entries */
1204 /* Two passes because R_JMP_SLOT should become first. Some targets
1205 (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1206 ST_FUNC
void build_got_entries(TCCState
*s1
)
1211 int i
, type
, gotplt_entry
, reloc_type
, sym_index
;
1212 struct sym_attr
*attr
;
1216 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1217 s
= s1
->sections
[i
];
1218 if (s
->sh_type
!= SHT_RELX
)
1220 /* no need to handle got relocations */
1221 if (s
->link
!= symtab_section
)
1223 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1224 type
= ELFW(R_TYPE
)(rel
->r_info
);
1225 gotplt_entry
= gotplt_entry_type(type
);
1226 if (gotplt_entry
== -1)
1227 tcc_error ("Unknown relocation type for got: %d", type
);
1228 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1229 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1231 if (gotplt_entry
== NO_GOTPLT_ENTRY
) {
1235 /* Automatically create PLT/GOT [entry] if it is an undefined
1236 reference (resolved at runtime), or the symbol is absolute,
1237 probably created by tcc_add_symbol, and thus on 64-bit
1238 targets might be too far from application code. */
1239 if (gotplt_entry
== AUTO_GOTPLT_ENTRY
) {
1240 if (sym
->st_shndx
== SHN_UNDEF
) {
1243 if (s1
->output_type
== TCC_OUTPUT_DLL
&& ! PCRELATIVE_DLLPLT
)
1245 /* Relocations for UNDEF symbols would normally need
1246 to be transferred into the executable or shared object.
1247 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1248 But TCC doesn't do that (at least for exes), so we
1249 need to resolve all such relocs locally. And that
1250 means PLT slots for functions in DLLs and COPY relocs for
1251 data symbols. COPY relocs were generated in
1252 bind_exe_dynsyms (and the symbol adjusted to be defined),
1253 and for functions we were generated a dynamic symbol
1254 of function type. */
1256 /* dynsym isn't set for -run :-/ */
1257 dynindex
= get_sym_attr(s1
, sym_index
, 0)->dyn_index
;
1258 esym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ dynindex
;
1260 && (ELFW(ST_TYPE
)(esym
->st_info
) == STT_FUNC
1261 || (ELFW(ST_TYPE
)(esym
->st_info
) == STT_NOTYPE
1262 && ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
)))
1265 } else if (sym
->st_shndx
== SHN_ABS
) {
1266 if (sym
->st_value
== 0) /* from tcc_add_btstub() */
1268 #ifndef TCC_TARGET_ARM
1272 /* from tcc_add_symbol(): on 64 bit platforms these
1273 need to go through .got */
1278 #ifdef TCC_TARGET_X86_64
1279 if ((type
== R_X86_64_PLT32
|| type
== R_X86_64_PC32
) &&
1280 sym
->st_shndx
!= SHN_UNDEF
&&
1281 (ELFW(ST_VISIBILITY
)(sym
->st_other
) != STV_DEFAULT
||
1282 ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
||
1283 s1
->output_type
== TCC_OUTPUT_EXE
)) {
1286 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PC32
);
1290 reloc_type
= code_reloc(type
);
1291 if (reloc_type
== -1)
1292 tcc_error ("Unknown relocation type: %d", type
);
1294 if (reloc_type
!= 0) {
1298 reloc_type
= R_JMP_SLOT
;
1302 reloc_type
= R_GLOB_DAT
;
1308 if (gotplt_entry
== BUILD_GOT_ONLY
)
1311 attr
= put_got_entry(s1
, reloc_type
, sym_index
);
1313 if (reloc_type
== R_JMP_SLOT
)
1314 rel
->r_info
= ELFW(R_INFO
)(attr
->plt_sym
, type
);
1320 /* .rel.plt refers to .got actually */
1321 if (s1
->plt
&& s1
->plt
->reloc
)
1322 s1
->plt
->reloc
->sh_info
= s1
->got
->sh_num
;
1327 ST_FUNC
int set_global_sym(TCCState
*s1
, const char *name
, Section
*sec
, addr_t offs
)
1329 int shn
= sec
? sec
->sh_num
: offs
|| !name
? SHN_ABS
: SHN_UNDEF
;
1330 if (sec
&& offs
== -1)
1331 offs
= sec
->data_offset
;
1332 return set_elf_sym(symtab_section
, offs
, 0,
1333 ELFW(ST_INFO
)(name
? STB_GLOBAL
: STB_LOCAL
, STT_NOTYPE
), 0, shn
, name
);
1336 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1341 s
= find_section_create(s1
, section_name
, 0);
1346 end_offset
= s
->data_offset
;
1348 snprintf(buf
, sizeof(buf
), "__%s_start", section_name
+ 1);
1349 set_global_sym(s1
, buf
, s
, 0);
1350 snprintf(buf
, sizeof(buf
), "__%s_end", section_name
+ 1);
1351 set_global_sym(s1
, buf
, s
, end_offset
);
1354 #ifndef TCC_TARGET_PE
1355 static void tcc_add_support(TCCState
*s1
, const char *filename
)
1358 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, filename
);
1359 tcc_add_file(s1
, buf
);
1363 ST_FUNC
void add_array (TCCState
*s1
, const char *sec
, int c
)
1366 s
= find_section(s1
, sec
);
1367 s
->sh_flags
|= SHF_WRITE
;
1368 #ifndef TCC_TARGET_PE
1369 s
->sh_type
= sec
[1] == 'i' ? SHT_INIT_ARRAY
: SHT_FINI_ARRAY
;
1371 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1372 section_ptr_add(s
, PTR_SIZE
);
1375 #ifdef CONFIG_TCC_BCHECK
1376 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
1378 if (0 == s1
->do_bounds_check
)
1380 section_ptr_add(bounds_section
, sizeof(addr_t
));
1384 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1385 a dynamic symbol to allow so's to have one each with a different value. */
1386 static void set_local_sym(TCCState
*s1
, const char *name
, Section
*s
, int offset
)
1388 int c
= find_elf_sym(s1
->symtab
, name
);
1390 ElfW(Sym
) *esym
= (ElfW(Sym
)*)s1
->symtab
->data
+ c
;
1391 esym
->st_info
= ELFW(ST_INFO
)(STB_LOCAL
, STT_NOTYPE
);
1392 esym
->st_value
= offset
;
1393 esym
->st_shndx
= s
->sh_num
;
1397 #ifdef CONFIG_TCC_BACKTRACE
1398 static void put_ptr(TCCState
*s1
, Section
*s
, int offs
)
1401 c
= set_global_sym(s1
, NULL
, s
, offs
);
1403 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1404 section_ptr_add(s
, PTR_SIZE
);
1407 ST_FUNC
void tcc_add_btstub(TCCState
*s1
)
1414 /* Align to PTR_SIZE */
1415 section_ptr_add(s
, -s
->data_offset
& (PTR_SIZE
- 1));
1417 /* create (part of) a struct rt_context (see tccrun.c) */
1418 put_ptr(s1
, stab_section
, 0);
1419 put_ptr(s1
, stab_section
, -1);
1420 put_ptr(s1
, stab_section
->link
, 0);
1421 section_ptr_add(s
, 3 * PTR_SIZE
);
1422 /* prog_base : local nameless symbol with offset 0 at SHN_ABS */
1423 put_ptr(s1
, NULL
, 0);
1425 #ifdef CONFIG_TCC_BCHECK
1426 if (s1
->do_bounds_check
) {
1427 put_ptr(s1
, bounds_section
, 0);
1431 section_ptr_add(s
, n
);
1434 "extern void __bt_init(),__bt_init_dll();"
1435 "static void *__rt_info[];"
1436 "__attribute__((constructor)) static void __bt_init_rt(){");
1437 #ifdef TCC_TARGET_PE
1438 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1439 #ifdef CONFIG_TCC_BCHECK
1440 cstr_printf(&cstr
, "__bt_init_dll(%d);", s1
->do_bounds_check
);
1442 cstr_printf(&cstr
, "__bt_init_dll(0);");
1445 cstr_printf(&cstr
, "__bt_init(__rt_info,%d);}",
1446 s1
->output_type
== TCC_OUTPUT_DLL
? 0 : s1
->rt_num_callers
+ 1);
1447 tcc_compile_string(s1
, cstr
.data
);
1449 set_local_sym(s1
, &"___rt_info"[!s1
->leading_underscore
], s
, o
);
1453 static void tcc_tcov_add_file(TCCState
*s1
, const char *filename
)
1459 if (tcov_section
== NULL
)
1461 section_ptr_add(tcov_section
, 1);
1462 write32le (tcov_section
->data
, tcov_section
->data_offset
);
1465 if (filename
[0] == '/')
1466 cstr_printf (&cstr
, "%s.tcov", filename
);
1468 getcwd (wd
, sizeof(wd
));
1469 cstr_printf (&cstr
, "%s/%s.tcov", wd
, filename
);
1471 ptr
= section_ptr_add(tcov_section
, cstr
.size
+ 1);
1472 strcpy((char *)ptr
, cstr
.data
);
1473 unlink((char *)ptr
);
1475 normalize_slashes((char *)ptr
);
1481 "extern char *__tcov_data[];"
1482 "extern void __store_test_coverage ();"
1483 "__attribute__((destructor)) static void __tcov_exit() {"
1484 "__store_test_coverage(__tcov_data);"
1486 tcc_compile_string(s1
, cstr
.data
);
1488 set_local_sym(s1
, &"___tcov_data"[!s1
->leading_underscore
], tcov_section
, 0);
1491 #ifndef TCC_TARGET_PE
1492 /* add tcc runtime libraries */
1493 ST_FUNC
void tcc_add_runtime(TCCState
*s1
)
1496 #ifdef CONFIG_TCC_BCHECK
1499 tcc_add_pragma_libs(s1
);
1501 if (!s1
->nostdlib
) {
1502 if (s1
->option_pthread
)
1503 tcc_add_library_err(s1
, "pthread");
1504 tcc_add_library_err(s1
, "c");
1506 if (!s1
->static_link
) {
1507 if (TCC_LIBGCC
[0] == '/')
1508 tcc_add_file(s1
, TCC_LIBGCC
);
1510 tcc_add_dll(s1
, TCC_LIBGCC
, 0);
1513 #if TCC_TARGET_ARM && TARGETOS_FreeBSD
1514 tcc_add_library_err(s1
, "gcc_s"); // unwind code
1516 #ifdef CONFIG_TCC_BCHECK
1517 if (s1
->do_bounds_check
&& s1
->output_type
!= TCC_OUTPUT_DLL
) {
1518 tcc_add_library_err(s1
, "pthread");
1519 #if !TARGETOS_OpenBSD && !TARGETOS_NetBSD
1520 tcc_add_library_err(s1
, "dl");
1522 tcc_add_support(s1
, "bcheck.o");
1523 if (s1
->static_link
)
1524 tcc_add_library_err(s1
, "c");
1527 #ifdef CONFIG_TCC_BACKTRACE
1528 if (s1
->do_backtrace
) {
1529 if (s1
->output_type
== TCC_OUTPUT_EXE
)
1530 tcc_add_support(s1
, "bt-exe.o");
1531 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1532 tcc_add_support(s1
, "bt-log.o");
1533 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1538 tcc_add_support(s1
, TCC_LIBTCC1
);
1540 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
1541 /* add crt end if not memory output */
1542 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1543 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1544 tcc_add_crt(s1
, "crtendS.o");
1546 tcc_add_crt(s1
, "crtend.o");
1547 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
1548 tcc_add_crt(s1
, "crtn.o");
1551 #elif !defined(TCC_TARGET_MACHO)
1552 /* add crt end if not memory output */
1553 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1554 tcc_add_crt(s1
, "crtn.o");
1560 /* add various standard linker symbols (must be done after the
1561 sections are filled (for example after allocating common
1563 static void tcc_add_linker_symbols(TCCState
*s1
)
1569 set_global_sym(s1
, "_etext", text_section
, -1);
1570 set_global_sym(s1
, "_edata", data_section
, -1);
1571 set_global_sym(s1
, "_end", bss_section
, -1);
1572 #if TARGETOS_OpenBSD
1573 set_global_sym(s1
, "__executable_start", NULL
, ELF_START_ADDR
);
1575 #ifdef TCC_TARGET_RISCV64
1576 /* XXX should be .sdata+0x800, not .data+0x800 */
1577 set_global_sym(s1
, "__global_pointer$", data_section
, 0x800);
1579 /* horrible new standard ldscript defines */
1580 #ifndef TCC_TARGET_PE
1581 add_init_array_defines(s1
, ".preinit_array");
1583 add_init_array_defines(s1
, ".init_array");
1584 add_init_array_defines(s1
, ".fini_array");
1585 /* add start and stop symbols for sections whose name can be
1587 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1588 s
= s1
->sections
[i
];
1589 if ((s
->sh_flags
& SHF_ALLOC
)
1590 && (s
->sh_type
== SHT_PROGBITS
1591 || s
->sh_type
== SHT_STRTAB
)) {
1593 /* check if section name can be expressed in C */
1599 if (!isid(c
) && !isnum(c
))
1603 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1604 set_global_sym(s1
, buf
, s
, 0);
1605 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1606 set_global_sym(s1
, buf
, s
, -1);
1612 ST_FUNC
void resolve_common_syms(TCCState
*s1
)
1616 /* Allocate common symbols in BSS. */
1617 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1618 if (sym
->st_shndx
== SHN_COMMON
) {
1619 /* symbol alignment is in st_value for SHN_COMMONs */
1620 sym
->st_value
= section_add(bss_section
, sym
->st_size
,
1622 sym
->st_shndx
= bss_section
->sh_num
;
1626 /* Now assign linker provided symbols their value. */
1627 tcc_add_linker_symbols(s1
);
1630 #ifndef ELF_OBJ_ONLY
1632 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1634 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1635 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1636 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1637 unsigned offset
= attr
->got_offset
;
1641 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1643 write64le(s1
->got
->data
+ offset
, sym
->st_value
);
1645 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1649 /* Perform relocation to GOT or PLT entries */
1650 ST_FUNC
void fill_got(TCCState
*s1
)
1656 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1657 s
= s1
->sections
[i
];
1658 if (s
->sh_type
!= SHT_RELX
)
1660 /* no need to handle got relocations */
1661 if (s
->link
!= symtab_section
)
1663 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1664 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1665 case R_X86_64_GOT32
:
1666 case R_X86_64_GOTPCREL
:
1667 case R_X86_64_GOTPCRELX
:
1668 case R_X86_64_REX_GOTPCRELX
:
1669 case R_X86_64_PLT32
:
1670 fill_got_entry(s1
, rel
);
1677 /* See put_got_entry for a description. This is the second stage
1678 where GOT references to local defined symbols are rewritten. */
1679 static void fill_local_got_entries(TCCState
*s1
)
1682 if (!s1
->got
->reloc
)
1684 for_each_elem(s1
->got
->reloc
, 0, rel
, ElfW_Rel
) {
1685 if (ELFW(R_TYPE
)(rel
->r_info
) == R_RELATIVE
) {
1686 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1687 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1688 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1689 unsigned offset
= attr
->got_offset
;
1690 if (offset
!= rel
->r_offset
- s1
->got
->sh_addr
)
1691 tcc_error_noabort("huh");
1692 rel
->r_info
= ELFW(R_INFO
)(0, R_RELATIVE
);
1693 #if SHT_RELX == SHT_RELA
1694 rel
->r_addend
= sym
->st_value
;
1696 /* All our REL architectures also happen to be 32bit LE. */
1697 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1703 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1704 in shared libraries and export non local defined symbols to shared libraries
1705 if -rdynamic switch was given on command line */
1706 static void bind_exe_dynsyms(TCCState
*s1
)
1709 int sym_index
, index
;
1710 ElfW(Sym
) *sym
, *esym
;
1713 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1714 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1715 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1716 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1717 if (sym
->st_shndx
== SHN_UNDEF
) {
1718 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1719 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1721 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1722 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1723 if ((type
== STT_FUNC
) || (type
== STT_GNU_IFUNC
)) {
1724 /* Indirect functions shall have STT_FUNC type in executable
1725 * dynsym section. Indeed, a dlsym call following a lazy
1726 * resolution would pick the symbol value from the
1727 * executable dynsym entry which would contain the address
1728 * of the function wanted by the caller of dlsym instead of
1729 * the address of the function that would return that
1732 = put_elf_sym(s1
->dynsym
, 0, esym
->st_size
,
1733 ELFW(ST_INFO
)(STB_GLOBAL
,STT_FUNC
), 0, 0,
1735 int index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1736 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1737 } else if (type
== STT_OBJECT
) {
1738 unsigned long offset
;
1740 offset
= bss_section
->data_offset
;
1741 /* XXX: which alignment ? */
1742 offset
= (offset
+ 16 - 1) & -16;
1743 set_elf_sym (s1
->symtab
, offset
, esym
->st_size
,
1744 esym
->st_info
, 0, bss_section
->sh_num
, name
);
1745 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1746 esym
->st_info
, 0, bss_section
->sh_num
,
1749 /* Ensure R_COPY works for weak symbol aliases */
1750 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1751 for_each_elem(s1
->dynsymtab_section
, 1, dynsym
, ElfW(Sym
)) {
1752 if ((dynsym
->st_value
== esym
->st_value
)
1753 && (ELFW(ST_BIND
)(dynsym
->st_info
) == STB_GLOBAL
)) {
1754 char *dynname
= (char *) s1
->dynsymtab_section
->link
->data
1756 put_elf_sym(s1
->dynsym
, offset
, dynsym
->st_size
,
1758 bss_section
->sh_num
, dynname
);
1764 put_elf_reloc(s1
->dynsym
, bss_section
,
1765 offset
, R_COPY
, index
);
1766 offset
+= esym
->st_size
;
1767 bss_section
->data_offset
= offset
;
1770 /* STB_WEAK undefined symbols are accepted */
1771 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1772 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1773 !strcmp(name
, "_fp_hw")) {
1775 tcc_error_noabort("undefined symbol '%s'", name
);
1778 } else if (s1
->rdynamic
&& ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1779 /* if -rdynamic option, then export all non local symbols */
1780 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1781 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
1782 0, sym
->st_shndx
, name
);
1787 /* Bind symbols of libraries: export all non local symbols of executable that
1788 are referenced by shared libraries. The reason is that the dynamic loader
1789 search symbol first in executable and then in libraries. Therefore a
1790 reference to a symbol already defined by a library can still be resolved by
1791 a symbol in the executable. */
1792 static void bind_libs_dynsyms(TCCState
*s1
)
1796 ElfW(Sym
) *sym
, *esym
;
1798 for_each_elem(s1
->dynsymtab_section
, 1, esym
, ElfW(Sym
)) {
1799 name
= (char *) s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1800 sym_index
= find_elf_sym(symtab_section
, name
);
1801 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1802 if (sym_index
&& sym
->st_shndx
!= SHN_UNDEF
1803 && ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1804 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1805 sym
->st_info
, 0, sym
->st_shndx
, name
);
1806 } else if (esym
->st_shndx
== SHN_UNDEF
) {
1807 /* weak symbols can stay undefined */
1808 if (ELFW(ST_BIND
)(esym
->st_info
) != STB_WEAK
)
1809 tcc_warning("undefined dynamic symbol '%s'", name
);
1814 /* Export all non local symbols. This is used by shared libraries so that the
1815 non local symbols they define can resolve a reference in another shared
1816 library or in the executable. Correspondingly, it allows undefined local
1817 symbols to be resolved by other shared libraries or by the executable. */
1818 static void export_global_syms(TCCState
*s1
)
1820 int dynindex
, index
;
1824 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1825 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1826 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1827 dynindex
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1828 sym
->st_info
, 0, sym
->st_shndx
, name
);
1829 index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1830 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1835 /* decide if an unallocated section should be output. */
1836 static int set_sec_sizes(TCCState
*s1
)
1841 int file_type
= s1
->output_type
;
1843 /* Allocate strings for section names */
1844 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1845 s
= s1
->sections
[i
];
1846 if (s
->sh_type
== SHT_RELX
&& !(s
->sh_flags
& SHF_ALLOC
)) {
1847 /* when generating a DLL, we include relocations but
1848 we may patch them */
1849 if (file_type
== TCC_OUTPUT_DLL
1850 && (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)) {
1851 int count
= prepare_dynamic_rel(s1
, s
);
1853 /* allocate the section */
1854 s
->sh_flags
|= SHF_ALLOC
;
1855 s
->sh_size
= count
* sizeof(ElfW_Rel
);
1856 if (!(s1
->sections
[s
->sh_info
]->sh_flags
& SHF_WRITE
))
1860 } else if ((s
->sh_flags
& SHF_ALLOC
)
1861 #ifdef TCC_TARGET_ARM
1862 || s
->sh_type
== SHT_ARM_ATTRIBUTES
1865 s
->sh_size
= s
->data_offset
;
1868 #ifdef TCC_TARGET_ARM
1869 /* XXX: Suppress stack unwinding section. */
1870 if (s
->sh_type
== SHT_ARM_EXIDX
) {
1881 /* Info to be copied in dynamic section */
1885 unsigned long data_offset
;
1890 /* Info for GNU_RELRO */
1897 static void alloc_sec_names(
1898 TCCState
*s1
, int is_obj
1901 static int layout_any_sections(
1902 TCCState
*s1
, int file_offset
, int *sec_order
, int is_obj
1905 /* Assign sections to segments and decide how are sections laid out when loaded
1906 in memory. This function also fills corresponding program headers. */
1907 static int layout_sections(TCCState
*s1
, ElfW(Phdr
) *phdr
,
1908 int phnum
, int phfill
,
1910 struct ro_inf
*roinf
, int *sec_order
)
1916 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
1917 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1920 unsigned long s_align
;
1924 int j
, k
, f
, file_type
= s1
->output_type
;
1926 s_align
= ELF_PAGE_SIZE
;
1927 if (s1
->section_align
)
1928 s_align
= s1
->section_align
;
1930 if (s1
->has_text_addr
) {
1931 int a_offset
, p_offset
;
1932 addr
= s1
->text_addr
;
1933 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1935 a_offset
= (int) (addr
& (s_align
- 1));
1936 p_offset
= file_offset
& (s_align
- 1);
1937 if (a_offset
< p_offset
)
1938 a_offset
+= s_align
;
1939 file_offset
+= (a_offset
- p_offset
);
1941 if (file_type
== TCC_OUTPUT_DLL
)
1944 addr
= ELF_START_ADDR
;
1945 /* compute address after headers */
1946 addr
+= (file_offset
& (s_align
- 1));
1950 /* Leave one program headers for the program interpreter and one for
1951 the program header table itself if needed. These are done later as
1952 they require section layout to be done first. */
1956 /* read only segment mapping for GNU_RELRO */
1957 roinf
->sh_offset
= roinf
->sh_addr
= roinf
->sh_size
= 0;
1959 for(j
= 0; j
< phfill
; j
++) {
1960 ph
->p_type
= j
== 2 ? PT_TLS
: PT_LOAD
;
1962 ph
->p_flags
= PF_R
| PF_X
;
1964 ph
->p_flags
= PF_R
| PF_W
;
1965 ph
->p_align
= j
== 2 ? 4 : s_align
;
1967 /* Decide the layout of sections loaded in memory. This must
1968 be done before program headers are filled since they contain
1969 info about the layout. We do the following ordering: interp,
1970 symbol tables, relocations, progbits, nobits */
1971 /* XXX: do faster and simpler sorting */
1973 for(k
= 0; k
< 7; k
++) {
1974 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1975 s
= s1
->sections
[i
];
1976 /* compute if section should be included */
1978 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
| SHF_TLS
)) !=
1981 } else if (j
== 1) {
1982 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
| SHF_TLS
)) !=
1983 (SHF_ALLOC
| SHF_WRITE
))
1986 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
| SHF_TLS
)) !=
1987 (SHF_ALLOC
| SHF_WRITE
| SHF_TLS
))
1993 } else if ((s
->sh_type
== SHT_DYNSYM
||
1994 s
->sh_type
== SHT_STRTAB
||
1995 s
->sh_type
== SHT_HASH
)
1996 && !strstr(s
->name
, ".stab")) {
1999 } else if (s
->sh_type
== SHT_RELX
) {
2000 if (s1
->plt
&& s
== s1
->plt
->reloc
) {
2007 } else if (s
->sh_type
== SHT_NOBITS
) {
2010 } else if ((s
== rodata_section
2011 #ifdef CONFIG_TCC_BCHECK
2012 || s
== bounds_section
2013 || s
== lbounds_section
2015 ) && (s
->sh_flags
& SHF_WRITE
)) {
2018 /* Align next section on page size.
2019 This is needed to remap roinf section ro. */
2027 /* section matches: we align it and add its size */
2030 s
->sh_addralign
= PAGESIZE
;
2031 addr
= (addr
+ s
->sh_addralign
- 1) &
2032 ~(s
->sh_addralign
- 1);
2033 file_offset
+= (int) ( addr
- tmp
);
2034 s
->sh_offset
= file_offset
;
2037 /* update program header infos */
2038 if (ph
->p_offset
== 0) {
2039 ph
->p_offset
= file_offset
;
2041 ph
->p_paddr
= ph
->p_vaddr
;
2045 if (roinf
->sh_size
== 0) {
2046 roinf
->sh_offset
= s
->sh_offset
;
2047 roinf
->sh_addr
= s
->sh_addr
;
2049 roinf
->sh_size
= (addr
- roinf
->sh_addr
) + s
->sh_size
;
2053 if (s
->sh_type
!= SHT_NOBITS
)
2054 file_offset
+= s
->sh_size
;
2058 /* Make the first PT_LOAD segment include the program
2059 headers itself (and the ELF header as well), it'll
2060 come out with same memory use but will make various
2061 tools like binutils strip work better. */
2062 ph
->p_offset
&= ~(ph
->p_align
- 1);
2063 ph
->p_vaddr
&= ~(ph
->p_align
- 1);
2064 ph
->p_paddr
&= ~(ph
->p_align
- 1);
2066 ph
->p_filesz
= file_offset
- ph
->p_offset
;
2067 ph
->p_memsz
= addr
- ph
->p_vaddr
;
2070 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
2071 /* if in the middle of a page, we duplicate the page in
2072 memory so that one copy is RX and the other is RW */
2073 if ((addr
& (s_align
- 1)) != 0)
2076 addr
= (addr
+ s_align
- 1) & ~(s_align
- 1);
2077 file_offset
= (file_offset
+ s_align
- 1) & ~(s_align
- 1);
2083 /* all other sections come after */
2084 return layout_any_sections(s1
, file_offset
, sec_order
, 0);
2087 /* put dynamic tag */
2088 static void put_dt(Section
*dynamic
, int dt
, addr_t val
)
2091 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
2093 dyn
->d_un
.d_val
= val
;
2096 static void fill_unloadable_phdr(ElfW(Phdr
) *phdr
, int phnum
, Section
*interp
,
2097 Section
*dynamic
, Section
*note
, struct ro_inf
*roinf
)
2101 /* if interpreter, then add corresponding program header */
2105 ph
->p_type
= PT_PHDR
;
2106 ph
->p_offset
= sizeof(ElfW(Ehdr
));
2107 ph
->p_filesz
= ph
->p_memsz
= phnum
* sizeof(ElfW(Phdr
));
2108 ph
->p_vaddr
= interp
->sh_addr
- ph
->p_filesz
;
2109 ph
->p_paddr
= ph
->p_vaddr
;
2110 ph
->p_flags
= PF_R
| PF_X
;
2111 ph
->p_align
= 4; /* interp->sh_addralign; */
2114 ph
->p_type
= PT_INTERP
;
2115 ph
->p_offset
= interp
->sh_offset
;
2116 ph
->p_vaddr
= interp
->sh_addr
;
2117 ph
->p_paddr
= ph
->p_vaddr
;
2118 ph
->p_filesz
= interp
->sh_size
;
2119 ph
->p_memsz
= interp
->sh_size
;
2121 ph
->p_align
= interp
->sh_addralign
;
2125 ph
= &phdr
[phnum
- 2 - (roinf
!= NULL
)];
2127 ph
->p_type
= PT_NOTE
;
2128 ph
->p_offset
= note
->sh_offset
;
2129 ph
->p_vaddr
= note
->sh_addr
;
2130 ph
->p_paddr
= ph
->p_vaddr
;
2131 ph
->p_filesz
= note
->sh_size
;
2132 ph
->p_memsz
= note
->sh_size
;
2134 ph
->p_align
= note
->sh_addralign
;
2137 /* if dynamic section, then add corresponding program header */
2139 ph
= &phdr
[phnum
- 1 - (roinf
!= NULL
)];
2141 ph
->p_type
= PT_DYNAMIC
;
2142 ph
->p_offset
= dynamic
->sh_offset
;
2143 ph
->p_vaddr
= dynamic
->sh_addr
;
2144 ph
->p_paddr
= ph
->p_vaddr
;
2145 ph
->p_filesz
= dynamic
->sh_size
;
2146 ph
->p_memsz
= dynamic
->sh_size
;
2147 ph
->p_flags
= PF_R
| PF_W
;
2148 ph
->p_align
= dynamic
->sh_addralign
;
2152 ph
= &phdr
[phnum
- 1];
2154 ph
->p_type
= PT_GNU_RELRO
;
2155 ph
->p_offset
= roinf
->sh_offset
;
2156 ph
->p_vaddr
= roinf
->sh_addr
;
2157 ph
->p_paddr
= ph
->p_vaddr
;
2158 ph
->p_filesz
= roinf
->sh_size
;
2159 ph
->p_memsz
= roinf
->sh_size
;
2165 /* Fill the dynamic section with tags describing the address and size of
2167 static void fill_dynamic(TCCState
*s1
, struct dyn_inf
*dyninf
)
2169 Section
*dynamic
= dyninf
->dynamic
;
2172 /* put dynamic section entries */
2173 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
2174 put_dt(dynamic
, DT_STRTAB
, dyninf
->dynstr
->sh_addr
);
2175 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
2176 put_dt(dynamic
, DT_STRSZ
, dyninf
->dynstr
->data_offset
);
2177 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
2179 put_dt(dynamic
, DT_RELA
, dyninf
->rel_addr
);
2180 put_dt(dynamic
, DT_RELASZ
, dyninf
->rel_size
);
2181 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
2182 if (s1
->plt
&& s1
->plt
->reloc
) {
2183 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2184 put_dt(dynamic
, DT_PLTRELSZ
, s1
->plt
->reloc
->data_offset
);
2185 put_dt(dynamic
, DT_JMPREL
, s1
->plt
->reloc
->sh_addr
);
2186 put_dt(dynamic
, DT_PLTREL
, DT_RELA
);
2188 put_dt(dynamic
, DT_RELACOUNT
, 0);
2190 put_dt(dynamic
, DT_REL
, dyninf
->rel_addr
);
2191 put_dt(dynamic
, DT_RELSZ
, dyninf
->rel_size
);
2192 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
2193 if (s1
->plt
&& s1
->plt
->reloc
) {
2194 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2195 put_dt(dynamic
, DT_PLTRELSZ
, s1
->plt
->reloc
->data_offset
);
2196 put_dt(dynamic
, DT_JMPREL
, s1
->plt
->reloc
->sh_addr
);
2197 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
2199 put_dt(dynamic
, DT_RELCOUNT
, 0);
2201 if (versym_section
&& verneed_section
) {
2202 /* The dynamic linker can not handle VERSYM without VERNEED */
2203 put_dt(dynamic
, DT_VERSYM
, versym_section
->sh_addr
);
2204 put_dt(dynamic
, DT_VERNEED
, verneed_section
->sh_addr
);
2205 put_dt(dynamic
, DT_VERNEEDNUM
, dt_verneednum
);
2207 s
= find_section_create (s1
, ".preinit_array", 0);
2208 if (s
&& s
->data_offset
) {
2209 put_dt(dynamic
, DT_PREINIT_ARRAY
, s
->sh_addr
);
2210 put_dt(dynamic
, DT_PREINIT_ARRAYSZ
, s
->data_offset
);
2212 s
= find_section_create (s1
, ".init_array", 0);
2213 if (s
&& s
->data_offset
) {
2214 put_dt(dynamic
, DT_INIT_ARRAY
, s
->sh_addr
);
2215 put_dt(dynamic
, DT_INIT_ARRAYSZ
, s
->data_offset
);
2217 s
= find_section_create (s1
, ".fini_array", 0);
2218 if (s
&& s
->data_offset
) {
2219 put_dt(dynamic
, DT_FINI_ARRAY
, s
->sh_addr
);
2220 put_dt(dynamic
, DT_FINI_ARRAYSZ
, s
->data_offset
);
2222 s
= find_section_create (s1
, ".init", 0);
2223 if (s
&& s
->data_offset
) {
2224 put_dt(dynamic
, DT_INIT
, s
->sh_addr
);
2226 s
= find_section_create (s1
, ".fini", 0);
2227 if (s
&& s
->data_offset
) {
2228 put_dt(dynamic
, DT_FINI
, s
->sh_addr
);
2231 put_dt(dynamic
, DT_DEBUG
, 0);
2232 put_dt(dynamic
, DT_NULL
, 0);
2235 /* Remove gaps between RELX sections.
2236 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2237 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2238 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2239 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2240 static void update_reloc_sections(TCCState
*s1
, struct dyn_inf
*dyninf
)
2243 unsigned long file_offset
= 0;
2245 Section
*relocplt
= s1
->plt
? s1
->plt
->reloc
: NULL
;
2247 /* dynamic relocation table information, for .dynamic section */
2248 dyninf
->rel_addr
= dyninf
->rel_size
= 0;
2250 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2251 s
= s1
->sections
[i
];
2252 if (s
->sh_type
== SHT_RELX
&& s
!= relocplt
) {
2253 if (dyninf
->rel_size
== 0) {
2254 dyninf
->rel_addr
= s
->sh_addr
;
2255 file_offset
= s
->sh_offset
;
2258 s
->sh_addr
= dyninf
->rel_addr
+ dyninf
->rel_size
;
2259 s
->sh_offset
= file_offset
+ dyninf
->rel_size
;
2261 dyninf
->rel_size
+= s
->sh_size
;
2266 #endif /* ndef ELF_OBJ_ONLY */
2268 /* Create an ELF file on disk.
2269 This function handle ELF specific layout requirements */
2270 static void tcc_output_elf(TCCState
*s1
, FILE *f
, int phnum
, ElfW(Phdr
) *phdr
,
2271 int file_offset
, int *sec_order
)
2273 int i
, shnum
, offset
, size
, file_type
;
2276 ElfW(Shdr
) shdr
, *sh
;
2278 file_type
= s1
->output_type
;
2279 shnum
= s1
->nb_sections
;
2281 memset(&ehdr
, 0, sizeof(ehdr
));
2284 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2285 ehdr
.e_phnum
= phnum
;
2286 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2290 file_offset
= (file_offset
+ 3) & -4;
2293 ehdr
.e_ident
[0] = ELFMAG0
;
2294 ehdr
.e_ident
[1] = ELFMAG1
;
2295 ehdr
.e_ident
[2] = ELFMAG2
;
2296 ehdr
.e_ident
[3] = ELFMAG3
;
2297 ehdr
.e_ident
[4] = ELFCLASSW
;
2298 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2299 ehdr
.e_ident
[6] = EV_CURRENT
;
2300 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2301 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2303 #ifdef TCC_TARGET_ARM
2305 ehdr
.e_ident
[EI_OSABI
] = 0;
2306 ehdr
.e_flags
= EF_ARM_EABI_VER4
;
2307 if (file_type
== TCC_OUTPUT_EXE
|| file_type
== TCC_OUTPUT_DLL
)
2308 ehdr
.e_flags
|= EF_ARM_HASENTRY
;
2309 if (s1
->float_abi
== ARM_HARD_FLOAT
)
2310 ehdr
.e_flags
|= EF_ARM_VFP_FLOAT
;
2312 ehdr
.e_flags
|= EF_ARM_SOFT_FLOAT
;
2314 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2316 #elif defined TCC_TARGET_RISCV64
2317 ehdr
.e_flags
= EF_RISCV_FLOAT_ABI_DOUBLE
;
2321 case TCC_OUTPUT_EXE
:
2322 ehdr
.e_type
= ET_EXEC
;
2323 ehdr
.e_entry
= get_sym_addr(s1
, "_start", 1, 0);
2325 case TCC_OUTPUT_DLL
:
2326 ehdr
.e_type
= ET_DYN
;
2327 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
2329 case TCC_OUTPUT_OBJ
:
2330 ehdr
.e_type
= ET_REL
;
2333 ehdr
.e_machine
= EM_TCC_TARGET
;
2334 ehdr
.e_version
= EV_CURRENT
;
2335 ehdr
.e_shoff
= file_offset
;
2336 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2337 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2338 ehdr
.e_shnum
= shnum
;
2339 ehdr
.e_shstrndx
= shnum
- 1;
2341 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2343 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2344 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2346 sort_syms(s1
, symtab_section
);
2347 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2348 s
= s1
->sections
[sec_order
[i
]];
2349 if (s
->sh_type
!= SHT_NOBITS
) {
2350 while (offset
< s
->sh_offset
) {
2356 fwrite(s
->data
, 1, size
, f
);
2361 /* output section headers */
2362 while (offset
< ehdr
.e_shoff
) {
2367 for(i
= 0; i
< s1
->nb_sections
; i
++) {
2369 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2370 s
= s1
->sections
[i
];
2372 sh
->sh_name
= s
->sh_name
;
2373 sh
->sh_type
= s
->sh_type
;
2374 sh
->sh_flags
= s
->sh_flags
;
2375 sh
->sh_entsize
= s
->sh_entsize
;
2376 sh
->sh_info
= s
->sh_info
;
2378 sh
->sh_link
= s
->link
->sh_num
;
2379 sh
->sh_addralign
= s
->sh_addralign
;
2380 sh
->sh_addr
= s
->sh_addr
;
2381 sh
->sh_offset
= s
->sh_offset
;
2382 sh
->sh_size
= s
->sh_size
;
2384 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2388 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
2389 const int *sec_order
)
2392 int i
, offset
, size
;
2395 for(i
=1;i
<s1
->nb_sections
;i
++) {
2396 s
= s1
->sections
[sec_order
[i
]];
2397 if (s
->sh_type
!= SHT_NOBITS
&&
2398 (s
->sh_flags
& SHF_ALLOC
)) {
2399 while (offset
< s
->sh_offset
) {
2404 fwrite(s
->data
, 1, size
, f
);
2410 /* Write an elf, coff or "binary" file */
2411 static int tcc_write_elf_file(TCCState
*s1
, const char *filename
, int phnum
,
2412 ElfW(Phdr
) *phdr
, int file_offset
, int *sec_order
)
2414 int fd
, mode
, file_type
;
2417 file_type
= s1
->output_type
;
2418 if (file_type
== TCC_OUTPUT_OBJ
)
2423 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2425 tcc_error_noabort("could not write '%s'", filename
);
2428 f
= fdopen(fd
, "wb");
2430 printf("<- %s\n", filename
);
2432 #ifdef TCC_TARGET_COFF
2433 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
)
2434 tcc_output_coff(s1
, f
);
2437 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2438 tcc_output_elf(s1
, f
, phnum
, phdr
, file_offset
, sec_order
);
2440 tcc_output_binary(s1
, f
, sec_order
);
2446 #ifndef ELF_OBJ_ONLY
2447 /* Sort section headers by assigned sh_addr, remove sections
2448 that we aren't going to output. */
2449 static void tidy_section_headers(TCCState
*s1
, int *sec_order
)
2451 int i
, nnew
, l
, *backmap
;
2455 snew
= tcc_malloc(s1
->nb_sections
* sizeof(snew
[0]));
2456 backmap
= tcc_malloc(s1
->nb_sections
* sizeof(backmap
[0]));
2457 for (i
= 0, nnew
= 0, l
= s1
->nb_sections
; i
< s1
->nb_sections
; i
++) {
2458 s
= s1
->sections
[sec_order
[i
]];
2459 if (!i
|| s
->sh_name
) {
2460 backmap
[sec_order
[i
]] = nnew
;
2464 backmap
[sec_order
[i
]] = 0;
2468 for (i
= 0; i
< nnew
; i
++) {
2472 if (s
->sh_type
== SHT_RELX
)
2473 s
->sh_info
= backmap
[s
->sh_info
];
2477 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
))
2478 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2479 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2480 if ( !s1
->static_link
) {
2481 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
))
2482 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2483 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2485 for (i
= 0; i
< s1
->nb_sections
; i
++)
2487 tcc_free(s1
->sections
);
2488 s1
->sections
= snew
;
2489 s1
->nb_sections
= nnew
;
2493 #ifdef TCC_TARGET_ARM
2494 static void create_arm_attribute_section(TCCState
*s1
)
2496 // Needed for DLL support.
2497 static const unsigned char arm_attr
[] = {
2499 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2500 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2501 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2502 0x05, 0x36, 0x00, // 'CPU_name', "6"
2503 0x06, 0x06, // 'CPU_arch', 'v6'
2504 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2505 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2506 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2507 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2508 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2509 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2510 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2511 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2512 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2513 0x1a, 0x02, // 'ABI_enum_size', 'int'
2514 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2515 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2517 Section
*attr
= new_section(s1
, ".ARM.attributes", SHT_ARM_ATTRIBUTES
, 0);
2518 unsigned char *ptr
= section_ptr_add(attr
, sizeof(arm_attr
));
2519 attr
->sh_addralign
= 1;
2520 memcpy(ptr
, arm_attr
, sizeof(arm_attr
));
2521 if (s1
->float_abi
!= ARM_HARD_FLOAT
) {
2522 ptr
[26] = 0x00; // 'FP_arch', 'No'
2523 ptr
[41] = 0x1e; // 'ABI_optimization_goals'
2524 ptr
[42] = 0x06; // 'Aggressive Debug'
2529 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2530 static Section
*create_bsd_note_section(TCCState
*s1
,
2534 Section
*s
= find_section (s1
, name
);
2536 if (s
->data_offset
== 0) {
2537 char *ptr
= section_ptr_add(s
, sizeof(ElfW(Nhdr
)) + 8 + 4);
2538 ElfW(Nhdr
) *note
= (ElfW(Nhdr
) *) ptr
;
2540 s
->sh_type
= SHT_NOTE
;
2543 note
->n_type
= ELF_NOTE_OS_GNU
;
2544 strcpy (ptr
+ sizeof(ElfW(Nhdr
)), value
);
2550 /* Output an elf, coff or binary file */
2551 /* XXX: suppress unneeded sections */
2552 static int elf_output_file(TCCState
*s1
, const char *filename
)
2554 int i
, ret
, phnum
, phfill
, shnum
, file_type
, file_offset
, *sec_order
;
2555 struct dyn_inf dyninf
= {0};
2556 struct ro_inf roinf
;
2558 Section
*interp
, *dynamic
, *dynstr
, *note
;
2559 struct ro_inf
*roinf_use
= NULL
;
2562 file_type
= s1
->output_type
;
2567 interp
= dynamic
= dynstr
= note
= NULL
;
2569 #ifdef TCC_TARGET_ARM
2570 create_arm_attribute_section (s1
);
2573 #if TARGETOS_OpenBSD
2574 note
= create_bsd_note_section (s1
, ".note.openbsd.ident", "OpenBSD");
2578 note
= create_bsd_note_section (s1
, ".note.netbsd.ident", "NetBSD");
2582 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2583 tcc_add_runtime(s1
);
2584 resolve_common_syms(s1
);
2586 if (!s1
->static_link
) {
2587 if (file_type
== TCC_OUTPUT_EXE
) {
2589 /* allow override the dynamic loader */
2590 const char *elfint
= getenv("LD_SO");
2592 elfint
= DEFAULT_ELFINTERP(s1
);
2593 /* add interpreter section only if executable */
2594 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
2595 interp
->sh_addralign
= 1;
2596 ptr
= section_ptr_add(interp
, 1 + strlen(elfint
));
2597 strcpy(ptr
, elfint
);
2600 /* add dynamic symbol table */
2601 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
2603 ".hash", SHF_ALLOC
);
2604 /* Number of local symbols (readelf complains if not set) */
2605 s1
->dynsym
->sh_info
= 1;
2606 dynstr
= s1
->dynsym
->link
;
2607 /* add dynamic section */
2608 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
2609 SHF_ALLOC
| SHF_WRITE
);
2610 dynamic
->link
= dynstr
;
2611 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
2615 if (file_type
== TCC_OUTPUT_EXE
) {
2616 bind_exe_dynsyms(s1
);
2619 bind_libs_dynsyms(s1
);
2621 /* shared library case: simply export all global symbols */
2622 export_global_syms(s1
);
2625 build_got_entries(s1
);
2629 textrel
= set_sec_sizes(s1
);
2630 alloc_sec_names(s1
, 0);
2632 if (!s1
->static_link
) {
2634 /* add a list of needed dlls */
2635 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2636 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
2637 if (dllref
->level
== 0)
2638 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
2642 put_dt(dynamic
, s1
->enable_new_dtags
? DT_RUNPATH
: DT_RPATH
,
2643 put_elf_str(dynstr
, s1
->rpath
));
2645 if (file_type
== TCC_OUTPUT_DLL
) {
2647 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
2648 /* XXX: currently, since we do not handle PIC code, we
2649 must relocate the readonly segments */
2651 put_dt(dynamic
, DT_TEXTREL
, 0);
2655 put_dt(dynamic
, DT_SYMBOLIC
, 0);
2657 dyninf
.dynamic
= dynamic
;
2658 dyninf
.dynstr
= dynstr
;
2659 /* remember offset and reserve space for 2nd call below */
2660 dyninf
.data_offset
= dynamic
->data_offset
;
2661 fill_dynamic(s1
, &dyninf
);
2662 dynamic
->sh_size
= dynamic
->data_offset
;
2663 dynstr
->sh_size
= dynstr
->data_offset
;
2666 for (i
= 1; i
< s1
->nb_sections
&&
2667 !(s1
->sections
[i
]->sh_flags
& SHF_TLS
); i
++);
2668 phfill
= 2 + (i
< s1
->nb_sections
);
2670 /* compute number of program headers */
2671 if (file_type
== TCC_OUTPUT_DLL
)
2673 else if (s1
->static_link
)
2676 phnum
= 5 + (i
< s1
->nb_sections
);
2679 phnum
+= note
!= NULL
;
2680 #if !TARGETOS_FreeBSD && !TARGETOS_NetBSD
2682 phnum
++, roinf_use
= &roinf
;
2685 /* allocate program segment headers */
2686 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
2687 /* compute number of sections */
2688 shnum
= s1
->nb_sections
;
2689 /* this array is used to reorder sections in the output file */
2690 sec_order
= tcc_malloc(sizeof(int) * shnum
);
2693 /* compute section to program header mapping */
2694 file_offset
= layout_sections(s1
, phdr
, phnum
, phfill
, interp
, &roinf
, sec_order
+ 1);
2696 /* Fill remaining program header and finalize relocation related to dynamic
2699 fill_unloadable_phdr(phdr
, phnum
, interp
, dynamic
, note
, roinf_use
);
2703 /* put in GOT the dynamic section address and relocate PLT */
2704 write32le(s1
->got
->data
, dynamic
->sh_addr
);
2705 if (file_type
== TCC_OUTPUT_EXE
2706 || (RELOCATE_DLLPLT
&& file_type
== TCC_OUTPUT_DLL
))
2709 /* relocate symbols in .dynsym now that final addresses are known */
2710 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
)) {
2711 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
) {
2712 /* do symbol relocation */
2713 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
2718 /* if building executable or DLL, then relocate each section
2719 except the GOT which is already relocated */
2720 relocate_syms(s1
, s1
->symtab
, 0);
2722 if (s1
->nb_errors
!= 0)
2724 relocate_sections(s1
);
2726 update_reloc_sections (s1
, &dyninf
);
2727 dynamic
->data_offset
= dyninf
.data_offset
;
2728 fill_dynamic(s1
, &dyninf
);
2730 tidy_section_headers(s1
, sec_order
);
2732 /* Perform relocation to GOT or PLT entries */
2733 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2736 fill_local_got_entries(s1
);
2738 /* Create the ELF file with name 'filename' */
2739 ret
= tcc_write_elf_file(s1
, filename
, phnum
, phdr
, file_offset
, sec_order
);
2740 s1
->nb_sections
= shnum
;
2743 tcc_free(sec_order
);
2747 #endif /* ndef ELF_OBJ_ONLY */
2749 /* Allocate strings for section names */
2750 static void alloc_sec_names(TCCState
*s1
, int is_obj
)
2753 Section
*s
, *strsec
;
2755 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
2756 put_elf_str(strsec
, "");
2757 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2758 s
= s1
->sections
[i
];
2760 s
->sh_size
= s
->data_offset
;
2761 if (s
== strsec
|| s
->sh_size
|| (s
->sh_flags
& SHF_ALLOC
))
2762 s
->sh_name
= put_elf_str(strsec
, s
->name
);
2764 strsec
->sh_size
= strsec
->data_offset
;
2767 static int layout_any_sections(TCCState
*s1
, int file_offset
, int *sec_order
, int is_obj
)
2771 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2772 s
= s1
->sections
[i
];
2773 if (!is_obj
&& (s
->sh_flags
& SHF_ALLOC
))
2776 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
2777 ~(s
->sh_addralign
- 1);
2778 s
->sh_offset
= file_offset
;
2779 if (s
->sh_type
!= SHT_NOBITS
)
2780 file_offset
+= s
->sh_size
;
2785 /* Output an elf .o file */
2786 static int elf_output_obj(TCCState
*s1
, const char *filename
)
2788 int ret
, file_offset
;
2792 /* Allocate strings for section names */
2793 alloc_sec_names(s1
, 1);
2795 /* this array is used to reorder sections in the output file */
2796 sec_order
= tcc_malloc(sizeof(int) * s1
->nb_sections
);
2798 file_offset
= layout_any_sections(s1
, sizeof (ElfW(Ehdr
)), sec_order
+ 1, 1);
2800 /* Create the ELF file with name 'filename' */
2801 ret
= tcc_write_elf_file(s1
, filename
, 0, NULL
, file_offset
, sec_order
);
2802 tcc_free(sec_order
);
2806 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2808 if (s
->test_coverage
)
2809 tcc_tcov_add_file(s
, filename
);
2810 if (s
->output_type
== TCC_OUTPUT_OBJ
)
2811 return elf_output_obj(s
, filename
);
2812 #ifdef TCC_TARGET_PE
2813 return pe_output_file(s
, filename
);
2814 #elif TCC_TARGET_MACHO
2815 return macho_output_file(s
, filename
);
2817 return elf_output_file(s
, filename
);
2821 ST_FUNC ssize_t
full_read(int fd
, void *buf
, size_t count
) {
2825 ssize_t num
= read(fd
, cbuf
, count
-rnum
);
2826 if (num
< 0) return num
;
2827 if (num
== 0) return rnum
;
2833 ST_FUNC
void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2837 data
= tcc_malloc(size
);
2838 lseek(fd
, file_offset
, SEEK_SET
);
2839 full_read(fd
, data
, size
);
2843 typedef struct SectionMergeInfo
{
2844 Section
*s
; /* corresponding existing section */
2845 unsigned long offset
; /* offset of the new section in the existing section */
2846 uint8_t new_section
; /* true if section 's' was added */
2847 uint8_t link_once
; /* true if link once section */
2850 ST_FUNC
int tcc_object_type(int fd
, ElfW(Ehdr
) *h
)
2852 int size
= full_read(fd
, h
, sizeof *h
);
2853 if (size
== sizeof *h
&& 0 == memcmp(h
, ELFMAG
, 4)) {
2854 if (h
->e_type
== ET_REL
)
2855 return AFF_BINTYPE_REL
;
2856 if (h
->e_type
== ET_DYN
)
2857 return AFF_BINTYPE_DYN
;
2858 } else if (size
>= 8) {
2859 if (0 == memcmp(h
, ARMAG
, 8))
2860 return AFF_BINTYPE_AR
;
2861 #ifdef TCC_TARGET_COFF
2862 if (((struct filehdr
*)h
)->f_magic
== COFF_C67_MAGIC
)
2863 return AFF_BINTYPE_C67
;
2869 /* load an object file and merge it with current files */
2870 /* XXX: handle correctly stab (debug) info */
2871 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
2872 int fd
, unsigned long file_offset
)
2875 ElfW(Shdr
) *shdr
, *sh
;
2876 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
, seencompressed
;
2877 char *strsec
, *strtab
;
2878 int stab_index
, stabstr_index
;
2879 int *old_to_new_syms
;
2880 char *sh_name
, *name
;
2881 SectionMergeInfo
*sm_table
, *sm
;
2882 ElfW(Sym
) *sym
, *symtab
;
2886 lseek(fd
, file_offset
, SEEK_SET
);
2887 if (tcc_object_type(fd
, &ehdr
) != AFF_BINTYPE_REL
)
2889 /* test CPU specific stuff */
2890 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2891 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2893 tcc_error_noabort("invalid object file");
2897 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2898 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2899 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2901 /* load section names */
2902 sh
= &shdr
[ehdr
.e_shstrndx
];
2903 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2905 /* load symtab and strtab */
2906 old_to_new_syms
= NULL
;
2911 stab_index
= stabstr_index
= 0;
2913 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2915 if (sh
->sh_type
== SHT_SYMTAB
) {
2917 tcc_error_noabort("object must contain only one symtab");
2922 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2923 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2924 sm_table
[i
].s
= symtab_section
;
2926 /* now load strtab */
2927 sh
= &shdr
[sh
->sh_link
];
2928 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2930 if (sh
->sh_flags
& SHF_COMPRESSED
)
2934 /* now examine each section and try to merge its content with the
2936 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2937 /* no need to examine section name strtab */
2938 if (i
== ehdr
.e_shstrndx
)
2941 if (sh
->sh_type
== SHT_RELX
)
2942 sh
= &shdr
[sh
->sh_info
];
2943 /* ignore sections types we do not handle (plus relocs to those) */
2944 if (sh
->sh_type
!= SHT_PROGBITS
&&
2946 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2948 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2949 sh
->sh_type
!= SHT_X86_64_UNWIND
&&
2951 sh
->sh_type
!= SHT_NOTE
&&
2952 sh
->sh_type
!= SHT_NOBITS
&&
2953 sh
->sh_type
!= SHT_PREINIT_ARRAY
&&
2954 sh
->sh_type
!= SHT_INIT_ARRAY
&&
2955 sh
->sh_type
!= SHT_FINI_ARRAY
&&
2956 strcmp(strsec
+ sh
->sh_name
, ".stabstr")
2960 && !strncmp(strsec
+ sh
->sh_name
, ".debug_", sizeof(".debug_")-1))
2964 sh_name
= strsec
+ sh
->sh_name
;
2965 if (sh
->sh_addralign
< 1)
2966 sh
->sh_addralign
= 1;
2967 /* find corresponding section, if any */
2968 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2969 s
= s1
->sections
[j
];
2970 if (!strcmp(s
->name
, sh_name
)) {
2971 if (!strncmp(sh_name
, ".gnu.linkonce",
2972 sizeof(".gnu.linkonce") - 1)) {
2973 /* if a 'linkonce' section is already present, we
2974 do not add it again. It is a little tricky as
2975 symbols can still be defined in
2977 sm_table
[i
].link_once
= 1;
2981 if (s
== stab_section
)
2983 if (s
== stab_section
->link
)
2989 /* not found: create new section */
2990 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
& ~SHF_GROUP
);
2991 /* take as much info as possible from the section. sh_link and
2992 sh_info will be updated later */
2993 s
->sh_addralign
= sh
->sh_addralign
;
2994 s
->sh_entsize
= sh
->sh_entsize
;
2995 sm_table
[i
].new_section
= 1;
2997 if (sh
->sh_type
!= s
->sh_type
) {
2998 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2999 if (strcmp (s
->name
, ".eh_frame"))
3002 tcc_error_noabort("invalid section type");
3006 /* align start of section */
3007 s
->data_offset
+= -s
->data_offset
& (sh
->sh_addralign
- 1);
3008 if (sh
->sh_addralign
> s
->sh_addralign
)
3009 s
->sh_addralign
= sh
->sh_addralign
;
3010 sm_table
[i
].offset
= s
->data_offset
;
3012 /* concatenate sections */
3014 if (sh
->sh_type
!= SHT_NOBITS
) {
3016 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
3017 ptr
= section_ptr_add(s
, size
);
3018 full_read(fd
, ptr
, size
);
3020 s
->data_offset
+= size
;
3025 /* gr relocate stab strings */
3026 if (stab_index
&& stabstr_index
) {
3029 s
= sm_table
[stab_index
].s
;
3030 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
3031 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
3032 o
= sm_table
[stabstr_index
].offset
;
3040 /* second short pass to update sh_link and sh_info fields of new
3042 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3044 if (!s
|| !sm_table
[i
].new_section
)
3047 if (sh
->sh_link
> 0)
3048 s
->link
= sm_table
[sh
->sh_link
].s
;
3049 if (sh
->sh_type
== SHT_RELX
) {
3050 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
3051 /* update backward link */
3052 s1
->sections
[s
->sh_info
]->reloc
= s
;
3056 /* resolve symbols */
3057 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
3060 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
3061 if (sym
->st_shndx
!= SHN_UNDEF
&&
3062 sym
->st_shndx
< SHN_LORESERVE
) {
3063 sm
= &sm_table
[sym
->st_shndx
];
3064 if (sm
->link_once
) {
3065 /* if a symbol is in a link once section, we use the
3066 already defined symbol. It is very important to get
3067 correct relocations */
3068 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
3069 name
= strtab
+ sym
->st_name
;
3070 sym_index
= find_elf_sym(symtab_section
, name
);
3072 old_to_new_syms
[i
] = sym_index
;
3076 /* if no corresponding section added, no need to add symbol */
3079 /* convert section number */
3080 sym
->st_shndx
= sm
->s
->sh_num
;
3082 sym
->st_value
+= sm
->offset
;
3085 name
= strtab
+ sym
->st_name
;
3086 sym_index
= set_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
3087 sym
->st_info
, sym
->st_other
,
3088 sym
->st_shndx
, name
);
3089 old_to_new_syms
[i
] = sym_index
;
3092 /* third pass to patch relocation entries */
3093 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3098 offset
= sm_table
[i
].offset
;
3100 switch(s
->sh_type
) {
3102 /* take relocation offset information */
3103 offseti
= sm_table
[sh
->sh_info
].offset
;
3104 for (rel
= (ElfW_Rel
*) s
->data
+ (offset
/ sizeof(*rel
));
3105 rel
< (ElfW_Rel
*) s
->data
+ ((offset
+ size
) / sizeof(*rel
));
3109 /* convert symbol index */
3110 type
= ELFW(R_TYPE
)(rel
->r_info
);
3111 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
3112 /* NOTE: only one symtab assumed */
3113 if (sym_index
>= nb_syms
)
3115 sym_index
= old_to_new_syms
[sym_index
];
3116 /* ignore link_once in rel section. */
3117 if (!sym_index
&& !sm_table
[sh
->sh_info
].link_once
3118 #ifdef TCC_TARGET_ARM
3119 && type
!= R_ARM_V4BX
3120 #elif defined TCC_TARGET_RISCV64
3121 && type
!= R_RISCV_ALIGN
3122 && type
!= R_RISCV_RELAX
3126 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3127 i
, strsec
+ sh
->sh_name
, (int)rel
->r_offset
);
3130 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
3131 /* offset the relocation offset */
3132 rel
->r_offset
+= offseti
;
3133 #ifdef TCC_TARGET_ARM
3134 /* Jumps and branches from a Thumb code to a PLT entry need
3135 special handling since PLT entries are ARM code.
3136 Unconditional bl instructions referencing PLT entries are
3137 handled by converting these instructions into blx
3138 instructions. Other case of instructions referencing a PLT
3139 entry require to add a Thumb stub before the PLT entry to
3140 switch to ARM mode. We set bit plt_thumb_stub of the
3141 attribute of a symbol to indicate such a case. */
3142 if (type
== R_ARM_THM_JUMP24
)
3143 get_sym_attr(s1
, sym_index
, 1)->plt_thumb_stub
= 1;
3156 tcc_free(old_to_new_syms
);
3163 typedef struct ArchiveHeader
{
3164 char ar_name
[16]; /* name of this member */
3165 char ar_date
[12]; /* file mtime */
3166 char ar_uid
[6]; /* owner uid; printed as decimal */
3167 char ar_gid
[6]; /* owner gid; printed as decimal */
3168 char ar_mode
[8]; /* file mode, printed as octal */
3169 char ar_size
[10]; /* file size, printed as decimal */
3170 char ar_fmag
[2]; /* should contain ARFMAG */
3173 #define ARFMAG "`\n"
3175 static unsigned long long get_be(const uint8_t *b
, int n
)
3177 unsigned long long ret
= 0;
3179 ret
= (ret
<< 8) | *b
++, --n
;
3183 static int read_ar_header(int fd
, int offset
, ArchiveHeader
*hdr
)
3187 lseek(fd
, offset
, SEEK_SET
);
3188 len
= full_read(fd
, hdr
, sizeof(ArchiveHeader
));
3189 if (len
!= sizeof(ArchiveHeader
))
3190 return len
? -1 : 0;
3192 for (e
= p
+ sizeof hdr
->ar_name
; e
> p
&& e
[-1] == ' ';)
3195 hdr
->ar_size
[sizeof hdr
->ar_size
-1] = 0;
3199 /* load only the objects which resolve undefined symbols */
3200 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
, int entrysize
)
3202 int i
, bound
, nsyms
, sym_index
, len
, ret
= -1;
3203 unsigned long long off
;
3205 const char *ar_names
, *p
;
3206 const uint8_t *ar_index
;
3210 data
= tcc_malloc(size
);
3211 if (full_read(fd
, data
, size
) != size
)
3213 nsyms
= get_be(data
, entrysize
);
3214 ar_index
= data
+ entrysize
;
3215 ar_names
= (char *) ar_index
+ nsyms
* entrysize
;
3219 for (p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
3220 Section
*s
= symtab_section
;
3221 sym_index
= find_elf_sym(s
, p
);
3224 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
3225 if(sym
->st_shndx
!= SHN_UNDEF
)
3227 off
= get_be(ar_index
+ i
* entrysize
, entrysize
);
3228 len
= read_ar_header(fd
, off
, &hdr
);
3229 if (len
<= 0 || memcmp(hdr
.ar_fmag
, ARFMAG
, 2)) {
3230 tcc_error_noabort("invalid archive");
3234 if (s1
->verbose
== 2)
3235 printf(" -> %s\n", hdr
.ar_name
);
3236 if (tcc_load_object_file(s1
, fd
, off
) < 0)
3247 /* load a '.a' file */
3248 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
, int alacarte
)
3251 /* char magic[8]; */
3253 unsigned long file_offset
;
3256 /* skip magic which was already checked */
3257 /* full_read(fd, magic, sizeof(magic)); */
3258 file_offset
= sizeof ARMAG
- 1;
3261 len
= read_ar_header(fd
, file_offset
, &hdr
);
3265 tcc_error_noabort("invalid archive");
3269 size
= strtol(hdr
.ar_size
, NULL
, 0);
3271 size
= (size
+ 1) & ~1;
3273 /* coff symbol table : we handle it */
3274 if (!strcmp(hdr
.ar_name
, "/"))
3275 return tcc_load_alacarte(s1
, fd
, size
, 4);
3276 if (!strcmp(hdr
.ar_name
, "/SYM64/"))
3277 return tcc_load_alacarte(s1
, fd
, size
, 8);
3278 } else if (tcc_object_type(fd
, &ehdr
) == AFF_BINTYPE_REL
) {
3279 if (s1
->verbose
== 2)
3280 printf(" -> %s\n", hdr
.ar_name
);
3281 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
3284 file_offset
+= size
;
3288 #ifndef ELF_OBJ_ONLY
3289 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3290 LV, maybe create a new entry for (LIB,VERSION). */
3291 static void set_ver_to_ver(TCCState
*s1
, int *n
, int **lv
, int i
, char *lib
, char *version
)
3294 *lv
= tcc_realloc(*lv
, (*n
+ 1) * sizeof(**lv
));
3297 if ((*lv
)[i
] == -1) {
3298 int v
, prev_same_lib
= -1;
3299 for (v
= 0; v
< nb_sym_versions
; v
++) {
3300 if (strcmp(sym_versions
[v
].lib
, lib
))
3303 if (!strcmp(sym_versions
[v
].version
, version
))
3306 if (v
== nb_sym_versions
) {
3307 sym_versions
= tcc_realloc (sym_versions
,
3308 (v
+ 1) * sizeof(*sym_versions
));
3309 sym_versions
[v
].lib
= tcc_strdup(lib
);
3310 sym_versions
[v
].version
= tcc_strdup(version
);
3311 sym_versions
[v
].out_index
= 0;
3312 sym_versions
[v
].prev_same_lib
= prev_same_lib
;
3319 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3322 set_sym_version(TCCState
*s1
, int sym_index
, int verndx
)
3324 if (sym_index
>= nb_sym_to_version
) {
3325 int newelems
= sym_index
? sym_index
* 2 : 1;
3326 sym_to_version
= tcc_realloc(sym_to_version
,
3327 newelems
* sizeof(*sym_to_version
));
3328 memset(sym_to_version
+ nb_sym_to_version
, -1,
3329 (newelems
- nb_sym_to_version
) * sizeof(*sym_to_version
));
3330 nb_sym_to_version
= newelems
;
3332 if (sym_to_version
[sym_index
] < 0)
3333 sym_to_version
[sym_index
] = verndx
;
3336 struct versym_info
{
3338 ElfW(Verdef
) *verdef
;
3339 ElfW(Verneed
) *verneed
;
3341 int nb_local_ver
, *local_ver
;
3345 static void store_version(TCCState
*s1
, struct versym_info
*v
, char *dynstr
)
3347 char *lib
, *version
;
3351 #define DEBUG_VERSION 0
3353 if (v
->versym
&& v
->verdef
) {
3354 ElfW(Verdef
) *vdef
= v
->verdef
;
3357 ElfW(Verdaux
) *verdaux
=
3358 (ElfW(Verdaux
) *) (((char *) vdef
) + vdef
->vd_aux
);
3361 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3362 vdef
->vd_version
, vdef
->vd_flags
, vdef
->vd_ndx
,
3366 version
= dynstr
+ verdaux
->vda_name
;
3371 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vdef
->vd_ndx
,
3374 printf (" verdaux(%u): %s\n", vdef
->vd_ndx
, version
);
3377 next
= vdef
->vd_next
;
3378 vdef
= (ElfW(Verdef
) *) (((char *) vdef
) + next
);
3381 if (v
->versym
&& v
->verneed
) {
3382 ElfW(Verneed
) *vneed
= v
->verneed
;
3384 ElfW(Vernaux
) *vernaux
=
3385 (ElfW(Vernaux
) *) (((char *) vneed
) + vneed
->vn_aux
);
3387 lib
= dynstr
+ vneed
->vn_file
;
3389 printf ("verneed: %u %s\n", vneed
->vn_version
, lib
);
3391 for (i
= 0; i
< vneed
->vn_cnt
; i
++) {
3392 if ((vernaux
->vna_other
& 0x8000) == 0) { /* hidden */
3393 version
= dynstr
+ vernaux
->vna_name
;
3394 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vernaux
->vna_other
,
3397 printf (" vernaux(%u): %u %u %s\n",
3398 vernaux
->vna_other
, vernaux
->vna_hash
,
3399 vernaux
->vna_flags
, version
);
3402 vernaux
= (ElfW(Vernaux
) *) (((char *) vernaux
) + vernaux
->vna_next
);
3404 next
= vneed
->vn_next
;
3405 vneed
= (ElfW(Verneed
) *) (((char *) vneed
) + next
);
3410 for (i
= 0; i
< v
->nb_local_ver
; i
++) {
3411 if (v
->local_ver
[i
] > 0) {
3412 printf ("%d: lib: %s, version %s\n",
3413 i
, sym_versions
[v
->local_ver
[i
]].lib
,
3414 sym_versions
[v
->local_ver
[i
]].version
);
3420 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3421 is referenced by the user (so it should be added as DT_NEEDED in
3422 the generated ELF file) */
3423 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
3426 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
3427 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
3428 ElfW(Sym
) *sym
, *dynsym
;
3429 ElfW(Dyn
) *dt
, *dynamic
;
3433 const char *name
, *soname
;
3434 DLLReference
*dllref
;
3435 struct versym_info v
;
3437 full_read(fd
, &ehdr
, sizeof(ehdr
));
3439 /* test CPU specific stuff */
3440 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
3441 ehdr
.e_machine
!= EM_TCC_TARGET
) {
3442 tcc_error_noabort("bad architecture");
3447 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
3449 /* load dynamic section and dynamic symbols */
3453 dynsym
= NULL
; /* avoid warning */
3454 dynstr
= NULL
; /* avoid warning */
3455 memset(&v
, 0, sizeof v
);
3457 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
3458 switch(sh
->sh_type
) {
3460 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
3461 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3464 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
3465 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3466 sh1
= &shdr
[sh
->sh_link
];
3467 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
3469 case SHT_GNU_verdef
:
3470 v
.verdef
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3472 case SHT_GNU_verneed
:
3473 v
.verneed
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3475 case SHT_GNU_versym
:
3476 v
.nb_versyms
= sh
->sh_size
/ sizeof(ElfW(Half
));
3477 v
.versym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3484 /* compute the real library name */
3485 soname
= tcc_basename(filename
);
3487 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3488 if (dt
->d_tag
== DT_SONAME
) {
3489 soname
= dynstr
+ dt
->d_un
.d_val
;
3493 /* if the dll is already loaded, do not load it */
3494 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
3495 dllref
= s1
->loaded_dlls
[i
];
3496 if (!strcmp(soname
, dllref
->name
)) {
3497 /* but update level if needed */
3498 if (level
< dllref
->level
)
3499 dllref
->level
= level
;
3505 if (v
.nb_versyms
!= nb_syms
)
3506 tcc_free (v
.versym
), v
.versym
= NULL
;
3508 store_version(s1
, &v
, dynstr
);
3510 /* add the dll and its level */
3511 tcc_add_dllref(s1
, soname
)->level
= level
;
3513 /* add dynamic symbols in dynsym_section */
3514 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
3515 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
3516 if (sym_bind
== STB_LOCAL
)
3518 name
= dynstr
+ sym
->st_name
;
3519 sym_index
= set_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
3520 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
3522 ElfW(Half
) vsym
= v
.versym
[i
];
3523 if ((vsym
& 0x8000) == 0 && vsym
> 0 && vsym
< v
.nb_local_ver
)
3524 set_sym_version(s1
, sym_index
, v
.local_ver
[vsym
]);
3528 /* load all referenced DLLs */
3529 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3532 name
= dynstr
+ dt
->d_un
.d_val
;
3533 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
3534 dllref
= s1
->loaded_dlls
[j
];
3535 if (!strcmp(name
, dllref
->name
))
3536 goto already_loaded
;
3538 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
3539 tcc_error_noabort("referenced dll '%s' not found", name
);
3553 tcc_free(v
.local_ver
);
3555 tcc_free(v
.verneed
);
3560 #define LD_TOK_NAME 256
3561 #define LD_TOK_EOF (-1)
3563 static int ld_inp(TCCState
*s1
)
3571 if (1 == read(s1
->fd
, &b
, 1))
3576 /* return next ld script token */
3577 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
3594 if (ch
== '*') { /* comment */
3595 for (d
= 0;; d
= ch
) {
3597 if (ch
== CH_EOF
|| (ch
== '/' && d
== '*'))
3608 /* case 'a' ... 'z': */
3635 /* case 'A' ... 'z': */
3669 if (!((ch
>= 'a' && ch
<= 'z') ||
3670 (ch
>= 'A' && ch
<= 'Z') ||
3671 (ch
>= '0' && ch
<= '9') ||
3672 strchr("/.-_+=$:\\,~", ch
)))
3674 if ((q
- name
) < name_size
- 1) {
3693 static int ld_add_file(TCCState
*s1
, const char filename
[])
3695 if (filename
[0] == '/') {
3696 if (CONFIG_SYSROOT
[0] == '\0'
3697 && tcc_add_file_internal(s1
, filename
, AFF_TYPE_BIN
) == 0)
3699 filename
= tcc_basename(filename
);
3701 return tcc_add_dll(s1
, filename
, 0);
3704 static int ld_add_file_list(TCCState
*s1
, const char *cmd
, int as_needed
)
3706 char filename
[1024], libname
[1024];
3707 int t
, group
, nblibs
= 0, ret
= 0;
3710 group
= !strcmp(cmd
, "GROUP");
3712 s1
->new_undef_sym
= 0;
3713 t
= ld_next(s1
, filename
, sizeof(filename
));
3715 tcc_error_noabort("( expected");
3717 goto lib_parse_error
;
3719 t
= ld_next(s1
, filename
, sizeof(filename
));
3722 if (t
== LD_TOK_EOF
) {
3723 tcc_error_noabort("unexpected end of file");
3725 goto lib_parse_error
;
3726 } else if (t
== ')') {
3728 } else if (t
== '-') {
3729 t
= ld_next(s1
, filename
, sizeof(filename
));
3730 if ((t
!= LD_TOK_NAME
) || (filename
[0] != 'l')) {
3731 tcc_error_noabort("library name expected");
3733 goto lib_parse_error
;
3735 pstrcpy(libname
, sizeof libname
, &filename
[1]);
3736 if (s1
->static_link
) {
3737 snprintf(filename
, sizeof filename
, "lib%s.a", libname
);
3739 snprintf(filename
, sizeof filename
, "lib%s.so", libname
);
3741 } else if (t
!= LD_TOK_NAME
) {
3742 tcc_error_noabort("filename expected");
3744 goto lib_parse_error
;
3746 if (!strcmp(filename
, "AS_NEEDED")) {
3747 ret
= ld_add_file_list(s1
, cmd
, 1);
3749 goto lib_parse_error
;
3751 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3753 ret
= ld_add_file(s1
, filename
);
3755 goto lib_parse_error
;
3757 /* Add the filename *and* the libname to avoid future conversions */
3758 dynarray_add(&libs
, &nblibs
, tcc_strdup(filename
));
3759 if (libname
[0] != '\0')
3760 dynarray_add(&libs
, &nblibs
, tcc_strdup(libname
));
3764 t
= ld_next(s1
, filename
, sizeof(filename
));
3766 t
= ld_next(s1
, filename
, sizeof(filename
));
3769 if (group
&& !as_needed
) {
3770 while (s1
->new_undef_sym
) {
3772 s1
->new_undef_sym
= 0;
3773 for (i
= 0; i
< nblibs
; i
++)
3774 ld_add_file(s1
, libs
[i
]);
3778 dynarray_reset(&libs
, &nblibs
);
3782 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3784 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
, int fd
)
3787 char filename
[1024];
3793 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3794 if (t
== LD_TOK_EOF
)
3796 else if (t
!= LD_TOK_NAME
)
3798 if (!strcmp(cmd
, "INPUT") ||
3799 !strcmp(cmd
, "GROUP")) {
3800 ret
= ld_add_file_list(s1
, cmd
, 0);
3803 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
3804 !strcmp(cmd
, "TARGET")) {
3805 /* ignore some commands */
3806 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3808 tcc_error_noabort("( expected");
3812 t
= ld_next(s1
, filename
, sizeof(filename
));
3813 if (t
== LD_TOK_EOF
) {
3814 tcc_error_noabort("unexpected end of file");
3816 } else if (t
== ')') {
3826 #endif /* !ELF_OBJ_ONLY */