2 * ELF file handling for TCC
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 /* Define this to get some debug output during relocation processing. */
26 /********************************************************/
27 /* global variables */
29 /* elf version information */
37 #define nb_sym_versions s1->nb_sym_versions
38 #define sym_versions s1->sym_versions
39 #define nb_sym_to_version s1->nb_sym_to_version
40 #define sym_to_version s1->sym_to_version
41 #define dt_verneednum s1->dt_verneednum
42 #define versym_section s1->versym_section
43 #define verneed_section s1->verneed_section
45 /* special flag to indicate that the section should not be linked to the other ones */
46 #define SHF_PRIVATE 0x80000000
47 /* section is dynsymtab_section */
48 #define SHF_DYNSYM 0x40000000
50 /* ------------------------------------------------------------------------- */
52 ST_FUNC
void tccelf_new(TCCState
*s
)
56 dynarray_add(&s
->sections
, &s
->nb_sections
, NULL
);
58 /* create standard sections */
59 text_section
= new_section(s
, ".text", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
60 data_section
= new_section(s
, ".data", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
61 bss_section
= new_section(s
, ".bss", SHT_NOBITS
, SHF_ALLOC
| SHF_WRITE
);
62 common_section
= new_section(s
, ".common", SHT_NOBITS
, SHF_PRIVATE
);
63 common_section
->sh_num
= SHN_COMMON
;
65 /* symbols are always generated for linking stage */
66 symtab_section
= new_symtab(s
, ".symtab", SHT_SYMTAB
, 0,
68 ".hashtab", SHF_PRIVATE
);
69 s
->symtab
= symtab_section
;
71 /* private symbol table for dynamic symbols */
72 s
->dynsymtab_section
= new_symtab(s
, ".dynsymtab", SHT_SYMTAB
, SHF_PRIVATE
|SHF_DYNSYM
,
74 ".dynhashtab", SHF_PRIVATE
);
75 get_sym_attr(s
, 0, 1);
78 #ifdef CONFIG_TCC_BCHECK
79 ST_FUNC
void tccelf_bounds_new(TCCState
*s
)
82 /* create bounds sections */
83 bounds_section
= new_section(s
, ".bounds",
84 SHT_PROGBITS
, SHF_ALLOC
);
85 lbounds_section
= new_section(s
, ".lbounds",
86 SHT_PROGBITS
, SHF_ALLOC
);
90 ST_FUNC
void tccelf_stab_new(TCCState
*s
)
94 #ifdef CONFIG_TCC_BACKTRACE
95 /* include stab info with standalone backtrace support */
96 if (s
->do_backtrace
&& s
->output_type
!= TCC_OUTPUT_MEMORY
)
99 stab_section
= new_section(s
, ".stab", SHT_PROGBITS
, shf
);
100 stab_section
->sh_entsize
= sizeof(Stab_Sym
);
101 stab_section
->sh_addralign
= sizeof ((Stab_Sym
*)0)->n_value
;
102 stab_section
->link
= new_section(s
, ".stabstr", SHT_STRTAB
, shf
);
103 /* put first entry */
104 put_stabs(s
, "", 0, 0, 0, 0);
107 static void free_section(Section
*s
)
112 ST_FUNC
void tccelf_delete(TCCState
*s1
)
117 /* free symbol versions */
118 for (i
= 0; i
< nb_sym_versions
; i
++) {
119 tcc_free(sym_versions
[i
].version
);
120 tcc_free(sym_versions
[i
].lib
);
122 tcc_free(sym_versions
);
123 tcc_free(sym_to_version
);
126 /* free all sections */
127 for(i
= 1; i
< s1
->nb_sections
; i
++)
128 free_section(s1
->sections
[i
]);
129 dynarray_reset(&s1
->sections
, &s1
->nb_sections
);
131 for(i
= 0; i
< s1
->nb_priv_sections
; i
++)
132 free_section(s1
->priv_sections
[i
]);
133 dynarray_reset(&s1
->priv_sections
, &s1
->nb_priv_sections
);
135 /* free any loaded DLLs */
137 for ( i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
138 DLLReference
*ref
= s1
->loaded_dlls
[i
];
141 FreeLibrary((HMODULE
)ref
->handle
);
143 dlclose(ref
->handle
);
147 /* free loaded dlls array */
148 dynarray_reset(&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
);
149 tcc_free(s1
->sym_attrs
);
151 symtab_section
= NULL
; /* for tccrun.c:rt_printline() */
154 /* save section data state */
155 ST_FUNC
void tccelf_begin_file(TCCState
*s1
)
158 for (i
= 1; i
< s1
->nb_sections
; i
++) {
160 s
->sh_offset
= s
->data_offset
;
162 /* disable symbol hashing during compilation */
163 s
= s1
->symtab
, s
->reloc
= s
->hash
, s
->hash
= NULL
;
164 #if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
169 /* At the end of compilation, convert any UNDEF syms to global, and merge
170 with previously existing symbols */
171 ST_FUNC
void tccelf_end_file(TCCState
*s1
)
173 Section
*s
= s1
->symtab
;
174 int first_sym
, nb_syms
, *tr
, i
;
176 first_sym
= s
->sh_offset
/ sizeof (ElfSym
);
177 nb_syms
= s
->data_offset
/ sizeof (ElfSym
) - first_sym
;
178 s
->data_offset
= s
->sh_offset
;
179 s
->link
->data_offset
= s
->link
->sh_offset
;
180 s
->hash
= s
->reloc
, s
->reloc
= NULL
;
181 tr
= tcc_mallocz(nb_syms
* sizeof *tr
);
183 for (i
= 0; i
< nb_syms
; ++i
) {
184 ElfSym
*sym
= (ElfSym
*)s
->data
+ first_sym
+ i
;
185 if (sym
->st_shndx
== SHN_UNDEF
186 && ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
)
187 sym
->st_info
= ELFW(ST_INFO
)(STB_GLOBAL
, ELFW(ST_TYPE
)(sym
->st_info
));
188 tr
[i
] = set_elf_sym(s
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
189 sym
->st_other
, sym
->st_shndx
, (char*)s
->link
->data
+ sym
->st_name
);
191 /* now update relocations */
192 for (i
= 1; i
< s1
->nb_sections
; i
++) {
193 Section
*sr
= s1
->sections
[i
];
194 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
195 ElfW_Rel
*rel
= (ElfW_Rel
*)(sr
->data
+ sr
->sh_offset
);
196 ElfW_Rel
*rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
197 for (; rel
< rel_end
; ++rel
) {
198 int n
= ELFW(R_SYM
)(rel
->r_info
) - first_sym
;
199 //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
200 rel
->r_info
= ELFW(R_INFO
)(tr
[n
], ELFW(R_TYPE
)(rel
->r_info
));
207 ST_FUNC Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
211 sec
= tcc_mallocz(sizeof(Section
) + strlen(name
));
213 strcpy(sec
->name
, name
);
214 sec
->sh_type
= sh_type
;
215 sec
->sh_flags
= sh_flags
;
218 sec
->sh_addralign
= 2;
226 case SHT_GNU_verneed
:
228 sec
->sh_addralign
= PTR_SIZE
;
231 sec
->sh_addralign
= 1;
234 sec
->sh_addralign
= PTR_SIZE
; /* gcc/pcc default alignment */
238 if (sh_flags
& SHF_PRIVATE
) {
239 dynarray_add(&s1
->priv_sections
, &s1
->nb_priv_sections
, sec
);
241 sec
->sh_num
= s1
->nb_sections
;
242 dynarray_add(&s1
->sections
, &s1
->nb_sections
, sec
);
248 ST_FUNC Section
*new_symtab(TCCState
*s1
,
249 const char *symtab_name
, int sh_type
, int sh_flags
,
250 const char *strtab_name
,
251 const char *hash_name
, int hash_sh_flags
)
253 Section
*symtab
, *strtab
, *hash
;
254 int *ptr
, nb_buckets
;
256 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
257 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
258 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
259 put_elf_str(strtab
, "");
260 symtab
->link
= strtab
;
261 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
265 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
266 hash
->sh_entsize
= sizeof(int);
270 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
273 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
277 /* realloc section and set its content to zero */
278 ST_FUNC
void section_realloc(Section
*sec
, unsigned long new_size
)
283 size
= sec
->data_allocated
;
286 while (size
< new_size
)
288 data
= tcc_realloc(sec
->data
, size
);
289 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
291 sec
->data_allocated
= size
;
294 /* reserve at least 'size' bytes aligned per 'align' in section
295 'sec' from current offset, and return the aligned offset */
296 ST_FUNC
size_t section_add(Section
*sec
, addr_t size
, int align
)
298 size_t offset
, offset1
;
300 offset
= (sec
->data_offset
+ align
- 1) & -align
;
301 offset1
= offset
+ size
;
302 if (sec
->sh_type
!= SHT_NOBITS
&& offset1
> sec
->data_allocated
)
303 section_realloc(sec
, offset1
);
304 sec
->data_offset
= offset1
;
305 if (align
> sec
->sh_addralign
)
306 sec
->sh_addralign
= align
;
310 /* reserve at least 'size' bytes in section 'sec' from
312 ST_FUNC
void *section_ptr_add(Section
*sec
, addr_t size
)
314 size_t offset
= section_add(sec
, size
, 1);
315 return sec
->data
+ offset
;
318 /* reserve at least 'size' bytes from section start */
319 ST_FUNC
void section_reserve(Section
*sec
, unsigned long size
)
321 if (size
> sec
->data_allocated
)
322 section_realloc(sec
, size
);
323 if (size
> sec
->data_offset
)
324 sec
->data_offset
= size
;
327 static Section
*find_section_create (TCCState
*s1
, const char *name
, int create
)
331 for(i
= 1; i
< s1
->nb_sections
; i
++) {
332 sec
= s1
->sections
[i
];
333 if (!strcmp(name
, sec
->name
))
336 /* sections are created as PROGBITS */
337 return create
? new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
) : NULL
;
340 /* return a reference to a section, and create it if it does not
342 ST_FUNC Section
*find_section(TCCState
*s1
, const char *name
)
344 return find_section_create (s1
, name
, 1);
347 /* ------------------------------------------------------------------------- */
349 ST_FUNC
int put_elf_str(Section
*s
, const char *sym
)
354 len
= strlen(sym
) + 1;
355 offset
= s
->data_offset
;
356 ptr
= section_ptr_add(s
, len
);
357 memmove(ptr
, sym
, len
);
361 /* elf symbol hashing function */
362 static unsigned long elf_hash(const unsigned char *name
)
364 unsigned long h
= 0, g
;
367 h
= (h
<< 4) + *name
++;
376 /* rebuild hash table of section s */
377 /* NOTE: we do factorize the hash table code to go faster */
378 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
381 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
382 unsigned char *strtab
;
384 strtab
= s
->link
->data
;
385 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
388 nb_buckets
= ((int*)s
->hash
->data
)[0];
390 s
->hash
->data_offset
= 0;
391 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
396 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
397 ptr
+= nb_buckets
+ 1;
399 sym
= (ElfW(Sym
) *)s
->data
+ 1;
400 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
401 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
402 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
413 /* return the symbol number */
414 ST_FUNC
int put_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
415 int info
, int other
, int shndx
, const char *name
)
417 int name_offset
, sym_index
;
422 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
424 name_offset
= put_elf_str(s
->link
, name
);
427 /* XXX: endianness */
428 sym
->st_name
= name_offset
;
429 sym
->st_value
= value
;
432 sym
->st_other
= other
;
433 sym
->st_shndx
= shndx
;
434 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
438 ptr
= section_ptr_add(hs
, sizeof(int));
439 base
= (int *)hs
->data
;
440 /* only add global or weak symbols. */
441 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
442 /* add another hashing entry */
444 h
= elf_hash((unsigned char *)s
->link
->data
+ name_offset
) % nbuckets
;
446 base
[2 + h
] = sym_index
;
448 /* we resize the hash table */
449 hs
->nb_hashed_syms
++;
450 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
451 rebuild_hash(s
, 2 * nbuckets
);
461 ST_FUNC
int find_elf_sym(Section
*s
, const char *name
)
465 int nbuckets
, sym_index
, h
;
471 nbuckets
= ((int *)hs
->data
)[0];
472 h
= elf_hash((unsigned char *) name
) % nbuckets
;
473 sym_index
= ((int *)hs
->data
)[2 + h
];
474 while (sym_index
!= 0) {
475 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
476 name1
= (char *) s
->link
->data
+ sym
->st_name
;
477 if (!strcmp(name
, name1
))
479 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
484 /* return elf symbol value, signal error if 'err' is nonzero, decorate
486 ST_FUNC addr_t
get_sym_addr(TCCState
*s1
, const char *name
, int err
, int forc
)
491 if (forc
&& s1
->leading_underscore
493 /* win32-32bit stdcall symbols always have _ already */
494 && !strchr(name
, '@')
498 pstrcpy(buf
+ 1, sizeof(buf
) - 1, name
);
501 sym_index
= find_elf_sym(s1
->symtab
, name
);
502 sym
= &((ElfW(Sym
) *)s1
->symtab
->data
)[sym_index
];
503 if (!sym_index
|| sym
->st_shndx
== SHN_UNDEF
) {
505 tcc_error("%s not defined", name
);
508 return sym
->st_value
;
511 /* return elf symbol value */
512 LIBTCCAPI
void *tcc_get_symbol(TCCState
*s
, const char *name
)
514 addr_t addr
= get_sym_addr(s
, name
, 0, 1);
515 return addr
== -1 ? NULL
: (void*)(uintptr_t)addr
;
518 /* list elf symbol names and values */
519 ST_FUNC
void list_elf_symbols(TCCState
*s
, void *ctx
,
520 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
524 int sym_index
, end_sym
;
526 unsigned char sym_vis
, sym_bind
;
529 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
530 for (sym_index
= 0; sym_index
< end_sym
; ++sym_index
) {
531 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
533 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
534 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
535 sym_vis
= ELFW(ST_VISIBILITY
)(sym
->st_other
);
536 if (sym_bind
== STB_GLOBAL
&& sym_vis
== STV_DEFAULT
)
537 symbol_cb(ctx
, name
, (void*)(uintptr_t)sym
->st_value
);
542 /* list elf symbol names and values */
543 LIBTCCAPI
void tcc_list_symbols(TCCState
*s
, void *ctx
,
544 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
546 list_elf_symbols(s
, ctx
, symbol_cb
);
551 version_add (TCCState
*s1
)
555 ElfW(Verneed
) *vn
= NULL
;
557 int sym_index
, end_sym
, nb_versions
= 2, nb_entries
= 0;
561 if (0 == nb_sym_versions
)
563 versym_section
= new_section(s1
, ".gnu.version", SHT_GNU_versym
, SHF_ALLOC
);
564 versym_section
->sh_entsize
= sizeof(ElfW(Half
));
565 versym_section
->link
= s1
->dynsym
;
567 /* add needed symbols */
569 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
570 versym
= section_ptr_add(versym_section
, end_sym
* sizeof(ElfW(Half
)));
571 for (sym_index
= 0; sym_index
< end_sym
; ++sym_index
) {
572 int dllindex
, verndx
;
573 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
574 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
575 dllindex
= find_elf_sym(s1
->dynsymtab_section
, name
);
576 verndx
= (dllindex
&& dllindex
< nb_sym_to_version
)
577 ? sym_to_version
[dllindex
] : -1;
579 if (!sym_versions
[verndx
].out_index
)
580 sym_versions
[verndx
].out_index
= nb_versions
++;
581 versym
[sym_index
] = sym_versions
[verndx
].out_index
;
583 versym
[sym_index
] = 0;
585 /* generate verneed section, but not when it will be empty. Some
586 dynamic linkers look at their contents even when DTVERNEEDNUM and
587 section size is zero. */
588 if (nb_versions
> 2) {
589 verneed_section
= new_section(s1
, ".gnu.version_r",
590 SHT_GNU_verneed
, SHF_ALLOC
);
591 verneed_section
->link
= s1
->dynsym
->link
;
592 for (i
= nb_sym_versions
; i
-- > 0;) {
593 struct sym_version
*sv
= &sym_versions
[i
];
594 int n_same_libs
= 0, prev
;
596 ElfW(Vernaux
) *vna
= 0;
597 if (sv
->out_index
< 1)
599 vnofs
= section_add(verneed_section
, sizeof(*vn
), 1);
600 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
602 vn
->vn_file
= put_elf_str(verneed_section
->link
, sv
->lib
);
603 vn
->vn_aux
= sizeof (*vn
);
605 prev
= sv
->prev_same_lib
;
606 if (sv
->out_index
> 0) {
607 vna
= section_ptr_add(verneed_section
, sizeof(*vna
));
608 vna
->vna_hash
= elf_hash ((const unsigned char *)sv
->version
);
610 vna
->vna_other
= sv
->out_index
;
612 vna
->vna_name
= put_elf_str(verneed_section
->link
, sv
->version
);
613 vna
->vna_next
= sizeof (*vna
);
617 sv
= &sym_versions
[prev
];
620 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
621 vn
->vn_cnt
= n_same_libs
;
622 vn
->vn_next
= sizeof(*vn
) + n_same_libs
* sizeof(*vna
);
627 verneed_section
->sh_info
= nb_entries
;
629 dt_verneednum
= nb_entries
;
633 /* add an elf symbol : check if it is already defined and patch
634 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
635 ST_FUNC
int set_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
636 int info
, int other
, int shndx
, const char *name
)
638 TCCState
*s1
= s
->s1
;
640 int sym_bind
, sym_index
, sym_type
, esym_bind
;
641 unsigned char sym_vis
, esym_vis
, new_vis
;
643 sym_bind
= ELFW(ST_BIND
)(info
);
644 sym_type
= ELFW(ST_TYPE
)(info
);
645 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
647 if (sym_bind
!= STB_LOCAL
) {
648 /* we search global or weak symbols */
649 sym_index
= find_elf_sym(s
, name
);
652 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
653 if (esym
->st_value
== value
&& esym
->st_size
== size
&& esym
->st_info
== info
654 && esym
->st_other
== other
&& esym
->st_shndx
== shndx
)
656 if (esym
->st_shndx
!= SHN_UNDEF
) {
657 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
658 /* propagate the most constraining visibility */
659 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
660 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
661 if (esym_vis
== STV_DEFAULT
) {
663 } else if (sym_vis
== STV_DEFAULT
) {
666 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
668 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
670 other
= esym
->st_other
; /* in case we have to patch esym */
671 if (shndx
== SHN_UNDEF
) {
672 /* ignore adding of undefined symbol if the
673 corresponding symbol is already defined */
674 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
675 /* global overrides weak, so patch */
677 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
678 /* weak is ignored if already global */
679 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_WEAK
) {
680 /* keep first-found weak definition, ignore subsequents */
681 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
682 /* ignore hidden symbols after */
683 } else if ((esym
->st_shndx
== SHN_COMMON
684 || esym
->st_shndx
== bss_section
->sh_num
)
685 && (shndx
< SHN_LORESERVE
686 && shndx
!= bss_section
->sh_num
)) {
687 /* data symbol gets precedence over common/bss */
689 } else if (shndx
== SHN_COMMON
|| shndx
== bss_section
->sh_num
) {
690 /* data symbol keeps precedence over common/bss */
691 } else if (s
->sh_flags
& SHF_DYNSYM
) {
692 /* we accept that two DLL define the same symbol */
693 } else if (esym
->st_other
& ST_ASM_SET
) {
694 /* If the existing symbol came from an asm .set
699 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
700 sym_bind
, shndx
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
702 tcc_error_noabort("'%s' defined twice", name
);
706 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
707 esym
->st_shndx
= shndx
;
708 s1
->new_undef_sym
= 1;
709 esym
->st_value
= value
;
710 esym
->st_size
= size
;
711 esym
->st_other
= other
;
715 sym_index
= put_elf_sym(s
, value
, size
,
716 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
723 ST_FUNC
void put_elf_reloca(Section
*symtab
, Section
*s
, unsigned long offset
,
724 int type
, int symbol
, addr_t addend
)
726 TCCState
*s1
= s
->s1
;
733 /* if no relocation section, create it */
734 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
735 /* if the symtab is allocated, then we consider the relocation
737 sr
= new_section(s
->s1
, buf
, SHT_RELX
, symtab
->sh_flags
);
738 sr
->sh_entsize
= sizeof(ElfW_Rel
);
740 sr
->sh_info
= s
->sh_num
;
743 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
744 rel
->r_offset
= offset
;
745 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
746 #if SHT_RELX == SHT_RELA
747 rel
->r_addend
= addend
;
749 if (SHT_RELX
!= SHT_RELA
&& addend
)
750 tcc_error("non-zero addend on REL architecture");
753 ST_FUNC
void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
754 int type
, int symbol
)
756 put_elf_reloca(symtab
, s
, offset
, type
, symbol
, 0);
759 /* Remove relocations for section S->reloc starting at oldrelocoffset
760 that are to the same place, retaining the last of them. As side effect
761 the relocations are sorted. Possibly reduces the number of relocs. */
762 ST_FUNC
void squeeze_multi_relocs(Section
*s
, size_t oldrelocoffset
)
764 Section
*sr
= s
->reloc
;
769 if (oldrelocoffset
+ sizeof(*r
) >= sr
->data_offset
)
771 /* The relocs we're dealing with are the result of initializer parsing.
772 So they will be mostly in order and there aren't many of them.
773 Secondly we need a stable sort (which qsort isn't). We use
774 a simple insertion sort. */
775 for (a
= oldrelocoffset
+ sizeof(*r
); a
< sr
->data_offset
; a
+= sizeof(*r
)) {
776 ssize_t i
= a
- sizeof(*r
);
777 addr
= ((ElfW_Rel
*)(sr
->data
+ a
))->r_offset
;
778 for (; i
>= (ssize_t
)oldrelocoffset
&&
779 ((ElfW_Rel
*)(sr
->data
+ i
))->r_offset
> addr
; i
-= sizeof(*r
)) {
780 ElfW_Rel tmp
= *(ElfW_Rel
*)(sr
->data
+ a
);
781 *(ElfW_Rel
*)(sr
->data
+ a
) = *(ElfW_Rel
*)(sr
->data
+ i
);
782 *(ElfW_Rel
*)(sr
->data
+ i
) = tmp
;
786 r
= (ElfW_Rel
*)(sr
->data
+ oldrelocoffset
);
788 for (; r
< (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
); r
++) {
789 if (dest
->r_offset
!= r
->r_offset
)
793 sr
->data_offset
= (unsigned char*)dest
- sr
->data
+ sizeof(*r
);
796 /* put stab debug information */
798 ST_FUNC
void put_stabs(TCCState
*s1
, const char *str
, int type
, int other
, int desc
,
805 && (offset
= stab_section
->data_offset
)
806 && (sym
= (Stab_Sym
*)(stab_section
->data
+ offset
) - 1)
807 && sym
->n_type
== type
808 && sym
->n_value
== value
) {
809 /* just update line_number in previous entry */
814 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
816 sym
->n_strx
= put_elf_str(stab_section
->link
, str
);
821 sym
->n_other
= other
;
823 sym
->n_value
= value
;
826 ST_FUNC
void put_stabs_r(TCCState
*s1
, const char *str
, int type
, int other
, int desc
,
827 unsigned long value
, Section
*sec
, int sym_index
)
829 put_elf_reloc(symtab_section
, stab_section
,
830 stab_section
->data_offset
+ 8,
831 sizeof ((Stab_Sym
*)0)->n_value
== PTR_SIZE
? R_DATA_PTR
: R_DATA_32
,
833 put_stabs(s1
, str
, type
, other
, desc
, value
);
836 ST_FUNC
void put_stabn(TCCState
*s1
, int type
, int other
, int desc
, int value
)
838 put_stabs(s1
, NULL
, type
, other
, desc
, value
);
841 ST_FUNC
struct sym_attr
*get_sym_attr(TCCState
*s1
, int index
, int alloc
)
844 struct sym_attr
*tab
;
846 if (index
>= s1
->nb_sym_attrs
) {
848 return s1
->sym_attrs
;
849 /* find immediately bigger power of 2 and reallocate array */
853 tab
= tcc_realloc(s1
->sym_attrs
, n
* sizeof(*s1
->sym_attrs
));
855 memset(s1
->sym_attrs
+ s1
->nb_sym_attrs
, 0,
856 (n
- s1
->nb_sym_attrs
) * sizeof(*s1
->sym_attrs
));
857 s1
->nb_sym_attrs
= n
;
859 return &s1
->sym_attrs
[index
];
862 /* In an ELF file symbol table, the local symbols must appear below
863 the global and weak ones. Since TCC cannot sort it while generating
864 the code, we must do it after. All the relocation tables are also
865 modified to take into account the symbol table sorting */
866 static void sort_syms(TCCState
*s1
, Section
*s
)
868 int *old_to_new_syms
;
876 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
877 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
878 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
880 /* first pass for local symbols */
881 p
= (ElfW(Sym
) *)s
->data
;
883 for(i
= 0; i
< nb_syms
; i
++) {
884 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
885 old_to_new_syms
[i
] = q
- new_syms
;
890 /* save the number of local symbols in section header */
891 if( s
->sh_size
) /* this 'if' makes IDA happy */
892 s
->sh_info
= q
- new_syms
;
894 /* then second pass for non local symbols */
895 p
= (ElfW(Sym
) *)s
->data
;
896 for(i
= 0; i
< nb_syms
; i
++) {
897 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
898 old_to_new_syms
[i
] = q
- new_syms
;
904 /* we copy the new symbols to the old */
905 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
908 /* now we modify all the relocations */
909 for(i
= 1; i
< s1
->nb_sections
; i
++) {
910 sr
= s1
->sections
[i
];
911 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
912 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
913 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
914 type
= ELFW(R_TYPE
)(rel
->r_info
);
915 sym_index
= old_to_new_syms
[sym_index
];
916 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
921 tcc_free(old_to_new_syms
);
924 /* relocate symbol table, resolve undefined symbols if do_resolve is
925 true and output error if undefined symbol. */
926 ST_FUNC
void relocate_syms(TCCState
*s1
, Section
*symtab
, int do_resolve
)
929 int sym_bind
, sh_num
;
932 for_each_elem(symtab
, 1, sym
, ElfW(Sym
)) {
933 sh_num
= sym
->st_shndx
;
934 if (sh_num
== SHN_UNDEF
) {
935 name
= (char *) s1
->symtab
->link
->data
+ sym
->st_name
;
936 /* Use ld.so to resolve symbol for us (for tcc -run) */
938 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
939 #ifdef TCC_TARGET_MACHO
940 /* The symbols in the symtables have a prepended '_'
941 but dlsym() needs the undecorated name. */
942 void *addr
= dlsym(RTLD_DEFAULT
, name
+ 1);
944 void *addr
= dlsym(RTLD_DEFAULT
, name
);
947 sym
->st_value
= (addr_t
) addr
;
949 printf ("relocate_sym: %s -> 0x%lx\n", name
, sym
->st_value
);
954 /* if dynamic symbol exist, it will be used in relocate_section */
955 } else if (s1
->dynsym
&& find_elf_sym(s1
->dynsym
, name
))
957 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
959 if (!strcmp(name
, "_fp_hw"))
961 /* only weak symbols are accepted to be undefined. Their
963 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
964 if (sym_bind
== STB_WEAK
)
967 tcc_error_noabort("undefined symbol '%s'", name
);
968 } else if (sh_num
< SHN_LORESERVE
) {
969 /* add section base */
970 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
976 /* relocate a given section (CPU dependent) by applying the relocations
977 in the associated relocation section */
978 ST_FUNC
void relocate_section(TCCState
*s1
, Section
*s
)
980 Section
*sr
= s
->reloc
;
987 qrel
= (ElfW_Rel
*)sr
->data
;
989 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
990 ptr
= s
->data
+ rel
->r_offset
;
991 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
992 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
993 type
= ELFW(R_TYPE
)(rel
->r_info
);
995 #if SHT_RELX == SHT_RELA
996 tgt
+= rel
->r_addend
;
998 addr
= s
->sh_addr
+ rel
->r_offset
;
999 relocate(s1
, rel
, type
, ptr
, addr
, tgt
);
1001 /* if the relocation is allocated, we change its symbol table */
1002 if (sr
->sh_flags
& SHF_ALLOC
) {
1003 sr
->link
= s1
->dynsym
;
1004 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
1005 size_t r
= (uint8_t*)qrel
- sr
->data
;
1006 if (sizeof ((Stab_Sym
*)0)->n_value
< PTR_SIZE
1007 && 0 == strcmp(s
->name
, ".stab"))
1008 r
= 0; /* cannot apply 64bit relocation to 32bit value */
1009 sr
->data_offset
= sr
->sh_size
= r
;
1014 #ifndef ELF_OBJ_ONLY
1015 /* relocate relocation table in 'sr' */
1016 static void relocate_rel(TCCState
*s1
, Section
*sr
)
1021 s
= s1
->sections
[sr
->sh_info
];
1022 for_each_elem(sr
, 0, rel
, ElfW_Rel
)
1023 rel
->r_offset
+= s
->sh_addr
;
1026 /* count the number of dynamic relocations so that we can reserve
1028 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
1031 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1033 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
1034 int sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1035 int type
= ELFW(R_TYPE
)(rel
->r_info
);
1037 #if defined(TCC_TARGET_I386)
1039 if (!get_sym_attr(s1
, sym_index
, 0)->dyn_index
1040 && ((ElfW(Sym
)*)symtab_section
->data
+ sym_index
)->st_shndx
== SHN_UNDEF
) {
1041 /* don't fixup unresolved (weak) symbols */
1042 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_386_RELATIVE
);
1045 #elif defined(TCC_TARGET_X86_64)
1052 #if defined(TCC_TARGET_I386)
1054 #elif defined(TCC_TARGET_X86_64)
1057 if (get_sym_attr(s1
, sym_index
, 0)->dyn_index
)
1065 /* allocate the section */
1066 sr
->sh_flags
|= SHF_ALLOC
;
1067 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
1074 #if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE)
1075 static void build_got(TCCState
*s1
)
1077 /* if no got, then create it */
1078 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
1079 s1
->got
->sh_entsize
= 4;
1080 set_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
1081 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
1082 /* keep space for _DYNAMIC pointer and two dummy got entries */
1083 section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
1086 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1087 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1088 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1089 Returns the offset of the GOT or (if any) PLT entry. */
1090 static struct sym_attr
* put_got_entry(TCCState
*s1
, int dyn_reloc_type
,
1096 struct sym_attr
*attr
;
1097 unsigned got_offset
;
1101 need_plt_entry
= (dyn_reloc_type
== R_JMP_SLOT
);
1102 attr
= get_sym_attr(s1
, sym_index
, 1);
1104 /* In case a function is both called and its address taken 2 GOT entries
1105 are created, one for taking the address (GOT) and the other for the PLT
1107 if (need_plt_entry
? attr
->plt_offset
: attr
->got_offset
)
1110 /* create the GOT entry */
1111 got_offset
= s1
->got
->data_offset
;
1112 section_ptr_add(s1
->got
, PTR_SIZE
);
1114 /* Create the GOT relocation that will insert the address of the object or
1115 function of interest in the GOT entry. This is a static relocation for
1116 memory output (dlsym will give us the address of symbols) and dynamic
1117 relocation otherwise (executable and DLLs). The relocation should be
1118 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1119 associated to a PLT entry) but is currently done at load time for an
1122 sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1123 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1126 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
) {
1127 /* Hack alarm. We don't want to emit dynamic symbols
1128 and symbol based relocs for STB_LOCAL symbols, but rather
1129 want to resolve them directly. At this point the symbol
1130 values aren't final yet, so we must defer this. We will later
1131 have to create a RELATIVE reloc anyway, so we misuse the
1132 relocation slot to smuggle the symbol reference until
1133 fill_local_got_entries. Not that the sym_index is
1134 relative to symtab_section, not s1->dynsym! Nevertheless
1135 we use s1->dyn_sym so that if this is the first call
1136 that got->reloc is correctly created. Also note that
1137 RELATIVE relocs are not normally created for the .got,
1138 so the types serves as a marker for later (and is retained
1139 also for the final output, which is okay because then the
1140 got is just normal data). */
1141 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, R_RELATIVE
,
1144 if (0 == attr
->dyn_index
)
1145 attr
->dyn_index
= set_elf_sym(s1
->dynsym
, sym
->st_value
,
1146 sym
->st_size
, sym
->st_info
, 0,
1147 sym
->st_shndx
, name
);
1148 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, dyn_reloc_type
,
1152 put_elf_reloc(symtab_section
, s1
->got
, got_offset
, dyn_reloc_type
,
1156 if (need_plt_entry
) {
1158 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1159 SHF_ALLOC
| SHF_EXECINSTR
);
1160 s1
->plt
->sh_entsize
= 4;
1163 attr
->plt_offset
= create_plt_entry(s1
, got_offset
, attr
);
1165 /* create a symbol 'sym@plt' for the PLT jump vector */
1167 if (len
> sizeof plt_name
- 5)
1168 len
= sizeof plt_name
- 5;
1169 memcpy(plt_name
, name
, len
);
1170 strcpy(plt_name
+ len
, "@plt");
1171 attr
->plt_sym
= put_elf_sym(s1
->symtab
, attr
->plt_offset
, sym
->st_size
,
1172 ELFW(ST_INFO
)(STB_GLOBAL
, STT_FUNC
), 0, s1
->plt
->sh_num
, plt_name
);
1175 attr
->got_offset
= got_offset
;
1181 /* build GOT and PLT entries */
1182 ST_FUNC
void build_got_entries(TCCState
*s1
)
1187 int i
, type
, gotplt_entry
, reloc_type
, sym_index
;
1188 struct sym_attr
*attr
;
1190 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1191 s
= s1
->sections
[i
];
1192 if (s
->sh_type
!= SHT_RELX
)
1194 /* no need to handle got relocations */
1195 if (s
->link
!= symtab_section
)
1197 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1198 type
= ELFW(R_TYPE
)(rel
->r_info
);
1199 gotplt_entry
= gotplt_entry_type(type
);
1200 if (gotplt_entry
== -1)
1201 tcc_error ("Unknown relocation type for got: %d", type
);
1202 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1203 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1205 if (gotplt_entry
== NO_GOTPLT_ENTRY
) {
1209 /* Automatically create PLT/GOT [entry] if it is an undefined
1210 reference (resolved at runtime), or the symbol is absolute,
1211 probably created by tcc_add_symbol, and thus on 64-bit
1212 targets might be too far from application code. */
1213 if (gotplt_entry
== AUTO_GOTPLT_ENTRY
) {
1214 if (sym
->st_shndx
== SHN_UNDEF
) {
1217 if (s1
->output_type
== TCC_OUTPUT_DLL
&& ! PCRELATIVE_DLLPLT
)
1219 /* Relocations for UNDEF symbols would normally need
1220 to be transferred into the executable or shared object.
1221 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1222 But TCC doesn't do that (at least for exes), so we
1223 need to resolve all such relocs locally. And that
1224 means PLT slots for functions in DLLs and COPY relocs for
1225 data symbols. COPY relocs were generated in
1226 bind_exe_dynsyms (and the symbol adjusted to be defined),
1227 and for functions we were generated a dynamic symbol
1228 of function type. */
1230 /* dynsym isn't set for -run :-/ */
1231 dynindex
= get_sym_attr(s1
, sym_index
, 0)->dyn_index
;
1232 esym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ dynindex
;
1234 && (ELFW(ST_TYPE
)(esym
->st_info
) == STT_FUNC
1235 || (ELFW(ST_TYPE
)(esym
->st_info
) == STT_NOTYPE
1236 && ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
)))
1239 } else if (!(sym
->st_shndx
== SHN_ABS
1240 #ifndef TCC_TARGET_ARM
1247 #ifdef TCC_TARGET_X86_64
1248 if ((type
== R_X86_64_PLT32
|| type
== R_X86_64_PC32
) &&
1249 sym
->st_shndx
!= SHN_UNDEF
&&
1250 (ELFW(ST_VISIBILITY
)(sym
->st_other
) != STV_DEFAULT
||
1251 ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
||
1252 s1
->output_type
== TCC_OUTPUT_EXE
)) {
1253 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PC32
);
1257 reloc_type
= code_reloc(type
);
1258 if (reloc_type
== -1)
1259 tcc_error ("Unknown relocation type: %d", type
);
1260 else if (reloc_type
!= 0) {
1262 reloc_type
= R_JMP_SLOT
;
1264 reloc_type
= R_GLOB_DAT
;
1269 if (gotplt_entry
== BUILD_GOT_ONLY
)
1272 attr
= put_got_entry(s1
, reloc_type
, sym_index
);
1274 if (reloc_type
== R_JMP_SLOT
)
1275 rel
->r_info
= ELFW(R_INFO
)(attr
->plt_sym
, type
);
1281 ST_FUNC
int set_global_sym(TCCState
*s1
, const char *name
, Section
*sec
, addr_t offs
)
1283 int shn
= sec
? sec
->sh_num
: offs
? SHN_ABS
: SHN_UNDEF
;
1284 if (sec
&& offs
== -1)
1285 offs
= sec
->data_offset
;
1286 return set_elf_sym(symtab_section
, offs
, 0,
1287 ELFW(ST_INFO
)(name
? STB_GLOBAL
: STB_LOCAL
, STT_NOTYPE
), 0, shn
, name
);
1290 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1295 s
= find_section(s1
, section_name
);
1300 end_offset
= s
->data_offset
;
1302 snprintf(buf
, sizeof(buf
), "__%s_start", section_name
+ 1);
1303 set_global_sym(s1
, buf
, s
, 0);
1304 snprintf(buf
, sizeof(buf
), "__%s_end", section_name
+ 1);
1305 set_global_sym(s1
, buf
, s
, end_offset
);
1308 #ifndef TCC_TARGET_PE
1309 static int tcc_add_support(TCCState
*s1
, const char *filename
)
1312 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, filename
);
1313 return tcc_add_file(s1
, buf
);
1317 ST_FUNC
void add_array (TCCState
*s1
, const char *sec
, int c
)
1320 s
= find_section(s1
, sec
);
1321 s
->sh_flags
|= SHF_WRITE
;
1322 #ifndef TCC_TARGET_PE
1323 s
->sh_type
= sec
[1] == 'i' ? SHT_INIT_ARRAY
: SHT_FINI_ARRAY
;
1325 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1326 section_ptr_add(s
, PTR_SIZE
);
1329 #ifdef CONFIG_TCC_BCHECK
1330 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
1332 if (0 == s1
->do_bounds_check
)
1334 section_ptr_add(bounds_section
, sizeof(addr_t
));
1338 #ifdef CONFIG_TCC_BACKTRACE
1339 static void put_ptr(TCCState
*s1
, Section
*s
, int offs
)
1342 c
= set_global_sym(s1
, NULL
, s
, offs
);
1344 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1345 section_ptr_add(s
, PTR_SIZE
);
1348 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1349 a dynamic symbol to allow so's to have one each with a different value. */
1350 static void set_local_sym(TCCState
*s1
, const char *name
, Section
*s
, int offset
)
1352 int c
= find_elf_sym(s1
->symtab
, name
);
1354 ElfW(Sym
) *esym
= (ElfW(Sym
)*)s1
->symtab
->data
+ c
;
1355 esym
->st_info
= ELFW(ST_INFO
)(STB_LOCAL
, STT_NOTYPE
);
1356 esym
->st_value
= offset
;
1357 esym
->st_shndx
= s
->sh_num
;
1361 ST_FUNC
void tcc_add_btstub(TCCState
*s1
)
1369 /* create (part of) a struct rt_context (see tccrun.c) */
1370 put_ptr(s1
, stab_section
, 0);
1371 put_ptr(s1
, stab_section
, -1);
1372 put_ptr(s1
, stab_section
->link
, 0);
1373 section_ptr_add(s
, 3 * PTR_SIZE
);
1375 #ifndef TCC_TARGET_MACHO
1376 /* XXX this relocation is wrong, it uses sym-index 0 (local,undef) */
1377 put_elf_reloc(s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, 0);
1379 section_ptr_add(s
, PTR_SIZE
);
1381 #ifdef CONFIG_TCC_BCHECK
1382 if (s1
->do_bounds_check
) {
1383 put_ptr(s1
, bounds_section
, 0);
1387 section_ptr_add(s
, n
);
1391 " extern void __bt_init(),*__rt_info[],__bt_init_dll();"
1392 "__attribute__((constructor)) static void __bt_init_rt(){");
1393 #ifdef TCC_TARGET_PE
1394 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1395 #ifdef CONFIG_TCC_BCHECK
1396 cstr_printf(&cstr
, "__bt_init_dll(%d);", s1
->do_bounds_check
);
1398 cstr_printf(&cstr
, "__bt_init_dll(0);");
1401 cstr_printf(&cstr
, "__bt_init(__rt_info,%d, 0);}",
1402 s1
->output_type
== TCC_OUTPUT_DLL
? 0 : s1
->rt_num_callers
+ 1);
1403 tcc_compile_string(s1
, cstr
.data
);
1405 set_local_sym(s1
, &"___rt_info"[!s1
->leading_underscore
], s
, o
);
1409 #ifndef TCC_TARGET_PE
1410 /* add tcc runtime libraries */
1411 ST_FUNC
void tcc_add_runtime(TCCState
*s1
)
1414 #ifdef CONFIG_TCC_BCHECK
1417 tcc_add_pragma_libs(s1
);
1419 if (!s1
->nostdlib
) {
1420 if (s1
->option_pthread
)
1421 tcc_add_library_err(s1
, "pthread");
1422 tcc_add_library_err(s1
, "c");
1424 if (!s1
->static_link
) {
1425 if (TCC_LIBGCC
[0] == '/')
1426 tcc_add_file(s1
, TCC_LIBGCC
);
1428 tcc_add_dll(s1
, TCC_LIBGCC
, 0);
1431 #ifdef CONFIG_TCC_BCHECK
1432 if (s1
->do_bounds_check
&& s1
->output_type
!= TCC_OUTPUT_DLL
) {
1433 tcc_add_library_err(s1
, "pthread");
1434 tcc_add_library_err(s1
, "dl");
1435 tcc_add_support(s1
, "bcheck.o");
1438 #ifdef CONFIG_TCC_BACKTRACE
1439 if (s1
->do_backtrace
) {
1440 if (s1
->output_type
== TCC_OUTPUT_EXE
)
1441 tcc_add_support(s1
, "bt-exe.o");
1442 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1443 tcc_add_support(s1
, "bt-log.o");
1444 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1448 tcc_add_support(s1
, TCC_LIBTCC1
);
1449 #ifndef TCC_TARGET_MACHO
1450 /* add crt end if not memory output */
1451 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1452 tcc_add_crt(s1
, "crtn.o");
1458 /* add various standard linker symbols (must be done after the
1459 sections are filled (for example after allocating common
1461 static void tcc_add_linker_symbols(TCCState
*s1
)
1467 set_global_sym(s1
, "_etext", text_section
, -1);
1468 set_global_sym(s1
, "_edata", data_section
, -1);
1469 set_global_sym(s1
, "_end", bss_section
, -1);
1470 #ifdef TCC_TARGET_RISCV64
1471 /* XXX should be .sdata+0x800, not .data+0x800 */
1472 set_global_sym(s1
, "__global_pointer$", data_section
, 0x800);
1474 /* horrible new standard ldscript defines */
1475 add_init_array_defines(s1
, ".preinit_array");
1476 add_init_array_defines(s1
, ".init_array");
1477 add_init_array_defines(s1
, ".fini_array");
1478 /* add start and stop symbols for sections whose name can be
1480 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1481 s
= s1
->sections
[i
];
1482 if ((s
->sh_flags
& SHF_ALLOC
)
1483 && (s
->sh_type
== SHT_PROGBITS
1484 || s
->sh_type
== SHT_STRTAB
)) {
1486 /* check if section name can be expressed in C */
1492 if (!isid(c
) && !isnum(c
))
1496 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1497 set_global_sym(s1
, buf
, s
, 0);
1498 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1499 set_global_sym(s1
, buf
, s
, -1);
1505 ST_FUNC
void resolve_common_syms(TCCState
*s1
)
1509 /* Allocate common symbols in BSS. */
1510 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1511 if (sym
->st_shndx
== SHN_COMMON
) {
1512 /* symbol alignment is in st_value for SHN_COMMONs */
1513 sym
->st_value
= section_add(bss_section
, sym
->st_size
,
1515 sym
->st_shndx
= bss_section
->sh_num
;
1519 /* Now assign linker provided symbols their value. */
1520 tcc_add_linker_symbols(s1
);
1523 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1524 const int *sec_order
)
1527 int i
, offset
, size
;
1530 for(i
=1;i
<s1
->nb_sections
;i
++) {
1531 s
= s1
->sections
[sec_order
[i
]];
1532 if (s
->sh_type
!= SHT_NOBITS
&&
1533 (s
->sh_flags
& SHF_ALLOC
)) {
1534 while (offset
< s
->sh_offset
) {
1539 fwrite(s
->data
, 1, size
, f
);
1545 #ifndef ELF_OBJ_ONLY
1546 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1548 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1549 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1550 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1551 unsigned offset
= attr
->got_offset
;
1555 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1556 #ifdef TCC_TARGET_X86_64
1557 write64le(s1
->got
->data
+ offset
, sym
->st_value
);
1559 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1563 /* Perform relocation to GOT or PLT entries */
1564 ST_FUNC
void fill_got(TCCState
*s1
)
1570 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1571 s
= s1
->sections
[i
];
1572 if (s
->sh_type
!= SHT_RELX
)
1574 /* no need to handle got relocations */
1575 if (s
->link
!= symtab_section
)
1577 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1578 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1579 case R_X86_64_GOT32
:
1580 case R_X86_64_GOTPCREL
:
1581 case R_X86_64_GOTPCRELX
:
1582 case R_X86_64_REX_GOTPCRELX
:
1583 case R_X86_64_PLT32
:
1584 fill_got_entry(s1
, rel
);
1591 /* See put_got_entry for a description. This is the second stage
1592 where GOT references to local defined symbols are rewritten. */
1593 static void fill_local_got_entries(TCCState
*s1
)
1596 if (!s1
->got
->reloc
)
1598 for_each_elem(s1
->got
->reloc
, 0, rel
, ElfW_Rel
) {
1599 if (ELFW(R_TYPE
)(rel
->r_info
) == R_RELATIVE
) {
1600 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1601 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1602 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1603 unsigned offset
= attr
->got_offset
;
1604 if (offset
!= rel
->r_offset
- s1
->got
->sh_addr
)
1605 tcc_error_noabort("huh");
1606 rel
->r_info
= ELFW(R_INFO
)(0, R_RELATIVE
);
1607 #if SHT_RELX == SHT_RELA
1608 rel
->r_addend
= sym
->st_value
;
1610 /* All our REL architectures also happen to be 32bit LE. */
1611 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1617 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1618 in shared libraries and export non local defined symbols to shared libraries
1619 if -rdynamic switch was given on command line */
1620 static void bind_exe_dynsyms(TCCState
*s1
)
1623 int sym_index
, index
;
1624 ElfW(Sym
) *sym
, *esym
;
1627 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1628 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1629 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1630 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1631 if (sym
->st_shndx
== SHN_UNDEF
) {
1632 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1633 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1635 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1636 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1637 if ((type
== STT_FUNC
) || (type
== STT_GNU_IFUNC
)) {
1638 /* Indirect functions shall have STT_FUNC type in executable
1639 * dynsym section. Indeed, a dlsym call following a lazy
1640 * resolution would pick the symbol value from the
1641 * executable dynsym entry which would contain the address
1642 * of the function wanted by the caller of dlsym instead of
1643 * the address of the function that would return that
1646 = put_elf_sym(s1
->dynsym
, 0, esym
->st_size
,
1647 ELFW(ST_INFO
)(STB_GLOBAL
,STT_FUNC
), 0, 0,
1649 int index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1650 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1651 } else if (type
== STT_OBJECT
) {
1652 unsigned long offset
;
1654 offset
= bss_section
->data_offset
;
1655 /* XXX: which alignment ? */
1656 offset
= (offset
+ 16 - 1) & -16;
1657 set_elf_sym (s1
->symtab
, offset
, esym
->st_size
,
1658 esym
->st_info
, 0, bss_section
->sh_num
, name
);
1659 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1660 esym
->st_info
, 0, bss_section
->sh_num
,
1663 /* Ensure R_COPY works for weak symbol aliases */
1664 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1665 for_each_elem(s1
->dynsymtab_section
, 1, dynsym
, ElfW(Sym
)) {
1666 if ((dynsym
->st_value
== esym
->st_value
)
1667 && (ELFW(ST_BIND
)(dynsym
->st_info
) == STB_GLOBAL
)) {
1668 char *dynname
= (char *) s1
->dynsymtab_section
->link
->data
1670 put_elf_sym(s1
->dynsym
, offset
, dynsym
->st_size
,
1672 bss_section
->sh_num
, dynname
);
1678 put_elf_reloc(s1
->dynsym
, bss_section
,
1679 offset
, R_COPY
, index
);
1680 offset
+= esym
->st_size
;
1681 bss_section
->data_offset
= offset
;
1684 /* STB_WEAK undefined symbols are accepted */
1685 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1686 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1687 !strcmp(name
, "_fp_hw")) {
1689 tcc_error_noabort("undefined symbol '%s'", name
);
1692 } else if (s1
->rdynamic
&& ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1693 /* if -rdynamic option, then export all non local symbols */
1694 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1695 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
1696 0, sym
->st_shndx
, name
);
1701 /* Bind symbols of libraries: export all non local symbols of executable that
1702 are referenced by shared libraries. The reason is that the dynamic loader
1703 search symbol first in executable and then in libraries. Therefore a
1704 reference to a symbol already defined by a library can still be resolved by
1705 a symbol in the executable. */
1706 static void bind_libs_dynsyms(TCCState
*s1
)
1710 ElfW(Sym
) *sym
, *esym
;
1712 for_each_elem(s1
->dynsymtab_section
, 1, esym
, ElfW(Sym
)) {
1713 name
= (char *) s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1714 sym_index
= find_elf_sym(symtab_section
, name
);
1715 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1716 if (sym_index
&& sym
->st_shndx
!= SHN_UNDEF
1717 && ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1718 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1719 sym
->st_info
, 0, sym
->st_shndx
, name
);
1720 } else if (esym
->st_shndx
== SHN_UNDEF
) {
1721 /* weak symbols can stay undefined */
1722 if (ELFW(ST_BIND
)(esym
->st_info
) != STB_WEAK
)
1723 tcc_warning("undefined dynamic symbol '%s'", name
);
1728 /* Export all non local symbols. This is used by shared libraries so that the
1729 non local symbols they define can resolve a reference in another shared
1730 library or in the executable. Correspondingly, it allows undefined local
1731 symbols to be resolved by other shared libraries or by the executable. */
1732 static void export_global_syms(TCCState
*s1
)
1734 int dynindex
, index
;
1738 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1739 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1740 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1741 dynindex
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1742 sym
->st_info
, 0, sym
->st_shndx
, name
);
1743 index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1744 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1750 /* Allocate strings for section names and decide if an unallocated section
1752 NOTE: the strsec section comes last, so its size is also correct ! */
1753 static int alloc_sec_names(TCCState
*s1
, int file_type
, Section
*strsec
)
1759 /* Allocate strings for section names */
1760 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1761 s
= s1
->sections
[i
];
1762 /* when generating a DLL, we include relocations but we may
1764 #ifndef ELF_OBJ_ONLY
1765 if (file_type
== TCC_OUTPUT_DLL
&&
1766 s
->sh_type
== SHT_RELX
&&
1767 !(s
->sh_flags
& SHF_ALLOC
) &&
1768 (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
) &&
1769 prepare_dynamic_rel(s1
, s
)) {
1770 if (!(s1
->sections
[s
->sh_info
]->sh_flags
& SHF_WRITE
))
1774 if ((s1
->do_debug
&& s
->sh_type
!= SHT_RELX
) ||
1775 file_type
== TCC_OUTPUT_OBJ
||
1776 (s
->sh_flags
& SHF_ALLOC
) ||
1777 i
== (s1
->nb_sections
- 1)) {
1778 /* we output all sections if debug or object file */
1779 s
->sh_size
= s
->data_offset
;
1781 if (s
->sh_size
|| (s
->sh_flags
& SHF_ALLOC
))
1782 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1784 strsec
->sh_size
= strsec
->data_offset
;
1788 /* Info to be copied in dynamic section */
1792 unsigned long data_offset
;
1795 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1801 /* Assign sections to segments and decide how are sections laid out when loaded
1802 in memory. This function also fills corresponding program headers. */
1803 static int layout_sections(TCCState
*s1
, ElfW(Phdr
) *phdr
, int phnum
,
1804 Section
*interp
, Section
* strsec
,
1805 struct dyn_inf
*dyninf
, int *sec_order
)
1807 int i
, j
, k
, file_type
, sh_order_index
, file_offset
;
1808 unsigned long s_align
;
1814 file_type
= s1
->output_type
;
1817 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
1818 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1819 s_align
= ELF_PAGE_SIZE
;
1820 if (s1
->section_align
)
1821 s_align
= s1
->section_align
;
1824 if (s1
->has_text_addr
) {
1825 int a_offset
, p_offset
;
1826 addr
= s1
->text_addr
;
1827 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1829 a_offset
= (int) (addr
& (s_align
- 1));
1830 p_offset
= file_offset
& (s_align
- 1);
1831 if (a_offset
< p_offset
)
1832 a_offset
+= s_align
;
1833 file_offset
+= (a_offset
- p_offset
);
1835 if (file_type
== TCC_OUTPUT_DLL
)
1838 addr
= ELF_START_ADDR
;
1839 /* compute address after headers */
1840 addr
+= (file_offset
& (s_align
- 1));
1844 /* Leave one program headers for the program interpreter and one for
1845 the program header table itself if needed. These are done later as
1846 they require section layout to be done first. */
1850 /* dynamic relocation table information, for .dynamic section */
1851 dyninf
->rel_addr
= dyninf
->rel_size
= 0;
1852 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1853 dyninf
->bss_addr
= dyninf
->bss_size
= 0;
1856 for(j
= 0; j
< 2; j
++) {
1857 ph
->p_type
= PT_LOAD
;
1859 ph
->p_flags
= PF_R
| PF_X
;
1861 ph
->p_flags
= PF_R
| PF_W
;
1862 ph
->p_align
= s_align
;
1864 /* Decide the layout of sections loaded in memory. This must
1865 be done before program headers are filled since they contain
1866 info about the layout. We do the following ordering: interp,
1867 symbol tables, relocations, progbits, nobits */
1868 /* XXX: do faster and simpler sorting */
1869 for(k
= 0; k
< 5; k
++) {
1870 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1871 s
= s1
->sections
[i
];
1872 /* compute if section should be included */
1874 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1878 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1879 (SHF_ALLOC
| SHF_WRITE
))
1885 } else if ((s
->sh_type
== SHT_DYNSYM
||
1886 s
->sh_type
== SHT_STRTAB
||
1887 s
->sh_type
== SHT_HASH
)
1888 && !strstr(s
->name
, ".stab")) {
1891 } else if (s
->sh_type
== SHT_RELX
) {
1894 } else if (s
->sh_type
== SHT_NOBITS
) {
1901 sec_order
[sh_order_index
++] = i
;
1903 /* section matches: we align it and add its size */
1905 addr
= (addr
+ s
->sh_addralign
- 1) &
1906 ~(s
->sh_addralign
- 1);
1907 file_offset
+= (int) ( addr
- tmp
);
1908 s
->sh_offset
= file_offset
;
1911 /* update program header infos */
1912 if (ph
->p_offset
== 0) {
1913 ph
->p_offset
= file_offset
;
1915 ph
->p_paddr
= ph
->p_vaddr
;
1917 /* update dynamic relocation infos */
1918 if (s
->sh_type
== SHT_RELX
) {
1919 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1920 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.got")) {
1921 dyninf
->rel_addr
= addr
;
1922 dyninf
->rel_size
+= s
->sh_size
; /* XXX only first rel. */
1924 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.bss")) {
1925 dyninf
->bss_addr
= addr
;
1926 dyninf
->bss_size
= s
->sh_size
; /* XXX only first rel. */
1929 if (dyninf
->rel_size
== 0)
1930 dyninf
->rel_addr
= addr
;
1931 dyninf
->rel_size
+= s
->sh_size
;
1935 if (s
->sh_type
!= SHT_NOBITS
)
1936 file_offset
+= s
->sh_size
;
1940 /* Make the first PT_LOAD segment include the program
1941 headers itself (and the ELF header as well), it'll
1942 come out with same memory use but will make various
1943 tools like binutils strip work better. */
1944 ph
->p_offset
&= ~(ph
->p_align
- 1);
1945 ph
->p_vaddr
&= ~(ph
->p_align
- 1);
1946 ph
->p_paddr
&= ~(ph
->p_align
- 1);
1948 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1949 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1952 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1953 /* if in the middle of a page, we duplicate the page in
1954 memory so that one copy is RX and the other is RW */
1955 if ((addr
& (s_align
- 1)) != 0)
1958 addr
= (addr
+ s_align
- 1) & ~(s_align
- 1);
1959 file_offset
= (file_offset
+ s_align
- 1) & ~(s_align
- 1);
1965 /* all other sections come after */
1966 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1967 s
= s1
->sections
[i
];
1968 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1970 sec_order
[sh_order_index
++] = i
;
1972 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1973 ~(s
->sh_addralign
- 1);
1974 s
->sh_offset
= file_offset
;
1975 if (s
->sh_type
!= SHT_NOBITS
)
1976 file_offset
+= s
->sh_size
;
1982 #ifndef ELF_OBJ_ONLY
1983 /* put dynamic tag */
1984 static void put_dt(Section
*dynamic
, int dt
, addr_t val
)
1987 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1989 dyn
->d_un
.d_val
= val
;
1992 static void fill_unloadable_phdr(ElfW(Phdr
) *phdr
, int phnum
, Section
*interp
,
1997 /* if interpreter, then add corresponding program header */
2001 ph
->p_type
= PT_PHDR
;
2002 ph
->p_offset
= sizeof(ElfW(Ehdr
));
2003 ph
->p_filesz
= ph
->p_memsz
= phnum
* sizeof(ElfW(Phdr
));
2004 ph
->p_vaddr
= interp
->sh_addr
- ph
->p_filesz
;
2005 ph
->p_paddr
= ph
->p_vaddr
;
2006 ph
->p_flags
= PF_R
| PF_X
;
2007 ph
->p_align
= 4; /* interp->sh_addralign; */
2010 ph
->p_type
= PT_INTERP
;
2011 ph
->p_offset
= interp
->sh_offset
;
2012 ph
->p_vaddr
= interp
->sh_addr
;
2013 ph
->p_paddr
= ph
->p_vaddr
;
2014 ph
->p_filesz
= interp
->sh_size
;
2015 ph
->p_memsz
= interp
->sh_size
;
2017 ph
->p_align
= interp
->sh_addralign
;
2020 /* if dynamic section, then add corresponding program header */
2022 ph
= &phdr
[phnum
- 1];
2024 ph
->p_type
= PT_DYNAMIC
;
2025 ph
->p_offset
= dynamic
->sh_offset
;
2026 ph
->p_vaddr
= dynamic
->sh_addr
;
2027 ph
->p_paddr
= ph
->p_vaddr
;
2028 ph
->p_filesz
= dynamic
->sh_size
;
2029 ph
->p_memsz
= dynamic
->sh_size
;
2030 ph
->p_flags
= PF_R
| PF_W
;
2031 ph
->p_align
= dynamic
->sh_addralign
;
2035 /* Fill the dynamic section with tags describing the address and size of
2037 static void fill_dynamic(TCCState
*s1
, struct dyn_inf
*dyninf
)
2039 Section
*dynamic
= dyninf
->dynamic
;
2042 /* put dynamic section entries */
2043 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
2044 put_dt(dynamic
, DT_STRTAB
, dyninf
->dynstr
->sh_addr
);
2045 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
2046 put_dt(dynamic
, DT_STRSZ
, dyninf
->dynstr
->data_offset
);
2047 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
2049 put_dt(dynamic
, DT_RELA
, dyninf
->rel_addr
);
2050 put_dt(dynamic
, DT_RELASZ
, dyninf
->rel_size
);
2051 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
2053 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2054 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2055 put_dt(dynamic
, DT_PLTRELSZ
, dyninf
->rel_size
);
2056 put_dt(dynamic
, DT_JMPREL
, dyninf
->rel_addr
);
2057 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
2058 put_dt(dynamic
, DT_REL
, dyninf
->bss_addr
);
2059 put_dt(dynamic
, DT_RELSZ
, dyninf
->bss_size
);
2061 put_dt(dynamic
, DT_REL
, dyninf
->rel_addr
);
2062 put_dt(dynamic
, DT_RELSZ
, dyninf
->rel_size
);
2063 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
2067 put_dt(dynamic
, DT_VERSYM
, versym_section
->sh_addr
);
2068 if (verneed_section
) {
2069 put_dt(dynamic
, DT_VERNEED
, verneed_section
->sh_addr
);
2070 put_dt(dynamic
, DT_VERNEEDNUM
, dt_verneednum
);
2072 s
= find_section_create (s1
, ".preinit_array", 0);
2073 if (s
&& s
->data_offset
) {
2074 put_dt(dynamic
, DT_PREINIT_ARRAY
, s
->sh_addr
);
2075 put_dt(dynamic
, DT_PREINIT_ARRAYSZ
, s
->data_offset
);
2077 s
= find_section_create (s1
, ".init_array", 0);
2078 if (s
&& s
->data_offset
) {
2079 put_dt(dynamic
, DT_INIT_ARRAY
, s
->sh_addr
);
2080 put_dt(dynamic
, DT_INIT_ARRAYSZ
, s
->data_offset
);
2082 s
= find_section_create (s1
, ".fini_array", 0);
2083 if (s
&& s
->data_offset
) {
2084 put_dt(dynamic
, DT_FINI_ARRAY
, s
->sh_addr
);
2085 put_dt(dynamic
, DT_FINI_ARRAYSZ
, s
->data_offset
);
2087 s
= find_section_create (s1
, ".init", 0);
2088 if (s
&& s
->data_offset
) {
2089 put_dt(dynamic
, DT_INIT
, s
->sh_addr
);
2091 s
= find_section_create (s1
, ".fini", 0);
2092 if (s
&& s
->data_offset
) {
2093 put_dt(dynamic
, DT_FINI
, s
->sh_addr
);
2096 put_dt(dynamic
, DT_DEBUG
, 0);
2097 put_dt(dynamic
, DT_NULL
, 0);
2100 /* Relocate remaining sections and symbols (that is those not related to
2102 static int final_sections_reloc(TCCState
*s1
)
2107 relocate_syms(s1
, s1
->symtab
, 0);
2109 if (s1
->nb_errors
!= 0)
2112 /* relocate sections */
2113 /* XXX: ignore sections with allocated relocations ? */
2114 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2115 s
= s1
->sections
[i
];
2116 if (s
->reloc
&& (s
!= s1
->got
|| s1
->static_link
))
2117 relocate_section(s1
, s
);
2120 /* relocate relocation entries if the relocation tables are
2121 allocated in the executable */
2122 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2123 s
= s1
->sections
[i
];
2124 if ((s
->sh_flags
& SHF_ALLOC
) &&
2125 s
->sh_type
== SHT_RELX
) {
2126 relocate_rel(s1
, s
);
2133 /* Create an ELF file on disk.
2134 This function handle ELF specific layout requirements */
2135 static void tcc_output_elf(TCCState
*s1
, FILE *f
, int phnum
, ElfW(Phdr
) *phdr
,
2136 int file_offset
, int *sec_order
)
2138 int i
, shnum
, offset
, size
, file_type
;
2141 ElfW(Shdr
) shdr
, *sh
;
2143 file_type
= s1
->output_type
;
2144 shnum
= s1
->nb_sections
;
2146 memset(&ehdr
, 0, sizeof(ehdr
));
2149 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2150 ehdr
.e_phnum
= phnum
;
2151 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2155 file_offset
= (file_offset
+ 3) & -4;
2158 ehdr
.e_ident
[0] = ELFMAG0
;
2159 ehdr
.e_ident
[1] = ELFMAG1
;
2160 ehdr
.e_ident
[2] = ELFMAG2
;
2161 ehdr
.e_ident
[3] = ELFMAG3
;
2162 ehdr
.e_ident
[4] = ELFCLASSW
;
2163 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2164 ehdr
.e_ident
[6] = EV_CURRENT
;
2165 #if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
2166 /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
2167 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2169 #ifdef TCC_TARGET_ARM
2171 ehdr
.e_ident
[EI_OSABI
] = 0;
2172 ehdr
.e_flags
= EF_ARM_EABI_VER4
;
2173 if (file_type
== TCC_OUTPUT_EXE
|| file_type
== TCC_OUTPUT_DLL
)
2174 ehdr
.e_flags
|= EF_ARM_HASENTRY
;
2175 if (s1
->float_abi
== ARM_HARD_FLOAT
)
2176 ehdr
.e_flags
|= EF_ARM_VFP_FLOAT
;
2178 ehdr
.e_flags
|= EF_ARM_SOFT_FLOAT
;
2180 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2182 #elif defined TCC_TARGET_RISCV64
2183 ehdr
.e_flags
= EF_RISCV_FLOAT_ABI_DOUBLE
;
2187 case TCC_OUTPUT_EXE
:
2188 ehdr
.e_type
= ET_EXEC
;
2189 ehdr
.e_entry
= get_sym_addr(s1
, "_start", 1, 0);
2191 case TCC_OUTPUT_DLL
:
2192 ehdr
.e_type
= ET_DYN
;
2193 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
2195 case TCC_OUTPUT_OBJ
:
2196 ehdr
.e_type
= ET_REL
;
2199 ehdr
.e_machine
= EM_TCC_TARGET
;
2200 ehdr
.e_version
= EV_CURRENT
;
2201 ehdr
.e_shoff
= file_offset
;
2202 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2203 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2204 ehdr
.e_shnum
= shnum
;
2205 ehdr
.e_shstrndx
= shnum
- 1;
2207 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2208 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2209 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2211 sort_syms(s1
, symtab_section
);
2212 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2213 s
= s1
->sections
[sec_order
[i
]];
2214 if (s
->sh_type
!= SHT_NOBITS
) {
2215 while (offset
< s
->sh_offset
) {
2221 fwrite(s
->data
, 1, size
, f
);
2226 /* output section headers */
2227 while (offset
< ehdr
.e_shoff
) {
2232 for(i
= 0; i
< s1
->nb_sections
; i
++) {
2234 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2235 s
= s1
->sections
[i
];
2237 sh
->sh_name
= s
->sh_name
;
2238 sh
->sh_type
= s
->sh_type
;
2239 sh
->sh_flags
= s
->sh_flags
;
2240 sh
->sh_entsize
= s
->sh_entsize
;
2241 sh
->sh_info
= s
->sh_info
;
2243 sh
->sh_link
= s
->link
->sh_num
;
2244 sh
->sh_addralign
= s
->sh_addralign
;
2245 sh
->sh_addr
= s
->sh_addr
;
2246 sh
->sh_offset
= s
->sh_offset
;
2247 sh
->sh_size
= s
->sh_size
;
2249 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2253 /* Write an elf, coff or "binary" file */
2254 static int tcc_write_elf_file(TCCState
*s1
, const char *filename
, int phnum
,
2255 ElfW(Phdr
) *phdr
, int file_offset
, int *sec_order
)
2257 int fd
, mode
, file_type
;
2260 file_type
= s1
->output_type
;
2261 if (file_type
== TCC_OUTPUT_OBJ
)
2266 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2268 tcc_error_noabort("could not write '%s'", filename
);
2271 f
= fdopen(fd
, "wb");
2273 printf("<- %s\n", filename
);
2275 #ifdef TCC_TARGET_COFF
2276 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
)
2277 tcc_output_coff(s1
, f
);
2280 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2281 tcc_output_elf(s1
, f
, phnum
, phdr
, file_offset
, sec_order
);
2283 tcc_output_binary(s1
, f
, sec_order
);
2289 #ifndef ELF_OBJ_ONLY
2290 /* Sort section headers by assigned sh_addr, remove sections
2291 that we aren't going to output. */
2292 static void tidy_section_headers(TCCState
*s1
, int *sec_order
)
2294 int i
, nnew
, l
, *backmap
;
2298 snew
= tcc_malloc(s1
->nb_sections
* sizeof(snew
[0]));
2299 backmap
= tcc_malloc(s1
->nb_sections
* sizeof(backmap
[0]));
2300 for (i
= 0, nnew
= 0, l
= s1
->nb_sections
; i
< s1
->nb_sections
; i
++) {
2301 s
= s1
->sections
[sec_order
[i
]];
2302 if (!i
|| s
->sh_name
) {
2303 backmap
[sec_order
[i
]] = nnew
;
2307 backmap
[sec_order
[i
]] = 0;
2311 for (i
= 0; i
< nnew
; i
++) {
2315 if (s
->sh_type
== SHT_RELX
)
2316 s
->sh_info
= backmap
[s
->sh_info
];
2320 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
))
2321 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2322 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2323 if( !s1
->static_link
) {
2324 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
))
2325 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2326 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2328 for (i
= 0; i
< s1
->nb_sections
; i
++)
2330 tcc_free(s1
->sections
);
2331 s1
->sections
= snew
;
2332 s1
->nb_sections
= nnew
;
2337 /* Output an elf, coff or binary file */
2338 /* XXX: suppress unneeded sections */
2339 static int elf_output_file(TCCState
*s1
, const char *filename
)
2341 int ret
, phnum
, shnum
, file_type
, file_offset
, *sec_order
;
2342 struct dyn_inf dyninf
= {0};
2344 Section
*strsec
, *interp
, *dynamic
, *dynstr
;
2346 file_type
= s1
->output_type
;
2351 interp
= dynamic
= dynstr
= NULL
; /* avoid warning */
2353 #ifndef ELF_OBJ_ONLY
2354 if (file_type
!= TCC_OUTPUT_OBJ
) {
2355 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2356 tcc_add_runtime(s1
);
2357 resolve_common_syms(s1
);
2359 if (!s1
->static_link
) {
2360 if (file_type
== TCC_OUTPUT_EXE
) {
2362 /* allow override the dynamic loader */
2363 const char *elfint
= getenv("LD_SO");
2365 elfint
= DEFAULT_ELFINTERP(s1
);
2366 /* add interpreter section only if executable */
2367 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
2368 interp
->sh_addralign
= 1;
2369 ptr
= section_ptr_add(interp
, 1 + strlen(elfint
));
2370 strcpy(ptr
, elfint
);
2373 /* add dynamic symbol table */
2374 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
2376 ".hash", SHF_ALLOC
);
2377 dynstr
= s1
->dynsym
->link
;
2378 /* add dynamic section */
2379 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
2380 SHF_ALLOC
| SHF_WRITE
);
2381 dynamic
->link
= dynstr
;
2382 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
2386 if (file_type
== TCC_OUTPUT_EXE
) {
2387 bind_exe_dynsyms(s1
);
2390 bind_libs_dynsyms(s1
);
2392 /* shared library case: simply export all global symbols */
2393 export_global_syms(s1
);
2396 build_got_entries(s1
);
2401 /* we add a section for symbols */
2402 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
2403 put_elf_str(strsec
, "");
2405 /* Allocate strings for section names */
2406 ret
= alloc_sec_names(s1
, file_type
, strsec
);
2408 #ifndef ELF_OBJ_ONLY
2411 /* add a list of needed dlls */
2412 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2413 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
2414 if (dllref
->level
== 0)
2415 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
2419 put_dt(dynamic
, s1
->enable_new_dtags
? DT_RUNPATH
: DT_RPATH
,
2420 put_elf_str(dynstr
, s1
->rpath
));
2422 if (file_type
== TCC_OUTPUT_DLL
) {
2424 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
2425 /* XXX: currently, since we do not handle PIC code, we
2426 must relocate the readonly segments */
2428 put_dt(dynamic
, DT_TEXTREL
, 0);
2432 put_dt(dynamic
, DT_SYMBOLIC
, 0);
2434 dyninf
.dynamic
= dynamic
;
2435 dyninf
.dynstr
= dynstr
;
2436 /* remember offset and reserve space for 2nd call below */
2437 dyninf
.data_offset
= dynamic
->data_offset
;
2438 fill_dynamic(s1
, &dyninf
);
2439 dynamic
->sh_size
= dynamic
->data_offset
;
2440 dynstr
->sh_size
= dynstr
->data_offset
;
2444 /* compute number of program headers */
2445 if (file_type
== TCC_OUTPUT_OBJ
)
2447 else if (file_type
== TCC_OUTPUT_DLL
)
2449 else if (s1
->static_link
)
2454 /* allocate program segment headers */
2455 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
2457 /* compute number of sections */
2458 shnum
= s1
->nb_sections
;
2460 /* this array is used to reorder sections in the output file */
2461 sec_order
= tcc_malloc(sizeof(int) * shnum
);
2464 /* compute section to program header mapping */
2465 file_offset
= layout_sections(s1
, phdr
, phnum
, interp
, strsec
, &dyninf
,
2468 #ifndef ELF_OBJ_ONLY
2469 /* Fill remaining program header and finalize relocation related to dynamic
2471 if (file_type
!= TCC_OUTPUT_OBJ
) {
2472 fill_unloadable_phdr(phdr
, phnum
, interp
, dynamic
);
2475 dynamic
->data_offset
= dyninf
.data_offset
;
2476 fill_dynamic(s1
, &dyninf
);
2478 /* put in GOT the dynamic section address and relocate PLT */
2479 write32le(s1
->got
->data
, dynamic
->sh_addr
);
2480 if (file_type
== TCC_OUTPUT_EXE
2481 || (RELOCATE_DLLPLT
&& file_type
== TCC_OUTPUT_DLL
))
2484 /* relocate symbols in .dynsym now that final addresses are known */
2485 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
)) {
2486 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
) {
2487 /* do symbol relocation */
2488 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
2493 /* if building executable or DLL, then relocate each section
2494 except the GOT which is already relocated */
2495 ret
= final_sections_reloc(s1
);
2498 tidy_section_headers(s1
, sec_order
);
2500 /* Perform relocation to GOT or PLT entries */
2501 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2504 fill_local_got_entries(s1
);
2508 /* Create the ELF file with name 'filename' */
2509 ret
= tcc_write_elf_file(s1
, filename
, phnum
, phdr
, file_offset
, sec_order
);
2510 s1
->nb_sections
= shnum
;
2513 tcc_free(sec_order
);
2518 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2521 #ifdef TCC_TARGET_PE
2522 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2523 ret
= pe_output_file(s
, filename
);
2525 #elif TCC_TARGET_MACHO
2526 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2527 ret
= macho_output_file(s
, filename
);
2530 ret
= elf_output_file(s
, filename
);
2534 ST_FUNC ssize_t
full_read(int fd
, void *buf
, size_t count
) {
2538 ssize_t num
= read(fd
, cbuf
, count
-rnum
);
2539 if (num
< 0) return num
;
2540 if (num
== 0) return rnum
;
2546 ST_FUNC
void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2550 data
= tcc_malloc(size
);
2551 lseek(fd
, file_offset
, SEEK_SET
);
2552 full_read(fd
, data
, size
);
2556 typedef struct SectionMergeInfo
{
2557 Section
*s
; /* corresponding existing section */
2558 unsigned long offset
; /* offset of the new section in the existing section */
2559 uint8_t new_section
; /* true if section 's' was added */
2560 uint8_t link_once
; /* true if link once section */
2563 ST_FUNC
int tcc_object_type(int fd
, ElfW(Ehdr
) *h
)
2565 int size
= full_read(fd
, h
, sizeof *h
);
2566 if (size
== sizeof *h
&& 0 == memcmp(h
, ELFMAG
, 4)) {
2567 if (h
->e_type
== ET_REL
)
2568 return AFF_BINTYPE_REL
;
2569 if (h
->e_type
== ET_DYN
)
2570 return AFF_BINTYPE_DYN
;
2571 } else if (size
>= 8) {
2572 if (0 == memcmp(h
, ARMAG
, 8))
2573 return AFF_BINTYPE_AR
;
2574 #ifdef TCC_TARGET_COFF
2575 if (((struct filehdr
*)h
)->f_magic
== COFF_C67_MAGIC
)
2576 return AFF_BINTYPE_C67
;
2582 /* load an object file and merge it with current files */
2583 /* XXX: handle correctly stab (debug) info */
2584 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
2585 int fd
, unsigned long file_offset
)
2588 ElfW(Shdr
) *shdr
, *sh
;
2589 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
, seencompressed
;
2590 char *strsec
, *strtab
;
2591 int stab_index
, stabstr_index
;
2592 int *old_to_new_syms
;
2593 char *sh_name
, *name
;
2594 SectionMergeInfo
*sm_table
, *sm
;
2595 ElfW(Sym
) *sym
, *symtab
;
2599 lseek(fd
, file_offset
, SEEK_SET
);
2600 if (tcc_object_type(fd
, &ehdr
) != AFF_BINTYPE_REL
)
2602 /* test CPU specific stuff */
2603 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2604 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2606 tcc_error_noabort("invalid object file");
2610 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2611 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2612 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2614 /* load section names */
2615 sh
= &shdr
[ehdr
.e_shstrndx
];
2616 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2618 /* load symtab and strtab */
2619 old_to_new_syms
= NULL
;
2624 stab_index
= stabstr_index
= 0;
2626 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2628 if (sh
->sh_type
== SHT_SYMTAB
) {
2630 tcc_error_noabort("object must contain only one symtab");
2635 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2636 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2637 sm_table
[i
].s
= symtab_section
;
2639 /* now load strtab */
2640 sh
= &shdr
[sh
->sh_link
];
2641 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2643 if (sh
->sh_flags
& SHF_COMPRESSED
)
2647 /* now examine each section and try to merge its content with the
2649 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2650 /* no need to examine section name strtab */
2651 if (i
== ehdr
.e_shstrndx
)
2654 if (sh
->sh_type
== SHT_RELX
)
2655 sh
= &shdr
[sh
->sh_info
];
2656 /* ignore sections types we do not handle (plus relocs to those) */
2657 if (sh
->sh_type
!= SHT_PROGBITS
&&
2659 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2661 sh
->sh_type
!= SHT_NOBITS
&&
2662 sh
->sh_type
!= SHT_PREINIT_ARRAY
&&
2663 sh
->sh_type
!= SHT_INIT_ARRAY
&&
2664 sh
->sh_type
!= SHT_FINI_ARRAY
&&
2665 strcmp(strsec
+ sh
->sh_name
, ".stabstr")
2669 && !strncmp(strsec
+ sh
->sh_name
, ".debug_", sizeof(".debug_")-1))
2673 sh_name
= strsec
+ sh
->sh_name
;
2674 if (sh
->sh_addralign
< 1)
2675 sh
->sh_addralign
= 1;
2676 /* find corresponding section, if any */
2677 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2678 s
= s1
->sections
[j
];
2679 if (!strcmp(s
->name
, sh_name
)) {
2680 if (!strncmp(sh_name
, ".gnu.linkonce",
2681 sizeof(".gnu.linkonce") - 1)) {
2682 /* if a 'linkonce' section is already present, we
2683 do not add it again. It is a little tricky as
2684 symbols can still be defined in
2686 sm_table
[i
].link_once
= 1;
2690 if (s
== stab_section
)
2692 if (s
== stab_section
->link
)
2698 /* not found: create new section */
2699 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
& ~SHF_GROUP
);
2700 /* take as much info as possible from the section. sh_link and
2701 sh_info will be updated later */
2702 s
->sh_addralign
= sh
->sh_addralign
;
2703 s
->sh_entsize
= sh
->sh_entsize
;
2704 sm_table
[i
].new_section
= 1;
2706 if (sh
->sh_type
!= s
->sh_type
) {
2707 tcc_error_noabort("invalid section type");
2710 /* align start of section */
2711 s
->data_offset
+= -s
->data_offset
& (sh
->sh_addralign
- 1);
2712 if (sh
->sh_addralign
> s
->sh_addralign
)
2713 s
->sh_addralign
= sh
->sh_addralign
;
2714 sm_table
[i
].offset
= s
->data_offset
;
2716 /* concatenate sections */
2718 if (sh
->sh_type
!= SHT_NOBITS
) {
2720 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2721 ptr
= section_ptr_add(s
, size
);
2722 full_read(fd
, ptr
, size
);
2724 s
->data_offset
+= size
;
2729 /* gr relocate stab strings */
2730 if (stab_index
&& stabstr_index
) {
2733 s
= sm_table
[stab_index
].s
;
2734 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2735 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2736 o
= sm_table
[stabstr_index
].offset
;
2744 /* second short pass to update sh_link and sh_info fields of new
2746 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2748 if (!s
|| !sm_table
[i
].new_section
)
2751 if (sh
->sh_link
> 0)
2752 s
->link
= sm_table
[sh
->sh_link
].s
;
2753 if (sh
->sh_type
== SHT_RELX
) {
2754 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2755 /* update backward link */
2756 s1
->sections
[s
->sh_info
]->reloc
= s
;
2760 /* resolve symbols */
2761 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2764 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2765 if (sym
->st_shndx
!= SHN_UNDEF
&&
2766 sym
->st_shndx
< SHN_LORESERVE
) {
2767 sm
= &sm_table
[sym
->st_shndx
];
2768 if (sm
->link_once
) {
2769 /* if a symbol is in a link once section, we use the
2770 already defined symbol. It is very important to get
2771 correct relocations */
2772 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2773 name
= strtab
+ sym
->st_name
;
2774 sym_index
= find_elf_sym(symtab_section
, name
);
2776 old_to_new_syms
[i
] = sym_index
;
2780 /* if no corresponding section added, no need to add symbol */
2783 /* convert section number */
2784 sym
->st_shndx
= sm
->s
->sh_num
;
2786 sym
->st_value
+= sm
->offset
;
2789 name
= strtab
+ sym
->st_name
;
2790 sym_index
= set_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2791 sym
->st_info
, sym
->st_other
,
2792 sym
->st_shndx
, name
);
2793 old_to_new_syms
[i
] = sym_index
;
2796 /* third pass to patch relocation entries */
2797 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2802 offset
= sm_table
[i
].offset
;
2803 switch(s
->sh_type
) {
2805 /* take relocation offset information */
2806 offseti
= sm_table
[sh
->sh_info
].offset
;
2807 for_each_elem(s
, (offset
/ sizeof(*rel
)), rel
, ElfW_Rel
) {
2810 /* convert symbol index */
2811 type
= ELFW(R_TYPE
)(rel
->r_info
);
2812 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2813 /* NOTE: only one symtab assumed */
2814 if (sym_index
>= nb_syms
)
2816 sym_index
= old_to_new_syms
[sym_index
];
2817 /* ignore link_once in rel section. */
2818 if (!sym_index
&& !sm_table
[sh
->sh_info
].link_once
2819 #ifdef TCC_TARGET_ARM
2820 && type
!= R_ARM_V4BX
2821 #elif defined TCC_TARGET_RISCV64
2822 && type
!= R_RISCV_ALIGN
2823 && type
!= R_RISCV_RELAX
2827 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2828 i
, strsec
+ sh
->sh_name
, (int)rel
->r_offset
);
2831 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2832 /* offset the relocation offset */
2833 rel
->r_offset
+= offseti
;
2834 #ifdef TCC_TARGET_ARM
2835 /* Jumps and branches from a Thumb code to a PLT entry need
2836 special handling since PLT entries are ARM code.
2837 Unconditional bl instructions referencing PLT entries are
2838 handled by converting these instructions into blx
2839 instructions. Other case of instructions referencing a PLT
2840 entry require to add a Thumb stub before the PLT entry to
2841 switch to ARM mode. We set bit plt_thumb_stub of the
2842 attribute of a symbol to indicate such a case. */
2843 if (type
== R_ARM_THM_JUMP24
)
2844 get_sym_attr(s1
, sym_index
, 1)->plt_thumb_stub
= 1;
2857 tcc_free(old_to_new_syms
);
2864 typedef struct ArchiveHeader
{
2865 char ar_name
[16]; /* name of this member */
2866 char ar_date
[12]; /* file mtime */
2867 char ar_uid
[6]; /* owner uid; printed as decimal */
2868 char ar_gid
[6]; /* owner gid; printed as decimal */
2869 char ar_mode
[8]; /* file mode, printed as octal */
2870 char ar_size
[10]; /* file size, printed as decimal */
2871 char ar_fmag
[2]; /* should contain ARFMAG */
2874 #define ARFMAG "`\n"
2876 static unsigned long long get_be(const uint8_t *b
, int n
)
2878 unsigned long long ret
= 0;
2880 ret
= (ret
<< 8) | *b
++, --n
;
2884 static int read_ar_header(int fd
, int offset
, ArchiveHeader
*hdr
)
2888 lseek(fd
, offset
, SEEK_SET
);
2889 len
= full_read(fd
, hdr
, sizeof(ArchiveHeader
));
2890 if (len
!= sizeof(ArchiveHeader
))
2891 return len
? -1 : 0;
2893 for (e
= p
+ sizeof hdr
->ar_name
; e
> p
&& e
[-1] == ' ';)
2896 hdr
->ar_size
[sizeof hdr
->ar_size
-1] = 0;
2900 /* load only the objects which resolve undefined symbols */
2901 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
, int entrysize
)
2903 int i
, bound
, nsyms
, sym_index
, len
, ret
= -1;
2904 unsigned long long off
;
2906 const char *ar_names
, *p
;
2907 const uint8_t *ar_index
;
2911 data
= tcc_malloc(size
);
2912 if (full_read(fd
, data
, size
) != size
)
2914 nsyms
= get_be(data
, entrysize
);
2915 ar_index
= data
+ entrysize
;
2916 ar_names
= (char *) ar_index
+ nsyms
* entrysize
;
2920 for (p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2921 Section
*s
= symtab_section
;
2922 sym_index
= find_elf_sym(s
, p
);
2925 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
2926 if(sym
->st_shndx
!= SHN_UNDEF
)
2928 off
= get_be(ar_index
+ i
* entrysize
, entrysize
);
2929 len
= read_ar_header(fd
, off
, &hdr
);
2930 if (len
<= 0 || memcmp(hdr
.ar_fmag
, ARFMAG
, 2)) {
2931 tcc_error_noabort("invalid archive");
2935 if (s1
->verbose
== 2)
2936 printf(" -> %s\n", hdr
.ar_name
);
2937 if (tcc_load_object_file(s1
, fd
, off
) < 0)
2948 /* load a '.a' file */
2949 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
, int alacarte
)
2952 /* char magic[8]; */
2954 unsigned long file_offset
;
2957 /* skip magic which was already checked */
2958 /* full_read(fd, magic, sizeof(magic)); */
2959 file_offset
= sizeof ARMAG
- 1;
2962 len
= read_ar_header(fd
, file_offset
, &hdr
);
2966 tcc_error_noabort("invalid archive");
2970 size
= strtol(hdr
.ar_size
, NULL
, 0);
2972 size
= (size
+ 1) & ~1;
2974 /* coff symbol table : we handle it */
2975 if (!strcmp(hdr
.ar_name
, "/"))
2976 return tcc_load_alacarte(s1
, fd
, size
, 4);
2977 if (!strcmp(hdr
.ar_name
, "/SYM64/"))
2978 return tcc_load_alacarte(s1
, fd
, size
, 8);
2979 } else if (tcc_object_type(fd
, &ehdr
) == AFF_BINTYPE_REL
) {
2980 if (s1
->verbose
== 2)
2981 printf(" -> %s\n", hdr
.ar_name
);
2982 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2985 file_offset
+= size
;
2989 #ifndef ELF_OBJ_ONLY
2990 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
2991 LV, maybe create a new entry for (LIB,VERSION). */
2992 static void set_ver_to_ver(TCCState
*s1
, int *n
, int **lv
, int i
, char *lib
, char *version
)
2995 *lv
= tcc_realloc(*lv
, (*n
+ 1) * sizeof(**lv
));
2998 if ((*lv
)[i
] == -1) {
2999 int v
, prev_same_lib
= -1;
3000 for (v
= 0; v
< nb_sym_versions
; v
++) {
3001 if (strcmp(sym_versions
[v
].lib
, lib
))
3004 if (!strcmp(sym_versions
[v
].version
, version
))
3007 if (v
== nb_sym_versions
) {
3008 sym_versions
= tcc_realloc (sym_versions
,
3009 (v
+ 1) * sizeof(*sym_versions
));
3010 sym_versions
[v
].lib
= tcc_strdup(lib
);
3011 sym_versions
[v
].version
= tcc_strdup(version
);
3012 sym_versions
[v
].out_index
= 0;
3013 sym_versions
[v
].prev_same_lib
= prev_same_lib
;
3020 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3023 set_sym_version(TCCState
*s1
, int sym_index
, int verndx
)
3025 if (sym_index
>= nb_sym_to_version
) {
3026 int newelems
= sym_index
? sym_index
* 2 : 1;
3027 sym_to_version
= tcc_realloc(sym_to_version
,
3028 newelems
* sizeof(*sym_to_version
));
3029 memset(sym_to_version
+ nb_sym_to_version
, -1,
3030 (newelems
- nb_sym_to_version
) * sizeof(*sym_to_version
));
3031 nb_sym_to_version
= newelems
;
3033 if (sym_to_version
[sym_index
] < 0)
3034 sym_to_version
[sym_index
] = verndx
;
3037 struct versym_info
{
3039 ElfW(Verdef
) *verdef
;
3040 ElfW(Verneed
) *verneed
;
3042 int nb_local_ver
, *local_ver
;
3046 static void store_version(TCCState
*s1
, struct versym_info
*v
, char *dynstr
)
3048 char *lib
, *version
;
3052 #define DEBUG_VERSION 0
3054 if (v
->versym
&& v
->verdef
) {
3055 ElfW(Verdef
) *vdef
= v
->verdef
;
3058 ElfW(Verdaux
) *verdaux
=
3059 (ElfW(Verdaux
) *) (((char *) vdef
) + vdef
->vd_aux
);
3062 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3063 vdef
->vd_version
, vdef
->vd_flags
, vdef
->vd_ndx
,
3067 version
= dynstr
+ verdaux
->vda_name
;
3072 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vdef
->vd_ndx
,
3075 printf (" verdaux(%u): %s\n", vdef
->vd_ndx
, version
);
3078 next
= vdef
->vd_next
;
3079 vdef
= (ElfW(Verdef
) *) (((char *) vdef
) + next
);
3082 if (v
->versym
&& v
->verneed
) {
3083 ElfW(Verneed
) *vneed
= v
->verneed
;
3085 ElfW(Vernaux
) *vernaux
=
3086 (ElfW(Vernaux
) *) (((char *) vneed
) + vneed
->vn_aux
);
3088 lib
= dynstr
+ vneed
->vn_file
;
3090 printf ("verneed: %u %s\n", vneed
->vn_version
, lib
);
3092 for (i
= 0; i
< vneed
->vn_cnt
; i
++) {
3093 if ((vernaux
->vna_other
& 0x8000) == 0) { /* hidden */
3094 version
= dynstr
+ vernaux
->vna_name
;
3095 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vernaux
->vna_other
,
3098 printf (" vernaux(%u): %u %u %s\n",
3099 vernaux
->vna_other
, vernaux
->vna_hash
,
3100 vernaux
->vna_flags
, version
);
3103 vernaux
= (ElfW(Vernaux
) *) (((char *) vernaux
) + vernaux
->vna_next
);
3105 next
= vneed
->vn_next
;
3106 vneed
= (ElfW(Verneed
) *) (((char *) vneed
) + next
);
3111 for (i
= 0; i
< v
->nb_local_ver
; i
++) {
3112 if (v
->local_ver
[i
] > 0) {
3113 printf ("%d: lib: %s, version %s\n",
3114 i
, sym_versions
[v
->local_ver
[i
]].lib
,
3115 sym_versions
[v
->local_ver
[i
]].version
);
3121 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3122 is referenced by the user (so it should be added as DT_NEEDED in
3123 the generated ELF file) */
3124 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
3127 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
3128 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
3129 ElfW(Sym
) *sym
, *dynsym
;
3130 ElfW(Dyn
) *dt
, *dynamic
;
3134 const char *name
, *soname
;
3135 DLLReference
*dllref
;
3136 struct versym_info v
;
3138 full_read(fd
, &ehdr
, sizeof(ehdr
));
3140 /* test CPU specific stuff */
3141 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
3142 ehdr
.e_machine
!= EM_TCC_TARGET
) {
3143 tcc_error_noabort("bad architecture");
3148 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
3150 /* load dynamic section and dynamic symbols */
3154 dynsym
= NULL
; /* avoid warning */
3155 dynstr
= NULL
; /* avoid warning */
3156 memset(&v
, 0, sizeof v
);
3158 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
3159 switch(sh
->sh_type
) {
3161 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
3162 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3165 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
3166 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3167 sh1
= &shdr
[sh
->sh_link
];
3168 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
3170 case SHT_GNU_verdef
:
3171 v
.verdef
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3173 case SHT_GNU_verneed
:
3174 v
.verneed
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3176 case SHT_GNU_versym
:
3177 v
.nb_versyms
= sh
->sh_size
/ sizeof(ElfW(Half
));
3178 v
.versym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3185 /* compute the real library name */
3186 soname
= tcc_basename(filename
);
3188 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3189 if (dt
->d_tag
== DT_SONAME
) {
3190 soname
= dynstr
+ dt
->d_un
.d_val
;
3194 /* if the dll is already loaded, do not load it */
3195 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
3196 dllref
= s1
->loaded_dlls
[i
];
3197 if (!strcmp(soname
, dllref
->name
)) {
3198 /* but update level if needed */
3199 if (level
< dllref
->level
)
3200 dllref
->level
= level
;
3206 if (v
.nb_versyms
!= nb_syms
)
3207 tcc_free (v
.versym
), v
.versym
= NULL
;
3209 store_version(s1
, &v
, dynstr
);
3211 /* add the dll and its level */
3212 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
3213 dllref
->level
= level
;
3214 strcpy(dllref
->name
, soname
);
3215 dynarray_add(&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
3217 /* add dynamic symbols in dynsym_section */
3218 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
3219 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
3220 if (sym_bind
== STB_LOCAL
)
3222 name
= dynstr
+ sym
->st_name
;
3223 sym_index
= set_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
3224 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
3226 ElfW(Half
) vsym
= v
.versym
[i
];
3227 if ((vsym
& 0x8000) == 0 && vsym
> 0 && vsym
< v
.nb_local_ver
)
3228 set_sym_version(s1
, sym_index
, v
.local_ver
[vsym
]);
3232 /* load all referenced DLLs */
3233 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3236 name
= dynstr
+ dt
->d_un
.d_val
;
3237 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
3238 dllref
= s1
->loaded_dlls
[j
];
3239 if (!strcmp(name
, dllref
->name
))
3240 goto already_loaded
;
3242 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
3243 tcc_error_noabort("referenced dll '%s' not found", name
);
3257 tcc_free(v
.local_ver
);
3259 tcc_free(v
.verneed
);
3264 #define LD_TOK_NAME 256
3265 #define LD_TOK_EOF (-1)
3267 static int ld_inp(TCCState
*s1
)
3275 if (1 == read(s1
->fd
, &b
, 1))
3280 /* return next ld script token */
3281 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
3298 if (ch
== '*') { /* comment */
3299 for (d
= 0;; d
= ch
) {
3301 if (ch
== CH_EOF
|| (ch
== '/' && d
== '*'))
3312 /* case 'a' ... 'z': */
3339 /* case 'A' ... 'z': */
3373 if (!((ch
>= 'a' && ch
<= 'z') ||
3374 (ch
>= 'A' && ch
<= 'Z') ||
3375 (ch
>= '0' && ch
<= '9') ||
3376 strchr("/.-_+=$:\\,~", ch
)))
3378 if ((q
- name
) < name_size
- 1) {
3397 static int ld_add_file(TCCState
*s1
, const char filename
[])
3399 if (filename
[0] == '/') {
3400 if (CONFIG_SYSROOT
[0] == '\0'
3401 && tcc_add_file_internal(s1
, filename
, AFF_TYPE_BIN
) == 0)
3403 filename
= tcc_basename(filename
);
3405 return tcc_add_dll(s1
, filename
, 0);
3408 static int ld_add_file_list(TCCState
*s1
, const char *cmd
, int as_needed
)
3410 char filename
[1024], libname
[1024];
3411 int t
, group
, nblibs
= 0, ret
= 0;
3414 group
= !strcmp(cmd
, "GROUP");
3416 s1
->new_undef_sym
= 0;
3417 t
= ld_next(s1
, filename
, sizeof(filename
));
3419 tcc_error_noabort("( expected");
3421 goto lib_parse_error
;
3423 t
= ld_next(s1
, filename
, sizeof(filename
));
3426 if (t
== LD_TOK_EOF
) {
3427 tcc_error_noabort("unexpected end of file");
3429 goto lib_parse_error
;
3430 } else if (t
== ')') {
3432 } else if (t
== '-') {
3433 t
= ld_next(s1
, filename
, sizeof(filename
));
3434 if ((t
!= LD_TOK_NAME
) || (filename
[0] != 'l')) {
3435 tcc_error_noabort("library name expected");
3437 goto lib_parse_error
;
3439 pstrcpy(libname
, sizeof libname
, &filename
[1]);
3440 if (s1
->static_link
) {
3441 snprintf(filename
, sizeof filename
, "lib%s.a", libname
);
3443 snprintf(filename
, sizeof filename
, "lib%s.so", libname
);
3445 } else if (t
!= LD_TOK_NAME
) {
3446 tcc_error_noabort("filename expected");
3448 goto lib_parse_error
;
3450 if (!strcmp(filename
, "AS_NEEDED")) {
3451 ret
= ld_add_file_list(s1
, cmd
, 1);
3453 goto lib_parse_error
;
3455 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3457 ret
= ld_add_file(s1
, filename
);
3459 goto lib_parse_error
;
3461 /* Add the filename *and* the libname to avoid future conversions */
3462 dynarray_add(&libs
, &nblibs
, tcc_strdup(filename
));
3463 if (libname
[0] != '\0')
3464 dynarray_add(&libs
, &nblibs
, tcc_strdup(libname
));
3468 t
= ld_next(s1
, filename
, sizeof(filename
));
3470 t
= ld_next(s1
, filename
, sizeof(filename
));
3473 if (group
&& !as_needed
) {
3474 while (s1
->new_undef_sym
) {
3476 s1
->new_undef_sym
= 0;
3477 for (i
= 0; i
< nblibs
; i
++)
3478 ld_add_file(s1
, libs
[i
]);
3482 dynarray_reset(&libs
, &nblibs
);
3486 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3488 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
, int fd
)
3491 char filename
[1024];
3497 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3498 if (t
== LD_TOK_EOF
)
3500 else if (t
!= LD_TOK_NAME
)
3502 if (!strcmp(cmd
, "INPUT") ||
3503 !strcmp(cmd
, "GROUP")) {
3504 ret
= ld_add_file_list(s1
, cmd
, 0);
3507 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
3508 !strcmp(cmd
, "TARGET")) {
3509 /* ignore some commands */
3510 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3512 tcc_error_noabort("( expected");
3516 t
= ld_next(s1
, filename
, sizeof(filename
));
3517 if (t
== LD_TOK_EOF
) {
3518 tcc_error_noabort("unexpected end of file");
3520 } else if (t
== ')') {
3530 #endif /* !ELF_OBJ_ONLY */