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 */
485 ST_FUNC addr_t
get_elf_sym_addr(TCCState
*s1
, const char *name
, int err
)
490 sym_index
= find_elf_sym(s1
->symtab
, name
);
491 sym
= &((ElfW(Sym
) *)s1
->symtab
->data
)[sym_index
];
492 if (!sym_index
|| sym
->st_shndx
== SHN_UNDEF
) {
494 tcc_error("%s not defined", name
);
497 return sym
->st_value
;
500 /* list elf symbol names and values */
501 ST_FUNC
void list_elf_symbols(TCCState
*s
, void *ctx
,
502 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
506 int sym_index
, end_sym
;
508 unsigned char sym_vis
, sym_bind
;
511 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
512 for (sym_index
= 0; sym_index
< end_sym
; ++sym_index
) {
513 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
515 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
516 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
517 sym_vis
= ELFW(ST_VISIBILITY
)(sym
->st_other
);
518 if (sym_bind
== STB_GLOBAL
&& sym_vis
== STV_DEFAULT
)
519 symbol_cb(ctx
, name
, (void*)(uintptr_t)sym
->st_value
);
524 /* return elf symbol value */
525 LIBTCCAPI
void *tcc_get_symbol(TCCState
*s
, const char *name
)
527 return (void*)(uintptr_t)get_elf_sym_addr(s
, name
, 0);
530 /* list elf symbol names and values */
531 LIBTCCAPI
void tcc_list_symbols(TCCState
*s
, void *ctx
,
532 void (*symbol_cb
)(void *ctx
, const char *name
, const void *val
))
534 list_elf_symbols(s
, ctx
, symbol_cb
);
537 #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
538 /* return elf symbol value or error */
539 ST_FUNC
void* tcc_get_symbol_err(TCCState
*s
, const char *name
)
541 return (void*)(uintptr_t)get_elf_sym_addr(s
, name
, 1);
547 version_add (TCCState
*s1
)
551 ElfW(Verneed
) *vn
= NULL
;
553 int sym_index
, end_sym
, nb_versions
= 2, nb_entries
= 0;
557 if (0 == nb_sym_versions
)
559 versym_section
= new_section(s1
, ".gnu.version", SHT_GNU_versym
, SHF_ALLOC
);
560 versym_section
->sh_entsize
= sizeof(ElfW(Half
));
561 versym_section
->link
= s1
->dynsym
;
563 /* add needed symbols */
565 end_sym
= symtab
->data_offset
/ sizeof (ElfSym
);
566 versym
= section_ptr_add(versym_section
, end_sym
* sizeof(ElfW(Half
)));
567 for (sym_index
= 0; sym_index
< end_sym
; ++sym_index
) {
568 int dllindex
, verndx
;
569 sym
= &((ElfW(Sym
) *)symtab
->data
)[sym_index
];
570 name
= (char *) symtab
->link
->data
+ sym
->st_name
;
571 dllindex
= find_elf_sym(s1
->dynsymtab_section
, name
);
572 verndx
= (dllindex
&& dllindex
< nb_sym_to_version
)
573 ? sym_to_version
[dllindex
] : -1;
575 if (!sym_versions
[verndx
].out_index
)
576 sym_versions
[verndx
].out_index
= nb_versions
++;
577 versym
[sym_index
] = sym_versions
[verndx
].out_index
;
579 versym
[sym_index
] = 0;
581 /* generate verneed section, but not when it will be empty. Some
582 dynamic linkers look at their contents even when DTVERNEEDNUM and
583 section size is zero. */
584 if (nb_versions
> 2) {
585 verneed_section
= new_section(s1
, ".gnu.version_r",
586 SHT_GNU_verneed
, SHF_ALLOC
);
587 verneed_section
->link
= s1
->dynsym
->link
;
588 for (i
= nb_sym_versions
; i
-- > 0;) {
589 struct sym_version
*sv
= &sym_versions
[i
];
590 int n_same_libs
= 0, prev
;
592 ElfW(Vernaux
) *vna
= 0;
593 if (sv
->out_index
< 1)
595 vnofs
= section_add(verneed_section
, sizeof(*vn
), 1);
596 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
598 vn
->vn_file
= put_elf_str(verneed_section
->link
, sv
->lib
);
599 vn
->vn_aux
= sizeof (*vn
);
601 prev
= sv
->prev_same_lib
;
602 if (sv
->out_index
> 0) {
603 vna
= section_ptr_add(verneed_section
, sizeof(*vna
));
604 vna
->vna_hash
= elf_hash ((const unsigned char *)sv
->version
);
606 vna
->vna_other
= sv
->out_index
;
608 vna
->vna_name
= put_elf_str(verneed_section
->link
, sv
->version
);
609 vna
->vna_next
= sizeof (*vna
);
613 sv
= &sym_versions
[prev
];
616 vn
= (ElfW(Verneed
)*)(verneed_section
->data
+ vnofs
);
617 vn
->vn_cnt
= n_same_libs
;
618 vn
->vn_next
= sizeof(*vn
) + n_same_libs
* sizeof(*vna
);
623 verneed_section
->sh_info
= nb_entries
;
625 dt_verneednum
= nb_entries
;
629 /* add an elf symbol : check if it is already defined and patch
630 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
631 ST_FUNC
int set_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
632 int info
, int other
, int shndx
, const char *name
)
634 TCCState
*s1
= s
->s1
;
636 int sym_bind
, sym_index
, sym_type
, esym_bind
;
637 unsigned char sym_vis
, esym_vis
, new_vis
;
639 sym_bind
= ELFW(ST_BIND
)(info
);
640 sym_type
= ELFW(ST_TYPE
)(info
);
641 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
643 if (sym_bind
!= STB_LOCAL
) {
644 /* we search global or weak symbols */
645 sym_index
= find_elf_sym(s
, name
);
648 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
649 if (esym
->st_value
== value
&& esym
->st_size
== size
&& esym
->st_info
== info
650 && esym
->st_other
== other
&& esym
->st_shndx
== shndx
)
652 if (esym
->st_shndx
!= SHN_UNDEF
) {
653 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
654 /* propagate the most constraining visibility */
655 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
656 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
657 if (esym_vis
== STV_DEFAULT
) {
659 } else if (sym_vis
== STV_DEFAULT
) {
662 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
664 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
666 other
= esym
->st_other
; /* in case we have to patch esym */
667 if (shndx
== SHN_UNDEF
) {
668 /* ignore adding of undefined symbol if the
669 corresponding symbol is already defined */
670 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
671 /* global overrides weak, so patch */
673 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
674 /* weak is ignored if already global */
675 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_WEAK
) {
676 /* keep first-found weak definition, ignore subsequents */
677 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
678 /* ignore hidden symbols after */
679 } else if ((esym
->st_shndx
== SHN_COMMON
680 || esym
->st_shndx
== bss_section
->sh_num
)
681 && (shndx
< SHN_LORESERVE
682 && shndx
!= bss_section
->sh_num
)) {
683 /* data symbol gets precedence over common/bss */
685 } else if (shndx
== SHN_COMMON
|| shndx
== bss_section
->sh_num
) {
686 /* data symbol keeps precedence over common/bss */
687 } else if (s
->sh_flags
& SHF_DYNSYM
) {
688 /* we accept that two DLL define the same symbol */
689 } else if (esym
->st_other
& ST_ASM_SET
) {
690 /* If the existing symbol came from an asm .set
695 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
696 sym_bind
, shndx
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
698 tcc_error_noabort("'%s' defined twice", name
);
702 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
703 esym
->st_shndx
= shndx
;
704 s1
->new_undef_sym
= 1;
705 esym
->st_value
= value
;
706 esym
->st_size
= size
;
707 esym
->st_other
= other
;
711 sym_index
= put_elf_sym(s
, value
, size
,
712 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
719 ST_FUNC
void put_elf_reloca(Section
*symtab
, Section
*s
, unsigned long offset
,
720 int type
, int symbol
, addr_t addend
)
722 TCCState
*s1
= s
->s1
;
729 /* if no relocation section, create it */
730 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
731 /* if the symtab is allocated, then we consider the relocation
733 sr
= new_section(s
->s1
, buf
, SHT_RELX
, symtab
->sh_flags
);
734 sr
->sh_entsize
= sizeof(ElfW_Rel
);
736 sr
->sh_info
= s
->sh_num
;
739 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
740 rel
->r_offset
= offset
;
741 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
742 #if SHT_RELX == SHT_RELA
743 rel
->r_addend
= addend
;
745 if (SHT_RELX
!= SHT_RELA
&& addend
)
746 tcc_error("non-zero addend on REL architecture");
749 ST_FUNC
void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
750 int type
, int symbol
)
752 put_elf_reloca(symtab
, s
, offset
, type
, symbol
, 0);
755 /* Remove relocations for section S->reloc starting at oldrelocoffset
756 that are to the same place, retaining the last of them. As side effect
757 the relocations are sorted. Possibly reduces the number of relocs. */
758 ST_FUNC
void squeeze_multi_relocs(Section
*s
, size_t oldrelocoffset
)
760 Section
*sr
= s
->reloc
;
765 if (oldrelocoffset
+ sizeof(*r
) >= sr
->data_offset
)
767 /* The relocs we're dealing with are the result of initializer parsing.
768 So they will be mostly in order and there aren't many of them.
769 Secondly we need a stable sort (which qsort isn't). We use
770 a simple insertion sort. */
771 for (a
= oldrelocoffset
+ sizeof(*r
); a
< sr
->data_offset
; a
+= sizeof(*r
)) {
772 ssize_t i
= a
- sizeof(*r
);
773 addr
= ((ElfW_Rel
*)(sr
->data
+ a
))->r_offset
;
774 for (; i
>= (ssize_t
)oldrelocoffset
&&
775 ((ElfW_Rel
*)(sr
->data
+ i
))->r_offset
> addr
; i
-= sizeof(*r
)) {
776 ElfW_Rel tmp
= *(ElfW_Rel
*)(sr
->data
+ a
);
777 *(ElfW_Rel
*)(sr
->data
+ a
) = *(ElfW_Rel
*)(sr
->data
+ i
);
778 *(ElfW_Rel
*)(sr
->data
+ i
) = tmp
;
782 r
= (ElfW_Rel
*)(sr
->data
+ oldrelocoffset
);
784 for (; r
< (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
); r
++) {
785 if (dest
->r_offset
!= r
->r_offset
)
789 sr
->data_offset
= (unsigned char*)dest
- sr
->data
+ sizeof(*r
);
792 /* put stab debug information */
794 ST_FUNC
void put_stabs(TCCState
*s1
, const char *str
, int type
, int other
, int desc
,
801 && (offset
= stab_section
->data_offset
)
802 && (sym
= (Stab_Sym
*)(stab_section
->data
+ offset
) - 1)
803 && sym
->n_type
== type
804 && sym
->n_value
== value
) {
805 /* just update line_number in previous entry */
810 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
812 sym
->n_strx
= put_elf_str(stab_section
->link
, str
);
817 sym
->n_other
= other
;
819 sym
->n_value
= value
;
822 ST_FUNC
void put_stabs_r(TCCState
*s1
, const char *str
, int type
, int other
, int desc
,
823 unsigned long value
, Section
*sec
, int sym_index
)
825 put_elf_reloc(symtab_section
, stab_section
,
826 stab_section
->data_offset
+ 8,
827 sizeof ((Stab_Sym
*)0)->n_value
== PTR_SIZE
? R_DATA_PTR
: R_DATA_32
,
829 put_stabs(s1
, str
, type
, other
, desc
, value
);
832 ST_FUNC
void put_stabn(TCCState
*s1
, int type
, int other
, int desc
, int value
)
834 put_stabs(s1
, NULL
, type
, other
, desc
, value
);
837 ST_FUNC
struct sym_attr
*get_sym_attr(TCCState
*s1
, int index
, int alloc
)
840 struct sym_attr
*tab
;
842 if (index
>= s1
->nb_sym_attrs
) {
844 return s1
->sym_attrs
;
845 /* find immediately bigger power of 2 and reallocate array */
849 tab
= tcc_realloc(s1
->sym_attrs
, n
* sizeof(*s1
->sym_attrs
));
851 memset(s1
->sym_attrs
+ s1
->nb_sym_attrs
, 0,
852 (n
- s1
->nb_sym_attrs
) * sizeof(*s1
->sym_attrs
));
853 s1
->nb_sym_attrs
= n
;
855 return &s1
->sym_attrs
[index
];
858 /* In an ELF file symbol table, the local symbols must appear below
859 the global and weak ones. Since TCC cannot sort it while generating
860 the code, we must do it after. All the relocation tables are also
861 modified to take into account the symbol table sorting */
862 static void sort_syms(TCCState
*s1
, Section
*s
)
864 int *old_to_new_syms
;
872 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
873 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
874 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
876 /* first pass for local symbols */
877 p
= (ElfW(Sym
) *)s
->data
;
879 for(i
= 0; i
< nb_syms
; i
++) {
880 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
881 old_to_new_syms
[i
] = q
- new_syms
;
886 /* save the number of local symbols in section header */
887 if( s
->sh_size
) /* this 'if' makes IDA happy */
888 s
->sh_info
= q
- new_syms
;
890 /* then second pass for non local symbols */
891 p
= (ElfW(Sym
) *)s
->data
;
892 for(i
= 0; i
< nb_syms
; i
++) {
893 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
894 old_to_new_syms
[i
] = q
- new_syms
;
900 /* we copy the new symbols to the old */
901 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
904 /* now we modify all the relocations */
905 for(i
= 1; i
< s1
->nb_sections
; i
++) {
906 sr
= s1
->sections
[i
];
907 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
908 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
909 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
910 type
= ELFW(R_TYPE
)(rel
->r_info
);
911 sym_index
= old_to_new_syms
[sym_index
];
912 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
917 tcc_free(old_to_new_syms
);
920 /* relocate symbol table, resolve undefined symbols if do_resolve is
921 true and output error if undefined symbol. */
922 ST_FUNC
void relocate_syms(TCCState
*s1
, Section
*symtab
, int do_resolve
)
925 int sym_bind
, sh_num
;
928 for_each_elem(symtab
, 1, sym
, ElfW(Sym
)) {
929 sh_num
= sym
->st_shndx
;
930 if (sh_num
== SHN_UNDEF
) {
931 name
= (char *) s1
->symtab
->link
->data
+ sym
->st_name
;
932 /* Use ld.so to resolve symbol for us (for tcc -run) */
934 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
935 #ifdef TCC_TARGET_MACHO
936 /* The symbols in the symtables have a prepended '_'
937 but dlsym() needs the undecorated name. */
938 void *addr
= dlsym(RTLD_DEFAULT
, name
+ 1);
940 void *addr
= dlsym(RTLD_DEFAULT
, name
);
943 sym
->st_value
= (addr_t
) addr
;
945 printf ("relocate_sym: %s -> 0x%lx\n", name
, sym
->st_value
);
950 /* if dynamic symbol exist, it will be used in relocate_section */
951 } else if (s1
->dynsym
&& find_elf_sym(s1
->dynsym
, name
))
953 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
955 if (!strcmp(name
, "_fp_hw"))
957 /* only weak symbols are accepted to be undefined. Their
959 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
960 if (sym_bind
== STB_WEAK
)
963 tcc_error_noabort("undefined symbol '%s'", name
);
964 } else if (sh_num
< SHN_LORESERVE
) {
965 /* add section base */
966 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
972 /* relocate a given section (CPU dependent) by applying the relocations
973 in the associated relocation section */
974 ST_FUNC
void relocate_section(TCCState
*s1
, Section
*s
)
976 Section
*sr
= s
->reloc
;
983 qrel
= (ElfW_Rel
*)sr
->data
;
985 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
986 ptr
= s
->data
+ rel
->r_offset
;
987 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
988 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
989 type
= ELFW(R_TYPE
)(rel
->r_info
);
991 #if SHT_RELX == SHT_RELA
992 tgt
+= rel
->r_addend
;
994 addr
= s
->sh_addr
+ rel
->r_offset
;
995 relocate(s1
, rel
, type
, ptr
, addr
, tgt
);
997 /* if the relocation is allocated, we change its symbol table */
998 if (sr
->sh_flags
& SHF_ALLOC
) {
999 sr
->link
= s1
->dynsym
;
1000 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
1001 size_t r
= (uint8_t*)qrel
- sr
->data
;
1002 if (sizeof ((Stab_Sym
*)0)->n_value
< PTR_SIZE
1003 && 0 == strcmp(s
->name
, ".stab"))
1004 r
= 0; /* cannot apply 64bit relocation to 32bit value */
1005 sr
->data_offset
= sr
->sh_size
= r
;
1010 #ifndef ELF_OBJ_ONLY
1011 /* relocate relocation table in 'sr' */
1012 static void relocate_rel(TCCState
*s1
, Section
*sr
)
1017 s
= s1
->sections
[sr
->sh_info
];
1018 for_each_elem(sr
, 0, rel
, ElfW_Rel
)
1019 rel
->r_offset
+= s
->sh_addr
;
1022 /* count the number of dynamic relocations so that we can reserve
1024 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
1027 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1029 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
1030 int sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1031 int type
= ELFW(R_TYPE
)(rel
->r_info
);
1033 #if defined(TCC_TARGET_I386)
1035 if (!get_sym_attr(s1
, sym_index
, 0)->dyn_index
1036 && ((ElfW(Sym
)*)symtab_section
->data
+ sym_index
)->st_shndx
== SHN_UNDEF
) {
1037 /* don't fixup unresolved (weak) symbols */
1038 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_386_RELATIVE
);
1041 #elif defined(TCC_TARGET_X86_64)
1048 #if defined(TCC_TARGET_I386)
1050 #elif defined(TCC_TARGET_X86_64)
1053 if (get_sym_attr(s1
, sym_index
, 0)->dyn_index
)
1061 /* allocate the section */
1062 sr
->sh_flags
|= SHF_ALLOC
;
1063 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
1070 #if !defined(ELF_OBJ_ONLY) || defined(TCC_TARGET_MACHO)
1071 static void build_got(TCCState
*s1
)
1073 /* if no got, then create it */
1074 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
1075 s1
->got
->sh_entsize
= 4;
1076 set_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
1077 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
1078 /* keep space for _DYNAMIC pointer and two dummy got entries */
1079 section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
1082 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1083 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1084 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1085 Returns the offset of the GOT or (if any) PLT entry. */
1086 static struct sym_attr
* put_got_entry(TCCState
*s1
, int dyn_reloc_type
,
1092 struct sym_attr
*attr
;
1093 unsigned got_offset
;
1097 need_plt_entry
= (dyn_reloc_type
== R_JMP_SLOT
);
1098 attr
= get_sym_attr(s1
, sym_index
, 1);
1100 /* In case a function is both called and its address taken 2 GOT entries
1101 are created, one for taking the address (GOT) and the other for the PLT
1103 if (need_plt_entry
? attr
->plt_offset
: attr
->got_offset
)
1106 /* create the GOT entry */
1107 got_offset
= s1
->got
->data_offset
;
1108 section_ptr_add(s1
->got
, PTR_SIZE
);
1110 /* Create the GOT relocation that will insert the address of the object or
1111 function of interest in the GOT entry. This is a static relocation for
1112 memory output (dlsym will give us the address of symbols) and dynamic
1113 relocation otherwise (executable and DLLs). The relocation should be
1114 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1115 associated to a PLT entry) but is currently done at load time for an
1118 sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1119 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1122 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
) {
1123 /* Hack alarm. We don't want to emit dynamic symbols
1124 and symbol based relocs for STB_LOCAL symbols, but rather
1125 want to resolve them directly. At this point the symbol
1126 values aren't final yet, so we must defer this. We will later
1127 have to create a RELATIVE reloc anyway, so we misuse the
1128 relocation slot to smuggle the symbol reference until
1129 fill_local_got_entries. Not that the sym_index is
1130 relative to symtab_section, not s1->dynsym! Nevertheless
1131 we use s1->dyn_sym so that if this is the first call
1132 that got->reloc is correctly created. Also note that
1133 RELATIVE relocs are not normally created for the .got,
1134 so the types serves as a marker for later (and is retained
1135 also for the final output, which is okay because then the
1136 got is just normal data). */
1137 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, R_RELATIVE
,
1140 if (0 == attr
->dyn_index
)
1141 attr
->dyn_index
= set_elf_sym(s1
->dynsym
, sym
->st_value
,
1142 sym
->st_size
, sym
->st_info
, 0,
1143 sym
->st_shndx
, name
);
1144 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, dyn_reloc_type
,
1148 put_elf_reloc(symtab_section
, s1
->got
, got_offset
, dyn_reloc_type
,
1152 if (need_plt_entry
) {
1154 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1155 SHF_ALLOC
| SHF_EXECINSTR
);
1156 s1
->plt
->sh_entsize
= 4;
1159 attr
->plt_offset
= create_plt_entry(s1
, got_offset
, attr
);
1161 /* create a symbol 'sym@plt' for the PLT jump vector */
1163 if (len
> sizeof plt_name
- 5)
1164 len
= sizeof plt_name
- 5;
1165 memcpy(plt_name
, name
, len
);
1166 strcpy(plt_name
+ len
, "@plt");
1167 attr
->plt_sym
= put_elf_sym(s1
->symtab
, attr
->plt_offset
, sym
->st_size
,
1168 ELFW(ST_INFO
)(STB_GLOBAL
, STT_FUNC
), 0, s1
->plt
->sh_num
, plt_name
);
1171 attr
->got_offset
= got_offset
;
1177 /* build GOT and PLT entries */
1178 ST_FUNC
void build_got_entries(TCCState
*s1
)
1183 int i
, type
, gotplt_entry
, reloc_type
, sym_index
;
1184 struct sym_attr
*attr
;
1186 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1187 s
= s1
->sections
[i
];
1188 if (s
->sh_type
!= SHT_RELX
)
1190 /* no need to handle got relocations */
1191 if (s
->link
!= symtab_section
)
1193 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1194 type
= ELFW(R_TYPE
)(rel
->r_info
);
1195 gotplt_entry
= gotplt_entry_type(type
);
1196 if (gotplt_entry
== -1)
1197 tcc_error ("Unknown relocation type for got: %d", type
);
1198 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1199 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1201 if (gotplt_entry
== NO_GOTPLT_ENTRY
) {
1205 /* Automatically create PLT/GOT [entry] if it is an undefined
1206 reference (resolved at runtime), or the symbol is absolute,
1207 probably created by tcc_add_symbol, and thus on 64-bit
1208 targets might be too far from application code. */
1209 if (gotplt_entry
== AUTO_GOTPLT_ENTRY
) {
1210 if (sym
->st_shndx
== SHN_UNDEF
) {
1213 if (s1
->output_type
== TCC_OUTPUT_DLL
&& ! PCRELATIVE_DLLPLT
)
1215 /* Relocations for UNDEF symbols would normally need
1216 to be transferred into the executable or shared object.
1217 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1218 But TCC doesn't do that (at least for exes), so we
1219 need to resolve all such relocs locally. And that
1220 means PLT slots for functions in DLLs and COPY relocs for
1221 data symbols. COPY relocs were generated in
1222 bind_exe_dynsyms (and the symbol adjusted to be defined),
1223 and for functions we were generated a dynamic symbol
1224 of function type. */
1226 /* dynsym isn't set for -run :-/ */
1227 dynindex
= get_sym_attr(s1
, sym_index
, 0)->dyn_index
;
1228 esym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ dynindex
;
1230 && (ELFW(ST_TYPE
)(esym
->st_info
) == STT_FUNC
1231 || (ELFW(ST_TYPE
)(esym
->st_info
) == STT_NOTYPE
1232 && ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
)))
1235 } else if (!(sym
->st_shndx
== SHN_ABS
1236 #ifndef TCC_TARGET_ARM
1243 #ifdef TCC_TARGET_X86_64
1244 if ((type
== R_X86_64_PLT32
|| type
== R_X86_64_PC32
) &&
1245 sym
->st_shndx
!= SHN_UNDEF
&&
1246 (ELFW(ST_VISIBILITY
)(sym
->st_other
) != STV_DEFAULT
||
1247 ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
||
1248 s1
->output_type
== TCC_OUTPUT_EXE
)) {
1249 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PC32
);
1253 reloc_type
= code_reloc(type
);
1254 if (reloc_type
== -1)
1255 tcc_error ("Unknown relocation type: %d", type
);
1256 else if (reloc_type
!= 0) {
1258 reloc_type
= R_JMP_SLOT
;
1260 reloc_type
= R_GLOB_DAT
;
1265 if (gotplt_entry
== BUILD_GOT_ONLY
)
1268 attr
= put_got_entry(s1
, reloc_type
, sym_index
);
1270 if (reloc_type
== R_JMP_SLOT
)
1271 rel
->r_info
= ELFW(R_INFO
)(attr
->plt_sym
, type
);
1277 ST_FUNC
int set_global_sym(TCCState
*s1
, const char *name
, Section
*sec
, long offs
)
1279 int shn
= sec
? sec
->sh_num
: offs
? SHN_ABS
: SHN_UNDEF
;
1280 if (sec
&& offs
== -1)
1281 offs
= sec
->data_offset
;
1282 return set_elf_sym(symtab_section
, offs
, 0,
1283 ELFW(ST_INFO
)(name
? STB_GLOBAL
: STB_LOCAL
, STT_NOTYPE
), 0, shn
, name
);
1286 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1291 s
= find_section(s1
, section_name
);
1296 end_offset
= s
->data_offset
;
1298 snprintf(buf
, sizeof(buf
), "__%s_start", section_name
+ 1);
1299 set_global_sym(s1
, buf
, s
, 0);
1300 snprintf(buf
, sizeof(buf
), "__%s_end", section_name
+ 1);
1301 set_global_sym(s1
, buf
, s
, end_offset
);
1304 #ifndef TCC_TARGET_PE
1305 static int tcc_add_support(TCCState
*s1
, const char *filename
)
1308 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, filename
);
1309 return tcc_add_file(s1
, buf
);
1313 ST_FUNC
void add_array (TCCState
*s1
, const char *sec
, int c
)
1316 s
= find_section(s1
, sec
);
1317 s
->sh_flags
|= SHF_WRITE
;
1318 #ifndef TCC_TARGET_PE
1319 s
->sh_type
= sec
[1] == 'i' ? SHT_INIT_ARRAY
: SHT_FINI_ARRAY
;
1321 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1322 section_ptr_add(s
, PTR_SIZE
);
1325 #ifdef CONFIG_TCC_BCHECK
1326 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
1328 if (0 == s1
->do_bounds_check
)
1330 section_ptr_add(bounds_section
, sizeof(addr_t
));
1334 #ifdef CONFIG_TCC_BACKTRACE
1335 static void put_ptr(TCCState
*s1
, Section
*s
, int offs
)
1338 c
= set_global_sym(s1
, NULL
, s
, offs
);
1340 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1341 section_ptr_add(s
, PTR_SIZE
);
1344 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1345 a dynamic symbol to allow so's to have one each with a different value. */
1346 static void set_local_sym(TCCState
*s1
, const char *name
, Section
*s
, int offset
)
1348 int c
= find_elf_sym(s1
->symtab
, name
);
1350 ElfW(Sym
) *esym
= (ElfW(Sym
)*)s1
->symtab
->data
+ c
;
1351 esym
->st_info
= ELFW(ST_INFO
)(STB_LOCAL
, STT_NOTYPE
);
1352 esym
->st_value
= offset
;
1353 esym
->st_shndx
= s
->sh_num
;
1357 ST_FUNC
void tcc_add_btstub(TCCState
*s1
)
1365 /* create (part of) a struct rt_context (see tccrun.c) */
1366 put_ptr(s1
, stab_section
, 0);
1367 put_ptr(s1
, stab_section
, -1);
1368 put_ptr(s1
, stab_section
->link
, 0);
1369 section_ptr_add(s
, 3 * PTR_SIZE
);
1371 put_elf_reloc(s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, 0);
1372 section_ptr_add(s
, PTR_SIZE
);
1374 #ifdef CONFIG_TCC_BCHECK
1375 if (s1
->do_bounds_check
) {
1376 put_ptr(s1
, bounds_section
, 0);
1380 section_ptr_add(s
, n
);
1384 " extern void __bt_init(),*__rt_info[],__bt_init_dll();"
1385 "__attribute__((constructor)) static void __bt_init_rt(){");
1386 #ifdef TCC_TARGET_PE
1387 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1388 #ifdef CONFIG_TCC_BCHECK
1389 cstr_printf(&cstr
, "__bt_init_dll(%d);", s1
->do_bounds_check
);
1391 cstr_printf(&cstr
, "__bt_init_dll(0);");
1394 cstr_printf(&cstr
, "__bt_init(__rt_info,%d);}",
1395 s1
->output_type
== TCC_OUTPUT_DLL
? 0 : s1
->rt_num_callers
+ 1);
1396 tcc_compile_string(s1
, cstr
.data
);
1398 set_local_sym(s1
, "__rt_info", s
, o
);
1402 #ifndef TCC_TARGET_PE
1403 /* add tcc runtime libraries */
1404 ST_FUNC
void tcc_add_runtime(TCCState
*s1
)
1407 #ifdef CONFIG_TCC_BCHECK
1410 tcc_add_pragma_libs(s1
);
1412 if (!s1
->nostdlib
) {
1413 if (s1
->option_pthread
)
1414 tcc_add_library_err(s1
, "pthread");
1415 tcc_add_library_err(s1
, "c");
1417 if (!s1
->static_link
) {
1418 if (TCC_LIBGCC
[0] == '/')
1419 tcc_add_file(s1
, TCC_LIBGCC
);
1421 tcc_add_dll(s1
, TCC_LIBGCC
, 0);
1424 #ifdef CONFIG_TCC_BCHECK
1425 if (s1
->do_bounds_check
&& s1
->output_type
!= TCC_OUTPUT_DLL
) {
1426 tcc_add_library_err(s1
, "pthread");
1427 tcc_add_library_err(s1
, "dl");
1428 tcc_add_support(s1
, "bcheck.o");
1431 #ifdef CONFIG_TCC_BACKTRACE
1432 if (s1
->do_backtrace
) {
1433 if (s1
->output_type
== TCC_OUTPUT_EXE
)
1434 tcc_add_support(s1
, "bt-exe.o");
1435 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1436 tcc_add_support(s1
, "bt-log.o");
1437 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1441 tcc_add_support(s1
, TCC_LIBTCC1
);
1442 /* add crt end if not memory output */
1443 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1444 tcc_add_crt(s1
, "crtn.o");
1449 /* add various standard linker symbols (must be done after the
1450 sections are filled (for example after allocating common
1452 static void tcc_add_linker_symbols(TCCState
*s1
)
1458 set_global_sym(s1
, "_etext", text_section
, -1);
1459 set_global_sym(s1
, "_edata", data_section
, -1);
1460 set_global_sym(s1
, "_end", bss_section
, -1);
1461 #ifdef TCC_TARGET_RISCV64
1462 /* XXX should be .sdata+0x800, not .data+0x800 */
1463 set_global_sym(s1
, "__global_pointer$", data_section
, 0x800);
1465 /* horrible new standard ldscript defines */
1466 add_init_array_defines(s1
, ".preinit_array");
1467 add_init_array_defines(s1
, ".init_array");
1468 add_init_array_defines(s1
, ".fini_array");
1469 /* add start and stop symbols for sections whose name can be
1471 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1472 s
= s1
->sections
[i
];
1473 if ((s
->sh_flags
& SHF_ALLOC
)
1474 && (s
->sh_type
== SHT_PROGBITS
1475 || s
->sh_type
== SHT_STRTAB
)) {
1477 /* check if section name can be expressed in C */
1483 if (!isid(c
) && !isnum(c
))
1487 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1488 set_global_sym(s1
, buf
, s
, 0);
1489 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1490 set_global_sym(s1
, buf
, s
, -1);
1496 ST_FUNC
void resolve_common_syms(TCCState
*s1
)
1500 /* Allocate common symbols in BSS. */
1501 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1502 if (sym
->st_shndx
== SHN_COMMON
) {
1503 /* symbol alignment is in st_value for SHN_COMMONs */
1504 sym
->st_value
= section_add(bss_section
, sym
->st_size
,
1506 sym
->st_shndx
= bss_section
->sh_num
;
1510 /* Now assign linker provided symbols their value. */
1511 tcc_add_linker_symbols(s1
);
1514 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1515 const int *sec_order
)
1518 int i
, offset
, size
;
1521 for(i
=1;i
<s1
->nb_sections
;i
++) {
1522 s
= s1
->sections
[sec_order
[i
]];
1523 if (s
->sh_type
!= SHT_NOBITS
&&
1524 (s
->sh_flags
& SHF_ALLOC
)) {
1525 while (offset
< s
->sh_offset
) {
1530 fwrite(s
->data
, 1, size
, f
);
1536 #ifndef ELF_OBJ_ONLY
1537 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1539 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1540 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1541 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1542 unsigned offset
= attr
->got_offset
;
1546 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1547 #ifdef TCC_TARGET_X86_64
1548 write64le(s1
->got
->data
+ offset
, sym
->st_value
);
1550 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1554 /* Perform relocation to GOT or PLT entries */
1555 ST_FUNC
void fill_got(TCCState
*s1
)
1561 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1562 s
= s1
->sections
[i
];
1563 if (s
->sh_type
!= SHT_RELX
)
1565 /* no need to handle got relocations */
1566 if (s
->link
!= symtab_section
)
1568 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1569 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1570 case R_X86_64_GOT32
:
1571 case R_X86_64_GOTPCREL
:
1572 case R_X86_64_GOTPCRELX
:
1573 case R_X86_64_REX_GOTPCRELX
:
1574 case R_X86_64_PLT32
:
1575 fill_got_entry(s1
, rel
);
1582 /* See put_got_entry for a description. This is the second stage
1583 where GOT references to local defined symbols are rewritten. */
1584 static void fill_local_got_entries(TCCState
*s1
)
1587 if (!s1
->got
->reloc
)
1589 for_each_elem(s1
->got
->reloc
, 0, rel
, ElfW_Rel
) {
1590 if (ELFW(R_TYPE
)(rel
->r_info
) == R_RELATIVE
) {
1591 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1592 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1593 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1594 unsigned offset
= attr
->got_offset
;
1595 if (offset
!= rel
->r_offset
- s1
->got
->sh_addr
)
1596 tcc_error_noabort("huh");
1597 rel
->r_info
= ELFW(R_INFO
)(0, R_RELATIVE
);
1598 #if SHT_RELX == SHT_RELA
1599 rel
->r_addend
= sym
->st_value
;
1601 /* All our REL architectures also happen to be 32bit LE. */
1602 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1608 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1609 in shared libraries and export non local defined symbols to shared libraries
1610 if -rdynamic switch was given on command line */
1611 static void bind_exe_dynsyms(TCCState
*s1
)
1614 int sym_index
, index
;
1615 ElfW(Sym
) *sym
, *esym
;
1618 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1619 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1620 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1621 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1622 if (sym
->st_shndx
== SHN_UNDEF
) {
1623 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1624 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1626 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1627 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1628 if ((type
== STT_FUNC
) || (type
== STT_GNU_IFUNC
)) {
1629 /* Indirect functions shall have STT_FUNC type in executable
1630 * dynsym section. Indeed, a dlsym call following a lazy
1631 * resolution would pick the symbol value from the
1632 * executable dynsym entry which would contain the address
1633 * of the function wanted by the caller of dlsym instead of
1634 * the address of the function that would return that
1637 = put_elf_sym(s1
->dynsym
, 0, esym
->st_size
,
1638 ELFW(ST_INFO
)(STB_GLOBAL
,STT_FUNC
), 0, 0,
1640 int index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1641 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1642 } else if (type
== STT_OBJECT
) {
1643 unsigned long offset
;
1645 offset
= bss_section
->data_offset
;
1646 /* XXX: which alignment ? */
1647 offset
= (offset
+ 16 - 1) & -16;
1648 set_elf_sym (s1
->symtab
, offset
, esym
->st_size
,
1649 esym
->st_info
, 0, bss_section
->sh_num
, name
);
1650 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1651 esym
->st_info
, 0, bss_section
->sh_num
,
1654 /* Ensure R_COPY works for weak symbol aliases */
1655 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1656 for_each_elem(s1
->dynsymtab_section
, 1, dynsym
, ElfW(Sym
)) {
1657 if ((dynsym
->st_value
== esym
->st_value
)
1658 && (ELFW(ST_BIND
)(dynsym
->st_info
) == STB_GLOBAL
)) {
1659 char *dynname
= (char *) s1
->dynsymtab_section
->link
->data
1661 put_elf_sym(s1
->dynsym
, offset
, dynsym
->st_size
,
1663 bss_section
->sh_num
, dynname
);
1669 put_elf_reloc(s1
->dynsym
, bss_section
,
1670 offset
, R_COPY
, index
);
1671 offset
+= esym
->st_size
;
1672 bss_section
->data_offset
= offset
;
1675 /* STB_WEAK undefined symbols are accepted */
1676 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1677 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1678 !strcmp(name
, "_fp_hw")) {
1680 tcc_error_noabort("undefined symbol '%s'", name
);
1683 } else if (s1
->rdynamic
&& ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1684 /* if -rdynamic option, then export all non local symbols */
1685 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1686 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
1687 0, sym
->st_shndx
, name
);
1692 /* Bind symbols of libraries: export all non local symbols of executable that
1693 are referenced by shared libraries. The reason is that the dynamic loader
1694 search symbol first in executable and then in libraries. Therefore a
1695 reference to a symbol already defined by a library can still be resolved by
1696 a symbol in the executable. */
1697 static void bind_libs_dynsyms(TCCState
*s1
)
1701 ElfW(Sym
) *sym
, *esym
;
1703 for_each_elem(s1
->dynsymtab_section
, 1, esym
, ElfW(Sym
)) {
1704 name
= (char *) s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1705 sym_index
= find_elf_sym(symtab_section
, name
);
1706 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1707 if (sym_index
&& sym
->st_shndx
!= SHN_UNDEF
1708 && ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1709 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1710 sym
->st_info
, 0, sym
->st_shndx
, name
);
1711 } else if (esym
->st_shndx
== SHN_UNDEF
) {
1712 /* weak symbols can stay undefined */
1713 if (ELFW(ST_BIND
)(esym
->st_info
) != STB_WEAK
)
1714 tcc_warning("undefined dynamic symbol '%s'", name
);
1719 /* Export all non local symbols. This is used by shared libraries so that the
1720 non local symbols they define can resolve a reference in another shared
1721 library or in the executable. Correspondingly, it allows undefined local
1722 symbols to be resolved by other shared libraries or by the executable. */
1723 static void export_global_syms(TCCState
*s1
)
1725 int dynindex
, index
;
1729 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1730 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1731 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1732 dynindex
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1733 sym
->st_info
, 0, sym
->st_shndx
, name
);
1734 index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1735 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1741 /* Allocate strings for section names and decide if an unallocated section
1743 NOTE: the strsec section comes last, so its size is also correct ! */
1744 static int alloc_sec_names(TCCState
*s1
, int file_type
, Section
*strsec
)
1750 /* Allocate strings for section names */
1751 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1752 s
= s1
->sections
[i
];
1753 /* when generating a DLL, we include relocations but we may
1755 #ifndef ELF_OBJ_ONLY
1756 if (file_type
== TCC_OUTPUT_DLL
&&
1757 s
->sh_type
== SHT_RELX
&&
1758 !(s
->sh_flags
& SHF_ALLOC
) &&
1759 (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
) &&
1760 prepare_dynamic_rel(s1
, s
)) {
1761 if (!(s1
->sections
[s
->sh_info
]->sh_flags
& SHF_WRITE
))
1765 if ((s1
->do_debug
&& s
->sh_type
!= SHT_RELX
) ||
1766 file_type
== TCC_OUTPUT_OBJ
||
1767 (s
->sh_flags
& SHF_ALLOC
) ||
1768 i
== (s1
->nb_sections
- 1)) {
1769 /* we output all sections if debug or object file */
1770 s
->sh_size
= s
->data_offset
;
1772 if (s
->sh_size
|| (s
->sh_flags
& SHF_ALLOC
))
1773 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1775 strsec
->sh_size
= strsec
->data_offset
;
1779 /* Info to be copied in dynamic section */
1783 unsigned long data_offset
;
1786 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1792 /* Assign sections to segments and decide how are sections laid out when loaded
1793 in memory. This function also fills corresponding program headers. */
1794 static int layout_sections(TCCState
*s1
, ElfW(Phdr
) *phdr
, int phnum
,
1795 Section
*interp
, Section
* strsec
,
1796 struct dyn_inf
*dyninf
, int *sec_order
)
1798 int i
, j
, k
, file_type
, sh_order_index
, file_offset
;
1799 unsigned long s_align
;
1805 file_type
= s1
->output_type
;
1808 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
1809 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1810 s_align
= ELF_PAGE_SIZE
;
1811 if (s1
->section_align
)
1812 s_align
= s1
->section_align
;
1815 if (s1
->has_text_addr
) {
1816 int a_offset
, p_offset
;
1817 addr
= s1
->text_addr
;
1818 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1820 a_offset
= (int) (addr
& (s_align
- 1));
1821 p_offset
= file_offset
& (s_align
- 1);
1822 if (a_offset
< p_offset
)
1823 a_offset
+= s_align
;
1824 file_offset
+= (a_offset
- p_offset
);
1826 if (file_type
== TCC_OUTPUT_DLL
)
1829 addr
= ELF_START_ADDR
;
1830 /* compute address after headers */
1831 addr
+= (file_offset
& (s_align
- 1));
1835 /* Leave one program headers for the program interpreter and one for
1836 the program header table itself if needed. These are done later as
1837 they require section layout to be done first. */
1841 /* dynamic relocation table information, for .dynamic section */
1842 dyninf
->rel_addr
= dyninf
->rel_size
= 0;
1843 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1844 dyninf
->bss_addr
= dyninf
->bss_size
= 0;
1847 for(j
= 0; j
< 2; j
++) {
1848 ph
->p_type
= PT_LOAD
;
1850 ph
->p_flags
= PF_R
| PF_X
;
1852 ph
->p_flags
= PF_R
| PF_W
;
1853 ph
->p_align
= s_align
;
1855 /* Decide the layout of sections loaded in memory. This must
1856 be done before program headers are filled since they contain
1857 info about the layout. We do the following ordering: interp,
1858 symbol tables, relocations, progbits, nobits */
1859 /* XXX: do faster and simpler sorting */
1860 for(k
= 0; k
< 5; k
++) {
1861 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1862 s
= s1
->sections
[i
];
1863 /* compute if section should be included */
1865 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1869 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1870 (SHF_ALLOC
| SHF_WRITE
))
1876 } else if ((s
->sh_type
== SHT_DYNSYM
||
1877 s
->sh_type
== SHT_STRTAB
||
1878 s
->sh_type
== SHT_HASH
)
1879 && !strstr(s
->name
, ".stab")) {
1882 } else if (s
->sh_type
== SHT_RELX
) {
1885 } else if (s
->sh_type
== SHT_NOBITS
) {
1892 sec_order
[sh_order_index
++] = i
;
1894 /* section matches: we align it and add its size */
1896 addr
= (addr
+ s
->sh_addralign
- 1) &
1897 ~(s
->sh_addralign
- 1);
1898 file_offset
+= (int) ( addr
- tmp
);
1899 s
->sh_offset
= file_offset
;
1902 /* update program header infos */
1903 if (ph
->p_offset
== 0) {
1904 ph
->p_offset
= file_offset
;
1906 ph
->p_paddr
= ph
->p_vaddr
;
1908 /* update dynamic relocation infos */
1909 if (s
->sh_type
== SHT_RELX
) {
1910 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1911 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.got")) {
1912 dyninf
->rel_addr
= addr
;
1913 dyninf
->rel_size
+= s
->sh_size
; /* XXX only first rel. */
1915 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.bss")) {
1916 dyninf
->bss_addr
= addr
;
1917 dyninf
->bss_size
= s
->sh_size
; /* XXX only first rel. */
1920 if (dyninf
->rel_size
== 0)
1921 dyninf
->rel_addr
= addr
;
1922 dyninf
->rel_size
+= s
->sh_size
;
1926 if (s
->sh_type
!= SHT_NOBITS
)
1927 file_offset
+= s
->sh_size
;
1931 /* Make the first PT_LOAD segment include the program
1932 headers itself (and the ELF header as well), it'll
1933 come out with same memory use but will make various
1934 tools like binutils strip work better. */
1935 ph
->p_offset
&= ~(ph
->p_align
- 1);
1936 ph
->p_vaddr
&= ~(ph
->p_align
- 1);
1937 ph
->p_paddr
&= ~(ph
->p_align
- 1);
1939 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1940 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1943 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1944 /* if in the middle of a page, we duplicate the page in
1945 memory so that one copy is RX and the other is RW */
1946 if ((addr
& (s_align
- 1)) != 0)
1949 addr
= (addr
+ s_align
- 1) & ~(s_align
- 1);
1950 file_offset
= (file_offset
+ s_align
- 1) & ~(s_align
- 1);
1956 /* all other sections come after */
1957 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1958 s
= s1
->sections
[i
];
1959 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1961 sec_order
[sh_order_index
++] = i
;
1963 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1964 ~(s
->sh_addralign
- 1);
1965 s
->sh_offset
= file_offset
;
1966 if (s
->sh_type
!= SHT_NOBITS
)
1967 file_offset
+= s
->sh_size
;
1973 #ifndef ELF_OBJ_ONLY
1974 /* put dynamic tag */
1975 static void put_dt(Section
*dynamic
, int dt
, addr_t val
)
1978 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1980 dyn
->d_un
.d_val
= val
;
1983 static void fill_unloadable_phdr(ElfW(Phdr
) *phdr
, int phnum
, Section
*interp
,
1988 /* if interpreter, then add corresponding program header */
1992 ph
->p_type
= PT_PHDR
;
1993 ph
->p_offset
= sizeof(ElfW(Ehdr
));
1994 ph
->p_filesz
= ph
->p_memsz
= phnum
* sizeof(ElfW(Phdr
));
1995 ph
->p_vaddr
= interp
->sh_addr
- ph
->p_filesz
;
1996 ph
->p_paddr
= ph
->p_vaddr
;
1997 ph
->p_flags
= PF_R
| PF_X
;
1998 ph
->p_align
= 4; /* interp->sh_addralign; */
2001 ph
->p_type
= PT_INTERP
;
2002 ph
->p_offset
= interp
->sh_offset
;
2003 ph
->p_vaddr
= interp
->sh_addr
;
2004 ph
->p_paddr
= ph
->p_vaddr
;
2005 ph
->p_filesz
= interp
->sh_size
;
2006 ph
->p_memsz
= interp
->sh_size
;
2008 ph
->p_align
= interp
->sh_addralign
;
2011 /* if dynamic section, then add corresponding program header */
2013 ph
= &phdr
[phnum
- 1];
2015 ph
->p_type
= PT_DYNAMIC
;
2016 ph
->p_offset
= dynamic
->sh_offset
;
2017 ph
->p_vaddr
= dynamic
->sh_addr
;
2018 ph
->p_paddr
= ph
->p_vaddr
;
2019 ph
->p_filesz
= dynamic
->sh_size
;
2020 ph
->p_memsz
= dynamic
->sh_size
;
2021 ph
->p_flags
= PF_R
| PF_W
;
2022 ph
->p_align
= dynamic
->sh_addralign
;
2026 /* Fill the dynamic section with tags describing the address and size of
2028 static void fill_dynamic(TCCState
*s1
, struct dyn_inf
*dyninf
)
2030 Section
*dynamic
= dyninf
->dynamic
;
2033 /* put dynamic section entries */
2034 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
2035 put_dt(dynamic
, DT_STRTAB
, dyninf
->dynstr
->sh_addr
);
2036 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
2037 put_dt(dynamic
, DT_STRSZ
, dyninf
->dynstr
->data_offset
);
2038 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
2040 put_dt(dynamic
, DT_RELA
, dyninf
->rel_addr
);
2041 put_dt(dynamic
, DT_RELASZ
, dyninf
->rel_size
);
2042 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
2044 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2045 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2046 put_dt(dynamic
, DT_PLTRELSZ
, dyninf
->rel_size
);
2047 put_dt(dynamic
, DT_JMPREL
, dyninf
->rel_addr
);
2048 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
2049 put_dt(dynamic
, DT_REL
, dyninf
->bss_addr
);
2050 put_dt(dynamic
, DT_RELSZ
, dyninf
->bss_size
);
2052 put_dt(dynamic
, DT_REL
, dyninf
->rel_addr
);
2053 put_dt(dynamic
, DT_RELSZ
, dyninf
->rel_size
);
2054 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
2058 put_dt(dynamic
, DT_VERSYM
, versym_section
->sh_addr
);
2059 if (verneed_section
) {
2060 put_dt(dynamic
, DT_VERNEED
, verneed_section
->sh_addr
);
2061 put_dt(dynamic
, DT_VERNEEDNUM
, dt_verneednum
);
2063 s
= find_section_create (s1
, ".preinit_array", 0);
2064 if (s
&& s
->data_offset
) {
2065 put_dt(dynamic
, DT_PREINIT_ARRAY
, s
->sh_addr
);
2066 put_dt(dynamic
, DT_PREINIT_ARRAYSZ
, s
->data_offset
);
2068 s
= find_section_create (s1
, ".init_array", 0);
2069 if (s
&& s
->data_offset
) {
2070 put_dt(dynamic
, DT_INIT_ARRAY
, s
->sh_addr
);
2071 put_dt(dynamic
, DT_INIT_ARRAYSZ
, s
->data_offset
);
2073 s
= find_section_create (s1
, ".fini_array", 0);
2074 if (s
&& s
->data_offset
) {
2075 put_dt(dynamic
, DT_FINI_ARRAY
, s
->sh_addr
);
2076 put_dt(dynamic
, DT_FINI_ARRAYSZ
, s
->data_offset
);
2078 s
= find_section_create (s1
, ".init", 0);
2079 if (s
&& s
->data_offset
) {
2080 put_dt(dynamic
, DT_INIT
, s
->sh_addr
);
2082 s
= find_section_create (s1
, ".fini", 0);
2083 if (s
&& s
->data_offset
) {
2084 put_dt(dynamic
, DT_FINI
, s
->sh_addr
);
2087 put_dt(dynamic
, DT_DEBUG
, 0);
2088 put_dt(dynamic
, DT_NULL
, 0);
2091 /* Relocate remaining sections and symbols (that is those not related to
2093 static int final_sections_reloc(TCCState
*s1
)
2098 relocate_syms(s1
, s1
->symtab
, 0);
2100 if (s1
->nb_errors
!= 0)
2103 /* relocate sections */
2104 /* XXX: ignore sections with allocated relocations ? */
2105 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2106 s
= s1
->sections
[i
];
2107 if (s
->reloc
&& (s
!= s1
->got
|| s1
->static_link
))
2108 relocate_section(s1
, s
);
2111 /* relocate relocation entries if the relocation tables are
2112 allocated in the executable */
2113 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2114 s
= s1
->sections
[i
];
2115 if ((s
->sh_flags
& SHF_ALLOC
) &&
2116 s
->sh_type
== SHT_RELX
) {
2117 relocate_rel(s1
, s
);
2124 /* Create an ELF file on disk.
2125 This function handle ELF specific layout requirements */
2126 static void tcc_output_elf(TCCState
*s1
, FILE *f
, int phnum
, ElfW(Phdr
) *phdr
,
2127 int file_offset
, int *sec_order
)
2129 int i
, shnum
, offset
, size
, file_type
;
2132 ElfW(Shdr
) shdr
, *sh
;
2134 file_type
= s1
->output_type
;
2135 shnum
= s1
->nb_sections
;
2137 memset(&ehdr
, 0, sizeof(ehdr
));
2140 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2141 ehdr
.e_phnum
= phnum
;
2142 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2146 file_offset
= (file_offset
+ 3) & -4;
2149 ehdr
.e_ident
[0] = ELFMAG0
;
2150 ehdr
.e_ident
[1] = ELFMAG1
;
2151 ehdr
.e_ident
[2] = ELFMAG2
;
2152 ehdr
.e_ident
[3] = ELFMAG3
;
2153 ehdr
.e_ident
[4] = ELFCLASSW
;
2154 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2155 ehdr
.e_ident
[6] = EV_CURRENT
;
2156 #if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
2157 /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
2158 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2160 #ifdef TCC_TARGET_ARM
2162 ehdr
.e_ident
[EI_OSABI
] = 0;
2163 ehdr
.e_flags
= EF_ARM_EABI_VER4
;
2164 if (file_type
== TCC_OUTPUT_EXE
|| file_type
== TCC_OUTPUT_DLL
)
2165 ehdr
.e_flags
|= EF_ARM_HASENTRY
;
2166 if (s1
->float_abi
== ARM_HARD_FLOAT
)
2167 ehdr
.e_flags
|= EF_ARM_VFP_FLOAT
;
2169 ehdr
.e_flags
|= EF_ARM_SOFT_FLOAT
;
2171 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2173 #elif defined TCC_TARGET_RISCV64
2174 ehdr
.e_flags
= EF_RISCV_FLOAT_ABI_DOUBLE
;
2178 case TCC_OUTPUT_EXE
:
2179 ehdr
.e_type
= ET_EXEC
;
2180 ehdr
.e_entry
= get_elf_sym_addr(s1
, "_start", 1);
2182 case TCC_OUTPUT_DLL
:
2183 ehdr
.e_type
= ET_DYN
;
2184 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
2186 case TCC_OUTPUT_OBJ
:
2187 ehdr
.e_type
= ET_REL
;
2190 ehdr
.e_machine
= EM_TCC_TARGET
;
2191 ehdr
.e_version
= EV_CURRENT
;
2192 ehdr
.e_shoff
= file_offset
;
2193 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2194 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2195 ehdr
.e_shnum
= shnum
;
2196 ehdr
.e_shstrndx
= shnum
- 1;
2198 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2199 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2200 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2202 sort_syms(s1
, symtab_section
);
2203 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2204 s
= s1
->sections
[sec_order
[i
]];
2205 if (s
->sh_type
!= SHT_NOBITS
) {
2206 while (offset
< s
->sh_offset
) {
2212 fwrite(s
->data
, 1, size
, f
);
2217 /* output section headers */
2218 while (offset
< ehdr
.e_shoff
) {
2223 for(i
= 0; i
< s1
->nb_sections
; i
++) {
2225 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2226 s
= s1
->sections
[i
];
2228 sh
->sh_name
= s
->sh_name
;
2229 sh
->sh_type
= s
->sh_type
;
2230 sh
->sh_flags
= s
->sh_flags
;
2231 sh
->sh_entsize
= s
->sh_entsize
;
2232 sh
->sh_info
= s
->sh_info
;
2234 sh
->sh_link
= s
->link
->sh_num
;
2235 sh
->sh_addralign
= s
->sh_addralign
;
2236 sh
->sh_addr
= s
->sh_addr
;
2237 sh
->sh_offset
= s
->sh_offset
;
2238 sh
->sh_size
= s
->sh_size
;
2240 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2244 /* Write an elf, coff or "binary" file */
2245 static int tcc_write_elf_file(TCCState
*s1
, const char *filename
, int phnum
,
2246 ElfW(Phdr
) *phdr
, int file_offset
, int *sec_order
)
2248 int fd
, mode
, file_type
;
2251 file_type
= s1
->output_type
;
2252 if (file_type
== TCC_OUTPUT_OBJ
)
2257 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2259 tcc_error_noabort("could not write '%s'", filename
);
2262 f
= fdopen(fd
, "wb");
2264 printf("<- %s\n", filename
);
2266 #ifdef TCC_TARGET_COFF
2267 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
)
2268 tcc_output_coff(s1
, f
);
2271 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2272 tcc_output_elf(s1
, f
, phnum
, phdr
, file_offset
, sec_order
);
2274 tcc_output_binary(s1
, f
, sec_order
);
2280 #ifndef ELF_OBJ_ONLY
2281 /* Sort section headers by assigned sh_addr, remove sections
2282 that we aren't going to output. */
2283 static void tidy_section_headers(TCCState
*s1
, int *sec_order
)
2285 int i
, nnew
, l
, *backmap
;
2289 snew
= tcc_malloc(s1
->nb_sections
* sizeof(snew
[0]));
2290 backmap
= tcc_malloc(s1
->nb_sections
* sizeof(backmap
[0]));
2291 for (i
= 0, nnew
= 0, l
= s1
->nb_sections
; i
< s1
->nb_sections
; i
++) {
2292 s
= s1
->sections
[sec_order
[i
]];
2293 if (!i
|| s
->sh_name
) {
2294 backmap
[sec_order
[i
]] = nnew
;
2298 backmap
[sec_order
[i
]] = 0;
2302 for (i
= 0; i
< nnew
; i
++) {
2306 if (s
->sh_type
== SHT_RELX
)
2307 s
->sh_info
= backmap
[s
->sh_info
];
2311 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
))
2312 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2313 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2314 if( !s1
->static_link
) {
2315 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
))
2316 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2317 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2319 for (i
= 0; i
< s1
->nb_sections
; i
++)
2321 tcc_free(s1
->sections
);
2322 s1
->sections
= snew
;
2323 s1
->nb_sections
= nnew
;
2328 /* Output an elf, coff or binary file */
2329 /* XXX: suppress unneeded sections */
2330 static int elf_output_file(TCCState
*s1
, const char *filename
)
2332 int ret
, phnum
, shnum
, file_type
, file_offset
, *sec_order
;
2333 struct dyn_inf dyninf
= {0};
2335 Section
*strsec
, *interp
, *dynamic
, *dynstr
;
2337 file_type
= s1
->output_type
;
2342 interp
= dynamic
= dynstr
= NULL
; /* avoid warning */
2344 #ifndef ELF_OBJ_ONLY
2345 if (file_type
!= TCC_OUTPUT_OBJ
) {
2346 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2347 tcc_add_runtime(s1
);
2348 resolve_common_syms(s1
);
2350 if (!s1
->static_link
) {
2351 if (file_type
== TCC_OUTPUT_EXE
) {
2353 /* allow override the dynamic loader */
2354 const char *elfint
= getenv("LD_SO");
2356 elfint
= DEFAULT_ELFINTERP(s1
);
2357 /* add interpreter section only if executable */
2358 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
2359 interp
->sh_addralign
= 1;
2360 ptr
= section_ptr_add(interp
, 1 + strlen(elfint
));
2361 strcpy(ptr
, elfint
);
2364 /* add dynamic symbol table */
2365 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
2367 ".hash", SHF_ALLOC
);
2368 dynstr
= s1
->dynsym
->link
;
2369 /* add dynamic section */
2370 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
2371 SHF_ALLOC
| SHF_WRITE
);
2372 dynamic
->link
= dynstr
;
2373 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
2377 if (file_type
== TCC_OUTPUT_EXE
) {
2378 bind_exe_dynsyms(s1
);
2381 bind_libs_dynsyms(s1
);
2383 /* shared library case: simply export all global symbols */
2384 export_global_syms(s1
);
2387 build_got_entries(s1
);
2392 /* we add a section for symbols */
2393 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
2394 put_elf_str(strsec
, "");
2396 /* Allocate strings for section names */
2397 ret
= alloc_sec_names(s1
, file_type
, strsec
);
2399 #ifndef ELF_OBJ_ONLY
2402 /* add a list of needed dlls */
2403 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2404 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
2405 if (dllref
->level
== 0)
2406 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
2410 put_dt(dynamic
, s1
->enable_new_dtags
? DT_RUNPATH
: DT_RPATH
,
2411 put_elf_str(dynstr
, s1
->rpath
));
2413 if (file_type
== TCC_OUTPUT_DLL
) {
2415 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
2416 /* XXX: currently, since we do not handle PIC code, we
2417 must relocate the readonly segments */
2419 put_dt(dynamic
, DT_TEXTREL
, 0);
2423 put_dt(dynamic
, DT_SYMBOLIC
, 0);
2425 dyninf
.dynamic
= dynamic
;
2426 dyninf
.dynstr
= dynstr
;
2427 /* remember offset and reserve space for 2nd call below */
2428 dyninf
.data_offset
= dynamic
->data_offset
;
2429 fill_dynamic(s1
, &dyninf
);
2430 dynamic
->sh_size
= dynamic
->data_offset
;
2431 dynstr
->sh_size
= dynstr
->data_offset
;
2435 /* compute number of program headers */
2436 if (file_type
== TCC_OUTPUT_OBJ
)
2438 else if (file_type
== TCC_OUTPUT_DLL
)
2440 else if (s1
->static_link
)
2445 /* allocate program segment headers */
2446 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
2448 /* compute number of sections */
2449 shnum
= s1
->nb_sections
;
2451 /* this array is used to reorder sections in the output file */
2452 sec_order
= tcc_malloc(sizeof(int) * shnum
);
2455 /* compute section to program header mapping */
2456 file_offset
= layout_sections(s1
, phdr
, phnum
, interp
, strsec
, &dyninf
,
2459 #ifndef ELF_OBJ_ONLY
2460 /* Fill remaining program header and finalize relocation related to dynamic
2462 if (file_type
!= TCC_OUTPUT_OBJ
) {
2463 fill_unloadable_phdr(phdr
, phnum
, interp
, dynamic
);
2466 dynamic
->data_offset
= dyninf
.data_offset
;
2467 fill_dynamic(s1
, &dyninf
);
2469 /* put in GOT the dynamic section address and relocate PLT */
2470 write32le(s1
->got
->data
, dynamic
->sh_addr
);
2471 if (file_type
== TCC_OUTPUT_EXE
2472 || (RELOCATE_DLLPLT
&& file_type
== TCC_OUTPUT_DLL
))
2475 /* relocate symbols in .dynsym now that final addresses are known */
2476 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
)) {
2477 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
) {
2478 /* do symbol relocation */
2479 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
2484 /* if building executable or DLL, then relocate each section
2485 except the GOT which is already relocated */
2486 ret
= final_sections_reloc(s1
);
2489 tidy_section_headers(s1
, sec_order
);
2491 /* Perform relocation to GOT or PLT entries */
2492 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2495 fill_local_got_entries(s1
);
2499 /* Create the ELF file with name 'filename' */
2500 ret
= tcc_write_elf_file(s1
, filename
, phnum
, phdr
, file_offset
, sec_order
);
2501 s1
->nb_sections
= shnum
;
2504 tcc_free(sec_order
);
2509 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2512 #ifdef TCC_TARGET_PE
2513 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2514 ret
= pe_output_file(s
, filename
);
2516 #elif TCC_TARGET_MACHO
2517 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2518 ret
= macho_output_file(s
, filename
);
2521 ret
= elf_output_file(s
, filename
);
2525 ssize_t
full_read(int fd
, void *buf
, size_t count
) {
2529 ssize_t num
= read(fd
, cbuf
, count
-rnum
);
2530 if (num
< 0) return num
;
2531 if (num
== 0) return rnum
;
2537 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2541 data
= tcc_malloc(size
);
2542 lseek(fd
, file_offset
, SEEK_SET
);
2543 full_read(fd
, data
, size
);
2547 typedef struct SectionMergeInfo
{
2548 Section
*s
; /* corresponding existing section */
2549 unsigned long offset
; /* offset of the new section in the existing section */
2550 uint8_t new_section
; /* true if section 's' was added */
2551 uint8_t link_once
; /* true if link once section */
2554 ST_FUNC
int tcc_object_type(int fd
, ElfW(Ehdr
) *h
)
2556 int size
= full_read(fd
, h
, sizeof *h
);
2557 if (size
== sizeof *h
&& 0 == memcmp(h
, ELFMAG
, 4)) {
2558 if (h
->e_type
== ET_REL
)
2559 return AFF_BINTYPE_REL
;
2560 if (h
->e_type
== ET_DYN
)
2561 return AFF_BINTYPE_DYN
;
2562 } else if (size
>= 8) {
2563 if (0 == memcmp(h
, ARMAG
, 8))
2564 return AFF_BINTYPE_AR
;
2565 #ifdef TCC_TARGET_COFF
2566 if (((struct filehdr
*)h
)->f_magic
== COFF_C67_MAGIC
)
2567 return AFF_BINTYPE_C67
;
2573 /* load an object file and merge it with current files */
2574 /* XXX: handle correctly stab (debug) info */
2575 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
2576 int fd
, unsigned long file_offset
)
2579 ElfW(Shdr
) *shdr
, *sh
;
2580 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
, seencompressed
;
2581 char *strsec
, *strtab
;
2582 int stab_index
, stabstr_index
;
2583 int *old_to_new_syms
;
2584 char *sh_name
, *name
;
2585 SectionMergeInfo
*sm_table
, *sm
;
2586 ElfW(Sym
) *sym
, *symtab
;
2590 lseek(fd
, file_offset
, SEEK_SET
);
2591 if (tcc_object_type(fd
, &ehdr
) != AFF_BINTYPE_REL
)
2593 /* test CPU specific stuff */
2594 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2595 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2597 tcc_error_noabort("invalid object file");
2601 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2602 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2603 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2605 /* load section names */
2606 sh
= &shdr
[ehdr
.e_shstrndx
];
2607 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2609 /* load symtab and strtab */
2610 old_to_new_syms
= NULL
;
2615 stab_index
= stabstr_index
= 0;
2617 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2619 if (sh
->sh_type
== SHT_SYMTAB
) {
2621 tcc_error_noabort("object must contain only one symtab");
2626 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2627 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2628 sm_table
[i
].s
= symtab_section
;
2630 /* now load strtab */
2631 sh
= &shdr
[sh
->sh_link
];
2632 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2634 if (sh
->sh_flags
& SHF_COMPRESSED
)
2638 /* now examine each section and try to merge its content with the
2640 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2641 /* no need to examine section name strtab */
2642 if (i
== ehdr
.e_shstrndx
)
2645 if (sh
->sh_type
== SHT_RELX
)
2646 sh
= &shdr
[sh
->sh_info
];
2647 /* ignore sections types we do not handle (plus relocs to those) */
2648 if (sh
->sh_type
!= SHT_PROGBITS
&&
2650 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2652 sh
->sh_type
!= SHT_NOBITS
&&
2653 sh
->sh_type
!= SHT_PREINIT_ARRAY
&&
2654 sh
->sh_type
!= SHT_INIT_ARRAY
&&
2655 sh
->sh_type
!= SHT_FINI_ARRAY
&&
2656 strcmp(strsec
+ sh
->sh_name
, ".stabstr")
2660 && !strncmp(strsec
+ sh
->sh_name
, ".debug_", sizeof(".debug_")-1))
2664 sh_name
= strsec
+ sh
->sh_name
;
2665 if (sh
->sh_addralign
< 1)
2666 sh
->sh_addralign
= 1;
2667 /* find corresponding section, if any */
2668 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2669 s
= s1
->sections
[j
];
2670 if (!strcmp(s
->name
, sh_name
)) {
2671 if (!strncmp(sh_name
, ".gnu.linkonce",
2672 sizeof(".gnu.linkonce") - 1)) {
2673 /* if a 'linkonce' section is already present, we
2674 do not add it again. It is a little tricky as
2675 symbols can still be defined in
2677 sm_table
[i
].link_once
= 1;
2681 if (s
== stab_section
)
2683 if (s
== stab_section
->link
)
2689 /* not found: create new section */
2690 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
& ~SHF_GROUP
);
2691 /* take as much info as possible from the section. sh_link and
2692 sh_info will be updated later */
2693 s
->sh_addralign
= sh
->sh_addralign
;
2694 s
->sh_entsize
= sh
->sh_entsize
;
2695 sm_table
[i
].new_section
= 1;
2697 if (sh
->sh_type
!= s
->sh_type
) {
2698 tcc_error_noabort("invalid section type");
2701 /* align start of section */
2702 s
->data_offset
+= -s
->data_offset
& (sh
->sh_addralign
- 1);
2703 if (sh
->sh_addralign
> s
->sh_addralign
)
2704 s
->sh_addralign
= sh
->sh_addralign
;
2705 sm_table
[i
].offset
= s
->data_offset
;
2707 /* concatenate sections */
2709 if (sh
->sh_type
!= SHT_NOBITS
) {
2711 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2712 ptr
= section_ptr_add(s
, size
);
2713 full_read(fd
, ptr
, size
);
2715 s
->data_offset
+= size
;
2720 /* gr relocate stab strings */
2721 if (stab_index
&& stabstr_index
) {
2724 s
= sm_table
[stab_index
].s
;
2725 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2726 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2727 o
= sm_table
[stabstr_index
].offset
;
2735 /* second short pass to update sh_link and sh_info fields of new
2737 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2739 if (!s
|| !sm_table
[i
].new_section
)
2742 if (sh
->sh_link
> 0)
2743 s
->link
= sm_table
[sh
->sh_link
].s
;
2744 if (sh
->sh_type
== SHT_RELX
) {
2745 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2746 /* update backward link */
2747 s1
->sections
[s
->sh_info
]->reloc
= s
;
2751 /* resolve symbols */
2752 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2755 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2756 if (sym
->st_shndx
!= SHN_UNDEF
&&
2757 sym
->st_shndx
< SHN_LORESERVE
) {
2758 sm
= &sm_table
[sym
->st_shndx
];
2759 if (sm
->link_once
) {
2760 /* if a symbol is in a link once section, we use the
2761 already defined symbol. It is very important to get
2762 correct relocations */
2763 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2764 name
= strtab
+ sym
->st_name
;
2765 sym_index
= find_elf_sym(symtab_section
, name
);
2767 old_to_new_syms
[i
] = sym_index
;
2771 /* if no corresponding section added, no need to add symbol */
2774 /* convert section number */
2775 sym
->st_shndx
= sm
->s
->sh_num
;
2777 sym
->st_value
+= sm
->offset
;
2780 name
= strtab
+ sym
->st_name
;
2781 sym_index
= set_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2782 sym
->st_info
, sym
->st_other
,
2783 sym
->st_shndx
, name
);
2784 old_to_new_syms
[i
] = sym_index
;
2787 /* third pass to patch relocation entries */
2788 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2793 offset
= sm_table
[i
].offset
;
2794 switch(s
->sh_type
) {
2796 /* take relocation offset information */
2797 offseti
= sm_table
[sh
->sh_info
].offset
;
2798 for_each_elem(s
, (offset
/ sizeof(*rel
)), rel
, ElfW_Rel
) {
2801 /* convert symbol index */
2802 type
= ELFW(R_TYPE
)(rel
->r_info
);
2803 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2804 /* NOTE: only one symtab assumed */
2805 if (sym_index
>= nb_syms
)
2807 sym_index
= old_to_new_syms
[sym_index
];
2808 /* ignore link_once in rel section. */
2809 if (!sym_index
&& !sm_table
[sh
->sh_info
].link_once
2810 #ifdef TCC_TARGET_ARM
2811 && type
!= R_ARM_V4BX
2812 #elif defined TCC_TARGET_RISCV64
2813 && type
!= R_RISCV_ALIGN
2814 && type
!= R_RISCV_RELAX
2818 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2819 i
, strsec
+ sh
->sh_name
, (int)rel
->r_offset
);
2822 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2823 /* offset the relocation offset */
2824 rel
->r_offset
+= offseti
;
2825 #ifdef TCC_TARGET_ARM
2826 /* Jumps and branches from a Thumb code to a PLT entry need
2827 special handling since PLT entries are ARM code.
2828 Unconditional bl instructions referencing PLT entries are
2829 handled by converting these instructions into blx
2830 instructions. Other case of instructions referencing a PLT
2831 entry require to add a Thumb stub before the PLT entry to
2832 switch to ARM mode. We set bit plt_thumb_stub of the
2833 attribute of a symbol to indicate such a case. */
2834 if (type
== R_ARM_THM_JUMP24
)
2835 get_sym_attr(s1
, sym_index
, 1)->plt_thumb_stub
= 1;
2848 tcc_free(old_to_new_syms
);
2855 typedef struct ArchiveHeader
{
2856 char ar_name
[16]; /* name of this member */
2857 char ar_date
[12]; /* file mtime */
2858 char ar_uid
[6]; /* owner uid; printed as decimal */
2859 char ar_gid
[6]; /* owner gid; printed as decimal */
2860 char ar_mode
[8]; /* file mode, printed as octal */
2861 char ar_size
[10]; /* file size, printed as decimal */
2862 char ar_fmag
[2]; /* should contain ARFMAG */
2865 #define ARFMAG "`\n"
2867 static unsigned long long get_be(const uint8_t *b
, int n
)
2869 unsigned long long ret
= 0;
2871 ret
= (ret
<< 8) | *b
++, --n
;
2875 static int read_ar_header(int fd
, int offset
, ArchiveHeader
*hdr
)
2879 lseek(fd
, offset
, SEEK_SET
);
2880 len
= full_read(fd
, hdr
, sizeof(ArchiveHeader
));
2881 if (len
!= sizeof(ArchiveHeader
))
2882 return len
? -1 : 0;
2884 for (e
= p
+ sizeof hdr
->ar_name
; e
> p
&& e
[-1] == ' ';)
2887 hdr
->ar_size
[sizeof hdr
->ar_size
-1] = 0;
2891 /* load only the objects which resolve undefined symbols */
2892 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
, int entrysize
)
2894 int i
, bound
, nsyms
, sym_index
, len
, ret
= -1;
2895 unsigned long long off
;
2897 const char *ar_names
, *p
;
2898 const uint8_t *ar_index
;
2902 data
= tcc_malloc(size
);
2903 if (full_read(fd
, data
, size
) != size
)
2905 nsyms
= get_be(data
, entrysize
);
2906 ar_index
= data
+ entrysize
;
2907 ar_names
= (char *) ar_index
+ nsyms
* entrysize
;
2911 for (p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2912 Section
*s
= symtab_section
;
2913 sym_index
= find_elf_sym(s
, p
);
2916 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
2917 if(sym
->st_shndx
!= SHN_UNDEF
)
2919 off
= get_be(ar_index
+ i
* entrysize
, entrysize
);
2920 len
= read_ar_header(fd
, off
, &hdr
);
2921 if (len
<= 0 || memcmp(hdr
.ar_fmag
, ARFMAG
, 2)) {
2922 tcc_error_noabort("invalid archive");
2926 if (s1
->verbose
== 2)
2927 printf(" -> %s\n", hdr
.ar_name
);
2928 if (tcc_load_object_file(s1
, fd
, off
) < 0)
2939 /* load a '.a' file */
2940 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
, int alacarte
)
2943 /* char magic[8]; */
2945 unsigned long file_offset
;
2948 /* skip magic which was already checked */
2949 /* full_read(fd, magic, sizeof(magic)); */
2950 file_offset
= sizeof ARMAG
- 1;
2953 len
= read_ar_header(fd
, file_offset
, &hdr
);
2957 tcc_error_noabort("invalid archive");
2961 size
= strtol(hdr
.ar_size
, NULL
, 0);
2963 size
= (size
+ 1) & ~1;
2965 /* coff symbol table : we handle it */
2966 if (!strcmp(hdr
.ar_name
, "/"))
2967 return tcc_load_alacarte(s1
, fd
, size
, 4);
2968 if (!strcmp(hdr
.ar_name
, "/SYM64/"))
2969 return tcc_load_alacarte(s1
, fd
, size
, 8);
2970 } else if (tcc_object_type(fd
, &ehdr
) == AFF_BINTYPE_REL
) {
2971 if (s1
->verbose
== 2)
2972 printf(" -> %s\n", hdr
.ar_name
);
2973 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2976 file_offset
+= size
;
2980 #ifndef ELF_OBJ_ONLY
2981 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
2982 LV, maybe create a new entry for (LIB,VERSION). */
2983 static void set_ver_to_ver(TCCState
*s1
, int *n
, int **lv
, int i
, char *lib
, char *version
)
2986 *lv
= tcc_realloc(*lv
, (*n
+ 1) * sizeof(**lv
));
2989 if ((*lv
)[i
] == -1) {
2990 int v
, prev_same_lib
= -1;
2991 for (v
= 0; v
< nb_sym_versions
; v
++) {
2992 if (strcmp(sym_versions
[v
].lib
, lib
))
2995 if (!strcmp(sym_versions
[v
].version
, version
))
2998 if (v
== nb_sym_versions
) {
2999 sym_versions
= tcc_realloc (sym_versions
,
3000 (v
+ 1) * sizeof(*sym_versions
));
3001 sym_versions
[v
].lib
= tcc_strdup(lib
);
3002 sym_versions
[v
].version
= tcc_strdup(version
);
3003 sym_versions
[v
].out_index
= 0;
3004 sym_versions
[v
].prev_same_lib
= prev_same_lib
;
3011 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3014 set_sym_version(TCCState
*s1
, int sym_index
, int verndx
)
3016 if (sym_index
>= nb_sym_to_version
) {
3017 int newelems
= sym_index
? sym_index
* 2 : 1;
3018 sym_to_version
= tcc_realloc(sym_to_version
,
3019 newelems
* sizeof(*sym_to_version
));
3020 memset(sym_to_version
+ nb_sym_to_version
, -1,
3021 (newelems
- nb_sym_to_version
) * sizeof(*sym_to_version
));
3022 nb_sym_to_version
= newelems
;
3024 if (sym_to_version
[sym_index
] < 0)
3025 sym_to_version
[sym_index
] = verndx
;
3028 struct versym_info
{
3030 ElfW(Verdef
) *verdef
;
3031 ElfW(Verneed
) *verneed
;
3033 int nb_local_ver
, *local_ver
;
3037 static void store_version(TCCState
*s1
, struct versym_info
*v
, char *dynstr
)
3039 char *lib
, *version
;
3043 #define DEBUG_VERSION 0
3045 if (v
->versym
&& v
->verdef
) {
3046 ElfW(Verdef
) *vdef
= v
->verdef
;
3049 ElfW(Verdaux
) *verdaux
=
3050 (ElfW(Verdaux
) *) (((char *) vdef
) + vdef
->vd_aux
);
3053 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3054 vdef
->vd_version
, vdef
->vd_flags
, vdef
->vd_ndx
,
3058 version
= dynstr
+ verdaux
->vda_name
;
3063 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vdef
->vd_ndx
,
3066 printf (" verdaux(%u): %s\n", vdef
->vd_ndx
, version
);
3069 next
= vdef
->vd_next
;
3070 vdef
= (ElfW(Verdef
) *) (((char *) vdef
) + next
);
3073 if (v
->versym
&& v
->verneed
) {
3074 ElfW(Verneed
) *vneed
= v
->verneed
;
3076 ElfW(Vernaux
) *vernaux
=
3077 (ElfW(Vernaux
) *) (((char *) vneed
) + vneed
->vn_aux
);
3079 lib
= dynstr
+ vneed
->vn_file
;
3081 printf ("verneed: %u %s\n", vneed
->vn_version
, lib
);
3083 for (i
= 0; i
< vneed
->vn_cnt
; i
++) {
3084 if ((vernaux
->vna_other
& 0x8000) == 0) { /* hidden */
3085 version
= dynstr
+ vernaux
->vna_name
;
3086 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vernaux
->vna_other
,
3089 printf (" vernaux(%u): %u %u %s\n",
3090 vernaux
->vna_other
, vernaux
->vna_hash
,
3091 vernaux
->vna_flags
, version
);
3094 vernaux
= (ElfW(Vernaux
) *) (((char *) vernaux
) + vernaux
->vna_next
);
3096 next
= vneed
->vn_next
;
3097 vneed
= (ElfW(Verneed
) *) (((char *) vneed
) + next
);
3102 for (i
= 0; i
< v
->nb_local_ver
; i
++) {
3103 if (v
->local_ver
[i
] > 0) {
3104 printf ("%d: lib: %s, version %s\n",
3105 i
, sym_versions
[v
->local_ver
[i
]].lib
,
3106 sym_versions
[v
->local_ver
[i
]].version
);
3112 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3113 is referenced by the user (so it should be added as DT_NEEDED in
3114 the generated ELF file) */
3115 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
3118 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
3119 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
3120 ElfW(Sym
) *sym
, *dynsym
;
3121 ElfW(Dyn
) *dt
, *dynamic
;
3125 const char *name
, *soname
;
3126 DLLReference
*dllref
;
3127 struct versym_info v
;
3129 full_read(fd
, &ehdr
, sizeof(ehdr
));
3131 /* test CPU specific stuff */
3132 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
3133 ehdr
.e_machine
!= EM_TCC_TARGET
) {
3134 tcc_error_noabort("bad architecture");
3139 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
3141 /* load dynamic section and dynamic symbols */
3145 dynsym
= NULL
; /* avoid warning */
3146 dynstr
= NULL
; /* avoid warning */
3147 memset(&v
, 0, sizeof v
);
3149 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
3150 switch(sh
->sh_type
) {
3152 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
3153 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3156 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
3157 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3158 sh1
= &shdr
[sh
->sh_link
];
3159 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
3161 case SHT_GNU_verdef
:
3162 v
.verdef
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3164 case SHT_GNU_verneed
:
3165 v
.verneed
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3167 case SHT_GNU_versym
:
3168 v
.nb_versyms
= sh
->sh_size
/ sizeof(ElfW(Half
));
3169 v
.versym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3176 /* compute the real library name */
3177 soname
= tcc_basename(filename
);
3179 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3180 if (dt
->d_tag
== DT_SONAME
) {
3181 soname
= dynstr
+ dt
->d_un
.d_val
;
3185 /* if the dll is already loaded, do not load it */
3186 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
3187 dllref
= s1
->loaded_dlls
[i
];
3188 if (!strcmp(soname
, dllref
->name
)) {
3189 /* but update level if needed */
3190 if (level
< dllref
->level
)
3191 dllref
->level
= level
;
3197 if (v
.nb_versyms
!= nb_syms
)
3198 tcc_free (v
.versym
), v
.versym
= NULL
;
3200 store_version(s1
, &v
, dynstr
);
3202 /* add the dll and its level */
3203 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
3204 dllref
->level
= level
;
3205 strcpy(dllref
->name
, soname
);
3206 dynarray_add(&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
3208 /* add dynamic symbols in dynsym_section */
3209 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
3210 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
3211 if (sym_bind
== STB_LOCAL
)
3213 name
= dynstr
+ sym
->st_name
;
3214 sym_index
= set_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
3215 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
3217 ElfW(Half
) vsym
= v
.versym
[i
];
3218 if ((vsym
& 0x8000) == 0 && vsym
> 0 && vsym
< v
.nb_local_ver
)
3219 set_sym_version(s1
, sym_index
, v
.local_ver
[vsym
]);
3223 /* load all referenced DLLs */
3224 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3227 name
= dynstr
+ dt
->d_un
.d_val
;
3228 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
3229 dllref
= s1
->loaded_dlls
[j
];
3230 if (!strcmp(name
, dllref
->name
))
3231 goto already_loaded
;
3233 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
3234 tcc_error_noabort("referenced dll '%s' not found", name
);
3248 tcc_free(v
.local_ver
);
3250 tcc_free(v
.verneed
);
3255 #define LD_TOK_NAME 256
3256 #define LD_TOK_EOF (-1)
3258 static int ld_inp(TCCState
*s1
)
3266 if (1 == read(s1
->fd
, &b
, 1))
3271 /* return next ld script token */
3272 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
3289 if (ch
== '*') { /* comment */
3290 for (d
= 0;; d
= ch
) {
3292 if (ch
== CH_EOF
|| (ch
== '/' && d
== '*'))
3303 /* case 'a' ... 'z': */
3330 /* case 'A' ... 'z': */
3364 if (!((ch
>= 'a' && ch
<= 'z') ||
3365 (ch
>= 'A' && ch
<= 'Z') ||
3366 (ch
>= '0' && ch
<= '9') ||
3367 strchr("/.-_+=$:\\,~", ch
)))
3369 if ((q
- name
) < name_size
- 1) {
3388 static int ld_add_file(TCCState
*s1
, const char filename
[])
3390 if (filename
[0] == '/') {
3391 if (CONFIG_SYSROOT
[0] == '\0'
3392 && tcc_add_file_internal(s1
, filename
, AFF_TYPE_BIN
) == 0)
3394 filename
= tcc_basename(filename
);
3396 return tcc_add_dll(s1
, filename
, 0);
3399 static int ld_add_file_list(TCCState
*s1
, const char *cmd
, int as_needed
)
3401 char filename
[1024], libname
[1024];
3402 int t
, group
, nblibs
= 0, ret
= 0;
3405 group
= !strcmp(cmd
, "GROUP");
3407 s1
->new_undef_sym
= 0;
3408 t
= ld_next(s1
, filename
, sizeof(filename
));
3410 tcc_error_noabort("( expected");
3412 goto lib_parse_error
;
3414 t
= ld_next(s1
, filename
, sizeof(filename
));
3417 if (t
== LD_TOK_EOF
) {
3418 tcc_error_noabort("unexpected end of file");
3420 goto lib_parse_error
;
3421 } else if (t
== ')') {
3423 } else if (t
== '-') {
3424 t
= ld_next(s1
, filename
, sizeof(filename
));
3425 if ((t
!= LD_TOK_NAME
) || (filename
[0] != 'l')) {
3426 tcc_error_noabort("library name expected");
3428 goto lib_parse_error
;
3430 pstrcpy(libname
, sizeof libname
, &filename
[1]);
3431 if (s1
->static_link
) {
3432 snprintf(filename
, sizeof filename
, "lib%s.a", libname
);
3434 snprintf(filename
, sizeof filename
, "lib%s.so", libname
);
3436 } else if (t
!= LD_TOK_NAME
) {
3437 tcc_error_noabort("filename expected");
3439 goto lib_parse_error
;
3441 if (!strcmp(filename
, "AS_NEEDED")) {
3442 ret
= ld_add_file_list(s1
, cmd
, 1);
3444 goto lib_parse_error
;
3446 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3448 ret
= ld_add_file(s1
, filename
);
3450 goto lib_parse_error
;
3452 /* Add the filename *and* the libname to avoid future conversions */
3453 dynarray_add(&libs
, &nblibs
, tcc_strdup(filename
));
3454 if (libname
[0] != '\0')
3455 dynarray_add(&libs
, &nblibs
, tcc_strdup(libname
));
3459 t
= ld_next(s1
, filename
, sizeof(filename
));
3461 t
= ld_next(s1
, filename
, sizeof(filename
));
3464 if (group
&& !as_needed
) {
3465 while (s1
->new_undef_sym
) {
3467 s1
->new_undef_sym
= 0;
3468 for (i
= 0; i
< nblibs
; i
++)
3469 ld_add_file(s1
, libs
[i
]);
3473 dynarray_reset(&libs
, &nblibs
);
3477 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3479 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
, int fd
)
3482 char filename
[1024];
3488 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3489 if (t
== LD_TOK_EOF
)
3491 else if (t
!= LD_TOK_NAME
)
3493 if (!strcmp(cmd
, "INPUT") ||
3494 !strcmp(cmd
, "GROUP")) {
3495 ret
= ld_add_file_list(s1
, cmd
, 0);
3498 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
3499 !strcmp(cmd
, "TARGET")) {
3500 /* ignore some commands */
3501 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3503 tcc_error_noabort("( expected");
3507 t
= ld_next(s1
, filename
, sizeof(filename
));
3508 if (t
== LD_TOK_EOF
) {
3509 tcc_error_noabort("unexpected end of file");
3511 } else if (t
== ')') {
3521 #endif /* !ELF_OBJ_ONLY */