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 /* create ro data section (make ro after relocation done with GNU_RELRO) */
62 data_ro_section
= new_section(s
, ".data.ro", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
63 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
64 common_section
= new_section(s
, ".common", SHT_NOBITS
, SHF_PRIVATE
);
65 common_section
->sh_num
= SHN_COMMON
;
67 /* symbols are always generated for linking stage */
68 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
70 ".hashtab", SHF_PRIVATE
);
71 s
->symtab
= symtab_section
;
73 /* private symbol table for dynamic symbols */
74 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
|SHF_DYNSYM
,
76 ".dynhashtab", SHF_PRIVATE
);
77 get_sym_attr(s
, 0, 1);
80 #ifdef CONFIG_TCC_BCHECK
81 ST_FUNC
void tccelf_bounds_new(TCCState
*s
)
84 /* create bounds sections (make ro after relocation done with GNU_RELRO) */
85 bounds_section
= new_section(s
, ".bounds",
86 SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
87 lbounds_section
= new_section(s
, ".lbounds",
88 SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
92 ST_FUNC
void tccelf_stab_new(TCCState
*s
)
96 #ifdef CONFIG_TCC_BACKTRACE
97 /* include stab info with standalone backtrace support */
98 if (s
->do_backtrace
&& s
->output_type
!= TCC_OUTPUT_MEMORY
)
99 shf
= SHF_ALLOC
| SHF_WRITE
; // SHF_WRITE needed for musl/SELINUX
101 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, shf
);
102 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
103 stab_section
->sh_addralign
= sizeof ((Stab_Sym
*)0)->n_value
;
104 stab_section
->link
= new_section(s
, ".stabstr", SHT_STRTAB
, shf
);
105 /* put first entry */
106 put_stabs(s
, "", 0, 0, 0, 0);
109 static void free_section(Section
*s
)
114 ST_FUNC
void tccelf_delete(TCCState
*s1
)
119 /* free symbol versions */
120 for (i
= 0; i
< nb_sym_versions
; i
++) {
121 tcc_free(sym_versions
[i
].version
);
122 tcc_free(sym_versions
[i
].lib
);
124 tcc_free(sym_versions
);
125 tcc_free(sym_to_version
);
128 /* free all sections */
129 for(i
= 1; i
< s1
->nb_sections
; i
++)
130 free_section(s1
->sections
[i
]);
131 dynarray_reset(&s1
->sections
, &s1
->nb_sections
);
133 for(i
= 0; i
< s1
->nb_priv_sections
; i
++)
134 free_section(s1
->priv_sections
[i
]);
135 dynarray_reset(&s1
->priv_sections
, &s1
->nb_priv_sections
);
137 /* free any loaded DLLs */
139 for ( i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
140 DLLReference
*ref
= s1
->loaded_dlls
[i
];
143 FreeLibrary((HMODULE
)ref
->handle
);
145 dlclose(ref
->handle
);
149 /* free loaded dlls array */
150 dynarray_reset(&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
);
151 tcc_free(s1
->sym_attrs
);
153 symtab_section
= NULL
; /* for tccrun.c:rt_printline() */
156 /* save section data state */
157 ST_FUNC
void tccelf_begin_file(TCCState
*s1
)
160 for (i
= 1; i
< s1
->nb_sections
; i
++) {
162 s
->sh_offset
= s
->data_offset
;
164 /* disable symbol hashing during compilation */
165 s
= s1
->symtab
, s
->reloc
= s
->hash
, s
->hash
= NULL
;
166 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
171 /* At the end of compilation, convert any UNDEF syms to global, and merge
172 with previously existing symbols */
173 ST_FUNC
void tccelf_end_file(TCCState
*s1
)
175 Section
*s
= s1
->symtab
;
176 int first_sym
, nb_syms
, *tr
, i
;
178 first_sym
= s
->sh_offset
/ sizeof (ElfSym
);
179 nb_syms
= s
->data_offset
/ sizeof (ElfSym
) - first_sym
;
180 s
->data_offset
= s
->sh_offset
;
181 s
->link
->data_offset
= s
->link
->sh_offset
;
182 s
->hash
= s
->reloc
, s
->reloc
= NULL
;
183 tr
= tcc_mallocz(nb_syms
* sizeof *tr
);
185 for (i
= 0; i
< nb_syms
; ++i
) {
186 ElfSym
*sym
= (ElfSym
*)s
->data
+ first_sym
+ i
;
187 if (sym
->st_shndx
== SHN_UNDEF
188 && ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
)
189 sym
->st_info
= ELFW(ST_INFO
)(STB_GLOBAL
, ELFW(ST_TYPE
)(sym
->st_info
));
190 tr
[i
] = set_elf_sym(s
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
191 sym
->st_other
, sym
->st_shndx
, (char*)s
->link
->data
+ sym
->st_name
);
193 /* now update relocations */
194 for (i
= 1; i
< s1
->nb_sections
; i
++) {
195 Section
*sr
= s1
->sections
[i
];
196 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
197 ElfW_Rel
*rel
= (ElfW_Rel
*)(sr
->data
+ sr
->sh_offset
);
198 ElfW_Rel
*rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
199 for (; rel
< rel_end
; ++rel
) {
200 int n
= ELFW(R_SYM
)(rel
->r_info
) - first_sym
;
201 //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
202 rel
->r_info
= ELFW(R_INFO
)(tr
[n
], ELFW(R_TYPE
)(rel
->r_info
));
208 /* record text/data/bss output for -bench info */
209 for (i
= 0; i
< 3; ++i
) {
210 s
= s1
->sections
[i
+ 1];
211 s1
->total_output
[i
] += s
->data_offset
- s
->sh_offset
;
215 ST_FUNC Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
219 sec
= tcc_mallocz(sizeof(Section
) + strlen(name
));
221 strcpy(sec
->name
, name
);
222 sec
->sh_type
= sh_type
;
223 sec
->sh_flags
= sh_flags
;
226 sec
->sh_addralign
= 2;
234 case SHT_GNU_verneed
:
236 sec
->sh_addralign
= PTR_SIZE
;
239 sec
->sh_addralign
= 1;
242 sec
->sh_addralign
= PTR_SIZE
; /* gcc/pcc default alignment */
246 if (sh_flags
& SHF_PRIVATE
) {
247 dynarray_add(&s1
->priv_sections
, &s1
->nb_priv_sections
, sec
);
249 sec
->sh_num
= s1
->nb_sections
;
250 dynarray_add(&s1
->sections
, &s1
->nb_sections
, sec
);
256 ST_FUNC Section
*new_symtab(TCCState
*s1
,
257 const char *symtab_name
, int sh_type
, int sh_flags
,
258 const char *strtab_name
,
259 const char *hash_name
, int hash_sh_flags
)
261 Section
*symtab
, *strtab
, *hash
;
262 int *ptr
, nb_buckets
;
264 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
265 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
266 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
267 put_elf_str(strtab
, "");
268 symtab
->link
= strtab
;
269 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
273 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
274 hash
->sh_entsize
= sizeof(int);
278 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
281 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
285 /* realloc section and set its content to zero */
286 ST_FUNC
void section_realloc(Section
*sec
, unsigned long new_size
)
291 size
= sec
->data_allocated
;
294 while (size
< new_size
)
296 data
= tcc_realloc(sec
->data
, size
);
297 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
299 sec
->data_allocated
= size
;
302 /* reserve at least 'size' bytes aligned per 'align' in section
303 'sec' from current offset, and return the aligned offset */
304 ST_FUNC
size_t section_add(Section
*sec
, addr_t size
, int align
)
306 size_t offset
, offset1
;
308 offset
= (sec
->data_offset
+ align
- 1) & -align
;
309 offset1
= offset
+ size
;
310 if (sec
->sh_type
!= SHT_NOBITS
&& offset1
> sec
->data_allocated
)
311 section_realloc(sec
, offset1
);
312 sec
->data_offset
= offset1
;
313 if (align
> sec
->sh_addralign
)
314 sec
->sh_addralign
= align
;
318 /* reserve at least 'size' bytes in section 'sec' from
320 ST_FUNC
void *section_ptr_add(Section
*sec
, addr_t size
)
322 size_t offset
= section_add(sec
, size
, 1);
323 return sec
->data
+ offset
;
327 /* reserve at least 'size' bytes from section start */
328 static void section_reserve(Section
*sec
, unsigned long size
)
330 if (size
> sec
->data_allocated
)
331 section_realloc(sec
, size
);
332 if (size
> sec
->data_offset
)
333 sec
->data_offset
= size
;
337 static Section
*find_section_create (TCCState
*s1
, const char *name
, int create
)
341 for(i
= 1; i
< s1
->nb_sections
; i
++) {
342 sec
= s1
->sections
[i
];
343 if (!strcmp(name
, sec
->name
))
346 /* sections are created as PROGBITS */
347 return create
? new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
) : NULL
;
350 /* return a reference to a section, and create it if it does not
352 ST_FUNC Section
*find_section(TCCState
*s1
, const char *name
)
354 return find_section_create (s1
, name
, 1);
357 /* ------------------------------------------------------------------------- */
359 ST_FUNC
int put_elf_str(Section
*s
, const char *sym
)
364 len
= strlen(sym
) + 1;
365 offset
= s
->data_offset
;
366 ptr
= section_ptr_add(s
, len
);
367 memmove(ptr
, sym
, len
);
371 /* elf symbol hashing function */
372 static unsigned long elf_hash(const unsigned char *name
)
374 unsigned long h
= 0, g
;
377 h
= (h
<< 4) + *name
++;
386 /* rebuild hash table of section s */
387 /* NOTE: we do factorize the hash table code to go faster */
388 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
391 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
392 unsigned char *strtab
;
394 strtab
= s
->link
->data
;
395 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
398 nb_buckets
= ((int*)s
->hash
->data
)[0];
400 s
->hash
->data_offset
= 0;
401 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
406 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
407 ptr
+= nb_buckets
+ 1;
409 sym
= (ElfW(Sym
) *)s
->data
+ 1;
410 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
411 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
412 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
423 /* return the symbol number */
424 ST_FUNC
int put_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
425 int info
, int other
, int shndx
, const char *name
)
427 int name_offset
, sym_index
;
432 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
434 name_offset
= put_elf_str(s
->link
, name
);
437 /* XXX: endianness */
438 sym
->st_name
= name_offset
;
439 sym
->st_value
= value
;
442 sym
->st_other
= other
;
443 sym
->st_shndx
= shndx
;
444 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
448 ptr
= section_ptr_add(hs
, sizeof(int));
449 base
= (int *)hs
->data
;
450 /* only add global or weak symbols. */
451 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
452 /* add another hashing entry */
454 h
= elf_hash((unsigned char *)s
->link
->data
+ name_offset
) % nbuckets
;
456 base
[2 + h
] = sym_index
;
458 /* we resize the hash table */
459 hs
->nb_hashed_syms
++;
460 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
461 rebuild_hash(s
, 2 * nbuckets
);
471 ST_FUNC
int find_elf_sym(Section
*s
, const char *name
)
475 int nbuckets
, sym_index
, h
;
481 nbuckets
= ((int *)hs
->data
)[0];
482 h
= elf_hash((unsigned char *) name
) % nbuckets
;
483 sym_index
= ((int *)hs
->data
)[2 + h
];
484 while (sym_index
!= 0) {
485 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
486 name1
= (char *) s
->link
->data
+ sym
->st_name
;
487 if (!strcmp(name
, name1
))
489 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
494 /* return elf symbol value, signal error if 'err' is nonzero, decorate
496 ST_FUNC addr_t
get_sym_addr(TCCState
*s1
, const char *name
, int err
, int forc
)
501 if (forc
&& s1
->leading_underscore
503 /* win32-32bit stdcall symbols always have _ already */
504 && !strchr(name
, '@')
508 pstrcpy(buf
+ 1, sizeof(buf
) - 1, name
);
511 sym_index
= find_elf_sym(s1
->symtab
, name
);
512 sym
= &((ElfW(Sym
) *)s1
->symtab
->data
)[sym_index
];
513 if (!sym_index
|| sym
->st_shndx
== SHN_UNDEF
) {
515 tcc_error("%s not defined", name
);
518 return sym
->st_value
;
521 /* return elf symbol value */
522 LIBTCCAPI
void *tcc_get_symbol(TCCState
*s
, const char *name
)
524 addr_t addr
= get_sym_addr(s
, name
, 0, 1);
525 return addr
== -1 ? NULL
: (void*)(uintptr_t)addr
;
528 /* list elf symbol names and values */
529 ST_FUNC
void list_elf_symbols(TCCState
*s
, void *ctx
,
530 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
534 int sym_index
, end_sym
;
536 unsigned char sym_vis
, sym_bind
;
539 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
540 for (sym_index
= 0; sym_index
< end_sym
; ++sym_index
) {
541 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
543 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
544 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
545 sym_vis
= ELFW(ST_VISIBILITY
)(sym
->st_other
);
546 if (sym_bind
== STB_GLOBAL
&& sym_vis
== STV_DEFAULT
)
547 symbol_cb(ctx
, name
, (void*)(uintptr_t)sym
->st_value
);
552 /* list elf symbol names and values */
553 LIBTCCAPI
void tcc_list_symbols(TCCState
*s
, void *ctx
,
554 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
556 list_elf_symbols(s
, ctx
, symbol_cb
);
561 version_add (TCCState
*s1
)
565 ElfW(Verneed
) *vn
= NULL
;
567 int sym_index
, end_sym
, nb_versions
= 2, nb_entries
= 0;
571 if (0 == nb_sym_versions
)
573 versym_section
= new_section(s1
, ".gnu.version", SHT_GNU_versym
, SHF_ALLOC
);
574 versym_section
->sh_entsize
= sizeof(ElfW(Half
));
575 versym_section
->link
= s1
->dynsym
;
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, but not when it will be empty. Some
596 dynamic linkers look at their contents even when DTVERNEEDNUM and
597 section size is zero. */
598 if (nb_versions
> 2) {
599 verneed_section
= new_section(s1
, ".gnu.version_r",
600 SHT_GNU_verneed
, SHF_ALLOC
);
601 verneed_section
->link
= s1
->dynsym
->link
;
602 for (i
= nb_sym_versions
; i
-- > 0;) {
603 struct sym_version
*sv
= &sym_versions
[i
];
604 int n_same_libs
= 0, prev
;
606 ElfW(Vernaux
) *vna
= 0;
607 if (sv
->out_index
< 1)
609 vnofs
= section_add(verneed_section
, sizeof(*vn
), 1);
610 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
612 vn
->vn_file
= put_elf_str(verneed_section
->link
, sv
->lib
);
613 vn
->vn_aux
= sizeof (*vn
);
615 prev
= sv
->prev_same_lib
;
616 if (sv
->out_index
> 0) {
617 vna
= section_ptr_add(verneed_section
, sizeof(*vna
));
618 vna
->vna_hash
= elf_hash ((const unsigned char *)sv
->version
);
620 vna
->vna_other
= sv
->out_index
;
622 vna
->vna_name
= put_elf_str(verneed_section
->link
, sv
->version
);
623 vna
->vna_next
= sizeof (*vna
);
627 sv
= &sym_versions
[prev
];
630 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
631 vn
->vn_cnt
= n_same_libs
;
632 vn
->vn_next
= sizeof(*vn
) + n_same_libs
* sizeof(*vna
);
637 verneed_section
->sh_info
= nb_entries
;
639 dt_verneednum
= nb_entries
;
643 /* add an elf symbol : check if it is already defined and patch
644 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
645 ST_FUNC
int set_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
646 int info
, int other
, int shndx
, const char *name
)
648 TCCState
*s1
= s
->s1
;
650 int sym_bind
, sym_index
, sym_type
, esym_bind
;
651 unsigned char sym_vis
, esym_vis
, new_vis
;
653 sym_bind
= ELFW(ST_BIND
)(info
);
654 sym_type
= ELFW(ST_TYPE
)(info
);
655 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
657 if (sym_bind
!= STB_LOCAL
) {
658 /* we search global or weak symbols */
659 sym_index
= find_elf_sym(s
, name
);
662 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
663 if (esym
->st_value
== value
&& esym
->st_size
== size
&& esym
->st_info
== info
664 && esym
->st_other
== other
&& esym
->st_shndx
== shndx
)
666 if (esym
->st_shndx
!= SHN_UNDEF
) {
667 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
668 /* propagate the most constraining visibility */
669 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
670 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
671 if (esym_vis
== STV_DEFAULT
) {
673 } else if (sym_vis
== STV_DEFAULT
) {
676 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
678 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
680 other
= esym
->st_other
; /* in case we have to patch esym */
681 if (shndx
== SHN_UNDEF
) {
682 /* ignore adding of undefined symbol if the
683 corresponding symbol is already defined */
684 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
685 /* global overrides weak, so patch */
687 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
688 /* weak is ignored if already global */
689 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_WEAK
) {
690 /* keep first-found weak definition, ignore subsequents */
691 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
692 /* ignore hidden symbols after */
693 } else if ((esym
->st_shndx
== SHN_COMMON
694 || esym
->st_shndx
== bss_section
->sh_num
)
695 && (shndx
< SHN_LORESERVE
696 && shndx
!= bss_section
->sh_num
)) {
697 /* data symbol gets precedence over common/bss */
699 } else if (shndx
== SHN_COMMON
|| shndx
== bss_section
->sh_num
) {
700 /* data symbol keeps precedence over common/bss */
701 } else if (s
->sh_flags
& SHF_DYNSYM
) {
702 /* we accept that two DLL define the same symbol */
703 } else if (esym
->st_other
& ST_ASM_SET
) {
704 /* If the existing symbol came from an asm .set
709 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
710 sym_bind
, shndx
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
712 tcc_error_noabort("'%s' defined twice", name
);
716 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
717 esym
->st_shndx
= shndx
;
718 s1
->new_undef_sym
= 1;
719 esym
->st_value
= value
;
720 esym
->st_size
= size
;
721 esym
->st_other
= other
;
725 sym_index
= put_elf_sym(s
, value
, size
,
726 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
733 ST_FUNC
void put_elf_reloca(Section
*symtab
, Section
*s
, unsigned long offset
,
734 int type
, int symbol
, addr_t addend
)
736 TCCState
*s1
= s
->s1
;
740 int jmp_slot
= type
== R_JMP_SLOT
;
742 sr
= jmp_slot
? s
->relocplt
: s
->reloc
;
744 /* if no relocation section, create it */
746 snprintf(buf
, sizeof(buf
), RELPLT_SECTION_FMT
);
748 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
749 /* if the symtab is allocated, then we consider the relocation
751 sr
= new_section(s
->s1
, buf
, SHT_RELX
, symtab
->sh_flags
);
752 sr
->sh_entsize
= sizeof(ElfW_Rel
);
754 sr
->sh_info
= s
->sh_num
;
760 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
761 rel
->r_offset
= offset
;
762 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
763 #if SHT_RELX == SHT_RELA
764 rel
->r_addend
= addend
;
766 if (SHT_RELX
!= SHT_RELA
&& addend
)
767 tcc_error("non-zero addend on REL architecture");
770 ST_FUNC
void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
771 int type
, int symbol
)
773 put_elf_reloca(symtab
, s
, offset
, type
, symbol
, 0);
776 /* put stab debug information */
777 ST_FUNC
void put_stabs(TCCState
*s1
, const char *str
, int type
, int other
, int desc
,
784 && (offset
= stab_section
->data_offset
)
785 && (sym
= (Stab_Sym
*)(stab_section
->data
+ offset
) - 1)
786 && sym
->n_type
== type
787 && sym
->n_value
== value
) {
788 /* just update line_number in previous entry */
793 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
795 sym
->n_strx
= put_elf_str(stab_section
->link
, str
);
800 sym
->n_other
= other
;
802 sym
->n_value
= value
;
805 ST_FUNC
void put_stabs_r(TCCState
*s1
, const char *str
, int type
, int other
, int desc
,
806 unsigned long value
, Section
*sec
, int sym_index
)
808 put_elf_reloc(symtab_section
, stab_section
,
809 stab_section
->data_offset
+ 8,
810 sizeof ((Stab_Sym
*)0)->n_value
== PTR_SIZE
? R_DATA_PTR
: R_DATA_32
,
812 put_stabs(s1
, str
, type
, other
, desc
, value
);
815 ST_FUNC
void put_stabn(TCCState
*s1
, int type
, int other
, int desc
, int value
)
817 put_stabs(s1
, NULL
, type
, other
, desc
, value
);
820 ST_FUNC
struct sym_attr
*get_sym_attr(TCCState
*s1
, int index
, int alloc
)
823 struct sym_attr
*tab
;
825 if (index
>= s1
->nb_sym_attrs
) {
827 return s1
->sym_attrs
;
828 /* find immediately bigger power of 2 and reallocate array */
832 tab
= tcc_realloc(s1
->sym_attrs
, n
* sizeof(*s1
->sym_attrs
));
834 memset(s1
->sym_attrs
+ s1
->nb_sym_attrs
, 0,
835 (n
- s1
->nb_sym_attrs
) * sizeof(*s1
->sym_attrs
));
836 s1
->nb_sym_attrs
= n
;
838 return &s1
->sym_attrs
[index
];
841 /* In an ELF file symbol table, the local symbols must appear below
842 the global and weak ones. Since TCC cannot sort it while generating
843 the code, we must do it after. All the relocation tables are also
844 modified to take into account the symbol table sorting */
845 static void sort_syms(TCCState
*s1
, Section
*s
)
847 int *old_to_new_syms
;
855 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
856 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
857 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
859 /* first pass for local symbols */
860 p
= (ElfW(Sym
) *)s
->data
;
862 for(i
= 0; i
< nb_syms
; i
++) {
863 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
864 old_to_new_syms
[i
] = q
- new_syms
;
869 /* save the number of local symbols in section header */
870 if( s
->sh_size
) /* this 'if' makes IDA happy */
871 s
->sh_info
= q
- new_syms
;
873 /* then second pass for non local symbols */
874 p
= (ElfW(Sym
) *)s
->data
;
875 for(i
= 0; i
< nb_syms
; i
++) {
876 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
877 old_to_new_syms
[i
] = q
- new_syms
;
883 /* we copy the new symbols to the old */
884 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
887 /* now we modify all the relocations */
888 for(i
= 1; i
< s1
->nb_sections
; i
++) {
889 sr
= s1
->sections
[i
];
890 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
891 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
892 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
893 type
= ELFW(R_TYPE
)(rel
->r_info
);
894 sym_index
= old_to_new_syms
[sym_index
];
895 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
900 tcc_free(old_to_new_syms
);
903 /* relocate symbol table, resolve undefined symbols if do_resolve is
904 true and output error if undefined symbol. */
905 ST_FUNC
void relocate_syms(TCCState
*s1
, Section
*symtab
, int do_resolve
)
908 int sym_bind
, sh_num
;
911 for_each_elem(symtab
, 1, sym
, ElfW(Sym
)) {
912 sh_num
= sym
->st_shndx
;
913 if (sh_num
== SHN_UNDEF
) {
914 name
= (char *) s1
->symtab
->link
->data
+ sym
->st_name
;
915 /* Use ld.so to resolve symbol for us (for tcc -run) */
917 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
918 /* dlsym() needs the undecorated name. */
919 void *addr
= dlsym(RTLD_DEFAULT
, &name
[s1
->leading_underscore
]);
920 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
923 for (i
= 0; i
< s1
->nb_loaded_dlls
; i
++)
924 if ((addr
= dlsym(s1
->loaded_dlls
[i
]->handle
, name
)))
929 sym
->st_value
= (addr_t
) addr
;
931 printf ("relocate_sym: %s -> 0x%lx\n", name
, sym
->st_value
);
936 /* if dynamic symbol exist, it will be used in relocate_section */
937 } else if (s1
->dynsym
&& find_elf_sym(s1
->dynsym
, name
))
939 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
941 if (!strcmp(name
, "_fp_hw"))
943 /* only weak symbols are accepted to be undefined. Their
945 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
946 if (sym_bind
== STB_WEAK
)
949 tcc_error_noabort("undefined symbol '%s'", name
);
950 } else if (sh_num
< SHN_LORESERVE
) {
951 /* add section base */
952 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
958 /* relocate a given section (CPU dependent) by applying the relocations
959 in the associated relocation section */
960 ST_FUNC
void relocate_section(TCCState
*s1
, Section
*s
)
962 Section
*sr
= s
->reloc
;
969 qrel
= (ElfW_Rel
*)sr
->data
;
971 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
972 ptr
= s
->data
+ rel
->r_offset
;
973 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
974 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
975 type
= ELFW(R_TYPE
)(rel
->r_info
);
977 #if SHT_RELX == SHT_RELA
978 tgt
+= rel
->r_addend
;
980 addr
= s
->sh_addr
+ rel
->r_offset
;
981 relocate(s1
, rel
, type
, ptr
, addr
, tgt
);
983 /* if the relocation is allocated, we change its symbol table */
984 if (sr
->sh_flags
& SHF_ALLOC
) {
985 sr
->link
= s1
->dynsym
;
986 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
987 size_t r
= (uint8_t*)qrel
- sr
->data
;
988 if (sizeof ((Stab_Sym
*)0)->n_value
< PTR_SIZE
989 && 0 == strcmp(s
->name
, ".stab"))
990 r
= 0; /* cannot apply 64bit relocation to 32bit value */
991 sr
->data_offset
= sr
->sh_size
= r
;
997 /* relocate relocation table in 'sr' */
998 static void relocate_rel(TCCState
*s1
, Section
*sr
)
1003 s
= s1
->sections
[sr
->sh_info
];
1004 for_each_elem(sr
, 0, rel
, ElfW_Rel
)
1005 rel
->r_offset
+= s
->sh_addr
;
1008 /* count the number of dynamic relocations so that we can reserve
1010 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
1013 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || \
1014 defined(TCC_TARGET_ARM) || defined(TCC_TARGET_ARM64) || \
1015 defined(TCC_TARGET_RISCV64)
1017 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
1018 int sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1019 int type
= ELFW(R_TYPE
)(rel
->r_info
);
1021 #if defined(TCC_TARGET_I386)
1023 if (!get_sym_attr(s1
, sym_index
, 0)->dyn_index
1024 && ((ElfW(Sym
)*)symtab_section
->data
+ sym_index
)->st_shndx
== SHN_UNDEF
) {
1025 /* don't fixup unresolved (weak) symbols */
1026 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_386_RELATIVE
);
1029 #elif defined(TCC_TARGET_X86_64)
1033 #elif defined(TCC_TARGET_ARM)
1036 #elif defined(TCC_TARGET_ARM64)
1037 case R_AARCH64_ABS32
:
1038 case R_AARCH64_ABS64
:
1039 #elif defined(TCC_TARGET_RISCV64)
1045 #if defined(TCC_TARGET_I386)
1047 #elif defined(TCC_TARGET_X86_64)
1050 ElfW(Sym
) *sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1052 /* Hidden defined symbols can and must be resolved locally.
1053 We're misusing a PLT32 reloc for this, as that's always
1054 resolved to its address even in shared libs. */
1055 if (sym
->st_shndx
!= SHN_UNDEF
&&
1056 ELFW(ST_VISIBILITY
)(sym
->st_other
) == STV_HIDDEN
) {
1057 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PLT32
);
1061 #elif defined(TCC_TARGET_ARM64)
1062 case R_AARCH64_PREL32
:
1064 if (get_sym_attr(s1
, sym_index
, 0)->dyn_index
)
1076 #if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE)
1077 static void build_got(TCCState
*s1
)
1079 /* if no got, then create it */
1080 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
1081 s1
->got
->sh_entsize
= 4;
1082 set_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
1083 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
1084 /* keep space for _DYNAMIC pointer and two dummy got entries */
1085 section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
1088 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1089 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1090 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1091 Returns the offset of the GOT or (if any) PLT entry. */
1092 static struct sym_attr
* put_got_entry(TCCState
*s1
, int dyn_reloc_type
,
1098 struct sym_attr
*attr
;
1099 unsigned got_offset
;
1103 need_plt_entry
= (dyn_reloc_type
== R_JMP_SLOT
);
1104 attr
= get_sym_attr(s1
, sym_index
, 1);
1106 /* In case a function is both called and its address taken 2 GOT entries
1107 are created, one for taking the address (GOT) and the other for the PLT
1109 if (need_plt_entry
? attr
->plt_offset
: attr
->got_offset
)
1112 /* create the GOT entry */
1113 got_offset
= s1
->got
->data_offset
;
1114 section_ptr_add(s1
->got
, PTR_SIZE
);
1116 /* Create the GOT relocation that will insert the address of the object or
1117 function of interest in the GOT entry. This is a static relocation for
1118 memory output (dlsym will give us the address of symbols) and dynamic
1119 relocation otherwise (executable and DLLs). The relocation should be
1120 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1121 associated to a PLT entry) but is currently done at load time for an
1124 sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1125 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1128 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
) {
1129 /* Hack alarm. We don't want to emit dynamic symbols
1130 and symbol based relocs for STB_LOCAL symbols, but rather
1131 want to resolve them directly. At this point the symbol
1132 values aren't final yet, so we must defer this. We will later
1133 have to create a RELATIVE reloc anyway, so we misuse the
1134 relocation slot to smuggle the symbol reference until
1135 fill_local_got_entries. Not that the sym_index is
1136 relative to symtab_section, not s1->dynsym! Nevertheless
1137 we use s1->dyn_sym so that if this is the first call
1138 that got->reloc is correctly created. Also note that
1139 RELATIVE relocs are not normally created for the .got,
1140 so the types serves as a marker for later (and is retained
1141 also for the final output, which is okay because then the
1142 got is just normal data). */
1143 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, R_RELATIVE
,
1146 if (0 == attr
->dyn_index
)
1147 attr
->dyn_index
= set_elf_sym(s1
->dynsym
, sym
->st_value
,
1148 sym
->st_size
, sym
->st_info
, 0,
1149 sym
->st_shndx
, name
);
1150 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, dyn_reloc_type
,
1154 put_elf_reloc(symtab_section
, s1
->got
, got_offset
, dyn_reloc_type
,
1158 if (need_plt_entry
) {
1160 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1161 SHF_ALLOC
| SHF_EXECINSTR
);
1162 s1
->plt
->sh_entsize
= 4;
1165 attr
->plt_offset
= create_plt_entry(s1
, got_offset
, attr
);
1167 /* create a symbol 'sym@plt' for the PLT jump vector */
1169 if (len
> sizeof plt_name
- 5)
1170 len
= sizeof plt_name
- 5;
1171 memcpy(plt_name
, name
, len
);
1172 strcpy(plt_name
+ len
, "@plt");
1173 attr
->plt_sym
= put_elf_sym(s1
->symtab
, attr
->plt_offset
, sym
->st_size
,
1174 ELFW(ST_INFO
)(STB_GLOBAL
, STT_FUNC
), 0, s1
->plt
->sh_num
, plt_name
);
1177 attr
->got_offset
= got_offset
;
1183 /* build GOT and PLT entries */
1184 static void build_got_entries_pass(TCCState
*s1
, int pass
)
1189 int i
, type
, gotplt_entry
, reloc_type
, sym_index
;
1190 struct sym_attr
*attr
;
1192 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1193 s
= s1
->sections
[i
];
1194 if (s
->sh_type
!= SHT_RELX
)
1196 /* no need to handle got relocations */
1197 if (s
->link
!= symtab_section
)
1199 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1200 type
= ELFW(R_TYPE
)(rel
->r_info
);
1201 gotplt_entry
= gotplt_entry_type(type
);
1202 if (gotplt_entry
== -1)
1203 tcc_error ("Unknown relocation type for got: %d", type
);
1204 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1205 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1207 if (gotplt_entry
== NO_GOTPLT_ENTRY
) {
1211 /* Automatically create PLT/GOT [entry] if it is an undefined
1212 reference (resolved at runtime), or the symbol is absolute,
1213 probably created by tcc_add_symbol, and thus on 64-bit
1214 targets might be too far from application code. */
1215 if (gotplt_entry
== AUTO_GOTPLT_ENTRY
) {
1216 if (sym
->st_shndx
== SHN_UNDEF
) {
1219 if (s1
->output_type
== TCC_OUTPUT_DLL
&& ! PCRELATIVE_DLLPLT
)
1221 /* Relocations for UNDEF symbols would normally need
1222 to be transferred into the executable or shared object.
1223 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1224 But TCC doesn't do that (at least for exes), so we
1225 need to resolve all such relocs locally. And that
1226 means PLT slots for functions in DLLs and COPY relocs for
1227 data symbols. COPY relocs were generated in
1228 bind_exe_dynsyms (and the symbol adjusted to be defined),
1229 and for functions we were generated a dynamic symbol
1230 of function type. */
1232 /* dynsym isn't set for -run :-/ */
1233 dynindex
= get_sym_attr(s1
, sym_index
, 0)->dyn_index
;
1234 esym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ dynindex
;
1236 && (ELFW(ST_TYPE
)(esym
->st_info
) == STT_FUNC
1237 || (ELFW(ST_TYPE
)(esym
->st_info
) == STT_NOTYPE
1238 && ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
)))
1241 } else if (!(sym
->st_shndx
== SHN_ABS
1242 #ifndef TCC_TARGET_ARM
1249 #ifdef TCC_TARGET_X86_64
1250 if ((type
== R_X86_64_PLT32
|| type
== R_X86_64_PC32
) &&
1251 sym
->st_shndx
!= SHN_UNDEF
&&
1252 (ELFW(ST_VISIBILITY
)(sym
->st_other
) != STV_DEFAULT
||
1253 ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
||
1254 s1
->output_type
== TCC_OUTPUT_EXE
)) {
1257 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PC32
);
1261 reloc_type
= code_reloc(type
);
1262 if (reloc_type
== -1)
1263 tcc_error ("Unknown relocation type: %d", type
);
1264 else if (reloc_type
!= 0) {
1266 reloc_type
= R_JMP_SLOT
;
1268 reloc_type
= R_GLOB_DAT
;
1271 if ((pass
== 0 && reloc_type
== R_GLOB_DAT
) ||
1272 (pass
== 1 && reloc_type
== R_JMP_SLOT
))
1278 if (gotplt_entry
== BUILD_GOT_ONLY
)
1281 attr
= put_got_entry(s1
, reloc_type
, sym_index
);
1283 if (reloc_type
== R_JMP_SLOT
)
1284 rel
->r_info
= ELFW(R_INFO
)(attr
->plt_sym
, type
);
1289 ST_FUNC
void build_got_entries(TCCState
*s1
)
1293 /* Two passes because R_JMP_SLOT should become first.
1294 Some targets (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1295 for (i
= 0; i
< 2; i
++)
1296 build_got_entries_pass(s1
, i
);
1300 ST_FUNC
int set_global_sym(TCCState
*s1
, const char *name
, Section
*sec
, addr_t offs
)
1302 int shn
= sec
? sec
->sh_num
: offs
? SHN_ABS
: SHN_UNDEF
;
1303 if (sec
&& offs
== -1)
1304 offs
= sec
->data_offset
;
1305 return set_elf_sym(symtab_section
, offs
, 0,
1306 ELFW(ST_INFO
)(name
? STB_GLOBAL
: STB_LOCAL
, STT_NOTYPE
), 0, shn
, name
);
1309 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1314 s
= find_section(s1
, section_name
);
1319 end_offset
= s
->data_offset
;
1321 snprintf(buf
, sizeof(buf
), "__%s_start", section_name
+ 1);
1322 set_global_sym(s1
, buf
, s
, 0);
1323 snprintf(buf
, sizeof(buf
), "__%s_end", section_name
+ 1);
1324 set_global_sym(s1
, buf
, s
, end_offset
);
1327 #ifndef TCC_TARGET_PE
1328 static void tcc_add_support(TCCState
*s1
, const char *filename
)
1331 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, filename
);
1332 tcc_add_file(s1
, buf
);
1336 ST_FUNC
void add_array (TCCState
*s1
, const char *sec
, int c
)
1339 s
= find_section(s1
, sec
);
1340 s
->sh_flags
|= SHF_WRITE
;
1341 #ifndef TCC_TARGET_PE
1342 s
->sh_type
= sec
[1] == 'i' ? SHT_INIT_ARRAY
: SHT_FINI_ARRAY
;
1344 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1345 section_ptr_add(s
, PTR_SIZE
);
1348 #ifdef CONFIG_TCC_BCHECK
1349 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
1351 if (0 == s1
->do_bounds_check
)
1353 section_ptr_add(bounds_section
, sizeof(addr_t
));
1357 #ifdef CONFIG_TCC_BACKTRACE
1358 static void put_ptr(TCCState
*s1
, Section
*s
, int offs
)
1361 c
= set_global_sym(s1
, NULL
, s
, offs
);
1363 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1364 section_ptr_add(s
, PTR_SIZE
);
1367 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1368 a dynamic symbol to allow so's to have one each with a different value. */
1369 static void set_local_sym(TCCState
*s1
, const char *name
, Section
*s
, int offset
)
1371 int c
= find_elf_sym(s1
->symtab
, name
);
1373 ElfW(Sym
) *esym
= (ElfW(Sym
)*)s1
->symtab
->data
+ c
;
1374 esym
->st_info
= ELFW(ST_INFO
)(STB_LOCAL
, STT_NOTYPE
);
1375 esym
->st_value
= offset
;
1376 esym
->st_shndx
= s
->sh_num
;
1380 ST_FUNC
void tcc_add_btstub(TCCState
*s1
)
1387 /* Align to PTR_SIZE */
1388 section_ptr_add(s
, -s
->data_offset
& (PTR_SIZE
- 1));
1390 /* create (part of) a struct rt_context (see tccrun.c) */
1391 put_ptr(s1
, stab_section
, 0);
1392 put_ptr(s1
, stab_section
, -1);
1393 put_ptr(s1
, stab_section
->link
, 0);
1394 section_ptr_add(s
, 3 * PTR_SIZE
);
1396 #ifndef TCC_TARGET_MACHO
1397 /* XXX this relocation is wrong, it uses sym-index 0 (local,undef) */
1398 put_elf_reloc(s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, 0);
1400 section_ptr_add(s
, PTR_SIZE
);
1402 #ifdef CONFIG_TCC_BCHECK
1403 if (s1
->do_bounds_check
) {
1404 put_ptr(s1
, bounds_section
, 0);
1408 section_ptr_add(s
, n
);
1412 " extern void __bt_init(),*__rt_info[],__bt_init_dll();"
1413 "__attribute__((constructor)) static void __bt_init_rt(){");
1414 #ifdef TCC_TARGET_PE
1415 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1416 #ifdef CONFIG_TCC_BCHECK
1417 cstr_printf(&cstr
, "__bt_init_dll(%d);", s1
->do_bounds_check
);
1419 cstr_printf(&cstr
, "__bt_init_dll(0);");
1422 cstr_printf(&cstr
, "__bt_init(__rt_info,%d, 0);}",
1423 s1
->output_type
== TCC_OUTPUT_DLL
? 0 : s1
->rt_num_callers
+ 1);
1424 tcc_compile_string(s1
, cstr
.data
);
1426 set_local_sym(s1
, &"___rt_info"[!s1
->leading_underscore
], s
, o
);
1430 #ifndef TCC_TARGET_PE
1431 /* add tcc runtime libraries */
1432 ST_FUNC
void tcc_add_runtime(TCCState
*s1
)
1435 #ifdef CONFIG_TCC_BCHECK
1438 tcc_add_pragma_libs(s1
);
1440 if (!s1
->nostdlib
) {
1441 if (s1
->option_pthread
)
1442 tcc_add_library_err(s1
, "pthread");
1443 tcc_add_library_err(s1
, "c");
1445 if (!s1
->static_link
) {
1446 if (TCC_LIBGCC
[0] == '/')
1447 tcc_add_file(s1
, TCC_LIBGCC
);
1449 tcc_add_dll(s1
, TCC_LIBGCC
, 0);
1452 #if TCC_TARGET_ARM && TARGETOS_FreeBSD
1453 tcc_add_library_err(s1
, "gcc_s"); // unwind code
1455 #ifdef CONFIG_TCC_BCHECK
1456 if (s1
->do_bounds_check
&& s1
->output_type
!= TCC_OUTPUT_DLL
) {
1457 tcc_add_library_err(s1
, "pthread");
1458 #if !TARGETOS_OpenBSD && !TARGETOS_NetBSD
1459 tcc_add_library_err(s1
, "dl");
1461 tcc_add_support(s1
, "bcheck.o");
1462 if (s1
->static_link
)
1463 tcc_add_library_err(s1
, "c");
1466 #ifdef CONFIG_TCC_BACKTRACE
1467 if (s1
->do_backtrace
) {
1468 if (s1
->output_type
== TCC_OUTPUT_EXE
)
1469 tcc_add_support(s1
, "bt-exe.o");
1470 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1471 tcc_add_support(s1
, "bt-log.o");
1472 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1476 if (strlen(TCC_LIBTCC1
) > 0)
1477 tcc_add_support(s1
, TCC_LIBTCC1
);
1478 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
1479 /* add crt end if not memory output */
1480 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1481 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1482 tcc_add_crt(s1
, "crtendS.o");
1484 tcc_add_crt(s1
, "crtend.o");
1485 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
1486 tcc_add_crt(s1
, "crtn.o");
1489 #elif !defined(TCC_TARGET_MACHO)
1490 /* add crt end if not memory output */
1491 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1492 tcc_add_crt(s1
, "crtn.o");
1498 /* add various standard linker symbols (must be done after the
1499 sections are filled (for example after allocating common
1501 static void tcc_add_linker_symbols(TCCState
*s1
)
1507 set_global_sym(s1
, "_etext", text_section
, -1);
1508 set_global_sym(s1
, "_edata", data_section
, -1);
1509 set_global_sym(s1
, "_end", bss_section
, -1);
1510 #if TARGETOS_OpenBSD
1511 set_global_sym(s1
, "__executable_start", NULL
, ELF_START_ADDR
);
1513 #ifdef TCC_TARGET_RISCV64
1514 /* XXX should be .sdata+0x800, not .data+0x800 */
1515 set_global_sym(s1
, "__global_pointer$", data_section
, 0x800);
1517 /* horrible new standard ldscript defines */
1518 add_init_array_defines(s1
, ".preinit_array");
1519 add_init_array_defines(s1
, ".init_array");
1520 add_init_array_defines(s1
, ".fini_array");
1521 /* add start and stop symbols for sections whose name can be
1523 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1524 s
= s1
->sections
[i
];
1525 if ((s
->sh_flags
& SHF_ALLOC
)
1526 && (s
->sh_type
== SHT_PROGBITS
1527 || s
->sh_type
== SHT_STRTAB
)) {
1529 /* check if section name can be expressed in C */
1535 if (!isid(c
) && !isnum(c
))
1539 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1540 set_global_sym(s1
, buf
, s
, 0);
1541 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1542 set_global_sym(s1
, buf
, s
, -1);
1548 ST_FUNC
void resolve_common_syms(TCCState
*s1
)
1552 /* Allocate common symbols in BSS. */
1553 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1554 if (sym
->st_shndx
== SHN_COMMON
) {
1555 /* symbol alignment is in st_value for SHN_COMMONs */
1556 sym
->st_value
= section_add(bss_section
, sym
->st_size
,
1558 sym
->st_shndx
= bss_section
->sh_num
;
1562 /* Now assign linker provided symbols their value. */
1563 tcc_add_linker_symbols(s1
);
1566 #ifndef ELF_OBJ_ONLY
1568 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1570 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1571 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1572 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1573 unsigned offset
= attr
->got_offset
;
1577 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1579 write64le(s1
->got
->data
+ offset
, sym
->st_value
);
1581 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1585 /* Perform relocation to GOT or PLT entries */
1586 ST_FUNC
void fill_got(TCCState
*s1
)
1592 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1593 s
= s1
->sections
[i
];
1594 if (s
->sh_type
!= SHT_RELX
)
1596 /* no need to handle got relocations */
1597 if (s
->link
!= symtab_section
)
1599 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1600 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1601 case R_X86_64_GOT32
:
1602 case R_X86_64_GOTPCREL
:
1603 case R_X86_64_GOTPCRELX
:
1604 case R_X86_64_REX_GOTPCRELX
:
1605 case R_X86_64_PLT32
:
1606 fill_got_entry(s1
, rel
);
1613 /* See put_got_entry for a description. This is the second stage
1614 where GOT references to local defined symbols are rewritten. */
1615 static void fill_local_got_entries(TCCState
*s1
)
1618 if (!s1
->got
->reloc
)
1620 for_each_elem(s1
->got
->reloc
, 0, rel
, ElfW_Rel
) {
1621 if (ELFW(R_TYPE
)(rel
->r_info
) == R_RELATIVE
) {
1622 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1623 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1624 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1625 unsigned offset
= attr
->got_offset
;
1626 if (offset
!= rel
->r_offset
- s1
->got
->sh_addr
)
1627 tcc_error_noabort("huh");
1628 rel
->r_info
= ELFW(R_INFO
)(0, R_RELATIVE
);
1629 #if SHT_RELX == SHT_RELA
1630 rel
->r_addend
= sym
->st_value
;
1632 /* All our REL architectures also happen to be 32bit LE. */
1633 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1639 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1640 in shared libraries and export non local defined symbols to shared libraries
1641 if -rdynamic switch was given on command line */
1642 static void bind_exe_dynsyms(TCCState
*s1
)
1645 int sym_index
, index
;
1646 ElfW(Sym
) *sym
, *esym
;
1649 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1650 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1651 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1652 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1653 if (sym
->st_shndx
== SHN_UNDEF
) {
1654 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1655 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1657 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1658 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1659 if ((type
== STT_FUNC
) || (type
== STT_GNU_IFUNC
)) {
1660 /* Indirect functions shall have STT_FUNC type in executable
1661 * dynsym section. Indeed, a dlsym call following a lazy
1662 * resolution would pick the symbol value from the
1663 * executable dynsym entry which would contain the address
1664 * of the function wanted by the caller of dlsym instead of
1665 * the address of the function that would return that
1668 = put_elf_sym(s1
->dynsym
, 0, esym
->st_size
,
1669 ELFW(ST_INFO
)(STB_GLOBAL
,STT_FUNC
), 0, 0,
1671 int index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1672 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1673 } else if (type
== STT_OBJECT
) {
1674 unsigned long offset
;
1676 offset
= bss_section
->data_offset
;
1677 /* XXX: which alignment ? */
1678 offset
= (offset
+ 16 - 1) & -16;
1679 set_elf_sym (s1
->symtab
, offset
, esym
->st_size
,
1680 esym
->st_info
, 0, bss_section
->sh_num
, name
);
1681 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1682 esym
->st_info
, 0, bss_section
->sh_num
,
1685 /* Ensure R_COPY works for weak symbol aliases */
1686 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1687 for_each_elem(s1
->dynsymtab_section
, 1, dynsym
, ElfW(Sym
)) {
1688 if ((dynsym
->st_value
== esym
->st_value
)
1689 && (ELFW(ST_BIND
)(dynsym
->st_info
) == STB_GLOBAL
)) {
1690 char *dynname
= (char *) s1
->dynsymtab_section
->link
->data
1692 put_elf_sym(s1
->dynsym
, offset
, dynsym
->st_size
,
1694 bss_section
->sh_num
, dynname
);
1700 put_elf_reloc(s1
->dynsym
, bss_section
,
1701 offset
, R_COPY
, index
);
1702 offset
+= esym
->st_size
;
1703 bss_section
->data_offset
= offset
;
1706 /* STB_WEAK undefined symbols are accepted */
1707 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1708 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1709 !strcmp(name
, "_fp_hw")) {
1711 tcc_error_noabort("undefined symbol '%s'", name
);
1714 } else if (s1
->rdynamic
&& ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1715 /* if -rdynamic option, then export all non local symbols */
1716 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1717 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
1718 0, sym
->st_shndx
, name
);
1723 /* Bind symbols of libraries: export all non local symbols of executable that
1724 are referenced by shared libraries. The reason is that the dynamic loader
1725 search symbol first in executable and then in libraries. Therefore a
1726 reference to a symbol already defined by a library can still be resolved by
1727 a symbol in the executable. */
1728 static void bind_libs_dynsyms(TCCState
*s1
)
1732 ElfW(Sym
) *sym
, *esym
;
1734 for_each_elem(s1
->dynsymtab_section
, 1, esym
, ElfW(Sym
)) {
1735 name
= (char *) s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1736 sym_index
= find_elf_sym(symtab_section
, name
);
1737 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1738 if (sym_index
&& sym
->st_shndx
!= SHN_UNDEF
1739 && ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1740 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1741 sym
->st_info
, 0, sym
->st_shndx
, name
);
1742 } else if (esym
->st_shndx
== SHN_UNDEF
) {
1743 /* weak symbols can stay undefined */
1744 if (ELFW(ST_BIND
)(esym
->st_info
) != STB_WEAK
)
1745 tcc_warning("undefined dynamic symbol '%s'", name
);
1750 /* Export all non local symbols. This is used by shared libraries so that the
1751 non local symbols they define can resolve a reference in another shared
1752 library or in the executable. Correspondingly, it allows undefined local
1753 symbols to be resolved by other shared libraries or by the executable. */
1754 static void export_global_syms(TCCState
*s1
)
1756 int dynindex
, index
;
1760 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1761 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1762 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1763 dynindex
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1764 sym
->st_info
, 0, sym
->st_shndx
, name
);
1765 index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1766 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1771 /* decide if an unallocated section should be output. */
1772 static int set_sec_sizes(TCCState
*s1
)
1777 int file_type
= s1
->output_type
;
1779 /* Allocate strings for section names */
1780 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1781 s
= s1
->sections
[i
];
1782 if (s
->sh_type
== SHT_RELX
&& !(s
->sh_flags
& SHF_ALLOC
)) {
1783 /* when generating a DLL, we include relocations but
1784 we may patch them */
1785 if (file_type
== TCC_OUTPUT_DLL
1786 && (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)) {
1787 int count
= prepare_dynamic_rel(s1
, s
);
1789 /* allocate the section */
1790 s
->sh_flags
|= SHF_ALLOC
;
1791 s
->sh_size
= count
* sizeof(ElfW_Rel
);
1792 if (!(s1
->sections
[s
->sh_info
]->sh_flags
& SHF_WRITE
))
1796 } else if ((s
->sh_flags
& SHF_ALLOC
)
1797 #ifdef TCC_TARGET_ARM
1798 || s
->sh_type
== SHT_ARM_ATTRIBUTES
1801 s
->sh_size
= s
->data_offset
;
1804 #ifdef TCC_TARGET_ARM
1805 /* XXX: Suppress stack unwinding section. */
1806 if (s
->sh_type
== SHT_ARM_EXIDX
) {
1817 /* Info to be copied in dynamic section */
1821 unsigned long data_offset
;
1826 /* Info for GNU_RELRO */
1833 static void alloc_sec_names(
1834 TCCState
*s1
, int is_obj
1837 static int layout_any_sections(
1838 TCCState
*s1
, int file_offset
, int *sec_order
, int is_obj
1841 /* Assign sections to segments and decide how are sections laid out when loaded
1842 in memory. This function also fills corresponding program headers. */
1843 static int layout_sections(TCCState
*s1
, ElfW(Phdr
) *phdr
,
1844 int phnum
, int phfill
,
1846 struct ro_inf
*roinf
, int *sec_order
)
1852 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
1853 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1856 unsigned long s_align
;
1860 int j
, k
, f
, file_type
= s1
->output_type
;
1862 s_align
= ELF_PAGE_SIZE
;
1863 if (s1
->section_align
)
1864 s_align
= s1
->section_align
;
1866 if (s1
->has_text_addr
) {
1867 int a_offset
, p_offset
;
1868 addr
= s1
->text_addr
;
1869 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1871 a_offset
= (int) (addr
& (s_align
- 1));
1872 p_offset
= file_offset
& (s_align
- 1);
1873 if (a_offset
< p_offset
)
1874 a_offset
+= s_align
;
1875 file_offset
+= (a_offset
- p_offset
);
1877 if (file_type
== TCC_OUTPUT_DLL
)
1880 addr
= ELF_START_ADDR
;
1881 /* compute address after headers */
1882 addr
+= (file_offset
& (s_align
- 1));
1886 /* Leave one program headers for the program interpreter and one for
1887 the program header table itself if needed. These are done later as
1888 they require section layout to be done first. */
1892 /* read only segment mapping for GNU_RELRO */
1893 roinf
->sh_offset
= roinf
->sh_addr
= roinf
->sh_size
= 0;
1895 for(j
= 0; j
< phfill
; j
++) {
1896 Section
*relocplt
= s1
->got
? s1
->got
->relocplt
: NULL
;
1898 ph
->p_type
= j
== 2 ? PT_TLS
: PT_LOAD
;
1900 ph
->p_flags
= PF_R
| PF_X
;
1902 ph
->p_flags
= PF_R
| PF_W
;
1903 ph
->p_align
= j
== 2 ? 4 : s_align
;
1905 /* Decide the layout of sections loaded in memory. This must
1906 be done before program headers are filled since they contain
1907 info about the layout. We do the following ordering: interp,
1908 symbol tables, relocations, progbits, nobits */
1909 /* XXX: do faster and simpler sorting */
1911 for(k
= 0; k
< 7; k
++) {
1912 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1913 s
= s1
->sections
[i
];
1914 /* compute if section should be included */
1916 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
| SHF_TLS
)) !=
1919 } else if (j
== 1) {
1920 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
| SHF_TLS
)) !=
1921 (SHF_ALLOC
| SHF_WRITE
))
1924 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
| SHF_TLS
)) !=
1925 (SHF_ALLOC
| SHF_WRITE
| SHF_TLS
))
1931 } else if ((s
->sh_type
== SHT_DYNSYM
||
1932 s
->sh_type
== SHT_STRTAB
||
1933 s
->sh_type
== SHT_HASH
)
1934 && !strstr(s
->name
, ".stab")) {
1937 } else if (s
->sh_type
== SHT_RELX
) {
1938 if (k
!= 2 && s
!= relocplt
)
1940 else if (k
!= 3 && s
== relocplt
)
1942 } else if (s
->sh_type
== SHT_NOBITS
) {
1945 } else if (s
== data_ro_section
||
1946 #ifdef CONFIG_TCC_BCHECK
1947 s
== bounds_section
||
1948 s
== lbounds_section
||
1953 /* Align next section on page size.
1954 This is needed to remap roinf section ro. */
1962 /* section matches: we align it and add its size */
1965 s
->sh_addralign
= PAGESIZE
;
1966 addr
= (addr
+ s
->sh_addralign
- 1) &
1967 ~(s
->sh_addralign
- 1);
1968 file_offset
+= (int) ( addr
- tmp
);
1969 s
->sh_offset
= file_offset
;
1972 /* update program header infos */
1973 if (ph
->p_offset
== 0) {
1974 ph
->p_offset
= file_offset
;
1976 ph
->p_paddr
= ph
->p_vaddr
;
1978 if (s
== data_ro_section
||
1979 #ifdef CONFIG_TCC_BCHECK
1980 s
== bounds_section
||
1981 s
== lbounds_section
||
1984 if (roinf
->sh_size
== 0) {
1985 roinf
->sh_offset
= s
->sh_offset
;
1986 roinf
->sh_addr
= s
->sh_addr
;
1988 roinf
->sh_size
= (addr
- roinf
->sh_addr
) + s
->sh_size
;
1991 if (s
->sh_type
!= SHT_NOBITS
)
1992 file_offset
+= s
->sh_size
;
1996 /* Make the first PT_LOAD segment include the program
1997 headers itself (and the ELF header as well), it'll
1998 come out with same memory use but will make various
1999 tools like binutils strip work better. */
2000 ph
->p_offset
&= ~(ph
->p_align
- 1);
2001 ph
->p_vaddr
&= ~(ph
->p_align
- 1);
2002 ph
->p_paddr
&= ~(ph
->p_align
- 1);
2004 ph
->p_filesz
= file_offset
- ph
->p_offset
;
2005 ph
->p_memsz
= addr
- ph
->p_vaddr
;
2008 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
2009 /* if in the middle of a page, we duplicate the page in
2010 memory so that one copy is RX and the other is RW */
2011 if ((addr
& (s_align
- 1)) != 0)
2014 addr
= (addr
+ s_align
- 1) & ~(s_align
- 1);
2015 file_offset
= (file_offset
+ s_align
- 1) & ~(s_align
- 1);
2021 /* all other sections come after */
2022 return layout_any_sections(s1
, file_offset
, sec_order
, 0);
2025 /* put dynamic tag */
2026 static void put_dt(Section
*dynamic
, int dt
, addr_t val
)
2029 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
2031 dyn
->d_un
.d_val
= val
;
2034 static void fill_unloadable_phdr(ElfW(Phdr
) *phdr
, int phnum
, Section
*interp
,
2035 Section
*dynamic
, Section
*note
, struct ro_inf
*roinf
)
2039 /* if interpreter, then add corresponding program header */
2043 ph
->p_type
= PT_PHDR
;
2044 ph
->p_offset
= sizeof(ElfW(Ehdr
));
2045 ph
->p_filesz
= ph
->p_memsz
= phnum
* sizeof(ElfW(Phdr
));
2046 ph
->p_vaddr
= interp
->sh_addr
- ph
->p_filesz
;
2047 ph
->p_paddr
= ph
->p_vaddr
;
2048 ph
->p_flags
= PF_R
| PF_X
;
2049 ph
->p_align
= 4; /* interp->sh_addralign; */
2052 ph
->p_type
= PT_INTERP
;
2053 ph
->p_offset
= interp
->sh_offset
;
2054 ph
->p_vaddr
= interp
->sh_addr
;
2055 ph
->p_paddr
= ph
->p_vaddr
;
2056 ph
->p_filesz
= interp
->sh_size
;
2057 ph
->p_memsz
= interp
->sh_size
;
2059 ph
->p_align
= interp
->sh_addralign
;
2063 ph
= &phdr
[phnum
- 2 - (roinf
!= NULL
)];
2065 ph
->p_type
= PT_NOTE
;
2066 ph
->p_offset
= note
->sh_offset
;
2067 ph
->p_vaddr
= note
->sh_addr
;
2068 ph
->p_paddr
= ph
->p_vaddr
;
2069 ph
->p_filesz
= note
->sh_size
;
2070 ph
->p_memsz
= note
->sh_size
;
2072 ph
->p_align
= note
->sh_addralign
;
2075 /* if dynamic section, then add corresponding program header */
2077 ph
= &phdr
[phnum
- 1 - (roinf
!= NULL
)];
2079 ph
->p_type
= PT_DYNAMIC
;
2080 ph
->p_offset
= dynamic
->sh_offset
;
2081 ph
->p_vaddr
= dynamic
->sh_addr
;
2082 ph
->p_paddr
= ph
->p_vaddr
;
2083 ph
->p_filesz
= dynamic
->sh_size
;
2084 ph
->p_memsz
= dynamic
->sh_size
;
2085 ph
->p_flags
= PF_R
| PF_W
;
2086 ph
->p_align
= dynamic
->sh_addralign
;
2090 ph
= &phdr
[phnum
- 1];
2092 ph
->p_type
= PT_GNU_RELRO
;
2093 ph
->p_offset
= roinf
->sh_offset
;
2094 ph
->p_vaddr
= roinf
->sh_addr
;
2095 ph
->p_paddr
= ph
->p_vaddr
;
2096 ph
->p_filesz
= roinf
->sh_size
;
2097 ph
->p_memsz
= roinf
->sh_size
;
2103 /* Fill the dynamic section with tags describing the address and size of
2105 static void fill_dynamic(TCCState
*s1
, struct dyn_inf
*dyninf
)
2107 Section
*dynamic
= dyninf
->dynamic
;
2110 /* put dynamic section entries */
2111 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
2112 put_dt(dynamic
, DT_STRTAB
, dyninf
->dynstr
->sh_addr
);
2113 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
2114 put_dt(dynamic
, DT_STRSZ
, dyninf
->dynstr
->data_offset
);
2115 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
2117 put_dt(dynamic
, DT_RELA
, dyninf
->rel_addr
);
2118 put_dt(dynamic
, DT_RELASZ
, dyninf
->rel_size
);
2119 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
2120 if (s1
->got
&& s1
->got
->relocplt
) {
2121 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2122 put_dt(dynamic
, DT_PLTRELSZ
, s1
->got
->relocplt
->data_offset
);
2123 put_dt(dynamic
, DT_JMPREL
, s1
->got
->relocplt
->sh_addr
);
2124 put_dt(dynamic
, DT_PLTREL
, DT_RELA
);
2126 put_dt(dynamic
, DT_RELACOUNT
, 0);
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);
2139 if (versym_section
&& verneed_section
) {
2140 /* The dynamic linker can not handle VERSYM without VERNEED */
2141 put_dt(dynamic
, DT_VERSYM
, versym_section
->sh_addr
);
2142 put_dt(dynamic
, DT_VERNEED
, verneed_section
->sh_addr
);
2143 put_dt(dynamic
, DT_VERNEEDNUM
, dt_verneednum
);
2145 s
= find_section_create (s1
, ".preinit_array", 0);
2146 if (s
&& s
->data_offset
) {
2147 put_dt(dynamic
, DT_PREINIT_ARRAY
, s
->sh_addr
);
2148 put_dt(dynamic
, DT_PREINIT_ARRAYSZ
, s
->data_offset
);
2150 s
= find_section_create (s1
, ".init_array", 0);
2151 if (s
&& s
->data_offset
) {
2152 put_dt(dynamic
, DT_INIT_ARRAY
, s
->sh_addr
);
2153 put_dt(dynamic
, DT_INIT_ARRAYSZ
, s
->data_offset
);
2155 s
= find_section_create (s1
, ".fini_array", 0);
2156 if (s
&& s
->data_offset
) {
2157 put_dt(dynamic
, DT_FINI_ARRAY
, s
->sh_addr
);
2158 put_dt(dynamic
, DT_FINI_ARRAYSZ
, s
->data_offset
);
2160 s
= find_section_create (s1
, ".init", 0);
2161 if (s
&& s
->data_offset
) {
2162 put_dt(dynamic
, DT_INIT
, s
->sh_addr
);
2164 s
= find_section_create (s1
, ".fini", 0);
2165 if (s
&& s
->data_offset
) {
2166 put_dt(dynamic
, DT_FINI
, s
->sh_addr
);
2169 put_dt(dynamic
, DT_DEBUG
, 0);
2170 put_dt(dynamic
, DT_NULL
, 0);
2173 /* Relocate remaining sections and symbols (that is those not related to
2175 static int final_sections_reloc(TCCState
*s1
)
2180 relocate_syms(s1
, s1
->symtab
, 0);
2182 if (s1
->nb_errors
!= 0)
2185 /* relocate sections */
2186 /* XXX: ignore sections with allocated relocations ? */
2187 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2188 s
= s1
->sections
[i
];
2189 if (s
->reloc
&& (s
!= s1
->got
|| s1
->static_link
))
2190 relocate_section(s1
, s
);
2193 /* relocate relocation entries if the relocation tables are
2194 allocated in the executable */
2195 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2196 s
= s1
->sections
[i
];
2197 if ((s
->sh_flags
& SHF_ALLOC
) &&
2198 s
->sh_type
== SHT_RELX
) {
2199 relocate_rel(s1
, s
);
2205 /* Remove gaps between RELX sections.
2206 These gaps are a result of final_sections_reloc. Here some relocs are removed.
2207 The gaps are then filled with 0 in tcc_output_elf. The 0 is intepreted as
2208 R_...NONE reloc. This does work on most targets but on OpenBSD/arm64 this
2209 is illegal. OpenBSD/arm64 does not support R_...NONE reloc. */
2210 static void update_reloc_sections(TCCState
*s1
, struct dyn_inf
*dyninf
)
2213 unsigned long file_offset
= 0;
2215 Section
*relocplt
= s1
->got
? s1
->got
->relocplt
: NULL
;
2217 /* dynamic relocation table information, for .dynamic section */
2218 dyninf
->rel_addr
= dyninf
->rel_size
= 0;
2220 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2221 s
= s1
->sections
[i
];
2222 if (s
->sh_type
== SHT_RELX
&& s
!= relocplt
) {
2223 if (dyninf
->rel_size
== 0) {
2224 dyninf
->rel_addr
= s
->sh_addr
;
2225 file_offset
= s
->sh_offset
;
2228 s
->sh_addr
= dyninf
->rel_addr
+ dyninf
->rel_size
;
2229 s
->sh_offset
= file_offset
+ dyninf
->rel_size
;
2231 dyninf
->rel_size
+= s
->sh_size
;
2236 #endif /* ndef ELF_OBJ_ONLY */
2238 /* Create an ELF file on disk.
2239 This function handle ELF specific layout requirements */
2240 static void tcc_output_elf(TCCState
*s1
, FILE *f
, int phnum
, ElfW(Phdr
) *phdr
,
2241 int file_offset
, int *sec_order
)
2243 int i
, shnum
, offset
, size
, file_type
;
2246 ElfW(Shdr
) shdr
, *sh
;
2248 file_type
= s1
->output_type
;
2249 shnum
= s1
->nb_sections
;
2251 memset(&ehdr
, 0, sizeof(ehdr
));
2254 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2255 ehdr
.e_phnum
= phnum
;
2256 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2260 file_offset
= (file_offset
+ 3) & -4;
2263 ehdr
.e_ident
[0] = ELFMAG0
;
2264 ehdr
.e_ident
[1] = ELFMAG1
;
2265 ehdr
.e_ident
[2] = ELFMAG2
;
2266 ehdr
.e_ident
[3] = ELFMAG3
;
2267 ehdr
.e_ident
[4] = ELFCLASSW
;
2268 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2269 ehdr
.e_ident
[6] = EV_CURRENT
;
2270 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2271 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2273 #ifdef TCC_TARGET_ARM
2275 ehdr
.e_ident
[EI_OSABI
] = 0;
2276 ehdr
.e_flags
= EF_ARM_EABI_VER4
;
2277 if (file_type
== TCC_OUTPUT_EXE
|| file_type
== TCC_OUTPUT_DLL
)
2278 ehdr
.e_flags
|= EF_ARM_HASENTRY
;
2279 if (s1
->float_abi
== ARM_HARD_FLOAT
)
2280 ehdr
.e_flags
|= EF_ARM_VFP_FLOAT
;
2282 ehdr
.e_flags
|= EF_ARM_SOFT_FLOAT
;
2284 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2286 #elif defined TCC_TARGET_RISCV64
2287 ehdr
.e_flags
= EF_RISCV_FLOAT_ABI_DOUBLE
;
2291 case TCC_OUTPUT_EXE
:
2292 ehdr
.e_type
= ET_EXEC
;
2293 ehdr
.e_entry
= get_sym_addr(s1
, "_start", 1, 0);
2295 case TCC_OUTPUT_DLL
:
2296 ehdr
.e_type
= ET_DYN
;
2297 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
2299 case TCC_OUTPUT_OBJ
:
2300 ehdr
.e_type
= ET_REL
;
2303 ehdr
.e_machine
= EM_TCC_TARGET
;
2304 ehdr
.e_version
= EV_CURRENT
;
2305 ehdr
.e_shoff
= file_offset
;
2306 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2307 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2308 ehdr
.e_shnum
= shnum
;
2309 ehdr
.e_shstrndx
= shnum
- 1;
2311 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2312 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2313 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2315 sort_syms(s1
, symtab_section
);
2316 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2317 s
= s1
->sections
[sec_order
[i
]];
2318 if (s
->sh_type
!= SHT_NOBITS
) {
2319 while (offset
< s
->sh_offset
) {
2325 fwrite(s
->data
, 1, size
, f
);
2330 /* output section headers */
2331 while (offset
< ehdr
.e_shoff
) {
2336 for(i
= 0; i
< s1
->nb_sections
; i
++) {
2338 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2339 s
= s1
->sections
[i
];
2341 sh
->sh_name
= s
->sh_name
;
2342 sh
->sh_type
= s
->sh_type
;
2343 sh
->sh_flags
= s
->sh_flags
;
2344 sh
->sh_entsize
= s
->sh_entsize
;
2345 sh
->sh_info
= s
->sh_info
;
2347 sh
->sh_link
= s
->link
->sh_num
;
2348 sh
->sh_addralign
= s
->sh_addralign
;
2349 sh
->sh_addr
= s
->sh_addr
;
2350 sh
->sh_offset
= s
->sh_offset
;
2351 sh
->sh_size
= s
->sh_size
;
2353 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2357 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
2358 const int *sec_order
)
2361 int i
, offset
, size
;
2364 for(i
=1;i
<s1
->nb_sections
;i
++) {
2365 s
= s1
->sections
[sec_order
[i
]];
2366 if (s
->sh_type
!= SHT_NOBITS
&&
2367 (s
->sh_flags
& SHF_ALLOC
)) {
2368 while (offset
< s
->sh_offset
) {
2373 fwrite(s
->data
, 1, size
, f
);
2379 /* Write an elf, coff or "binary" file */
2380 static int tcc_write_elf_file(TCCState
*s1
, const char *filename
, int phnum
,
2381 ElfW(Phdr
) *phdr
, int file_offset
, int *sec_order
)
2383 int fd
, mode
, file_type
;
2386 file_type
= s1
->output_type
;
2387 if (file_type
== TCC_OUTPUT_OBJ
)
2392 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2394 tcc_error_noabort("could not write '%s'", filename
);
2397 f
= fdopen(fd
, "wb");
2399 printf("<- %s\n", filename
);
2401 #ifdef TCC_TARGET_COFF
2402 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
)
2403 tcc_output_coff(s1
, f
);
2406 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2407 tcc_output_elf(s1
, f
, phnum
, phdr
, file_offset
, sec_order
);
2409 tcc_output_binary(s1
, f
, sec_order
);
2415 #ifndef ELF_OBJ_ONLY
2416 /* Sort section headers by assigned sh_addr, remove sections
2417 that we aren't going to output. */
2418 static void tidy_section_headers(TCCState
*s1
, int *sec_order
)
2420 int i
, nnew
, l
, *backmap
;
2424 snew
= tcc_malloc(s1
->nb_sections
* sizeof(snew
[0]));
2425 backmap
= tcc_malloc(s1
->nb_sections
* sizeof(backmap
[0]));
2426 for (i
= 0, nnew
= 0, l
= s1
->nb_sections
; i
< s1
->nb_sections
; i
++) {
2427 s
= s1
->sections
[sec_order
[i
]];
2428 if (!i
|| s
->sh_name
) {
2429 backmap
[sec_order
[i
]] = nnew
;
2433 backmap
[sec_order
[i
]] = 0;
2437 for (i
= 0; i
< nnew
; i
++) {
2441 if (s
->sh_type
== SHT_RELX
)
2442 s
->sh_info
= backmap
[s
->sh_info
];
2446 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
))
2447 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2448 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2449 if ( !s1
->static_link
) {
2450 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
))
2451 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2452 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2454 for (i
= 0; i
< s1
->nb_sections
; i
++)
2456 tcc_free(s1
->sections
);
2457 s1
->sections
= snew
;
2458 s1
->nb_sections
= nnew
;
2462 #ifdef TCC_TARGET_ARM
2463 static void create_arm_attribute_section(TCCState
*s1
)
2465 // Needed for DLL support.
2466 static const unsigned char arm_attr
[] = {
2468 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2469 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2470 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2471 0x05, 0x36, 0x00, // 'CPU_name', "6"
2472 0x06, 0x06, // 'CPU_arch', 'v6'
2473 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2474 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2475 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2476 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2477 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2478 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2479 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2480 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2481 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2482 0x1a, 0x02, // 'ABI_enum_size', 'int'
2483 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2484 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2486 Section
*attr
= new_section(s1
, ".ARM.attributes", SHT_ARM_ATTRIBUTES
, 0);
2487 unsigned char *ptr
= section_ptr_add(attr
, sizeof(arm_attr
));
2488 attr
->sh_addralign
= 1;
2489 memcpy(ptr
, arm_attr
, sizeof(arm_attr
));
2490 if (s1
->float_abi
!= ARM_HARD_FLOAT
) {
2491 ptr
[26] = 0x00; // 'FP_arch', 'No'
2492 ptr
[41] = 0x1e; // 'ABI_optimization_goals'
2493 ptr
[42] = 0x06; // 'Aggressive Debug'
2498 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2499 static Section
*create_bsd_note_section(TCCState
*s1
,
2503 Section
*s
= find_section (s1
, name
);
2505 if (s
->data_offset
== 0) {
2506 char *ptr
= section_ptr_add(s
, sizeof(ElfW(Nhdr
)) + 8 + 4);
2507 ElfW(Nhdr
) *note
= (ElfW(Nhdr
) *) ptr
;
2509 s
->sh_type
= SHT_NOTE
;
2512 note
->n_type
= ELF_NOTE_OS_GNU
;
2513 strcpy (ptr
+ sizeof(ElfW(Nhdr
)), value
);
2519 /* Output an elf, coff or binary file */
2520 /* XXX: suppress unneeded sections */
2521 static int elf_output_file(TCCState
*s1
, const char *filename
)
2523 int i
, ret
, phnum
, phfill
, shnum
, file_type
, file_offset
, *sec_order
;
2524 struct dyn_inf dyninf
= {0};
2525 struct ro_inf roinf
;
2527 Section
*interp
, *dynamic
, *dynstr
, *note
;
2528 struct ro_inf
*roinf_use
= NULL
;
2531 file_type
= s1
->output_type
;
2536 interp
= dynamic
= dynstr
= note
= NULL
;
2538 #ifdef TCC_TARGET_ARM
2539 create_arm_attribute_section (s1
);
2542 #if TARGETOS_OpenBSD
2543 note
= create_bsd_note_section (s1
, ".note.openbsd.ident", "OpenBSD");
2547 note
= create_bsd_note_section (s1
, ".note.netbsd.ident", "NetBSD");
2551 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2552 tcc_add_runtime(s1
);
2553 resolve_common_syms(s1
);
2555 if (!s1
->static_link
) {
2556 if (file_type
== TCC_OUTPUT_EXE
) {
2558 /* allow override the dynamic loader */
2559 const char *elfint
= getenv("LD_SO");
2561 elfint
= DEFAULT_ELFINTERP(s1
);
2562 /* add interpreter section only if executable */
2563 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
2564 interp
->sh_addralign
= 1;
2565 ptr
= section_ptr_add(interp
, 1 + strlen(elfint
));
2566 strcpy(ptr
, elfint
);
2569 /* add dynamic symbol table */
2570 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
2572 ".hash", SHF_ALLOC
);
2573 /* Number of local symbols (readelf complains if not set) */
2574 s1
->dynsym
->sh_info
= 1;
2575 dynstr
= s1
->dynsym
->link
;
2576 /* add dynamic section */
2577 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
2578 SHF_ALLOC
| SHF_WRITE
);
2579 dynamic
->link
= dynstr
;
2580 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
2584 if (file_type
== TCC_OUTPUT_EXE
) {
2585 bind_exe_dynsyms(s1
);
2588 bind_libs_dynsyms(s1
);
2590 /* shared library case: simply export all global symbols */
2591 export_global_syms(s1
);
2594 build_got_entries(s1
);
2598 textrel
= set_sec_sizes(s1
);
2599 alloc_sec_names(s1
, 0);
2601 if (!s1
->static_link
) {
2603 /* add a list of needed dlls */
2604 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2605 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
2606 if (dllref
->level
== 0)
2607 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
2611 put_dt(dynamic
, s1
->enable_new_dtags
? DT_RUNPATH
: DT_RPATH
,
2612 put_elf_str(dynstr
, s1
->rpath
));
2614 if (file_type
== TCC_OUTPUT_DLL
) {
2616 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
2617 /* XXX: currently, since we do not handle PIC code, we
2618 must relocate the readonly segments */
2620 put_dt(dynamic
, DT_TEXTREL
, 0);
2624 put_dt(dynamic
, DT_SYMBOLIC
, 0);
2626 dyninf
.dynamic
= dynamic
;
2627 dyninf
.dynstr
= dynstr
;
2628 /* remember offset and reserve space for 2nd call below */
2629 dyninf
.data_offset
= dynamic
->data_offset
;
2630 fill_dynamic(s1
, &dyninf
);
2631 dynamic
->sh_size
= dynamic
->data_offset
;
2632 dynstr
->sh_size
= dynstr
->data_offset
;
2635 for (i
= 1; i
< s1
->nb_sections
&&
2636 !(s1
->sections
[i
]->sh_flags
& SHF_TLS
); i
++);
2637 phfill
= 2 + (i
< s1
->nb_sections
);
2639 /* compute number of program headers */
2640 if (file_type
== TCC_OUTPUT_DLL
)
2642 else if (s1
->static_link
)
2645 phnum
= 5 + (i
< s1
->nb_sections
);
2648 phnum
+= note
!= NULL
;
2649 #if !TARGETOS_FreeBSD && !TARGETOS_NetBSD
2651 phnum
++, roinf_use
= &roinf
;
2654 /* allocate program segment headers */
2655 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
2656 /* compute number of sections */
2657 shnum
= s1
->nb_sections
;
2658 /* this array is used to reorder sections in the output file */
2659 sec_order
= tcc_malloc(sizeof(int) * shnum
);
2662 /* compute section to program header mapping */
2663 file_offset
= layout_sections(s1
, phdr
, phnum
, phfill
, interp
, &roinf
, sec_order
+ 1);
2665 /* Fill remaining program header and finalize relocation related to dynamic
2668 fill_unloadable_phdr(phdr
, phnum
, interp
, dynamic
, note
, roinf_use
);
2672 /* put in GOT the dynamic section address and relocate PLT */
2673 write32le(s1
->got
->data
, dynamic
->sh_addr
);
2674 if (file_type
== TCC_OUTPUT_EXE
2675 || (RELOCATE_DLLPLT
&& file_type
== TCC_OUTPUT_DLL
))
2678 /* relocate symbols in .dynsym now that final addresses are known */
2679 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
)) {
2680 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
) {
2681 /* do symbol relocation */
2682 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
2687 /* if building executable or DLL, then relocate each section
2688 except the GOT which is already relocated */
2689 ret
= final_sections_reloc(s1
);
2693 update_reloc_sections (s1
, &dyninf
);
2694 dynamic
->data_offset
= dyninf
.data_offset
;
2695 fill_dynamic(s1
, &dyninf
);
2697 tidy_section_headers(s1
, sec_order
);
2699 /* Perform relocation to GOT or PLT entries */
2700 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2703 fill_local_got_entries(s1
);
2705 /* Create the ELF file with name 'filename' */
2706 ret
= tcc_write_elf_file(s1
, filename
, phnum
, phdr
, file_offset
, sec_order
);
2707 s1
->nb_sections
= shnum
;
2710 tcc_free(sec_order
);
2714 #endif /* ndef ELF_OBJ_ONLY */
2716 /* Allocate strings for section names */
2717 static void alloc_sec_names(TCCState
*s1
, int is_obj
)
2720 Section
*s
, *strsec
;
2722 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
2723 put_elf_str(strsec
, "");
2724 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2725 s
= s1
->sections
[i
];
2727 s
->sh_size
= s
->data_offset
;
2728 if (s
== strsec
|| s
->sh_size
|| (s
->sh_flags
& SHF_ALLOC
))
2729 s
->sh_name
= put_elf_str(strsec
, s
->name
);
2731 strsec
->sh_size
= strsec
->data_offset
;
2734 static int layout_any_sections(TCCState
*s1
, int file_offset
, int *sec_order
, int is_obj
)
2738 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2739 s
= s1
->sections
[i
];
2740 if (!is_obj
&& (s
->sh_flags
& SHF_ALLOC
))
2743 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
2744 ~(s
->sh_addralign
- 1);
2745 s
->sh_offset
= file_offset
;
2746 if (s
->sh_type
!= SHT_NOBITS
)
2747 file_offset
+= s
->sh_size
;
2752 /* Output an elf .o file */
2753 static int elf_output_obj(TCCState
*s1
, const char *filename
)
2755 int ret
, file_offset
;
2759 /* Allocate strings for section names */
2760 alloc_sec_names(s1
, 1);
2762 /* this array is used to reorder sections in the output file */
2763 sec_order
= tcc_malloc(sizeof(int) * s1
->nb_sections
);
2765 file_offset
= layout_any_sections(s1
, sizeof (ElfW(Ehdr
)), sec_order
+ 1, 1);
2767 /* Create the ELF file with name 'filename' */
2768 ret
= tcc_write_elf_file(s1
, filename
, 0, NULL
, file_offset
, sec_order
);
2769 tcc_free(sec_order
);
2773 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2775 if (s
->output_type
== TCC_OUTPUT_OBJ
)
2776 return elf_output_obj(s
, filename
);
2777 #ifdef TCC_TARGET_PE
2778 return pe_output_file(s
, filename
);
2779 #elif TCC_TARGET_MACHO
2780 return macho_output_file(s
, filename
);
2782 return elf_output_file(s
, filename
);
2786 ST_FUNC ssize_t
full_read(int fd
, void *buf
, size_t count
) {
2790 ssize_t num
= read(fd
, cbuf
, count
-rnum
);
2791 if (num
< 0) return num
;
2792 if (num
== 0) return rnum
;
2798 ST_FUNC
void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2802 data
= tcc_malloc(size
);
2803 lseek(fd
, file_offset
, SEEK_SET
);
2804 full_read(fd
, data
, size
);
2808 typedef struct SectionMergeInfo
{
2809 Section
*s
; /* corresponding existing section */
2810 unsigned long offset
; /* offset of the new section in the existing section */
2811 uint8_t new_section
; /* true if section 's' was added */
2812 uint8_t link_once
; /* true if link once section */
2815 ST_FUNC
int tcc_object_type(int fd
, ElfW(Ehdr
) *h
)
2817 int size
= full_read(fd
, h
, sizeof *h
);
2818 if (size
== sizeof *h
&& 0 == memcmp(h
, ELFMAG
, 4)) {
2819 if (h
->e_type
== ET_REL
)
2820 return AFF_BINTYPE_REL
;
2821 if (h
->e_type
== ET_DYN
)
2822 return AFF_BINTYPE_DYN
;
2823 } else if (size
>= 8) {
2824 if (0 == memcmp(h
, ARMAG
, 8))
2825 return AFF_BINTYPE_AR
;
2826 #ifdef TCC_TARGET_COFF
2827 if (((struct filehdr
*)h
)->f_magic
== COFF_C67_MAGIC
)
2828 return AFF_BINTYPE_C67
;
2834 /* load an object file and merge it with current files */
2835 /* XXX: handle correctly stab (debug) info */
2836 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
2837 int fd
, unsigned long file_offset
)
2840 ElfW(Shdr
) *shdr
, *sh
;
2841 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
, seencompressed
;
2842 char *strsec
, *strtab
;
2843 int stab_index
, stabstr_index
;
2844 int *old_to_new_syms
;
2845 char *sh_name
, *name
;
2846 SectionMergeInfo
*sm_table
, *sm
;
2847 ElfW(Sym
) *sym
, *symtab
;
2851 lseek(fd
, file_offset
, SEEK_SET
);
2852 if (tcc_object_type(fd
, &ehdr
) != AFF_BINTYPE_REL
)
2854 /* test CPU specific stuff */
2855 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2856 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2858 tcc_error_noabort("invalid object file");
2862 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2863 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2864 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2866 /* load section names */
2867 sh
= &shdr
[ehdr
.e_shstrndx
];
2868 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2870 /* load symtab and strtab */
2871 old_to_new_syms
= NULL
;
2876 stab_index
= stabstr_index
= 0;
2878 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2880 if (sh
->sh_type
== SHT_SYMTAB
) {
2882 tcc_error_noabort("object must contain only one symtab");
2887 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2888 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2889 sm_table
[i
].s
= symtab_section
;
2891 /* now load strtab */
2892 sh
= &shdr
[sh
->sh_link
];
2893 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2895 if (sh
->sh_flags
& SHF_COMPRESSED
)
2899 /* now examine each section and try to merge its content with the
2901 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2902 /* no need to examine section name strtab */
2903 if (i
== ehdr
.e_shstrndx
)
2906 if (sh
->sh_type
== SHT_RELX
)
2907 sh
= &shdr
[sh
->sh_info
];
2908 /* ignore sections types we do not handle (plus relocs to those) */
2909 if (sh
->sh_type
!= SHT_PROGBITS
&&
2911 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2913 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2914 sh
->sh_type
!= SHT_X86_64_UNWIND
&&
2916 sh
->sh_type
!= SHT_NOTE
&&
2917 sh
->sh_type
!= SHT_NOBITS
&&
2918 sh
->sh_type
!= SHT_PREINIT_ARRAY
&&
2919 sh
->sh_type
!= SHT_INIT_ARRAY
&&
2920 sh
->sh_type
!= SHT_FINI_ARRAY
&&
2921 strcmp(strsec
+ sh
->sh_name
, ".stabstr")
2925 && !strncmp(strsec
+ sh
->sh_name
, ".debug_", sizeof(".debug_")-1))
2929 sh_name
= strsec
+ sh
->sh_name
;
2930 if (sh
->sh_addralign
< 1)
2931 sh
->sh_addralign
= 1;
2932 /* find corresponding section, if any */
2933 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2934 s
= s1
->sections
[j
];
2935 if (!strcmp(s
->name
, sh_name
)) {
2936 if (!strncmp(sh_name
, ".gnu.linkonce",
2937 sizeof(".gnu.linkonce") - 1)) {
2938 /* if a 'linkonce' section is already present, we
2939 do not add it again. It is a little tricky as
2940 symbols can still be defined in
2942 sm_table
[i
].link_once
= 1;
2946 if (s
== stab_section
)
2948 if (s
== stab_section
->link
)
2954 /* not found: create new section */
2955 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
& ~SHF_GROUP
);
2956 /* take as much info as possible from the section. sh_link and
2957 sh_info will be updated later */
2958 s
->sh_addralign
= sh
->sh_addralign
;
2959 s
->sh_entsize
= sh
->sh_entsize
;
2960 sm_table
[i
].new_section
= 1;
2962 if (sh
->sh_type
!= s
->sh_type
) {
2963 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2964 if (strcmp (s
->name
, ".eh_frame"))
2967 tcc_error_noabort("invalid section type");
2971 /* align start of section */
2972 s
->data_offset
+= -s
->data_offset
& (sh
->sh_addralign
- 1);
2973 if (sh
->sh_addralign
> s
->sh_addralign
)
2974 s
->sh_addralign
= sh
->sh_addralign
;
2975 sm_table
[i
].offset
= s
->data_offset
;
2977 /* concatenate sections */
2979 if (sh
->sh_type
!= SHT_NOBITS
) {
2981 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2982 ptr
= section_ptr_add(s
, size
);
2983 full_read(fd
, ptr
, size
);
2985 s
->data_offset
+= size
;
2990 /* gr relocate stab strings */
2991 if (stab_index
&& stabstr_index
) {
2994 s
= sm_table
[stab_index
].s
;
2995 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2996 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2997 o
= sm_table
[stabstr_index
].offset
;
3005 /* second short pass to update sh_link and sh_info fields of new
3007 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3009 if (!s
|| !sm_table
[i
].new_section
)
3012 if (sh
->sh_link
> 0)
3013 s
->link
= sm_table
[sh
->sh_link
].s
;
3014 if (sh
->sh_type
== SHT_RELX
) {
3015 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
3016 /* update backward link */
3017 s1
->sections
[s
->sh_info
]->reloc
= s
;
3021 /* resolve symbols */
3022 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
3025 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
3026 if (sym
->st_shndx
!= SHN_UNDEF
&&
3027 sym
->st_shndx
< SHN_LORESERVE
) {
3028 sm
= &sm_table
[sym
->st_shndx
];
3029 if (sm
->link_once
) {
3030 /* if a symbol is in a link once section, we use the
3031 already defined symbol. It is very important to get
3032 correct relocations */
3033 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
3034 name
= strtab
+ sym
->st_name
;
3035 sym_index
= find_elf_sym(symtab_section
, name
);
3037 old_to_new_syms
[i
] = sym_index
;
3041 /* if no corresponding section added, no need to add symbol */
3044 /* convert section number */
3045 sym
->st_shndx
= sm
->s
->sh_num
;
3047 sym
->st_value
+= sm
->offset
;
3050 name
= strtab
+ sym
->st_name
;
3051 sym_index
= set_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
3052 sym
->st_info
, sym
->st_other
,
3053 sym
->st_shndx
, name
);
3054 old_to_new_syms
[i
] = sym_index
;
3057 /* third pass to patch relocation entries */
3058 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3063 offset
= sm_table
[i
].offset
;
3065 switch(s
->sh_type
) {
3067 /* take relocation offset information */
3068 offseti
= sm_table
[sh
->sh_info
].offset
;
3069 for (rel
= (ElfW_Rel
*) s
->data
+ (offset
/ sizeof(*rel
));
3070 rel
< (ElfW_Rel
*) s
->data
+ ((offset
+ size
) / sizeof(*rel
));
3074 /* convert symbol index */
3075 type
= ELFW(R_TYPE
)(rel
->r_info
);
3076 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
3077 /* NOTE: only one symtab assumed */
3078 if (sym_index
>= nb_syms
)
3080 sym_index
= old_to_new_syms
[sym_index
];
3081 /* ignore link_once in rel section. */
3082 if (!sym_index
&& !sm_table
[sh
->sh_info
].link_once
3083 #ifdef TCC_TARGET_ARM
3084 && type
!= R_ARM_V4BX
3085 #elif defined TCC_TARGET_RISCV64
3086 && type
!= R_RISCV_ALIGN
3087 && type
!= R_RISCV_RELAX
3091 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3092 i
, strsec
+ sh
->sh_name
, (int)rel
->r_offset
);
3095 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
3096 /* offset the relocation offset */
3097 rel
->r_offset
+= offseti
;
3098 #ifdef TCC_TARGET_ARM
3099 /* Jumps and branches from a Thumb code to a PLT entry need
3100 special handling since PLT entries are ARM code.
3101 Unconditional bl instructions referencing PLT entries are
3102 handled by converting these instructions into blx
3103 instructions. Other case of instructions referencing a PLT
3104 entry require to add a Thumb stub before the PLT entry to
3105 switch to ARM mode. We set bit plt_thumb_stub of the
3106 attribute of a symbol to indicate such a case. */
3107 if (type
== R_ARM_THM_JUMP24
)
3108 get_sym_attr(s1
, sym_index
, 1)->plt_thumb_stub
= 1;
3121 tcc_free(old_to_new_syms
);
3128 typedef struct ArchiveHeader
{
3129 char ar_name
[16]; /* name of this member */
3130 char ar_date
[12]; /* file mtime */
3131 char ar_uid
[6]; /* owner uid; printed as decimal */
3132 char ar_gid
[6]; /* owner gid; printed as decimal */
3133 char ar_mode
[8]; /* file mode, printed as octal */
3134 char ar_size
[10]; /* file size, printed as decimal */
3135 char ar_fmag
[2]; /* should contain ARFMAG */
3138 #define ARFMAG "`\n"
3140 static unsigned long long get_be(const uint8_t *b
, int n
)
3142 unsigned long long ret
= 0;
3144 ret
= (ret
<< 8) | *b
++, --n
;
3148 static int read_ar_header(int fd
, int offset
, ArchiveHeader
*hdr
)
3152 lseek(fd
, offset
, SEEK_SET
);
3153 len
= full_read(fd
, hdr
, sizeof(ArchiveHeader
));
3154 if (len
!= sizeof(ArchiveHeader
))
3155 return len
? -1 : 0;
3157 for (e
= p
+ sizeof hdr
->ar_name
; e
> p
&& e
[-1] == ' ';)
3160 hdr
->ar_size
[sizeof hdr
->ar_size
-1] = 0;
3164 /* load only the objects which resolve undefined symbols */
3165 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
, int entrysize
)
3167 int i
, bound
, nsyms
, sym_index
, len
, ret
= -1;
3168 unsigned long long off
;
3170 const char *ar_names
, *p
;
3171 const uint8_t *ar_index
;
3175 data
= tcc_malloc(size
);
3176 if (full_read(fd
, data
, size
) != size
)
3178 nsyms
= get_be(data
, entrysize
);
3179 ar_index
= data
+ entrysize
;
3180 ar_names
= (char *) ar_index
+ nsyms
* entrysize
;
3184 for (p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
3185 Section
*s
= symtab_section
;
3186 sym_index
= find_elf_sym(s
, p
);
3189 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
3190 if(sym
->st_shndx
!= SHN_UNDEF
)
3192 off
= get_be(ar_index
+ i
* entrysize
, entrysize
);
3193 len
= read_ar_header(fd
, off
, &hdr
);
3194 if (len
<= 0 || memcmp(hdr
.ar_fmag
, ARFMAG
, 2)) {
3195 tcc_error_noabort("invalid archive");
3199 if (s1
->verbose
== 2)
3200 printf(" -> %s\n", hdr
.ar_name
);
3201 if (tcc_load_object_file(s1
, fd
, off
) < 0)
3212 /* load a '.a' file */
3213 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
, int alacarte
)
3216 /* char magic[8]; */
3218 unsigned long file_offset
;
3221 /* skip magic which was already checked */
3222 /* full_read(fd, magic, sizeof(magic)); */
3223 file_offset
= sizeof ARMAG
- 1;
3226 len
= read_ar_header(fd
, file_offset
, &hdr
);
3230 tcc_error_noabort("invalid archive");
3234 size
= strtol(hdr
.ar_size
, NULL
, 0);
3236 size
= (size
+ 1) & ~1;
3238 /* coff symbol table : we handle it */
3239 if (!strcmp(hdr
.ar_name
, "/"))
3240 return tcc_load_alacarte(s1
, fd
, size
, 4);
3241 if (!strcmp(hdr
.ar_name
, "/SYM64/"))
3242 return tcc_load_alacarte(s1
, fd
, size
, 8);
3243 } else if (tcc_object_type(fd
, &ehdr
) == AFF_BINTYPE_REL
) {
3244 if (s1
->verbose
== 2)
3245 printf(" -> %s\n", hdr
.ar_name
);
3246 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
3249 file_offset
+= size
;
3253 #ifndef ELF_OBJ_ONLY
3254 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3255 LV, maybe create a new entry for (LIB,VERSION). */
3256 static void set_ver_to_ver(TCCState
*s1
, int *n
, int **lv
, int i
, char *lib
, char *version
)
3259 *lv
= tcc_realloc(*lv
, (*n
+ 1) * sizeof(**lv
));
3262 if ((*lv
)[i
] == -1) {
3263 int v
, prev_same_lib
= -1;
3264 for (v
= 0; v
< nb_sym_versions
; v
++) {
3265 if (strcmp(sym_versions
[v
].lib
, lib
))
3268 if (!strcmp(sym_versions
[v
].version
, version
))
3271 if (v
== nb_sym_versions
) {
3272 sym_versions
= tcc_realloc (sym_versions
,
3273 (v
+ 1) * sizeof(*sym_versions
));
3274 sym_versions
[v
].lib
= tcc_strdup(lib
);
3275 sym_versions
[v
].version
= tcc_strdup(version
);
3276 sym_versions
[v
].out_index
= 0;
3277 sym_versions
[v
].prev_same_lib
= prev_same_lib
;
3284 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3287 set_sym_version(TCCState
*s1
, int sym_index
, int verndx
)
3289 if (sym_index
>= nb_sym_to_version
) {
3290 int newelems
= sym_index
? sym_index
* 2 : 1;
3291 sym_to_version
= tcc_realloc(sym_to_version
,
3292 newelems
* sizeof(*sym_to_version
));
3293 memset(sym_to_version
+ nb_sym_to_version
, -1,
3294 (newelems
- nb_sym_to_version
) * sizeof(*sym_to_version
));
3295 nb_sym_to_version
= newelems
;
3297 if (sym_to_version
[sym_index
] < 0)
3298 sym_to_version
[sym_index
] = verndx
;
3301 struct versym_info
{
3303 ElfW(Verdef
) *verdef
;
3304 ElfW(Verneed
) *verneed
;
3306 int nb_local_ver
, *local_ver
;
3310 static void store_version(TCCState
*s1
, struct versym_info
*v
, char *dynstr
)
3312 char *lib
, *version
;
3316 #define DEBUG_VERSION 0
3318 if (v
->versym
&& v
->verdef
) {
3319 ElfW(Verdef
) *vdef
= v
->verdef
;
3322 ElfW(Verdaux
) *verdaux
=
3323 (ElfW(Verdaux
) *) (((char *) vdef
) + vdef
->vd_aux
);
3326 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3327 vdef
->vd_version
, vdef
->vd_flags
, vdef
->vd_ndx
,
3331 version
= dynstr
+ verdaux
->vda_name
;
3336 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vdef
->vd_ndx
,
3339 printf (" verdaux(%u): %s\n", vdef
->vd_ndx
, version
);
3342 next
= vdef
->vd_next
;
3343 vdef
= (ElfW(Verdef
) *) (((char *) vdef
) + next
);
3346 if (v
->versym
&& v
->verneed
) {
3347 ElfW(Verneed
) *vneed
= v
->verneed
;
3349 ElfW(Vernaux
) *vernaux
=
3350 (ElfW(Vernaux
) *) (((char *) vneed
) + vneed
->vn_aux
);
3352 lib
= dynstr
+ vneed
->vn_file
;
3354 printf ("verneed: %u %s\n", vneed
->vn_version
, lib
);
3356 for (i
= 0; i
< vneed
->vn_cnt
; i
++) {
3357 if ((vernaux
->vna_other
& 0x8000) == 0) { /* hidden */
3358 version
= dynstr
+ vernaux
->vna_name
;
3359 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vernaux
->vna_other
,
3362 printf (" vernaux(%u): %u %u %s\n",
3363 vernaux
->vna_other
, vernaux
->vna_hash
,
3364 vernaux
->vna_flags
, version
);
3367 vernaux
= (ElfW(Vernaux
) *) (((char *) vernaux
) + vernaux
->vna_next
);
3369 next
= vneed
->vn_next
;
3370 vneed
= (ElfW(Verneed
) *) (((char *) vneed
) + next
);
3375 for (i
= 0; i
< v
->nb_local_ver
; i
++) {
3376 if (v
->local_ver
[i
] > 0) {
3377 printf ("%d: lib: %s, version %s\n",
3378 i
, sym_versions
[v
->local_ver
[i
]].lib
,
3379 sym_versions
[v
->local_ver
[i
]].version
);
3385 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3386 is referenced by the user (so it should be added as DT_NEEDED in
3387 the generated ELF file) */
3388 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
3391 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
3392 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
3393 ElfW(Sym
) *sym
, *dynsym
;
3394 ElfW(Dyn
) *dt
, *dynamic
;
3398 const char *name
, *soname
;
3399 DLLReference
*dllref
;
3400 struct versym_info v
;
3402 full_read(fd
, &ehdr
, sizeof(ehdr
));
3404 /* test CPU specific stuff */
3405 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
3406 ehdr
.e_machine
!= EM_TCC_TARGET
) {
3407 tcc_error_noabort("bad architecture");
3412 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
3414 /* load dynamic section and dynamic symbols */
3418 dynsym
= NULL
; /* avoid warning */
3419 dynstr
= NULL
; /* avoid warning */
3420 memset(&v
, 0, sizeof v
);
3422 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
3423 switch(sh
->sh_type
) {
3425 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
3426 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3429 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
3430 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3431 sh1
= &shdr
[sh
->sh_link
];
3432 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
3434 case SHT_GNU_verdef
:
3435 v
.verdef
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3437 case SHT_GNU_verneed
:
3438 v
.verneed
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3440 case SHT_GNU_versym
:
3441 v
.nb_versyms
= sh
->sh_size
/ sizeof(ElfW(Half
));
3442 v
.versym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3449 /* compute the real library name */
3450 soname
= tcc_basename(filename
);
3452 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3453 if (dt
->d_tag
== DT_SONAME
) {
3454 soname
= dynstr
+ dt
->d_un
.d_val
;
3458 /* if the dll is already loaded, do not load it */
3459 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
3460 dllref
= s1
->loaded_dlls
[i
];
3461 if (!strcmp(soname
, dllref
->name
)) {
3462 /* but update level if needed */
3463 if (level
< dllref
->level
)
3464 dllref
->level
= level
;
3470 if (v
.nb_versyms
!= nb_syms
)
3471 tcc_free (v
.versym
), v
.versym
= NULL
;
3473 store_version(s1
, &v
, dynstr
);
3475 /* add the dll and its level */
3476 tcc_add_dllref(s1
, soname
)->level
= level
;
3478 /* add dynamic symbols in dynsym_section */
3479 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
3480 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
3481 if (sym_bind
== STB_LOCAL
)
3483 name
= dynstr
+ sym
->st_name
;
3484 sym_index
= set_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
3485 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
3487 ElfW(Half
) vsym
= v
.versym
[i
];
3488 if ((vsym
& 0x8000) == 0 && vsym
> 0 && vsym
< v
.nb_local_ver
)
3489 set_sym_version(s1
, sym_index
, v
.local_ver
[vsym
]);
3493 /* load all referenced DLLs */
3494 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3497 name
= dynstr
+ dt
->d_un
.d_val
;
3498 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
3499 dllref
= s1
->loaded_dlls
[j
];
3500 if (!strcmp(name
, dllref
->name
))
3501 goto already_loaded
;
3503 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
3504 tcc_error_noabort("referenced dll '%s' not found", name
);
3518 tcc_free(v
.local_ver
);
3520 tcc_free(v
.verneed
);
3525 #define LD_TOK_NAME 256
3526 #define LD_TOK_EOF (-1)
3528 static int ld_inp(TCCState
*s1
)
3536 if (1 == read(s1
->fd
, &b
, 1))
3541 /* return next ld script token */
3542 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
3559 if (ch
== '*') { /* comment */
3560 for (d
= 0;; d
= ch
) {
3562 if (ch
== CH_EOF
|| (ch
== '/' && d
== '*'))
3573 /* case 'a' ... 'z': */
3600 /* case 'A' ... 'z': */
3634 if (!((ch
>= 'a' && ch
<= 'z') ||
3635 (ch
>= 'A' && ch
<= 'Z') ||
3636 (ch
>= '0' && ch
<= '9') ||
3637 strchr("/.-_+=$:\\,~", ch
)))
3639 if ((q
- name
) < name_size
- 1) {
3658 static int ld_add_file(TCCState
*s1
, const char filename
[])
3660 if (filename
[0] == '/') {
3661 if (CONFIG_SYSROOT
[0] == '\0'
3662 && tcc_add_file_internal(s1
, filename
, AFF_TYPE_BIN
) == 0)
3664 filename
= tcc_basename(filename
);
3666 return tcc_add_dll(s1
, filename
, 0);
3669 static int ld_add_file_list(TCCState
*s1
, const char *cmd
, int as_needed
)
3671 char filename
[1024], libname
[1024];
3672 int t
, group
, nblibs
= 0, ret
= 0;
3675 group
= !strcmp(cmd
, "GROUP");
3677 s1
->new_undef_sym
= 0;
3678 t
= ld_next(s1
, filename
, sizeof(filename
));
3680 tcc_error_noabort("( expected");
3682 goto lib_parse_error
;
3684 t
= ld_next(s1
, filename
, sizeof(filename
));
3687 if (t
== LD_TOK_EOF
) {
3688 tcc_error_noabort("unexpected end of file");
3690 goto lib_parse_error
;
3691 } else if (t
== ')') {
3693 } else if (t
== '-') {
3694 t
= ld_next(s1
, filename
, sizeof(filename
));
3695 if ((t
!= LD_TOK_NAME
) || (filename
[0] != 'l')) {
3696 tcc_error_noabort("library name expected");
3698 goto lib_parse_error
;
3700 pstrcpy(libname
, sizeof libname
, &filename
[1]);
3701 if (s1
->static_link
) {
3702 snprintf(filename
, sizeof filename
, "lib%s.a", libname
);
3704 snprintf(filename
, sizeof filename
, "lib%s.so", libname
);
3706 } else if (t
!= LD_TOK_NAME
) {
3707 tcc_error_noabort("filename expected");
3709 goto lib_parse_error
;
3711 if (!strcmp(filename
, "AS_NEEDED")) {
3712 ret
= ld_add_file_list(s1
, cmd
, 1);
3714 goto lib_parse_error
;
3716 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3718 ret
= ld_add_file(s1
, filename
);
3720 goto lib_parse_error
;
3722 /* Add the filename *and* the libname to avoid future conversions */
3723 dynarray_add(&libs
, &nblibs
, tcc_strdup(filename
));
3724 if (libname
[0] != '\0')
3725 dynarray_add(&libs
, &nblibs
, tcc_strdup(libname
));
3729 t
= ld_next(s1
, filename
, sizeof(filename
));
3731 t
= ld_next(s1
, filename
, sizeof(filename
));
3734 if (group
&& !as_needed
) {
3735 while (s1
->new_undef_sym
) {
3737 s1
->new_undef_sym
= 0;
3738 for (i
= 0; i
< nblibs
; i
++)
3739 ld_add_file(s1
, libs
[i
]);
3743 dynarray_reset(&libs
, &nblibs
);
3747 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3749 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
, int fd
)
3752 char filename
[1024];
3758 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3759 if (t
== LD_TOK_EOF
)
3761 else if (t
!= LD_TOK_NAME
)
3763 if (!strcmp(cmd
, "INPUT") ||
3764 !strcmp(cmd
, "GROUP")) {
3765 ret
= ld_add_file_list(s1
, cmd
, 0);
3768 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
3769 !strcmp(cmd
, "TARGET")) {
3770 /* ignore some commands */
3771 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3773 tcc_error_noabort("( expected");
3777 t
= ld_next(s1
, filename
, sizeof(filename
));
3778 if (t
== LD_TOK_EOF
) {
3779 tcc_error_noabort("unexpected end of file");
3781 } else if (t
== ')') {
3791 #endif /* !ELF_OBJ_ONLY */