2 * ELF file handling for TCC
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 /* Define this to get some debug output during relocation processing. */
26 /********************************************************/
27 /* global variables */
29 /* elf version information */
37 #define nb_sym_versions s1->nb_sym_versions
38 #define sym_versions s1->sym_versions
39 #define nb_sym_to_version s1->nb_sym_to_version
40 #define sym_to_version s1->sym_to_version
41 #define dt_verneednum s1->dt_verneednum
42 #define versym_section s1->versym_section
43 #define verneed_section s1->verneed_section
45 /* special flag to indicate that the section should not be linked to the other ones */
46 #define SHF_PRIVATE 0x80000000
47 /* section is dynsymtab_section */
48 #define SHF_DYNSYM 0x40000000
50 /* ------------------------------------------------------------------------- */
52 ST_FUNC
void tccelf_new(TCCState
*s
)
56 dynarray_add(&s
->sections
, &s
->nb_sections
, NULL
);
58 /* create standard sections */
59 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
60 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
61 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
62 common_section
= new_section(s
, ".common", SHT_NOBITS
, SHF_PRIVATE
);
63 common_section
->sh_num
= SHN_COMMON
;
65 /* symbols are always generated for linking stage */
66 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
68 ".hashtab", SHF_PRIVATE
);
69 s
->symtab
= symtab_section
;
71 /* private symbol table for dynamic symbols */
72 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
|SHF_DYNSYM
,
74 ".dynhashtab", SHF_PRIVATE
);
75 get_sym_attr(s
, 0, 1);
78 #ifdef CONFIG_TCC_BCHECK
79 ST_FUNC
void tccelf_bounds_new(TCCState
*s
)
82 /* create bounds sections */
83 bounds_section
= new_section(s
, ".bounds",
84 SHT_PROGBITS
, SHF_ALLOC
);
85 lbounds_section
= new_section(s
, ".lbounds",
86 SHT_PROGBITS
, SHF_ALLOC
);
90 ST_FUNC
void tccelf_stab_new(TCCState
*s
)
94 #ifdef CONFIG_TCC_BACKTRACE
95 /* include stab info with standalone backtrace support */
96 if (s
->do_backtrace
&& s
->output_type
!= TCC_OUTPUT_MEMORY
)
97 shf
= SHF_ALLOC
| SHF_WRITE
; // SHF_WRITE needed for musl/SELINUX
99 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, shf
);
100 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
101 stab_section
->sh_addralign
= sizeof ((Stab_Sym
*)0)->n_value
;
102 stab_section
->link
= new_section(s
, ".stabstr", SHT_STRTAB
, shf
);
103 /* put first entry */
104 put_stabs(s
, "", 0, 0, 0, 0);
107 static void free_section(Section
*s
)
112 ST_FUNC
void tccelf_delete(TCCState
*s1
)
117 /* free symbol versions */
118 for (i
= 0; i
< nb_sym_versions
; i
++) {
119 tcc_free(sym_versions
[i
].version
);
120 tcc_free(sym_versions
[i
].lib
);
122 tcc_free(sym_versions
);
123 tcc_free(sym_to_version
);
126 /* free all sections */
127 for(i
= 1; i
< s1
->nb_sections
; i
++)
128 free_section(s1
->sections
[i
]);
129 dynarray_reset(&s1
->sections
, &s1
->nb_sections
);
131 for(i
= 0; i
< s1
->nb_priv_sections
; i
++)
132 free_section(s1
->priv_sections
[i
]);
133 dynarray_reset(&s1
->priv_sections
, &s1
->nb_priv_sections
);
135 /* free any loaded DLLs */
137 for ( i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
138 DLLReference
*ref
= s1
->loaded_dlls
[i
];
141 FreeLibrary((HMODULE
)ref
->handle
);
143 dlclose(ref
->handle
);
147 /* free loaded dlls array */
148 dynarray_reset(&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
);
149 tcc_free(s1
->sym_attrs
);
151 symtab_section
= NULL
; /* for tccrun.c:rt_printline() */
154 /* save section data state */
155 ST_FUNC
void tccelf_begin_file(TCCState
*s1
)
158 for (i
= 1; i
< s1
->nb_sections
; i
++) {
160 s
->sh_offset
= s
->data_offset
;
162 /* disable symbol hashing during compilation */
163 s
= s1
->symtab
, s
->reloc
= s
->hash
, s
->hash
= NULL
;
164 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
169 /* At the end of compilation, convert any UNDEF syms to global, and merge
170 with previously existing symbols */
171 ST_FUNC
void tccelf_end_file(TCCState
*s1
)
173 Section
*s
= s1
->symtab
;
174 int first_sym
, nb_syms
, *tr
, i
;
176 first_sym
= s
->sh_offset
/ sizeof (ElfSym
);
177 nb_syms
= s
->data_offset
/ sizeof (ElfSym
) - first_sym
;
178 s
->data_offset
= s
->sh_offset
;
179 s
->link
->data_offset
= s
->link
->sh_offset
;
180 s
->hash
= s
->reloc
, s
->reloc
= NULL
;
181 tr
= tcc_mallocz(nb_syms
* sizeof *tr
);
183 for (i
= 0; i
< nb_syms
; ++i
) {
184 ElfSym
*sym
= (ElfSym
*)s
->data
+ first_sym
+ i
;
185 if (sym
->st_shndx
== SHN_UNDEF
186 && ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
)
187 sym
->st_info
= ELFW(ST_INFO
)(STB_GLOBAL
, ELFW(ST_TYPE
)(sym
->st_info
));
188 tr
[i
] = set_elf_sym(s
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
189 sym
->st_other
, sym
->st_shndx
, (char*)s
->link
->data
+ sym
->st_name
);
191 /* now update relocations */
192 for (i
= 1; i
< s1
->nb_sections
; i
++) {
193 Section
*sr
= s1
->sections
[i
];
194 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
195 ElfW_Rel
*rel
= (ElfW_Rel
*)(sr
->data
+ sr
->sh_offset
);
196 ElfW_Rel
*rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
197 for (; rel
< rel_end
; ++rel
) {
198 int n
= ELFW(R_SYM
)(rel
->r_info
) - first_sym
;
199 //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
200 rel
->r_info
= ELFW(R_INFO
)(tr
[n
], ELFW(R_TYPE
)(rel
->r_info
));
206 /* record text/data/bss output for -bench info */
207 for (i
= 0; i
< 3; ++i
) {
208 s
= s1
->sections
[i
+ 1];
209 s1
->total_output
[i
] += s
->data_offset
- s
->sh_offset
;
213 ST_FUNC Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
217 sec
= tcc_mallocz(sizeof(Section
) + strlen(name
));
219 strcpy(sec
->name
, name
);
220 sec
->sh_type
= sh_type
;
221 sec
->sh_flags
= sh_flags
;
224 sec
->sh_addralign
= 2;
232 case SHT_GNU_verneed
:
234 sec
->sh_addralign
= PTR_SIZE
;
237 sec
->sh_addralign
= 1;
240 sec
->sh_addralign
= PTR_SIZE
; /* gcc/pcc default alignment */
244 if (sh_flags
& SHF_PRIVATE
) {
245 dynarray_add(&s1
->priv_sections
, &s1
->nb_priv_sections
, sec
);
247 sec
->sh_num
= s1
->nb_sections
;
248 dynarray_add(&s1
->sections
, &s1
->nb_sections
, sec
);
254 ST_FUNC Section
*new_symtab(TCCState
*s1
,
255 const char *symtab_name
, int sh_type
, int sh_flags
,
256 const char *strtab_name
,
257 const char *hash_name
, int hash_sh_flags
)
259 Section
*symtab
, *strtab
, *hash
;
260 int *ptr
, nb_buckets
;
262 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
263 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
264 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
265 put_elf_str(strtab
, "");
266 symtab
->link
= strtab
;
267 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
271 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
272 hash
->sh_entsize
= sizeof(int);
276 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
279 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
283 /* realloc section and set its content to zero */
284 ST_FUNC
void section_realloc(Section
*sec
, unsigned long new_size
)
289 size
= sec
->data_allocated
;
292 while (size
< new_size
)
294 data
= tcc_realloc(sec
->data
, size
);
295 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
297 sec
->data_allocated
= size
;
300 /* reserve at least 'size' bytes aligned per 'align' in section
301 'sec' from current offset, and return the aligned offset */
302 ST_FUNC
size_t section_add(Section
*sec
, addr_t size
, int align
)
304 size_t offset
, offset1
;
306 offset
= (sec
->data_offset
+ align
- 1) & -align
;
307 offset1
= offset
+ size
;
308 if (sec
->sh_type
!= SHT_NOBITS
&& offset1
> sec
->data_allocated
)
309 section_realloc(sec
, offset1
);
310 sec
->data_offset
= offset1
;
311 if (align
> sec
->sh_addralign
)
312 sec
->sh_addralign
= align
;
316 /* reserve at least 'size' bytes in section 'sec' from
318 ST_FUNC
void *section_ptr_add(Section
*sec
, addr_t size
)
320 size_t offset
= section_add(sec
, size
, 1);
321 return sec
->data
+ offset
;
325 /* reserve at least 'size' bytes from section start */
326 static void section_reserve(Section
*sec
, unsigned long size
)
328 if (size
> sec
->data_allocated
)
329 section_realloc(sec
, size
);
330 if (size
> sec
->data_offset
)
331 sec
->data_offset
= size
;
335 static Section
*find_section_create (TCCState
*s1
, const char *name
, int create
)
339 for(i
= 1; i
< s1
->nb_sections
; i
++) {
340 sec
= s1
->sections
[i
];
341 if (!strcmp(name
, sec
->name
))
344 /* sections are created as PROGBITS */
345 return create
? new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
) : NULL
;
348 /* return a reference to a section, and create it if it does not
350 ST_FUNC Section
*find_section(TCCState
*s1
, const char *name
)
352 return find_section_create (s1
, name
, 1);
355 /* ------------------------------------------------------------------------- */
357 ST_FUNC
int put_elf_str(Section
*s
, const char *sym
)
362 len
= strlen(sym
) + 1;
363 offset
= s
->data_offset
;
364 ptr
= section_ptr_add(s
, len
);
365 memmove(ptr
, sym
, len
);
369 /* elf symbol hashing function */
370 static unsigned long elf_hash(const unsigned char *name
)
372 unsigned long h
= 0, g
;
375 h
= (h
<< 4) + *name
++;
384 /* rebuild hash table of section s */
385 /* NOTE: we do factorize the hash table code to go faster */
386 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
389 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
390 unsigned char *strtab
;
392 strtab
= s
->link
->data
;
393 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
396 nb_buckets
= ((int*)s
->hash
->data
)[0];
398 s
->hash
->data_offset
= 0;
399 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
404 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
405 ptr
+= nb_buckets
+ 1;
407 sym
= (ElfW(Sym
) *)s
->data
+ 1;
408 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
409 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
410 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
421 /* return the symbol number */
422 ST_FUNC
int put_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
423 int info
, int other
, int shndx
, const char *name
)
425 int name_offset
, sym_index
;
430 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
432 name_offset
= put_elf_str(s
->link
, name
);
435 /* XXX: endianness */
436 sym
->st_name
= name_offset
;
437 sym
->st_value
= value
;
440 sym
->st_other
= other
;
441 sym
->st_shndx
= shndx
;
442 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
446 ptr
= section_ptr_add(hs
, sizeof(int));
447 base
= (int *)hs
->data
;
448 /* only add global or weak symbols. */
449 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
450 /* add another hashing entry */
452 h
= elf_hash((unsigned char *)s
->link
->data
+ name_offset
) % nbuckets
;
454 base
[2 + h
] = sym_index
;
456 /* we resize the hash table */
457 hs
->nb_hashed_syms
++;
458 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
459 rebuild_hash(s
, 2 * nbuckets
);
469 ST_FUNC
int find_elf_sym(Section
*s
, const char *name
)
473 int nbuckets
, sym_index
, h
;
479 nbuckets
= ((int *)hs
->data
)[0];
480 h
= elf_hash((unsigned char *) name
) % nbuckets
;
481 sym_index
= ((int *)hs
->data
)[2 + h
];
482 while (sym_index
!= 0) {
483 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
484 name1
= (char *) s
->link
->data
+ sym
->st_name
;
485 if (!strcmp(name
, name1
))
487 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
492 /* return elf symbol value, signal error if 'err' is nonzero, decorate
494 ST_FUNC addr_t
get_sym_addr(TCCState
*s1
, const char *name
, int err
, int forc
)
499 if (forc
&& s1
->leading_underscore
501 /* win32-32bit stdcall symbols always have _ already */
502 && !strchr(name
, '@')
506 pstrcpy(buf
+ 1, sizeof(buf
) - 1, name
);
509 sym_index
= find_elf_sym(s1
->symtab
, name
);
510 sym
= &((ElfW(Sym
) *)s1
->symtab
->data
)[sym_index
];
511 if (!sym_index
|| sym
->st_shndx
== SHN_UNDEF
) {
513 tcc_error("%s not defined", name
);
516 return sym
->st_value
;
519 /* return elf symbol value */
520 LIBTCCAPI
void *tcc_get_symbol(TCCState
*s
, const char *name
)
522 addr_t addr
= get_sym_addr(s
, name
, 0, 1);
523 return addr
== -1 ? NULL
: (void*)(uintptr_t)addr
;
526 /* list elf symbol names and values */
527 ST_FUNC
void list_elf_symbols(TCCState
*s
, void *ctx
,
528 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
532 int sym_index
, end_sym
;
534 unsigned char sym_vis
, sym_bind
;
537 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
538 for (sym_index
= 0; sym_index
< end_sym
; ++sym_index
) {
539 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
541 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
542 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
543 sym_vis
= ELFW(ST_VISIBILITY
)(sym
->st_other
);
544 if (sym_bind
== STB_GLOBAL
&& sym_vis
== STV_DEFAULT
)
545 symbol_cb(ctx
, name
, (void*)(uintptr_t)sym
->st_value
);
550 /* list elf symbol names and values */
551 LIBTCCAPI
void tcc_list_symbols(TCCState
*s
, void *ctx
,
552 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
554 list_elf_symbols(s
, ctx
, symbol_cb
);
559 version_add (TCCState
*s1
)
563 ElfW(Verneed
) *vn
= NULL
;
565 int sym_index
, end_sym
, nb_versions
= 2, nb_entries
= 0;
569 if (0 == nb_sym_versions
)
571 versym_section
= new_section(s1
, ".gnu.version", SHT_GNU_versym
, SHF_ALLOC
);
572 versym_section
->sh_entsize
= sizeof(ElfW(Half
));
573 versym_section
->link
= s1
->dynsym
;
575 /* add needed symbols */
577 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
578 versym
= section_ptr_add(versym_section
, end_sym
* sizeof(ElfW(Half
)));
579 for (sym_index
= 0; sym_index
< end_sym
; ++sym_index
) {
580 int dllindex
, verndx
;
581 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
582 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
583 dllindex
= find_elf_sym(s1
->dynsymtab_section
, name
);
584 verndx
= (dllindex
&& dllindex
< nb_sym_to_version
)
585 ? sym_to_version
[dllindex
] : -1;
587 if (!sym_versions
[verndx
].out_index
)
588 sym_versions
[verndx
].out_index
= nb_versions
++;
589 versym
[sym_index
] = sym_versions
[verndx
].out_index
;
591 versym
[sym_index
] = 0;
593 /* generate verneed section, but not when it will be empty. Some
594 dynamic linkers look at their contents even when DTVERNEEDNUM and
595 section size is zero. */
596 if (nb_versions
> 2) {
597 verneed_section
= new_section(s1
, ".gnu.version_r",
598 SHT_GNU_verneed
, SHF_ALLOC
);
599 verneed_section
->link
= s1
->dynsym
->link
;
600 for (i
= nb_sym_versions
; i
-- > 0;) {
601 struct sym_version
*sv
= &sym_versions
[i
];
602 int n_same_libs
= 0, prev
;
604 ElfW(Vernaux
) *vna
= 0;
605 if (sv
->out_index
< 1)
607 vnofs
= section_add(verneed_section
, sizeof(*vn
), 1);
608 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
610 vn
->vn_file
= put_elf_str(verneed_section
->link
, sv
->lib
);
611 vn
->vn_aux
= sizeof (*vn
);
613 prev
= sv
->prev_same_lib
;
614 if (sv
->out_index
> 0) {
615 vna
= section_ptr_add(verneed_section
, sizeof(*vna
));
616 vna
->vna_hash
= elf_hash ((const unsigned char *)sv
->version
);
618 vna
->vna_other
= sv
->out_index
;
620 vna
->vna_name
= put_elf_str(verneed_section
->link
, sv
->version
);
621 vna
->vna_next
= sizeof (*vna
);
625 sv
= &sym_versions
[prev
];
628 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
629 vn
->vn_cnt
= n_same_libs
;
630 vn
->vn_next
= sizeof(*vn
) + n_same_libs
* sizeof(*vna
);
635 verneed_section
->sh_info
= nb_entries
;
637 dt_verneednum
= nb_entries
;
641 /* add an elf symbol : check if it is already defined and patch
642 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
643 ST_FUNC
int set_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
644 int info
, int other
, int shndx
, const char *name
)
646 TCCState
*s1
= s
->s1
;
648 int sym_bind
, sym_index
, sym_type
, esym_bind
;
649 unsigned char sym_vis
, esym_vis
, new_vis
;
651 sym_bind
= ELFW(ST_BIND
)(info
);
652 sym_type
= ELFW(ST_TYPE
)(info
);
653 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
655 if (sym_bind
!= STB_LOCAL
) {
656 /* we search global or weak symbols */
657 sym_index
= find_elf_sym(s
, name
);
660 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
661 if (esym
->st_value
== value
&& esym
->st_size
== size
&& esym
->st_info
== info
662 && esym
->st_other
== other
&& esym
->st_shndx
== shndx
)
664 if (esym
->st_shndx
!= SHN_UNDEF
) {
665 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
666 /* propagate the most constraining visibility */
667 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
668 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
669 if (esym_vis
== STV_DEFAULT
) {
671 } else if (sym_vis
== STV_DEFAULT
) {
674 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
676 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
678 other
= esym
->st_other
; /* in case we have to patch esym */
679 if (shndx
== SHN_UNDEF
) {
680 /* ignore adding of undefined symbol if the
681 corresponding symbol is already defined */
682 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
683 /* global overrides weak, so patch */
685 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
686 /* weak is ignored if already global */
687 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_WEAK
) {
688 /* keep first-found weak definition, ignore subsequents */
689 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
690 /* ignore hidden symbols after */
691 } else if ((esym
->st_shndx
== SHN_COMMON
692 || esym
->st_shndx
== bss_section
->sh_num
)
693 && (shndx
< SHN_LORESERVE
694 && shndx
!= bss_section
->sh_num
)) {
695 /* data symbol gets precedence over common/bss */
697 } else if (shndx
== SHN_COMMON
|| shndx
== bss_section
->sh_num
) {
698 /* data symbol keeps precedence over common/bss */
699 } else if (s
->sh_flags
& SHF_DYNSYM
) {
700 /* we accept that two DLL define the same symbol */
701 } else if (esym
->st_other
& ST_ASM_SET
) {
702 /* If the existing symbol came from an asm .set
707 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
708 sym_bind
, shndx
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
710 tcc_error_noabort("'%s' defined twice", name
);
714 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
715 esym
->st_shndx
= shndx
;
716 s1
->new_undef_sym
= 1;
717 esym
->st_value
= value
;
718 esym
->st_size
= size
;
719 esym
->st_other
= other
;
723 sym_index
= put_elf_sym(s
, value
, size
,
724 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
731 ST_FUNC
void put_elf_reloca(Section
*symtab
, Section
*s
, unsigned long offset
,
732 int type
, int symbol
, addr_t addend
)
734 TCCState
*s1
= s
->s1
;
738 int jmp_slot
= type
== R_JMP_SLOT
;
740 sr
= jmp_slot
? s
->relocplt
: s
->reloc
;
742 /* if no relocation section, create it */
744 snprintf(buf
, sizeof(buf
), RELPLT_SECTION_FMT
);
746 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
747 /* if the symtab is allocated, then we consider the relocation
749 sr
= new_section(s
->s1
, buf
, SHT_RELX
, symtab
->sh_flags
);
750 sr
->sh_entsize
= sizeof(ElfW_Rel
);
752 sr
->sh_info
= s
->sh_num
;
758 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
759 rel
->r_offset
= offset
;
760 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
761 #if SHT_RELX == SHT_RELA
762 rel
->r_addend
= addend
;
764 if (SHT_RELX
!= SHT_RELA
&& addend
)
765 tcc_error("non-zero addend on REL architecture");
768 ST_FUNC
void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
769 int type
, int symbol
)
771 put_elf_reloca(symtab
, s
, offset
, type
, symbol
, 0);
774 /* put stab debug information */
775 ST_FUNC
void put_stabs(TCCState
*s1
, const char *str
, int type
, int other
, int desc
,
782 && (offset
= stab_section
->data_offset
)
783 && (sym
= (Stab_Sym
*)(stab_section
->data
+ offset
) - 1)
784 && sym
->n_type
== type
785 && sym
->n_value
== value
) {
786 /* just update line_number in previous entry */
791 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
793 sym
->n_strx
= put_elf_str(stab_section
->link
, str
);
798 sym
->n_other
= other
;
800 sym
->n_value
= value
;
803 ST_FUNC
void put_stabs_r(TCCState
*s1
, const char *str
, int type
, int other
, int desc
,
804 unsigned long value
, Section
*sec
, int sym_index
)
806 put_elf_reloc(symtab_section
, stab_section
,
807 stab_section
->data_offset
+ 8,
808 sizeof ((Stab_Sym
*)0)->n_value
== PTR_SIZE
? R_DATA_PTR
: R_DATA_32
,
810 put_stabs(s1
, str
, type
, other
, desc
, value
);
813 ST_FUNC
void put_stabn(TCCState
*s1
, int type
, int other
, int desc
, int value
)
815 put_stabs(s1
, NULL
, type
, other
, desc
, value
);
818 ST_FUNC
struct sym_attr
*get_sym_attr(TCCState
*s1
, int index
, int alloc
)
821 struct sym_attr
*tab
;
823 if (index
>= s1
->nb_sym_attrs
) {
825 return s1
->sym_attrs
;
826 /* find immediately bigger power of 2 and reallocate array */
830 tab
= tcc_realloc(s1
->sym_attrs
, n
* sizeof(*s1
->sym_attrs
));
832 memset(s1
->sym_attrs
+ s1
->nb_sym_attrs
, 0,
833 (n
- s1
->nb_sym_attrs
) * sizeof(*s1
->sym_attrs
));
834 s1
->nb_sym_attrs
= n
;
836 return &s1
->sym_attrs
[index
];
839 /* In an ELF file symbol table, the local symbols must appear below
840 the global and weak ones. Since TCC cannot sort it while generating
841 the code, we must do it after. All the relocation tables are also
842 modified to take into account the symbol table sorting */
843 static void sort_syms(TCCState
*s1
, Section
*s
)
845 int *old_to_new_syms
;
853 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
854 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
855 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
857 /* first pass for local symbols */
858 p
= (ElfW(Sym
) *)s
->data
;
860 for(i
= 0; i
< nb_syms
; i
++) {
861 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
862 old_to_new_syms
[i
] = q
- new_syms
;
867 /* save the number of local symbols in section header */
868 if( s
->sh_size
) /* this 'if' makes IDA happy */
869 s
->sh_info
= q
- new_syms
;
871 /* then second pass for non local symbols */
872 p
= (ElfW(Sym
) *)s
->data
;
873 for(i
= 0; i
< nb_syms
; i
++) {
874 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
875 old_to_new_syms
[i
] = q
- new_syms
;
881 /* we copy the new symbols to the old */
882 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
885 /* now we modify all the relocations */
886 for(i
= 1; i
< s1
->nb_sections
; i
++) {
887 sr
= s1
->sections
[i
];
888 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
889 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
890 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
891 type
= ELFW(R_TYPE
)(rel
->r_info
);
892 sym_index
= old_to_new_syms
[sym_index
];
893 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
898 tcc_free(old_to_new_syms
);
901 /* relocate symbol table, resolve undefined symbols if do_resolve is
902 true and output error if undefined symbol. */
903 ST_FUNC
void relocate_syms(TCCState
*s1
, Section
*symtab
, int do_resolve
)
906 int sym_bind
, sh_num
;
909 for_each_elem(symtab
, 1, sym
, ElfW(Sym
)) {
910 sh_num
= sym
->st_shndx
;
911 if (sh_num
== SHN_UNDEF
) {
912 name
= (char *) s1
->symtab
->link
->data
+ sym
->st_name
;
913 /* Use ld.so to resolve symbol for us (for tcc -run) */
915 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
916 /* dlsym() needs the undecorated name. */
917 void *addr
= dlsym(RTLD_DEFAULT
, &name
[s1
->leading_underscore
]);
918 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
921 for (i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
922 if ((addr
= dlsym(s1
->loaded_dlls
[i
]->handle
, name
)))
927 sym
->st_value
= (addr_t
) addr
;
929 printf ("relocate_sym: %s -> 0x%lx\n", name
, sym
->st_value
);
934 /* if dynamic symbol exist, it will be used in relocate_section */
935 } else if (s1
->dynsym
&& find_elf_sym(s1
->dynsym
, name
))
937 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
939 if (!strcmp(name
, "_fp_hw"))
941 /* only weak symbols are accepted to be undefined. Their
943 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
944 if (sym_bind
== STB_WEAK
)
947 tcc_error_noabort("undefined symbol '%s'", name
);
948 } else if (sh_num
< SHN_LORESERVE
) {
949 /* add section base */
950 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
956 /* relocate a given section (CPU dependent) by applying the relocations
957 in the associated relocation section */
958 ST_FUNC
void relocate_section(TCCState
*s1
, Section
*s
)
960 Section
*sr
= s
->reloc
;
967 qrel
= (ElfW_Rel
*)sr
->data
;
969 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
970 ptr
= s
->data
+ rel
->r_offset
;
971 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
972 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
973 type
= ELFW(R_TYPE
)(rel
->r_info
);
975 #if SHT_RELX == SHT_RELA
976 tgt
+= rel
->r_addend
;
978 addr
= s
->sh_addr
+ rel
->r_offset
;
979 relocate(s1
, rel
, type
, ptr
, addr
, tgt
);
981 /* if the relocation is allocated, we change its symbol table */
982 if (sr
->sh_flags
& SHF_ALLOC
) {
983 sr
->link
= s1
->dynsym
;
984 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
985 size_t r
= (uint8_t*)qrel
- sr
->data
;
986 if (sizeof ((Stab_Sym
*)0)->n_value
< PTR_SIZE
987 && 0 == strcmp(s
->name
, ".stab"))
988 r
= 0; /* cannot apply 64bit relocation to 32bit value */
989 sr
->data_offset
= sr
->sh_size
= r
;
995 /* relocate relocation table in 'sr' */
996 static void relocate_rel(TCCState
*s1
, Section
*sr
)
1001 s
= s1
->sections
[sr
->sh_info
];
1002 for_each_elem(sr
, 0, rel
, ElfW_Rel
)
1003 rel
->r_offset
+= s
->sh_addr
;
1006 /* count the number of dynamic relocations so that we can reserve
1008 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
1011 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1012 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1013 defined(TCC_TARGET_RISCV64)
1015 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
1016 int sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1017 int type
= ELFW(R_TYPE
)(rel
->r_info
);
1019 #if defined(TCC_TARGET_I386)
1021 if (!get_sym_attr(s1
, sym_index
, 0)->dyn_index
1022 && ((ElfW(Sym
)*)symtab_section
->data
+ sym_index
)->st_shndx
== SHN_UNDEF
) {
1023 /* don't fixup unresolved (weak) symbols */
1024 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_386_RELATIVE
);
1027 #elif defined(TCC_TARGET_X86_64)
1031 #elif defined(TCC_TARGET_ARM)
1033 #elif defined(TCC_TARGET_ARM64)
1034 case R_AARCH64_ABS32
:
1035 case R_AARCH64_ABS64
:
1036 #elif defined(TCC_TARGET_RISCV64)
1042 #if defined(TCC_TARGET_I386)
1044 #elif defined(TCC_TARGET_X86_64)
1046 #elif defined(TCC_TARGET_ARM64)
1047 case R_AARCH64_PREL32
:
1049 if (get_sym_attr(s1
, sym_index
, 0)->dyn_index
)
1057 /* allocate the section */
1058 sr
->sh_flags
|= SHF_ALLOC
;
1059 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
1066 #if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE)
1067 static void build_got(TCCState
*s1
)
1069 /* if no got, then create it */
1070 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
1071 s1
->got
->sh_entsize
= 4;
1072 set_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
1073 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
1074 /* keep space for _DYNAMIC pointer and two dummy got entries */
1075 section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
1078 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1079 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1080 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1081 Returns the offset of the GOT or (if any) PLT entry. */
1082 static struct sym_attr
* put_got_entry(TCCState
*s1
, int dyn_reloc_type
,
1088 struct sym_attr
*attr
;
1089 unsigned got_offset
;
1093 need_plt_entry
= (dyn_reloc_type
== R_JMP_SLOT
);
1094 attr
= get_sym_attr(s1
, sym_index
, 1);
1096 /* In case a function is both called and its address taken 2 GOT entries
1097 are created, one for taking the address (GOT) and the other for the PLT
1099 if (need_plt_entry
? attr
->plt_offset
: attr
->got_offset
)
1102 /* create the GOT entry */
1103 got_offset
= s1
->got
->data_offset
;
1104 section_ptr_add(s1
->got
, PTR_SIZE
);
1106 /* Create the GOT relocation that will insert the address of the object or
1107 function of interest in the GOT entry. This is a static relocation for
1108 memory output (dlsym will give us the address of symbols) and dynamic
1109 relocation otherwise (executable and DLLs). The relocation should be
1110 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1111 associated to a PLT entry) but is currently done at load time for an
1114 sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1115 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1118 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
) {
1119 /* Hack alarm. We don't want to emit dynamic symbols
1120 and symbol based relocs for STB_LOCAL symbols, but rather
1121 want to resolve them directly. At this point the symbol
1122 values aren't final yet, so we must defer this. We will later
1123 have to create a RELATIVE reloc anyway, so we misuse the
1124 relocation slot to smuggle the symbol reference until
1125 fill_local_got_entries. Not that the sym_index is
1126 relative to symtab_section, not s1->dynsym! Nevertheless
1127 we use s1->dyn_sym so that if this is the first call
1128 that got->reloc is correctly created. Also note that
1129 RELATIVE relocs are not normally created for the .got,
1130 so the types serves as a marker for later (and is retained
1131 also for the final output, which is okay because then the
1132 got is just normal data). */
1133 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, R_RELATIVE
,
1136 if (0 == attr
->dyn_index
)
1137 attr
->dyn_index
= set_elf_sym(s1
->dynsym
, sym
->st_value
,
1138 sym
->st_size
, sym
->st_info
, 0,
1139 sym
->st_shndx
, name
);
1140 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, dyn_reloc_type
,
1144 put_elf_reloc(symtab_section
, s1
->got
, got_offset
, dyn_reloc_type
,
1148 if (need_plt_entry
) {
1150 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1151 SHF_ALLOC
| SHF_EXECINSTR
);
1152 s1
->plt
->sh_entsize
= 4;
1155 attr
->plt_offset
= create_plt_entry(s1
, got_offset
, attr
);
1157 /* create a symbol 'sym@plt' for the PLT jump vector */
1159 if (len
> sizeof plt_name
- 5)
1160 len
= sizeof plt_name
- 5;
1161 memcpy(plt_name
, name
, len
);
1162 strcpy(plt_name
+ len
, "@plt");
1163 attr
->plt_sym
= put_elf_sym(s1
->symtab
, attr
->plt_offset
, sym
->st_size
,
1164 ELFW(ST_INFO
)(STB_GLOBAL
, STT_FUNC
), 0, s1
->plt
->sh_num
, plt_name
);
1167 attr
->got_offset
= got_offset
;
1173 /* build GOT and PLT entries */
1174 static void build_got_entries_pass(TCCState
*s1
, int pass
)
1179 int i
, type
, gotplt_entry
, reloc_type
, sym_index
;
1180 struct sym_attr
*attr
;
1182 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1183 s
= s1
->sections
[i
];
1184 if (s
->sh_type
!= SHT_RELX
)
1186 /* no need to handle got relocations */
1187 if (s
->link
!= symtab_section
)
1189 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1190 type
= ELFW(R_TYPE
)(rel
->r_info
);
1191 gotplt_entry
= gotplt_entry_type(type
);
1192 if (gotplt_entry
== -1)
1193 tcc_error ("Unknown relocation type for got: %d", type
);
1194 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1195 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1197 if (gotplt_entry
== NO_GOTPLT_ENTRY
) {
1201 /* Automatically create PLT/GOT [entry] if it is an undefined
1202 reference (resolved at runtime), or the symbol is absolute,
1203 probably created by tcc_add_symbol, and thus on 64-bit
1204 targets might be too far from application code. */
1205 if (gotplt_entry
== AUTO_GOTPLT_ENTRY
) {
1206 if (sym
->st_shndx
== SHN_UNDEF
) {
1209 if (s1
->output_type
== TCC_OUTPUT_DLL
&& ! PCRELATIVE_DLLPLT
)
1211 /* Relocations for UNDEF symbols would normally need
1212 to be transferred into the executable or shared object.
1213 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1214 But TCC doesn't do that (at least for exes), so we
1215 need to resolve all such relocs locally. And that
1216 means PLT slots for functions in DLLs and COPY relocs for
1217 data symbols. COPY relocs were generated in
1218 bind_exe_dynsyms (and the symbol adjusted to be defined),
1219 and for functions we were generated a dynamic symbol
1220 of function type. */
1222 /* dynsym isn't set for -run :-/ */
1223 dynindex
= get_sym_attr(s1
, sym_index
, 0)->dyn_index
;
1224 esym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ dynindex
;
1226 && (ELFW(ST_TYPE
)(esym
->st_info
) == STT_FUNC
1227 || (ELFW(ST_TYPE
)(esym
->st_info
) == STT_NOTYPE
1228 && ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
)))
1231 } else if (!(sym
->st_shndx
== SHN_ABS
1232 #ifndef TCC_TARGET_ARM
1239 #ifdef TCC_TARGET_X86_64
1240 if ((type
== R_X86_64_PLT32
|| type
== R_X86_64_PC32
) &&
1241 sym
->st_shndx
!= SHN_UNDEF
&&
1242 (ELFW(ST_VISIBILITY
)(sym
->st_other
) != STV_DEFAULT
||
1243 ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
||
1244 s1
->output_type
== TCC_OUTPUT_EXE
)) {
1247 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PC32
);
1251 reloc_type
= code_reloc(type
);
1252 if (reloc_type
== -1)
1253 tcc_error ("Unknown relocation type: %d", type
);
1254 else if (reloc_type
!= 0) {
1256 reloc_type
= R_JMP_SLOT
;
1258 reloc_type
= R_GLOB_DAT
;
1261 if ((pass
== 0 && reloc_type
== R_GLOB_DAT
) ||
1262 (pass
== 1 && reloc_type
== R_JMP_SLOT
))
1268 if (gotplt_entry
== BUILD_GOT_ONLY
)
1271 attr
= put_got_entry(s1
, reloc_type
, sym_index
);
1273 if (reloc_type
== R_JMP_SLOT
)
1274 rel
->r_info
= ELFW(R_INFO
)(attr
->plt_sym
, type
);
1279 ST_FUNC
void build_got_entries(TCCState
*s1
)
1283 /* Two passes because R_JMP_SLOT should become first.
1284 Some targets (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1285 for (i
= 0; i
< 2; i
++)
1286 build_got_entries_pass(s1
, i
);
1290 ST_FUNC
int set_global_sym(TCCState
*s1
, const char *name
, Section
*sec
, addr_t offs
)
1292 int shn
= sec
? sec
->sh_num
: offs
? SHN_ABS
: SHN_UNDEF
;
1293 if (sec
&& offs
== -1)
1294 offs
= sec
->data_offset
;
1295 return set_elf_sym(symtab_section
, offs
, 0,
1296 ELFW(ST_INFO
)(name
? STB_GLOBAL
: STB_LOCAL
, STT_NOTYPE
), 0, shn
, name
);
1299 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1304 s
= find_section(s1
, section_name
);
1309 end_offset
= s
->data_offset
;
1311 snprintf(buf
, sizeof(buf
), "__%s_start", section_name
+ 1);
1312 set_global_sym(s1
, buf
, s
, 0);
1313 snprintf(buf
, sizeof(buf
), "__%s_end", section_name
+ 1);
1314 set_global_sym(s1
, buf
, s
, end_offset
);
1317 #ifndef TCC_TARGET_PE
1318 static void tcc_add_support(TCCState
*s1
, const char *filename
)
1321 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, filename
);
1322 tcc_add_file(s1
, buf
);
1326 ST_FUNC
void add_array (TCCState
*s1
, const char *sec
, int c
)
1329 s
= find_section(s1
, sec
);
1330 s
->sh_flags
|= SHF_WRITE
;
1331 #ifndef TCC_TARGET_PE
1332 s
->sh_type
= sec
[1] == 'i' ? SHT_INIT_ARRAY
: SHT_FINI_ARRAY
;
1334 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1335 section_ptr_add(s
, PTR_SIZE
);
1338 #ifdef CONFIG_TCC_BCHECK
1339 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
1341 if (0 == s1
->do_bounds_check
)
1343 section_ptr_add(bounds_section
, sizeof(addr_t
));
1347 #ifdef CONFIG_TCC_BACKTRACE
1348 static void put_ptr(TCCState
*s1
, Section
*s
, int offs
)
1351 c
= set_global_sym(s1
, NULL
, s
, offs
);
1353 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1354 section_ptr_add(s
, PTR_SIZE
);
1357 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1358 a dynamic symbol to allow so's to have one each with a different value. */
1359 static void set_local_sym(TCCState
*s1
, const char *name
, Section
*s
, int offset
)
1361 int c
= find_elf_sym(s1
->symtab
, name
);
1363 ElfW(Sym
) *esym
= (ElfW(Sym
)*)s1
->symtab
->data
+ c
;
1364 esym
->st_info
= ELFW(ST_INFO
)(STB_LOCAL
, STT_NOTYPE
);
1365 esym
->st_value
= offset
;
1366 esym
->st_shndx
= s
->sh_num
;
1370 ST_FUNC
void tcc_add_btstub(TCCState
*s1
)
1378 /* create (part of) a struct rt_context (see tccrun.c) */
1379 put_ptr(s1
, stab_section
, 0);
1380 put_ptr(s1
, stab_section
, -1);
1381 put_ptr(s1
, stab_section
->link
, 0);
1382 section_ptr_add(s
, 3 * PTR_SIZE
);
1384 #ifndef TCC_TARGET_MACHO
1385 /* XXX this relocation is wrong, it uses sym-index 0 (local,undef) */
1386 put_elf_reloc(s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, 0);
1388 section_ptr_add(s
, PTR_SIZE
);
1390 #ifdef CONFIG_TCC_BCHECK
1391 if (s1
->do_bounds_check
) {
1392 put_ptr(s1
, bounds_section
, 0);
1396 section_ptr_add(s
, n
);
1400 " extern void __bt_init(),*__rt_info[],__bt_init_dll();"
1401 "__attribute__((constructor)) static void __bt_init_rt(){");
1402 #ifdef TCC_TARGET_PE
1403 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1404 #ifdef CONFIG_TCC_BCHECK
1405 cstr_printf(&cstr
, "__bt_init_dll(%d);", s1
->do_bounds_check
);
1407 cstr_printf(&cstr
, "__bt_init_dll(0);");
1410 cstr_printf(&cstr
, "__bt_init(__rt_info,%d, 0);}",
1411 s1
->output_type
== TCC_OUTPUT_DLL
? 0 : s1
->rt_num_callers
+ 1);
1412 tcc_compile_string(s1
, cstr
.data
);
1414 set_local_sym(s1
, &"___rt_info"[!s1
->leading_underscore
], s
, o
);
1418 #ifndef TCC_TARGET_PE
1419 /* add tcc runtime libraries */
1420 ST_FUNC
void tcc_add_runtime(TCCState
*s1
)
1423 #ifdef CONFIG_TCC_BCHECK
1426 tcc_add_pragma_libs(s1
);
1428 if (!s1
->nostdlib
) {
1429 if (s1
->option_pthread
)
1430 tcc_add_library_err(s1
, "pthread");
1431 tcc_add_library_err(s1
, "c");
1433 if (!s1
->static_link
) {
1434 if (TCC_LIBGCC
[0] == '/')
1435 tcc_add_file(s1
, TCC_LIBGCC
);
1437 tcc_add_dll(s1
, TCC_LIBGCC
, 0);
1440 #ifdef CONFIG_TCC_BCHECK
1441 if (s1
->do_bounds_check
&& s1
->output_type
!= TCC_OUTPUT_DLL
) {
1442 tcc_add_library_err(s1
, "pthread");
1443 #if !TARGETOS_OpenBSD && !TARGETOS_NetBSD
1444 tcc_add_library_err(s1
, "dl");
1446 tcc_add_support(s1
, "bcheck.o");
1449 #ifdef CONFIG_TCC_BACKTRACE
1450 if (s1
->do_backtrace
) {
1451 if (s1
->output_type
== TCC_OUTPUT_EXE
)
1452 tcc_add_support(s1
, "bt-exe.o");
1453 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1454 tcc_add_support(s1
, "bt-log.o");
1455 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1459 if (strlen(TCC_LIBTCC1
) > 0)
1460 tcc_add_support(s1
, TCC_LIBTCC1
);
1461 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
1462 /* add crt end if not memory output */
1463 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1464 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1465 tcc_add_crt(s1
, "crtendS.o");
1467 tcc_add_crt(s1
, "crtend.o");
1468 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
1469 tcc_add_crt(s1
, "crtn.o");
1472 #elif !defined(TCC_TARGET_MACHO)
1473 /* add crt end if not memory output */
1474 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1475 tcc_add_crt(s1
, "crtn.o");
1481 /* add various standard linker symbols (must be done after the
1482 sections are filled (for example after allocating common
1484 static void tcc_add_linker_symbols(TCCState
*s1
)
1490 set_global_sym(s1
, "_etext", text_section
, -1);
1491 set_global_sym(s1
, "_edata", data_section
, -1);
1492 set_global_sym(s1
, "_end", bss_section
, -1);
1493 #ifdef TCC_TARGET_RISCV64
1494 /* XXX should be .sdata+0x800, not .data+0x800 */
1495 set_global_sym(s1
, "__global_pointer$", data_section
, 0x800);
1497 /* horrible new standard ldscript defines */
1498 add_init_array_defines(s1
, ".preinit_array");
1499 add_init_array_defines(s1
, ".init_array");
1500 add_init_array_defines(s1
, ".fini_array");
1501 /* add start and stop symbols for sections whose name can be
1503 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1504 s
= s1
->sections
[i
];
1505 if ((s
->sh_flags
& SHF_ALLOC
)
1506 && (s
->sh_type
== SHT_PROGBITS
1507 || s
->sh_type
== SHT_STRTAB
)) {
1509 /* check if section name can be expressed in C */
1515 if (!isid(c
) && !isnum(c
))
1519 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1520 set_global_sym(s1
, buf
, s
, 0);
1521 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1522 set_global_sym(s1
, buf
, s
, -1);
1528 ST_FUNC
void resolve_common_syms(TCCState
*s1
)
1532 /* Allocate common symbols in BSS. */
1533 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1534 if (sym
->st_shndx
== SHN_COMMON
) {
1535 /* symbol alignment is in st_value for SHN_COMMONs */
1536 sym
->st_value
= section_add(bss_section
, sym
->st_size
,
1538 sym
->st_shndx
= bss_section
->sh_num
;
1542 /* Now assign linker provided symbols their value. */
1543 tcc_add_linker_symbols(s1
);
1546 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1547 const int *sec_order
)
1550 int i
, offset
, size
;
1553 for(i
=1;i
<s1
->nb_sections
;i
++) {
1554 s
= s1
->sections
[sec_order
[i
]];
1555 if (s
->sh_type
!= SHT_NOBITS
&&
1556 (s
->sh_flags
& SHF_ALLOC
)) {
1557 while (offset
< s
->sh_offset
) {
1562 fwrite(s
->data
, 1, size
, f
);
1568 #ifndef ELF_OBJ_ONLY
1569 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1571 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1572 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1573 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1574 unsigned offset
= attr
->got_offset
;
1578 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1580 write64le(s1
->got
->data
+ offset
, sym
->st_value
);
1582 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1586 /* Perform relocation to GOT or PLT entries */
1587 ST_FUNC
void fill_got(TCCState
*s1
)
1593 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1594 s
= s1
->sections
[i
];
1595 if (s
->sh_type
!= SHT_RELX
)
1597 /* no need to handle got relocations */
1598 if (s
->link
!= symtab_section
)
1600 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1601 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1602 case R_X86_64_GOT32
:
1603 case R_X86_64_GOTPCREL
:
1604 case R_X86_64_GOTPCRELX
:
1605 case R_X86_64_REX_GOTPCRELX
:
1606 case R_X86_64_PLT32
:
1607 fill_got_entry(s1
, rel
);
1614 /* See put_got_entry for a description. This is the second stage
1615 where GOT references to local defined symbols are rewritten. */
1616 static void fill_local_got_entries(TCCState
*s1
)
1619 if (!s1
->got
->reloc
)
1621 for_each_elem(s1
->got
->reloc
, 0, rel
, ElfW_Rel
) {
1622 if (ELFW(R_TYPE
)(rel
->r_info
) == R_RELATIVE
) {
1623 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1624 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1625 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1626 unsigned offset
= attr
->got_offset
;
1627 if (offset
!= rel
->r_offset
- s1
->got
->sh_addr
)
1628 tcc_error_noabort("huh");
1629 rel
->r_info
= ELFW(R_INFO
)(0, R_RELATIVE
);
1630 #if SHT_RELX == SHT_RELA
1631 rel
->r_addend
= sym
->st_value
;
1633 /* All our REL architectures also happen to be 32bit LE. */
1634 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1640 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1641 in shared libraries and export non local defined symbols to shared libraries
1642 if -rdynamic switch was given on command line */
1643 static void bind_exe_dynsyms(TCCState
*s1
)
1646 int sym_index
, index
;
1647 ElfW(Sym
) *sym
, *esym
;
1650 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1651 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1652 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1653 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1654 if (sym
->st_shndx
== SHN_UNDEF
) {
1655 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1656 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1658 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1659 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1660 if ((type
== STT_FUNC
) || (type
== STT_GNU_IFUNC
)) {
1661 /* Indirect functions shall have STT_FUNC type in executable
1662 * dynsym section. Indeed, a dlsym call following a lazy
1663 * resolution would pick the symbol value from the
1664 * executable dynsym entry which would contain the address
1665 * of the function wanted by the caller of dlsym instead of
1666 * the address of the function that would return that
1669 = put_elf_sym(s1
->dynsym
, 0, esym
->st_size
,
1670 ELFW(ST_INFO
)(STB_GLOBAL
,STT_FUNC
), 0, 0,
1672 int index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1673 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1674 } else if (type
== STT_OBJECT
) {
1675 unsigned long offset
;
1677 offset
= bss_section
->data_offset
;
1678 /* XXX: which alignment ? */
1679 offset
= (offset
+ 16 - 1) & -16;
1680 set_elf_sym (s1
->symtab
, offset
, esym
->st_size
,
1681 esym
->st_info
, 0, bss_section
->sh_num
, name
);
1682 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1683 esym
->st_info
, 0, bss_section
->sh_num
,
1686 /* Ensure R_COPY works for weak symbol aliases */
1687 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1688 for_each_elem(s1
->dynsymtab_section
, 1, dynsym
, ElfW(Sym
)) {
1689 if ((dynsym
->st_value
== esym
->st_value
)
1690 && (ELFW(ST_BIND
)(dynsym
->st_info
) == STB_GLOBAL
)) {
1691 char *dynname
= (char *) s1
->dynsymtab_section
->link
->data
1693 put_elf_sym(s1
->dynsym
, offset
, dynsym
->st_size
,
1695 bss_section
->sh_num
, dynname
);
1701 put_elf_reloc(s1
->dynsym
, bss_section
,
1702 offset
, R_COPY
, index
);
1703 offset
+= esym
->st_size
;
1704 bss_section
->data_offset
= offset
;
1707 /* STB_WEAK undefined symbols are accepted */
1708 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1709 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1710 !strcmp(name
, "_fp_hw")) {
1712 tcc_error_noabort("undefined symbol '%s'", name
);
1715 } else if (s1
->rdynamic
&& ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1716 /* if -rdynamic option, then export all non local symbols */
1717 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1718 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
1719 0, sym
->st_shndx
, name
);
1724 /* Bind symbols of libraries: export all non local symbols of executable that
1725 are referenced by shared libraries. The reason is that the dynamic loader
1726 search symbol first in executable and then in libraries. Therefore a
1727 reference to a symbol already defined by a library can still be resolved by
1728 a symbol in the executable. */
1729 static void bind_libs_dynsyms(TCCState
*s1
)
1733 ElfW(Sym
) *sym
, *esym
;
1735 for_each_elem(s1
->dynsymtab_section
, 1, esym
, ElfW(Sym
)) {
1736 name
= (char *) s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1737 sym_index
= find_elf_sym(symtab_section
, name
);
1738 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1739 if (sym_index
&& sym
->st_shndx
!= SHN_UNDEF
1740 && ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1741 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1742 sym
->st_info
, 0, sym
->st_shndx
, name
);
1743 } else if (esym
->st_shndx
== SHN_UNDEF
) {
1744 /* weak symbols can stay undefined */
1745 if (ELFW(ST_BIND
)(esym
->st_info
) != STB_WEAK
)
1746 tcc_warning("undefined dynamic symbol '%s'", name
);
1751 /* Export all non local symbols. This is used by shared libraries so that the
1752 non local symbols they define can resolve a reference in another shared
1753 library or in the executable. Correspondingly, it allows undefined local
1754 symbols to be resolved by other shared libraries or by the executable. */
1755 static void export_global_syms(TCCState
*s1
)
1757 int dynindex
, index
;
1761 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1762 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1763 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1764 dynindex
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1765 sym
->st_info
, 0, sym
->st_shndx
, name
);
1766 index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1767 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1773 /* Allocate strings for section names and decide if an unallocated section
1775 NOTE: the strsec section comes last, so its size is also correct ! */
1776 static int alloc_sec_names(TCCState
*s1
, int file_type
, Section
*strsec
)
1782 /* Allocate strings for section names */
1783 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1784 s
= s1
->sections
[i
];
1785 /* when generating a DLL, we include relocations but we may
1787 #ifndef ELF_OBJ_ONLY
1788 if (file_type
== TCC_OUTPUT_DLL
&&
1789 s
->sh_type
== SHT_RELX
&&
1790 !(s
->sh_flags
& SHF_ALLOC
) &&
1791 (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
) &&
1792 prepare_dynamic_rel(s1
, s
)) {
1793 if (!(s1
->sections
[s
->sh_info
]->sh_flags
& SHF_WRITE
))
1797 if ((s1
->do_debug
&& s
->sh_type
!= SHT_RELX
) ||
1798 file_type
== TCC_OUTPUT_OBJ
||
1799 (s
->sh_flags
& SHF_ALLOC
) ||
1800 i
== (s1
->nb_sections
- 1)
1801 #ifdef TCC_TARGET_ARM
1802 || s
->sh_type
== SHT_ARM_ATTRIBUTES
1805 /* we output all sections if debug or object file */
1806 s
->sh_size
= s
->data_offset
;
1808 #ifdef TCC_TARGET_ARM
1809 /* XXX: Suppress stack unwinding section. */
1810 if (s
->sh_type
== SHT_ARM_EXIDX
) {
1815 if (s
->sh_size
|| (s
->sh_flags
& SHF_ALLOC
))
1816 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1818 strsec
->sh_size
= strsec
->data_offset
;
1822 /* Info to be copied in dynamic section */
1826 unsigned long data_offset
;
1829 #if PTR_SIZE == 4 && (TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel)
1835 /* Assign sections to segments and decide how are sections laid out when loaded
1836 in memory. This function also fills corresponding program headers. */
1837 static int layout_sections(TCCState
*s1
, ElfW(Phdr
) *phdr
, int phnum
,
1838 Section
*interp
, Section
* strsec
,
1839 struct dyn_inf
*dyninf
, int *sec_order
)
1841 int i
, sh_order_index
, file_offset
;
1846 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
1847 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1849 #ifndef ELF_OBJ_ONLY
1850 if (phnum
> 0) { /* phnum is 0 for TCC_OUTPUT_OBJ */
1851 unsigned long s_align
;
1855 int j
, k
, file_type
= s1
->output_type
;
1857 s_align
= ELF_PAGE_SIZE
;
1858 if (s1
->section_align
)
1859 s_align
= s1
->section_align
;
1861 if (s1
->has_text_addr
) {
1862 int a_offset
, p_offset
;
1863 addr
= s1
->text_addr
;
1864 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1866 a_offset
= (int) (addr
& (s_align
- 1));
1867 p_offset
= file_offset
& (s_align
- 1);
1868 if (a_offset
< p_offset
)
1869 a_offset
+= s_align
;
1870 file_offset
+= (a_offset
- p_offset
);
1872 if (file_type
== TCC_OUTPUT_DLL
)
1875 addr
= ELF_START_ADDR
;
1876 /* compute address after headers */
1877 addr
+= (file_offset
& (s_align
- 1));
1881 /* Leave one program headers for the program interpreter and one for
1882 the program header table itself if needed. These are done later as
1883 they require section layout to be done first. */
1887 /* dynamic relocation table information, for .dynamic section */
1888 dyninf
->rel_addr
= dyninf
->rel_size
= 0;
1889 #if PTR_SIZE == 4 && (TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel)
1890 dyninf
->bss_addr
= dyninf
->bss_size
= 0;
1893 for(j
= 0; j
< (phnum
== 6 ? 3 : 2); j
++) {
1894 Section
*relocplt
= s1
->got
? s1
->got
->relocplt
: NULL
;
1896 ph
->p_type
= j
== 2 ? PT_TLS
: PT_LOAD
;
1898 ph
->p_flags
= PF_R
| PF_X
;
1900 ph
->p_flags
= PF_R
| PF_W
;
1901 ph
->p_align
= j
== 2 ? 4 : s_align
;
1903 /* Decide the layout of sections loaded in memory. This must
1904 be done before program headers are filled since they contain
1905 info about the layout. We do the following ordering: interp,
1906 symbol tables, relocations, progbits, nobits */
1907 /* XXX: do faster and simpler sorting */
1908 for(k
= 0; k
< 6; k
++) {
1909 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1910 s
= s1
->sections
[i
];
1911 /* compute if section should be included */
1913 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
| SHF_TLS
)) !=
1916 } else if (j
== 1) {
1917 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
| SHF_TLS
)) !=
1918 (SHF_ALLOC
| SHF_WRITE
))
1921 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
| SHF_TLS
)) !=
1922 (SHF_ALLOC
| SHF_WRITE
| SHF_TLS
))
1928 } else if ((s
->sh_type
== SHT_DYNSYM
||
1929 s
->sh_type
== SHT_STRTAB
||
1930 s
->sh_type
== SHT_HASH
)
1931 && !strstr(s
->name
, ".stab")) {
1934 } else if (s
->sh_type
== SHT_RELX
) {
1935 if (k
!= 2 && s
!= relocplt
)
1937 else if (k
!= 3 && s
== relocplt
)
1939 } else if (s
->sh_type
== SHT_NOBITS
) {
1946 sec_order
[sh_order_index
++] = i
;
1948 /* section matches: we align it and add its size */
1950 addr
= (addr
+ s
->sh_addralign
- 1) &
1951 ~(s
->sh_addralign
- 1);
1952 file_offset
+= (int) ( addr
- tmp
);
1953 s
->sh_offset
= file_offset
;
1956 /* update program header infos */
1957 if (ph
->p_offset
== 0) {
1958 ph
->p_offset
= file_offset
;
1960 ph
->p_paddr
= ph
->p_vaddr
;
1962 /* update dynamic relocation infos */
1963 if (s
->sh_type
== SHT_RELX
&& s
!= relocplt
) {
1964 #if PTR_SIZE == 4 && (TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel)
1965 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.got")) {
1966 dyninf
->rel_addr
= addr
;
1967 dyninf
->rel_size
+= s
->sh_size
; /* XXX only first rel. */
1969 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.bss")) {
1970 dyninf
->bss_addr
= addr
;
1971 dyninf
->bss_size
= s
->sh_size
; /* XXX only first rel. */
1974 if (dyninf
->rel_size
== 0)
1975 dyninf
->rel_addr
= addr
;
1976 dyninf
->rel_size
+= s
->sh_size
;
1980 if (s
->sh_type
!= SHT_NOBITS
)
1981 file_offset
+= s
->sh_size
;
1985 /* Make the first PT_LOAD segment include the program
1986 headers itself (and the ELF header as well), it'll
1987 come out with same memory use but will make various
1988 tools like binutils strip work better. */
1989 ph
->p_offset
&= ~(ph
->p_align
- 1);
1990 ph
->p_vaddr
&= ~(ph
->p_align
- 1);
1991 ph
->p_paddr
&= ~(ph
->p_align
- 1);
1993 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1994 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1997 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1998 /* if in the middle of a page, we duplicate the page in
1999 memory so that one copy is RX and the other is RW */
2000 if ((addr
& (s_align
- 1)) != 0)
2003 addr
= (addr
+ s_align
- 1) & ~(s_align
- 1);
2004 file_offset
= (file_offset
+ s_align
- 1) & ~(s_align
- 1);
2009 #endif /* ELF_OBJ_ONLY */
2011 /* all other sections come after */
2012 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2013 s
= s1
->sections
[i
];
2014 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
2016 sec_order
[sh_order_index
++] = i
;
2018 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
2019 ~(s
->sh_addralign
- 1);
2020 s
->sh_offset
= file_offset
;
2021 if (s
->sh_type
!= SHT_NOBITS
)
2022 file_offset
+= s
->sh_size
;
2028 #ifndef ELF_OBJ_ONLY
2029 /* put dynamic tag */
2030 static void put_dt(Section
*dynamic
, int dt
, addr_t val
)
2033 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
2035 dyn
->d_un
.d_val
= val
;
2038 static void fill_unloadable_phdr(ElfW(Phdr
) *phdr
, int phnum
, Section
*interp
,
2039 Section
*dynamic
, Section
*note
)
2043 /* if interpreter, then add corresponding program header */
2047 ph
->p_type
= PT_PHDR
;
2048 ph
->p_offset
= sizeof(ElfW(Ehdr
));
2049 ph
->p_filesz
= ph
->p_memsz
= phnum
* sizeof(ElfW(Phdr
));
2050 ph
->p_vaddr
= interp
->sh_addr
- ph
->p_filesz
;
2051 ph
->p_paddr
= ph
->p_vaddr
;
2052 ph
->p_flags
= PF_R
| PF_X
;
2053 ph
->p_align
= 4; /* interp->sh_addralign; */
2056 ph
->p_type
= PT_INTERP
;
2057 ph
->p_offset
= interp
->sh_offset
;
2058 ph
->p_vaddr
= interp
->sh_addr
;
2059 ph
->p_paddr
= ph
->p_vaddr
;
2060 ph
->p_filesz
= interp
->sh_size
;
2061 ph
->p_memsz
= interp
->sh_size
;
2063 ph
->p_align
= interp
->sh_addralign
;
2067 ph
= &phdr
[phnum
- 2];
2069 ph
->p_type
= PT_NOTE
;
2070 ph
->p_offset
= note
->sh_offset
;
2071 ph
->p_vaddr
= note
->sh_addr
;
2072 ph
->p_paddr
= ph
->p_vaddr
;
2073 ph
->p_filesz
= note
->sh_size
;
2074 ph
->p_memsz
= note
->sh_size
;
2076 ph
->p_align
= note
->sh_addralign
;
2079 /* if dynamic section, then add corresponding program header */
2081 ph
= &phdr
[phnum
- 1];
2083 ph
->p_type
= PT_DYNAMIC
;
2084 ph
->p_offset
= dynamic
->sh_offset
;
2085 ph
->p_vaddr
= dynamic
->sh_addr
;
2086 ph
->p_paddr
= ph
->p_vaddr
;
2087 ph
->p_filesz
= dynamic
->sh_size
;
2088 ph
->p_memsz
= dynamic
->sh_size
;
2089 ph
->p_flags
= PF_R
| PF_W
;
2090 ph
->p_align
= dynamic
->sh_addralign
;
2094 /* Fill the dynamic section with tags describing the address and size of
2096 static void fill_dynamic(TCCState
*s1
, struct dyn_inf
*dyninf
)
2098 Section
*dynamic
= dyninf
->dynamic
;
2101 /* put dynamic section entries */
2102 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
2103 put_dt(dynamic
, DT_STRTAB
, dyninf
->dynstr
->sh_addr
);
2104 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
2105 put_dt(dynamic
, DT_STRSZ
, dyninf
->dynstr
->data_offset
);
2106 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
2108 put_dt(dynamic
, DT_RELA
, dyninf
->rel_addr
);
2109 put_dt(dynamic
, DT_RELASZ
, dyninf
->rel_size
);
2110 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
2111 if (s1
->got
&& s1
->got
->relocplt
) {
2112 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2113 put_dt(dynamic
, DT_PLTRELSZ
, s1
->got
->relocplt
->data_offset
);
2114 put_dt(dynamic
, DT_JMPREL
, s1
->got
->relocplt
->sh_addr
);
2115 put_dt(dynamic
, DT_PLTREL
, DT_RELA
);
2117 put_dt(dynamic
, DT_RELACOUNT
, 0);
2119 #if PTR_SIZE == 4 && (TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel)
2121 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2122 put_dt(dynamic
, DT_PLTRELSZ
, dyninf
->rel_size
);
2123 put_dt(dynamic
, DT_JMPREL
, dyninf
->rel_addr
);
2124 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
2125 put_dt(dynamic
, DT_REL
, dyninf
->bss_addr
);
2126 put_dt(dynamic
, DT_RELSZ
, dyninf
->bss_size
);
2128 put_dt(dynamic
, DT_REL
, dyninf
->rel_addr
);
2129 put_dt(dynamic
, DT_RELSZ
, dyninf
->rel_size
);
2130 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
2131 if (s1
->got
&& s1
->got
->relocplt
) {
2132 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2133 put_dt(dynamic
, DT_PLTRELSZ
, s1
->got
->relocplt
->data_offset
);
2134 put_dt(dynamic
, DT_JMPREL
, s1
->got
->relocplt
->sh_addr
);
2135 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
2137 put_dt(dynamic
, DT_RELCOUNT
, 0);
2140 if (versym_section
&& verneed_section
) {
2141 /* The dynamic linker can not handle VERSYM without VERNEED */
2142 put_dt(dynamic
, DT_VERSYM
, versym_section
->sh_addr
);
2143 put_dt(dynamic
, DT_VERNEED
, verneed_section
->sh_addr
);
2144 put_dt(dynamic
, DT_VERNEEDNUM
, dt_verneednum
);
2146 s
= find_section_create (s1
, ".preinit_array", 0);
2147 if (s
&& s
->data_offset
) {
2148 put_dt(dynamic
, DT_PREINIT_ARRAY
, s
->sh_addr
);
2149 put_dt(dynamic
, DT_PREINIT_ARRAYSZ
, s
->data_offset
);
2151 s
= find_section_create (s1
, ".init_array", 0);
2152 if (s
&& s
->data_offset
) {
2153 put_dt(dynamic
, DT_INIT_ARRAY
, s
->sh_addr
);
2154 put_dt(dynamic
, DT_INIT_ARRAYSZ
, s
->data_offset
);
2156 s
= find_section_create (s1
, ".fini_array", 0);
2157 if (s
&& s
->data_offset
) {
2158 put_dt(dynamic
, DT_FINI_ARRAY
, s
->sh_addr
);
2159 put_dt(dynamic
, DT_FINI_ARRAYSZ
, s
->data_offset
);
2161 s
= find_section_create (s1
, ".init", 0);
2162 if (s
&& s
->data_offset
) {
2163 put_dt(dynamic
, DT_INIT
, s
->sh_addr
);
2165 s
= find_section_create (s1
, ".fini", 0);
2166 if (s
&& s
->data_offset
) {
2167 put_dt(dynamic
, DT_FINI
, s
->sh_addr
);
2170 put_dt(dynamic
, DT_DEBUG
, 0);
2171 put_dt(dynamic
, DT_NULL
, 0);
2174 /* Relocate remaining sections and symbols (that is those not related to
2176 static int final_sections_reloc(TCCState
*s1
)
2181 relocate_syms(s1
, s1
->symtab
, 0);
2183 if (s1
->nb_errors
!= 0)
2186 /* relocate sections */
2187 /* XXX: ignore sections with allocated relocations ? */
2188 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2189 s
= s1
->sections
[i
];
2190 if (s
->reloc
&& (s
!= s1
->got
|| s1
->static_link
))
2191 relocate_section(s1
, s
);
2194 /* relocate relocation entries if the relocation tables are
2195 allocated in the executable */
2196 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2197 s
= s1
->sections
[i
];
2198 if ((s
->sh_flags
& SHF_ALLOC
) &&
2199 s
->sh_type
== SHT_RELX
) {
2200 relocate_rel(s1
, s
);
2207 /* Create an ELF file on disk.
2208 This function handle ELF specific layout requirements */
2209 static void tcc_output_elf(TCCState
*s1
, FILE *f
, int phnum
, ElfW(Phdr
) *phdr
,
2210 int file_offset
, int *sec_order
)
2212 int i
, shnum
, offset
, size
, file_type
;
2215 ElfW(Shdr
) shdr
, *sh
;
2217 file_type
= s1
->output_type
;
2218 shnum
= s1
->nb_sections
;
2220 memset(&ehdr
, 0, sizeof(ehdr
));
2223 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2224 ehdr
.e_phnum
= phnum
;
2225 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2229 file_offset
= (file_offset
+ 3) & -4;
2232 ehdr
.e_ident
[0] = ELFMAG0
;
2233 ehdr
.e_ident
[1] = ELFMAG1
;
2234 ehdr
.e_ident
[2] = ELFMAG2
;
2235 ehdr
.e_ident
[3] = ELFMAG3
;
2236 ehdr
.e_ident
[4] = ELFCLASSW
;
2237 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2238 ehdr
.e_ident
[6] = EV_CURRENT
;
2239 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2240 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2242 #ifdef TCC_TARGET_ARM
2244 ehdr
.e_ident
[EI_OSABI
] = 0;
2245 ehdr
.e_flags
= EF_ARM_EABI_VER4
;
2246 if (file_type
== TCC_OUTPUT_EXE
|| file_type
== TCC_OUTPUT_DLL
)
2247 ehdr
.e_flags
|= EF_ARM_HASENTRY
;
2248 if (s1
->float_abi
== ARM_HARD_FLOAT
)
2249 ehdr
.e_flags
|= EF_ARM_VFP_FLOAT
;
2251 ehdr
.e_flags
|= EF_ARM_SOFT_FLOAT
;
2253 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2255 #elif defined TCC_TARGET_RISCV64
2256 ehdr
.e_flags
= EF_RISCV_FLOAT_ABI_DOUBLE
;
2260 case TCC_OUTPUT_EXE
:
2261 ehdr
.e_type
= ET_EXEC
;
2262 ehdr
.e_entry
= get_sym_addr(s1
, "_start", 1, 0);
2264 case TCC_OUTPUT_DLL
:
2265 ehdr
.e_type
= ET_DYN
;
2266 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
2268 case TCC_OUTPUT_OBJ
:
2269 ehdr
.e_type
= ET_REL
;
2272 ehdr
.e_machine
= EM_TCC_TARGET
;
2273 ehdr
.e_version
= EV_CURRENT
;
2274 ehdr
.e_shoff
= file_offset
;
2275 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2276 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2277 ehdr
.e_shnum
= shnum
;
2278 ehdr
.e_shstrndx
= shnum
- 1;
2280 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2281 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2282 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2284 sort_syms(s1
, symtab_section
);
2285 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2286 s
= s1
->sections
[sec_order
[i
]];
2287 if (s
->sh_type
!= SHT_NOBITS
) {
2288 while (offset
< s
->sh_offset
) {
2294 fwrite(s
->data
, 1, size
, f
);
2299 /* output section headers */
2300 while (offset
< ehdr
.e_shoff
) {
2305 for(i
= 0; i
< s1
->nb_sections
; i
++) {
2307 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2308 s
= s1
->sections
[i
];
2310 sh
->sh_name
= s
->sh_name
;
2311 sh
->sh_type
= s
->sh_type
;
2312 sh
->sh_flags
= s
->sh_flags
;
2313 sh
->sh_entsize
= s
->sh_entsize
;
2314 sh
->sh_info
= s
->sh_info
;
2316 sh
->sh_link
= s
->link
->sh_num
;
2317 sh
->sh_addralign
= s
->sh_addralign
;
2318 sh
->sh_addr
= s
->sh_addr
;
2319 sh
->sh_offset
= s
->sh_offset
;
2320 sh
->sh_size
= s
->sh_size
;
2322 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2326 /* Write an elf, coff or "binary" file */
2327 static int tcc_write_elf_file(TCCState
*s1
, const char *filename
, int phnum
,
2328 ElfW(Phdr
) *phdr
, int file_offset
, int *sec_order
)
2330 int fd
, mode
, file_type
;
2333 file_type
= s1
->output_type
;
2334 if (file_type
== TCC_OUTPUT_OBJ
)
2339 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2341 tcc_error_noabort("could not write '%s'", filename
);
2344 f
= fdopen(fd
, "wb");
2346 printf("<- %s\n", filename
);
2348 #ifdef TCC_TARGET_COFF
2349 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
)
2350 tcc_output_coff(s1
, f
);
2353 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2354 tcc_output_elf(s1
, f
, phnum
, phdr
, file_offset
, sec_order
);
2356 tcc_output_binary(s1
, f
, sec_order
);
2362 #ifndef ELF_OBJ_ONLY
2363 /* Sort section headers by assigned sh_addr, remove sections
2364 that we aren't going to output. */
2365 static void tidy_section_headers(TCCState
*s1
, int *sec_order
)
2367 int i
, nnew
, l
, *backmap
;
2371 snew
= tcc_malloc(s1
->nb_sections
* sizeof(snew
[0]));
2372 backmap
= tcc_malloc(s1
->nb_sections
* sizeof(backmap
[0]));
2373 for (i
= 0, nnew
= 0, l
= s1
->nb_sections
; i
< s1
->nb_sections
; i
++) {
2374 s
= s1
->sections
[sec_order
[i
]];
2375 if (!i
|| s
->sh_name
) {
2376 backmap
[sec_order
[i
]] = nnew
;
2380 backmap
[sec_order
[i
]] = 0;
2384 for (i
= 0; i
< nnew
; i
++) {
2388 if (s
->sh_type
== SHT_RELX
)
2389 s
->sh_info
= backmap
[s
->sh_info
];
2393 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
))
2394 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2395 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2396 if ( !s1
->static_link
) {
2397 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
))
2398 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2399 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2401 for (i
= 0; i
< s1
->nb_sections
; i
++)
2403 tcc_free(s1
->sections
);
2404 s1
->sections
= snew
;
2405 s1
->nb_sections
= nnew
;
2410 #ifdef TCC_TARGET_ARM
2411 static void create_arm_attribute_section(TCCState
*s1
)
2413 // Needed for DLL support.
2414 static const unsigned char arm_attr
[] = {
2416 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2417 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2418 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2419 0x05, 0x36, 0x00, // 'CPU_name', "6"
2420 0x06, 0x06, // 'CPU_arch', 'v6'
2421 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2422 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2423 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2424 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2425 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2426 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2427 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2428 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2429 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2430 0x1a, 0x02, // 'ABI_enum_size', 'int'
2431 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2432 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2434 Section
*attr
= new_section(s1
, ".ARM.attributes", SHT_ARM_ATTRIBUTES
, 0);
2435 unsigned char *ptr
= section_ptr_add(attr
, sizeof(arm_attr
));
2436 attr
->sh_addralign
= 1;
2437 memcpy(ptr
, arm_attr
, sizeof(arm_attr
));
2438 if (s1
->float_abi
!= ARM_HARD_FLOAT
) {
2439 ptr
[26] = 0x00; // 'FP_arch', 'No'
2440 ptr
[41] = 0x1e; // 'ABI_optimization_goals'
2441 ptr
[42] = 0x06; // 'Aggressive Debug'
2446 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2447 static Section
*create_bsd_note_section(TCCState
*s1
,
2451 Section
*s
= find_section (s1
, name
);
2453 if (s
->data_offset
== 0) {
2454 unsigned char *ptr
= section_ptr_add(s
, sizeof(ElfW(Nhdr
)) + 8 + 4);
2455 ElfW(Nhdr
) *note
= (ElfW(Nhdr
) *) ptr
;
2457 s
->sh_type
= SHT_NOTE
;
2460 note
->n_type
= ELF_NOTE_OS_GNU
;
2461 strcpy (ptr
+ sizeof(ElfW(Nhdr
)), value
);
2467 /* Output an elf, coff or binary file */
2468 /* XXX: suppress unneeded sections */
2469 static int elf_output_file(TCCState
*s1
, const char *filename
)
2471 int ret
, phnum
, shnum
, file_type
, file_offset
, *sec_order
;
2472 struct dyn_inf dyninf
= {0};
2474 Section
*strsec
, *interp
, *dynamic
, *dynstr
, *note
= NULL
;
2476 file_type
= s1
->output_type
;
2478 #ifdef TCC_TARGET_ARM
2479 create_arm_attribute_section (s1
);
2481 #if TARGETOS_OpenBSD
2482 if (file_type
!= TCC_OUTPUT_OBJ
)
2483 note
= create_bsd_note_section (s1
, ".note.openbsd.ident", "OpenBSD");
2486 if (file_type
!= TCC_OUTPUT_OBJ
)
2487 note
= create_bsd_note_section (s1
, ".note.netbsd.ident", "NetBSD");
2494 interp
= dynamic
= dynstr
= NULL
; /* avoid warning */
2496 #ifndef ELF_OBJ_ONLY
2497 if (file_type
!= TCC_OUTPUT_OBJ
) {
2498 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2499 tcc_add_runtime(s1
);
2500 resolve_common_syms(s1
);
2502 if (!s1
->static_link
) {
2503 if (file_type
== TCC_OUTPUT_EXE
) {
2505 /* allow override the dynamic loader */
2506 const char *elfint
= getenv("LD_SO");
2508 elfint
= DEFAULT_ELFINTERP(s1
);
2509 /* add interpreter section only if executable */
2510 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
2511 interp
->sh_addralign
= 1;
2512 ptr
= section_ptr_add(interp
, 1 + strlen(elfint
));
2513 strcpy(ptr
, elfint
);
2516 /* add dynamic symbol table */
2517 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
2519 ".hash", SHF_ALLOC
);
2520 dynstr
= s1
->dynsym
->link
;
2521 /* add dynamic section */
2522 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
2523 SHF_ALLOC
| SHF_WRITE
);
2524 dynamic
->link
= dynstr
;
2525 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
2529 if (file_type
== TCC_OUTPUT_EXE
) {
2530 bind_exe_dynsyms(s1
);
2533 bind_libs_dynsyms(s1
);
2535 /* shared library case: simply export all global symbols */
2536 export_global_syms(s1
);
2539 build_got_entries(s1
);
2544 /* we add a section for symbols */
2545 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
2546 put_elf_str(strsec
, "");
2548 /* Allocate strings for section names */
2549 ret
= alloc_sec_names(s1
, file_type
, strsec
);
2551 #ifndef ELF_OBJ_ONLY
2554 /* add a list of needed dlls */
2555 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2556 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
2557 if (dllref
->level
== 0)
2558 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
2562 put_dt(dynamic
, s1
->enable_new_dtags
? DT_RUNPATH
: DT_RPATH
,
2563 put_elf_str(dynstr
, s1
->rpath
));
2565 if (file_type
== TCC_OUTPUT_DLL
) {
2567 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
2568 /* XXX: currently, since we do not handle PIC code, we
2569 must relocate the readonly segments */
2571 put_dt(dynamic
, DT_TEXTREL
, 0);
2575 put_dt(dynamic
, DT_SYMBOLIC
, 0);
2577 dyninf
.dynamic
= dynamic
;
2578 dyninf
.dynstr
= dynstr
;
2579 /* remember offset and reserve space for 2nd call below */
2580 dyninf
.data_offset
= dynamic
->data_offset
;
2581 fill_dynamic(s1
, &dyninf
);
2582 dynamic
->sh_size
= dynamic
->data_offset
;
2583 dynstr
->sh_size
= dynstr
->data_offset
;
2587 /* compute number of program headers */
2588 if (file_type
== TCC_OUTPUT_OBJ
)
2590 else if (file_type
== TCC_OUTPUT_DLL
)
2592 else if (s1
->static_link
)
2596 for (i
= 1; i
< s1
->nb_sections
&&
2597 !(s1
->sections
[i
]->sh_flags
& SHF_TLS
); i
++);
2598 phnum
= i
< s1
->nb_sections
? 6 : 5;
2601 phnum
+= note
!= NULL
;
2603 /* allocate program segment headers */
2604 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
2606 /* compute number of sections */
2607 shnum
= s1
->nb_sections
;
2609 /* this array is used to reorder sections in the output file */
2610 sec_order
= tcc_malloc(sizeof(int) * shnum
);
2613 /* compute section to program header mapping */
2614 file_offset
= layout_sections(s1
, phdr
, phnum
, interp
, strsec
, &dyninf
,
2617 #ifndef ELF_OBJ_ONLY
2618 /* Fill remaining program header and finalize relocation related to dynamic
2620 if (file_type
!= TCC_OUTPUT_OBJ
) {
2621 fill_unloadable_phdr(phdr
, phnum
, interp
, dynamic
, note
);
2624 dynamic
->data_offset
= dyninf
.data_offset
;
2625 fill_dynamic(s1
, &dyninf
);
2627 /* put in GOT the dynamic section address and relocate PLT */
2628 write32le(s1
->got
->data
, dynamic
->sh_addr
);
2629 if (file_type
== TCC_OUTPUT_EXE
2630 || (RELOCATE_DLLPLT
&& file_type
== TCC_OUTPUT_DLL
))
2633 /* relocate symbols in .dynsym now that final addresses are known */
2634 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
)) {
2635 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
) {
2636 /* do symbol relocation */
2637 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
2642 /* if building executable or DLL, then relocate each section
2643 except the GOT which is already relocated */
2644 ret
= final_sections_reloc(s1
);
2647 tidy_section_headers(s1
, sec_order
);
2649 /* Perform relocation to GOT or PLT entries */
2650 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2653 fill_local_got_entries(s1
);
2657 /* Create the ELF file with name 'filename' */
2658 ret
= tcc_write_elf_file(s1
, filename
, phnum
, phdr
, file_offset
, sec_order
);
2659 s1
->nb_sections
= shnum
;
2662 tcc_free(sec_order
);
2667 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2670 #ifdef TCC_TARGET_PE
2671 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2672 ret
= pe_output_file(s
, filename
);
2674 #elif TCC_TARGET_MACHO
2675 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2676 ret
= macho_output_file(s
, filename
);
2679 ret
= elf_output_file(s
, filename
);
2683 ST_FUNC ssize_t
full_read(int fd
, void *buf
, size_t count
) {
2687 ssize_t num
= read(fd
, cbuf
, count
-rnum
);
2688 if (num
< 0) return num
;
2689 if (num
== 0) return rnum
;
2695 ST_FUNC
void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2699 data
= tcc_malloc(size
);
2700 lseek(fd
, file_offset
, SEEK_SET
);
2701 full_read(fd
, data
, size
);
2705 typedef struct SectionMergeInfo
{
2706 Section
*s
; /* corresponding existing section */
2707 unsigned long offset
; /* offset of the new section in the existing section */
2708 uint8_t new_section
; /* true if section 's' was added */
2709 uint8_t link_once
; /* true if link once section */
2712 ST_FUNC
int tcc_object_type(int fd
, ElfW(Ehdr
) *h
)
2714 int size
= full_read(fd
, h
, sizeof *h
);
2715 if (size
== sizeof *h
&& 0 == memcmp(h
, ELFMAG
, 4)) {
2716 if (h
->e_type
== ET_REL
)
2717 return AFF_BINTYPE_REL
;
2718 if (h
->e_type
== ET_DYN
)
2719 return AFF_BINTYPE_DYN
;
2720 } else if (size
>= 8) {
2721 if (0 == memcmp(h
, ARMAG
, 8))
2722 return AFF_BINTYPE_AR
;
2723 #ifdef TCC_TARGET_COFF
2724 if (((struct filehdr
*)h
)->f_magic
== COFF_C67_MAGIC
)
2725 return AFF_BINTYPE_C67
;
2731 /* load an object file and merge it with current files */
2732 /* XXX: handle correctly stab (debug) info */
2733 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
2734 int fd
, unsigned long file_offset
)
2737 ElfW(Shdr
) *shdr
, *sh
;
2738 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
, seencompressed
;
2739 char *strsec
, *strtab
;
2740 int stab_index
, stabstr_index
;
2741 int *old_to_new_syms
;
2742 char *sh_name
, *name
;
2743 SectionMergeInfo
*sm_table
, *sm
;
2744 ElfW(Sym
) *sym
, *symtab
;
2748 lseek(fd
, file_offset
, SEEK_SET
);
2749 if (tcc_object_type(fd
, &ehdr
) != AFF_BINTYPE_REL
)
2751 /* test CPU specific stuff */
2752 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2753 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2755 tcc_error_noabort("invalid object file");
2759 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2760 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2761 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2763 /* load section names */
2764 sh
= &shdr
[ehdr
.e_shstrndx
];
2765 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2767 /* load symtab and strtab */
2768 old_to_new_syms
= NULL
;
2773 stab_index
= stabstr_index
= 0;
2775 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2777 if (sh
->sh_type
== SHT_SYMTAB
) {
2779 tcc_error_noabort("object must contain only one symtab");
2784 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2785 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2786 sm_table
[i
].s
= symtab_section
;
2788 /* now load strtab */
2789 sh
= &shdr
[sh
->sh_link
];
2790 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2792 if (sh
->sh_flags
& SHF_COMPRESSED
)
2796 /* now examine each section and try to merge its content with the
2798 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2799 /* no need to examine section name strtab */
2800 if (i
== ehdr
.e_shstrndx
)
2803 if (sh
->sh_type
== SHT_RELX
)
2804 sh
= &shdr
[sh
->sh_info
];
2805 /* ignore sections types we do not handle (plus relocs to those) */
2806 if (sh
->sh_type
!= SHT_PROGBITS
&&
2808 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2810 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2811 sh
->sh_type
!= SHT_X86_64_UNWIND
&&
2812 sh
->sh_type
!= SHT_NOTE
&&
2814 sh
->sh_type
!= SHT_NOBITS
&&
2815 sh
->sh_type
!= SHT_PREINIT_ARRAY
&&
2816 sh
->sh_type
!= SHT_INIT_ARRAY
&&
2817 sh
->sh_type
!= SHT_FINI_ARRAY
&&
2818 strcmp(strsec
+ sh
->sh_name
, ".stabstr")
2822 && !strncmp(strsec
+ sh
->sh_name
, ".debug_", sizeof(".debug_")-1))
2826 sh_name
= strsec
+ sh
->sh_name
;
2827 if (sh
->sh_addralign
< 1)
2828 sh
->sh_addralign
= 1;
2829 /* find corresponding section, if any */
2830 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2831 s
= s1
->sections
[j
];
2832 if (!strcmp(s
->name
, sh_name
)) {
2833 if (!strncmp(sh_name
, ".gnu.linkonce",
2834 sizeof(".gnu.linkonce") - 1)) {
2835 /* if a 'linkonce' section is already present, we
2836 do not add it again. It is a little tricky as
2837 symbols can still be defined in
2839 sm_table
[i
].link_once
= 1;
2843 if (s
== stab_section
)
2845 if (s
== stab_section
->link
)
2851 /* not found: create new section */
2852 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
& ~SHF_GROUP
);
2853 /* take as much info as possible from the section. sh_link and
2854 sh_info will be updated later */
2855 s
->sh_addralign
= sh
->sh_addralign
;
2856 s
->sh_entsize
= sh
->sh_entsize
;
2857 sm_table
[i
].new_section
= 1;
2859 if (sh
->sh_type
!= s
->sh_type
) {
2860 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2861 if (strcmp (s
->name
, ".eh_frame"))
2864 tcc_error_noabort("invalid section type");
2868 /* align start of section */
2869 s
->data_offset
+= -s
->data_offset
& (sh
->sh_addralign
- 1);
2870 if (sh
->sh_addralign
> s
->sh_addralign
)
2871 s
->sh_addralign
= sh
->sh_addralign
;
2872 sm_table
[i
].offset
= s
->data_offset
;
2874 /* concatenate sections */
2876 if (sh
->sh_type
!= SHT_NOBITS
) {
2878 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2879 ptr
= section_ptr_add(s
, size
);
2880 full_read(fd
, ptr
, size
);
2882 s
->data_offset
+= size
;
2887 /* gr relocate stab strings */
2888 if (stab_index
&& stabstr_index
) {
2891 s
= sm_table
[stab_index
].s
;
2892 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2893 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2894 o
= sm_table
[stabstr_index
].offset
;
2902 /* second short pass to update sh_link and sh_info fields of new
2904 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2906 if (!s
|| !sm_table
[i
].new_section
)
2909 if (sh
->sh_link
> 0)
2910 s
->link
= sm_table
[sh
->sh_link
].s
;
2911 if (sh
->sh_type
== SHT_RELX
) {
2912 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2913 /* update backward link */
2914 s1
->sections
[s
->sh_info
]->reloc
= s
;
2918 /* resolve symbols */
2919 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2922 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2923 if (sym
->st_shndx
!= SHN_UNDEF
&&
2924 sym
->st_shndx
< SHN_LORESERVE
) {
2925 sm
= &sm_table
[sym
->st_shndx
];
2926 if (sm
->link_once
) {
2927 /* if a symbol is in a link once section, we use the
2928 already defined symbol. It is very important to get
2929 correct relocations */
2930 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2931 name
= strtab
+ sym
->st_name
;
2932 sym_index
= find_elf_sym(symtab_section
, name
);
2934 old_to_new_syms
[i
] = sym_index
;
2938 /* if no corresponding section added, no need to add symbol */
2941 /* convert section number */
2942 sym
->st_shndx
= sm
->s
->sh_num
;
2944 sym
->st_value
+= sm
->offset
;
2947 name
= strtab
+ sym
->st_name
;
2948 sym_index
= set_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2949 sym
->st_info
, sym
->st_other
,
2950 sym
->st_shndx
, name
);
2951 old_to_new_syms
[i
] = sym_index
;
2954 /* third pass to patch relocation entries */
2955 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2960 offset
= sm_table
[i
].offset
;
2961 switch(s
->sh_type
) {
2963 /* take relocation offset information */
2964 offseti
= sm_table
[sh
->sh_info
].offset
;
2965 for_each_elem(s
, (offset
/ sizeof(*rel
)), rel
, ElfW_Rel
) {
2968 /* convert symbol index */
2969 type
= ELFW(R_TYPE
)(rel
->r_info
);
2970 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2971 /* NOTE: only one symtab assumed */
2972 if (sym_index
>= nb_syms
)
2974 sym_index
= old_to_new_syms
[sym_index
];
2975 /* ignore link_once in rel section. */
2976 if (!sym_index
&& !sm_table
[sh
->sh_info
].link_once
2977 #ifdef TCC_TARGET_ARM
2978 && type
!= R_ARM_V4BX
2979 #elif defined TCC_TARGET_RISCV64
2980 && type
!= R_RISCV_ALIGN
2981 && type
!= R_RISCV_RELAX
2985 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2986 i
, strsec
+ sh
->sh_name
, (int)rel
->r_offset
);
2989 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2990 /* offset the relocation offset */
2991 rel
->r_offset
+= offseti
;
2992 #ifdef TCC_TARGET_ARM
2993 /* Jumps and branches from a Thumb code to a PLT entry need
2994 special handling since PLT entries are ARM code.
2995 Unconditional bl instructions referencing PLT entries are
2996 handled by converting these instructions into blx
2997 instructions. Other case of instructions referencing a PLT
2998 entry require to add a Thumb stub before the PLT entry to
2999 switch to ARM mode. We set bit plt_thumb_stub of the
3000 attribute of a symbol to indicate such a case. */
3001 if (type
== R_ARM_THM_JUMP24
)
3002 get_sym_attr(s1
, sym_index
, 1)->plt_thumb_stub
= 1;
3015 tcc_free(old_to_new_syms
);
3022 typedef struct ArchiveHeader
{
3023 char ar_name
[16]; /* name of this member */
3024 char ar_date
[12]; /* file mtime */
3025 char ar_uid
[6]; /* owner uid; printed as decimal */
3026 char ar_gid
[6]; /* owner gid; printed as decimal */
3027 char ar_mode
[8]; /* file mode, printed as octal */
3028 char ar_size
[10]; /* file size, printed as decimal */
3029 char ar_fmag
[2]; /* should contain ARFMAG */
3032 #define ARFMAG "`\n"
3034 static unsigned long long get_be(const uint8_t *b
, int n
)
3036 unsigned long long ret
= 0;
3038 ret
= (ret
<< 8) | *b
++, --n
;
3042 static int read_ar_header(int fd
, int offset
, ArchiveHeader
*hdr
)
3046 lseek(fd
, offset
, SEEK_SET
);
3047 len
= full_read(fd
, hdr
, sizeof(ArchiveHeader
));
3048 if (len
!= sizeof(ArchiveHeader
))
3049 return len
? -1 : 0;
3051 for (e
= p
+ sizeof hdr
->ar_name
; e
> p
&& e
[-1] == ' ';)
3054 hdr
->ar_size
[sizeof hdr
->ar_size
-1] = 0;
3058 /* load only the objects which resolve undefined symbols */
3059 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
, int entrysize
)
3061 int i
, bound
, nsyms
, sym_index
, len
, ret
= -1;
3062 unsigned long long off
;
3064 const char *ar_names
, *p
;
3065 const uint8_t *ar_index
;
3069 data
= tcc_malloc(size
);
3070 if (full_read(fd
, data
, size
) != size
)
3072 nsyms
= get_be(data
, entrysize
);
3073 ar_index
= data
+ entrysize
;
3074 ar_names
= (char *) ar_index
+ nsyms
* entrysize
;
3078 for (p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
3079 Section
*s
= symtab_section
;
3080 sym_index
= find_elf_sym(s
, p
);
3083 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
3084 if(sym
->st_shndx
!= SHN_UNDEF
)
3086 off
= get_be(ar_index
+ i
* entrysize
, entrysize
);
3087 len
= read_ar_header(fd
, off
, &hdr
);
3088 if (len
<= 0 || memcmp(hdr
.ar_fmag
, ARFMAG
, 2)) {
3089 tcc_error_noabort("invalid archive");
3093 if (s1
->verbose
== 2)
3094 printf(" -> %s\n", hdr
.ar_name
);
3095 if (tcc_load_object_file(s1
, fd
, off
) < 0)
3106 /* load a '.a' file */
3107 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
, int alacarte
)
3110 /* char magic[8]; */
3112 unsigned long file_offset
;
3115 /* skip magic which was already checked */
3116 /* full_read(fd, magic, sizeof(magic)); */
3117 file_offset
= sizeof ARMAG
- 1;
3120 len
= read_ar_header(fd
, file_offset
, &hdr
);
3124 tcc_error_noabort("invalid archive");
3128 size
= strtol(hdr
.ar_size
, NULL
, 0);
3130 size
= (size
+ 1) & ~1;
3132 /* coff symbol table : we handle it */
3133 if (!strcmp(hdr
.ar_name
, "/"))
3134 return tcc_load_alacarte(s1
, fd
, size
, 4);
3135 if (!strcmp(hdr
.ar_name
, "/SYM64/"))
3136 return tcc_load_alacarte(s1
, fd
, size
, 8);
3137 } else if (tcc_object_type(fd
, &ehdr
) == AFF_BINTYPE_REL
) {
3138 if (s1
->verbose
== 2)
3139 printf(" -> %s\n", hdr
.ar_name
);
3140 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
3143 file_offset
+= size
;
3147 #ifndef ELF_OBJ_ONLY
3148 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3149 LV, maybe create a new entry for (LIB,VERSION). */
3150 static void set_ver_to_ver(TCCState
*s1
, int *n
, int **lv
, int i
, char *lib
, char *version
)
3153 *lv
= tcc_realloc(*lv
, (*n
+ 1) * sizeof(**lv
));
3156 if ((*lv
)[i
] == -1) {
3157 int v
, prev_same_lib
= -1;
3158 for (v
= 0; v
< nb_sym_versions
; v
++) {
3159 if (strcmp(sym_versions
[v
].lib
, lib
))
3162 if (!strcmp(sym_versions
[v
].version
, version
))
3165 if (v
== nb_sym_versions
) {
3166 sym_versions
= tcc_realloc (sym_versions
,
3167 (v
+ 1) * sizeof(*sym_versions
));
3168 sym_versions
[v
].lib
= tcc_strdup(lib
);
3169 sym_versions
[v
].version
= tcc_strdup(version
);
3170 sym_versions
[v
].out_index
= 0;
3171 sym_versions
[v
].prev_same_lib
= prev_same_lib
;
3178 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3181 set_sym_version(TCCState
*s1
, int sym_index
, int verndx
)
3183 if (sym_index
>= nb_sym_to_version
) {
3184 int newelems
= sym_index
? sym_index
* 2 : 1;
3185 sym_to_version
= tcc_realloc(sym_to_version
,
3186 newelems
* sizeof(*sym_to_version
));
3187 memset(sym_to_version
+ nb_sym_to_version
, -1,
3188 (newelems
- nb_sym_to_version
) * sizeof(*sym_to_version
));
3189 nb_sym_to_version
= newelems
;
3191 if (sym_to_version
[sym_index
] < 0)
3192 sym_to_version
[sym_index
] = verndx
;
3195 struct versym_info
{
3197 ElfW(Verdef
) *verdef
;
3198 ElfW(Verneed
) *verneed
;
3200 int nb_local_ver
, *local_ver
;
3204 static void store_version(TCCState
*s1
, struct versym_info
*v
, char *dynstr
)
3206 char *lib
, *version
;
3210 #define DEBUG_VERSION 0
3212 if (v
->versym
&& v
->verdef
) {
3213 ElfW(Verdef
) *vdef
= v
->verdef
;
3216 ElfW(Verdaux
) *verdaux
=
3217 (ElfW(Verdaux
) *) (((char *) vdef
) + vdef
->vd_aux
);
3220 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3221 vdef
->vd_version
, vdef
->vd_flags
, vdef
->vd_ndx
,
3225 version
= dynstr
+ verdaux
->vda_name
;
3230 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vdef
->vd_ndx
,
3233 printf (" verdaux(%u): %s\n", vdef
->vd_ndx
, version
);
3236 next
= vdef
->vd_next
;
3237 vdef
= (ElfW(Verdef
) *) (((char *) vdef
) + next
);
3240 if (v
->versym
&& v
->verneed
) {
3241 ElfW(Verneed
) *vneed
= v
->verneed
;
3243 ElfW(Vernaux
) *vernaux
=
3244 (ElfW(Vernaux
) *) (((char *) vneed
) + vneed
->vn_aux
);
3246 lib
= dynstr
+ vneed
->vn_file
;
3248 printf ("verneed: %u %s\n", vneed
->vn_version
, lib
);
3250 for (i
= 0; i
< vneed
->vn_cnt
; i
++) {
3251 if ((vernaux
->vna_other
& 0x8000) == 0) { /* hidden */
3252 version
= dynstr
+ vernaux
->vna_name
;
3253 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vernaux
->vna_other
,
3256 printf (" vernaux(%u): %u %u %s\n",
3257 vernaux
->vna_other
, vernaux
->vna_hash
,
3258 vernaux
->vna_flags
, version
);
3261 vernaux
= (ElfW(Vernaux
) *) (((char *) vernaux
) + vernaux
->vna_next
);
3263 next
= vneed
->vn_next
;
3264 vneed
= (ElfW(Verneed
) *) (((char *) vneed
) + next
);
3269 for (i
= 0; i
< v
->nb_local_ver
; i
++) {
3270 if (v
->local_ver
[i
] > 0) {
3271 printf ("%d: lib: %s, version %s\n",
3272 i
, sym_versions
[v
->local_ver
[i
]].lib
,
3273 sym_versions
[v
->local_ver
[i
]].version
);
3279 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3280 is referenced by the user (so it should be added as DT_NEEDED in
3281 the generated ELF file) */
3282 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
3285 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
3286 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
3287 ElfW(Sym
) *sym
, *dynsym
;
3288 ElfW(Dyn
) *dt
, *dynamic
;
3292 const char *name
, *soname
;
3293 DLLReference
*dllref
;
3294 struct versym_info v
;
3296 full_read(fd
, &ehdr
, sizeof(ehdr
));
3298 /* test CPU specific stuff */
3299 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
3300 ehdr
.e_machine
!= EM_TCC_TARGET
) {
3301 tcc_error_noabort("bad architecture");
3306 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
3308 /* load dynamic section and dynamic symbols */
3312 dynsym
= NULL
; /* avoid warning */
3313 dynstr
= NULL
; /* avoid warning */
3314 memset(&v
, 0, sizeof v
);
3316 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
3317 switch(sh
->sh_type
) {
3319 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
3320 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3323 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
3324 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3325 sh1
= &shdr
[sh
->sh_link
];
3326 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
3328 case SHT_GNU_verdef
:
3329 v
.verdef
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3331 case SHT_GNU_verneed
:
3332 v
.verneed
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3334 case SHT_GNU_versym
:
3335 v
.nb_versyms
= sh
->sh_size
/ sizeof(ElfW(Half
));
3336 v
.versym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3343 /* compute the real library name */
3344 soname
= tcc_basename(filename
);
3346 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3347 if (dt
->d_tag
== DT_SONAME
) {
3348 soname
= dynstr
+ dt
->d_un
.d_val
;
3352 /* if the dll is already loaded, do not load it */
3353 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
3354 dllref
= s1
->loaded_dlls
[i
];
3355 if (!strcmp(soname
, dllref
->name
)) {
3356 /* but update level if needed */
3357 if (level
< dllref
->level
)
3358 dllref
->level
= level
;
3364 if (v
.nb_versyms
!= nb_syms
)
3365 tcc_free (v
.versym
), v
.versym
= NULL
;
3367 store_version(s1
, &v
, dynstr
);
3369 /* add the dll and its level */
3370 tcc_add_dllref(s1
, soname
)->level
= level
;
3372 /* add dynamic symbols in dynsym_section */
3373 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
3374 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
3375 if (sym_bind
== STB_LOCAL
)
3377 name
= dynstr
+ sym
->st_name
;
3378 sym_index
= set_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
3379 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
3381 ElfW(Half
) vsym
= v
.versym
[i
];
3382 if ((vsym
& 0x8000) == 0 && vsym
> 0 && vsym
< v
.nb_local_ver
)
3383 set_sym_version(s1
, sym_index
, v
.local_ver
[vsym
]);
3387 /* load all referenced DLLs */
3388 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3391 name
= dynstr
+ dt
->d_un
.d_val
;
3392 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
3393 dllref
= s1
->loaded_dlls
[j
];
3394 if (!strcmp(name
, dllref
->name
))
3395 goto already_loaded
;
3397 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
3398 tcc_error_noabort("referenced dll '%s' not found", name
);
3412 tcc_free(v
.local_ver
);
3414 tcc_free(v
.verneed
);
3419 #define LD_TOK_NAME 256
3420 #define LD_TOK_EOF (-1)
3422 static int ld_inp(TCCState
*s1
)
3430 if (1 == read(s1
->fd
, &b
, 1))
3435 /* return next ld script token */
3436 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
3453 if (ch
== '*') { /* comment */
3454 for (d
= 0;; d
= ch
) {
3456 if (ch
== CH_EOF
|| (ch
== '/' && d
== '*'))
3467 /* case 'a' ... 'z': */
3494 /* case 'A' ... 'z': */
3528 if (!((ch
>= 'a' && ch
<= 'z') ||
3529 (ch
>= 'A' && ch
<= 'Z') ||
3530 (ch
>= '0' && ch
<= '9') ||
3531 strchr("/.-_+=$:\\,~", ch
)))
3533 if ((q
- name
) < name_size
- 1) {
3552 static int ld_add_file(TCCState
*s1
, const char filename
[])
3554 if (filename
[0] == '/') {
3555 if (CONFIG_SYSROOT
[0] == '\0'
3556 && tcc_add_file_internal(s1
, filename
, AFF_TYPE_BIN
) == 0)
3558 filename
= tcc_basename(filename
);
3560 return tcc_add_dll(s1
, filename
, 0);
3563 static int ld_add_file_list(TCCState
*s1
, const char *cmd
, int as_needed
)
3565 char filename
[1024], libname
[1024];
3566 int t
, group
, nblibs
= 0, ret
= 0;
3569 group
= !strcmp(cmd
, "GROUP");
3571 s1
->new_undef_sym
= 0;
3572 t
= ld_next(s1
, filename
, sizeof(filename
));
3574 tcc_error_noabort("( expected");
3576 goto lib_parse_error
;
3578 t
= ld_next(s1
, filename
, sizeof(filename
));
3581 if (t
== LD_TOK_EOF
) {
3582 tcc_error_noabort("unexpected end of file");
3584 goto lib_parse_error
;
3585 } else if (t
== ')') {
3587 } else if (t
== '-') {
3588 t
= ld_next(s1
, filename
, sizeof(filename
));
3589 if ((t
!= LD_TOK_NAME
) || (filename
[0] != 'l')) {
3590 tcc_error_noabort("library name expected");
3592 goto lib_parse_error
;
3594 pstrcpy(libname
, sizeof libname
, &filename
[1]);
3595 if (s1
->static_link
) {
3596 snprintf(filename
, sizeof filename
, "lib%s.a", libname
);
3598 snprintf(filename
, sizeof filename
, "lib%s.so", libname
);
3600 } else if (t
!= LD_TOK_NAME
) {
3601 tcc_error_noabort("filename expected");
3603 goto lib_parse_error
;
3605 if (!strcmp(filename
, "AS_NEEDED")) {
3606 ret
= ld_add_file_list(s1
, cmd
, 1);
3608 goto lib_parse_error
;
3610 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3612 ret
= ld_add_file(s1
, filename
);
3614 goto lib_parse_error
;
3616 /* Add the filename *and* the libname to avoid future conversions */
3617 dynarray_add(&libs
, &nblibs
, tcc_strdup(filename
));
3618 if (libname
[0] != '\0')
3619 dynarray_add(&libs
, &nblibs
, tcc_strdup(libname
));
3623 t
= ld_next(s1
, filename
, sizeof(filename
));
3625 t
= ld_next(s1
, filename
, sizeof(filename
));
3628 if (group
&& !as_needed
) {
3629 while (s1
->new_undef_sym
) {
3631 s1
->new_undef_sym
= 0;
3632 for (i
= 0; i
< nblibs
; i
++)
3633 ld_add_file(s1
, libs
[i
]);
3637 dynarray_reset(&libs
, &nblibs
);
3641 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3643 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
, int fd
)
3646 char filename
[1024];
3652 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3653 if (t
== LD_TOK_EOF
)
3655 else if (t
!= LD_TOK_NAME
)
3657 if (!strcmp(cmd
, "INPUT") ||
3658 !strcmp(cmd
, "GROUP")) {
3659 ret
= ld_add_file_list(s1
, cmd
, 0);
3662 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
3663 !strcmp(cmd
, "TARGET")) {
3664 /* ignore some commands */
3665 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3667 tcc_error_noabort("( expected");
3671 t
= ld_next(s1
, filename
, sizeof(filename
));
3672 if (t
== LD_TOK_EOF
) {
3673 tcc_error_noabort("unexpected end of file");
3675 } else if (t
== ')') {
3685 #endif /* !ELF_OBJ_ONLY */