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
);
89 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
93 if (0 == s1
->do_bounds_check
)
95 ptr
= section_ptr_add(bounds_section
, sizeof(*ptr
));
97 set_elf_sym(symtab_section
, 0, 0,
98 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
99 bounds_section
->sh_num
, "__bounds_start");
100 /* pull bcheck.o from libtcc1.a */
101 set_elf_sym(symtab_section
, 0, 0,
102 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
103 SHN_UNDEF
, "__bound_init");
107 ST_FUNC
void tccelf_stab_new(TCCState
*s
)
110 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, 0);
111 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
112 stab_section
->sh_addralign
= 4;
113 stab_section
->link
= new_section(s
, ".stabstr", SHT_STRTAB
, 0);
114 put_elf_str(stab_section
->link
, "");
115 /* put first entry */
116 put_stabs(s
, "", 0, 0, 0, 0);
119 static void free_section(Section
*s
)
124 ST_FUNC
void tccelf_delete(TCCState
*s1
)
129 /* free symbol versions */
130 for (i
= 0; i
< nb_sym_versions
; i
++) {
131 tcc_free(sym_versions
[i
].version
);
132 tcc_free(sym_versions
[i
].lib
);
134 tcc_free(sym_versions
);
135 tcc_free(sym_to_version
);
138 /* free all sections */
139 for(i
= 1; i
< s1
->nb_sections
; i
++)
140 free_section(s1
->sections
[i
]);
141 dynarray_reset(&s1
->sections
, &s1
->nb_sections
);
143 for(i
= 0; i
< s1
->nb_priv_sections
; i
++)
144 free_section(s1
->priv_sections
[i
]);
145 dynarray_reset(&s1
->priv_sections
, &s1
->nb_priv_sections
);
147 /* free any loaded DLLs */
149 for ( i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
150 DLLReference
*ref
= s1
->loaded_dlls
[i
];
153 FreeLibrary((HMODULE
)ref
->handle
);
155 dlclose(ref
->handle
);
159 /* free loaded dlls array */
160 dynarray_reset(&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
);
161 tcc_free(s1
->sym_attrs
);
163 symtab_section
= NULL
; /* for tccrun.c:rt_printline() */
166 /* save section data state */
167 ST_FUNC
void tccelf_begin_file(TCCState
*s1
)
170 for (i
= 1; i
< s1
->nb_sections
; i
++) {
172 s
->sh_offset
= s
->data_offset
;
174 /* disable symbol hashing during compilation */
175 s
= s1
->symtab
, s
->reloc
= s
->hash
, s
->hash
= NULL
;
176 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
181 /* At the end of compilation, convert any UNDEF syms to global, and merge
182 with previously existing symbols */
183 ST_FUNC
void tccelf_end_file(TCCState
*s1
)
185 Section
*s
= s1
->symtab
;
186 int first_sym
, nb_syms
, *tr
, i
;
188 first_sym
= s
->sh_offset
/ sizeof (ElfSym
);
189 nb_syms
= s
->data_offset
/ sizeof (ElfSym
) - first_sym
;
190 s
->data_offset
= s
->sh_offset
;
191 s
->link
->data_offset
= s
->link
->sh_offset
;
192 s
->hash
= s
->reloc
, s
->reloc
= NULL
;
193 tr
= tcc_mallocz(nb_syms
* sizeof *tr
);
195 for (i
= 0; i
< nb_syms
; ++i
) {
196 ElfSym
*sym
= (ElfSym
*)s
->data
+ first_sym
+ i
;
197 if (sym
->st_shndx
== SHN_UNDEF
198 && ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
)
199 sym
->st_info
= ELFW(ST_INFO
)(STB_GLOBAL
, ELFW(ST_TYPE
)(sym
->st_info
));
200 tr
[i
] = set_elf_sym(s
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
201 sym
->st_other
, sym
->st_shndx
, (char*)s
->link
->data
+ sym
->st_name
);
203 /* now update relocations */
204 for (i
= 1; i
< s1
->nb_sections
; i
++) {
205 Section
*sr
= s1
->sections
[i
];
206 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
207 ElfW_Rel
*rel
= (ElfW_Rel
*)(sr
->data
+ sr
->sh_offset
);
208 ElfW_Rel
*rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
209 for (; rel
< rel_end
; ++rel
) {
210 int n
= ELFW(R_SYM
)(rel
->r_info
) - first_sym
;
211 //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
212 rel
->r_info
= ELFW(R_INFO
)(tr
[n
], ELFW(R_TYPE
)(rel
->r_info
));
219 ST_FUNC Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
223 sec
= tcc_mallocz(sizeof(Section
) + strlen(name
));
225 strcpy(sec
->name
, name
);
226 sec
->sh_type
= sh_type
;
227 sec
->sh_flags
= sh_flags
;
230 sec
->sh_addralign
= 2;
238 case SHT_GNU_verneed
:
240 sec
->sh_addralign
= PTR_SIZE
;
243 sec
->sh_addralign
= 1;
246 sec
->sh_addralign
= PTR_SIZE
; /* gcc/pcc default alignment */
250 if (sh_flags
& SHF_PRIVATE
) {
251 dynarray_add(&s1
->priv_sections
, &s1
->nb_priv_sections
, sec
);
253 sec
->sh_num
= s1
->nb_sections
;
254 dynarray_add(&s1
->sections
, &s1
->nb_sections
, sec
);
260 ST_FUNC Section
*new_symtab(TCCState
*s1
,
261 const char *symtab_name
, int sh_type
, int sh_flags
,
262 const char *strtab_name
,
263 const char *hash_name
, int hash_sh_flags
)
265 Section
*symtab
, *strtab
, *hash
;
266 int *ptr
, nb_buckets
;
268 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
269 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
270 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
271 put_elf_str(strtab
, "");
272 symtab
->link
= strtab
;
273 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
277 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
278 hash
->sh_entsize
= sizeof(int);
282 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
285 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
289 /* realloc section and set its content to zero */
290 ST_FUNC
void section_realloc(Section
*sec
, unsigned long new_size
)
295 size
= sec
->data_allocated
;
298 while (size
< new_size
)
300 data
= tcc_realloc(sec
->data
, size
);
301 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
303 sec
->data_allocated
= size
;
306 /* reserve at least 'size' bytes aligned per 'align' in section
307 'sec' from current offset, and return the aligned offset */
308 ST_FUNC
size_t section_add(Section
*sec
, addr_t size
, int align
)
310 size_t offset
, offset1
;
312 offset
= (sec
->data_offset
+ align
- 1) & -align
;
313 offset1
= offset
+ size
;
314 if (sec
->sh_type
!= SHT_NOBITS
&& offset1
> sec
->data_allocated
)
315 section_realloc(sec
, offset1
);
316 sec
->data_offset
= offset1
;
317 if (align
> sec
->sh_addralign
)
318 sec
->sh_addralign
= align
;
322 /* reserve at least 'size' bytes in section 'sec' from
324 ST_FUNC
void *section_ptr_add(Section
*sec
, addr_t size
)
326 size_t offset
= section_add(sec
, size
, 1);
327 return sec
->data
+ offset
;
330 /* reserve at least 'size' bytes from section start */
331 ST_FUNC
void section_reserve(Section
*sec
, unsigned long size
)
333 if (size
> sec
->data_allocated
)
334 section_realloc(sec
, size
);
335 if (size
> sec
->data_offset
)
336 sec
->data_offset
= size
;
339 static Section
*find_section_create (TCCState
*s1
, const char *name
, int create
)
343 for(i
= 1; i
< s1
->nb_sections
; i
++) {
344 sec
= s1
->sections
[i
];
345 if (!strcmp(name
, sec
->name
))
348 /* sections are created as PROGBITS */
349 return create
? new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
) : NULL
;
352 /* return a reference to a section, and create it if it does not
354 ST_FUNC Section
*find_section(TCCState
*s1
, const char *name
)
356 return find_section_create (s1
, name
, 1);
359 /* ------------------------------------------------------------------------- */
361 ST_FUNC
int put_elf_str(Section
*s
, const char *sym
)
366 len
= strlen(sym
) + 1;
367 offset
= s
->data_offset
;
368 ptr
= section_ptr_add(s
, len
);
369 memmove(ptr
, sym
, len
);
373 /* elf symbol hashing function */
374 static unsigned long elf_hash(const unsigned char *name
)
376 unsigned long h
= 0, g
;
379 h
= (h
<< 4) + *name
++;
388 /* rebuild hash table of section s */
389 /* NOTE: we do factorize the hash table code to go faster */
390 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
393 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
394 unsigned char *strtab
;
396 strtab
= s
->link
->data
;
397 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
400 nb_buckets
= ((int*)s
->hash
->data
)[0];
402 s
->hash
->data_offset
= 0;
403 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
408 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
409 ptr
+= nb_buckets
+ 1;
411 sym
= (ElfW(Sym
) *)s
->data
+ 1;
412 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
413 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
414 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
425 /* return the symbol number */
426 ST_FUNC
int put_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
427 int info
, int other
, int shndx
, const char *name
)
429 int name_offset
, sym_index
;
434 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
436 name_offset
= put_elf_str(s
->link
, name
);
439 /* XXX: endianness */
440 sym
->st_name
= name_offset
;
441 sym
->st_value
= value
;
444 sym
->st_other
= other
;
445 sym
->st_shndx
= shndx
;
446 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
450 ptr
= section_ptr_add(hs
, sizeof(int));
451 base
= (int *)hs
->data
;
452 /* only add global or weak symbols. */
453 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
454 /* add another hashing entry */
456 h
= elf_hash((unsigned char *)s
->link
->data
+ name_offset
) % nbuckets
;
458 base
[2 + h
] = sym_index
;
460 /* we resize the hash table */
461 hs
->nb_hashed_syms
++;
462 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
463 rebuild_hash(s
, 2 * nbuckets
);
473 ST_FUNC
int find_elf_sym(Section
*s
, const char *name
)
477 int nbuckets
, sym_index
, h
;
483 nbuckets
= ((int *)hs
->data
)[0];
484 h
= elf_hash((unsigned char *) name
) % nbuckets
;
485 sym_index
= ((int *)hs
->data
)[2 + h
];
486 while (sym_index
!= 0) {
487 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
488 name1
= (char *) s
->link
->data
+ sym
->st_name
;
489 if (!strcmp(name
, name1
))
491 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
496 /* return elf symbol value, signal error if 'err' is nonzero */
497 ST_FUNC addr_t
get_elf_sym_addr(TCCState
*s1
, const char *name
, int err
)
502 sym_index
= find_elf_sym(s1
->symtab
, name
);
503 sym
= &((ElfW(Sym
) *)s1
->symtab
->data
)[sym_index
];
504 if (!sym_index
|| sym
->st_shndx
== SHN_UNDEF
) {
506 tcc_error("%s not defined", name
);
509 return sym
->st_value
;
512 /* list elf symbol names and values */
513 ST_FUNC
void list_elf_symbols(TCCState
*s
, void *ctx
,
514 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
518 int sym_index
, end_sym
;
520 unsigned char sym_vis
, sym_bind
;
523 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
524 for (sym_index
= 0; sym_index
< end_sym
; ++sym_index
) {
525 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
527 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
528 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
529 sym_vis
= ELFW(ST_VISIBILITY
)(sym
->st_other
);
530 if (sym_bind
== STB_GLOBAL
&& sym_vis
== STV_DEFAULT
)
531 symbol_cb(ctx
, name
, (void*)(uintptr_t)sym
->st_value
);
536 /* return elf symbol value */
537 LIBTCCAPI
void *tcc_get_symbol(TCCState
*s
, const char *name
)
539 return (void*)(uintptr_t)get_elf_sym_addr(s
, name
, 0);
542 /* list elf symbol names and values */
543 LIBTCCAPI
void tcc_list_symbols(TCCState
*s
, void *ctx
,
544 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
546 list_elf_symbols(s
, ctx
, symbol_cb
);
549 #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
550 /* return elf symbol value or error */
551 ST_FUNC
void* tcc_get_symbol_err(TCCState
*s
, const char *name
)
553 return (void*)(uintptr_t)get_elf_sym_addr(s
, name
, 1);
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 verneed_section
= new_section(s1
, ".gnu.version_r", SHT_GNU_verneed
, SHF_ALLOC
);
574 versym_section
->link
= s1
->dynsym
;
575 verneed_section
->link
= s1
->dynsym
->link
;
577 /* add needed symbols */
579 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
580 versym
= section_ptr_add(versym_section
, end_sym
* sizeof(ElfW(Half
)));
581 for (sym_index
= 0; sym_index
< end_sym
; ++sym_index
) {
582 int dllindex
, verndx
;
583 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
584 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
585 dllindex
= find_elf_sym(s1
->dynsymtab_section
, name
);
586 verndx
= (dllindex
&& dllindex
< nb_sym_to_version
)
587 ? sym_to_version
[dllindex
] : -1;
589 if (!sym_versions
[verndx
].out_index
)
590 sym_versions
[verndx
].out_index
= nb_versions
++;
591 versym
[sym_index
] = sym_versions
[verndx
].out_index
;
593 versym
[sym_index
] = 0;
595 /* generate verneed section */
596 for (i
= nb_sym_versions
; i
-- > 0;) {
597 struct sym_version
*sv
= &sym_versions
[i
];
598 int n_same_libs
= 0, prev
;
600 ElfW(Vernaux
) *vna
= 0;
601 if (sv
->out_index
< 1)
603 vnofs
= section_add(verneed_section
, sizeof(*vn
), 1);
604 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
606 vn
->vn_file
= put_elf_str(verneed_section
->link
, sv
->lib
);
607 vn
->vn_aux
= sizeof (*vn
);
609 prev
= sv
->prev_same_lib
;
610 if (sv
->out_index
> 0) {
611 vna
= section_ptr_add(verneed_section
, sizeof(*vna
));
612 vna
->vna_hash
= elf_hash ((const unsigned char *)sv
->version
);
614 vna
->vna_other
= sv
->out_index
;
616 vna
->vna_name
= put_elf_str(verneed_section
->link
, sv
->version
);
617 vna
->vna_next
= sizeof (*vna
);
621 sv
= &sym_versions
[prev
];
624 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
625 vn
->vn_cnt
= n_same_libs
;
626 vn
->vn_next
= sizeof(*vn
) + n_same_libs
* sizeof(*vna
);
631 verneed_section
->sh_info
= nb_entries
;
632 dt_verneednum
= nb_entries
;
636 /* add an elf symbol : check if it is already defined and patch
637 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
638 ST_FUNC
int set_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
639 int info
, int other
, int shndx
, const char *name
)
641 TCCState
*s1
= s
->s1
;
643 int sym_bind
, sym_index
, sym_type
, esym_bind
;
644 unsigned char sym_vis
, esym_vis
, new_vis
;
646 sym_bind
= ELFW(ST_BIND
)(info
);
647 sym_type
= ELFW(ST_TYPE
)(info
);
648 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
650 if (sym_bind
!= STB_LOCAL
) {
651 /* we search global or weak symbols */
652 sym_index
= find_elf_sym(s
, name
);
655 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
656 if (esym
->st_value
== value
&& esym
->st_size
== size
&& esym
->st_info
== info
657 && esym
->st_other
== other
&& esym
->st_shndx
== shndx
)
659 if (esym
->st_shndx
!= SHN_UNDEF
) {
660 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
661 /* propagate the most constraining visibility */
662 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
663 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
664 if (esym_vis
== STV_DEFAULT
) {
666 } else if (sym_vis
== STV_DEFAULT
) {
669 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
671 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
673 other
= esym
->st_other
; /* in case we have to patch esym */
674 if (shndx
== SHN_UNDEF
) {
675 /* ignore adding of undefined symbol if the
676 corresponding symbol is already defined */
677 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
678 /* global overrides weak, so patch */
680 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
681 /* weak is ignored if already global */
682 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_WEAK
) {
683 /* keep first-found weak definition, ignore subsequents */
684 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
685 /* ignore hidden symbols after */
686 } else if ((esym
->st_shndx
== SHN_COMMON
687 || esym
->st_shndx
== bss_section
->sh_num
)
688 && (shndx
< SHN_LORESERVE
689 && shndx
!= bss_section
->sh_num
)) {
690 /* data symbol gets precedence over common/bss */
692 } else if (shndx
== SHN_COMMON
|| shndx
== bss_section
->sh_num
) {
693 /* data symbol keeps precedence over common/bss */
694 } else if (s
->sh_flags
& SHF_DYNSYM
) {
695 /* we accept that two DLL define the same symbol */
696 } else if (esym
->st_other
& ST_ASM_SET
) {
697 /* If the existing symbol came from an asm .set
702 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
703 sym_bind
, shndx
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
705 tcc_error_noabort("'%s' defined twice", name
);
709 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
710 esym
->st_shndx
= shndx
;
711 s1
->new_undef_sym
= 1;
712 esym
->st_value
= value
;
713 esym
->st_size
= size
;
714 esym
->st_other
= other
;
718 sym_index
= put_elf_sym(s
, value
, size
,
719 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
726 ST_FUNC
void put_elf_reloca(Section
*symtab
, Section
*s
, unsigned long offset
,
727 int type
, int symbol
, addr_t addend
)
729 TCCState
*s1
= s
->s1
;
736 /* if no relocation section, create it */
737 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
738 /* if the symtab is allocated, then we consider the relocation
740 sr
= new_section(s
->s1
, buf
, SHT_RELX
, symtab
->sh_flags
);
741 sr
->sh_entsize
= sizeof(ElfW_Rel
);
743 sr
->sh_info
= s
->sh_num
;
746 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
747 rel
->r_offset
= offset
;
748 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
749 #if SHT_RELX == SHT_RELA
750 rel
->r_addend
= addend
;
752 if (SHT_RELX
!= SHT_RELA
&& addend
)
753 tcc_error("non-zero addend on REL architecture");
756 ST_FUNC
void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
757 int type
, int symbol
)
759 put_elf_reloca(symtab
, s
, offset
, type
, symbol
, 0);
762 /* Remove relocations for section S->reloc starting at oldrelocoffset
763 that are to the same place, retaining the last of them. As side effect
764 the relocations are sorted. Possibly reduces the number of relocs. */
765 ST_FUNC
void squeeze_multi_relocs(Section
*s
, size_t oldrelocoffset
)
767 Section
*sr
= s
->reloc
;
772 if (oldrelocoffset
+ sizeof(*r
) >= sr
->data_offset
)
774 /* The relocs we're dealing with are the result of initializer parsing.
775 So they will be mostly in order and there aren't many of them.
776 Secondly we need a stable sort (which qsort isn't). We use
777 a simple insertion sort. */
778 for (a
= oldrelocoffset
+ sizeof(*r
); a
< sr
->data_offset
; a
+= sizeof(*r
)) {
779 ssize_t i
= a
- sizeof(*r
);
780 addr
= ((ElfW_Rel
*)(sr
->data
+ a
))->r_offset
;
781 for (; i
>= (ssize_t
)oldrelocoffset
&&
782 ((ElfW_Rel
*)(sr
->data
+ i
))->r_offset
> addr
; i
-= sizeof(*r
)) {
783 ElfW_Rel tmp
= *(ElfW_Rel
*)(sr
->data
+ a
);
784 *(ElfW_Rel
*)(sr
->data
+ a
) = *(ElfW_Rel
*)(sr
->data
+ i
);
785 *(ElfW_Rel
*)(sr
->data
+ i
) = tmp
;
789 r
= (ElfW_Rel
*)(sr
->data
+ oldrelocoffset
);
791 for (; r
< (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
); r
++) {
792 if (dest
->r_offset
!= r
->r_offset
)
796 sr
->data_offset
= (unsigned char*)dest
- sr
->data
+ sizeof(*r
);
799 /* put stab debug information */
801 ST_FUNC
void put_stabs(TCCState
*s1
, const char *str
, int type
, int other
, int desc
,
806 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
808 sym
->n_strx
= put_elf_str(stab_section
->link
, str
);
813 sym
->n_other
= other
;
815 sym
->n_value
= value
;
818 ST_FUNC
void put_stabs_r(TCCState
*s1
, const char *str
, int type
, int other
, int desc
,
819 unsigned long value
, Section
*sec
, int sym_index
)
821 put_stabs(s1
, str
, type
, other
, desc
, value
);
822 put_elf_reloc(symtab_section
, stab_section
,
823 stab_section
->data_offset
- sizeof(unsigned int),
824 R_DATA_32
, sym_index
);
827 ST_FUNC
void put_stabn(TCCState
*s1
, int type
, int other
, int desc
, int value
)
829 put_stabs(s1
, NULL
, type
, other
, desc
, value
);
832 ST_FUNC
struct sym_attr
*get_sym_attr(TCCState
*s1
, int index
, int alloc
)
835 struct sym_attr
*tab
;
837 if (index
>= s1
->nb_sym_attrs
) {
839 return s1
->sym_attrs
;
840 /* find immediately bigger power of 2 and reallocate array */
844 tab
= tcc_realloc(s1
->sym_attrs
, n
* sizeof(*s1
->sym_attrs
));
846 memset(s1
->sym_attrs
+ s1
->nb_sym_attrs
, 0,
847 (n
- s1
->nb_sym_attrs
) * sizeof(*s1
->sym_attrs
));
848 s1
->nb_sym_attrs
= n
;
850 return &s1
->sym_attrs
[index
];
853 /* Browse each elem of type <type> in section <sec> starting at elem <startoff>
854 using variable <elem> */
855 #define for_each_elem(sec, startoff, elem, type) \
856 for (elem = (type *) sec->data + startoff; \
857 elem < (type *) (sec->data + sec->data_offset); elem++)
859 /* In an ELF file symbol table, the local symbols must appear below
860 the global and weak ones. Since TCC cannot sort it while generating
861 the code, we must do it after. All the relocation tables are also
862 modified to take into account the symbol table sorting */
863 static void sort_syms(TCCState
*s1
, Section
*s
)
865 int *old_to_new_syms
;
873 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
874 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
875 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
877 /* first pass for local symbols */
878 p
= (ElfW(Sym
) *)s
->data
;
880 for(i
= 0; i
< nb_syms
; i
++) {
881 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
882 old_to_new_syms
[i
] = q
- new_syms
;
887 /* save the number of local symbols in section header */
888 if( s
->sh_size
) /* this 'if' makes IDA happy */
889 s
->sh_info
= q
- new_syms
;
891 /* then second pass for non local symbols */
892 p
= (ElfW(Sym
) *)s
->data
;
893 for(i
= 0; i
< nb_syms
; i
++) {
894 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
895 old_to_new_syms
[i
] = q
- new_syms
;
901 /* we copy the new symbols to the old */
902 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
905 /* now we modify all the relocations */
906 for(i
= 1; i
< s1
->nb_sections
; i
++) {
907 sr
= s1
->sections
[i
];
908 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
909 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
910 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
911 type
= ELFW(R_TYPE
)(rel
->r_info
);
912 sym_index
= old_to_new_syms
[sym_index
];
913 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
918 tcc_free(old_to_new_syms
);
921 /* relocate symbol table, resolve undefined symbols if do_resolve is
922 true and output error if undefined symbol. */
923 ST_FUNC
void relocate_syms(TCCState
*s1
, Section
*symtab
, int do_resolve
)
926 int sym_bind
, sh_num
;
929 for_each_elem(symtab
, 1, sym
, ElfW(Sym
)) {
930 sh_num
= sym
->st_shndx
;
931 if (sh_num
== SHN_UNDEF
) {
932 name
= (char *) s1
->symtab
->link
->data
+ sym
->st_name
;
933 /* Use ld.so to resolve symbol for us (for tcc -run) */
935 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
936 void *addr
= dlsym(RTLD_DEFAULT
, name
);
938 sym
->st_value
= (addr_t
) addr
;
940 printf ("relocate_sym: %s -> 0x%lx\n", name
, sym
->st_value
);
945 /* if dynamic symbol exist, it will be used in relocate_section */
946 } else if (s1
->dynsym
&& find_elf_sym(s1
->dynsym
, name
))
948 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
950 if (!strcmp(name
, "_fp_hw"))
952 /* only weak symbols are accepted to be undefined. Their
954 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
955 if (sym_bind
== STB_WEAK
)
958 tcc_error_noabort("undefined symbol '%s'", name
);
959 } else if (sh_num
< SHN_LORESERVE
) {
960 /* add section base */
961 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
967 /* relocate a given section (CPU dependent) by applying the relocations
968 in the associated relocation section */
969 ST_FUNC
void relocate_section(TCCState
*s1
, Section
*s
)
971 Section
*sr
= s
->reloc
;
978 qrel
= (ElfW_Rel
*)sr
->data
;
980 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
981 ptr
= s
->data
+ rel
->r_offset
;
982 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
983 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
984 type
= ELFW(R_TYPE
)(rel
->r_info
);
986 #if SHT_RELX == SHT_RELA
987 tgt
+= rel
->r_addend
;
989 addr
= s
->sh_addr
+ rel
->r_offset
;
990 relocate(s1
, rel
, type
, ptr
, addr
, tgt
);
992 /* if the relocation is allocated, we change its symbol table */
993 if (sr
->sh_flags
& SHF_ALLOC
)
994 sr
->link
= s1
->dynsym
;
998 /* relocate relocation table in 'sr' */
999 static void relocate_rel(TCCState
*s1
, Section
*sr
)
1004 s
= s1
->sections
[sr
->sh_info
];
1005 for_each_elem(sr
, 0, rel
, ElfW_Rel
)
1006 rel
->r_offset
+= s
->sh_addr
;
1009 /* count the number of dynamic relocations so that we can reserve
1011 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
1014 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1016 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
1017 int sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1018 int type
= ELFW(R_TYPE
)(rel
->r_info
);
1020 #if defined(TCC_TARGET_I386)
1022 if (!get_sym_attr(s1
, sym_index
, 0)->dyn_index
1023 && ((ElfW(Sym
)*)symtab_section
->data
+ sym_index
)->st_shndx
== SHN_UNDEF
) {
1024 /* don't fixup unresolved (weak) symbols */
1025 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_386_RELATIVE
);
1028 #elif defined(TCC_TARGET_X86_64)
1035 #if defined(TCC_TARGET_I386)
1037 #elif defined(TCC_TARGET_X86_64)
1040 if (get_sym_attr(s1
, sym_index
, 0)->dyn_index
)
1048 /* allocate the section */
1049 sr
->sh_flags
|= SHF_ALLOC
;
1050 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
1056 static void build_got(TCCState
*s1
)
1058 /* if no got, then create it */
1059 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
1060 s1
->got
->sh_entsize
= 4;
1061 set_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
1062 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
1063 /* keep space for _DYNAMIC pointer and two dummy got entries */
1064 section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
1067 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1068 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1069 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1070 Returns the offset of the GOT or (if any) PLT entry. */
1071 static struct sym_attr
* put_got_entry(TCCState
*s1
, int dyn_reloc_type
,
1077 struct sym_attr
*attr
;
1078 unsigned got_offset
;
1082 need_plt_entry
= (dyn_reloc_type
== R_JMP_SLOT
);
1083 attr
= get_sym_attr(s1
, sym_index
, 1);
1085 /* In case a function is both called and its address taken 2 GOT entries
1086 are created, one for taking the address (GOT) and the other for the PLT
1088 if (need_plt_entry
? attr
->plt_offset
: attr
->got_offset
)
1091 /* create the GOT entry */
1092 got_offset
= s1
->got
->data_offset
;
1093 section_ptr_add(s1
->got
, PTR_SIZE
);
1095 /* Create the GOT relocation that will insert the address of the object or
1096 function of interest in the GOT entry. This is a static relocation for
1097 memory output (dlsym will give us the address of symbols) and dynamic
1098 relocation otherwise (executable and DLLs). The relocation should be
1099 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1100 associated to a PLT entry) but is currently done at load time for an
1103 sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1104 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1107 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
) {
1108 /* Hack alarm. We don't want to emit dynamic symbols
1109 and symbol based relocs for STB_LOCAL symbols, but rather
1110 want to resolve them directly. At this point the symbol
1111 values aren't final yet, so we must defer this. We will later
1112 have to create a RELATIVE reloc anyway, so we misuse the
1113 relocation slot to smuggle the symbol reference until
1114 fill_local_got_entries. Not that the sym_index is
1115 relative to symtab_section, not s1->dynsym! Nevertheless
1116 we use s1->dyn_sym so that if this is the first call
1117 that got->reloc is correctly created. Also note that
1118 RELATIVE relocs are not normally created for the .got,
1119 so the types serves as a marker for later (and is retained
1120 also for the final output, which is okay because then the
1121 got is just normal data). */
1122 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, R_RELATIVE
,
1125 if (0 == attr
->dyn_index
)
1126 attr
->dyn_index
= set_elf_sym(s1
->dynsym
, sym
->st_value
,
1127 sym
->st_size
, sym
->st_info
, 0,
1128 sym
->st_shndx
, name
);
1129 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, dyn_reloc_type
,
1133 put_elf_reloc(symtab_section
, s1
->got
, got_offset
, dyn_reloc_type
,
1137 if (need_plt_entry
) {
1139 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1140 SHF_ALLOC
| SHF_EXECINSTR
);
1141 s1
->plt
->sh_entsize
= 4;
1144 attr
->plt_offset
= create_plt_entry(s1
, got_offset
, attr
);
1146 /* create a symbol 'sym@plt' for the PLT jump vector */
1148 if (len
> sizeof plt_name
- 5)
1149 len
= sizeof plt_name
- 5;
1150 memcpy(plt_name
, name
, len
);
1151 strcpy(plt_name
+ len
, "@plt");
1152 attr
->plt_sym
= put_elf_sym(s1
->symtab
, attr
->plt_offset
, sym
->st_size
,
1153 ELFW(ST_INFO
)(STB_GLOBAL
, STT_FUNC
), 0, s1
->plt
->sh_num
, plt_name
);
1156 attr
->got_offset
= got_offset
;
1162 /* build GOT and PLT entries */
1163 ST_FUNC
void build_got_entries(TCCState
*s1
)
1168 int i
, type
, gotplt_entry
, reloc_type
, sym_index
;
1169 struct sym_attr
*attr
;
1171 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1172 s
= s1
->sections
[i
];
1173 if (s
->sh_type
!= SHT_RELX
)
1175 /* no need to handle got relocations */
1176 if (s
->link
!= symtab_section
)
1178 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1179 type
= ELFW(R_TYPE
)(rel
->r_info
);
1180 gotplt_entry
= gotplt_entry_type(type
);
1181 if (gotplt_entry
== -1)
1182 tcc_error ("Unknown relocation type for got: %d", type
);
1183 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1184 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1186 if (gotplt_entry
== NO_GOTPLT_ENTRY
) {
1190 /* Automatically create PLT/GOT [entry] if it is an undefined
1191 reference (resolved at runtime), or the symbol is absolute,
1192 probably created by tcc_add_symbol, and thus on 64-bit
1193 targets might be too far from application code. */
1194 if (gotplt_entry
== AUTO_GOTPLT_ENTRY
) {
1195 if (sym
->st_shndx
== SHN_UNDEF
) {
1198 if (s1
->output_type
== TCC_OUTPUT_DLL
&& ! PCRELATIVE_DLLPLT
)
1200 /* Relocations for UNDEF symbols would normally need
1201 to be transferred into the executable or shared object.
1202 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1203 But TCC doesn't do that (at least for exes), so we
1204 need to resolve all such relocs locally. And that
1205 means PLT slots for functions in DLLs and COPY relocs for
1206 data symbols. COPY relocs were generated in
1207 bind_exe_dynsyms (and the symbol adjusted to be defined),
1208 and for functions we were generated a dynamic symbol
1209 of function type. */
1211 /* dynsym isn't set for -run :-/ */
1212 dynindex
= get_sym_attr(s1
, sym_index
, 0)->dyn_index
;
1213 esym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ dynindex
;
1215 && (ELFW(ST_TYPE
)(esym
->st_info
) == STT_FUNC
1216 || (ELFW(ST_TYPE
)(esym
->st_info
) == STT_NOTYPE
1217 && ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
)))
1220 } else if (!(sym
->st_shndx
== SHN_ABS
1221 #ifndef TCC_TARGET_ARM
1228 #ifdef TCC_TARGET_X86_64
1229 if ((type
== R_X86_64_PLT32
|| type
== R_X86_64_PC32
) &&
1230 sym
->st_shndx
!= SHN_UNDEF
&&
1231 (ELFW(ST_VISIBILITY
)(sym
->st_other
) != STV_DEFAULT
||
1232 ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
||
1233 s1
->output_type
== TCC_OUTPUT_EXE
)) {
1234 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PC32
);
1238 reloc_type
= code_reloc(type
);
1239 if (reloc_type
== -1)
1240 tcc_error ("Unknown relocation type: %d", type
);
1241 else if (reloc_type
!= 0) {
1243 reloc_type
= R_JMP_SLOT
;
1245 reloc_type
= R_GLOB_DAT
;
1250 if (gotplt_entry
== BUILD_GOT_ONLY
)
1253 attr
= put_got_entry(s1
, reloc_type
, sym_index
);
1255 if (reloc_type
== R_JMP_SLOT
)
1256 rel
->r_info
= ELFW(R_INFO
)(attr
->plt_sym
, type
);
1261 /* put dynamic tag */
1262 static void put_dt(Section
*dynamic
, int dt
, addr_t val
)
1265 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1267 dyn
->d_un
.d_val
= val
;
1271 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1275 char sym_start
[1024];
1278 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1279 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1281 s
= find_section(s1
, section_name
);
1286 end_offset
= s
->data_offset
;
1289 set_elf_sym(symtab_section
,
1291 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1292 s
->sh_num
, sym_start
);
1293 set_elf_sym(symtab_section
,
1295 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1296 s
->sh_num
, sym_end
);
1299 #ifndef TCC_TARGET_PE
1300 static int tcc_add_support(TCCState
*s1
, const char *filename
)
1303 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, filename
);
1304 return tcc_add_file(s1
, buf
);
1308 static void add_array (const char *section
, TCCState
*s1
, Sym
*sym
, int sh_type
)
1313 s
= find_section(s1
, section
);
1315 s
->sh_flags
|= SHF_WRITE
;
1316 #ifndef TCC_TARGET_PE
1317 s
->sh_type
= sh_type
;
1319 ptr
= section_ptr_add(s
, PTR_SIZE
);
1320 memset (ptr
, 0, PTR_SIZE
);
1321 put_elf_reloc (s1
->symtab
, s
, ptr
- s
->data
, R_DATA_PTR
, sym
->c
);
1325 ST_FUNC
void add_init_array (TCCState
*s1
, Sym
*sym
)
1327 add_array (".init_array", s1
, sym
, SHT_INIT_ARRAY
);
1330 ST_FUNC
void add_fini_array (TCCState
*s1
, Sym
*sym
)
1332 add_array (".fini_array", s1
, sym
, SHT_FINI_ARRAY
);
1335 /* add tcc runtime libraries */
1336 ST_FUNC
void tcc_add_runtime(TCCState
*s1
)
1339 #ifdef CONFIG_TCC_BCHECK
1342 tcc_add_pragma_libs(s1
);
1343 #ifndef TCC_TARGET_PE
1345 if (!s1
->nostdlib
) {
1346 tcc_add_library_err(s1
, "c");
1348 if (!s1
->static_link
) {
1349 if (TCC_LIBGCC
[0] == '/')
1350 tcc_add_file(s1
, TCC_LIBGCC
);
1352 tcc_add_dll(s1
, TCC_LIBGCC
, 0);
1355 #ifdef CONFIG_TCC_BCHECK
1356 if (s1
->do_bounds_check
&& s1
->output_type
!= TCC_OUTPUT_DLL
) {
1357 tcc_add_library_err(s1
, "pthread");
1358 tcc_add_library_err(s1
, "dl");
1359 tcc_add_support(s1
, TCC_LIBBCHECK
);
1362 tcc_add_support(s1
, TCC_LIBTCC1
);
1363 /* add crt end if not memory output */
1364 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1365 tcc_add_crt(s1
, "crtn.o");
1370 /* add various standard linker symbols (must be done after the
1371 sections are filled (for example after allocating common
1373 static void tcc_add_linker_symbols(TCCState
*s1
)
1379 set_elf_sym(symtab_section
,
1380 text_section
->data_offset
, 0,
1381 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1382 text_section
->sh_num
, "_etext");
1383 set_elf_sym(symtab_section
,
1384 data_section
->data_offset
, 0,
1385 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1386 data_section
->sh_num
, "_edata");
1387 set_elf_sym(symtab_section
,
1388 bss_section
->data_offset
, 0,
1389 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1390 bss_section
->sh_num
, "_end");
1391 #ifdef TCC_TARGET_RISCV64
1392 /* XXX should be .sdata+0x800, not .data+0x800 */
1393 set_elf_sym(symtab_section
,
1395 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1396 data_section
->sh_num
, "__global_pointer$");
1398 /* horrible new standard ldscript defines */
1399 add_init_array_defines(s1
, ".preinit_array");
1400 add_init_array_defines(s1
, ".init_array");
1401 add_init_array_defines(s1
, ".fini_array");
1403 /* add start and stop symbols for sections whose name can be
1405 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1406 s
= s1
->sections
[i
];
1407 if (s
->sh_type
== SHT_PROGBITS
&&
1408 (s
->sh_flags
& SHF_ALLOC
)) {
1412 /* check if section name can be expressed in C */
1418 if (!isid(ch
) && !isnum(ch
))
1422 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1423 set_elf_sym(symtab_section
,
1425 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1427 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1428 set_elf_sym(symtab_section
,
1430 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1437 ST_FUNC
void resolve_common_syms(TCCState
*s1
)
1441 /* Allocate common symbols in BSS. */
1442 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1443 if (sym
->st_shndx
== SHN_COMMON
) {
1444 /* symbol alignment is in st_value for SHN_COMMONs */
1445 sym
->st_value
= section_add(bss_section
, sym
->st_size
,
1447 sym
->st_shndx
= bss_section
->sh_num
;
1451 /* Now assign linker provided symbols their value. */
1452 tcc_add_linker_symbols(s1
);
1455 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1456 const int *sec_order
)
1459 int i
, offset
, size
;
1462 for(i
=1;i
<s1
->nb_sections
;i
++) {
1463 s
= s1
->sections
[sec_order
[i
]];
1464 if (s
->sh_type
!= SHT_NOBITS
&&
1465 (s
->sh_flags
& SHF_ALLOC
)) {
1466 while (offset
< s
->sh_offset
) {
1471 fwrite(s
->data
, 1, size
, f
);
1477 #ifndef ELF_OBJ_ONLY
1478 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1480 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1481 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1482 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1483 unsigned offset
= attr
->got_offset
;
1487 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1488 #ifdef TCC_TARGET_X86_64
1489 write64le(s1
->got
->data
+ offset
, sym
->st_value
);
1491 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1495 /* Perform relocation to GOT or PLT entries */
1496 ST_FUNC
void fill_got(TCCState
*s1
)
1502 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1503 s
= s1
->sections
[i
];
1504 if (s
->sh_type
!= SHT_RELX
)
1506 /* no need to handle got relocations */
1507 if (s
->link
!= symtab_section
)
1509 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1510 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1511 case R_X86_64_GOT32
:
1512 case R_X86_64_GOTPCREL
:
1513 case R_X86_64_GOTPCRELX
:
1514 case R_X86_64_REX_GOTPCRELX
:
1515 case R_X86_64_PLT32
:
1516 fill_got_entry(s1
, rel
);
1523 /* See put_got_entry for a description. This is the second stage
1524 where GOT references to local defined symbols are rewritten. */
1525 static void fill_local_got_entries(TCCState
*s1
)
1528 if (!s1
->got
->reloc
)
1530 for_each_elem(s1
->got
->reloc
, 0, rel
, ElfW_Rel
) {
1531 if (ELFW(R_TYPE
)(rel
->r_info
) == R_RELATIVE
) {
1532 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1533 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1534 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1535 unsigned offset
= attr
->got_offset
;
1536 if (offset
!= rel
->r_offset
- s1
->got
->sh_addr
)
1537 tcc_error_noabort("huh");
1538 rel
->r_info
= ELFW(R_INFO
)(0, R_RELATIVE
);
1539 #if SHT_RELX == SHT_RELA
1540 rel
->r_addend
= sym
->st_value
;
1542 /* All our REL architectures also happen to be 32bit LE. */
1543 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1549 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1550 in shared libraries and export non local defined symbols to shared libraries
1551 if -rdynamic switch was given on command line */
1552 static void bind_exe_dynsyms(TCCState
*s1
)
1555 int sym_index
, index
;
1556 ElfW(Sym
) *sym
, *esym
;
1559 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1560 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1561 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1562 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1563 if (sym
->st_shndx
== SHN_UNDEF
) {
1564 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1565 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1567 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1568 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1569 if ((type
== STT_FUNC
) || (type
== STT_GNU_IFUNC
)) {
1570 /* Indirect functions shall have STT_FUNC type in executable
1571 * dynsym section. Indeed, a dlsym call following a lazy
1572 * resolution would pick the symbol value from the
1573 * executable dynsym entry which would contain the address
1574 * of the function wanted by the caller of dlsym instead of
1575 * the address of the function that would return that
1578 = put_elf_sym(s1
->dynsym
, 0, esym
->st_size
,
1579 ELFW(ST_INFO
)(STB_GLOBAL
,STT_FUNC
), 0, 0,
1581 int index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1582 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1583 } else if (type
== STT_OBJECT
) {
1584 unsigned long offset
;
1586 offset
= bss_section
->data_offset
;
1587 /* XXX: which alignment ? */
1588 offset
= (offset
+ 16 - 1) & -16;
1589 set_elf_sym (s1
->symtab
, offset
, esym
->st_size
,
1590 esym
->st_info
, 0, bss_section
->sh_num
, name
);
1591 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1592 esym
->st_info
, 0, bss_section
->sh_num
,
1595 /* Ensure R_COPY works for weak symbol aliases */
1596 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1597 for_each_elem(s1
->dynsymtab_section
, 1, dynsym
, ElfW(Sym
)) {
1598 if ((dynsym
->st_value
== esym
->st_value
)
1599 && (ELFW(ST_BIND
)(dynsym
->st_info
) == STB_GLOBAL
)) {
1600 char *dynname
= (char *) s1
->dynsymtab_section
->link
->data
1602 put_elf_sym(s1
->dynsym
, offset
, dynsym
->st_size
,
1604 bss_section
->sh_num
, dynname
);
1610 put_elf_reloc(s1
->dynsym
, bss_section
,
1611 offset
, R_COPY
, index
);
1612 offset
+= esym
->st_size
;
1613 bss_section
->data_offset
= offset
;
1616 /* STB_WEAK undefined symbols are accepted */
1617 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1618 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1619 !strcmp(name
, "_fp_hw")) {
1621 tcc_error_noabort("undefined symbol '%s'", name
);
1624 } else if (s1
->rdynamic
&& ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1625 /* if -rdynamic option, then export all non local symbols */
1626 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1627 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
1628 0, sym
->st_shndx
, name
);
1633 /* Bind symbols of libraries: export all non local symbols of executable that
1634 are referenced by shared libraries. The reason is that the dynamic loader
1635 search symbol first in executable and then in libraries. Therefore a
1636 reference to a symbol already defined by a library can still be resolved by
1637 a symbol in the executable. */
1638 static void bind_libs_dynsyms(TCCState
*s1
)
1642 ElfW(Sym
) *sym
, *esym
;
1644 for_each_elem(s1
->dynsymtab_section
, 1, esym
, ElfW(Sym
)) {
1645 name
= (char *) s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1646 sym_index
= find_elf_sym(symtab_section
, name
);
1647 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1648 if (sym_index
&& sym
->st_shndx
!= SHN_UNDEF
1649 && ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1650 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1651 sym
->st_info
, 0, sym
->st_shndx
, name
);
1652 } else if (esym
->st_shndx
== SHN_UNDEF
) {
1653 /* weak symbols can stay undefined */
1654 if (ELFW(ST_BIND
)(esym
->st_info
) != STB_WEAK
)
1655 tcc_warning("undefined dynamic symbol '%s'", name
);
1660 /* Export all non local symbols. This is used by shared libraries so that the
1661 non local symbols they define can resolve a reference in another shared
1662 library or in the executable. Correspondingly, it allows undefined local
1663 symbols to be resolved by other shared libraries or by the executable. */
1664 static void export_global_syms(TCCState
*s1
)
1666 int dynindex
, index
;
1670 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1671 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1672 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1673 dynindex
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1674 sym
->st_info
, 0, sym
->st_shndx
, name
);
1675 index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1676 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1682 /* Allocate strings for section names and decide if an unallocated section
1684 NOTE: the strsec section comes last, so its size is also correct ! */
1685 static int alloc_sec_names(TCCState
*s1
, int file_type
, Section
*strsec
)
1691 /* Allocate strings for section names */
1692 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1693 s
= s1
->sections
[i
];
1694 /* when generating a DLL, we include relocations but we may
1696 #ifndef ELF_OBJ_ONLY
1697 if (file_type
== TCC_OUTPUT_DLL
&&
1698 s
->sh_type
== SHT_RELX
&&
1699 !(s
->sh_flags
& SHF_ALLOC
) &&
1700 (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
) &&
1701 prepare_dynamic_rel(s1
, s
)) {
1702 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_EXECINSTR
)
1706 if ((s1
->do_debug
&& s
->sh_type
!= SHT_RELX
) ||
1707 file_type
== TCC_OUTPUT_OBJ
||
1708 (s
->sh_flags
& SHF_ALLOC
) ||
1709 i
== (s1
->nb_sections
- 1)) {
1710 /* we output all sections if debug or object file */
1711 s
->sh_size
= s
->data_offset
;
1713 if (s
->sh_size
|| (s
->sh_flags
& SHF_ALLOC
))
1714 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1716 strsec
->sh_size
= strsec
->data_offset
;
1720 /* Info to be copied in dynamic section */
1724 unsigned long data_offset
;
1727 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1733 /* Assign sections to segments and decide how are sections laid out when loaded
1734 in memory. This function also fills corresponding program headers. */
1735 static int layout_sections(TCCState
*s1
, ElfW(Phdr
) *phdr
, int phnum
,
1736 Section
*interp
, Section
* strsec
,
1737 struct dyn_inf
*dyninf
, int *sec_order
)
1739 int i
, j
, k
, file_type
, sh_order_index
, file_offset
;
1740 unsigned long s_align
;
1746 file_type
= s1
->output_type
;
1749 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
1750 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1751 s_align
= ELF_PAGE_SIZE
;
1752 if (s1
->section_align
)
1753 s_align
= s1
->section_align
;
1756 if (s1
->has_text_addr
) {
1757 int a_offset
, p_offset
;
1758 addr
= s1
->text_addr
;
1759 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1761 a_offset
= (int) (addr
& (s_align
- 1));
1762 p_offset
= file_offset
& (s_align
- 1);
1763 if (a_offset
< p_offset
)
1764 a_offset
+= s_align
;
1765 file_offset
+= (a_offset
- p_offset
);
1767 if (file_type
== TCC_OUTPUT_DLL
)
1770 addr
= ELF_START_ADDR
;
1771 /* compute address after headers */
1772 addr
+= (file_offset
& (s_align
- 1));
1776 /* Leave one program headers for the program interpreter and one for
1777 the program header table itself if needed. These are done later as
1778 they require section layout to be done first. */
1782 /* dynamic relocation table information, for .dynamic section */
1783 dyninf
->rel_addr
= dyninf
->rel_size
= 0;
1784 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1785 dyninf
->bss_addr
= dyninf
->bss_size
= 0;
1788 for(j
= 0; j
< 2; j
++) {
1789 ph
->p_type
= PT_LOAD
;
1791 ph
->p_flags
= PF_R
| PF_X
;
1793 ph
->p_flags
= PF_R
| PF_W
;
1794 ph
->p_align
= s_align
;
1796 /* Decide the layout of sections loaded in memory. This must
1797 be done before program headers are filled since they contain
1798 info about the layout. We do the following ordering: interp,
1799 symbol tables, relocations, progbits, nobits */
1800 /* XXX: do faster and simpler sorting */
1801 for(k
= 0; k
< 5; k
++) {
1802 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1803 s
= s1
->sections
[i
];
1804 /* compute if section should be included */
1806 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1810 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1811 (SHF_ALLOC
| SHF_WRITE
))
1817 } else if (s
->sh_type
== SHT_DYNSYM
||
1818 s
->sh_type
== SHT_STRTAB
||
1819 s
->sh_type
== SHT_HASH
) {
1822 } else if (s
->sh_type
== SHT_RELX
) {
1825 } else if (s
->sh_type
== SHT_NOBITS
) {
1832 sec_order
[sh_order_index
++] = i
;
1834 /* section matches: we align it and add its size */
1836 addr
= (addr
+ s
->sh_addralign
- 1) &
1837 ~(s
->sh_addralign
- 1);
1838 file_offset
+= (int) ( addr
- tmp
);
1839 s
->sh_offset
= file_offset
;
1842 /* update program header infos */
1843 if (ph
->p_offset
== 0) {
1844 ph
->p_offset
= file_offset
;
1846 ph
->p_paddr
= ph
->p_vaddr
;
1848 /* update dynamic relocation infos */
1849 if (s
->sh_type
== SHT_RELX
) {
1850 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1851 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.got")) {
1852 dyninf
->rel_addr
= addr
;
1853 dyninf
->rel_size
+= s
->sh_size
; /* XXX only first rel. */
1855 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.bss")) {
1856 dyninf
->bss_addr
= addr
;
1857 dyninf
->bss_size
= s
->sh_size
; /* XXX only first rel. */
1860 if (dyninf
->rel_size
== 0)
1861 dyninf
->rel_addr
= addr
;
1862 dyninf
->rel_size
+= s
->sh_size
;
1866 if (s
->sh_type
!= SHT_NOBITS
)
1867 file_offset
+= s
->sh_size
;
1871 /* Make the first PT_LOAD segment include the program
1872 headers itself (and the ELF header as well), it'll
1873 come out with same memory use but will make various
1874 tools like binutils strip work better. */
1875 ph
->p_offset
&= ~(ph
->p_align
- 1);
1876 ph
->p_vaddr
&= ~(ph
->p_align
- 1);
1877 ph
->p_paddr
&= ~(ph
->p_align
- 1);
1879 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1880 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1883 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1884 /* if in the middle of a page, we duplicate the page in
1885 memory so that one copy is RX and the other is RW */
1886 if ((addr
& (s_align
- 1)) != 0)
1889 addr
= (addr
+ s_align
- 1) & ~(s_align
- 1);
1890 file_offset
= (file_offset
+ s_align
- 1) & ~(s_align
- 1);
1896 /* all other sections come after */
1897 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1898 s
= s1
->sections
[i
];
1899 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1901 sec_order
[sh_order_index
++] = i
;
1903 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1904 ~(s
->sh_addralign
- 1);
1905 s
->sh_offset
= file_offset
;
1906 if (s
->sh_type
!= SHT_NOBITS
)
1907 file_offset
+= s
->sh_size
;
1913 #ifndef ELF_OBJ_ONLY
1914 static void fill_unloadable_phdr(ElfW(Phdr
) *phdr
, int phnum
, Section
*interp
,
1919 /* if interpreter, then add corresponding program header */
1923 ph
->p_type
= PT_PHDR
;
1924 ph
->p_offset
= sizeof(ElfW(Ehdr
));
1925 ph
->p_filesz
= ph
->p_memsz
= phnum
* sizeof(ElfW(Phdr
));
1926 ph
->p_vaddr
= interp
->sh_addr
- ph
->p_filesz
;
1927 ph
->p_paddr
= ph
->p_vaddr
;
1928 ph
->p_flags
= PF_R
| PF_X
;
1929 ph
->p_align
= 4; /* interp->sh_addralign; */
1932 ph
->p_type
= PT_INTERP
;
1933 ph
->p_offset
= interp
->sh_offset
;
1934 ph
->p_vaddr
= interp
->sh_addr
;
1935 ph
->p_paddr
= ph
->p_vaddr
;
1936 ph
->p_filesz
= interp
->sh_size
;
1937 ph
->p_memsz
= interp
->sh_size
;
1939 ph
->p_align
= interp
->sh_addralign
;
1942 /* if dynamic section, then add corresponding program header */
1944 ph
= &phdr
[phnum
- 1];
1946 ph
->p_type
= PT_DYNAMIC
;
1947 ph
->p_offset
= dynamic
->sh_offset
;
1948 ph
->p_vaddr
= dynamic
->sh_addr
;
1949 ph
->p_paddr
= ph
->p_vaddr
;
1950 ph
->p_filesz
= dynamic
->sh_size
;
1951 ph
->p_memsz
= dynamic
->sh_size
;
1952 ph
->p_flags
= PF_R
| PF_W
;
1953 ph
->p_align
= dynamic
->sh_addralign
;
1957 /* Fill the dynamic section with tags describing the address and size of
1959 static void fill_dynamic(TCCState
*s1
, struct dyn_inf
*dyninf
)
1961 Section
*dynamic
= dyninf
->dynamic
;
1964 /* put dynamic section entries */
1965 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1966 put_dt(dynamic
, DT_STRTAB
, dyninf
->dynstr
->sh_addr
);
1967 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1968 put_dt(dynamic
, DT_STRSZ
, dyninf
->dynstr
->data_offset
);
1969 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1971 put_dt(dynamic
, DT_RELA
, dyninf
->rel_addr
);
1972 put_dt(dynamic
, DT_RELASZ
, dyninf
->rel_size
);
1973 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1975 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1976 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
1977 put_dt(dynamic
, DT_PLTRELSZ
, dyninf
->rel_size
);
1978 put_dt(dynamic
, DT_JMPREL
, dyninf
->rel_addr
);
1979 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
1980 put_dt(dynamic
, DT_REL
, dyninf
->bss_addr
);
1981 put_dt(dynamic
, DT_RELSZ
, dyninf
->bss_size
);
1983 put_dt(dynamic
, DT_REL
, dyninf
->rel_addr
);
1984 put_dt(dynamic
, DT_RELSZ
, dyninf
->rel_size
);
1985 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1988 if (versym_section
) {
1989 put_dt(dynamic
, DT_VERNEED
, verneed_section
->sh_addr
);
1990 put_dt(dynamic
, DT_VERNEEDNUM
, dt_verneednum
);
1991 put_dt(dynamic
, DT_VERSYM
, versym_section
->sh_addr
);
1993 s
= find_section_create (s1
, ".preinit_array", 0);
1994 if (s
&& s
->data_offset
) {
1995 put_dt(dynamic
, DT_PREINIT_ARRAY
, s
->sh_addr
);
1996 put_dt(dynamic
, DT_PREINIT_ARRAYSZ
, s
->data_offset
);
1998 s
= find_section_create (s1
, ".init_array", 0);
1999 if (s
&& s
->data_offset
) {
2000 put_dt(dynamic
, DT_INIT_ARRAY
, s
->sh_addr
);
2001 put_dt(dynamic
, DT_INIT_ARRAYSZ
, s
->data_offset
);
2003 s
= find_section_create (s1
, ".fini_array", 0);
2004 if (s
&& s
->data_offset
) {
2005 put_dt(dynamic
, DT_FINI_ARRAY
, s
->sh_addr
);
2006 put_dt(dynamic
, DT_FINI_ARRAYSZ
, s
->data_offset
);
2008 s
= find_section_create (s1
, ".init", 0);
2009 if (s
&& s
->data_offset
) {
2010 put_dt(dynamic
, DT_INIT
, s
->sh_addr
);
2012 s
= find_section_create (s1
, ".fini", 0);
2013 if (s
&& s
->data_offset
) {
2014 put_dt(dynamic
, DT_FINI
, s
->sh_addr
);
2017 put_dt(dynamic
, DT_DEBUG
, 0);
2018 put_dt(dynamic
, DT_NULL
, 0);
2021 /* Relocate remaining sections and symbols (that is those not related to
2023 static int final_sections_reloc(TCCState
*s1
)
2028 relocate_syms(s1
, s1
->symtab
, 0);
2030 if (s1
->nb_errors
!= 0)
2033 /* relocate sections */
2034 /* XXX: ignore sections with allocated relocations ? */
2035 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2036 s
= s1
->sections
[i
];
2037 if (s
->reloc
&& (s
!= s1
->got
|| s1
->static_link
))
2038 relocate_section(s1
, s
);
2041 /* relocate relocation entries if the relocation tables are
2042 allocated in the executable */
2043 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2044 s
= s1
->sections
[i
];
2045 if ((s
->sh_flags
& SHF_ALLOC
) &&
2046 s
->sh_type
== SHT_RELX
) {
2047 relocate_rel(s1
, s
);
2054 /* Create an ELF file on disk.
2055 This function handle ELF specific layout requirements */
2056 static void tcc_output_elf(TCCState
*s1
, FILE *f
, int phnum
, ElfW(Phdr
) *phdr
,
2057 int file_offset
, int *sec_order
)
2059 int i
, shnum
, offset
, size
, file_type
;
2062 ElfW(Shdr
) shdr
, *sh
;
2065 file_type
= s1
->output_type
;
2066 shnum
= s1
->nb_sections
;
2068 memset(&ehdr
, 0, sizeof(ehdr
));
2071 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2072 ehdr
.e_phnum
= phnum
;
2073 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2077 file_offset
= (file_offset
+ 3) & -4;
2080 ehdr
.e_ident
[0] = ELFMAG0
;
2081 ehdr
.e_ident
[1] = ELFMAG1
;
2082 ehdr
.e_ident
[2] = ELFMAG2
;
2083 ehdr
.e_ident
[3] = ELFMAG3
;
2084 ehdr
.e_ident
[4] = ELFCLASSW
;
2085 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2086 ehdr
.e_ident
[6] = EV_CURRENT
;
2087 #if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
2088 /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
2089 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2091 #ifdef TCC_TARGET_ARM
2093 ehdr
.e_ident
[EI_OSABI
] = 0;
2094 ehdr
.e_flags
= EF_ARM_EABI_VER4
;
2095 if (file_type
== TCC_OUTPUT_EXE
|| file_type
== TCC_OUTPUT_DLL
)
2096 ehdr
.e_flags
|= EF_ARM_HASENTRY
;
2097 if (s1
->float_abi
== ARM_HARD_FLOAT
)
2098 ehdr
.e_flags
|= EF_ARM_VFP_FLOAT
;
2100 ehdr
.e_flags
|= EF_ARM_SOFT_FLOAT
;
2102 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2104 #elif defined TCC_TARGET_RISCV64
2105 ehdr
.e_flags
= EF_RISCV_FLOAT_ABI_DOUBLE
;
2109 case TCC_OUTPUT_EXE
:
2110 ehdr
.e_type
= ET_EXEC
;
2111 ehdr
.e_entry
= get_elf_sym_addr(s1
, "_start", 1);
2113 case TCC_OUTPUT_DLL
:
2114 ehdr
.e_type
= ET_DYN
;
2115 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
2117 case TCC_OUTPUT_OBJ
:
2118 ehdr
.e_type
= ET_REL
;
2121 ehdr
.e_machine
= EM_TCC_TARGET
;
2122 ehdr
.e_version
= EV_CURRENT
;
2123 ehdr
.e_shoff
= file_offset
;
2124 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2125 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2126 ehdr
.e_shnum
= shnum
;
2127 ehdr
.e_shstrndx
= shnum
- 1;
2129 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2130 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2131 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2133 sort_syms(s1
, symtab_section
);
2135 for_each_elem(s1
->dynsym
, 0, sym
, ElfW(Sym
))
2136 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
)
2137 s1
->dynsym
->sh_info
++;
2138 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2139 s
= s1
->sections
[sec_order
[i
]];
2140 if (s
->sh_type
!= SHT_NOBITS
) {
2141 while (offset
< s
->sh_offset
) {
2147 fwrite(s
->data
, 1, size
, f
);
2152 /* output section headers */
2153 while (offset
< ehdr
.e_shoff
) {
2158 for(i
= 0; i
< s1
->nb_sections
; i
++) {
2160 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2161 s
= s1
->sections
[i
];
2163 sh
->sh_name
= s
->sh_name
;
2164 sh
->sh_type
= s
->sh_type
;
2165 sh
->sh_flags
= s
->sh_flags
;
2166 sh
->sh_entsize
= s
->sh_entsize
;
2167 sh
->sh_info
= s
->sh_info
;
2169 sh
->sh_link
= s
->link
->sh_num
;
2170 sh
->sh_addralign
= s
->sh_addralign
;
2171 sh
->sh_addr
= s
->sh_addr
;
2172 sh
->sh_offset
= s
->sh_offset
;
2173 sh
->sh_size
= s
->sh_size
;
2175 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2179 /* Write an elf, coff or "binary" file */
2180 static int tcc_write_elf_file(TCCState
*s1
, const char *filename
, int phnum
,
2181 ElfW(Phdr
) *phdr
, int file_offset
, int *sec_order
)
2183 int fd
, mode
, file_type
;
2186 file_type
= s1
->output_type
;
2187 if (file_type
== TCC_OUTPUT_OBJ
)
2192 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2194 tcc_error_noabort("could not write '%s'", filename
);
2197 f
= fdopen(fd
, "wb");
2199 printf("<- %s\n", filename
);
2201 #ifdef TCC_TARGET_COFF
2202 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
)
2203 tcc_output_coff(s1
, f
);
2206 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2207 tcc_output_elf(s1
, f
, phnum
, phdr
, file_offset
, sec_order
);
2209 tcc_output_binary(s1
, f
, sec_order
);
2215 #ifndef ELF_OBJ_ONLY
2216 /* Sort section headers by assigned sh_addr, remove sections
2217 that we aren't going to output. */
2218 static void tidy_section_headers(TCCState
*s1
, int *sec_order
)
2220 int i
, nnew
, l
, *backmap
;
2224 snew
= tcc_malloc(s1
->nb_sections
* sizeof(snew
[0]));
2225 backmap
= tcc_malloc(s1
->nb_sections
* sizeof(backmap
[0]));
2226 for (i
= 0, nnew
= 0, l
= s1
->nb_sections
; i
< s1
->nb_sections
; i
++) {
2227 s
= s1
->sections
[sec_order
[i
]];
2228 if (!i
|| s
->sh_name
) {
2229 backmap
[sec_order
[i
]] = nnew
;
2233 backmap
[sec_order
[i
]] = 0;
2237 for (i
= 0; i
< nnew
; i
++) {
2241 if (s
->sh_type
== SHT_RELX
)
2242 s
->sh_info
= backmap
[s
->sh_info
];
2246 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
))
2247 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2248 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2249 if( !s1
->static_link
) {
2250 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
))
2251 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2252 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2254 for (i
= 0; i
< s1
->nb_sections
; i
++)
2256 tcc_free(s1
->sections
);
2257 s1
->sections
= snew
;
2258 s1
->nb_sections
= nnew
;
2263 /* Output an elf, coff or binary file */
2264 /* XXX: suppress unneeded sections */
2265 static int elf_output_file(TCCState
*s1
, const char *filename
)
2267 int ret
, phnum
, shnum
, file_type
, file_offset
, *sec_order
;
2268 struct dyn_inf dyninf
= {0};
2270 Section
*strsec
, *interp
, *dynamic
, *dynstr
;
2272 file_type
= s1
->output_type
;
2277 interp
= dynamic
= dynstr
= NULL
; /* avoid warning */
2279 #ifndef ELF_OBJ_ONLY
2280 if (file_type
!= TCC_OUTPUT_OBJ
) {
2281 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2282 tcc_add_runtime(s1
);
2283 resolve_common_syms(s1
);
2285 if (!s1
->static_link
) {
2286 if (file_type
== TCC_OUTPUT_EXE
) {
2288 /* allow override the dynamic loader */
2289 const char *elfint
= getenv("LD_SO");
2291 elfint
= DEFAULT_ELFINTERP(s1
);
2292 /* add interpreter section only if executable */
2293 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
2294 interp
->sh_addralign
= 1;
2295 ptr
= section_ptr_add(interp
, 1 + strlen(elfint
));
2296 strcpy(ptr
, elfint
);
2299 /* add dynamic symbol table */
2300 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
2302 ".hash", SHF_ALLOC
);
2303 dynstr
= s1
->dynsym
->link
;
2304 /* add dynamic section */
2305 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
2306 SHF_ALLOC
| SHF_WRITE
);
2307 dynamic
->link
= dynstr
;
2308 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
2312 if (file_type
== TCC_OUTPUT_EXE
) {
2313 bind_exe_dynsyms(s1
);
2316 bind_libs_dynsyms(s1
);
2318 /* shared library case: simply export all global symbols */
2319 export_global_syms(s1
);
2322 build_got_entries(s1
);
2327 /* we add a section for symbols */
2328 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
2329 put_elf_str(strsec
, "");
2331 /* Allocate strings for section names */
2332 ret
= alloc_sec_names(s1
, file_type
, strsec
);
2334 #ifndef ELF_OBJ_ONLY
2337 /* add a list of needed dlls */
2338 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2339 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
2340 if (dllref
->level
== 0)
2341 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
2345 put_dt(dynamic
, s1
->enable_new_dtags
? DT_RUNPATH
: DT_RPATH
,
2346 put_elf_str(dynstr
, s1
->rpath
));
2348 if (file_type
== TCC_OUTPUT_DLL
) {
2350 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
2351 /* XXX: currently, since we do not handle PIC code, we
2352 must relocate the readonly segments */
2354 put_dt(dynamic
, DT_TEXTREL
, 0);
2358 put_dt(dynamic
, DT_SYMBOLIC
, 0);
2360 dyninf
.dynamic
= dynamic
;
2361 dyninf
.dynstr
= dynstr
;
2362 /* remember offset and reserve space for 2nd call below */
2363 dyninf
.data_offset
= dynamic
->data_offset
;
2364 fill_dynamic(s1
, &dyninf
);
2365 dynamic
->sh_size
= dynamic
->data_offset
;
2366 dynstr
->sh_size
= dynstr
->data_offset
;
2370 /* compute number of program headers */
2371 if (file_type
== TCC_OUTPUT_OBJ
)
2373 else if (file_type
== TCC_OUTPUT_DLL
)
2375 else if (s1
->static_link
)
2380 /* allocate program segment headers */
2381 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
2383 /* compute number of sections */
2384 shnum
= s1
->nb_sections
;
2386 /* this array is used to reorder sections in the output file */
2387 sec_order
= tcc_malloc(sizeof(int) * shnum
);
2390 /* compute section to program header mapping */
2391 file_offset
= layout_sections(s1
, phdr
, phnum
, interp
, strsec
, &dyninf
,
2394 #ifndef ELF_OBJ_ONLY
2395 /* Fill remaining program header and finalize relocation related to dynamic
2397 if (file_type
!= TCC_OUTPUT_OBJ
) {
2398 fill_unloadable_phdr(phdr
, phnum
, interp
, dynamic
);
2401 dynamic
->data_offset
= dyninf
.data_offset
;
2402 fill_dynamic(s1
, &dyninf
);
2404 /* put in GOT the dynamic section address and relocate PLT */
2405 write32le(s1
->got
->data
, dynamic
->sh_addr
);
2406 if (file_type
== TCC_OUTPUT_EXE
2407 || (RELOCATE_DLLPLT
&& file_type
== TCC_OUTPUT_DLL
))
2410 /* relocate symbols in .dynsym now that final addresses are known */
2411 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
)) {
2412 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
) {
2413 /* do symbol relocation */
2414 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
2419 /* if building executable or DLL, then relocate each section
2420 except the GOT which is already relocated */
2421 ret
= final_sections_reloc(s1
);
2424 tidy_section_headers(s1
, sec_order
);
2426 /* Perform relocation to GOT or PLT entries */
2427 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2430 fill_local_got_entries(s1
);
2434 /* Create the ELF file with name 'filename' */
2435 ret
= tcc_write_elf_file(s1
, filename
, phnum
, phdr
, file_offset
, sec_order
);
2436 s1
->nb_sections
= shnum
;
2439 tcc_free(sec_order
);
2444 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2447 #ifdef TCC_TARGET_PE
2448 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2449 ret
= pe_output_file(s
, filename
);
2452 ret
= elf_output_file(s
, filename
);
2456 ssize_t
full_read(int fd
, void *buf
, size_t count
) {
2460 ssize_t num
= read(fd
, cbuf
, count
-rnum
);
2461 if (num
< 0) return num
;
2462 if (num
== 0) return rnum
;
2468 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2472 data
= tcc_malloc(size
);
2473 lseek(fd
, file_offset
, SEEK_SET
);
2474 full_read(fd
, data
, size
);
2478 typedef struct SectionMergeInfo
{
2479 Section
*s
; /* corresponding existing section */
2480 unsigned long offset
; /* offset of the new section in the existing section */
2481 uint8_t new_section
; /* true if section 's' was added */
2482 uint8_t link_once
; /* true if link once section */
2485 ST_FUNC
int tcc_object_type(int fd
, ElfW(Ehdr
) *h
)
2487 int size
= full_read(fd
, h
, sizeof *h
);
2488 if (size
== sizeof *h
&& 0 == memcmp(h
, ELFMAG
, 4)) {
2489 if (h
->e_type
== ET_REL
)
2490 return AFF_BINTYPE_REL
;
2491 if (h
->e_type
== ET_DYN
)
2492 return AFF_BINTYPE_DYN
;
2493 } else if (size
>= 8) {
2494 if (0 == memcmp(h
, ARMAG
, 8))
2495 return AFF_BINTYPE_AR
;
2496 #ifdef TCC_TARGET_COFF
2497 if (((struct filehdr
*)h
)->f_magic
== COFF_C67_MAGIC
)
2498 return AFF_BINTYPE_C67
;
2504 /* load an object file and merge it with current files */
2505 /* XXX: handle correctly stab (debug) info */
2506 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
2507 int fd
, unsigned long file_offset
)
2510 ElfW(Shdr
) *shdr
, *sh
;
2511 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
, seencompressed
;
2512 char *strsec
, *strtab
;
2513 int stab_index
, stabstr_index
;
2514 int *old_to_new_syms
;
2515 char *sh_name
, *name
;
2516 SectionMergeInfo
*sm_table
, *sm
;
2517 ElfW(Sym
) *sym
, *symtab
;
2521 lseek(fd
, file_offset
, SEEK_SET
);
2522 if (tcc_object_type(fd
, &ehdr
) != AFF_BINTYPE_REL
)
2524 /* test CPU specific stuff */
2525 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2526 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2528 tcc_error_noabort("invalid object file");
2532 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2533 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2534 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2536 /* load section names */
2537 sh
= &shdr
[ehdr
.e_shstrndx
];
2538 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2540 /* load symtab and strtab */
2541 old_to_new_syms
= NULL
;
2546 stab_index
= stabstr_index
= 0;
2548 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2550 if (sh
->sh_type
== SHT_SYMTAB
) {
2552 tcc_error_noabort("object must contain only one symtab");
2557 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2558 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2559 sm_table
[i
].s
= symtab_section
;
2561 /* now load strtab */
2562 sh
= &shdr
[sh
->sh_link
];
2563 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2565 if (sh
->sh_flags
& SHF_COMPRESSED
)
2569 /* now examine each section and try to merge its content with the
2571 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2572 /* no need to examine section name strtab */
2573 if (i
== ehdr
.e_shstrndx
)
2576 if (sh
->sh_type
== SHT_RELX
)
2577 sh
= &shdr
[sh
->sh_info
];
2578 /* ignore sections types we do not handle (plus relocs to those) */
2579 if (sh
->sh_type
!= SHT_PROGBITS
&&
2581 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2583 sh
->sh_type
!= SHT_NOBITS
&&
2584 sh
->sh_type
!= SHT_PREINIT_ARRAY
&&
2585 sh
->sh_type
!= SHT_INIT_ARRAY
&&
2586 sh
->sh_type
!= SHT_FINI_ARRAY
&&
2587 strcmp(strsec
+ sh
->sh_name
, ".stabstr")
2591 && !strncmp(strsec
+ sh
->sh_name
, ".debug_", sizeof(".debug_")-1))
2595 sh_name
= strsec
+ sh
->sh_name
;
2596 if (sh
->sh_addralign
< 1)
2597 sh
->sh_addralign
= 1;
2598 /* find corresponding section, if any */
2599 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2600 s
= s1
->sections
[j
];
2601 if (!strcmp(s
->name
, sh_name
)) {
2602 if (!strncmp(sh_name
, ".gnu.linkonce",
2603 sizeof(".gnu.linkonce") - 1)) {
2604 /* if a 'linkonce' section is already present, we
2605 do not add it again. It is a little tricky as
2606 symbols can still be defined in
2608 sm_table
[i
].link_once
= 1;
2612 if (s
== stab_section
)
2614 if (s
== stab_section
->link
)
2620 /* not found: create new section */
2621 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
& ~SHF_GROUP
);
2622 /* take as much info as possible from the section. sh_link and
2623 sh_info will be updated later */
2624 s
->sh_addralign
= sh
->sh_addralign
;
2625 s
->sh_entsize
= sh
->sh_entsize
;
2626 sm_table
[i
].new_section
= 1;
2628 if (sh
->sh_type
!= s
->sh_type
) {
2629 tcc_error_noabort("invalid section type");
2632 /* align start of section */
2633 s
->data_offset
+= -s
->data_offset
& (sh
->sh_addralign
- 1);
2634 if (sh
->sh_addralign
> s
->sh_addralign
)
2635 s
->sh_addralign
= sh
->sh_addralign
;
2636 sm_table
[i
].offset
= s
->data_offset
;
2638 /* concatenate sections */
2640 if (sh
->sh_type
!= SHT_NOBITS
) {
2642 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2643 ptr
= section_ptr_add(s
, size
);
2644 full_read(fd
, ptr
, size
);
2646 s
->data_offset
+= size
;
2651 /* gr relocate stab strings */
2652 if (stab_index
&& stabstr_index
) {
2655 s
= sm_table
[stab_index
].s
;
2656 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2657 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2658 o
= sm_table
[stabstr_index
].offset
;
2666 /* second short pass to update sh_link and sh_info fields of new
2668 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2670 if (!s
|| !sm_table
[i
].new_section
)
2673 if (sh
->sh_link
> 0)
2674 s
->link
= sm_table
[sh
->sh_link
].s
;
2675 if (sh
->sh_type
== SHT_RELX
) {
2676 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2677 /* update backward link */
2678 s1
->sections
[s
->sh_info
]->reloc
= s
;
2682 /* resolve symbols */
2683 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2686 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2687 if (sym
->st_shndx
!= SHN_UNDEF
&&
2688 sym
->st_shndx
< SHN_LORESERVE
) {
2689 sm
= &sm_table
[sym
->st_shndx
];
2690 if (sm
->link_once
) {
2691 /* if a symbol is in a link once section, we use the
2692 already defined symbol. It is very important to get
2693 correct relocations */
2694 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2695 name
= strtab
+ sym
->st_name
;
2696 sym_index
= find_elf_sym(symtab_section
, name
);
2698 old_to_new_syms
[i
] = sym_index
;
2702 /* if no corresponding section added, no need to add symbol */
2705 /* convert section number */
2706 sym
->st_shndx
= sm
->s
->sh_num
;
2708 sym
->st_value
+= sm
->offset
;
2711 name
= strtab
+ sym
->st_name
;
2712 sym_index
= set_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2713 sym
->st_info
, sym
->st_other
,
2714 sym
->st_shndx
, name
);
2715 old_to_new_syms
[i
] = sym_index
;
2718 /* third pass to patch relocation entries */
2719 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2724 offset
= sm_table
[i
].offset
;
2725 switch(s
->sh_type
) {
2727 /* take relocation offset information */
2728 offseti
= sm_table
[sh
->sh_info
].offset
;
2729 for_each_elem(s
, (offset
/ sizeof(*rel
)), rel
, ElfW_Rel
) {
2732 /* convert symbol index */
2733 type
= ELFW(R_TYPE
)(rel
->r_info
);
2734 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2735 /* NOTE: only one symtab assumed */
2736 if (sym_index
>= nb_syms
)
2738 sym_index
= old_to_new_syms
[sym_index
];
2739 /* ignore link_once in rel section. */
2740 if (!sym_index
&& !sm_table
[sh
->sh_info
].link_once
2741 #ifdef TCC_TARGET_ARM
2742 && type
!= R_ARM_V4BX
2743 #elif defined TCC_TARGET_RISCV64
2744 && type
!= R_RISCV_ALIGN
2745 && type
!= R_RISCV_RELAX
2749 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2750 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2753 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2754 /* offset the relocation offset */
2755 rel
->r_offset
+= offseti
;
2756 #ifdef TCC_TARGET_ARM
2757 /* Jumps and branches from a Thumb code to a PLT entry need
2758 special handling since PLT entries are ARM code.
2759 Unconditional bl instructions referencing PLT entries are
2760 handled by converting these instructions into blx
2761 instructions. Other case of instructions referencing a PLT
2762 entry require to add a Thumb stub before the PLT entry to
2763 switch to ARM mode. We set bit plt_thumb_stub of the
2764 attribute of a symbol to indicate such a case. */
2765 if (type
== R_ARM_THM_JUMP24
)
2766 get_sym_attr(s1
, sym_index
, 1)->plt_thumb_stub
= 1;
2779 tcc_free(old_to_new_syms
);
2786 typedef struct ArchiveHeader
{
2787 char ar_name
[16]; /* name of this member */
2788 char ar_date
[12]; /* file mtime */
2789 char ar_uid
[6]; /* owner uid; printed as decimal */
2790 char ar_gid
[6]; /* owner gid; printed as decimal */
2791 char ar_mode
[8]; /* file mode, printed as octal */
2792 char ar_size
[10]; /* file size, printed as decimal */
2793 char ar_fmag
[2]; /* should contain ARFMAG */
2796 #define ARFMAG "`\n"
2798 static unsigned long long get_be(const uint8_t *b
, int n
)
2800 unsigned long long ret
= 0;
2802 ret
= (ret
<< 8) | *b
++, --n
;
2806 static int read_ar_header(int fd
, int offset
, ArchiveHeader
*hdr
)
2810 lseek(fd
, offset
, SEEK_SET
);
2811 len
= full_read(fd
, hdr
, sizeof(ArchiveHeader
));
2812 if (len
!= sizeof(ArchiveHeader
))
2813 return len
? -1 : 0;
2815 for (e
= p
+ sizeof hdr
->ar_name
; e
> p
&& e
[-1] == ' ';)
2818 hdr
->ar_size
[sizeof hdr
->ar_size
-1] = 0;
2822 /* load only the objects which resolve undefined symbols */
2823 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
, int entrysize
)
2825 int i
, bound
, nsyms
, sym_index
, len
, ret
= -1;
2826 unsigned long long off
;
2828 const char *ar_names
, *p
;
2829 const uint8_t *ar_index
;
2833 data
= tcc_malloc(size
);
2834 if (full_read(fd
, data
, size
) != size
)
2836 nsyms
= get_be(data
, entrysize
);
2837 ar_index
= data
+ entrysize
;
2838 ar_names
= (char *) ar_index
+ nsyms
* entrysize
;
2842 for (p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2843 Section
*s
= symtab_section
;
2844 sym_index
= find_elf_sym(s
, p
);
2845 #ifdef TCC_TARGET_PE /* windows DLL's don't have UNDEF syms */
2846 if (sym_index
== 0) {
2847 s
= s1
->dynsymtab_section
;
2848 sym_index
= find_elf_sym(s
, p
);
2853 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
2854 if(sym
->st_shndx
!= SHN_UNDEF
)
2856 off
= get_be(ar_index
+ i
* entrysize
, entrysize
);
2857 len
= read_ar_header(fd
, off
, &hdr
);
2858 if (len
<= 0 || memcmp(hdr
.ar_fmag
, ARFMAG
, 2)) {
2859 tcc_error_noabort("invalid archive");
2863 if (s1
->verbose
== 2)
2864 printf(" -> %s\n", hdr
.ar_name
);
2865 if (tcc_load_object_file(s1
, fd
, off
) < 0)
2876 /* load a '.a' file */
2877 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
, int alacarte
)
2880 /* char magic[8]; */
2882 unsigned long file_offset
;
2885 /* skip magic which was already checked */
2886 /* full_read(fd, magic, sizeof(magic)); */
2887 file_offset
= sizeof ARMAG
- 1;
2890 len
= read_ar_header(fd
, file_offset
, &hdr
);
2894 tcc_error_noabort("invalid archive");
2898 size
= strtol(hdr
.ar_size
, NULL
, 0);
2900 size
= (size
+ 1) & ~1;
2902 /* coff symbol table : we handle it */
2903 if (!strcmp(hdr
.ar_name
, "/"))
2904 return tcc_load_alacarte(s1
, fd
, size
, 4);
2905 if (!strcmp(hdr
.ar_name
, "/SYM64/"))
2906 return tcc_load_alacarte(s1
, fd
, size
, 8);
2907 } else if (tcc_object_type(fd
, &ehdr
) == AFF_BINTYPE_REL
) {
2908 if (s1
->verbose
== 2)
2909 printf(" -> %s\n", hdr
.ar_name
);
2910 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2913 file_offset
+= size
;
2917 #ifndef ELF_OBJ_ONLY
2918 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
2919 LV, maybe create a new entry for (LIB,VERSION). */
2920 static void set_ver_to_ver(TCCState
*s1
, int *n
, int **lv
, int i
, char *lib
, char *version
)
2923 *lv
= tcc_realloc(*lv
, (*n
+ 1) * sizeof(**lv
));
2926 if ((*lv
)[i
] == -1) {
2927 int v
, prev_same_lib
= -1;
2928 for (v
= 0; v
< nb_sym_versions
; v
++) {
2929 if (strcmp(sym_versions
[v
].lib
, lib
))
2932 if (!strcmp(sym_versions
[v
].version
, version
))
2935 if (v
== nb_sym_versions
) {
2936 sym_versions
= tcc_realloc (sym_versions
,
2937 (v
+ 1) * sizeof(*sym_versions
));
2938 sym_versions
[v
].lib
= tcc_strdup(lib
);
2939 sym_versions
[v
].version
= tcc_strdup(version
);
2940 sym_versions
[v
].out_index
= 0;
2941 sym_versions
[v
].prev_same_lib
= prev_same_lib
;
2948 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
2951 set_sym_version(TCCState
*s1
, int sym_index
, int verndx
)
2953 if (sym_index
>= nb_sym_to_version
) {
2954 int newelems
= sym_index
? sym_index
* 2 : 1;
2955 sym_to_version
= tcc_realloc(sym_to_version
,
2956 newelems
* sizeof(*sym_to_version
));
2957 memset(sym_to_version
+ nb_sym_to_version
, -1,
2958 (newelems
- nb_sym_to_version
) * sizeof(*sym_to_version
));
2959 nb_sym_to_version
= newelems
;
2961 if (sym_to_version
[sym_index
] < 0)
2962 sym_to_version
[sym_index
] = verndx
;
2965 struct versym_info
{
2967 ElfW(Verdef
) *verdef
;
2968 ElfW(Verneed
) *verneed
;
2970 int nb_local_ver
, *local_ver
;
2974 static void store_version(TCCState
*s1
, struct versym_info
*v
, char *dynstr
)
2976 char *lib
, *version
;
2980 #define DEBUG_VERSION 0
2982 if (v
->versym
&& v
->verdef
) {
2983 ElfW(Verdef
) *vdef
= v
->verdef
;
2986 ElfW(Verdaux
) *verdaux
=
2987 (ElfW(Verdaux
) *) (((char *) vdef
) + vdef
->vd_aux
);
2990 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
2991 vdef
->vd_version
, vdef
->vd_flags
, vdef
->vd_ndx
,
2995 version
= dynstr
+ verdaux
->vda_name
;
3000 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vdef
->vd_ndx
,
3003 printf (" verdaux(%u): %s\n", vdef
->vd_ndx
, version
);
3006 next
= vdef
->vd_next
;
3007 vdef
= (ElfW(Verdef
) *) (((char *) vdef
) + next
);
3010 if (v
->versym
&& v
->verneed
) {
3011 ElfW(Verneed
) *vneed
= v
->verneed
;
3013 ElfW(Vernaux
) *vernaux
=
3014 (ElfW(Vernaux
) *) (((char *) vneed
) + vneed
->vn_aux
);
3016 lib
= dynstr
+ vneed
->vn_file
;
3018 printf ("verneed: %u %s\n", vneed
->vn_version
, lib
);
3020 for (i
= 0; i
< vneed
->vn_cnt
; i
++) {
3021 if ((vernaux
->vna_other
& 0x8000) == 0) { /* hidden */
3022 version
= dynstr
+ vernaux
->vna_name
;
3023 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vernaux
->vna_other
,
3026 printf (" vernaux(%u): %u %u %s\n",
3027 vernaux
->vna_other
, vernaux
->vna_hash
,
3028 vernaux
->vna_flags
, version
);
3031 vernaux
= (ElfW(Vernaux
) *) (((char *) vernaux
) + vernaux
->vna_next
);
3033 next
= vneed
->vn_next
;
3034 vneed
= (ElfW(Verneed
) *) (((char *) vneed
) + next
);
3039 for (i
= 0; i
< v
->nb_local_ver
; i
++) {
3040 if (v
->local_ver
[i
] > 0) {
3041 printf ("%d: lib: %s, version %s\n",
3042 i
, sym_versions
[v
->local_ver
[i
]].lib
,
3043 sym_versions
[v
->local_ver
[i
]].version
);
3049 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3050 is referenced by the user (so it should be added as DT_NEEDED in
3051 the generated ELF file) */
3052 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
3055 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
3056 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
3057 ElfW(Sym
) *sym
, *dynsym
;
3058 ElfW(Dyn
) *dt
, *dynamic
;
3062 const char *name
, *soname
;
3063 DLLReference
*dllref
;
3064 struct versym_info v
;
3066 full_read(fd
, &ehdr
, sizeof(ehdr
));
3068 /* test CPU specific stuff */
3069 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
3070 ehdr
.e_machine
!= EM_TCC_TARGET
) {
3071 tcc_error_noabort("bad architecture");
3076 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
3078 /* load dynamic section and dynamic symbols */
3082 dynsym
= NULL
; /* avoid warning */
3083 dynstr
= NULL
; /* avoid warning */
3084 memset(&v
, 0, sizeof v
);
3086 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
3087 switch(sh
->sh_type
) {
3089 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
3090 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3093 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
3094 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3095 sh1
= &shdr
[sh
->sh_link
];
3096 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
3098 case SHT_GNU_verdef
:
3099 v
.verdef
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3101 case SHT_GNU_verneed
:
3102 v
.verneed
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3104 case SHT_GNU_versym
:
3105 v
.nb_versyms
= sh
->sh_size
/ sizeof(ElfW(Half
));
3106 v
.versym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3113 /* compute the real library name */
3114 soname
= tcc_basename(filename
);
3116 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3117 if (dt
->d_tag
== DT_SONAME
) {
3118 soname
= dynstr
+ dt
->d_un
.d_val
;
3122 /* if the dll is already loaded, do not load it */
3123 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
3124 dllref
= s1
->loaded_dlls
[i
];
3125 if (!strcmp(soname
, dllref
->name
)) {
3126 /* but update level if needed */
3127 if (level
< dllref
->level
)
3128 dllref
->level
= level
;
3134 if (v
.nb_versyms
!= nb_syms
)
3135 tcc_free (v
.versym
), v
.versym
= NULL
;
3137 store_version(s1
, &v
, dynstr
);
3139 /* add the dll and its level */
3140 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
3141 dllref
->level
= level
;
3142 strcpy(dllref
->name
, soname
);
3143 dynarray_add(&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
3145 /* add dynamic symbols in dynsym_section */
3146 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
3147 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
3148 if (sym_bind
== STB_LOCAL
)
3150 name
= dynstr
+ sym
->st_name
;
3151 sym_index
= set_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
3152 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
3154 ElfW(Half
) vsym
= v
.versym
[i
];
3155 if ((vsym
& 0x8000) == 0 && vsym
> 0 && vsym
< v
.nb_local_ver
)
3156 set_sym_version(s1
, sym_index
, v
.local_ver
[vsym
]);
3160 /* load all referenced DLLs */
3161 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3164 name
= dynstr
+ dt
->d_un
.d_val
;
3165 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
3166 dllref
= s1
->loaded_dlls
[j
];
3167 if (!strcmp(name
, dllref
->name
))
3168 goto already_loaded
;
3170 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
3171 tcc_error_noabort("referenced dll '%s' not found", name
);
3185 tcc_free(v
.local_ver
);
3187 tcc_free(v
.verneed
);
3192 #define LD_TOK_NAME 256
3193 #define LD_TOK_EOF (-1)
3195 static int ld_inp(TCCState
*s1
)
3203 if (1 == read(s1
->fd
, &b
, 1))
3208 /* return next ld script token */
3209 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
3226 if (ch
== '*') { /* comment */
3227 for (d
= 0;; d
= ch
) {
3229 if (ch
== CH_EOF
|| (ch
== '/' && d
== '*'))
3240 /* case 'a' ... 'z': */
3267 /* case 'A' ... 'z': */
3301 if (!((ch
>= 'a' && ch
<= 'z') ||
3302 (ch
>= 'A' && ch
<= 'Z') ||
3303 (ch
>= '0' && ch
<= '9') ||
3304 strchr("/.-_+=$:\\,~", ch
)))
3306 if ((q
- name
) < name_size
- 1) {
3325 static int ld_add_file(TCCState
*s1
, const char filename
[])
3327 if (filename
[0] == '/') {
3328 if (CONFIG_SYSROOT
[0] == '\0'
3329 && tcc_add_file_internal(s1
, filename
, AFF_TYPE_BIN
) == 0)
3331 filename
= tcc_basename(filename
);
3333 return tcc_add_dll(s1
, filename
, 0);
3336 static int ld_add_file_list(TCCState
*s1
, const char *cmd
, int as_needed
)
3338 char filename
[1024], libname
[1024];
3339 int t
, group
, nblibs
= 0, ret
= 0;
3342 group
= !strcmp(cmd
, "GROUP");
3344 s1
->new_undef_sym
= 0;
3345 t
= ld_next(s1
, filename
, sizeof(filename
));
3347 tcc_error_noabort("( expected");
3349 goto lib_parse_error
;
3351 t
= ld_next(s1
, filename
, sizeof(filename
));
3354 if (t
== LD_TOK_EOF
) {
3355 tcc_error_noabort("unexpected end of file");
3357 goto lib_parse_error
;
3358 } else if (t
== ')') {
3360 } else if (t
== '-') {
3361 t
= ld_next(s1
, filename
, sizeof(filename
));
3362 if ((t
!= LD_TOK_NAME
) || (filename
[0] != 'l')) {
3363 tcc_error_noabort("library name expected");
3365 goto lib_parse_error
;
3367 pstrcpy(libname
, sizeof libname
, &filename
[1]);
3368 if (s1
->static_link
) {
3369 snprintf(filename
, sizeof filename
, "lib%s.a", libname
);
3371 snprintf(filename
, sizeof filename
, "lib%s.so", libname
);
3373 } else if (t
!= LD_TOK_NAME
) {
3374 tcc_error_noabort("filename expected");
3376 goto lib_parse_error
;
3378 if (!strcmp(filename
, "AS_NEEDED")) {
3379 ret
= ld_add_file_list(s1
, cmd
, 1);
3381 goto lib_parse_error
;
3383 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3385 ret
= ld_add_file(s1
, filename
);
3387 goto lib_parse_error
;
3389 /* Add the filename *and* the libname to avoid future conversions */
3390 dynarray_add(&libs
, &nblibs
, tcc_strdup(filename
));
3391 if (libname
[0] != '\0')
3392 dynarray_add(&libs
, &nblibs
, tcc_strdup(libname
));
3396 t
= ld_next(s1
, filename
, sizeof(filename
));
3398 t
= ld_next(s1
, filename
, sizeof(filename
));
3401 if (group
&& !as_needed
) {
3402 while (s1
->new_undef_sym
) {
3404 s1
->new_undef_sym
= 0;
3405 for (i
= 0; i
< nblibs
; i
++)
3406 ld_add_file(s1
, libs
[i
]);
3410 dynarray_reset(&libs
, &nblibs
);
3414 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3416 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
, int fd
)
3419 char filename
[1024];
3425 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3426 if (t
== LD_TOK_EOF
)
3428 else if (t
!= LD_TOK_NAME
)
3430 if (!strcmp(cmd
, "INPUT") ||
3431 !strcmp(cmd
, "GROUP")) {
3432 ret
= ld_add_file_list(s1
, cmd
, 0);
3435 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
3436 !strcmp(cmd
, "TARGET")) {
3437 /* ignore some commands */
3438 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3440 tcc_error_noabort("( expected");
3444 t
= ld_next(s1
, filename
, sizeof(filename
));
3445 if (t
== LD_TOK_EOF
) {
3446 tcc_error_noabort("unexpected end of file");
3448 } else if (t
== ')') {
3458 #endif /* !ELF_OBJ_ONLY */