2 * ELF file handling for TCC
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 /* Define this to get some debug output during relocation processing. */
26 /********************************************************/
27 /* global variables */
29 /* elf version information */
37 #define nb_sym_versions s1->nb_sym_versions
38 #define sym_versions s1->sym_versions
39 #define nb_sym_to_version s1->nb_sym_to_version
40 #define sym_to_version s1->sym_to_version
41 #define dt_verneednum s1->dt_verneednum
42 #define versym_section s1->versym_section
43 #define verneed_section s1->verneed_section
45 /* special flag to indicate that the section should not be linked to the other ones */
46 #define SHF_PRIVATE 0x80000000
47 /* section is dynsymtab_section */
48 #define SHF_DYNSYM 0x40000000
51 static const int shf_RELRO
= SHF_ALLOC
;
52 static const char rdata
[] = ".rdata";
54 static const int shf_RELRO
= SHF_ALLOC
| SHF_WRITE
;
55 static const char rdata
[] = ".data.ro";
58 /* ------------------------------------------------------------------------- */
60 ST_FUNC
void tccelf_new(TCCState
*s
)
64 dynarray_add(&s
->sections
, &s
->nb_sections
, NULL
);
66 /* create standard sections */
67 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
68 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
69 /* create ro data section (make ro after relocation done with GNU_RELRO) */
70 rodata_section
= new_section(s
, rdata
, SHT_PROGBITS
, shf_RELRO
);
71 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
72 common_section
= new_section(s
, ".common", SHT_NOBITS
, SHF_PRIVATE
);
73 common_section
->sh_num
= SHN_COMMON
;
75 /* symbols are always generated for linking stage */
76 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
78 ".hashtab", SHF_PRIVATE
);
79 s
->symtab
= symtab_section
;
81 /* private symbol table for dynamic symbols */
82 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
|SHF_DYNSYM
,
84 ".dynhashtab", SHF_PRIVATE
);
85 get_sym_attr(s
, 0, 1);
88 #ifdef CONFIG_TCC_BCHECK
89 ST_FUNC
void tccelf_bounds_new(TCCState
*s
)
92 /* create bounds sections (make ro after relocation done with GNU_RELRO) */
93 bounds_section
= new_section(s
, ".bounds", SHT_PROGBITS
, shf_RELRO
);
94 lbounds_section
= new_section(s
, ".lbounds", SHT_PROGBITS
, shf_RELRO
);
98 static void free_section(Section
*s
)
103 ST_FUNC
void tccelf_delete(TCCState
*s1
)
108 /* free symbol versions */
109 for (i
= 0; i
< nb_sym_versions
; i
++) {
110 tcc_free(sym_versions
[i
].version
);
111 tcc_free(sym_versions
[i
].lib
);
113 tcc_free(sym_versions
);
114 tcc_free(sym_to_version
);
117 /* free all sections */
118 for(i
= 1; i
< s1
->nb_sections
; i
++)
119 free_section(s1
->sections
[i
]);
120 dynarray_reset(&s1
->sections
, &s1
->nb_sections
);
122 for(i
= 0; i
< s1
->nb_priv_sections
; i
++)
123 free_section(s1
->priv_sections
[i
]);
124 dynarray_reset(&s1
->priv_sections
, &s1
->nb_priv_sections
);
126 /* free any loaded DLLs */
128 for ( i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
129 DLLReference
*ref
= s1
->loaded_dlls
[i
];
132 FreeLibrary((HMODULE
)ref
->handle
);
134 dlclose(ref
->handle
);
138 /* free loaded dlls array */
139 dynarray_reset(&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
);
140 tcc_free(s1
->sym_attrs
);
142 symtab_section
= NULL
; /* for tccrun.c:rt_printline() */
145 /* save section data state */
146 ST_FUNC
void tccelf_begin_file(TCCState
*s1
)
149 for (i
= 1; i
< s1
->nb_sections
; i
++) {
151 s
->sh_offset
= s
->data_offset
;
153 /* disable symbol hashing during compilation */
154 s
= s1
->symtab
, s
->reloc
= s
->hash
, s
->hash
= NULL
;
155 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
160 /* At the end of compilation, convert any UNDEF syms to global, and merge
161 with previously existing symbols */
162 ST_FUNC
void tccelf_end_file(TCCState
*s1
)
164 Section
*s
= s1
->symtab
;
165 int first_sym
, nb_syms
, *tr
, i
;
167 first_sym
= s
->sh_offset
/ sizeof (ElfSym
);
168 nb_syms
= s
->data_offset
/ sizeof (ElfSym
) - first_sym
;
169 s
->data_offset
= s
->sh_offset
;
170 s
->link
->data_offset
= s
->link
->sh_offset
;
171 s
->hash
= s
->reloc
, s
->reloc
= NULL
;
172 tr
= tcc_mallocz(nb_syms
* sizeof *tr
);
174 for (i
= 0; i
< nb_syms
; ++i
) {
175 ElfSym
*sym
= (ElfSym
*)s
->data
+ first_sym
+ i
;
176 if (sym
->st_shndx
== SHN_UNDEF
177 && ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
)
178 sym
->st_info
= ELFW(ST_INFO
)(STB_GLOBAL
, ELFW(ST_TYPE
)(sym
->st_info
));
179 /* An ELF relocatable file should have the types of its undefined global symbol set
180 to STT_NOTYPE or it will confuse binutils bfd */
181 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
&& s1
->output_type
== TCC_OUTPUT_OBJ
)
182 if (sym
->st_shndx
== SHN_UNDEF
&& ELFW(ST_BIND
)(sym
->st_info
) == STB_GLOBAL
)
183 sym
->st_info
= ELFW(ST_INFO
)(STB_GLOBAL
, ELFW(ST_TYPE
)(STT_NOTYPE
));
184 tr
[i
] = set_elf_sym(s
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
185 sym
->st_other
, sym
->st_shndx
, (char*)s
->link
->data
+ sym
->st_name
);
187 /* now update relocations */
188 for (i
= 1; i
< s1
->nb_sections
; i
++) {
189 Section
*sr
= s1
->sections
[i
];
190 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
191 ElfW_Rel
*rel
= (ElfW_Rel
*)(sr
->data
+ sr
->sh_offset
);
192 ElfW_Rel
*rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
193 for (; rel
< rel_end
; ++rel
) {
194 int n
= ELFW(R_SYM
)(rel
->r_info
) - first_sym
;
195 if (n
< 0) /* zero sym_index in reloc (can happen with asm) */
197 rel
->r_info
= ELFW(R_INFO
)(tr
[n
], ELFW(R_TYPE
)(rel
->r_info
));
203 /* record text/data/bss output for -bench info */
204 for (i
= 0; i
< 4; ++i
) {
205 s
= s1
->sections
[i
+ 1];
206 s1
->total_output
[i
] += s
->data_offset
- s
->sh_offset
;
210 ST_FUNC Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
214 sec
= tcc_mallocz(sizeof(Section
) + strlen(name
));
216 strcpy(sec
->name
, name
);
217 sec
->sh_type
= sh_type
;
218 sec
->sh_flags
= sh_flags
;
221 sec
->sh_addralign
= 2;
230 case SHT_GNU_verneed
:
232 sec
->sh_addralign
= PTR_SIZE
;
235 sec
->sh_addralign
= 1;
238 sec
->sh_addralign
= PTR_SIZE
; /* gcc/pcc default alignment */
242 if (sh_flags
& SHF_PRIVATE
) {
243 dynarray_add(&s1
->priv_sections
, &s1
->nb_priv_sections
, sec
);
245 sec
->sh_num
= s1
->nb_sections
;
246 dynarray_add(&s1
->sections
, &s1
->nb_sections
, sec
);
252 ST_FUNC Section
*new_symtab(TCCState
*s1
,
253 const char *symtab_name
, int sh_type
, int sh_flags
,
254 const char *strtab_name
,
255 const char *hash_name
, int hash_sh_flags
)
257 Section
*symtab
, *strtab
, *hash
;
258 int *ptr
, nb_buckets
;
260 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
261 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
262 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
263 put_elf_str(strtab
, "");
264 symtab
->link
= strtab
;
265 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
269 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
270 hash
->sh_entsize
= sizeof(int);
274 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
277 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
281 /* realloc section and set its content to zero */
282 ST_FUNC
void section_realloc(Section
*sec
, unsigned long new_size
)
287 size
= sec
->data_allocated
;
290 while (size
< new_size
)
292 data
= tcc_realloc(sec
->data
, size
);
293 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
295 sec
->data_allocated
= size
;
298 /* reserve at least 'size' bytes aligned per 'align' in section
299 'sec' from current offset, and return the aligned offset */
300 ST_FUNC
size_t section_add(Section
*sec
, addr_t size
, int align
)
302 size_t offset
, offset1
;
304 offset
= (sec
->data_offset
+ align
- 1) & -align
;
305 offset1
= offset
+ size
;
306 if (sec
->sh_type
!= SHT_NOBITS
&& offset1
> sec
->data_allocated
)
307 section_realloc(sec
, offset1
);
308 sec
->data_offset
= offset1
;
309 if (align
> sec
->sh_addralign
)
310 sec
->sh_addralign
= align
;
314 /* reserve at least 'size' bytes in section 'sec' from
316 ST_FUNC
void *section_ptr_add(Section
*sec
, addr_t size
)
318 size_t offset
= section_add(sec
, size
, 1);
319 return sec
->data
+ offset
;
323 /* reserve at least 'size' bytes from section start */
324 static void section_reserve(Section
*sec
, unsigned long size
)
326 if (size
> sec
->data_allocated
)
327 section_realloc(sec
, size
);
328 if (size
> sec
->data_offset
)
329 sec
->data_offset
= size
;
333 static Section
*have_section(TCCState
*s1
, const char *name
)
337 for(i
= 1; i
< s1
->nb_sections
; i
++) {
338 sec
= s1
->sections
[i
];
339 if (!strcmp(name
, sec
->name
))
345 /* return a reference to a section, and create it if it does not
347 ST_FUNC Section
*find_section(TCCState
*s1
, const char *name
)
349 Section
*sec
= have_section(s1
, name
);
352 /* sections are created as PROGBITS */
353 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
356 /* ------------------------------------------------------------------------- */
358 ST_FUNC
int put_elf_str(Section
*s
, const char *sym
)
363 len
= strlen(sym
) + 1;
364 offset
= s
->data_offset
;
365 ptr
= section_ptr_add(s
, len
);
366 memmove(ptr
, sym
, len
);
370 /* elf symbol hashing function */
371 static ElfW(Word
) elf_hash(const unsigned char *name
)
376 h
= (h
<< 4) + *name
++;
385 /* rebuild hash table of section s */
386 /* NOTE: we do factorize the hash table code to go faster */
387 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
390 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
391 unsigned char *strtab
;
393 strtab
= s
->link
->data
;
394 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
397 nb_buckets
= ((int*)s
->hash
->data
)[0];
399 s
->hash
->data_offset
= 0;
400 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
405 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
406 ptr
+= nb_buckets
+ 1;
408 sym
= (ElfW(Sym
) *)s
->data
+ 1;
409 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
410 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
411 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
422 /* return the symbol number */
423 ST_FUNC
int put_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
424 int info
, int other
, int shndx
, const char *name
)
426 int name_offset
, sym_index
;
431 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
433 name_offset
= put_elf_str(s
->link
, name
);
436 /* XXX: endianness */
437 sym
->st_name
= name_offset
;
438 sym
->st_value
= value
;
441 sym
->st_other
= other
;
442 sym
->st_shndx
= shndx
;
443 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
447 ptr
= section_ptr_add(hs
, sizeof(int));
448 base
= (int *)hs
->data
;
449 /* only add global or weak symbols. */
450 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
451 /* add another hashing entry */
453 h
= elf_hash((unsigned char *)s
->link
->data
+ name_offset
) % nbuckets
;
455 base
[2 + h
] = sym_index
;
457 /* we resize the hash table */
458 hs
->nb_hashed_syms
++;
459 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
460 rebuild_hash(s
, 2 * nbuckets
);
470 ST_FUNC
int find_elf_sym(Section
*s
, const char *name
)
474 int nbuckets
, sym_index
, h
;
480 nbuckets
= ((int *)hs
->data
)[0];
481 h
= elf_hash((unsigned char *) name
) % nbuckets
;
482 sym_index
= ((int *)hs
->data
)[2 + h
];
483 while (sym_index
!= 0) {
484 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
485 name1
= (char *) s
->link
->data
+ sym
->st_name
;
486 if (!strcmp(name
, name1
))
488 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
493 /* return elf symbol value, signal error if 'err' is nonzero, decorate
495 ST_FUNC addr_t
get_sym_addr(TCCState
*s1
, const char *name
, int err
, int forc
)
500 if (forc
&& s1
->leading_underscore
502 /* win32-32bit stdcall symbols always have _ already */
503 && !strchr(name
, '@')
507 pstrcpy(buf
+ 1, sizeof(buf
) - 1, name
);
510 sym_index
= find_elf_sym(s1
->symtab
, name
);
511 sym
= &((ElfW(Sym
) *)s1
->symtab
->data
)[sym_index
];
512 if (!sym_index
|| sym
->st_shndx
== SHN_UNDEF
) {
514 tcc_error_noabort("%s not defined", name
);
517 return sym
->st_value
;
520 /* return elf symbol value */
521 LIBTCCAPI
void *tcc_get_symbol(TCCState
*s
, const char *name
)
523 addr_t addr
= get_sym_addr(s
, name
, 0, 1);
524 return addr
== -1 ? NULL
: (void*)(uintptr_t)addr
;
527 /* list elf symbol names and values */
528 ST_FUNC
void list_elf_symbols(TCCState
*s
, void *ctx
,
529 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
533 int sym_index
, end_sym
;
535 unsigned char sym_vis
, sym_bind
;
538 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
539 for (sym_index
= 0; sym_index
< end_sym
; ++sym_index
) {
540 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
542 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
543 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
544 sym_vis
= ELFW(ST_VISIBILITY
)(sym
->st_other
);
545 if (sym_bind
== STB_GLOBAL
&& sym_vis
== STV_DEFAULT
)
546 symbol_cb(ctx
, name
, (void*)(uintptr_t)sym
->st_value
);
551 /* list elf symbol names and values */
552 LIBTCCAPI
void tcc_list_symbols(TCCState
*s
, void *ctx
,
553 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
555 list_elf_symbols(s
, ctx
, symbol_cb
);
560 version_add (TCCState
*s1
)
564 ElfW(Verneed
) *vn
= NULL
;
566 int sym_index
, end_sym
, nb_versions
= 2, nb_entries
= 0;
570 if (0 == nb_sym_versions
)
572 versym_section
= new_section(s1
, ".gnu.version", SHT_GNU_versym
, SHF_ALLOC
);
573 versym_section
->sh_entsize
= sizeof(ElfW(Half
));
574 versym_section
->link
= s1
->dynsym
;
576 /* add needed symbols */
578 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
579 versym
= section_ptr_add(versym_section
, end_sym
* sizeof(ElfW(Half
)));
580 for (sym_index
= 1; sym_index
< end_sym
; ++sym_index
) {
581 int dllindex
, verndx
;
582 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
583 if (sym
->st_shndx
!= SHN_UNDEF
)
584 continue; /* defined symbol doesn't need library version */
585 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
586 dllindex
= find_elf_sym(s1
->dynsymtab_section
, name
);
587 verndx
= (dllindex
&& dllindex
< nb_sym_to_version
)
588 ? sym_to_version
[dllindex
] : -1;
590 if (!sym_versions
[verndx
].out_index
)
591 sym_versions
[verndx
].out_index
= nb_versions
++;
592 versym
[sym_index
] = sym_versions
[verndx
].out_index
;
595 /* generate verneed section, but not when it will be empty. Some
596 dynamic linkers look at their contents even when DTVERNEEDNUM and
597 section size is zero. */
598 if (nb_versions
> 2) {
599 verneed_section
= new_section(s1
, ".gnu.version_r",
600 SHT_GNU_verneed
, SHF_ALLOC
);
601 verneed_section
->link
= s1
->dynsym
->link
;
602 for (i
= nb_sym_versions
; i
-- > 0;) {
603 struct sym_version
*sv
= &sym_versions
[i
];
604 int n_same_libs
= 0, prev
;
606 ElfW(Vernaux
) *vna
= 0;
607 if (sv
->out_index
< 1)
610 /* make sure that a DT_NEEDED tag is put */
611 /* abitest-tcc fails on older i386-linux with "ld-linux.so.2" DT_NEEDED
612 ret_int_test... Inconsistency detected by ld.so: dl-minimal.c: 148:
613 realloc: Assertion `ptr == alloc_last_block' failed! */
614 if (strcmp(sv
->lib
, "ld-linux.so.2"))
615 tcc_add_dllref(s1
, sv
->lib
, 0);
617 vnofs
= section_add(verneed_section
, sizeof(*vn
), 1);
618 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
620 vn
->vn_file
= put_elf_str(verneed_section
->link
, sv
->lib
);
621 vn
->vn_aux
= sizeof (*vn
);
623 prev
= sv
->prev_same_lib
;
624 if (sv
->out_index
> 0) {
625 vna
= section_ptr_add(verneed_section
, sizeof(*vna
));
626 vna
->vna_hash
= elf_hash ((const unsigned char *)sv
->version
);
628 vna
->vna_other
= sv
->out_index
;
630 vna
->vna_name
= put_elf_str(verneed_section
->link
, sv
->version
);
631 vna
->vna_next
= sizeof (*vna
);
635 sv
= &sym_versions
[prev
];
638 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
639 vn
->vn_cnt
= n_same_libs
;
640 vn
->vn_next
= sizeof(*vn
) + n_same_libs
* sizeof(*vna
);
645 verneed_section
->sh_info
= nb_entries
;
647 dt_verneednum
= nb_entries
;
649 #endif /* ndef ELF_OBJ_ONLY */
651 /* add an elf symbol : check if it is already defined and patch
652 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
653 ST_FUNC
int set_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
654 int info
, int other
, int shndx
, const char *name
)
656 TCCState
*s1
= s
->s1
;
658 int sym_bind
, sym_index
, sym_type
, esym_bind
;
659 unsigned char sym_vis
, esym_vis
, new_vis
;
661 sym_bind
= ELFW(ST_BIND
)(info
);
662 sym_type
= ELFW(ST_TYPE
)(info
);
663 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
665 if (sym_bind
!= STB_LOCAL
) {
666 /* we search global or weak symbols */
667 sym_index
= find_elf_sym(s
, name
);
670 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
671 if (esym
->st_value
== value
&& esym
->st_size
== size
&& esym
->st_info
== info
672 && esym
->st_other
== other
&& esym
->st_shndx
== shndx
)
674 if (esym
->st_shndx
!= SHN_UNDEF
) {
675 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
676 /* propagate the most constraining visibility */
677 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
678 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
679 if (esym_vis
== STV_DEFAULT
) {
681 } else if (sym_vis
== STV_DEFAULT
) {
684 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
686 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
688 if (shndx
== SHN_UNDEF
) {
689 /* ignore adding of undefined symbol if the
690 corresponding symbol is already defined */
691 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
692 /* global overrides weak, so patch */
694 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
695 /* weak is ignored if already global */
696 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_WEAK
) {
697 /* keep first-found weak definition, ignore subsequents */
698 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
699 /* ignore hidden symbols after */
700 } else if ((esym
->st_shndx
== SHN_COMMON
701 || esym
->st_shndx
== bss_section
->sh_num
)
702 && (shndx
< SHN_LORESERVE
703 && shndx
!= bss_section
->sh_num
)) {
704 /* data symbol gets precedence over common/bss */
706 } else if (shndx
== SHN_COMMON
|| shndx
== bss_section
->sh_num
) {
707 /* data symbol keeps precedence over common/bss */
708 } else if (s
->sh_flags
& SHF_DYNSYM
) {
709 /* we accept that two DLL define the same symbol */
710 } else if (esym
->st_other
& ST_ASM_SET
) {
711 /* If the existing symbol came from an asm .set
716 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
717 sym_bind
, shndx
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
719 tcc_error_noabort("'%s' defined twice", name
);
722 esym
->st_other
= other
;
724 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
725 esym
->st_shndx
= shndx
;
726 s1
->new_undef_sym
= 1;
727 esym
->st_value
= value
;
728 esym
->st_size
= size
;
732 sym_index
= put_elf_sym(s
, value
, size
,
733 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
740 ST_FUNC
void put_elf_reloca(Section
*symtab
, Section
*s
, unsigned long offset
,
741 int type
, int symbol
, addr_t addend
)
743 TCCState
*s1
= s
->s1
;
750 /* if no relocation section, create it */
751 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
752 /* if the symtab is allocated, then we consider the relocation
754 sr
= new_section(s
->s1
, buf
, SHT_RELX
, symtab
->sh_flags
);
755 sr
->sh_entsize
= sizeof(ElfW_Rel
);
757 sr
->sh_info
= s
->sh_num
;
760 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
761 rel
->r_offset
= offset
;
762 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
763 #if SHT_RELX == SHT_RELA
764 rel
->r_addend
= addend
;
766 if (SHT_RELX
!= SHT_RELA
&& addend
)
767 tcc_error_noabort("non-zero addend on REL architecture");
770 ST_FUNC
void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
771 int type
, int symbol
)
773 put_elf_reloca(symtab
, s
, offset
, type
, symbol
, 0);
776 ST_FUNC
struct sym_attr
*get_sym_attr(TCCState
*s1
, int index
, int alloc
)
779 struct sym_attr
*tab
;
781 if (index
>= s1
->nb_sym_attrs
) {
783 return s1
->sym_attrs
;
784 /* find immediately bigger power of 2 and reallocate array */
788 tab
= tcc_realloc(s1
->sym_attrs
, n
* sizeof(*s1
->sym_attrs
));
790 memset(s1
->sym_attrs
+ s1
->nb_sym_attrs
, 0,
791 (n
- s1
->nb_sym_attrs
) * sizeof(*s1
->sym_attrs
));
792 s1
->nb_sym_attrs
= n
;
794 return &s1
->sym_attrs
[index
];
797 static void modify_reloctions_old_to_new(TCCState
*s1
, Section
*s
, int *old_to_new_syms
)
799 int i
, type
, sym_index
;
803 for(i
= 1; i
< s1
->nb_sections
; i
++) {
804 sr
= s1
->sections
[i
];
805 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
806 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
807 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
808 type
= ELFW(R_TYPE
)(rel
->r_info
);
809 sym_index
= old_to_new_syms
[sym_index
];
810 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
816 /* In an ELF file symbol table, the local symbols must appear below
817 the global and weak ones. Since TCC cannot sort it while generating
818 the code, we must do it after. All the relocation tables are also
819 modified to take into account the symbol table sorting */
820 static void sort_syms(TCCState
*s1
, Section
*s
)
822 int *old_to_new_syms
;
827 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
828 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
829 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
831 /* first pass for local symbols */
832 p
= (ElfW(Sym
) *)s
->data
;
834 for(i
= 0; i
< nb_syms
; i
++) {
835 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
836 old_to_new_syms
[i
] = q
- new_syms
;
841 /* save the number of local symbols in section header */
842 if( s
->sh_size
) /* this 'if' makes IDA happy */
843 s
->sh_info
= q
- new_syms
;
845 /* then second pass for non local symbols */
846 p
= (ElfW(Sym
) *)s
->data
;
847 for(i
= 0; i
< nb_syms
; i
++) {
848 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
849 old_to_new_syms
[i
] = q
- new_syms
;
855 /* we copy the new symbols to the old */
856 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
859 modify_reloctions_old_to_new(s1
, s
, old_to_new_syms
);
861 tcc_free(old_to_new_syms
);
865 /* See: https://flapenguin.me/elf-dt-gnu-hash */
866 #define ELFCLASS_BITS (PTR_SIZE * 8)
868 static Section
*create_gnu_hash(TCCState
*s1
)
870 int nb_syms
, i
, ndef
, nbuckets
, symoffset
, bloom_size
, bloom_shift
;
873 Section
*dynsym
= s1
->dynsym
;
876 gnu_hash
= new_section(s1
, ".gnu.hash", SHT_GNU_HASH
, SHF_ALLOC
);
877 gnu_hash
->link
= dynsym
->hash
->link
;
879 nb_syms
= dynsym
->data_offset
/ sizeof(ElfW(Sym
));
881 /* count def symbols */
883 p
= (ElfW(Sym
) *)dynsym
->data
;
884 for(i
= 0; i
< nb_syms
; i
++, p
++)
885 ndef
+= p
->st_shndx
!= SHN_UNDEF
;
887 /* calculate gnu hash sizes and fill header */
888 nbuckets
= ndef
/ 4 + 1;
889 symoffset
= nb_syms
- ndef
;
890 bloom_shift
= PTR_SIZE
== 8 ? 6 : 5;
891 bloom_size
= 1; /* must be power of two */
892 while (ndef
>= bloom_size
* (1 << (bloom_shift
- 3)))
894 ptr
= section_ptr_add(gnu_hash
, 4 * 4 +
895 PTR_SIZE
* bloom_size
+
901 ptr
[3] = bloom_shift
;
905 static Elf32_Word
elf_gnu_hash (const unsigned char *name
)
910 while ((c
= *name
++))
915 static void update_gnu_hash(TCCState
*s1
, Section
*gnu_hash
)
917 int *old_to_new_syms
;
919 int nb_syms
, i
, nbuckets
, bloom_size
, bloom_shift
;
922 Section
*dynsym
= s1
->dynsym
;
923 Elf32_Word
*ptr
, *buckets
, *chain
, *hash
;
924 unsigned int *nextbuck
;
926 unsigned char *strtab
;
927 struct { int first
, last
; } *buck
;
929 strtab
= dynsym
->link
->data
;
930 nb_syms
= dynsym
->data_offset
/ sizeof(ElfW(Sym
));
931 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
932 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
933 hash
= tcc_malloc(nb_syms
* sizeof(Elf32_Word
));
934 nextbuck
= tcc_malloc(nb_syms
* sizeof(int));
936 /* calculate hashes and copy undefs */
937 p
= (ElfW(Sym
) *)dynsym
->data
;
939 for(i
= 0; i
< nb_syms
; i
++, p
++) {
940 if (p
->st_shndx
== SHN_UNDEF
) {
941 old_to_new_syms
[i
] = q
- new_syms
;
945 hash
[i
] = elf_gnu_hash(strtab
+ p
->st_name
);
948 ptr
= (Elf32_Word
*) gnu_hash
->data
;
951 bloom_shift
= ptr
[3];
952 bloom
= (addr_t
*) (void *) &ptr
[4];
953 buckets
= (Elf32_Word
*) (void *) &bloom
[bloom_size
];
954 chain
= &buckets
[nbuckets
];
955 buck
= tcc_malloc(nbuckets
* sizeof(*buck
));
957 if (gnu_hash
->data_offset
!= 4 * 4 +
958 PTR_SIZE
* bloom_size
+
960 (nb_syms
- (q
- new_syms
)) * 4)
961 tcc_error_noabort ("gnu_hash size incorrect");
964 for(i
= 0; i
< nbuckets
; i
++)
967 p
= (ElfW(Sym
) *)dynsym
->data
;
968 for(i
= 0; i
< nb_syms
; i
++, p
++)
969 if (p
->st_shndx
!= SHN_UNDEF
) {
970 int bucket
= hash
[i
] % nbuckets
;
972 if (buck
[bucket
].first
== -1)
973 buck
[bucket
].first
= buck
[bucket
].last
= i
;
975 nextbuck
[buck
[bucket
].last
] = i
;
976 buck
[bucket
].last
= i
;
980 /* fill buckets/chains/bloom and sort symbols */
981 p
= (ElfW(Sym
) *)dynsym
->data
;
982 for(i
= 0; i
< nbuckets
; i
++) {
983 int cur
= buck
[i
].first
;
986 buckets
[i
] = q
- new_syms
;
988 old_to_new_syms
[cur
] = q
- new_syms
;
990 *chain
++ = hash
[cur
] & ~1;
991 bloom
[(hash
[cur
] / ELFCLASS_BITS
) % bloom_size
] |=
992 (addr_t
)1 << (hash
[cur
] % ELFCLASS_BITS
) |
993 (addr_t
)1 << ((hash
[cur
] >> bloom_shift
) % ELFCLASS_BITS
);
994 if (cur
== buck
[i
].last
)
1002 memcpy(dynsym
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
1008 modify_reloctions_old_to_new(s1
, dynsym
, old_to_new_syms
);
1010 /* modify the versions */
1011 vs
= versym_section
;
1013 ElfW(Half
) *newver
, *versym
= (ElfW(Half
) *)vs
->data
;
1016 newver
= tcc_malloc(nb_syms
* sizeof(*newver
));
1017 for (i
= 0; i
< nb_syms
; i
++)
1018 newver
[old_to_new_syms
[i
]] = versym
[i
];
1019 memcpy(vs
->data
, newver
, nb_syms
* sizeof(*newver
));
1024 tcc_free(old_to_new_syms
);
1027 ptr
= (Elf32_Word
*) dynsym
->hash
->data
;
1028 rebuild_hash(dynsym
, ptr
[0]);
1030 #endif /* ELF_OBJ_ONLY */
1032 /* relocate symbol table, resolve undefined symbols if do_resolve is
1033 true and output error if undefined symbol. */
1034 ST_FUNC
void relocate_syms(TCCState
*s1
, Section
*symtab
, int do_resolve
)
1037 int sym_bind
, sh_num
;
1040 for_each_elem(symtab
, 1, sym
, ElfW(Sym
)) {
1041 sh_num
= sym
->st_shndx
;
1042 if (sh_num
== SHN_UNDEF
) {
1043 if (do_resolve
== 2) /* relocating dynsym */
1045 name
= (char *) s1
->symtab
->link
->data
+ sym
->st_name
;
1046 /* Use ld.so to resolve symbol for us (for tcc -run) */
1048 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
1049 /* dlsym() needs the undecorated name. */
1050 void *addr
= dlsym(RTLD_DEFAULT
, &name
[s1
->leading_underscore
]);
1051 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD || TARGETOS_ANDROID
1054 for (i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
1055 if ((addr
= dlsym(s1
->loaded_dlls
[i
]->handle
, name
)))
1060 sym
->st_value
= (addr_t
) addr
;
1062 printf ("relocate_sym: %s -> 0x%lx\n", name
, sym
->st_value
);
1067 /* if dynamic symbol exist, it will be used in relocate_section */
1068 } else if (s1
->dynsym
&& find_elf_sym(s1
->dynsym
, name
))
1070 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1072 if (!strcmp(name
, "_fp_hw"))
1074 /* only weak symbols are accepted to be undefined. Their
1076 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
1077 if (sym_bind
== STB_WEAK
)
1080 tcc_error_noabort("undefined symbol '%s'", name
);
1082 } else if (sh_num
< SHN_LORESERVE
) {
1083 /* add section base */
1084 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1090 /* relocate a given section (CPU dependent) by applying the relocations
1091 in the associated relocation section */
1092 static void relocate_section(TCCState
*s1
, Section
*s
, Section
*sr
)
1096 int type
, sym_index
;
1099 int is_dwarf
= s
->sh_num
>= s1
->dwlo
&& s
->sh_num
< s1
->dwhi
;
1101 qrel
= (ElfW_Rel
*)sr
->data
;
1102 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
1103 ptr
= s
->data
+ rel
->r_offset
;
1104 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1105 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1106 type
= ELFW(R_TYPE
)(rel
->r_info
);
1107 tgt
= sym
->st_value
;
1108 #if SHT_RELX == SHT_RELA
1109 tgt
+= rel
->r_addend
;
1111 if (is_dwarf
&& type
== R_DATA_32DW
1112 && sym
->st_shndx
>= s1
->dwlo
&& sym
->st_shndx
< s1
->dwhi
) {
1113 /* dwarf section relocation to each other */
1114 add32le(ptr
, tgt
- s1
->sections
[sym
->st_shndx
]->sh_addr
);
1117 addr
= s
->sh_addr
+ rel
->r_offset
;
1118 relocate(s1
, rel
, type
, ptr
, addr
, tgt
);
1120 #ifndef ELF_OBJ_ONLY
1121 /* if the relocation is allocated, we change its symbol table */
1122 if (sr
->sh_flags
& SHF_ALLOC
) {
1123 sr
->link
= s1
->dynsym
;
1124 if (s1
->output_type
& TCC_OUTPUT_DYN
) {
1125 size_t r
= (uint8_t*)qrel
- sr
->data
;
1126 if (sizeof ((Stab_Sym
*)0)->n_value
< PTR_SIZE
1127 && 0 == strcmp(s
->name
, ".stab"))
1128 r
= 0; /* cannot apply 64bit relocation to 32bit value */
1129 sr
->data_offset
= sr
->sh_size
= r
;
1130 #ifdef CONFIG_TCC_PIE
1131 if (r
&& 0 == (s
->sh_flags
& SHF_WRITE
))
1132 tcc_warning("%d relocations to ro-section %s", (unsigned)(r
/ sizeof *qrel
), s
->name
);
1139 /* relocate all sections */
1140 ST_FUNC
void relocate_sections(TCCState
*s1
)
1145 for (i
= 1; i
< s1
->nb_sections
; ++i
) {
1146 sr
= s1
->sections
[i
];
1147 if (sr
->sh_type
!= SHT_RELX
)
1149 s
= s1
->sections
[sr
->sh_info
];
1150 #ifndef TCC_TARGET_MACHO
1153 || s1
->output_type
== TCC_OUTPUT_MEMORY
)
1156 relocate_section(s1
, s
, sr
);
1158 #ifndef ELF_OBJ_ONLY
1159 if (sr
->sh_flags
& SHF_ALLOC
) {
1161 /* relocate relocation table in 'sr' */
1162 for_each_elem(sr
, 0, rel
, ElfW_Rel
)
1163 rel
->r_offset
+= s
->sh_addr
;
1169 #ifndef ELF_OBJ_ONLY
1170 /* count the number of dynamic relocations so that we can reserve
1172 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
1175 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1176 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1177 defined(TCC_TARGET_RISCV64)
1179 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
1180 int sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1181 int type
= ELFW(R_TYPE
)(rel
->r_info
);
1183 #if defined(TCC_TARGET_I386)
1185 if (!get_sym_attr(s1
, sym_index
, 0)->dyn_index
1186 && ((ElfW(Sym
)*)symtab_section
->data
+ sym_index
)->st_shndx
== SHN_UNDEF
) {
1187 /* don't fixup unresolved (weak) symbols */
1188 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_386_RELATIVE
);
1191 #elif defined(TCC_TARGET_X86_64)
1195 #elif defined(TCC_TARGET_ARM)
1198 #elif defined(TCC_TARGET_ARM64)
1199 case R_AARCH64_ABS32
:
1200 case R_AARCH64_ABS64
:
1201 #elif defined(TCC_TARGET_RISCV64)
1207 #if defined(TCC_TARGET_I386)
1209 #elif defined(TCC_TARGET_X86_64)
1212 ElfW(Sym
) *sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1213 /* Hidden defined symbols can and must be resolved locally.
1214 We're misusing a PLT32 reloc for this, as that's always
1215 resolved to its address even in shared libs. */
1216 if (sym
->st_shndx
!= SHN_UNDEF
&&
1217 ELFW(ST_VISIBILITY
)(sym
->st_other
) == STV_HIDDEN
) {
1218 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PLT32
);
1222 #elif defined(TCC_TARGET_ARM64)
1223 case R_AARCH64_PREL32
:
1225 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1227 if (get_sym_attr(s1
, sym_index
, 0)->dyn_index
)
1239 #ifdef NEED_BUILD_GOT
1240 static int build_got(TCCState
*s1
)
1242 /* if no got, then create it */
1243 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
1244 s1
->got
->sh_entsize
= 4;
1245 /* keep space for _DYNAMIC pointer and two dummy got entries */
1246 section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
1247 return set_elf_sym(symtab_section
, 0, 0, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
1248 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
1251 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1252 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1253 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1254 Returns the offset of the GOT or (if any) PLT entry. */
1255 static struct sym_attr
* put_got_entry(TCCState
*s1
, int dyn_reloc_type
,
1261 struct sym_attr
*attr
;
1262 unsigned got_offset
;
1267 need_plt_entry
= (dyn_reloc_type
== R_JMP_SLOT
);
1268 attr
= get_sym_attr(s1
, sym_index
, 1);
1270 /* In case a function is both called and its address taken 2 GOT entries
1271 are created, one for taking the address (GOT) and the other for the PLT
1273 if (need_plt_entry
? attr
->plt_offset
: attr
->got_offset
)
1277 if (need_plt_entry
) {
1279 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
1280 s1
->plt
->sh_entsize
= 4;
1285 /* create the GOT entry */
1286 got_offset
= s1
->got
->data_offset
;
1287 section_ptr_add(s1
->got
, PTR_SIZE
);
1289 /* Create the GOT relocation that will insert the address of the object or
1290 function of interest in the GOT entry. This is a static relocation for
1291 memory output (dlsym will give us the address of symbols) and dynamic
1292 relocation otherwise (executable and DLLs). The relocation should be
1293 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1294 associated to a PLT entry) but is currently done at load time for an
1297 sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1298 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1299 //printf("sym %d %s\n", need_plt_entry, name);
1302 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
) {
1303 /* Hack alarm. We don't want to emit dynamic symbols
1304 and symbol based relocs for STB_LOCAL symbols, but rather
1305 want to resolve them directly. At this point the symbol
1306 values aren't final yet, so we must defer this. We will later
1307 have to create a RELATIVE reloc anyway, so we misuse the
1308 relocation slot to smuggle the symbol reference until
1309 fill_local_got_entries. Not that the sym_index is
1310 relative to symtab_section, not s1->dynsym! Nevertheless
1311 we use s1->dyn_sym so that if this is the first call
1312 that got->reloc is correctly created. Also note that
1313 RELATIVE relocs are not normally created for the .got,
1314 so the types serves as a marker for later (and is retained
1315 also for the final output, which is okay because then the
1316 got is just normal data). */
1317 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, R_RELATIVE
,
1320 if (0 == attr
->dyn_index
)
1321 attr
->dyn_index
= set_elf_sym(s1
->dynsym
, sym
->st_value
,
1322 sym
->st_size
, sym
->st_info
, 0,
1323 sym
->st_shndx
, name
);
1324 put_elf_reloc(s1
->dynsym
, s_rel
, got_offset
, dyn_reloc_type
,
1328 put_elf_reloc(symtab_section
, s1
->got
, got_offset
, dyn_reloc_type
,
1332 if (need_plt_entry
) {
1333 attr
->plt_offset
= create_plt_entry(s1
, got_offset
, attr
);
1335 /* create a symbol 'sym@plt' for the PLT jump vector */
1337 if (len
> sizeof plt_name
- 5)
1338 len
= sizeof plt_name
- 5;
1339 memcpy(plt_name
, name
, len
);
1340 strcpy(plt_name
+ len
, "@plt");
1341 attr
->plt_sym
= put_elf_sym(s1
->symtab
, attr
->plt_offset
, 0,
1342 ELFW(ST_INFO
)(STB_GLOBAL
, STT_FUNC
), 0, s1
->plt
->sh_num
, plt_name
);
1344 attr
->got_offset
= got_offset
;
1350 /* build GOT and PLT entries */
1351 /* Two passes because R_JMP_SLOT should become first. Some targets
1352 (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1353 ST_FUNC
void build_got_entries(TCCState
*s1
, int got_sym
)
1358 int i
, type
, gotplt_entry
, reloc_type
, sym_index
;
1359 struct sym_attr
*attr
;
1362 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1363 s
= s1
->sections
[i
];
1364 if (s
->sh_type
!= SHT_RELX
)
1366 /* no need to handle got relocations */
1367 if (s
->link
!= symtab_section
)
1369 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1370 type
= ELFW(R_TYPE
)(rel
->r_info
);
1371 gotplt_entry
= gotplt_entry_type(type
);
1372 if (gotplt_entry
== -1) {
1373 tcc_error_noabort ("Unknown relocation type for got: %d", type
);
1376 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1377 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1379 if (gotplt_entry
== NO_GOTPLT_ENTRY
) {
1383 /* Automatically create PLT/GOT [entry] if it is an undefined
1384 reference (resolved at runtime), or the symbol is absolute,
1385 probably created by tcc_add_symbol, and thus on 64-bit
1386 targets might be too far from application code. */
1387 if (gotplt_entry
== AUTO_GOTPLT_ENTRY
) {
1388 if (sym
->st_shndx
== SHN_UNDEF
) {
1391 if (!PCRELATIVE_DLLPLT
1392 && (s1
->output_type
& TCC_OUTPUT_DYN
))
1394 /* Relocations for UNDEF symbols would normally need
1395 to be transferred into the executable or shared object.
1396 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1397 But TCC doesn't do that (at least for exes), so we
1398 need to resolve all such relocs locally. And that
1399 means PLT slots for functions in DLLs and COPY relocs for
1400 data symbols. COPY relocs were generated in
1401 bind_exe_dynsyms (and the symbol adjusted to be defined),
1402 and for functions we were generated a dynamic symbol
1403 of function type. */
1405 /* dynsym isn't set for -run :-/ */
1406 dynindex
= get_sym_attr(s1
, sym_index
, 0)->dyn_index
;
1407 esym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ dynindex
;
1409 && (ELFW(ST_TYPE
)(esym
->st_info
) == STT_FUNC
1410 || (ELFW(ST_TYPE
)(esym
->st_info
) == STT_NOTYPE
1411 && ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
)))
1414 } else if (sym
->st_shndx
== SHN_ABS
) {
1415 if (sym
->st_value
== 0) /* from tcc_add_btstub() */
1417 #ifndef TCC_TARGET_ARM
1421 /* from tcc_add_symbol(): on 64 bit platforms these
1422 need to go through .got */
1427 #ifdef TCC_TARGET_X86_64
1428 if ((type
== R_X86_64_PLT32
|| type
== R_X86_64_PC32
) &&
1429 sym
->st_shndx
!= SHN_UNDEF
&&
1430 (ELFW(ST_VISIBILITY
)(sym
->st_other
) != STV_DEFAULT
||
1431 ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
||
1432 s1
->output_type
& TCC_OUTPUT_EXE
)) {
1435 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PC32
);
1439 reloc_type
= code_reloc(type
);
1440 if (reloc_type
== -1) {
1441 tcc_error_noabort ("Unknown relocation type: %d", type
);
1445 if (reloc_type
!= 0) {
1449 reloc_type
= R_JMP_SLOT
;
1453 reloc_type
= R_GLOB_DAT
;
1457 got_sym
= build_got(s1
);
1459 if (gotplt_entry
== BUILD_GOT_ONLY
)
1462 attr
= put_got_entry(s1
, reloc_type
, sym_index
);
1464 if (reloc_type
== R_JMP_SLOT
)
1465 rel
->r_info
= ELFW(R_INFO
)(attr
->plt_sym
, type
);
1470 /* .rel.plt refers to .got actually */
1471 if (s1
->plt
&& s1
->plt
->reloc
)
1472 s1
->plt
->reloc
->sh_info
= s1
->got
->sh_num
;
1473 if (got_sym
) /* set size */
1474 ((ElfW(Sym
)*)symtab_section
->data
)[got_sym
].st_size
= s1
->got
->data_offset
;
1476 #endif /* def NEED_BUILD_GOT */
1478 ST_FUNC
int set_global_sym(TCCState
*s1
, const char *name
, Section
*sec
, addr_t offs
)
1480 int shn
= sec
? sec
->sh_num
: offs
|| !name
? SHN_ABS
: SHN_UNDEF
;
1481 if (sec
&& offs
== -1)
1482 offs
= sec
->data_offset
;
1483 return set_elf_sym(symtab_section
, offs
, 0,
1484 ELFW(ST_INFO
)(name
? STB_GLOBAL
: STB_LOCAL
, STT_NOTYPE
), 0, shn
, name
);
1487 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1492 s
= have_section(s1
, section_name
);
1493 if (!s
|| !(s
->sh_flags
& SHF_ALLOC
)) {
1497 end_offset
= s
->data_offset
;
1499 snprintf(buf
, sizeof(buf
), "__%s_start", section_name
+ 1);
1500 set_global_sym(s1
, buf
, s
, 0);
1501 snprintf(buf
, sizeof(buf
), "__%s_end", section_name
+ 1);
1502 set_global_sym(s1
, buf
, s
, end_offset
);
1505 ST_FUNC
void add_array (TCCState
*s1
, const char *sec
, int c
)
1508 s
= find_section(s1
, sec
);
1509 s
->sh_flags
= shf_RELRO
;
1510 s
->sh_type
= sec
[1] == 'i' ? SHT_INIT_ARRAY
: SHT_FINI_ARRAY
;
1511 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1512 section_ptr_add(s
, PTR_SIZE
);
1515 #ifdef CONFIG_TCC_BCHECK
1516 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
1518 if (0 == s1
->do_bounds_check
)
1520 section_ptr_add(bounds_section
, sizeof(addr_t
));
1524 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1525 a dynamic symbol to allow so's to have one each with a different value. */
1526 static void set_local_sym(TCCState
*s1
, const char *name
, Section
*s
, int offset
)
1528 int c
= find_elf_sym(s1
->symtab
, name
);
1530 ElfW(Sym
) *esym
= (ElfW(Sym
)*)s1
->symtab
->data
+ c
;
1531 esym
->st_info
= ELFW(ST_INFO
)(STB_LOCAL
, STT_NOTYPE
);
1532 esym
->st_value
= offset
;
1533 esym
->st_shndx
= s
->sh_num
;
1537 /* avoid generating debug/test_coverage code for stub functions */
1538 static void tcc_compile_string_no_debug(TCCState
*s
, const char *str
)
1540 int save_do_debug
= s
->do_debug
;
1541 int save_test_coverage
= s
->test_coverage
;
1544 s
->test_coverage
= 0;
1545 tcc_compile_string(s
, str
);
1546 s
->do_debug
= save_do_debug
;
1547 s
->test_coverage
= save_test_coverage
;
1550 #ifdef CONFIG_TCC_BACKTRACE
1551 static void put_ptr(TCCState
*s1
, Section
*s
, int offs
)
1554 c
= set_global_sym(s1
, NULL
, s
, offs
);
1556 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1557 section_ptr_add(s
, PTR_SIZE
);
1560 ST_FUNC
void tcc_add_btstub(TCCState
*s1
)
1567 /* Align to PTR_SIZE */
1568 section_ptr_add(s
, -s
->data_offset
& (PTR_SIZE
- 1));
1570 /* create (part of) a struct rt_context (see tccrun.c) */
1572 put_ptr(s1
, dwarf_line_section
, 0);
1573 put_ptr(s1
, dwarf_line_section
, -1);
1575 put_ptr(s1
, dwarf_line_str_section
, 0);
1577 put_ptr(s1
, dwarf_str_section
, 0);
1581 put_ptr(s1
, stab_section
, 0);
1582 put_ptr(s1
, stab_section
, -1);
1583 put_ptr(s1
, stab_section
->link
, 0);
1585 *(addr_t
*)section_ptr_add(s
, PTR_SIZE
) = s1
->dwarf
;
1586 /* skip esym_start/esym_end/elf_str (not loaded) */
1587 section_ptr_add(s
, 3 * PTR_SIZE
);
1588 /* prog_base : local nameless symbol with offset 0 at SHN_ABS */
1589 put_ptr(s1
, NULL
, 0);
1590 #if defined TCC_TARGET_MACHO
1591 /* adjust for __PAGEZERO */
1592 if (s1
->dwarf
== 0 && s1
->output_type
== TCC_OUTPUT_EXE
)
1593 write64le(data_section
->data
+ data_section
->data_offset
- PTR_SIZE
,
1597 #ifdef CONFIG_TCC_BCHECK
1598 if (s1
->do_bounds_check
) {
1599 put_ptr(s1
, bounds_section
, 0);
1603 section_ptr_add(s
, n
);
1606 "extern void __bt_init(),__bt_exit(),__bt_init_dll();"
1607 "static void *__rt_info[];"
1608 "__attribute__((constructor)) static void __bt_init_rt(){");
1609 #ifdef TCC_TARGET_PE
1610 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1611 #ifdef CONFIG_TCC_BCHECK
1612 cstr_printf(&cstr
, "__bt_init_dll(%d);", s1
->do_bounds_check
);
1614 cstr_printf(&cstr
, "__bt_init_dll(0);");
1617 cstr_printf(&cstr
, "__bt_init(__rt_info,%d);}",
1618 s1
->output_type
== TCC_OUTPUT_DLL
? 0 : s1
->rt_num_callers
+ 1);
1619 /* In case dlcose is called by application */
1621 "__attribute__((destructor)) static void __bt_exit_rt(){"
1622 "__bt_exit(__rt_info);}");
1623 tcc_compile_string_no_debug(s1
, cstr
.data
);
1625 set_local_sym(s1
, &"___rt_info"[!s1
->leading_underscore
], s
, o
);
1627 #endif /* def CONFIG_TCC_BACKTRACE */
1629 static void tcc_tcov_add_file(TCCState
*s1
, const char *filename
)
1635 if (tcov_section
== NULL
)
1637 section_ptr_add(tcov_section
, 1);
1638 write32le (tcov_section
->data
, tcov_section
->data_offset
);
1641 if (filename
[0] == '/')
1642 cstr_printf (&cstr
, "%s.tcov", filename
);
1644 getcwd (wd
, sizeof(wd
));
1645 cstr_printf (&cstr
, "%s/%s.tcov", wd
, filename
);
1647 ptr
= section_ptr_add(tcov_section
, cstr
.size
+ 1);
1648 strcpy((char *)ptr
, cstr
.data
);
1649 unlink((char *)ptr
);
1651 normalize_slashes((char *)ptr
);
1657 "extern char *__tcov_data[];"
1658 "extern void __store_test_coverage ();"
1659 "__attribute__((destructor)) static void __tcov_exit() {"
1660 "__store_test_coverage(__tcov_data);"
1662 tcc_compile_string_no_debug(s1
, cstr
.data
);
1664 set_local_sym(s1
, &"___tcov_data"[!s1
->leading_underscore
], tcov_section
, 0);
1667 #ifndef TCC_TARGET_PE
1668 /* add tcc runtime libraries */
1669 ST_FUNC
void tcc_add_runtime(TCCState
*s1
)
1673 #ifdef CONFIG_TCC_BCHECK
1676 tcc_add_pragma_libs(s1
);
1679 if (!s1
->nostdlib
) {
1680 int lpthread
= s1
->option_pthread
;
1682 #ifdef CONFIG_TCC_BCHECK
1683 if (s1
->do_bounds_check
&& s1
->output_type
!= TCC_OUTPUT_DLL
) {
1684 tcc_add_support(s1
, "bcheck.o");
1685 # if !(TARGETOS_OpenBSD || TARGETOS_NetBSD)
1686 tcc_add_library_err(s1
, "dl");
1691 #ifdef CONFIG_TCC_BACKTRACE
1692 if (s1
->do_backtrace
) {
1693 if (s1
->output_type
& TCC_OUTPUT_EXE
)
1694 tcc_add_support(s1
, "bt-exe.o");
1695 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1696 tcc_add_support(s1
, "bt-log.o");
1697 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1702 tcc_add_library_err(s1
, "pthread");
1703 tcc_add_library_err(s1
, "c");
1705 if (!s1
->static_link
) {
1706 if (TCC_LIBGCC
[0] == '/')
1707 tcc_add_file(s1
, TCC_LIBGCC
);
1709 tcc_add_dll(s1
, TCC_LIBGCC
, 0);
1712 #if defined TCC_TARGET_ARM && TARGETOS_FreeBSD
1713 tcc_add_library_err(s1
, "gcc_s"); // unwind code
1716 tcc_add_support(s1
, TCC_LIBTCC1
);
1718 /* add crt end if not memory output */
1719 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1720 #if defined TCC_TARGET_MACHO
1722 #elif TARGETOS_FreeBSD || TARGETOS_NetBSD
1723 if (s1
->output_type
& TCC_OUTPUT_DYN
)
1724 tcc_add_crt(s1
, "crtendS.o");
1726 tcc_add_crt(s1
, "crtend.o");
1727 tcc_add_crt(s1
, "crtn.o");
1728 #elif TARGETOS_OpenBSD
1729 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1730 tcc_add_crt(s1
, "crtendS.o");
1732 tcc_add_crt(s1
, "crtend.o");
1733 #elif TARGETOS_ANDROID
1734 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1735 tcc_add_crt(s1
, "crtend_so.o");
1737 tcc_add_crt(s1
, "crtend_android.o");
1739 tcc_add_crt(s1
, "crtn.o");
1744 #endif /* ndef TCC_TARGET_PE */
1746 /* add various standard linker symbols (must be done after the
1747 sections are filled (for example after allocating common
1749 static void tcc_add_linker_symbols(TCCState
*s1
)
1755 set_global_sym(s1
, "_etext", text_section
, -1);
1756 set_global_sym(s1
, "_edata", data_section
, -1);
1757 set_global_sym(s1
, "_end", bss_section
, -1);
1758 #if TARGETOS_OpenBSD
1759 set_global_sym(s1
, "__executable_start", NULL
, ELF_START_ADDR
);
1761 #ifdef TCC_TARGET_RISCV64
1762 /* XXX should be .sdata+0x800, not .data+0x800 */
1763 set_global_sym(s1
, "__global_pointer$", data_section
, 0x800);
1765 /* horrible new standard ldscript defines */
1766 add_init_array_defines(s1
, ".preinit_array");
1767 add_init_array_defines(s1
, ".init_array");
1768 add_init_array_defines(s1
, ".fini_array");
1769 /* add start and stop symbols for sections whose name can be
1771 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1772 s
= s1
->sections
[i
];
1773 if ((s
->sh_flags
& SHF_ALLOC
)
1774 && (s
->sh_type
== SHT_PROGBITS
1775 || s
->sh_type
== SHT_STRTAB
)) {
1777 /* check if section name can be expressed in C */
1783 if (!isid(c
) && !isnum(c
))
1787 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1788 set_global_sym(s1
, buf
, s
, 0);
1789 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1790 set_global_sym(s1
, buf
, s
, -1);
1796 ST_FUNC
void resolve_common_syms(TCCState
*s1
)
1800 /* Allocate common symbols in BSS. */
1801 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1802 if (sym
->st_shndx
== SHN_COMMON
) {
1803 /* symbol alignment is in st_value for SHN_COMMONs */
1804 sym
->st_value
= section_add(bss_section
, sym
->st_size
,
1806 sym
->st_shndx
= bss_section
->sh_num
;
1810 /* Now assign linker provided symbols their value. */
1811 tcc_add_linker_symbols(s1
);
1814 #ifndef ELF_OBJ_ONLY
1815 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1817 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1818 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1819 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1820 unsigned offset
= attr
->got_offset
;
1824 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1826 write64le(s1
->got
->data
+ offset
, sym
->st_value
);
1828 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1832 /* Perform relocation to GOT or PLT entries */
1833 ST_FUNC
void fill_got(TCCState
*s1
)
1839 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1840 s
= s1
->sections
[i
];
1841 if (s
->sh_type
!= SHT_RELX
)
1843 /* no need to handle got relocations */
1844 if (s
->link
!= symtab_section
)
1846 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1847 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1848 case R_X86_64_GOT32
:
1849 case R_X86_64_GOTPCREL
:
1850 case R_X86_64_GOTPCRELX
:
1851 case R_X86_64_REX_GOTPCRELX
:
1852 case R_X86_64_PLT32
:
1853 fill_got_entry(s1
, rel
);
1860 /* See put_got_entry for a description. This is the second stage
1861 where GOT references to local defined symbols are rewritten. */
1862 static void fill_local_got_entries(TCCState
*s1
)
1865 if (!s1
->got
->reloc
)
1867 for_each_elem(s1
->got
->reloc
, 0, rel
, ElfW_Rel
) {
1868 if (ELFW(R_TYPE
)(rel
->r_info
) == R_RELATIVE
) {
1869 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1870 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1871 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1872 unsigned offset
= attr
->got_offset
;
1873 if (offset
!= rel
->r_offset
- s1
->got
->sh_addr
)
1874 tcc_error_noabort("fill_local_got_entries: huh?");
1875 rel
->r_info
= ELFW(R_INFO
)(0, R_RELATIVE
);
1876 #if SHT_RELX == SHT_RELA
1877 rel
->r_addend
= sym
->st_value
;
1879 /* All our REL architectures also happen to be 32bit LE. */
1880 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1886 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1887 in shared libraries */
1888 static void bind_exe_dynsyms(TCCState
*s1
, int is_PIE
)
1891 int sym_index
, index
;
1892 ElfW(Sym
) *sym
, *esym
;
1895 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1896 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1897 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1898 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1899 if (sym
->st_shndx
== SHN_UNDEF
) {
1900 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1901 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1905 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1906 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1907 if ((type
== STT_FUNC
) || (type
== STT_GNU_IFUNC
)) {
1908 /* Indirect functions shall have STT_FUNC type in executable
1909 * dynsym section. Indeed, a dlsym call following a lazy
1910 * resolution would pick the symbol value from the
1911 * executable dynsym entry which would contain the address
1912 * of the function wanted by the caller of dlsym instead of
1913 * the address of the function that would return that
1916 = put_elf_sym(s1
->dynsym
, 0, esym
->st_size
,
1917 ELFW(ST_INFO
)(STB_GLOBAL
,STT_FUNC
), 0, 0,
1919 int index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1920 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1921 } else if (type
== STT_OBJECT
) {
1922 unsigned long offset
;
1924 offset
= bss_section
->data_offset
;
1925 /* XXX: which alignment ? */
1926 offset
= (offset
+ 16 - 1) & -16;
1927 set_elf_sym (s1
->symtab
, offset
, esym
->st_size
,
1928 esym
->st_info
, 0, bss_section
->sh_num
, name
);
1929 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1930 esym
->st_info
, 0, bss_section
->sh_num
,
1933 /* Ensure R_COPY works for weak symbol aliases */
1934 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1935 for_each_elem(s1
->dynsymtab_section
, 1, dynsym
, ElfW(Sym
)) {
1936 if ((dynsym
->st_value
== esym
->st_value
)
1937 && (ELFW(ST_BIND
)(dynsym
->st_info
) == STB_GLOBAL
)) {
1938 char *dynname
= (char *) s1
->dynsymtab_section
->link
->data
1940 put_elf_sym(s1
->dynsym
, offset
, dynsym
->st_size
,
1942 bss_section
->sh_num
, dynname
);
1948 put_elf_reloc(s1
->dynsym
, bss_section
,
1949 offset
, R_COPY
, index
);
1950 offset
+= esym
->st_size
;
1951 bss_section
->data_offset
= offset
;
1954 /* STB_WEAK undefined symbols are accepted */
1955 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1956 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1957 !strcmp(name
, "_fp_hw")) {
1959 tcc_error_noabort("undefined symbol '%s'", name
);
1966 /* Bind symbols of libraries: export all non local symbols of executable that
1967 are referenced by shared libraries. The reason is that the dynamic loader
1968 search symbol first in executable and then in libraries. Therefore a
1969 reference to a symbol already defined by a library can still be resolved by
1970 a symbol in the executable. With -rdynamic, export all defined symbols */
1971 static void bind_libs_dynsyms(TCCState
*s1
)
1975 ElfW(Sym
) *sym
, *esym
;
1977 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1978 name
= (char *)symtab_section
->link
->data
+ sym
->st_name
;
1979 dynsym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1980 if (sym
->st_shndx
!= SHN_UNDEF
) {
1981 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
1982 && (dynsym_index
|| s1
->rdynamic
))
1983 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1984 sym
->st_info
, 0, sym
->st_shndx
, name
);
1985 } else if (dynsym_index
) {
1986 esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ dynsym_index
;
1987 if (esym
->st_shndx
== SHN_UNDEF
) {
1988 /* weak symbols can stay undefined */
1989 if (ELFW(ST_BIND
)(esym
->st_info
) != STB_WEAK
)
1990 tcc_warning("undefined dynamic symbol '%s'", name
);
1996 /* Export all non local symbols. This is used by shared libraries so that the
1997 non local symbols they define can resolve a reference in another shared
1998 library or in the executable. Correspondingly, it allows undefined local
1999 symbols to be resolved by other shared libraries or by the executable. */
2000 static void export_global_syms(TCCState
*s1
)
2002 int dynindex
, index
;
2005 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
2006 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2007 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
2008 dynindex
= set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
2009 sym
->st_info
, 0, sym
->st_shndx
, name
);
2010 index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
2011 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
2016 /* decide if an unallocated section should be output. */
2017 static int set_sec_sizes(TCCState
*s1
)
2022 int file_type
= s1
->output_type
;
2024 /* Allocate strings for section names */
2025 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2026 s
= s1
->sections
[i
];
2027 if (s
->sh_type
== SHT_RELX
&& !(s
->sh_flags
& SHF_ALLOC
)) {
2028 /* when generating a DLL, we include relocations but
2029 we may patch them */
2030 if ((file_type
& TCC_OUTPUT_DYN
)
2031 && (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)) {
2032 int count
= prepare_dynamic_rel(s1
, s
);
2034 /* allocate the section */
2035 s
->sh_flags
|= SHF_ALLOC
;
2036 s
->sh_size
= count
* sizeof(ElfW_Rel
);
2037 if (!(s1
->sections
[s
->sh_info
]->sh_flags
& SHF_WRITE
))
2041 } else if ((s
->sh_flags
& SHF_ALLOC
)
2042 #ifdef TCC_TARGET_ARM
2043 || s
->sh_type
== SHT_ARM_ATTRIBUTES
2046 s
->sh_size
= s
->data_offset
;
2049 #ifdef TCC_TARGET_ARM
2050 /* XXX: Suppress stack unwinding section. */
2051 if (s
->sh_type
== SHT_ARM_EXIDX
) {
2061 /* various data used under elf_output_file() */
2066 /* Info to be copied in dynamic section */
2067 unsigned long data_offset
;
2078 /* read only segment mapping for GNU_RELRO */
2079 Section _roinf
, *roinf
;
2082 /* Decide the layout of sections loaded in memory. This must be done before
2083 program headers are filled since they contain info about the layout.
2084 We do the following ordering: interp, symbol tables, relocations, progbits,
2086 static int sort_sections(TCCState
*s1
, int *sec_order
, Section
*interp
)
2089 int i
, j
, k
, f
, f0
, n
;
2090 int nb_sections
= s1
->nb_sections
;
2091 int *sec_cls
= sec_order
+ nb_sections
;
2093 for (i
= 1; i
< nb_sections
; i
++) {
2094 s
= s1
->sections
[i
];
2095 if (s
->sh_flags
& SHF_ALLOC
) {
2097 if (s
->sh_flags
& SHF_WRITE
)
2099 if (s
->sh_flags
& SHF_TLS
)
2101 } else if (s
->sh_name
) {
2104 j
= 0x900; /* no sh_name: won't go to file */
2106 if (s
->sh_type
== SHT_SYMTAB
|| s
->sh_type
== SHT_DYNSYM
) {
2108 } else if (s
->sh_type
== SHT_STRTAB
&& strcmp(s
->name
, ".stabstr")) {
2110 if (i
== nb_sections
- 1) /* ".shstrtab" assumed to remain last */
2112 } else if (s
->sh_type
== SHT_HASH
|| s
->sh_type
== SHT_GNU_HASH
) {
2114 } else if (s
->sh_type
== SHT_RELX
) {
2116 if (s1
->plt
&& s
== s1
->plt
->reloc
)
2118 } else if (s
->sh_type
== SHT_PREINIT_ARRAY
) {
2120 } else if (s
->sh_type
== SHT_INIT_ARRAY
) {
2122 } else if (s
->sh_type
== SHT_FINI_ARRAY
) {
2124 #ifdef CONFIG_TCC_BCHECK
2125 } else if (s
== bounds_section
|| s
== lbounds_section
) {
2128 } else if (s
== rodata_section
|| 0 == strcmp(s
->name
, ".data.rel.ro")) {
2130 } else if (s
->sh_type
== SHT_DYNAMIC
) {
2132 } else if (s
== s1
->got
) {
2133 k
= 0x47; /* .got as RELRO needs BIND_NOW in DT_FLAGS */
2136 if (s
->sh_type
== SHT_NOTE
)
2138 if (s
->sh_flags
& SHF_EXECINSTR
)
2140 if (s
->sh_type
== SHT_NOBITS
)
2147 for (n
= i
; n
> 1 && k
< (f
= sec_cls
[n
- 1]); --n
)
2148 sec_cls
[n
] = f
, sec_order
[n
] = sec_order
[n
- 1];
2149 sec_cls
[n
] = k
, sec_order
[n
] = i
;
2153 /* count PT_LOAD headers needed */
2155 for (i
= 1; i
< nb_sections
; i
++) {
2156 s
= s1
->sections
[sec_order
[i
]];
2160 f
= s
->sh_flags
& (SHF_ALLOC
|SHF_WRITE
|SHF_EXECINSTR
|SHF_TLS
);
2162 /* NetBSD only supports 2 PT_LOAD sections.
2163 See: https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */
2164 if ((f
& SHF_WRITE
) == 0) f
|= SHF_EXECINSTR
;
2166 if ((k
& 0xfff0) == 0x240) /* RELRO sections */
2169 if (f
!= f0
) /* start new header when flags changed or relro */
2170 f0
= f
, ++n
, f
|= 1<<8;
2173 //printf("ph %d sec %02d : %3X %3X %8.2X %04X %s\n", !!f * n, i, f, k, s->sh_type, s->sh_size, s->name);
2178 static ElfW(Phdr
) *fill_phdr(ElfW(Phdr
) *ph
, int type
, Section
*s
)
2181 ph
->p_offset
= s
->sh_offset
;
2182 ph
->p_vaddr
= s
->sh_addr
;
2183 ph
->p_filesz
= s
->sh_size
;
2184 ph
->p_align
= s
->sh_addralign
;
2188 ph
->p_paddr
= ph
->p_vaddr
;
2189 ph
->p_memsz
= ph
->p_filesz
;
2193 /* Assign sections to segments and decide how are sections laid out when loaded
2194 in memory. This function also fills corresponding program headers. */
2195 static int layout_sections(TCCState
*s1
, int *sec_order
, struct dyn_inf
*d
)
2198 addr_t addr
, tmp
, align
, s_align
, base
;
2199 ElfW(Phdr
) *ph
= NULL
;
2200 int i
, f
, n
, phnum
, phfill
;
2203 /* compute number of program headers */
2204 phnum
= sort_sections(s1
, sec_order
, d
->interp
);
2205 phfill
= 0; /* set to 1 to have dll's with a PT_PHDR */
2216 d
->phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
2219 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2220 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2222 s_align
= ELF_PAGE_SIZE
;
2223 if (s1
->section_align
)
2224 s_align
= s1
->section_align
;
2226 addr
= ELF_START_ADDR
;
2227 if (s1
->output_type
& TCC_OUTPUT_DYN
)
2230 if (s1
->has_text_addr
) {
2231 addr
= s1
->text_addr
;
2233 int a_offset
, p_offset
;
2234 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
2236 a_offset
= (int) (addr
& (s_align
- 1));
2237 p_offset
= file_offset
& (s_align
- 1);
2238 if (a_offset
< p_offset
)
2239 a_offset
+= s_align
;
2240 file_offset
+= (a_offset
- p_offset
);
2244 /* compute address after headers */
2245 addr
= addr
+ (file_offset
& (s_align
- 1));
2248 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2249 s
= s1
->sections
[sec_order
[i
]];
2250 f
= sec_order
[i
+ s1
->nb_sections
];
2251 align
= s
->sh_addralign
- 1;
2253 if (f
== 0) { /* no alloc */
2254 file_offset
= (file_offset
+ align
) & ~align
;
2255 s
->sh_offset
= file_offset
;
2256 if (s
->sh_type
!= SHT_NOBITS
)
2257 file_offset
+= s
->sh_size
;
2261 if ((f
& 1<<8) && n
) {
2262 /* different rwx section flags */
2263 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
2264 /* if in the middle of a page, w e duplicate the page in
2265 memory so that one copy is RX and the other is RW */
2266 if ((addr
& (s_align
- 1)) != 0)
2269 align
= s_align
- 1;
2274 addr
= (addr
+ align
) & ~align
;
2275 file_offset
+= (int)(addr
- tmp
);
2276 s
->sh_offset
= file_offset
;
2280 /* set new program header */
2281 ph
= &d
->phdr
[phfill
+ n
];
2282 ph
->p_type
= PT_LOAD
;
2283 ph
->p_align
= s_align
;
2286 ph
->p_flags
|= PF_W
;
2287 if (f
& SHF_EXECINSTR
)
2288 ph
->p_flags
|= PF_X
;
2290 ph
->p_type
= PT_TLS
;
2291 ph
->p_align
= align
+ 1;
2294 ph
->p_offset
= file_offset
;
2297 /* Make the first PT_LOAD segment include the program
2298 headers itself (and the ELF header as well), it'll
2299 come out with same memory use but will make various
2300 tools like binutils strip work better. */
2304 ph
->p_paddr
= ph
->p_vaddr
;
2309 Section
*roinf
= &d
->_roinf
;
2310 if (roinf
->sh_size
== 0) {
2311 roinf
->sh_offset
= s
->sh_offset
;
2312 roinf
->sh_addr
= s
->sh_addr
;
2313 roinf
->sh_addralign
= 1;
2315 roinf
->sh_size
= (addr
- roinf
->sh_addr
) + s
->sh_size
;
2319 if (s
->sh_type
!= SHT_NOBITS
)
2320 file_offset
+= s
->sh_size
;
2322 ph
->p_filesz
= file_offset
- ph
->p_offset
;
2323 ph
->p_memsz
= addr
- ph
->p_vaddr
;
2326 /* Fill other headers */
2328 fill_phdr(++ph
, PT_NOTE
, d
->note
);
2330 fill_phdr(++ph
, PT_DYNAMIC
, d
->dynamic
)->p_flags
|= PF_W
;
2332 fill_phdr(++ph
, PT_GNU_RELRO
, d
->roinf
)->p_flags
|= PF_W
;
2334 fill_phdr(&d
->phdr
[1], PT_INTERP
, d
->interp
);
2337 ph
->p_offset
= sizeof(ElfW(Ehdr
));
2338 ph
->p_vaddr
= base
+ ph
->p_offset
;
2339 ph
->p_filesz
= phnum
* sizeof(ElfW(Phdr
));
2341 fill_phdr(ph
, PT_PHDR
, NULL
);
2346 /* put dynamic tag */
2347 static void put_dt(Section
*dynamic
, int dt
, addr_t val
)
2350 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
2352 dyn
->d_un
.d_val
= val
;
2355 /* Fill the dynamic section with tags describing the address and size of
2357 static void fill_dynamic(TCCState
*s1
, struct dyn_inf
*dyninf
)
2359 Section
*dynamic
= dyninf
->dynamic
;
2362 /* put dynamic section entries */
2363 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
2364 put_dt(dynamic
, DT_GNU_HASH
, dyninf
->gnu_hash
->sh_addr
);
2365 put_dt(dynamic
, DT_STRTAB
, dyninf
->dynstr
->sh_addr
);
2366 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
2367 put_dt(dynamic
, DT_STRSZ
, dyninf
->dynstr
->data_offset
);
2368 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
2370 put_dt(dynamic
, DT_RELA
, dyninf
->rel_addr
);
2371 put_dt(dynamic
, DT_RELASZ
, dyninf
->rel_size
);
2372 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
2373 if (s1
->plt
&& s1
->plt
->reloc
) {
2374 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2375 put_dt(dynamic
, DT_PLTRELSZ
, s1
->plt
->reloc
->data_offset
);
2376 put_dt(dynamic
, DT_JMPREL
, s1
->plt
->reloc
->sh_addr
);
2377 put_dt(dynamic
, DT_PLTREL
, DT_RELA
);
2379 put_dt(dynamic
, DT_RELACOUNT
, 0);
2381 put_dt(dynamic
, DT_REL
, dyninf
->rel_addr
);
2382 put_dt(dynamic
, DT_RELSZ
, dyninf
->rel_size
);
2383 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
2384 if (s1
->plt
&& s1
->plt
->reloc
) {
2385 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2386 put_dt(dynamic
, DT_PLTRELSZ
, s1
->plt
->reloc
->data_offset
);
2387 put_dt(dynamic
, DT_JMPREL
, s1
->plt
->reloc
->sh_addr
);
2388 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
2390 put_dt(dynamic
, DT_RELCOUNT
, 0);
2392 if (versym_section
&& verneed_section
) {
2393 /* The dynamic linker can not handle VERSYM without VERNEED */
2394 put_dt(dynamic
, DT_VERSYM
, versym_section
->sh_addr
);
2395 put_dt(dynamic
, DT_VERNEED
, verneed_section
->sh_addr
);
2396 put_dt(dynamic
, DT_VERNEEDNUM
, dt_verneednum
);
2398 s
= have_section(s1
, ".preinit_array");
2399 if (s
&& s
->data_offset
) {
2400 put_dt(dynamic
, DT_PREINIT_ARRAY
, s
->sh_addr
);
2401 put_dt(dynamic
, DT_PREINIT_ARRAYSZ
, s
->data_offset
);
2403 s
= have_section(s1
, ".init_array");
2404 if (s
&& s
->data_offset
) {
2405 put_dt(dynamic
, DT_INIT_ARRAY
, s
->sh_addr
);
2406 put_dt(dynamic
, DT_INIT_ARRAYSZ
, s
->data_offset
);
2408 s
= have_section(s1
, ".fini_array");
2409 if (s
&& s
->data_offset
) {
2410 put_dt(dynamic
, DT_FINI_ARRAY
, s
->sh_addr
);
2411 put_dt(dynamic
, DT_FINI_ARRAYSZ
, s
->data_offset
);
2413 s
= have_section(s1
, ".init");
2414 if (s
&& s
->data_offset
) {
2415 put_dt(dynamic
, DT_INIT
, s
->sh_addr
);
2417 s
= have_section(s1
, ".fini");
2418 if (s
&& s
->data_offset
) {
2419 put_dt(dynamic
, DT_FINI
, s
->sh_addr
);
2422 put_dt(dynamic
, DT_DEBUG
, 0);
2423 put_dt(dynamic
, DT_NULL
, 0);
2426 /* Remove gaps between RELX sections.
2427 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2428 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2429 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2430 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2431 static void update_reloc_sections(TCCState
*s1
, struct dyn_inf
*dyninf
)
2434 unsigned long file_offset
= 0;
2436 Section
*relocplt
= s1
->plt
? s1
->plt
->reloc
: NULL
;
2438 /* dynamic relocation table information, for .dynamic section */
2439 dyninf
->rel_addr
= dyninf
->rel_size
= 0;
2441 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2442 s
= s1
->sections
[i
];
2443 if (s
->sh_type
== SHT_RELX
&& s
!= relocplt
) {
2444 if (dyninf
->rel_size
== 0) {
2445 dyninf
->rel_addr
= s
->sh_addr
;
2446 file_offset
= s
->sh_offset
;
2449 s
->sh_addr
= dyninf
->rel_addr
+ dyninf
->rel_size
;
2450 s
->sh_offset
= file_offset
+ dyninf
->rel_size
;
2452 dyninf
->rel_size
+= s
->sh_size
;
2457 static int tidy_section_headers(TCCState
*s1
, int *sec_order
);
2458 #endif /* ndef ELF_OBJ_ONLY */
2460 /* Create an ELF file on disk.
2461 This function handle ELF specific layout requirements */
2462 static int tcc_output_elf(TCCState
*s1
, FILE *f
, int phnum
, ElfW(Phdr
) *phdr
,
2463 int file_offset
, int *sec_order
)
2465 int i
, shnum
, offset
, size
, file_type
;
2468 ElfW(Shdr
) shdr
, *sh
;
2470 file_type
= s1
->output_type
;
2471 shnum
= s1
->nb_sections
;
2473 memset(&ehdr
, 0, sizeof(ehdr
));
2476 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2477 ehdr
.e_phnum
= phnum
;
2478 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2479 #ifndef ELF_OBJ_ONLY
2480 shnum
= tidy_section_headers(s1
, sec_order
);
2485 file_offset
= (file_offset
+ 3) & -4;
2488 ehdr
.e_ident
[0] = ELFMAG0
;
2489 ehdr
.e_ident
[1] = ELFMAG1
;
2490 ehdr
.e_ident
[2] = ELFMAG2
;
2491 ehdr
.e_ident
[3] = ELFMAG3
;
2492 ehdr
.e_ident
[4] = ELFCLASSW
;
2493 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2494 ehdr
.e_ident
[6] = EV_CURRENT
;
2496 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2497 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2498 #elif defined TCC_TARGET_ARM && defined TCC_ARM_EABI
2499 ehdr
.e_flags
= EF_ARM_EABI_VER5
;
2500 ehdr
.e_flags
|= s1
->float_abi
== ARM_HARD_FLOAT
2501 ? EF_ARM_VFP_FLOAT
: EF_ARM_SOFT_FLOAT
;
2502 #elif defined TCC_TARGET_ARM
2503 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2504 #elif defined TCC_TARGET_RISCV64
2505 ehdr
.e_flags
= EF_RISCV_FLOAT_ABI_DOUBLE
;
2508 if (file_type
== TCC_OUTPUT_OBJ
) {
2509 ehdr
.e_type
= ET_REL
;
2511 if (file_type
& TCC_OUTPUT_DYN
)
2512 ehdr
.e_type
= ET_DYN
;
2514 ehdr
.e_type
= ET_EXEC
;
2515 if (s1
->elf_entryname
)
2516 ehdr
.e_entry
= get_sym_addr(s1
, s1
->elf_entryname
, 1, 0);
2518 ehdr
.e_entry
= get_sym_addr(s1
, "_start", !!(file_type
& TCC_OUTPUT_EXE
), 0);
2519 if (ehdr
.e_entry
== (addr_t
)-1)
2520 ehdr
.e_entry
= text_section
->sh_addr
;
2525 ehdr
.e_machine
= EM_TCC_TARGET
;
2526 ehdr
.e_version
= EV_CURRENT
;
2527 ehdr
.e_shoff
= file_offset
;
2528 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2529 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2530 ehdr
.e_shnum
= shnum
;
2531 ehdr
.e_shstrndx
= shnum
- 1;
2533 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2535 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2536 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2538 sort_syms(s1
, symtab_section
);
2540 for(i
= 1; i
< shnum
; i
++) {
2541 s
= s1
->sections
[sec_order
? sec_order
[i
] : i
];
2542 if (s
->sh_type
!= SHT_NOBITS
) {
2543 while (offset
< s
->sh_offset
) {
2549 fwrite(s
->data
, 1, size
, f
);
2554 /* output section headers */
2555 while (offset
< ehdr
.e_shoff
) {
2560 for(i
= 0; i
< shnum
; i
++) {
2562 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2563 s
= s1
->sections
[i
];
2565 sh
->sh_name
= s
->sh_name
;
2566 sh
->sh_type
= s
->sh_type
;
2567 sh
->sh_flags
= s
->sh_flags
;
2568 sh
->sh_entsize
= s
->sh_entsize
;
2569 sh
->sh_info
= s
->sh_info
;
2571 sh
->sh_link
= s
->link
->sh_num
;
2572 sh
->sh_addralign
= s
->sh_addralign
;
2573 sh
->sh_addr
= s
->sh_addr
;
2574 sh
->sh_offset
= s
->sh_offset
;
2575 sh
->sh_size
= s
->sh_size
;
2577 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2582 static int tcc_output_binary(TCCState
*s1
, FILE *f
,
2583 const int *sec_order
)
2586 int i
, offset
, size
;
2589 for(i
=1;i
<s1
->nb_sections
;i
++) {
2590 s
= s1
->sections
[sec_order
[i
]];
2591 if (s
->sh_type
!= SHT_NOBITS
&&
2592 (s
->sh_flags
& SHF_ALLOC
)) {
2593 while (offset
< s
->sh_offset
) {
2598 fwrite(s
->data
, 1, size
, f
);
2605 /* Write an elf, coff or "binary" file */
2606 static int tcc_write_elf_file(TCCState
*s1
, const char *filename
, int phnum
,
2607 ElfW(Phdr
) *phdr
, int file_offset
, int *sec_order
)
2609 int fd
, mode
, file_type
, ret
;
2612 file_type
= s1
->output_type
;
2613 if (file_type
== TCC_OUTPUT_OBJ
)
2618 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2619 if (fd
< 0 || (f
= fdopen(fd
, "wb")) == NULL
)
2620 return tcc_error_noabort("could not write '%s: %s'", filename
, strerror(errno
));
2622 printf("<- %s\n", filename
);
2623 #ifdef TCC_TARGET_COFF
2624 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
)
2625 tcc_output_coff(s1
, f
);
2628 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2629 ret
= tcc_output_elf(s1
, f
, phnum
, phdr
, file_offset
, sec_order
);
2631 ret
= tcc_output_binary(s1
, f
, sec_order
);
2637 #ifndef ELF_OBJ_ONLY
2638 /* Sort section headers by assigned sh_addr, remove sections
2639 that we aren't going to output. */
2640 static int tidy_section_headers(TCCState
*s1
, int *sec_order
)
2642 int i
, nnew
, l
, *backmap
;
2646 snew
= tcc_malloc(s1
->nb_sections
* sizeof(snew
[0]));
2647 backmap
= tcc_malloc(s1
->nb_sections
* sizeof(backmap
[0]));
2648 for (i
= 0, nnew
= 0, l
= s1
->nb_sections
; i
< s1
->nb_sections
; i
++) {
2649 s
= s1
->sections
[sec_order
[i
]];
2650 if (!i
|| s
->sh_name
) {
2651 backmap
[sec_order
[i
]] = nnew
;
2655 backmap
[sec_order
[i
]] = 0;
2659 for (i
= 0; i
< nnew
; i
++) {
2663 if (s
->sh_type
== SHT_RELX
)
2664 s
->sh_info
= backmap
[s
->sh_info
];
2668 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
))
2669 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2670 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2671 if ( !s1
->static_link
) {
2672 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
))
2673 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2674 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2676 for (i
= 0; i
< s1
->nb_sections
; i
++)
2678 tcc_free(s1
->sections
);
2679 s1
->sections
= snew
;
2684 #ifdef TCC_TARGET_ARM
2685 static void create_arm_attribute_section(TCCState
*s1
)
2687 // Needed for DLL support.
2688 static const unsigned char arm_attr
[] = {
2690 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2691 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2692 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2693 0x05, 0x36, 0x00, // 'CPU_name', "6"
2694 0x06, 0x06, // 'CPU_arch', 'v6'
2695 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2696 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2697 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2698 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2699 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2700 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2701 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2702 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2703 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2704 0x1a, 0x02, // 'ABI_enum_size', 'int'
2705 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2706 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2708 Section
*attr
= new_section(s1
, ".ARM.attributes", SHT_ARM_ATTRIBUTES
, 0);
2709 unsigned char *ptr
= section_ptr_add(attr
, sizeof(arm_attr
));
2710 attr
->sh_addralign
= 1;
2711 memcpy(ptr
, arm_attr
, sizeof(arm_attr
));
2712 if (s1
->float_abi
!= ARM_HARD_FLOAT
) {
2713 ptr
[26] = 0x00; // 'FP_arch', 'No'
2714 ptr
[41] = 0x1e; // 'ABI_optimization_goals'
2715 ptr
[42] = 0x06; // 'Aggressive Debug'
2720 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2721 static Section
*create_bsd_note_section(TCCState
*s1
,
2725 Section
*s
= find_section (s1
, name
);
2727 if (s
->data_offset
== 0) {
2728 char *ptr
= section_ptr_add(s
, sizeof(ElfW(Nhdr
)) + 8 + 4);
2729 ElfW(Nhdr
) *note
= (ElfW(Nhdr
) *) ptr
;
2731 s
->sh_type
= SHT_NOTE
;
2734 note
->n_type
= ELF_NOTE_OS_GNU
;
2735 strcpy (ptr
+ sizeof(ElfW(Nhdr
)), value
);
2741 static void alloc_sec_names(TCCState
*s1
, int is_obj
);
2743 /* Output an elf, coff or binary file */
2744 /* XXX: suppress unneeded sections */
2745 static int elf_output_file(TCCState
*s1
, const char *filename
)
2747 int i
, ret
, file_type
, file_offset
, *sec_order
;
2748 struct dyn_inf dyninf
= {0};
2749 Section
*interp
, *dynstr
, *dynamic
;
2750 int textrel
, got_sym
, dt_flags_1
;
2752 file_type
= s1
->output_type
;
2755 interp
= dynstr
= dynamic
= NULL
;
2757 dyninf
.roinf
= &dyninf
._roinf
;
2759 #ifdef TCC_TARGET_ARM
2760 create_arm_attribute_section (s1
);
2763 #if TARGETOS_OpenBSD
2764 dyninf
.note
= create_bsd_note_section (s1
, ".note.openbsd.ident", "OpenBSD");
2768 dyninf
.note
= create_bsd_note_section (s1
, ".note.netbsd.ident", "NetBSD");
2771 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
2772 dyninf
.roinf
= NULL
;
2774 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2775 tcc_add_runtime(s1
);
2776 resolve_common_syms(s1
);
2778 if (!s1
->static_link
) {
2779 if (file_type
& TCC_OUTPUT_EXE
) {
2781 /* allow override the dynamic loader */
2782 const char *elfint
= getenv("LD_SO");
2784 elfint
= DEFAULT_ELFINTERP(s1
);
2785 /* add interpreter section only if executable */
2786 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
2787 interp
->sh_addralign
= 1;
2788 ptr
= section_ptr_add(interp
, 1 + strlen(elfint
));
2789 strcpy(ptr
, elfint
);
2790 dyninf
.interp
= interp
;
2793 /* add dynamic symbol table */
2794 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
2796 ".hash", SHF_ALLOC
);
2797 /* Number of local symbols (readelf complains if not set) */
2798 s1
->dynsym
->sh_info
= 1;
2799 dynstr
= s1
->dynsym
->link
;
2800 /* add dynamic section */
2801 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
2802 SHF_ALLOC
| SHF_WRITE
);
2803 dynamic
->link
= dynstr
;
2804 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
2806 got_sym
= build_got(s1
);
2807 if (file_type
& TCC_OUTPUT_EXE
) {
2808 bind_exe_dynsyms(s1
, file_type
& TCC_OUTPUT_DYN
);
2812 build_got_entries(s1
, got_sym
);
2813 if (file_type
& TCC_OUTPUT_EXE
) {
2814 bind_libs_dynsyms(s1
);
2816 /* shared library case: simply export all global symbols */
2817 export_global_syms(s1
);
2819 dyninf
.gnu_hash
= create_gnu_hash(s1
);
2821 build_got_entries(s1
, 0);
2825 textrel
= set_sec_sizes(s1
);
2826 alloc_sec_names(s1
, 0);
2828 if (!s1
->static_link
) {
2829 /* add a list of needed dlls */
2830 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2831 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
2832 if (dllref
->level
== 0)
2833 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
2837 put_dt(dynamic
, s1
->enable_new_dtags
? DT_RUNPATH
: DT_RPATH
,
2838 put_elf_str(dynstr
, s1
->rpath
));
2840 dt_flags_1
= DF_1_NOW
;
2841 if (file_type
& TCC_OUTPUT_DYN
) {
2843 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
2844 /* XXX: currently, since we do not handle PIC code, we
2845 must relocate the readonly segments */
2847 put_dt(dynamic
, DT_TEXTREL
, 0);
2848 if (file_type
& TCC_OUTPUT_EXE
)
2849 dt_flags_1
= DF_1_NOW
| DF_1_PIE
;
2851 put_dt(dynamic
, DT_FLAGS
, DF_BIND_NOW
);
2852 put_dt(dynamic
, DT_FLAGS_1
, dt_flags_1
);
2854 put_dt(dynamic
, DT_SYMBOLIC
, 0);
2856 dyninf
.dynamic
= dynamic
;
2857 dyninf
.dynstr
= dynstr
;
2858 /* remember offset and reserve space for 2nd call below */
2859 dyninf
.data_offset
= dynamic
->data_offset
;
2860 fill_dynamic(s1
, &dyninf
);
2861 dynamic
->sh_size
= dynamic
->data_offset
;
2862 dynstr
->sh_size
= dynstr
->data_offset
;
2865 /* this array is used to reorder sections in the output file */
2866 sec_order
= tcc_malloc(sizeof(int) * 2 * s1
->nb_sections
);
2867 /* compute section to program header mapping */
2868 file_offset
= layout_sections(s1
, sec_order
, &dyninf
);
2871 /* put in GOT the dynamic section address and relocate PLT */
2872 write32le(s1
->got
->data
, dynamic
->sh_addr
);
2873 if (file_type
== TCC_OUTPUT_EXE
2874 || (RELOCATE_DLLPLT
&& (file_type
& TCC_OUTPUT_DYN
)))
2876 /* relocate symbols in .dynsym now that final addresses are known */
2877 relocate_syms(s1
, s1
->dynsym
, 2);
2880 /* if building executable or DLL, then relocate each section
2881 except the GOT which is already relocated */
2882 relocate_syms(s1
, s1
->symtab
, 0);
2883 if (s1
->nb_errors
!= 0)
2885 relocate_sections(s1
);
2887 update_reloc_sections (s1
, &dyninf
);
2888 dynamic
->data_offset
= dyninf
.data_offset
;
2889 fill_dynamic(s1
, &dyninf
);
2891 /* Perform relocation to GOT or PLT entries */
2892 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2895 fill_local_got_entries(s1
);
2897 if (dyninf
.gnu_hash
)
2898 update_gnu_hash(s1
, dyninf
.gnu_hash
);
2900 /* Create the ELF file with name 'filename' */
2901 ret
= tcc_write_elf_file(s1
, filename
, dyninf
.phnum
, dyninf
.phdr
, file_offset
, sec_order
);
2903 tcc_free(sec_order
);
2904 tcc_free(dyninf
.phdr
);
2907 #endif /* ndef ELF_OBJ_ONLY */
2909 /* Allocate strings for section names */
2910 static void alloc_sec_names(TCCState
*s1
, int is_obj
)
2913 Section
*s
, *strsec
;
2915 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
2916 put_elf_str(strsec
, "");
2917 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2918 s
= s1
->sections
[i
];
2920 s
->sh_size
= s
->data_offset
;
2921 if (s
== strsec
|| s
->sh_size
|| (s
->sh_flags
& SHF_ALLOC
))
2922 s
->sh_name
= put_elf_str(strsec
, s
->name
);
2924 strsec
->sh_size
= strsec
->data_offset
;
2927 /* Output an elf .o file */
2928 static int elf_output_obj(TCCState
*s1
, const char *filename
)
2931 int i
, ret
, file_offset
;
2933 /* Allocate strings for section names */
2934 alloc_sec_names(s1
, 1);
2935 file_offset
= sizeof (ElfW(Ehdr
));
2936 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2937 s
= s1
->sections
[i
];
2938 file_offset
= (file_offset
+ 15) & -16;
2939 s
->sh_offset
= file_offset
;
2940 if (s
->sh_type
!= SHT_NOBITS
)
2941 file_offset
+= s
->sh_size
;
2943 /* Create the ELF file with name 'filename' */
2944 ret
= tcc_write_elf_file(s1
, filename
, 0, NULL
, file_offset
, NULL
);
2948 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2950 if (s
->test_coverage
)
2951 tcc_tcov_add_file(s
, filename
);
2952 if (s
->output_type
== TCC_OUTPUT_OBJ
)
2953 return elf_output_obj(s
, filename
);
2954 #ifdef TCC_TARGET_PE
2955 return pe_output_file(s
, filename
);
2956 #elif TCC_TARGET_MACHO
2957 return macho_output_file(s
, filename
);
2959 return elf_output_file(s
, filename
);
2963 ST_FUNC ssize_t
full_read(int fd
, void *buf
, size_t count
) {
2967 ssize_t num
= read(fd
, cbuf
, count
-rnum
);
2968 if (num
< 0) return num
;
2969 if (num
== 0) return rnum
;
2975 ST_FUNC
void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2979 data
= tcc_malloc(size
);
2980 lseek(fd
, file_offset
, SEEK_SET
);
2981 full_read(fd
, data
, size
);
2985 typedef struct SectionMergeInfo
{
2986 Section
*s
; /* corresponding existing section */
2987 unsigned long offset
; /* offset of the new section in the existing section */
2988 uint8_t new_section
; /* true if section 's' was added */
2989 uint8_t link_once
; /* true if link once section */
2992 ST_FUNC
int tcc_object_type(int fd
, ElfW(Ehdr
) *h
)
2994 int size
= full_read(fd
, h
, sizeof *h
);
2995 if (size
== sizeof *h
&& 0 == memcmp(h
, ELFMAG
, 4)) {
2996 if (h
->e_type
== ET_REL
)
2997 return AFF_BINTYPE_REL
;
2998 if (h
->e_type
== ET_DYN
)
2999 return AFF_BINTYPE_DYN
;
3000 } else if (size
>= 8) {
3001 if (0 == memcmp(h
, ARMAG
, 8))
3002 return AFF_BINTYPE_AR
;
3003 #ifdef TCC_TARGET_COFF
3004 if (((struct filehdr
*)h
)->f_magic
== COFF_C67_MAGIC
)
3005 return AFF_BINTYPE_C67
;
3011 /* load an object file and merge it with current files */
3012 /* XXX: handle correctly stab (debug) info */
3013 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
3014 int fd
, unsigned long file_offset
)
3017 ElfW(Shdr
) *shdr
, *sh
;
3018 unsigned long size
, offset
, offseti
;
3019 int i
, j
, nb_syms
, sym_index
, ret
, seencompressed
;
3020 char *strsec
, *strtab
;
3021 int stab_index
, stabstr_index
;
3022 int *old_to_new_syms
;
3023 char *sh_name
, *name
;
3024 SectionMergeInfo
*sm_table
, *sm
;
3025 ElfW(Sym
) *sym
, *symtab
;
3029 lseek(fd
, file_offset
, SEEK_SET
);
3030 if (tcc_object_type(fd
, &ehdr
) != AFF_BINTYPE_REL
)
3032 /* test CPU specific stuff */
3033 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
3034 ehdr
.e_machine
!= EM_TCC_TARGET
) {
3036 return tcc_error_noabort("invalid object file");
3039 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
3040 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
3041 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
3043 /* load section names */
3044 sh
= &shdr
[ehdr
.e_shstrndx
];
3045 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
3047 /* load symtab and strtab */
3048 old_to_new_syms
= NULL
;
3053 stab_index
= stabstr_index
= 0;
3056 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3058 if (sh
->sh_type
== SHT_SYMTAB
) {
3060 tcc_error_noabort("object must contain only one symtab");
3063 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
3064 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
3065 sm_table
[i
].s
= symtab_section
;
3067 /* now load strtab */
3068 sh
= &shdr
[sh
->sh_link
];
3069 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
3071 if (sh
->sh_flags
& SHF_COMPRESSED
)
3075 /* now examine each section and try to merge its content with the
3077 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3078 /* no need to examine section name strtab */
3079 if (i
== ehdr
.e_shstrndx
)
3082 if (sh
->sh_type
== SHT_RELX
)
3083 sh
= &shdr
[sh
->sh_info
];
3084 /* ignore sections types we do not handle (plus relocs to those) */
3085 if (sh
->sh_type
!= SHT_PROGBITS
&&
3087 sh
->sh_type
!= SHT_ARM_EXIDX
&&
3089 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3090 sh
->sh_type
!= SHT_X86_64_UNWIND
&&
3092 sh
->sh_type
!= SHT_NOTE
&&
3093 sh
->sh_type
!= SHT_NOBITS
&&
3094 sh
->sh_type
!= SHT_PREINIT_ARRAY
&&
3095 sh
->sh_type
!= SHT_INIT_ARRAY
&&
3096 sh
->sh_type
!= SHT_FINI_ARRAY
&&
3097 strcmp(strsec
+ sh
->sh_name
, ".stabstr")
3100 if (seencompressed
&& 0 == strncmp(strsec
+ sh
->sh_name
, ".debug_", 7))
3104 sh_name
= strsec
+ sh
->sh_name
;
3105 if (sh
->sh_addralign
< 1)
3106 sh
->sh_addralign
= 1;
3107 /* find corresponding section, if any */
3108 for(j
= 1; j
< s1
->nb_sections
;j
++) {
3109 s
= s1
->sections
[j
];
3110 if (!strcmp(s
->name
, sh_name
)) {
3111 if (!strncmp(sh_name
, ".gnu.linkonce",
3112 sizeof(".gnu.linkonce") - 1)) {
3113 /* if a 'linkonce' section is already present, we
3114 do not add it again. It is a little tricky as
3115 symbols can still be defined in
3117 sm_table
[i
].link_once
= 1;
3121 if (s
== stab_section
)
3123 if (s
== stab_section
->link
)
3129 /* not found: create new section */
3130 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
& ~SHF_GROUP
);
3131 /* take as much info as possible from the section. sh_link and
3132 sh_info will be updated later */
3133 s
->sh_addralign
= sh
->sh_addralign
;
3134 s
->sh_entsize
= sh
->sh_entsize
;
3135 sm_table
[i
].new_section
= 1;
3137 if (sh
->sh_type
!= s
->sh_type
3138 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
3139 && strcmp (s
->name
, ".eh_frame")
3142 tcc_error_noabort("invalid section type");
3145 /* align start of section */
3146 s
->data_offset
+= -s
->data_offset
& (sh
->sh_addralign
- 1);
3147 if (sh
->sh_addralign
> s
->sh_addralign
)
3148 s
->sh_addralign
= sh
->sh_addralign
;
3149 sm_table
[i
].offset
= s
->data_offset
;
3151 /* concatenate sections */
3153 if (sh
->sh_type
!= SHT_NOBITS
) {
3155 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
3156 ptr
= section_ptr_add(s
, size
);
3157 full_read(fd
, ptr
, size
);
3159 s
->data_offset
+= size
;
3164 /* gr relocate stab strings */
3165 if (stab_index
&& stabstr_index
) {
3168 s
= sm_table
[stab_index
].s
;
3169 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
3170 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
3171 o
= sm_table
[stabstr_index
].offset
;
3179 /* second short pass to update sh_link and sh_info fields of new
3181 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3183 if (!s
|| !sm_table
[i
].new_section
)
3186 if (sh
->sh_link
> 0)
3187 s
->link
= sm_table
[sh
->sh_link
].s
;
3188 if (sh
->sh_type
== SHT_RELX
) {
3189 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
3190 /* update backward link */
3191 s1
->sections
[s
->sh_info
]->reloc
= s
;
3195 /* resolve symbols */
3196 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
3199 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
3200 if (sym
->st_shndx
!= SHN_UNDEF
&&
3201 sym
->st_shndx
< SHN_LORESERVE
) {
3202 sm
= &sm_table
[sym
->st_shndx
];
3203 if (sm
->link_once
) {
3204 /* if a symbol is in a link once section, we use the
3205 already defined symbol. It is very important to get
3206 correct relocations */
3207 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
3208 name
= strtab
+ sym
->st_name
;
3209 sym_index
= find_elf_sym(symtab_section
, name
);
3211 old_to_new_syms
[i
] = sym_index
;
3215 /* if no corresponding section added, no need to add symbol */
3218 /* convert section number */
3219 sym
->st_shndx
= sm
->s
->sh_num
;
3221 sym
->st_value
+= sm
->offset
;
3224 name
= strtab
+ sym
->st_name
;
3225 sym_index
= set_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
3226 sym
->st_info
, sym
->st_other
,
3227 sym
->st_shndx
, name
);
3228 old_to_new_syms
[i
] = sym_index
;
3231 /* third pass to patch relocation entries */
3232 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3237 offset
= sm_table
[i
].offset
;
3239 switch(s
->sh_type
) {
3241 /* take relocation offset information */
3242 offseti
= sm_table
[sh
->sh_info
].offset
;
3243 for (rel
= (ElfW_Rel
*) s
->data
+ (offset
/ sizeof(*rel
));
3244 rel
< (ElfW_Rel
*) s
->data
+ ((offset
+ size
) / sizeof(*rel
));
3248 /* convert symbol index */
3249 type
= ELFW(R_TYPE
)(rel
->r_info
);
3250 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
3251 /* NOTE: only one symtab assumed */
3252 if (sym_index
>= nb_syms
)
3254 sym_index
= old_to_new_syms
[sym_index
];
3255 /* ignore link_once in rel section. */
3256 if (!sym_index
&& !sm_table
[sh
->sh_info
].link_once
3257 #ifdef TCC_TARGET_ARM
3258 && type
!= R_ARM_V4BX
3259 #elif defined TCC_TARGET_RISCV64
3260 && type
!= R_RISCV_ALIGN
3261 && type
!= R_RISCV_RELAX
3265 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3266 i
, strsec
+ sh
->sh_name
, (int)rel
->r_offset
);
3269 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
3270 /* offset the relocation offset */
3271 rel
->r_offset
+= offseti
;
3272 #ifdef TCC_TARGET_ARM
3273 /* Jumps and branches from a Thumb code to a PLT entry need
3274 special handling since PLT entries are ARM code.
3275 Unconditional bl instructions referencing PLT entries are
3276 handled by converting these instructions into blx
3277 instructions. Other case of instructions referencing a PLT
3278 entry require to add a Thumb stub before the PLT entry to
3279 switch to ARM mode. We set bit plt_thumb_stub of the
3280 attribute of a symbol to indicate such a case. */
3281 if (type
== R_ARM_THM_JUMP24
)
3282 get_sym_attr(s1
, sym_index
, 1)->plt_thumb_stub
= 1;
3295 tcc_free(old_to_new_syms
);
3302 typedef struct ArchiveHeader
{
3303 char ar_name
[16]; /* name of this member */
3304 char ar_date
[12]; /* file mtime */
3305 char ar_uid
[6]; /* owner uid; printed as decimal */
3306 char ar_gid
[6]; /* owner gid; printed as decimal */
3307 char ar_mode
[8]; /* file mode, printed as octal */
3308 char ar_size
[10]; /* file size, printed as decimal */
3309 char ar_fmag
[2]; /* should contain ARFMAG */
3312 #define ARFMAG "`\n"
3314 static unsigned long long get_be(const uint8_t *b
, int n
)
3316 unsigned long long ret
= 0;
3318 ret
= (ret
<< 8) | *b
++, --n
;
3322 static int read_ar_header(int fd
, int offset
, ArchiveHeader
*hdr
)
3326 lseek(fd
, offset
, SEEK_SET
);
3327 len
= full_read(fd
, hdr
, sizeof(ArchiveHeader
));
3328 if (len
!= sizeof(ArchiveHeader
))
3329 return len
? -1 : 0;
3331 for (e
= p
+ sizeof hdr
->ar_name
; e
> p
&& e
[-1] == ' ';)
3334 hdr
->ar_size
[sizeof hdr
->ar_size
-1] = 0;
3338 /* load only the objects which resolve undefined symbols */
3339 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
, int entrysize
)
3341 int i
, bound
, nsyms
, sym_index
, len
, ret
= -1;
3342 unsigned long long off
;
3344 const char *ar_names
, *p
;
3345 const uint8_t *ar_index
;
3349 data
= tcc_malloc(size
);
3350 if (full_read(fd
, data
, size
) != size
)
3352 nsyms
= get_be(data
, entrysize
);
3353 ar_index
= data
+ entrysize
;
3354 ar_names
= (char *) ar_index
+ nsyms
* entrysize
;
3358 for (p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
3359 Section
*s
= symtab_section
;
3360 sym_index
= find_elf_sym(s
, p
);
3363 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
3364 if(sym
->st_shndx
!= SHN_UNDEF
)
3366 off
= get_be(ar_index
+ i
* entrysize
, entrysize
);
3367 len
= read_ar_header(fd
, off
, &hdr
);
3368 if (len
<= 0 || memcmp(hdr
.ar_fmag
, ARFMAG
, 2)) {
3369 tcc_error_noabort("invalid archive");
3373 if (s1
->verbose
== 2)
3374 printf(" -> %s\n", hdr
.ar_name
);
3375 if (tcc_load_object_file(s1
, fd
, off
) < 0)
3386 /* load a '.a' file */
3387 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
, int alacarte
)
3390 /* char magic[8]; */
3392 unsigned long file_offset
;
3395 /* skip magic which was already checked */
3396 /* full_read(fd, magic, sizeof(magic)); */
3397 file_offset
= sizeof ARMAG
- 1;
3400 len
= read_ar_header(fd
, file_offset
, &hdr
);
3404 return tcc_error_noabort("invalid archive");
3406 size
= strtol(hdr
.ar_size
, NULL
, 0);
3408 size
= (size
+ 1) & ~1;
3410 /* coff symbol table : we handle it */
3411 if (!strcmp(hdr
.ar_name
, "/"))
3412 return tcc_load_alacarte(s1
, fd
, size
, 4);
3413 if (!strcmp(hdr
.ar_name
, "/SYM64/"))
3414 return tcc_load_alacarte(s1
, fd
, size
, 8);
3415 } else if (tcc_object_type(fd
, &ehdr
) == AFF_BINTYPE_REL
) {
3416 if (s1
->verbose
== 2)
3417 printf(" -> %s\n", hdr
.ar_name
);
3418 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
3421 file_offset
+= size
;
3425 #ifndef ELF_OBJ_ONLY
3426 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3427 LV, maybe create a new entry for (LIB,VERSION). */
3428 static void set_ver_to_ver(TCCState
*s1
, int *n
, int **lv
, int i
, char *lib
, char *version
)
3431 *lv
= tcc_realloc(*lv
, (*n
+ 1) * sizeof(**lv
));
3434 if ((*lv
)[i
] == -1) {
3435 int v
, prev_same_lib
= -1;
3436 for (v
= 0; v
< nb_sym_versions
; v
++) {
3437 if (strcmp(sym_versions
[v
].lib
, lib
))
3440 if (!strcmp(sym_versions
[v
].version
, version
))
3443 if (v
== nb_sym_versions
) {
3444 sym_versions
= tcc_realloc (sym_versions
,
3445 (v
+ 1) * sizeof(*sym_versions
));
3446 sym_versions
[v
].lib
= tcc_strdup(lib
);
3447 sym_versions
[v
].version
= tcc_strdup(version
);
3448 sym_versions
[v
].out_index
= 0;
3449 sym_versions
[v
].prev_same_lib
= prev_same_lib
;
3456 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3459 set_sym_version(TCCState
*s1
, int sym_index
, int verndx
)
3461 if (sym_index
>= nb_sym_to_version
) {
3462 int newelems
= sym_index
? sym_index
* 2 : 1;
3463 sym_to_version
= tcc_realloc(sym_to_version
,
3464 newelems
* sizeof(*sym_to_version
));
3465 memset(sym_to_version
+ nb_sym_to_version
, -1,
3466 (newelems
- nb_sym_to_version
) * sizeof(*sym_to_version
));
3467 nb_sym_to_version
= newelems
;
3469 if (sym_to_version
[sym_index
] < 0)
3470 sym_to_version
[sym_index
] = verndx
;
3473 struct versym_info
{
3475 ElfW(Verdef
) *verdef
;
3476 ElfW(Verneed
) *verneed
;
3478 int nb_local_ver
, *local_ver
;
3482 static void store_version(TCCState
*s1
, struct versym_info
*v
, char *dynstr
)
3484 char *lib
, *version
;
3488 #define DEBUG_VERSION 0
3490 if (v
->versym
&& v
->verdef
) {
3491 ElfW(Verdef
) *vdef
= v
->verdef
;
3494 ElfW(Verdaux
) *verdaux
=
3495 (ElfW(Verdaux
) *) (((char *) vdef
) + vdef
->vd_aux
);
3498 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3499 vdef
->vd_version
, vdef
->vd_flags
, vdef
->vd_ndx
,
3503 version
= dynstr
+ verdaux
->vda_name
;
3508 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vdef
->vd_ndx
,
3511 printf (" verdaux(%u): %s\n", vdef
->vd_ndx
, version
);
3514 next
= vdef
->vd_next
;
3515 vdef
= (ElfW(Verdef
) *) (((char *) vdef
) + next
);
3518 if (v
->versym
&& v
->verneed
) {
3519 ElfW(Verneed
) *vneed
= v
->verneed
;
3521 ElfW(Vernaux
) *vernaux
=
3522 (ElfW(Vernaux
) *) (((char *) vneed
) + vneed
->vn_aux
);
3524 lib
= dynstr
+ vneed
->vn_file
;
3526 printf ("verneed: %u %s\n", vneed
->vn_version
, lib
);
3528 for (i
= 0; i
< vneed
->vn_cnt
; i
++) {
3529 if ((vernaux
->vna_other
& 0x8000) == 0) { /* hidden */
3530 version
= dynstr
+ vernaux
->vna_name
;
3531 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vernaux
->vna_other
,
3534 printf (" vernaux(%u): %u %u %s\n",
3535 vernaux
->vna_other
, vernaux
->vna_hash
,
3536 vernaux
->vna_flags
, version
);
3539 vernaux
= (ElfW(Vernaux
) *) (((char *) vernaux
) + vernaux
->vna_next
);
3541 next
= vneed
->vn_next
;
3542 vneed
= (ElfW(Verneed
) *) (((char *) vneed
) + next
);
3547 for (i
= 0; i
< v
->nb_local_ver
; i
++) {
3548 if (v
->local_ver
[i
] > 0) {
3549 printf ("%d: lib: %s, version %s\n",
3550 i
, sym_versions
[v
->local_ver
[i
]].lib
,
3551 sym_versions
[v
->local_ver
[i
]].version
);
3557 /* load a library / DLL
3558 'level = 0' means that the DLL is referenced by the user
3559 (so it should be added as DT_NEEDED in the generated ELF file) */
3560 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
3563 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
3564 int i
, nb_syms
, nb_dts
, sym_bind
, ret
= -1;
3565 ElfW(Sym
) *sym
, *dynsym
;
3566 ElfW(Dyn
) *dt
, *dynamic
;
3570 const char *name
, *soname
;
3571 struct versym_info v
;
3573 full_read(fd
, &ehdr
, sizeof(ehdr
));
3575 /* test CPU specific stuff */
3576 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
3577 ehdr
.e_machine
!= EM_TCC_TARGET
) {
3578 return tcc_error_noabort("bad architecture");
3582 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
3584 /* load dynamic section and dynamic symbols */
3588 dynsym
= NULL
; /* avoid warning */
3589 dynstr
= NULL
; /* avoid warning */
3590 memset(&v
, 0, sizeof v
);
3592 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
3593 switch(sh
->sh_type
) {
3595 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
3596 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3599 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
3600 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3601 sh1
= &shdr
[sh
->sh_link
];
3602 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
3604 case SHT_GNU_verdef
:
3605 v
.verdef
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3607 case SHT_GNU_verneed
:
3608 v
.verneed
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3610 case SHT_GNU_versym
:
3611 v
.nb_versyms
= sh
->sh_size
/ sizeof(ElfW(Half
));
3612 v
.versym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3622 /* compute the real library name */
3623 soname
= tcc_basename(filename
);
3624 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++)
3625 if (dt
->d_tag
== DT_SONAME
)
3626 soname
= dynstr
+ dt
->d_un
.d_val
;
3628 /* if the dll is already loaded, do not load it */
3629 if (tcc_add_dllref(s1
, soname
, level
)->found
)
3632 if (v
.nb_versyms
!= nb_syms
)
3633 tcc_free (v
.versym
), v
.versym
= NULL
;
3635 store_version(s1
, &v
, dynstr
);
3637 /* add dynamic symbols in dynsym_section */
3638 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
3639 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
3640 if (sym_bind
== STB_LOCAL
)
3642 name
= dynstr
+ sym
->st_name
;
3643 sym_index
= set_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
3644 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
3646 ElfW(Half
) vsym
= v
.versym
[i
];
3647 if ((vsym
& 0x8000) == 0 && vsym
> 0 && vsym
< v
.nb_local_ver
)
3648 set_sym_version(s1
, sym_index
, v
.local_ver
[vsym
]);
3652 /* do not load all referenced libraries
3653 (recursive loading can break linking of libraries) */
3654 /* following DT_NEEDED is needed for the dynamic loader (libdl.so),
3655 but it is no longer needed, when linking a library or a program.
3656 When tcc output mode is OUTPUT_MEM,
3657 tcc calls dlopen, which handles DT_NEEDED for us */
3660 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++)
3661 if (dt
->d_tag
== DT_RPATH
)
3662 tcc_add_library_path(s1
, dynstr
+ dt
->d_un
.d_val
);
3664 /* load all referenced DLLs */
3665 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3668 name
= dynstr
+ dt
->d_un
.d_val
;
3669 if (tcc_add_dllref(s1
, name
, -1))
3671 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
3672 ret
= tcc_error_noabort("referenced dll '%s' not found", name
);
3686 tcc_free(v
.local_ver
);
3688 tcc_free(v
.verneed
);
3693 #define LD_TOK_NAME 256
3694 #define LD_TOK_EOF (-1)
3696 static int ld_inp(TCCState
*s1
)
3704 if (1 == read(s1
->fd
, &b
, 1))
3709 /* return next ld script token */
3710 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
3727 if (ch
== '*') { /* comment */
3728 for (d
= 0;; d
= ch
) {
3730 if (ch
== CH_EOF
|| (ch
== '/' && d
== '*'))
3741 /* case 'a' ... 'z': */
3768 /* case 'A' ... 'z': */
3802 if (!((ch
>= 'a' && ch
<= 'z') ||
3803 (ch
>= 'A' && ch
<= 'Z') ||
3804 (ch
>= '0' && ch
<= '9') ||
3805 strchr("/.-_+=$:\\,~", ch
)))
3807 if ((q
- name
) < name_size
- 1) {
3826 static int ld_add_file(TCCState
*s1
, const char filename
[])
3828 if (filename
[0] == '/') {
3829 if (CONFIG_SYSROOT
[0] == '\0'
3830 && tcc_add_file_internal(s1
, filename
, AFF_TYPE_BIN
) == 0)
3832 filename
= tcc_basename(filename
);
3834 return tcc_add_dll(s1
, filename
, 0);
3837 static int ld_add_file_list(TCCState
*s1
, const char *cmd
, int as_needed
)
3839 char filename
[1024], libname
[1024];
3840 int t
, group
, nblibs
= 0, ret
= 0;
3843 group
= !strcmp(cmd
, "GROUP");
3845 s1
->new_undef_sym
= 0;
3846 t
= ld_next(s1
, filename
, sizeof(filename
));
3848 ret
= tcc_error_noabort("( expected");
3849 goto lib_parse_error
;
3851 t
= ld_next(s1
, filename
, sizeof(filename
));
3854 if (t
== LD_TOK_EOF
) {
3855 ret
= tcc_error_noabort("unexpected end of file");
3856 goto lib_parse_error
;
3857 } else if (t
== ')') {
3859 } else if (t
== '-') {
3860 t
= ld_next(s1
, filename
, sizeof(filename
));
3861 if ((t
!= LD_TOK_NAME
) || (filename
[0] != 'l')) {
3862 ret
= tcc_error_noabort("library name expected");
3863 goto lib_parse_error
;
3865 pstrcpy(libname
, sizeof libname
, &filename
[1]);
3866 if (s1
->static_link
) {
3867 snprintf(filename
, sizeof filename
, "lib%s.a", libname
);
3869 snprintf(filename
, sizeof filename
, "lib%s.so", libname
);
3871 } else if (t
!= LD_TOK_NAME
) {
3872 ret
= tcc_error_noabort("filename expected");
3873 goto lib_parse_error
;
3875 if (!strcmp(filename
, "AS_NEEDED")) {
3876 ret
= ld_add_file_list(s1
, cmd
, 1);
3878 goto lib_parse_error
;
3880 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3882 ret
= ld_add_file(s1
, filename
);
3884 goto lib_parse_error
;
3886 /* Add the filename *and* the libname to avoid future conversions */
3887 dynarray_add(&libs
, &nblibs
, tcc_strdup(filename
));
3888 if (libname
[0] != '\0')
3889 dynarray_add(&libs
, &nblibs
, tcc_strdup(libname
));
3893 t
= ld_next(s1
, filename
, sizeof(filename
));
3895 t
= ld_next(s1
, filename
, sizeof(filename
));
3898 if (group
&& !as_needed
) {
3899 while (s1
->new_undef_sym
) {
3901 s1
->new_undef_sym
= 0;
3902 for (i
= 0; i
< nblibs
; i
++)
3903 ld_add_file(s1
, libs
[i
]);
3907 dynarray_reset(&libs
, &nblibs
);
3911 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3913 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
, int fd
)
3916 char filename
[1024];
3922 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3923 if (t
== LD_TOK_EOF
)
3925 else if (t
!= LD_TOK_NAME
)
3927 if (!strcmp(cmd
, "INPUT") ||
3928 !strcmp(cmd
, "GROUP")) {
3929 ret
= ld_add_file_list(s1
, cmd
, 0);
3932 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
3933 !strcmp(cmd
, "TARGET")) {
3934 /* ignore some commands */
3935 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3937 return tcc_error_noabort("( expected");
3939 t
= ld_next(s1
, filename
, sizeof(filename
));
3940 if (t
== LD_TOK_EOF
) {
3941 return tcc_error_noabort("unexpected end of file");
3942 } else if (t
== ')') {
3952 #endif /* !ELF_OBJ_ONLY */