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)
1035 #elif defined(TCC_TARGET_ARM64)
1036 case R_AARCH64_ABS32
:
1037 case R_AARCH64_ABS64
:
1038 #elif defined(TCC_TARGET_RISCV64)
1044 #if defined(TCC_TARGET_I386)
1046 #elif defined(TCC_TARGET_X86_64)
1049 ElfW(Sym
) *sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1051 /* support __dso_handle in atexit() */
1052 if (sym
->st_shndx
!= SHN_UNDEF
&&
1053 ELFW(ST_VISIBILITY
)(sym
->st_other
) == STV_HIDDEN
) {
1054 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PLT32
);
1058 #elif defined(TCC_TARGET_ARM64)
1059 case R_AARCH64_PREL32
:
1061 if (get_sym_attr(s1
, sym_index
, 0)->dyn_index
)
1069 /* allocate the section */
1070 sr
->sh_flags
|= SHF_ALLOC
;
1071 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
1078 #if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE)
1079 static void build_got(TCCState
*s1
)
1081 /* if no got, then create it */
1082 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
1083 s1
->got
->sh_entsize
= 4;
1084 set_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
1085 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
1086 /* keep space for _DYNAMIC pointer and two dummy got entries */
1087 section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
1090 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1091 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1092 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1093 Returns the offset of the GOT or (if any) PLT entry. */
1094 static struct sym_attr
* put_got_entry(TCCState
*s1
, int dyn_reloc_type
,
1100 struct sym_attr
*attr
;
1101 unsigned got_offset
;
1105 need_plt_entry
= (dyn_reloc_type
== R_JMP_SLOT
);
1106 attr
= get_sym_attr(s1
, sym_index
, 1);
1108 /* In case a function is both called and its address taken 2 GOT entries
1109 are created, one for taking the address (GOT) and the other for the PLT
1111 if (need_plt_entry
? attr
->plt_offset
: attr
->got_offset
)
1114 /* create the GOT entry */
1115 got_offset
= s1
->got
->data_offset
;
1116 section_ptr_add(s1
->got
, PTR_SIZE
);
1118 /* Create the GOT relocation that will insert the address of the object or
1119 function of interest in the GOT entry. This is a static relocation for
1120 memory output (dlsym will give us the address of symbols) and dynamic
1121 relocation otherwise (executable and DLLs). The relocation should be
1122 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1123 associated to a PLT entry) but is currently done at load time for an
1126 sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1127 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1130 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
) {
1131 /* Hack alarm. We don't want to emit dynamic symbols
1132 and symbol based relocs for STB_LOCAL symbols, but rather
1133 want to resolve them directly. At this point the symbol
1134 values aren't final yet, so we must defer this. We will later
1135 have to create a RELATIVE reloc anyway, so we misuse the
1136 relocation slot to smuggle the symbol reference until
1137 fill_local_got_entries. Not that the sym_index is
1138 relative to symtab_section, not s1->dynsym! Nevertheless
1139 we use s1->dyn_sym so that if this is the first call
1140 that got->reloc is correctly created. Also note that
1141 RELATIVE relocs are not normally created for the .got,
1142 so the types serves as a marker for later (and is retained
1143 also for the final output, which is okay because then the
1144 got is just normal data). */
1145 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, R_RELATIVE
,
1148 if (0 == attr
->dyn_index
)
1149 attr
->dyn_index
= set_elf_sym(s1
->dynsym
, sym
->st_value
,
1150 sym
->st_size
, sym
->st_info
, 0,
1151 sym
->st_shndx
, name
);
1152 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, dyn_reloc_type
,
1156 put_elf_reloc(symtab_section
, s1
->got
, got_offset
, dyn_reloc_type
,
1160 if (need_plt_entry
) {
1162 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1163 SHF_ALLOC
| SHF_EXECINSTR
);
1164 s1
->plt
->sh_entsize
= 4;
1167 attr
->plt_offset
= create_plt_entry(s1
, got_offset
, attr
);
1169 /* create a symbol 'sym@plt' for the PLT jump vector */
1171 if (len
> sizeof plt_name
- 5)
1172 len
= sizeof plt_name
- 5;
1173 memcpy(plt_name
, name
, len
);
1174 strcpy(plt_name
+ len
, "@plt");
1175 attr
->plt_sym
= put_elf_sym(s1
->symtab
, attr
->plt_offset
, sym
->st_size
,
1176 ELFW(ST_INFO
)(STB_GLOBAL
, STT_FUNC
), 0, s1
->plt
->sh_num
, plt_name
);
1179 attr
->got_offset
= got_offset
;
1185 /* build GOT and PLT entries */
1186 static void build_got_entries_pass(TCCState
*s1
, int pass
)
1191 int i
, type
, gotplt_entry
, reloc_type
, sym_index
;
1192 struct sym_attr
*attr
;
1194 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1195 s
= s1
->sections
[i
];
1196 if (s
->sh_type
!= SHT_RELX
)
1198 /* no need to handle got relocations */
1199 if (s
->link
!= symtab_section
)
1201 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1202 type
= ELFW(R_TYPE
)(rel
->r_info
);
1203 gotplt_entry
= gotplt_entry_type(type
);
1204 if (gotplt_entry
== -1)
1205 tcc_error ("Unknown relocation type for got: %d", type
);
1206 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1207 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1209 if (gotplt_entry
== NO_GOTPLT_ENTRY
) {
1213 /* Automatically create PLT/GOT [entry] if it is an undefined
1214 reference (resolved at runtime), or the symbol is absolute,
1215 probably created by tcc_add_symbol, and thus on 64-bit
1216 targets might be too far from application code. */
1217 if (gotplt_entry
== AUTO_GOTPLT_ENTRY
) {
1218 if (sym
->st_shndx
== SHN_UNDEF
) {
1221 if (s1
->output_type
== TCC_OUTPUT_DLL
&& ! PCRELATIVE_DLLPLT
)
1223 /* Relocations for UNDEF symbols would normally need
1224 to be transferred into the executable or shared object.
1225 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1226 But TCC doesn't do that (at least for exes), so we
1227 need to resolve all such relocs locally. And that
1228 means PLT slots for functions in DLLs and COPY relocs for
1229 data symbols. COPY relocs were generated in
1230 bind_exe_dynsyms (and the symbol adjusted to be defined),
1231 and for functions we were generated a dynamic symbol
1232 of function type. */
1234 /* dynsym isn't set for -run :-/ */
1235 dynindex
= get_sym_attr(s1
, sym_index
, 0)->dyn_index
;
1236 esym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ dynindex
;
1238 && (ELFW(ST_TYPE
)(esym
->st_info
) == STT_FUNC
1239 || (ELFW(ST_TYPE
)(esym
->st_info
) == STT_NOTYPE
1240 && ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
)))
1243 } else if (!(sym
->st_shndx
== SHN_ABS
1244 #ifndef TCC_TARGET_ARM
1251 #ifdef TCC_TARGET_X86_64
1252 if ((type
== R_X86_64_PLT32
|| type
== R_X86_64_PC32
) &&
1253 sym
->st_shndx
!= SHN_UNDEF
&&
1254 (ELFW(ST_VISIBILITY
)(sym
->st_other
) != STV_DEFAULT
||
1255 ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
||
1256 s1
->output_type
== TCC_OUTPUT_EXE
)) {
1259 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PC32
);
1263 reloc_type
= code_reloc(type
);
1264 if (reloc_type
== -1)
1265 tcc_error ("Unknown relocation type: %d", type
);
1266 else if (reloc_type
!= 0) {
1268 reloc_type
= R_JMP_SLOT
;
1270 reloc_type
= R_GLOB_DAT
;
1273 if ((pass
== 0 && reloc_type
== R_GLOB_DAT
) ||
1274 (pass
== 1 && reloc_type
== R_JMP_SLOT
))
1280 if (gotplt_entry
== BUILD_GOT_ONLY
)
1283 attr
= put_got_entry(s1
, reloc_type
, sym_index
);
1285 if (reloc_type
== R_JMP_SLOT
)
1286 rel
->r_info
= ELFW(R_INFO
)(attr
->plt_sym
, type
);
1291 ST_FUNC
void build_got_entries(TCCState
*s1
)
1295 /* Two passes because R_JMP_SLOT should become first.
1296 Some targets (arm, arm64) do not allow mixing R_JMP_SLOT and R_GLOB_DAT. */
1297 for (i
= 0; i
< 2; i
++)
1298 build_got_entries_pass(s1
, i
);
1302 ST_FUNC
int set_global_sym(TCCState
*s1
, const char *name
, Section
*sec
, addr_t offs
)
1304 int shn
= sec
? sec
->sh_num
: offs
? SHN_ABS
: SHN_UNDEF
;
1305 if (sec
&& offs
== -1)
1306 offs
= sec
->data_offset
;
1307 return set_elf_sym(symtab_section
, offs
, 0,
1308 ELFW(ST_INFO
)(name
? STB_GLOBAL
: STB_LOCAL
, STT_NOTYPE
), 0, shn
, name
);
1311 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1316 s
= find_section(s1
, section_name
);
1321 end_offset
= s
->data_offset
;
1323 snprintf(buf
, sizeof(buf
), "__%s_start", section_name
+ 1);
1324 set_global_sym(s1
, buf
, s
, 0);
1325 snprintf(buf
, sizeof(buf
), "__%s_end", section_name
+ 1);
1326 set_global_sym(s1
, buf
, s
, end_offset
);
1329 #ifndef TCC_TARGET_PE
1330 static void tcc_add_support(TCCState
*s1
, const char *filename
)
1333 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, filename
);
1334 tcc_add_file(s1
, buf
);
1338 ST_FUNC
void add_array (TCCState
*s1
, const char *sec
, int c
)
1341 s
= find_section(s1
, sec
);
1342 s
->sh_flags
|= SHF_WRITE
;
1343 #ifndef TCC_TARGET_PE
1344 s
->sh_type
= sec
[1] == 'i' ? SHT_INIT_ARRAY
: SHT_FINI_ARRAY
;
1346 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1347 section_ptr_add(s
, PTR_SIZE
);
1350 #ifdef CONFIG_TCC_BCHECK
1351 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
1353 if (0 == s1
->do_bounds_check
)
1355 section_ptr_add(bounds_section
, sizeof(addr_t
));
1359 #ifdef CONFIG_TCC_BACKTRACE
1360 static void put_ptr(TCCState
*s1
, Section
*s
, int offs
)
1363 c
= set_global_sym(s1
, NULL
, s
, offs
);
1365 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1366 section_ptr_add(s
, PTR_SIZE
);
1369 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1370 a dynamic symbol to allow so's to have one each with a different value. */
1371 static void set_local_sym(TCCState
*s1
, const char *name
, Section
*s
, int offset
)
1373 int c
= find_elf_sym(s1
->symtab
, name
);
1375 ElfW(Sym
) *esym
= (ElfW(Sym
)*)s1
->symtab
->data
+ c
;
1376 esym
->st_info
= ELFW(ST_INFO
)(STB_LOCAL
, STT_NOTYPE
);
1377 esym
->st_value
= offset
;
1378 esym
->st_shndx
= s
->sh_num
;
1382 ST_FUNC
void tcc_add_btstub(TCCState
*s1
)
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 #ifdef CONFIG_TCC_BCHECK
1453 if (s1
->do_bounds_check
&& s1
->output_type
!= TCC_OUTPUT_DLL
) {
1454 tcc_add_library_err(s1
, "pthread");
1455 #if !TARGETOS_OpenBSD && !TARGETOS_NetBSD
1456 tcc_add_library_err(s1
, "dl");
1458 tcc_add_support(s1
, "bcheck.o");
1461 #ifdef CONFIG_TCC_BACKTRACE
1462 if (s1
->do_backtrace
) {
1463 if (s1
->output_type
== TCC_OUTPUT_EXE
)
1464 tcc_add_support(s1
, "bt-exe.o");
1465 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1466 tcc_add_support(s1
, "bt-log.o");
1467 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1471 if (strlen(TCC_LIBTCC1
) > 0)
1472 tcc_add_support(s1
, TCC_LIBTCC1
);
1473 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
1474 /* add crt end if not memory output */
1475 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1476 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1477 tcc_add_crt(s1
, "crtendS.o");
1479 tcc_add_crt(s1
, "crtend.o");
1480 #if TARGETOS_FreeBSD || TARGETOS_NetBSD
1481 tcc_add_crt(s1
, "crtn.o");
1484 #elif !defined(TCC_TARGET_MACHO)
1485 /* add crt end if not memory output */
1486 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1487 tcc_add_crt(s1
, "crtn.o");
1493 /* add various standard linker symbols (must be done after the
1494 sections are filled (for example after allocating common
1496 static void tcc_add_linker_symbols(TCCState
*s1
)
1502 set_global_sym(s1
, "_etext", text_section
, -1);
1503 set_global_sym(s1
, "_edata", data_section
, -1);
1504 set_global_sym(s1
, "_end", bss_section
, -1);
1505 #ifdef TCC_TARGET_RISCV64
1506 /* XXX should be .sdata+0x800, not .data+0x800 */
1507 set_global_sym(s1
, "__global_pointer$", data_section
, 0x800);
1509 /* horrible new standard ldscript defines */
1510 add_init_array_defines(s1
, ".preinit_array");
1511 add_init_array_defines(s1
, ".init_array");
1512 add_init_array_defines(s1
, ".fini_array");
1513 /* add start and stop symbols for sections whose name can be
1515 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1516 s
= s1
->sections
[i
];
1517 if ((s
->sh_flags
& SHF_ALLOC
)
1518 && (s
->sh_type
== SHT_PROGBITS
1519 || s
->sh_type
== SHT_STRTAB
)) {
1521 /* check if section name can be expressed in C */
1527 if (!isid(c
) && !isnum(c
))
1531 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1532 set_global_sym(s1
, buf
, s
, 0);
1533 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1534 set_global_sym(s1
, buf
, s
, -1);
1540 ST_FUNC
void resolve_common_syms(TCCState
*s1
)
1544 /* Allocate common symbols in BSS. */
1545 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1546 if (sym
->st_shndx
== SHN_COMMON
) {
1547 /* symbol alignment is in st_value for SHN_COMMONs */
1548 sym
->st_value
= section_add(bss_section
, sym
->st_size
,
1550 sym
->st_shndx
= bss_section
->sh_num
;
1554 /* Now assign linker provided symbols their value. */
1555 tcc_add_linker_symbols(s1
);
1558 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1559 const int *sec_order
)
1562 int i
, offset
, size
;
1565 for(i
=1;i
<s1
->nb_sections
;i
++) {
1566 s
= s1
->sections
[sec_order
[i
]];
1567 if (s
->sh_type
!= SHT_NOBITS
&&
1568 (s
->sh_flags
& SHF_ALLOC
)) {
1569 while (offset
< s
->sh_offset
) {
1574 fwrite(s
->data
, 1, size
, f
);
1580 #ifndef ELF_OBJ_ONLY
1581 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1583 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1584 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1585 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1586 unsigned offset
= attr
->got_offset
;
1590 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1592 write64le(s1
->got
->data
+ offset
, sym
->st_value
);
1594 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1598 /* Perform relocation to GOT or PLT entries */
1599 ST_FUNC
void fill_got(TCCState
*s1
)
1605 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1606 s
= s1
->sections
[i
];
1607 if (s
->sh_type
!= SHT_RELX
)
1609 /* no need to handle got relocations */
1610 if (s
->link
!= symtab_section
)
1612 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1613 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1614 case R_X86_64_GOT32
:
1615 case R_X86_64_GOTPCREL
:
1616 case R_X86_64_GOTPCRELX
:
1617 case R_X86_64_REX_GOTPCRELX
:
1618 case R_X86_64_PLT32
:
1619 fill_got_entry(s1
, rel
);
1626 /* See put_got_entry for a description. This is the second stage
1627 where GOT references to local defined symbols are rewritten. */
1628 static void fill_local_got_entries(TCCState
*s1
)
1631 if (!s1
->got
->reloc
)
1633 for_each_elem(s1
->got
->reloc
, 0, rel
, ElfW_Rel
) {
1634 if (ELFW(R_TYPE
)(rel
->r_info
) == R_RELATIVE
) {
1635 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1636 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1637 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1638 unsigned offset
= attr
->got_offset
;
1639 if (offset
!= rel
->r_offset
- s1
->got
->sh_addr
)
1640 tcc_error_noabort("huh");
1641 rel
->r_info
= ELFW(R_INFO
)(0, R_RELATIVE
);
1642 #if SHT_RELX == SHT_RELA
1643 rel
->r_addend
= sym
->st_value
;
1645 /* All our REL architectures also happen to be 32bit LE. */
1646 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1652 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1653 in shared libraries and export non local defined symbols to shared libraries
1654 if -rdynamic switch was given on command line */
1655 static void bind_exe_dynsyms(TCCState
*s1
)
1658 int sym_index
, index
;
1659 ElfW(Sym
) *sym
, *esym
;
1662 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1663 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1664 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1665 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1666 if (sym
->st_shndx
== SHN_UNDEF
) {
1667 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1668 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1670 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1671 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1672 if ((type
== STT_FUNC
) || (type
== STT_GNU_IFUNC
)) {
1673 /* Indirect functions shall have STT_FUNC type in executable
1674 * dynsym section. Indeed, a dlsym call following a lazy
1675 * resolution would pick the symbol value from the
1676 * executable dynsym entry which would contain the address
1677 * of the function wanted by the caller of dlsym instead of
1678 * the address of the function that would return that
1681 = put_elf_sym(s1
->dynsym
, 0, esym
->st_size
,
1682 ELFW(ST_INFO
)(STB_GLOBAL
,STT_FUNC
), 0, 0,
1684 int index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1685 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1686 } else if (type
== STT_OBJECT
) {
1687 unsigned long offset
;
1689 offset
= bss_section
->data_offset
;
1690 /* XXX: which alignment ? */
1691 offset
= (offset
+ 16 - 1) & -16;
1692 set_elf_sym (s1
->symtab
, offset
, esym
->st_size
,
1693 esym
->st_info
, 0, bss_section
->sh_num
, name
);
1694 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1695 esym
->st_info
, 0, bss_section
->sh_num
,
1698 /* Ensure R_COPY works for weak symbol aliases */
1699 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1700 for_each_elem(s1
->dynsymtab_section
, 1, dynsym
, ElfW(Sym
)) {
1701 if ((dynsym
->st_value
== esym
->st_value
)
1702 && (ELFW(ST_BIND
)(dynsym
->st_info
) == STB_GLOBAL
)) {
1703 char *dynname
= (char *) s1
->dynsymtab_section
->link
->data
1705 put_elf_sym(s1
->dynsym
, offset
, dynsym
->st_size
,
1707 bss_section
->sh_num
, dynname
);
1713 put_elf_reloc(s1
->dynsym
, bss_section
,
1714 offset
, R_COPY
, index
);
1715 offset
+= esym
->st_size
;
1716 bss_section
->data_offset
= offset
;
1719 /* STB_WEAK undefined symbols are accepted */
1720 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1721 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1722 !strcmp(name
, "_fp_hw")) {
1724 tcc_error_noabort("undefined symbol '%s'", name
);
1727 } else if (s1
->rdynamic
&& ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1728 /* if -rdynamic option, then export all non local symbols */
1729 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1730 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
1731 0, sym
->st_shndx
, name
);
1736 /* Bind symbols of libraries: export all non local symbols of executable that
1737 are referenced by shared libraries. The reason is that the dynamic loader
1738 search symbol first in executable and then in libraries. Therefore a
1739 reference to a symbol already defined by a library can still be resolved by
1740 a symbol in the executable. */
1741 static void bind_libs_dynsyms(TCCState
*s1
)
1745 ElfW(Sym
) *sym
, *esym
;
1747 for_each_elem(s1
->dynsymtab_section
, 1, esym
, ElfW(Sym
)) {
1748 name
= (char *) s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1749 sym_index
= find_elf_sym(symtab_section
, name
);
1750 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1751 if (sym_index
&& sym
->st_shndx
!= SHN_UNDEF
1752 && ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1753 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1754 sym
->st_info
, 0, sym
->st_shndx
, name
);
1755 } else if (esym
->st_shndx
== SHN_UNDEF
) {
1756 /* weak symbols can stay undefined */
1757 if (ELFW(ST_BIND
)(esym
->st_info
) != STB_WEAK
)
1758 tcc_warning("undefined dynamic symbol '%s'", name
);
1763 /* Export all non local symbols. This is used by shared libraries so that the
1764 non local symbols they define can resolve a reference in another shared
1765 library or in the executable. Correspondingly, it allows undefined local
1766 symbols to be resolved by other shared libraries or by the executable. */
1767 static void export_global_syms(TCCState
*s1
)
1769 int dynindex
, index
;
1773 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1774 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1775 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1776 dynindex
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1777 sym
->st_info
, 0, sym
->st_shndx
, name
);
1778 index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1779 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1785 /* Allocate strings for section names and decide if an unallocated section
1787 NOTE: the strsec section comes last, so its size is also correct ! */
1788 static int alloc_sec_names(TCCState
*s1
, int file_type
, Section
*strsec
)
1794 /* Allocate strings for section names */
1795 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1796 s
= s1
->sections
[i
];
1797 /* when generating a DLL, we include relocations but we may
1799 #ifndef ELF_OBJ_ONLY
1800 if (file_type
== TCC_OUTPUT_DLL
&&
1801 s
->sh_type
== SHT_RELX
&&
1802 !(s
->sh_flags
& SHF_ALLOC
) &&
1803 (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
) &&
1804 prepare_dynamic_rel(s1
, s
)) {
1805 if (!(s1
->sections
[s
->sh_info
]->sh_flags
& SHF_WRITE
))
1809 if ((s1
->do_debug
&& s
->sh_type
!= SHT_RELX
) ||
1810 file_type
== TCC_OUTPUT_OBJ
||
1811 (s
->sh_flags
& SHF_ALLOC
) ||
1812 i
== (s1
->nb_sections
- 1)
1813 #ifdef TCC_TARGET_ARM
1814 || s
->sh_type
== SHT_ARM_ATTRIBUTES
1817 /* we output all sections if debug or object file */
1818 s
->sh_size
= s
->data_offset
;
1820 #ifdef TCC_TARGET_ARM
1821 /* XXX: Suppress stack unwinding section. */
1822 if (s
->sh_type
== SHT_ARM_EXIDX
) {
1827 if (s
->sh_size
|| (s
->sh_flags
& SHF_ALLOC
))
1828 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1830 strsec
->sh_size
= strsec
->data_offset
;
1834 /* Info to be copied in dynamic section */
1838 unsigned long data_offset
;
1843 /* Info for GNU_RELRO */
1850 /* Assign sections to segments and decide how are sections laid out when loaded
1851 in memory. This function also fills corresponding program headers. */
1852 static int layout_sections(TCCState
*s1
, ElfW(Phdr
) *phdr
,
1853 int phnum
, int phfill
,
1854 Section
*interp
, Section
* strsec
,
1855 struct dyn_inf
*dyninf
, struct ro_inf
*roinf
,
1858 int i
, sh_order_index
, file_offset
;
1863 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
1864 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1866 #ifndef ELF_OBJ_ONLY
1867 if (phnum
> 0) { /* phnum is 0 for TCC_OUTPUT_OBJ */
1868 unsigned long s_align
;
1872 int j
, k
, file_type
= s1
->output_type
;
1874 s_align
= ELF_PAGE_SIZE
;
1875 if (s1
->section_align
)
1876 s_align
= s1
->section_align
;
1878 if (s1
->has_text_addr
) {
1879 int a_offset
, p_offset
;
1880 addr
= s1
->text_addr
;
1881 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1883 a_offset
= (int) (addr
& (s_align
- 1));
1884 p_offset
= file_offset
& (s_align
- 1);
1885 if (a_offset
< p_offset
)
1886 a_offset
+= s_align
;
1887 file_offset
+= (a_offset
- p_offset
);
1889 if (file_type
== TCC_OUTPUT_DLL
)
1892 addr
= ELF_START_ADDR
;
1893 /* compute address after headers */
1894 addr
+= (file_offset
& (s_align
- 1));
1898 /* Leave one program headers for the program interpreter and one for
1899 the program header table itself if needed. These are done later as
1900 they require section layout to be done first. */
1904 /* dynamic relocation table information, for .dynamic section */
1905 dyninf
->rel_addr
= dyninf
->rel_size
= 0;
1907 /* read only segment mapping for GNU_RELRO */
1908 roinf
->sh_offset
= roinf
->sh_addr
= roinf
->sh_size
= 0;
1910 for(j
= 0; j
< phfill
; j
++) {
1911 Section
*relocplt
= s1
->got
? s1
->got
->relocplt
: NULL
;
1913 ph
->p_type
= j
== 2 ? PT_TLS
: PT_LOAD
;
1915 ph
->p_flags
= PF_R
| PF_X
;
1917 ph
->p_flags
= PF_R
| PF_W
;
1918 ph
->p_align
= j
== 2 ? 4 : s_align
;
1920 /* Decide the layout of sections loaded in memory. This must
1921 be done before program headers are filled since they contain
1922 info about the layout. We do the following ordering: interp,
1923 symbol tables, relocations, progbits, nobits */
1924 /* XXX: do faster and simpler sorting */
1925 for(k
= 0; k
< 7; k
++) {
1926 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1927 s
= s1
->sections
[i
];
1928 /* compute if section should be included */
1930 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
| SHF_TLS
)) !=
1933 } else if (j
== 1) {
1934 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
| SHF_TLS
)) !=
1935 (SHF_ALLOC
| SHF_WRITE
))
1938 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
| SHF_TLS
)) !=
1939 (SHF_ALLOC
| SHF_WRITE
| SHF_TLS
))
1945 } else if ((s
->sh_type
== SHT_DYNSYM
||
1946 s
->sh_type
== SHT_STRTAB
||
1947 s
->sh_type
== SHT_HASH
)
1948 && !strstr(s
->name
, ".stab")) {
1951 } else if (s
->sh_type
== SHT_RELX
) {
1952 if (k
!= 2 && s
!= relocplt
)
1954 else if (k
!= 3 && s
== relocplt
)
1956 } else if (s
->sh_type
== SHT_NOBITS
) {
1959 } else if (s
== data_ro_section
||
1960 s
== bounds_section
||
1961 s
== lbounds_section
) {
1968 sec_order
[sh_order_index
++] = i
;
1970 /* section matches: we align it and add its size */
1972 addr
= (addr
+ s
->sh_addralign
- 1) &
1973 ~(s
->sh_addralign
- 1);
1974 file_offset
+= (int) ( addr
- tmp
);
1975 s
->sh_offset
= file_offset
;
1978 /* update program header infos */
1979 if (ph
->p_offset
== 0) {
1980 ph
->p_offset
= file_offset
;
1982 ph
->p_paddr
= ph
->p_vaddr
;
1984 /* update dynamic relocation infos */
1985 if (s
->sh_type
== SHT_RELX
&& s
!= relocplt
) {
1986 if (dyninf
->rel_size
== 0)
1987 dyninf
->rel_addr
= addr
;
1988 dyninf
->rel_size
= (addr
- dyninf
->rel_addr
) + s
->sh_size
;
1990 if (s
== data_ro_section
||
1991 s
== bounds_section
||
1992 s
== lbounds_section
) {
1993 if (roinf
->sh_size
== 0) {
1994 roinf
->sh_offset
= s
->sh_offset
;
1995 roinf
->sh_addr
= s
->sh_addr
;
1997 roinf
->sh_size
= (addr
- roinf
->sh_addr
) + s
->sh_size
;
2000 if (s
->sh_type
!= SHT_NOBITS
)
2001 file_offset
+= s
->sh_size
;
2005 /* Make the first PT_LOAD segment include the program
2006 headers itself (and the ELF header as well), it'll
2007 come out with same memory use but will make various
2008 tools like binutils strip work better. */
2009 ph
->p_offset
&= ~(ph
->p_align
- 1);
2010 ph
->p_vaddr
&= ~(ph
->p_align
- 1);
2011 ph
->p_paddr
&= ~(ph
->p_align
- 1);
2013 ph
->p_filesz
= file_offset
- ph
->p_offset
;
2014 ph
->p_memsz
= addr
- ph
->p_vaddr
;
2017 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
2018 /* if in the middle of a page, we duplicate the page in
2019 memory so that one copy is RX and the other is RW */
2020 if ((addr
& (s_align
- 1)) != 0)
2023 addr
= (addr
+ s_align
- 1) & ~(s_align
- 1);
2024 file_offset
= (file_offset
+ s_align
- 1) & ~(s_align
- 1);
2029 #endif /* ELF_OBJ_ONLY */
2031 /* all other sections come after */
2032 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2033 s
= s1
->sections
[i
];
2034 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
2036 sec_order
[sh_order_index
++] = i
;
2038 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
2039 ~(s
->sh_addralign
- 1);
2040 s
->sh_offset
= file_offset
;
2041 if (s
->sh_type
!= SHT_NOBITS
)
2042 file_offset
+= s
->sh_size
;
2048 #ifndef ELF_OBJ_ONLY
2049 /* put dynamic tag */
2050 static void put_dt(Section
*dynamic
, int dt
, addr_t val
)
2053 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
2055 dyn
->d_un
.d_val
= val
;
2058 static void fill_unloadable_phdr(ElfW(Phdr
) *phdr
, int phnum
, Section
*interp
,
2059 Section
*dynamic
, Section
*note
, struct ro_inf
*roinf
)
2063 /* if interpreter, then add corresponding program header */
2067 ph
->p_type
= PT_PHDR
;
2068 ph
->p_offset
= sizeof(ElfW(Ehdr
));
2069 ph
->p_filesz
= ph
->p_memsz
= phnum
* sizeof(ElfW(Phdr
));
2070 ph
->p_vaddr
= interp
->sh_addr
- ph
->p_filesz
;
2071 ph
->p_paddr
= ph
->p_vaddr
;
2072 ph
->p_flags
= PF_R
| PF_X
;
2073 ph
->p_align
= 4; /* interp->sh_addralign; */
2076 ph
->p_type
= PT_INTERP
;
2077 ph
->p_offset
= interp
->sh_offset
;
2078 ph
->p_vaddr
= interp
->sh_addr
;
2079 ph
->p_paddr
= ph
->p_vaddr
;
2080 ph
->p_filesz
= interp
->sh_size
;
2081 ph
->p_memsz
= interp
->sh_size
;
2083 ph
->p_align
= interp
->sh_addralign
;
2087 ph
= &phdr
[phnum
- 2 - (roinf
!= NULL
)];
2089 ph
->p_type
= PT_NOTE
;
2090 ph
->p_offset
= note
->sh_offset
;
2091 ph
->p_vaddr
= note
->sh_addr
;
2092 ph
->p_paddr
= ph
->p_vaddr
;
2093 ph
->p_filesz
= note
->sh_size
;
2094 ph
->p_memsz
= note
->sh_size
;
2096 ph
->p_align
= note
->sh_addralign
;
2099 /* if dynamic section, then add corresponding program header */
2101 ph
= &phdr
[phnum
- 1 - (roinf
!= NULL
)];
2103 ph
->p_type
= PT_DYNAMIC
;
2104 ph
->p_offset
= dynamic
->sh_offset
;
2105 ph
->p_vaddr
= dynamic
->sh_addr
;
2106 ph
->p_paddr
= ph
->p_vaddr
;
2107 ph
->p_filesz
= dynamic
->sh_size
;
2108 ph
->p_memsz
= dynamic
->sh_size
;
2109 ph
->p_flags
= PF_R
| PF_W
;
2110 ph
->p_align
= dynamic
->sh_addralign
;
2114 ph
= &phdr
[phnum
- 1];
2116 ph
->p_type
= PT_GNU_RELRO
;
2117 ph
->p_offset
= roinf
->sh_offset
;
2118 ph
->p_vaddr
= roinf
->sh_addr
;
2119 ph
->p_paddr
= ph
->p_vaddr
;
2120 ph
->p_filesz
= roinf
->sh_size
;
2121 ph
->p_memsz
= roinf
->sh_size
;
2127 /* Fill the dynamic section with tags describing the address and size of
2129 static void fill_dynamic(TCCState
*s1
, struct dyn_inf
*dyninf
)
2131 Section
*dynamic
= dyninf
->dynamic
;
2134 /* put dynamic section entries */
2135 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
2136 put_dt(dynamic
, DT_STRTAB
, dyninf
->dynstr
->sh_addr
);
2137 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
2138 put_dt(dynamic
, DT_STRSZ
, dyninf
->dynstr
->data_offset
);
2139 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
2141 put_dt(dynamic
, DT_RELA
, dyninf
->rel_addr
);
2142 put_dt(dynamic
, DT_RELASZ
, dyninf
->rel_size
);
2143 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
2144 if (s1
->got
&& s1
->got
->relocplt
) {
2145 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2146 put_dt(dynamic
, DT_PLTRELSZ
, s1
->got
->relocplt
->data_offset
);
2147 put_dt(dynamic
, DT_JMPREL
, s1
->got
->relocplt
->sh_addr
);
2148 put_dt(dynamic
, DT_PLTREL
, DT_RELA
);
2150 put_dt(dynamic
, DT_RELACOUNT
, 0);
2152 put_dt(dynamic
, DT_REL
, dyninf
->rel_addr
);
2153 put_dt(dynamic
, DT_RELSZ
, dyninf
->rel_size
);
2154 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
2155 if (s1
->got
&& s1
->got
->relocplt
) {
2156 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2157 put_dt(dynamic
, DT_PLTRELSZ
, s1
->got
->relocplt
->data_offset
);
2158 put_dt(dynamic
, DT_JMPREL
, s1
->got
->relocplt
->sh_addr
);
2159 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
2161 put_dt(dynamic
, DT_RELCOUNT
, 0);
2163 if (versym_section
&& verneed_section
) {
2164 /* The dynamic linker can not handle VERSYM without VERNEED */
2165 put_dt(dynamic
, DT_VERSYM
, versym_section
->sh_addr
);
2166 put_dt(dynamic
, DT_VERNEED
, verneed_section
->sh_addr
);
2167 put_dt(dynamic
, DT_VERNEEDNUM
, dt_verneednum
);
2169 s
= find_section_create (s1
, ".preinit_array", 0);
2170 if (s
&& s
->data_offset
) {
2171 put_dt(dynamic
, DT_PREINIT_ARRAY
, s
->sh_addr
);
2172 put_dt(dynamic
, DT_PREINIT_ARRAYSZ
, s
->data_offset
);
2174 s
= find_section_create (s1
, ".init_array", 0);
2175 if (s
&& s
->data_offset
) {
2176 put_dt(dynamic
, DT_INIT_ARRAY
, s
->sh_addr
);
2177 put_dt(dynamic
, DT_INIT_ARRAYSZ
, s
->data_offset
);
2179 s
= find_section_create (s1
, ".fini_array", 0);
2180 if (s
&& s
->data_offset
) {
2181 put_dt(dynamic
, DT_FINI_ARRAY
, s
->sh_addr
);
2182 put_dt(dynamic
, DT_FINI_ARRAYSZ
, s
->data_offset
);
2184 s
= find_section_create (s1
, ".init", 0);
2185 if (s
&& s
->data_offset
) {
2186 put_dt(dynamic
, DT_INIT
, s
->sh_addr
);
2188 s
= find_section_create (s1
, ".fini", 0);
2189 if (s
&& s
->data_offset
) {
2190 put_dt(dynamic
, DT_FINI
, s
->sh_addr
);
2193 put_dt(dynamic
, DT_DEBUG
, 0);
2194 put_dt(dynamic
, DT_NULL
, 0);
2197 /* Relocate remaining sections and symbols (that is those not related to
2199 static int final_sections_reloc(TCCState
*s1
)
2204 relocate_syms(s1
, s1
->symtab
, 0);
2206 if (s1
->nb_errors
!= 0)
2209 /* relocate sections */
2210 /* XXX: ignore sections with allocated relocations ? */
2211 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2212 s
= s1
->sections
[i
];
2213 if (s
->reloc
&& (s
!= s1
->got
|| s1
->static_link
))
2214 relocate_section(s1
, s
);
2217 /* relocate relocation entries if the relocation tables are
2218 allocated in the executable */
2219 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2220 s
= s1
->sections
[i
];
2221 if ((s
->sh_flags
& SHF_ALLOC
) &&
2222 s
->sh_type
== SHT_RELX
) {
2223 relocate_rel(s1
, s
);
2230 /* Create an ELF file on disk.
2231 This function handle ELF specific layout requirements */
2232 static void tcc_output_elf(TCCState
*s1
, FILE *f
, int phnum
, ElfW(Phdr
) *phdr
,
2233 int file_offset
, int *sec_order
)
2235 int i
, shnum
, offset
, size
, file_type
;
2238 ElfW(Shdr
) shdr
, *sh
;
2240 file_type
= s1
->output_type
;
2241 shnum
= s1
->nb_sections
;
2243 memset(&ehdr
, 0, sizeof(ehdr
));
2246 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2247 ehdr
.e_phnum
= phnum
;
2248 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2252 file_offset
= (file_offset
+ 3) & -4;
2255 ehdr
.e_ident
[0] = ELFMAG0
;
2256 ehdr
.e_ident
[1] = ELFMAG1
;
2257 ehdr
.e_ident
[2] = ELFMAG2
;
2258 ehdr
.e_ident
[3] = ELFMAG3
;
2259 ehdr
.e_ident
[4] = ELFCLASSW
;
2260 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2261 ehdr
.e_ident
[6] = EV_CURRENT
;
2262 #if TARGETOS_FreeBSD || TARGETOS_FreeBSD_kernel
2263 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2265 #ifdef TCC_TARGET_ARM
2267 ehdr
.e_ident
[EI_OSABI
] = 0;
2268 ehdr
.e_flags
= EF_ARM_EABI_VER4
;
2269 if (file_type
== TCC_OUTPUT_EXE
|| file_type
== TCC_OUTPUT_DLL
)
2270 ehdr
.e_flags
|= EF_ARM_HASENTRY
;
2271 if (s1
->float_abi
== ARM_HARD_FLOAT
)
2272 ehdr
.e_flags
|= EF_ARM_VFP_FLOAT
;
2274 ehdr
.e_flags
|= EF_ARM_SOFT_FLOAT
;
2276 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2278 #elif defined TCC_TARGET_RISCV64
2279 ehdr
.e_flags
= EF_RISCV_FLOAT_ABI_DOUBLE
;
2283 case TCC_OUTPUT_EXE
:
2284 ehdr
.e_type
= ET_EXEC
;
2285 ehdr
.e_entry
= get_sym_addr(s1
, "_start", 1, 0);
2287 case TCC_OUTPUT_DLL
:
2288 ehdr
.e_type
= ET_DYN
;
2289 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
2291 case TCC_OUTPUT_OBJ
:
2292 ehdr
.e_type
= ET_REL
;
2295 ehdr
.e_machine
= EM_TCC_TARGET
;
2296 ehdr
.e_version
= EV_CURRENT
;
2297 ehdr
.e_shoff
= file_offset
;
2298 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2299 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2300 ehdr
.e_shnum
= shnum
;
2301 ehdr
.e_shstrndx
= shnum
- 1;
2303 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2304 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2305 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2307 sort_syms(s1
, symtab_section
);
2308 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2309 s
= s1
->sections
[sec_order
[i
]];
2310 if (s
->sh_type
!= SHT_NOBITS
) {
2311 while (offset
< s
->sh_offset
) {
2317 fwrite(s
->data
, 1, size
, f
);
2322 /* output section headers */
2323 while (offset
< ehdr
.e_shoff
) {
2328 for(i
= 0; i
< s1
->nb_sections
; i
++) {
2330 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2331 s
= s1
->sections
[i
];
2333 sh
->sh_name
= s
->sh_name
;
2334 sh
->sh_type
= s
->sh_type
;
2335 sh
->sh_flags
= s
->sh_flags
;
2336 sh
->sh_entsize
= s
->sh_entsize
;
2337 sh
->sh_info
= s
->sh_info
;
2339 sh
->sh_link
= s
->link
->sh_num
;
2340 sh
->sh_addralign
= s
->sh_addralign
;
2341 sh
->sh_addr
= s
->sh_addr
;
2342 sh
->sh_offset
= s
->sh_offset
;
2343 sh
->sh_size
= s
->sh_size
;
2345 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2349 /* Write an elf, coff or "binary" file */
2350 static int tcc_write_elf_file(TCCState
*s1
, const char *filename
, int phnum
,
2351 ElfW(Phdr
) *phdr
, int file_offset
, int *sec_order
)
2353 int fd
, mode
, file_type
;
2356 file_type
= s1
->output_type
;
2357 if (file_type
== TCC_OUTPUT_OBJ
)
2362 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2364 tcc_error_noabort("could not write '%s'", filename
);
2367 f
= fdopen(fd
, "wb");
2369 printf("<- %s\n", filename
);
2371 #ifdef TCC_TARGET_COFF
2372 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
)
2373 tcc_output_coff(s1
, f
);
2376 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2377 tcc_output_elf(s1
, f
, phnum
, phdr
, file_offset
, sec_order
);
2379 tcc_output_binary(s1
, f
, sec_order
);
2385 #ifndef ELF_OBJ_ONLY
2386 /* Sort section headers by assigned sh_addr, remove sections
2387 that we aren't going to output. */
2388 static void tidy_section_headers(TCCState
*s1
, int *sec_order
)
2390 int i
, nnew
, l
, *backmap
;
2394 snew
= tcc_malloc(s1
->nb_sections
* sizeof(snew
[0]));
2395 backmap
= tcc_malloc(s1
->nb_sections
* sizeof(backmap
[0]));
2396 for (i
= 0, nnew
= 0, l
= s1
->nb_sections
; i
< s1
->nb_sections
; i
++) {
2397 s
= s1
->sections
[sec_order
[i
]];
2398 if (!i
|| s
->sh_name
) {
2399 backmap
[sec_order
[i
]] = nnew
;
2403 backmap
[sec_order
[i
]] = 0;
2407 for (i
= 0; i
< nnew
; i
++) {
2411 if (s
->sh_type
== SHT_RELX
)
2412 s
->sh_info
= backmap
[s
->sh_info
];
2416 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
))
2417 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2418 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2419 if ( !s1
->static_link
) {
2420 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
))
2421 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2422 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2424 for (i
= 0; i
< s1
->nb_sections
; i
++)
2426 tcc_free(s1
->sections
);
2427 s1
->sections
= snew
;
2428 s1
->nb_sections
= nnew
;
2433 #ifdef TCC_TARGET_ARM
2434 static void create_arm_attribute_section(TCCState
*s1
)
2436 // Needed for DLL support.
2437 static const unsigned char arm_attr
[] = {
2439 0x2c, 0x00, 0x00, 0x00, // size 0x2c
2440 'a', 'e', 'a', 'b', 'i', 0x00, // "aeabi"
2441 0x01, 0x22, 0x00, 0x00, 0x00, // 'File Attributes', size 0x22
2442 0x05, 0x36, 0x00, // 'CPU_name', "6"
2443 0x06, 0x06, // 'CPU_arch', 'v6'
2444 0x08, 0x01, // 'ARM_ISA_use', 'Yes'
2445 0x09, 0x01, // 'THUMB_ISA_use', 'Thumb-1'
2446 0x0a, 0x02, // 'FP_arch', 'VFPv2'
2447 0x12, 0x04, // 'ABI_PCS_wchar_t', 4
2448 0x14, 0x01, // 'ABI_FP_denormal', 'Needed'
2449 0x15, 0x01, // 'ABI_FP_exceptions', 'Needed'
2450 0x17, 0x03, // 'ABI_FP_number_model', 'IEEE 754'
2451 0x18, 0x01, // 'ABI_align_needed', '8-byte'
2452 0x19, 0x01, // 'ABI_align_preserved', '8-byte, except leaf SP'
2453 0x1a, 0x02, // 'ABI_enum_size', 'int'
2454 0x1c, 0x01, // 'ABI_VFP_args', 'VFP registers'
2455 0x22, 0x01 // 'CPU_unaligned_access', 'v6'
2457 Section
*attr
= new_section(s1
, ".ARM.attributes", SHT_ARM_ATTRIBUTES
, 0);
2458 unsigned char *ptr
= section_ptr_add(attr
, sizeof(arm_attr
));
2459 attr
->sh_addralign
= 1;
2460 memcpy(ptr
, arm_attr
, sizeof(arm_attr
));
2461 if (s1
->float_abi
!= ARM_HARD_FLOAT
) {
2462 ptr
[26] = 0x00; // 'FP_arch', 'No'
2463 ptr
[41] = 0x1e; // 'ABI_optimization_goals'
2464 ptr
[42] = 0x06; // 'Aggressive Debug'
2469 #if TARGETOS_OpenBSD || TARGETOS_NetBSD
2470 static Section
*create_bsd_note_section(TCCState
*s1
,
2474 Section
*s
= find_section (s1
, name
);
2476 if (s
->data_offset
== 0) {
2477 unsigned char *ptr
= section_ptr_add(s
, sizeof(ElfW(Nhdr
)) + 8 + 4);
2478 ElfW(Nhdr
) *note
= (ElfW(Nhdr
) *) ptr
;
2480 s
->sh_type
= SHT_NOTE
;
2483 note
->n_type
= ELF_NOTE_OS_GNU
;
2484 strcpy (ptr
+ sizeof(ElfW(Nhdr
)), value
);
2490 /* Output an elf, coff or binary file */
2491 /* XXX: suppress unneeded sections */
2492 static int elf_output_file(TCCState
*s1
, const char *filename
)
2494 int i
, ret
, phnum
, phfill
, shnum
, file_type
, file_offset
, *sec_order
;
2495 struct dyn_inf dyninf
= {0};
2496 struct ro_inf roinf
, *roinf_use
= NULL
;
2498 Section
*strsec
, *interp
, *dynamic
, *dynstr
, *note
= NULL
;
2500 file_type
= s1
->output_type
;
2502 #ifdef TCC_TARGET_ARM
2503 create_arm_attribute_section (s1
);
2505 #if TARGETOS_OpenBSD
2506 if (file_type
!= TCC_OUTPUT_OBJ
)
2507 note
= create_bsd_note_section (s1
, ".note.openbsd.ident", "OpenBSD");
2510 if (file_type
!= TCC_OUTPUT_OBJ
)
2511 note
= create_bsd_note_section (s1
, ".note.netbsd.ident", "NetBSD");
2518 interp
= dynamic
= dynstr
= NULL
; /* avoid warning */
2520 #ifndef ELF_OBJ_ONLY
2521 if (file_type
!= TCC_OUTPUT_OBJ
) {
2522 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2523 tcc_add_runtime(s1
);
2524 resolve_common_syms(s1
);
2526 if (!s1
->static_link
) {
2527 if (file_type
== TCC_OUTPUT_EXE
) {
2529 /* allow override the dynamic loader */
2530 const char *elfint
= getenv("LD_SO");
2532 elfint
= DEFAULT_ELFINTERP(s1
);
2533 /* add interpreter section only if executable */
2534 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
2535 interp
->sh_addralign
= 1;
2536 ptr
= section_ptr_add(interp
, 1 + strlen(elfint
));
2537 strcpy(ptr
, elfint
);
2540 /* add dynamic symbol table */
2541 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
2543 ".hash", SHF_ALLOC
);
2544 /* Number of local symbols (readelf complains if not set) */
2545 s1
->dynsym
->sh_info
= 1;
2546 dynstr
= s1
->dynsym
->link
;
2547 /* add dynamic section */
2548 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
2549 SHF_ALLOC
| SHF_WRITE
);
2550 dynamic
->link
= dynstr
;
2551 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
2555 if (file_type
== TCC_OUTPUT_EXE
) {
2556 bind_exe_dynsyms(s1
);
2559 bind_libs_dynsyms(s1
);
2561 /* shared library case: simply export all global symbols */
2562 export_global_syms(s1
);
2565 build_got_entries(s1
);
2570 /* we add a section for symbols */
2571 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
2572 put_elf_str(strsec
, "");
2574 /* Allocate strings for section names */
2575 ret
= alloc_sec_names(s1
, file_type
, strsec
);
2577 #ifndef ELF_OBJ_ONLY
2580 /* add a list of needed dlls */
2581 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2582 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
2583 if (dllref
->level
== 0)
2584 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
2588 put_dt(dynamic
, s1
->enable_new_dtags
? DT_RUNPATH
: DT_RPATH
,
2589 put_elf_str(dynstr
, s1
->rpath
));
2591 if (file_type
== TCC_OUTPUT_DLL
) {
2593 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
2594 /* XXX: currently, since we do not handle PIC code, we
2595 must relocate the readonly segments */
2597 put_dt(dynamic
, DT_TEXTREL
, 0);
2601 put_dt(dynamic
, DT_SYMBOLIC
, 0);
2603 dyninf
.dynamic
= dynamic
;
2604 dyninf
.dynstr
= dynstr
;
2605 /* remember offset and reserve space for 2nd call below */
2606 dyninf
.data_offset
= dynamic
->data_offset
;
2607 fill_dynamic(s1
, &dyninf
);
2608 dynamic
->sh_size
= dynamic
->data_offset
;
2609 dynstr
->sh_size
= dynstr
->data_offset
;
2613 for (i
= 1; i
< s1
->nb_sections
&&
2614 !(s1
->sections
[i
]->sh_flags
& SHF_TLS
); i
++);
2615 phfill
= 2 + (i
< s1
->nb_sections
);
2617 /* compute number of program headers */
2618 if (file_type
== TCC_OUTPUT_OBJ
)
2620 else if (file_type
== TCC_OUTPUT_DLL
)
2622 else if (s1
->static_link
)
2625 phnum
= 5 + (i
< s1
->nb_sections
);
2628 phnum
+= note
!= NULL
;
2630 #if !TARGETOS_FreeBSD && !TARGETOS_NetBSD && !defined(__APPLE__) && !defined(_WIN32)
2632 if (file_type
!= TCC_OUTPUT_OBJ
) {
2638 /* allocate program segment headers */
2639 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
2641 /* compute number of sections */
2642 shnum
= s1
->nb_sections
;
2644 /* this array is used to reorder sections in the output file */
2645 sec_order
= tcc_malloc(sizeof(int) * shnum
);
2648 /* compute section to program header mapping */
2649 file_offset
= layout_sections(s1
, phdr
, phnum
, phfill
, interp
, strsec
,
2650 &dyninf
, &roinf
, sec_order
);
2652 #ifndef ELF_OBJ_ONLY
2653 /* Fill remaining program header and finalize relocation related to dynamic
2655 if (file_type
!= TCC_OUTPUT_OBJ
) {
2656 fill_unloadable_phdr(phdr
, phnum
, interp
, dynamic
, note
, roinf_use
);
2659 dynamic
->data_offset
= dyninf
.data_offset
;
2660 fill_dynamic(s1
, &dyninf
);
2662 /* put in GOT the dynamic section address and relocate PLT */
2663 write32le(s1
->got
->data
, dynamic
->sh_addr
);
2664 if (file_type
== TCC_OUTPUT_EXE
2665 || (RELOCATE_DLLPLT
&& file_type
== TCC_OUTPUT_DLL
))
2668 /* relocate symbols in .dynsym now that final addresses are known */
2669 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
)) {
2670 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
) {
2671 /* do symbol relocation */
2672 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
2677 /* if building executable or DLL, then relocate each section
2678 except the GOT which is already relocated */
2679 ret
= final_sections_reloc(s1
);
2682 tidy_section_headers(s1
, sec_order
);
2684 /* Perform relocation to GOT or PLT entries */
2685 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2688 fill_local_got_entries(s1
);
2692 /* Create the ELF file with name 'filename' */
2693 ret
= tcc_write_elf_file(s1
, filename
, phnum
, phdr
, file_offset
, sec_order
);
2694 s1
->nb_sections
= shnum
;
2697 tcc_free(sec_order
);
2702 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2705 #ifdef TCC_TARGET_PE
2706 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2707 ret
= pe_output_file(s
, filename
);
2709 #elif TCC_TARGET_MACHO
2710 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2711 ret
= macho_output_file(s
, filename
);
2714 ret
= elf_output_file(s
, filename
);
2718 ST_FUNC ssize_t
full_read(int fd
, void *buf
, size_t count
) {
2722 ssize_t num
= read(fd
, cbuf
, count
-rnum
);
2723 if (num
< 0) return num
;
2724 if (num
== 0) return rnum
;
2730 ST_FUNC
void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2734 data
= tcc_malloc(size
);
2735 lseek(fd
, file_offset
, SEEK_SET
);
2736 full_read(fd
, data
, size
);
2740 typedef struct SectionMergeInfo
{
2741 Section
*s
; /* corresponding existing section */
2742 unsigned long offset
; /* offset of the new section in the existing section */
2743 uint8_t new_section
; /* true if section 's' was added */
2744 uint8_t link_once
; /* true if link once section */
2747 ST_FUNC
int tcc_object_type(int fd
, ElfW(Ehdr
) *h
)
2749 int size
= full_read(fd
, h
, sizeof *h
);
2750 if (size
== sizeof *h
&& 0 == memcmp(h
, ELFMAG
, 4)) {
2751 if (h
->e_type
== ET_REL
)
2752 return AFF_BINTYPE_REL
;
2753 if (h
->e_type
== ET_DYN
)
2754 return AFF_BINTYPE_DYN
;
2755 } else if (size
>= 8) {
2756 if (0 == memcmp(h
, ARMAG
, 8))
2757 return AFF_BINTYPE_AR
;
2758 #ifdef TCC_TARGET_COFF
2759 if (((struct filehdr
*)h
)->f_magic
== COFF_C67_MAGIC
)
2760 return AFF_BINTYPE_C67
;
2766 /* load an object file and merge it with current files */
2767 /* XXX: handle correctly stab (debug) info */
2768 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
2769 int fd
, unsigned long file_offset
)
2772 ElfW(Shdr
) *shdr
, *sh
;
2773 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
, seencompressed
;
2774 char *strsec
, *strtab
;
2775 int stab_index
, stabstr_index
;
2776 int *old_to_new_syms
;
2777 char *sh_name
, *name
;
2778 SectionMergeInfo
*sm_table
, *sm
;
2779 ElfW(Sym
) *sym
, *symtab
;
2782 unsigned int *used_offset
;
2784 lseek(fd
, file_offset
, SEEK_SET
);
2785 if (tcc_object_type(fd
, &ehdr
) != AFF_BINTYPE_REL
)
2787 /* test CPU specific stuff */
2788 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2789 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2791 tcc_error_noabort("invalid object file");
2795 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2796 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2797 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2798 used_offset
= tcc_mallocz(sizeof(*used_offset
) * s1
->nb_sections
);
2800 /* load section names */
2801 sh
= &shdr
[ehdr
.e_shstrndx
];
2802 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2804 /* load symtab and strtab */
2805 old_to_new_syms
= NULL
;
2810 stab_index
= stabstr_index
= 0;
2812 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2814 if (sh
->sh_type
== SHT_SYMTAB
) {
2816 tcc_error_noabort("object must contain only one symtab");
2821 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2822 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2823 sm_table
[i
].s
= symtab_section
;
2825 /* now load strtab */
2826 sh
= &shdr
[sh
->sh_link
];
2827 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2829 if (sh
->sh_flags
& SHF_COMPRESSED
)
2833 /* now examine each section and try to merge its content with the
2835 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2836 /* no need to examine section name strtab */
2837 if (i
== ehdr
.e_shstrndx
)
2840 if (sh
->sh_type
== SHT_RELX
)
2841 sh
= &shdr
[sh
->sh_info
];
2842 /* ignore sections types we do not handle (plus relocs to those) */
2843 if (sh
->sh_type
!= SHT_PROGBITS
&&
2845 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2847 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2848 sh
->sh_type
!= SHT_X86_64_UNWIND
&&
2850 sh
->sh_type
!= SHT_NOTE
&&
2851 sh
->sh_type
!= SHT_NOBITS
&&
2852 sh
->sh_type
!= SHT_PREINIT_ARRAY
&&
2853 sh
->sh_type
!= SHT_INIT_ARRAY
&&
2854 sh
->sh_type
!= SHT_FINI_ARRAY
&&
2855 strcmp(strsec
+ sh
->sh_name
, ".stabstr")
2859 && !strncmp(strsec
+ sh
->sh_name
, ".debug_", sizeof(".debug_")-1))
2863 sh_name
= strsec
+ sh
->sh_name
;
2864 if (sh
->sh_addralign
< 1)
2865 sh
->sh_addralign
= 1;
2866 /* find corresponding section, if any */
2867 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2868 s
= s1
->sections
[j
];
2869 if (!strcmp(s
->name
, sh_name
)) {
2870 if (!strncmp(sh_name
, ".gnu.linkonce",
2871 sizeof(".gnu.linkonce") - 1)) {
2872 /* if a 'linkonce' section is already present, we
2873 do not add it again. It is a little tricky as
2874 symbols can still be defined in
2876 sm_table
[i
].link_once
= 1;
2880 if (s
== stab_section
)
2882 if (s
== stab_section
->link
)
2888 /* not found: create new section */
2889 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
& ~SHF_GROUP
);
2890 /* take as much info as possible from the section. sh_link and
2891 sh_info will be updated later */
2892 s
->sh_addralign
= sh
->sh_addralign
;
2893 s
->sh_entsize
= sh
->sh_entsize
;
2894 sm_table
[i
].new_section
= 1;
2895 used_offset
= tcc_realloc(used_offset
, sizeof(*used_offset
) * s1
->nb_sections
);
2898 if (sh
->sh_type
!= s
->sh_type
) {
2899 #if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD
2900 if (strcmp (s
->name
, ".eh_frame"))
2903 tcc_error_noabort("invalid section type");
2907 /* align start of section */
2908 s
->data_offset
+= -s
->data_offset
& (sh
->sh_addralign
- 1);
2909 if (sh
->sh_addralign
> s
->sh_addralign
)
2910 s
->sh_addralign
= sh
->sh_addralign
;
2911 sm_table
[i
].offset
= used_offset
[j
] + s
->data_offset
;
2912 used_offset
[j
] = sm_table
[i
].offset
;
2914 /* concatenate sections */
2916 if (sh
->sh_type
!= SHT_NOBITS
) {
2918 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2919 ptr
= section_ptr_add(s
, size
);
2920 full_read(fd
, ptr
, size
);
2922 s
->data_offset
+= size
;
2927 /* gr relocate stab strings */
2928 if (stab_index
&& stabstr_index
) {
2931 s
= sm_table
[stab_index
].s
;
2932 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2933 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2934 o
= sm_table
[stabstr_index
].offset
;
2942 /* second short pass to update sh_link and sh_info fields of new
2944 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2946 if (!s
|| !sm_table
[i
].new_section
)
2949 if (sh
->sh_link
> 0)
2950 s
->link
= sm_table
[sh
->sh_link
].s
;
2951 if (sh
->sh_type
== SHT_RELX
) {
2952 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2953 /* update backward link */
2954 s1
->sections
[s
->sh_info
]->reloc
= s
;
2958 /* resolve symbols */
2959 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2962 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2963 if (sym
->st_shndx
!= SHN_UNDEF
&&
2964 sym
->st_shndx
< SHN_LORESERVE
) {
2965 sm
= &sm_table
[sym
->st_shndx
];
2966 if (sm
->link_once
) {
2967 /* if a symbol is in a link once section, we use the
2968 already defined symbol. It is very important to get
2969 correct relocations */
2970 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2971 name
= strtab
+ sym
->st_name
;
2972 sym_index
= find_elf_sym(symtab_section
, name
);
2974 old_to_new_syms
[i
] = sym_index
;
2978 /* if no corresponding section added, no need to add symbol */
2981 /* convert section number */
2982 sym
->st_shndx
= sm
->s
->sh_num
;
2984 sym
->st_value
+= sm
->offset
;
2987 name
= strtab
+ sym
->st_name
;
2988 sym_index
= set_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2989 sym
->st_info
, sym
->st_other
,
2990 sym
->st_shndx
, name
);
2991 old_to_new_syms
[i
] = sym_index
;
2994 /* third pass to patch relocation entries */
2995 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
3000 offset
= sm_table
[i
].offset
;
3001 switch(s
->sh_type
) {
3003 /* take relocation offset information */
3004 offseti
= sm_table
[sh
->sh_info
].offset
;
3005 for_each_elem(s
, (offset
/ sizeof(*rel
)), rel
, ElfW_Rel
) {
3008 /* convert symbol index */
3009 type
= ELFW(R_TYPE
)(rel
->r_info
);
3010 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
3011 /* NOTE: only one symtab assumed */
3012 if (sym_index
>= nb_syms
)
3014 sym_index
= old_to_new_syms
[sym_index
];
3015 /* ignore link_once in rel section. */
3016 if (!sym_index
&& !sm_table
[sh
->sh_info
].link_once
3017 #ifdef TCC_TARGET_ARM
3018 && type
!= R_ARM_V4BX
3019 #elif defined TCC_TARGET_RISCV64
3020 && type
!= R_RISCV_ALIGN
3021 && type
!= R_RISCV_RELAX
3025 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
3026 i
, strsec
+ sh
->sh_name
, (int)rel
->r_offset
);
3029 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
3030 /* offset the relocation offset */
3031 rel
->r_offset
+= offseti
;
3032 #ifdef TCC_TARGET_ARM
3033 /* Jumps and branches from a Thumb code to a PLT entry need
3034 special handling since PLT entries are ARM code.
3035 Unconditional bl instructions referencing PLT entries are
3036 handled by converting these instructions into blx
3037 instructions. Other case of instructions referencing a PLT
3038 entry require to add a Thumb stub before the PLT entry to
3039 switch to ARM mode. We set bit plt_thumb_stub of the
3040 attribute of a symbol to indicate such a case. */
3041 if (type
== R_ARM_THM_JUMP24
)
3042 get_sym_attr(s1
, sym_index
, 1)->plt_thumb_stub
= 1;
3055 tcc_free(old_to_new_syms
);
3057 tcc_free(used_offset
);
3063 typedef struct ArchiveHeader
{
3064 char ar_name
[16]; /* name of this member */
3065 char ar_date
[12]; /* file mtime */
3066 char ar_uid
[6]; /* owner uid; printed as decimal */
3067 char ar_gid
[6]; /* owner gid; printed as decimal */
3068 char ar_mode
[8]; /* file mode, printed as octal */
3069 char ar_size
[10]; /* file size, printed as decimal */
3070 char ar_fmag
[2]; /* should contain ARFMAG */
3073 #define ARFMAG "`\n"
3075 static unsigned long long get_be(const uint8_t *b
, int n
)
3077 unsigned long long ret
= 0;
3079 ret
= (ret
<< 8) | *b
++, --n
;
3083 static int read_ar_header(int fd
, int offset
, ArchiveHeader
*hdr
)
3087 lseek(fd
, offset
, SEEK_SET
);
3088 len
= full_read(fd
, hdr
, sizeof(ArchiveHeader
));
3089 if (len
!= sizeof(ArchiveHeader
))
3090 return len
? -1 : 0;
3092 for (e
= p
+ sizeof hdr
->ar_name
; e
> p
&& e
[-1] == ' ';)
3095 hdr
->ar_size
[sizeof hdr
->ar_size
-1] = 0;
3099 /* load only the objects which resolve undefined symbols */
3100 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
, int entrysize
)
3102 int i
, bound
, nsyms
, sym_index
, len
, ret
= -1;
3103 unsigned long long off
;
3105 const char *ar_names
, *p
;
3106 const uint8_t *ar_index
;
3110 data
= tcc_malloc(size
);
3111 if (full_read(fd
, data
, size
) != size
)
3113 nsyms
= get_be(data
, entrysize
);
3114 ar_index
= data
+ entrysize
;
3115 ar_names
= (char *) ar_index
+ nsyms
* entrysize
;
3119 for (p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
3120 Section
*s
= symtab_section
;
3121 sym_index
= find_elf_sym(s
, p
);
3124 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
3125 if(sym
->st_shndx
!= SHN_UNDEF
)
3127 off
= get_be(ar_index
+ i
* entrysize
, entrysize
);
3128 len
= read_ar_header(fd
, off
, &hdr
);
3129 if (len
<= 0 || memcmp(hdr
.ar_fmag
, ARFMAG
, 2)) {
3130 tcc_error_noabort("invalid archive");
3134 if (s1
->verbose
== 2)
3135 printf(" -> %s\n", hdr
.ar_name
);
3136 if (tcc_load_object_file(s1
, fd
, off
) < 0)
3147 /* load a '.a' file */
3148 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
, int alacarte
)
3151 /* char magic[8]; */
3153 unsigned long file_offset
;
3156 /* skip magic which was already checked */
3157 /* full_read(fd, magic, sizeof(magic)); */
3158 file_offset
= sizeof ARMAG
- 1;
3161 len
= read_ar_header(fd
, file_offset
, &hdr
);
3165 tcc_error_noabort("invalid archive");
3169 size
= strtol(hdr
.ar_size
, NULL
, 0);
3171 size
= (size
+ 1) & ~1;
3173 /* coff symbol table : we handle it */
3174 if (!strcmp(hdr
.ar_name
, "/"))
3175 return tcc_load_alacarte(s1
, fd
, size
, 4);
3176 if (!strcmp(hdr
.ar_name
, "/SYM64/"))
3177 return tcc_load_alacarte(s1
, fd
, size
, 8);
3178 } else if (tcc_object_type(fd
, &ehdr
) == AFF_BINTYPE_REL
) {
3179 if (s1
->verbose
== 2)
3180 printf(" -> %s\n", hdr
.ar_name
);
3181 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
3184 file_offset
+= size
;
3188 #ifndef ELF_OBJ_ONLY
3189 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
3190 LV, maybe create a new entry for (LIB,VERSION). */
3191 static void set_ver_to_ver(TCCState
*s1
, int *n
, int **lv
, int i
, char *lib
, char *version
)
3194 *lv
= tcc_realloc(*lv
, (*n
+ 1) * sizeof(**lv
));
3197 if ((*lv
)[i
] == -1) {
3198 int v
, prev_same_lib
= -1;
3199 for (v
= 0; v
< nb_sym_versions
; v
++) {
3200 if (strcmp(sym_versions
[v
].lib
, lib
))
3203 if (!strcmp(sym_versions
[v
].version
, version
))
3206 if (v
== nb_sym_versions
) {
3207 sym_versions
= tcc_realloc (sym_versions
,
3208 (v
+ 1) * sizeof(*sym_versions
));
3209 sym_versions
[v
].lib
= tcc_strdup(lib
);
3210 sym_versions
[v
].version
= tcc_strdup(version
);
3211 sym_versions
[v
].out_index
= 0;
3212 sym_versions
[v
].prev_same_lib
= prev_same_lib
;
3219 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3222 set_sym_version(TCCState
*s1
, int sym_index
, int verndx
)
3224 if (sym_index
>= nb_sym_to_version
) {
3225 int newelems
= sym_index
? sym_index
* 2 : 1;
3226 sym_to_version
= tcc_realloc(sym_to_version
,
3227 newelems
* sizeof(*sym_to_version
));
3228 memset(sym_to_version
+ nb_sym_to_version
, -1,
3229 (newelems
- nb_sym_to_version
) * sizeof(*sym_to_version
));
3230 nb_sym_to_version
= newelems
;
3232 if (sym_to_version
[sym_index
] < 0)
3233 sym_to_version
[sym_index
] = verndx
;
3236 struct versym_info
{
3238 ElfW(Verdef
) *verdef
;
3239 ElfW(Verneed
) *verneed
;
3241 int nb_local_ver
, *local_ver
;
3245 static void store_version(TCCState
*s1
, struct versym_info
*v
, char *dynstr
)
3247 char *lib
, *version
;
3251 #define DEBUG_VERSION 0
3253 if (v
->versym
&& v
->verdef
) {
3254 ElfW(Verdef
) *vdef
= v
->verdef
;
3257 ElfW(Verdaux
) *verdaux
=
3258 (ElfW(Verdaux
) *) (((char *) vdef
) + vdef
->vd_aux
);
3261 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3262 vdef
->vd_version
, vdef
->vd_flags
, vdef
->vd_ndx
,
3266 version
= dynstr
+ verdaux
->vda_name
;
3271 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vdef
->vd_ndx
,
3274 printf (" verdaux(%u): %s\n", vdef
->vd_ndx
, version
);
3277 next
= vdef
->vd_next
;
3278 vdef
= (ElfW(Verdef
) *) (((char *) vdef
) + next
);
3281 if (v
->versym
&& v
->verneed
) {
3282 ElfW(Verneed
) *vneed
= v
->verneed
;
3284 ElfW(Vernaux
) *vernaux
=
3285 (ElfW(Vernaux
) *) (((char *) vneed
) + vneed
->vn_aux
);
3287 lib
= dynstr
+ vneed
->vn_file
;
3289 printf ("verneed: %u %s\n", vneed
->vn_version
, lib
);
3291 for (i
= 0; i
< vneed
->vn_cnt
; i
++) {
3292 if ((vernaux
->vna_other
& 0x8000) == 0) { /* hidden */
3293 version
= dynstr
+ vernaux
->vna_name
;
3294 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vernaux
->vna_other
,
3297 printf (" vernaux(%u): %u %u %s\n",
3298 vernaux
->vna_other
, vernaux
->vna_hash
,
3299 vernaux
->vna_flags
, version
);
3302 vernaux
= (ElfW(Vernaux
) *) (((char *) vernaux
) + vernaux
->vna_next
);
3304 next
= vneed
->vn_next
;
3305 vneed
= (ElfW(Verneed
) *) (((char *) vneed
) + next
);
3310 for (i
= 0; i
< v
->nb_local_ver
; i
++) {
3311 if (v
->local_ver
[i
] > 0) {
3312 printf ("%d: lib: %s, version %s\n",
3313 i
, sym_versions
[v
->local_ver
[i
]].lib
,
3314 sym_versions
[v
->local_ver
[i
]].version
);
3320 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3321 is referenced by the user (so it should be added as DT_NEEDED in
3322 the generated ELF file) */
3323 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
3326 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
3327 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
3328 ElfW(Sym
) *sym
, *dynsym
;
3329 ElfW(Dyn
) *dt
, *dynamic
;
3333 const char *name
, *soname
;
3334 DLLReference
*dllref
;
3335 struct versym_info v
;
3337 full_read(fd
, &ehdr
, sizeof(ehdr
));
3339 /* test CPU specific stuff */
3340 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
3341 ehdr
.e_machine
!= EM_TCC_TARGET
) {
3342 tcc_error_noabort("bad architecture");
3347 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
3349 /* load dynamic section and dynamic symbols */
3353 dynsym
= NULL
; /* avoid warning */
3354 dynstr
= NULL
; /* avoid warning */
3355 memset(&v
, 0, sizeof v
);
3357 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
3358 switch(sh
->sh_type
) {
3360 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
3361 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3364 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
3365 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3366 sh1
= &shdr
[sh
->sh_link
];
3367 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
3369 case SHT_GNU_verdef
:
3370 v
.verdef
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3372 case SHT_GNU_verneed
:
3373 v
.verneed
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3375 case SHT_GNU_versym
:
3376 v
.nb_versyms
= sh
->sh_size
/ sizeof(ElfW(Half
));
3377 v
.versym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3384 /* compute the real library name */
3385 soname
= tcc_basename(filename
);
3387 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3388 if (dt
->d_tag
== DT_SONAME
) {
3389 soname
= dynstr
+ dt
->d_un
.d_val
;
3393 /* if the dll is already loaded, do not load it */
3394 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
3395 dllref
= s1
->loaded_dlls
[i
];
3396 if (!strcmp(soname
, dllref
->name
)) {
3397 /* but update level if needed */
3398 if (level
< dllref
->level
)
3399 dllref
->level
= level
;
3405 if (v
.nb_versyms
!= nb_syms
)
3406 tcc_free (v
.versym
), v
.versym
= NULL
;
3408 store_version(s1
, &v
, dynstr
);
3410 /* add the dll and its level */
3411 tcc_add_dllref(s1
, soname
)->level
= level
;
3413 /* add dynamic symbols in dynsym_section */
3414 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
3415 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
3416 if (sym_bind
== STB_LOCAL
)
3418 name
= dynstr
+ sym
->st_name
;
3419 sym_index
= set_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
3420 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
3422 ElfW(Half
) vsym
= v
.versym
[i
];
3423 if ((vsym
& 0x8000) == 0 && vsym
> 0 && vsym
< v
.nb_local_ver
)
3424 set_sym_version(s1
, sym_index
, v
.local_ver
[vsym
]);
3428 /* load all referenced DLLs */
3429 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3432 name
= dynstr
+ dt
->d_un
.d_val
;
3433 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
3434 dllref
= s1
->loaded_dlls
[j
];
3435 if (!strcmp(name
, dllref
->name
))
3436 goto already_loaded
;
3438 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
3439 tcc_error_noabort("referenced dll '%s' not found", name
);
3453 tcc_free(v
.local_ver
);
3455 tcc_free(v
.verneed
);
3460 #define LD_TOK_NAME 256
3461 #define LD_TOK_EOF (-1)
3463 static int ld_inp(TCCState
*s1
)
3471 if (1 == read(s1
->fd
, &b
, 1))
3476 /* return next ld script token */
3477 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
3494 if (ch
== '*') { /* comment */
3495 for (d
= 0;; d
= ch
) {
3497 if (ch
== CH_EOF
|| (ch
== '/' && d
== '*'))
3508 /* case 'a' ... 'z': */
3535 /* case 'A' ... 'z': */
3569 if (!((ch
>= 'a' && ch
<= 'z') ||
3570 (ch
>= 'A' && ch
<= 'Z') ||
3571 (ch
>= '0' && ch
<= '9') ||
3572 strchr("/.-_+=$:\\,~", ch
)))
3574 if ((q
- name
) < name_size
- 1) {
3593 static int ld_add_file(TCCState
*s1
, const char filename
[])
3595 if (filename
[0] == '/') {
3596 if (CONFIG_SYSROOT
[0] == '\0'
3597 && tcc_add_file_internal(s1
, filename
, AFF_TYPE_BIN
) == 0)
3599 filename
= tcc_basename(filename
);
3601 return tcc_add_dll(s1
, filename
, 0);
3604 static int ld_add_file_list(TCCState
*s1
, const char *cmd
, int as_needed
)
3606 char filename
[1024], libname
[1024];
3607 int t
, group
, nblibs
= 0, ret
= 0;
3610 group
= !strcmp(cmd
, "GROUP");
3612 s1
->new_undef_sym
= 0;
3613 t
= ld_next(s1
, filename
, sizeof(filename
));
3615 tcc_error_noabort("( expected");
3617 goto lib_parse_error
;
3619 t
= ld_next(s1
, filename
, sizeof(filename
));
3622 if (t
== LD_TOK_EOF
) {
3623 tcc_error_noabort("unexpected end of file");
3625 goto lib_parse_error
;
3626 } else if (t
== ')') {
3628 } else if (t
== '-') {
3629 t
= ld_next(s1
, filename
, sizeof(filename
));
3630 if ((t
!= LD_TOK_NAME
) || (filename
[0] != 'l')) {
3631 tcc_error_noabort("library name expected");
3633 goto lib_parse_error
;
3635 pstrcpy(libname
, sizeof libname
, &filename
[1]);
3636 if (s1
->static_link
) {
3637 snprintf(filename
, sizeof filename
, "lib%s.a", libname
);
3639 snprintf(filename
, sizeof filename
, "lib%s.so", libname
);
3641 } else if (t
!= LD_TOK_NAME
) {
3642 tcc_error_noabort("filename expected");
3644 goto lib_parse_error
;
3646 if (!strcmp(filename
, "AS_NEEDED")) {
3647 ret
= ld_add_file_list(s1
, cmd
, 1);
3649 goto lib_parse_error
;
3651 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3653 ret
= ld_add_file(s1
, filename
);
3655 goto lib_parse_error
;
3657 /* Add the filename *and* the libname to avoid future conversions */
3658 dynarray_add(&libs
, &nblibs
, tcc_strdup(filename
));
3659 if (libname
[0] != '\0')
3660 dynarray_add(&libs
, &nblibs
, tcc_strdup(libname
));
3664 t
= ld_next(s1
, filename
, sizeof(filename
));
3666 t
= ld_next(s1
, filename
, sizeof(filename
));
3669 if (group
&& !as_needed
) {
3670 while (s1
->new_undef_sym
) {
3672 s1
->new_undef_sym
= 0;
3673 for (i
= 0; i
< nblibs
; i
++)
3674 ld_add_file(s1
, libs
[i
]);
3678 dynarray_reset(&libs
, &nblibs
);
3682 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3684 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
, int fd
)
3687 char filename
[1024];
3693 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3694 if (t
== LD_TOK_EOF
)
3696 else if (t
!= LD_TOK_NAME
)
3698 if (!strcmp(cmd
, "INPUT") ||
3699 !strcmp(cmd
, "GROUP")) {
3700 ret
= ld_add_file_list(s1
, cmd
, 0);
3703 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
3704 !strcmp(cmd
, "TARGET")) {
3705 /* ignore some commands */
3706 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3708 tcc_error_noabort("( expected");
3712 t
= ld_next(s1
, filename
, sizeof(filename
));
3713 if (t
== LD_TOK_EOF
) {
3714 tcc_error_noabort("unexpected end of file");
3716 } else if (t
== ')') {
3726 #endif /* !ELF_OBJ_ONLY */