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 /* Browse each elem of type <type> in section <sec> starting at elem <startoff>
859 using variable <elem> */
860 #define for_each_elem(sec, startoff, elem, type) \
861 for (elem = (type *) sec->data + startoff; \
862 elem < (type *) (sec->data + sec->data_offset); elem++)
864 /* In an ELF file symbol table, the local symbols must appear below
865 the global and weak ones. Since TCC cannot sort it while generating
866 the code, we must do it after. All the relocation tables are also
867 modified to take into account the symbol table sorting */
868 static void sort_syms(TCCState
*s1
, Section
*s
)
870 int *old_to_new_syms
;
878 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
879 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
880 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
882 /* first pass for local symbols */
883 p
= (ElfW(Sym
) *)s
->data
;
885 for(i
= 0; i
< nb_syms
; i
++) {
886 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
887 old_to_new_syms
[i
] = q
- new_syms
;
892 /* save the number of local symbols in section header */
893 if( s
->sh_size
) /* this 'if' makes IDA happy */
894 s
->sh_info
= q
- new_syms
;
896 /* then second pass for non local symbols */
897 p
= (ElfW(Sym
) *)s
->data
;
898 for(i
= 0; i
< nb_syms
; i
++) {
899 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
900 old_to_new_syms
[i
] = q
- new_syms
;
906 /* we copy the new symbols to the old */
907 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
910 /* now we modify all the relocations */
911 for(i
= 1; i
< s1
->nb_sections
; i
++) {
912 sr
= s1
->sections
[i
];
913 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
914 for_each_elem(sr
, 0, rel
, ElfW_Rel
) {
915 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
916 type
= ELFW(R_TYPE
)(rel
->r_info
);
917 sym_index
= old_to_new_syms
[sym_index
];
918 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
923 tcc_free(old_to_new_syms
);
926 /* relocate symbol table, resolve undefined symbols if do_resolve is
927 true and output error if undefined symbol. */
928 ST_FUNC
void relocate_syms(TCCState
*s1
, Section
*symtab
, int do_resolve
)
931 int sym_bind
, sh_num
;
934 for_each_elem(symtab
, 1, sym
, ElfW(Sym
)) {
935 sh_num
= sym
->st_shndx
;
936 if (sh_num
== SHN_UNDEF
) {
937 name
= (char *) s1
->symtab
->link
->data
+ sym
->st_name
;
938 /* Use ld.so to resolve symbol for us (for tcc -run) */
940 #if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
941 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
);
1069 static void build_got(TCCState
*s1
)
1071 /* if no got, then create it */
1072 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
1073 s1
->got
->sh_entsize
= 4;
1074 set_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
1075 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
1076 /* keep space for _DYNAMIC pointer and two dummy got entries */
1077 section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
1080 /* Create a GOT and (for function call) a PLT entry corresponding to a symbol
1081 in s1->symtab. When creating the dynamic symbol table entry for the GOT
1082 relocation, use 'size' and 'info' for the corresponding symbol metadata.
1083 Returns the offset of the GOT or (if any) PLT entry. */
1084 static struct sym_attr
* put_got_entry(TCCState
*s1
, int dyn_reloc_type
,
1090 struct sym_attr
*attr
;
1091 unsigned got_offset
;
1095 need_plt_entry
= (dyn_reloc_type
== R_JMP_SLOT
);
1096 attr
= get_sym_attr(s1
, sym_index
, 1);
1098 /* In case a function is both called and its address taken 2 GOT entries
1099 are created, one for taking the address (GOT) and the other for the PLT
1101 if (need_plt_entry
? attr
->plt_offset
: attr
->got_offset
)
1104 /* create the GOT entry */
1105 got_offset
= s1
->got
->data_offset
;
1106 section_ptr_add(s1
->got
, PTR_SIZE
);
1108 /* Create the GOT relocation that will insert the address of the object or
1109 function of interest in the GOT entry. This is a static relocation for
1110 memory output (dlsym will give us the address of symbols) and dynamic
1111 relocation otherwise (executable and DLLs). The relocation should be
1112 done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
1113 associated to a PLT entry) but is currently done at load time for an
1116 sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1117 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1120 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
) {
1121 /* Hack alarm. We don't want to emit dynamic symbols
1122 and symbol based relocs for STB_LOCAL symbols, but rather
1123 want to resolve them directly. At this point the symbol
1124 values aren't final yet, so we must defer this. We will later
1125 have to create a RELATIVE reloc anyway, so we misuse the
1126 relocation slot to smuggle the symbol reference until
1127 fill_local_got_entries. Not that the sym_index is
1128 relative to symtab_section, not s1->dynsym! Nevertheless
1129 we use s1->dyn_sym so that if this is the first call
1130 that got->reloc is correctly created. Also note that
1131 RELATIVE relocs are not normally created for the .got,
1132 so the types serves as a marker for later (and is retained
1133 also for the final output, which is okay because then the
1134 got is just normal data). */
1135 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, R_RELATIVE
,
1138 if (0 == attr
->dyn_index
)
1139 attr
->dyn_index
= set_elf_sym(s1
->dynsym
, sym
->st_value
,
1140 sym
->st_size
, sym
->st_info
, 0,
1141 sym
->st_shndx
, name
);
1142 put_elf_reloc(s1
->dynsym
, s1
->got
, got_offset
, dyn_reloc_type
,
1146 put_elf_reloc(symtab_section
, s1
->got
, got_offset
, dyn_reloc_type
,
1150 if (need_plt_entry
) {
1152 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1153 SHF_ALLOC
| SHF_EXECINSTR
);
1154 s1
->plt
->sh_entsize
= 4;
1157 attr
->plt_offset
= create_plt_entry(s1
, got_offset
, attr
);
1159 /* create a symbol 'sym@plt' for the PLT jump vector */
1161 if (len
> sizeof plt_name
- 5)
1162 len
= sizeof plt_name
- 5;
1163 memcpy(plt_name
, name
, len
);
1164 strcpy(plt_name
+ len
, "@plt");
1165 attr
->plt_sym
= put_elf_sym(s1
->symtab
, attr
->plt_offset
, sym
->st_size
,
1166 ELFW(ST_INFO
)(STB_GLOBAL
, STT_FUNC
), 0, s1
->plt
->sh_num
, plt_name
);
1169 attr
->got_offset
= got_offset
;
1175 /* build GOT and PLT entries */
1176 ST_FUNC
void build_got_entries(TCCState
*s1
)
1181 int i
, type
, gotplt_entry
, reloc_type
, sym_index
;
1182 struct sym_attr
*attr
;
1184 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1185 s
= s1
->sections
[i
];
1186 if (s
->sh_type
!= SHT_RELX
)
1188 /* no need to handle got relocations */
1189 if (s
->link
!= symtab_section
)
1191 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1192 type
= ELFW(R_TYPE
)(rel
->r_info
);
1193 gotplt_entry
= gotplt_entry_type(type
);
1194 if (gotplt_entry
== -1)
1195 tcc_error ("Unknown relocation type for got: %d", type
);
1196 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1197 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1199 if (gotplt_entry
== NO_GOTPLT_ENTRY
) {
1203 /* Automatically create PLT/GOT [entry] if it is an undefined
1204 reference (resolved at runtime), or the symbol is absolute,
1205 probably created by tcc_add_symbol, and thus on 64-bit
1206 targets might be too far from application code. */
1207 if (gotplt_entry
== AUTO_GOTPLT_ENTRY
) {
1208 if (sym
->st_shndx
== SHN_UNDEF
) {
1211 if (s1
->output_type
== TCC_OUTPUT_DLL
&& ! PCRELATIVE_DLLPLT
)
1213 /* Relocations for UNDEF symbols would normally need
1214 to be transferred into the executable or shared object.
1215 If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
1216 But TCC doesn't do that (at least for exes), so we
1217 need to resolve all such relocs locally. And that
1218 means PLT slots for functions in DLLs and COPY relocs for
1219 data symbols. COPY relocs were generated in
1220 bind_exe_dynsyms (and the symbol adjusted to be defined),
1221 and for functions we were generated a dynamic symbol
1222 of function type. */
1224 /* dynsym isn't set for -run :-/ */
1225 dynindex
= get_sym_attr(s1
, sym_index
, 0)->dyn_index
;
1226 esym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ dynindex
;
1228 && (ELFW(ST_TYPE
)(esym
->st_info
) == STT_FUNC
1229 || (ELFW(ST_TYPE
)(esym
->st_info
) == STT_NOTYPE
1230 && ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
)))
1233 } else if (!(sym
->st_shndx
== SHN_ABS
1234 #ifndef TCC_TARGET_ARM
1241 #ifdef TCC_TARGET_X86_64
1242 if ((type
== R_X86_64_PLT32
|| type
== R_X86_64_PC32
) &&
1243 sym
->st_shndx
!= SHN_UNDEF
&&
1244 (ELFW(ST_VISIBILITY
)(sym
->st_other
) != STV_DEFAULT
||
1245 ELFW(ST_BIND
)(sym
->st_info
) == STB_LOCAL
||
1246 s1
->output_type
== TCC_OUTPUT_EXE
)) {
1247 rel
->r_info
= ELFW(R_INFO
)(sym_index
, R_X86_64_PC32
);
1251 reloc_type
= code_reloc(type
);
1252 if (reloc_type
== -1)
1253 tcc_error ("Unknown relocation type: %d", type
);
1254 else if (reloc_type
!= 0) {
1256 reloc_type
= R_JMP_SLOT
;
1258 reloc_type
= R_GLOB_DAT
;
1263 if (gotplt_entry
== BUILD_GOT_ONLY
)
1266 attr
= put_got_entry(s1
, reloc_type
, sym_index
);
1268 if (reloc_type
== R_JMP_SLOT
)
1269 rel
->r_info
= ELFW(R_INFO
)(attr
->plt_sym
, type
);
1274 /* put dynamic tag */
1275 static void put_dt(Section
*dynamic
, int dt
, addr_t val
)
1278 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1280 dyn
->d_un
.d_val
= val
;
1284 ST_FUNC
int set_global_sym(TCCState
*s1
, const char *name
, Section
*sec
, long offs
)
1286 int shn
= sec
? sec
->sh_num
: offs
? SHN_ABS
: SHN_UNDEF
;
1287 if (sec
&& offs
== -1)
1288 offs
= sec
->data_offset
;
1289 return set_elf_sym(symtab_section
, offs
, 0,
1290 ELFW(ST_INFO
)(name
? STB_GLOBAL
: STB_LOCAL
, STT_NOTYPE
), 0, shn
, name
);
1293 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1298 s
= find_section(s1
, section_name
);
1303 end_offset
= s
->data_offset
;
1305 snprintf(buf
, sizeof(buf
), "__%s_start", section_name
+ 1);
1306 set_global_sym(s1
, buf
, s
, 0);
1307 snprintf(buf
, sizeof(buf
), "__%s_end", section_name
+ 1);
1308 set_global_sym(s1
, buf
, s
, end_offset
);
1311 #ifndef TCC_TARGET_PE
1312 static int tcc_add_support(TCCState
*s1
, const char *filename
)
1315 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, filename
);
1316 return tcc_add_file(s1
, buf
);
1320 ST_FUNC
void add_array (TCCState
*s1
, const char *sec
, int c
)
1323 s
= find_section(s1
, sec
);
1324 s
->sh_flags
|= SHF_WRITE
;
1325 #ifndef TCC_TARGET_PE
1326 s
->sh_type
= sec
[1] == 'i' ? SHT_INIT_ARRAY
: SHT_FINI_ARRAY
;
1328 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1329 section_ptr_add(s
, PTR_SIZE
);
1332 #ifdef CONFIG_TCC_BCHECK
1333 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
1335 if (0 == s1
->do_bounds_check
)
1337 section_ptr_add(bounds_section
, sizeof(addr_t
));
1341 #ifdef CONFIG_TCC_BACKTRACE
1342 static void put_ptr(TCCState
*s1
, Section
*s
, int offs
)
1345 c
= set_global_sym(s1
, NULL
, s
, offs
);
1347 put_elf_reloc (s1
->symtab
, s
, s
->data_offset
, R_DATA_PTR
, c
);
1348 section_ptr_add(s
, PTR_SIZE
);
1351 /* set symbol to STB_LOCAL and resolve. The point is to not export it as
1352 a dynamic symbol to allow so's to have one each with a different value. */
1353 static void set_local_sym(TCCState
*s1
, const char *name
, Section
*s
, int offset
)
1355 int c
= find_elf_sym(s1
->symtab
, name
);
1357 ElfW(Sym
) *esym
= (ElfW(Sym
)*)s1
->symtab
->data
+ c
;
1358 esym
->st_info
= ELFW(ST_INFO
)(STB_LOCAL
, STT_NOTYPE
);
1359 esym
->st_value
= offset
;
1360 esym
->st_shndx
= s
->sh_num
;
1364 ST_FUNC
void tcc_add_btstub(TCCState
*s1
)
1372 /* create (part of) a struct rt_context (see tccrun.c) */
1373 put_ptr(s1
, stab_section
, 0);
1374 put_ptr(s1
, stab_section
, -1);
1375 put_ptr(s1
, stab_section
->link
, 0);
1376 section_ptr_add(s
, 3 * PTR_SIZE
);
1378 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);}",
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", 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 tcc_add_library_err(s1
, "c");
1422 if (!s1
->static_link
) {
1423 if (TCC_LIBGCC
[0] == '/')
1424 tcc_add_file(s1
, TCC_LIBGCC
);
1426 tcc_add_dll(s1
, TCC_LIBGCC
, 0);
1429 #ifdef CONFIG_TCC_BCHECK
1430 if (s1
->do_bounds_check
&& s1
->output_type
!= TCC_OUTPUT_DLL
) {
1431 tcc_add_library_err(s1
, "pthread");
1432 tcc_add_library_err(s1
, "dl");
1433 tcc_add_support(s1
, "bcheck.o");
1436 #ifdef CONFIG_TCC_BACKTRACE
1437 if (s1
->do_backtrace
) {
1438 if (s1
->output_type
== TCC_OUTPUT_EXE
)
1439 tcc_add_support(s1
, "bt-exe.o");
1440 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1441 tcc_add_support(s1
, "bt-log.o");
1442 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1446 tcc_add_support(s1
, TCC_LIBTCC1
);
1447 /* add crt end if not memory output */
1448 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1449 tcc_add_crt(s1
, "crtn.o");
1454 /* add various standard linker symbols (must be done after the
1455 sections are filled (for example after allocating common
1457 static void tcc_add_linker_symbols(TCCState
*s1
)
1463 set_global_sym(s1
, "_etext", text_section
, -1);
1464 set_global_sym(s1
, "_edata", data_section
, -1);
1465 set_global_sym(s1
, "_end", bss_section
, -1);
1466 #ifdef TCC_TARGET_RISCV64
1467 /* XXX should be .sdata+0x800, not .data+0x800 */
1468 set_global_sym(s1
, "__global_pointer$", data_section
, 0x800);
1470 /* horrible new standard ldscript defines */
1471 add_init_array_defines(s1
, ".preinit_array");
1472 add_init_array_defines(s1
, ".init_array");
1473 add_init_array_defines(s1
, ".fini_array");
1474 /* add start and stop symbols for sections whose name can be
1476 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1477 s
= s1
->sections
[i
];
1478 if ((s
->sh_flags
& SHF_ALLOC
)
1479 && (s
->sh_type
== SHT_PROGBITS
1480 || s
->sh_type
== SHT_STRTAB
)) {
1482 /* check if section name can be expressed in C */
1488 if (!isid(c
) && !isnum(c
))
1492 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1493 set_global_sym(s1
, buf
, s
, 0);
1494 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1495 set_global_sym(s1
, buf
, s
, -1);
1501 ST_FUNC
void resolve_common_syms(TCCState
*s1
)
1505 /* Allocate common symbols in BSS. */
1506 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1507 if (sym
->st_shndx
== SHN_COMMON
) {
1508 /* symbol alignment is in st_value for SHN_COMMONs */
1509 sym
->st_value
= section_add(bss_section
, sym
->st_size
,
1511 sym
->st_shndx
= bss_section
->sh_num
;
1515 /* Now assign linker provided symbols their value. */
1516 tcc_add_linker_symbols(s1
);
1519 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1520 const int *sec_order
)
1523 int i
, offset
, size
;
1526 for(i
=1;i
<s1
->nb_sections
;i
++) {
1527 s
= s1
->sections
[sec_order
[i
]];
1528 if (s
->sh_type
!= SHT_NOBITS
&&
1529 (s
->sh_flags
& SHF_ALLOC
)) {
1530 while (offset
< s
->sh_offset
) {
1535 fwrite(s
->data
, 1, size
, f
);
1541 #ifndef ELF_OBJ_ONLY
1542 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1544 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1545 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1546 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1547 unsigned offset
= attr
->got_offset
;
1551 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1552 #ifdef TCC_TARGET_X86_64
1553 write64le(s1
->got
->data
+ offset
, sym
->st_value
);
1555 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1559 /* Perform relocation to GOT or PLT entries */
1560 ST_FUNC
void fill_got(TCCState
*s1
)
1566 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1567 s
= s1
->sections
[i
];
1568 if (s
->sh_type
!= SHT_RELX
)
1570 /* no need to handle got relocations */
1571 if (s
->link
!= symtab_section
)
1573 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1574 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1575 case R_X86_64_GOT32
:
1576 case R_X86_64_GOTPCREL
:
1577 case R_X86_64_GOTPCRELX
:
1578 case R_X86_64_REX_GOTPCRELX
:
1579 case R_X86_64_PLT32
:
1580 fill_got_entry(s1
, rel
);
1587 /* See put_got_entry for a description. This is the second stage
1588 where GOT references to local defined symbols are rewritten. */
1589 static void fill_local_got_entries(TCCState
*s1
)
1592 if (!s1
->got
->reloc
)
1594 for_each_elem(s1
->got
->reloc
, 0, rel
, ElfW_Rel
) {
1595 if (ELFW(R_TYPE
)(rel
->r_info
) == R_RELATIVE
) {
1596 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1597 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1598 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1599 unsigned offset
= attr
->got_offset
;
1600 if (offset
!= rel
->r_offset
- s1
->got
->sh_addr
)
1601 tcc_error_noabort("huh");
1602 rel
->r_info
= ELFW(R_INFO
)(0, R_RELATIVE
);
1603 #if SHT_RELX == SHT_RELA
1604 rel
->r_addend
= sym
->st_value
;
1606 /* All our REL architectures also happen to be 32bit LE. */
1607 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1613 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1614 in shared libraries and export non local defined symbols to shared libraries
1615 if -rdynamic switch was given on command line */
1616 static void bind_exe_dynsyms(TCCState
*s1
)
1619 int sym_index
, index
;
1620 ElfW(Sym
) *sym
, *esym
;
1623 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1624 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1625 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1626 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1627 if (sym
->st_shndx
== SHN_UNDEF
) {
1628 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1629 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1631 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1632 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1633 if ((type
== STT_FUNC
) || (type
== STT_GNU_IFUNC
)) {
1634 /* Indirect functions shall have STT_FUNC type in executable
1635 * dynsym section. Indeed, a dlsym call following a lazy
1636 * resolution would pick the symbol value from the
1637 * executable dynsym entry which would contain the address
1638 * of the function wanted by the caller of dlsym instead of
1639 * the address of the function that would return that
1642 = put_elf_sym(s1
->dynsym
, 0, esym
->st_size
,
1643 ELFW(ST_INFO
)(STB_GLOBAL
,STT_FUNC
), 0, 0,
1645 int index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1646 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1647 } else if (type
== STT_OBJECT
) {
1648 unsigned long offset
;
1650 offset
= bss_section
->data_offset
;
1651 /* XXX: which alignment ? */
1652 offset
= (offset
+ 16 - 1) & -16;
1653 set_elf_sym (s1
->symtab
, offset
, esym
->st_size
,
1654 esym
->st_info
, 0, bss_section
->sh_num
, name
);
1655 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1656 esym
->st_info
, 0, bss_section
->sh_num
,
1659 /* Ensure R_COPY works for weak symbol aliases */
1660 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1661 for_each_elem(s1
->dynsymtab_section
, 1, dynsym
, ElfW(Sym
)) {
1662 if ((dynsym
->st_value
== esym
->st_value
)
1663 && (ELFW(ST_BIND
)(dynsym
->st_info
) == STB_GLOBAL
)) {
1664 char *dynname
= (char *) s1
->dynsymtab_section
->link
->data
1666 put_elf_sym(s1
->dynsym
, offset
, dynsym
->st_size
,
1668 bss_section
->sh_num
, dynname
);
1674 put_elf_reloc(s1
->dynsym
, bss_section
,
1675 offset
, R_COPY
, index
);
1676 offset
+= esym
->st_size
;
1677 bss_section
->data_offset
= offset
;
1680 /* STB_WEAK undefined symbols are accepted */
1681 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1682 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1683 !strcmp(name
, "_fp_hw")) {
1685 tcc_error_noabort("undefined symbol '%s'", name
);
1688 } else if (s1
->rdynamic
&& ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1689 /* if -rdynamic option, then export all non local symbols */
1690 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1691 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
1692 0, sym
->st_shndx
, name
);
1697 /* Bind symbols of libraries: export all non local symbols of executable that
1698 are referenced by shared libraries. The reason is that the dynamic loader
1699 search symbol first in executable and then in libraries. Therefore a
1700 reference to a symbol already defined by a library can still be resolved by
1701 a symbol in the executable. */
1702 static void bind_libs_dynsyms(TCCState
*s1
)
1706 ElfW(Sym
) *sym
, *esym
;
1708 for_each_elem(s1
->dynsymtab_section
, 1, esym
, ElfW(Sym
)) {
1709 name
= (char *) s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1710 sym_index
= find_elf_sym(symtab_section
, name
);
1711 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1712 if (sym_index
&& sym
->st_shndx
!= SHN_UNDEF
1713 && ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1714 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1715 sym
->st_info
, 0, sym
->st_shndx
, name
);
1716 } else if (esym
->st_shndx
== SHN_UNDEF
) {
1717 /* weak symbols can stay undefined */
1718 if (ELFW(ST_BIND
)(esym
->st_info
) != STB_WEAK
)
1719 tcc_warning("undefined dynamic symbol '%s'", name
);
1724 /* Export all non local symbols. This is used by shared libraries so that the
1725 non local symbols they define can resolve a reference in another shared
1726 library or in the executable. Correspondingly, it allows undefined local
1727 symbols to be resolved by other shared libraries or by the executable. */
1728 static void export_global_syms(TCCState
*s1
)
1730 int dynindex
, index
;
1734 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1735 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1736 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1737 dynindex
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1738 sym
->st_info
, 0, sym
->st_shndx
, name
);
1739 index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1740 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1746 /* Allocate strings for section names and decide if an unallocated section
1748 NOTE: the strsec section comes last, so its size is also correct ! */
1749 static int alloc_sec_names(TCCState
*s1
, int file_type
, Section
*strsec
)
1755 /* Allocate strings for section names */
1756 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1757 s
= s1
->sections
[i
];
1758 /* when generating a DLL, we include relocations but we may
1760 #ifndef ELF_OBJ_ONLY
1761 if (file_type
== TCC_OUTPUT_DLL
&&
1762 s
->sh_type
== SHT_RELX
&&
1763 !(s
->sh_flags
& SHF_ALLOC
) &&
1764 (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
) &&
1765 prepare_dynamic_rel(s1
, s
)) {
1766 if (!(s1
->sections
[s
->sh_info
]->sh_flags
& SHF_WRITE
))
1770 if ((s1
->do_debug
&& s
->sh_type
!= SHT_RELX
) ||
1771 file_type
== TCC_OUTPUT_OBJ
||
1772 (s
->sh_flags
& SHF_ALLOC
) ||
1773 i
== (s1
->nb_sections
- 1)) {
1774 /* we output all sections if debug or object file */
1775 s
->sh_size
= s
->data_offset
;
1777 if (s
->sh_size
|| (s
->sh_flags
& SHF_ALLOC
))
1778 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1780 strsec
->sh_size
= strsec
->data_offset
;
1784 /* Info to be copied in dynamic section */
1788 unsigned long data_offset
;
1791 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1797 /* Assign sections to segments and decide how are sections laid out when loaded
1798 in memory. This function also fills corresponding program headers. */
1799 static int layout_sections(TCCState
*s1
, ElfW(Phdr
) *phdr
, int phnum
,
1800 Section
*interp
, Section
* strsec
,
1801 struct dyn_inf
*dyninf
, int *sec_order
)
1803 int i
, j
, k
, file_type
, sh_order_index
, file_offset
;
1804 unsigned long s_align
;
1810 file_type
= s1
->output_type
;
1813 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
1814 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1815 s_align
= ELF_PAGE_SIZE
;
1816 if (s1
->section_align
)
1817 s_align
= s1
->section_align
;
1820 if (s1
->has_text_addr
) {
1821 int a_offset
, p_offset
;
1822 addr
= s1
->text_addr
;
1823 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1825 a_offset
= (int) (addr
& (s_align
- 1));
1826 p_offset
= file_offset
& (s_align
- 1);
1827 if (a_offset
< p_offset
)
1828 a_offset
+= s_align
;
1829 file_offset
+= (a_offset
- p_offset
);
1831 if (file_type
== TCC_OUTPUT_DLL
)
1834 addr
= ELF_START_ADDR
;
1835 /* compute address after headers */
1836 addr
+= (file_offset
& (s_align
- 1));
1840 /* Leave one program headers for the program interpreter and one for
1841 the program header table itself if needed. These are done later as
1842 they require section layout to be done first. */
1846 /* dynamic relocation table information, for .dynamic section */
1847 dyninf
->rel_addr
= dyninf
->rel_size
= 0;
1848 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1849 dyninf
->bss_addr
= dyninf
->bss_size
= 0;
1852 for(j
= 0; j
< 2; j
++) {
1853 ph
->p_type
= PT_LOAD
;
1855 ph
->p_flags
= PF_R
| PF_X
;
1857 ph
->p_flags
= PF_R
| PF_W
;
1858 ph
->p_align
= s_align
;
1860 /* Decide the layout of sections loaded in memory. This must
1861 be done before program headers are filled since they contain
1862 info about the layout. We do the following ordering: interp,
1863 symbol tables, relocations, progbits, nobits */
1864 /* XXX: do faster and simpler sorting */
1865 for(k
= 0; k
< 5; k
++) {
1866 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1867 s
= s1
->sections
[i
];
1868 /* compute if section should be included */
1870 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1874 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1875 (SHF_ALLOC
| SHF_WRITE
))
1881 } else if ((s
->sh_type
== SHT_DYNSYM
||
1882 s
->sh_type
== SHT_STRTAB
||
1883 s
->sh_type
== SHT_HASH
)
1884 && !strstr(s
->name
, ".stab")) {
1887 } else if (s
->sh_type
== SHT_RELX
) {
1890 } else if (s
->sh_type
== SHT_NOBITS
) {
1897 sec_order
[sh_order_index
++] = i
;
1899 /* section matches: we align it and add its size */
1901 addr
= (addr
+ s
->sh_addralign
- 1) &
1902 ~(s
->sh_addralign
- 1);
1903 file_offset
+= (int) ( addr
- tmp
);
1904 s
->sh_offset
= file_offset
;
1907 /* update program header infos */
1908 if (ph
->p_offset
== 0) {
1909 ph
->p_offset
= file_offset
;
1911 ph
->p_paddr
= ph
->p_vaddr
;
1913 /* update dynamic relocation infos */
1914 if (s
->sh_type
== SHT_RELX
) {
1915 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1916 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.got")) {
1917 dyninf
->rel_addr
= addr
;
1918 dyninf
->rel_size
+= s
->sh_size
; /* XXX only first rel. */
1920 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.bss")) {
1921 dyninf
->bss_addr
= addr
;
1922 dyninf
->bss_size
= s
->sh_size
; /* XXX only first rel. */
1925 if (dyninf
->rel_size
== 0)
1926 dyninf
->rel_addr
= addr
;
1927 dyninf
->rel_size
+= s
->sh_size
;
1931 if (s
->sh_type
!= SHT_NOBITS
)
1932 file_offset
+= s
->sh_size
;
1936 /* Make the first PT_LOAD segment include the program
1937 headers itself (and the ELF header as well), it'll
1938 come out with same memory use but will make various
1939 tools like binutils strip work better. */
1940 ph
->p_offset
&= ~(ph
->p_align
- 1);
1941 ph
->p_vaddr
&= ~(ph
->p_align
- 1);
1942 ph
->p_paddr
&= ~(ph
->p_align
- 1);
1944 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1945 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1948 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1949 /* if in the middle of a page, we duplicate the page in
1950 memory so that one copy is RX and the other is RW */
1951 if ((addr
& (s_align
- 1)) != 0)
1954 addr
= (addr
+ s_align
- 1) & ~(s_align
- 1);
1955 file_offset
= (file_offset
+ s_align
- 1) & ~(s_align
- 1);
1961 /* all other sections come after */
1962 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1963 s
= s1
->sections
[i
];
1964 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1966 sec_order
[sh_order_index
++] = i
;
1968 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1969 ~(s
->sh_addralign
- 1);
1970 s
->sh_offset
= file_offset
;
1971 if (s
->sh_type
!= SHT_NOBITS
)
1972 file_offset
+= s
->sh_size
;
1978 #ifndef ELF_OBJ_ONLY
1979 static void fill_unloadable_phdr(ElfW(Phdr
) *phdr
, int phnum
, Section
*interp
,
1984 /* if interpreter, then add corresponding program header */
1988 ph
->p_type
= PT_PHDR
;
1989 ph
->p_offset
= sizeof(ElfW(Ehdr
));
1990 ph
->p_filesz
= ph
->p_memsz
= phnum
* sizeof(ElfW(Phdr
));
1991 ph
->p_vaddr
= interp
->sh_addr
- ph
->p_filesz
;
1992 ph
->p_paddr
= ph
->p_vaddr
;
1993 ph
->p_flags
= PF_R
| PF_X
;
1994 ph
->p_align
= 4; /* interp->sh_addralign; */
1997 ph
->p_type
= PT_INTERP
;
1998 ph
->p_offset
= interp
->sh_offset
;
1999 ph
->p_vaddr
= interp
->sh_addr
;
2000 ph
->p_paddr
= ph
->p_vaddr
;
2001 ph
->p_filesz
= interp
->sh_size
;
2002 ph
->p_memsz
= interp
->sh_size
;
2004 ph
->p_align
= interp
->sh_addralign
;
2007 /* if dynamic section, then add corresponding program header */
2009 ph
= &phdr
[phnum
- 1];
2011 ph
->p_type
= PT_DYNAMIC
;
2012 ph
->p_offset
= dynamic
->sh_offset
;
2013 ph
->p_vaddr
= dynamic
->sh_addr
;
2014 ph
->p_paddr
= ph
->p_vaddr
;
2015 ph
->p_filesz
= dynamic
->sh_size
;
2016 ph
->p_memsz
= dynamic
->sh_size
;
2017 ph
->p_flags
= PF_R
| PF_W
;
2018 ph
->p_align
= dynamic
->sh_addralign
;
2022 /* Fill the dynamic section with tags describing the address and size of
2024 static void fill_dynamic(TCCState
*s1
, struct dyn_inf
*dyninf
)
2026 Section
*dynamic
= dyninf
->dynamic
;
2029 /* put dynamic section entries */
2030 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
2031 put_dt(dynamic
, DT_STRTAB
, dyninf
->dynstr
->sh_addr
);
2032 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
2033 put_dt(dynamic
, DT_STRSZ
, dyninf
->dynstr
->data_offset
);
2034 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
2036 put_dt(dynamic
, DT_RELA
, dyninf
->rel_addr
);
2037 put_dt(dynamic
, DT_RELASZ
, dyninf
->rel_size
);
2038 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
2040 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2041 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2042 put_dt(dynamic
, DT_PLTRELSZ
, dyninf
->rel_size
);
2043 put_dt(dynamic
, DT_JMPREL
, dyninf
->rel_addr
);
2044 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
2045 put_dt(dynamic
, DT_REL
, dyninf
->bss_addr
);
2046 put_dt(dynamic
, DT_RELSZ
, dyninf
->bss_size
);
2048 put_dt(dynamic
, DT_REL
, dyninf
->rel_addr
);
2049 put_dt(dynamic
, DT_RELSZ
, dyninf
->rel_size
);
2050 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
2054 put_dt(dynamic
, DT_VERSYM
, versym_section
->sh_addr
);
2055 if (verneed_section
) {
2056 put_dt(dynamic
, DT_VERNEED
, verneed_section
->sh_addr
);
2057 put_dt(dynamic
, DT_VERNEEDNUM
, dt_verneednum
);
2059 s
= find_section_create (s1
, ".preinit_array", 0);
2060 if (s
&& s
->data_offset
) {
2061 put_dt(dynamic
, DT_PREINIT_ARRAY
, s
->sh_addr
);
2062 put_dt(dynamic
, DT_PREINIT_ARRAYSZ
, s
->data_offset
);
2064 s
= find_section_create (s1
, ".init_array", 0);
2065 if (s
&& s
->data_offset
) {
2066 put_dt(dynamic
, DT_INIT_ARRAY
, s
->sh_addr
);
2067 put_dt(dynamic
, DT_INIT_ARRAYSZ
, s
->data_offset
);
2069 s
= find_section_create (s1
, ".fini_array", 0);
2070 if (s
&& s
->data_offset
) {
2071 put_dt(dynamic
, DT_FINI_ARRAY
, s
->sh_addr
);
2072 put_dt(dynamic
, DT_FINI_ARRAYSZ
, s
->data_offset
);
2074 s
= find_section_create (s1
, ".init", 0);
2075 if (s
&& s
->data_offset
) {
2076 put_dt(dynamic
, DT_INIT
, s
->sh_addr
);
2078 s
= find_section_create (s1
, ".fini", 0);
2079 if (s
&& s
->data_offset
) {
2080 put_dt(dynamic
, DT_FINI
, s
->sh_addr
);
2083 put_dt(dynamic
, DT_DEBUG
, 0);
2084 put_dt(dynamic
, DT_NULL
, 0);
2087 /* Relocate remaining sections and symbols (that is those not related to
2089 static int final_sections_reloc(TCCState
*s1
)
2094 relocate_syms(s1
, s1
->symtab
, 0);
2096 if (s1
->nb_errors
!= 0)
2099 /* relocate sections */
2100 /* XXX: ignore sections with allocated relocations ? */
2101 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2102 s
= s1
->sections
[i
];
2103 if (s
->reloc
&& (s
!= s1
->got
|| s1
->static_link
))
2104 relocate_section(s1
, s
);
2107 /* relocate relocation entries if the relocation tables are
2108 allocated in the executable */
2109 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2110 s
= s1
->sections
[i
];
2111 if ((s
->sh_flags
& SHF_ALLOC
) &&
2112 s
->sh_type
== SHT_RELX
) {
2113 relocate_rel(s1
, s
);
2120 /* Create an ELF file on disk.
2121 This function handle ELF specific layout requirements */
2122 static void tcc_output_elf(TCCState
*s1
, FILE *f
, int phnum
, ElfW(Phdr
) *phdr
,
2123 int file_offset
, int *sec_order
)
2125 int i
, shnum
, offset
, size
, file_type
;
2128 ElfW(Shdr
) shdr
, *sh
;
2130 file_type
= s1
->output_type
;
2131 shnum
= s1
->nb_sections
;
2133 memset(&ehdr
, 0, sizeof(ehdr
));
2136 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2137 ehdr
.e_phnum
= phnum
;
2138 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2142 file_offset
= (file_offset
+ 3) & -4;
2145 ehdr
.e_ident
[0] = ELFMAG0
;
2146 ehdr
.e_ident
[1] = ELFMAG1
;
2147 ehdr
.e_ident
[2] = ELFMAG2
;
2148 ehdr
.e_ident
[3] = ELFMAG3
;
2149 ehdr
.e_ident
[4] = ELFCLASSW
;
2150 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2151 ehdr
.e_ident
[6] = EV_CURRENT
;
2152 #if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
2153 /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
2154 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2156 #ifdef TCC_TARGET_ARM
2158 ehdr
.e_ident
[EI_OSABI
] = 0;
2159 ehdr
.e_flags
= EF_ARM_EABI_VER4
;
2160 if (file_type
== TCC_OUTPUT_EXE
|| file_type
== TCC_OUTPUT_DLL
)
2161 ehdr
.e_flags
|= EF_ARM_HASENTRY
;
2162 if (s1
->float_abi
== ARM_HARD_FLOAT
)
2163 ehdr
.e_flags
|= EF_ARM_VFP_FLOAT
;
2165 ehdr
.e_flags
|= EF_ARM_SOFT_FLOAT
;
2167 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2169 #elif defined TCC_TARGET_RISCV64
2170 ehdr
.e_flags
= EF_RISCV_FLOAT_ABI_DOUBLE
;
2174 case TCC_OUTPUT_EXE
:
2175 ehdr
.e_type
= ET_EXEC
;
2176 ehdr
.e_entry
= get_elf_sym_addr(s1
, "_start", 1);
2178 case TCC_OUTPUT_DLL
:
2179 ehdr
.e_type
= ET_DYN
;
2180 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
2182 case TCC_OUTPUT_OBJ
:
2183 ehdr
.e_type
= ET_REL
;
2186 ehdr
.e_machine
= EM_TCC_TARGET
;
2187 ehdr
.e_version
= EV_CURRENT
;
2188 ehdr
.e_shoff
= file_offset
;
2189 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2190 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2191 ehdr
.e_shnum
= shnum
;
2192 ehdr
.e_shstrndx
= shnum
- 1;
2194 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2195 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2196 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2198 sort_syms(s1
, symtab_section
);
2199 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2200 s
= s1
->sections
[sec_order
[i
]];
2201 if (s
->sh_type
!= SHT_NOBITS
) {
2202 while (offset
< s
->sh_offset
) {
2208 fwrite(s
->data
, 1, size
, f
);
2213 /* output section headers */
2214 while (offset
< ehdr
.e_shoff
) {
2219 for(i
= 0; i
< s1
->nb_sections
; i
++) {
2221 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2222 s
= s1
->sections
[i
];
2224 sh
->sh_name
= s
->sh_name
;
2225 sh
->sh_type
= s
->sh_type
;
2226 sh
->sh_flags
= s
->sh_flags
;
2227 sh
->sh_entsize
= s
->sh_entsize
;
2228 sh
->sh_info
= s
->sh_info
;
2230 sh
->sh_link
= s
->link
->sh_num
;
2231 sh
->sh_addralign
= s
->sh_addralign
;
2232 sh
->sh_addr
= s
->sh_addr
;
2233 sh
->sh_offset
= s
->sh_offset
;
2234 sh
->sh_size
= s
->sh_size
;
2236 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2240 /* Write an elf, coff or "binary" file */
2241 static int tcc_write_elf_file(TCCState
*s1
, const char *filename
, int phnum
,
2242 ElfW(Phdr
) *phdr
, int file_offset
, int *sec_order
)
2244 int fd
, mode
, file_type
;
2247 file_type
= s1
->output_type
;
2248 if (file_type
== TCC_OUTPUT_OBJ
)
2253 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2255 tcc_error_noabort("could not write '%s'", filename
);
2258 f
= fdopen(fd
, "wb");
2260 printf("<- %s\n", filename
);
2262 #ifdef TCC_TARGET_COFF
2263 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
)
2264 tcc_output_coff(s1
, f
);
2267 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2268 tcc_output_elf(s1
, f
, phnum
, phdr
, file_offset
, sec_order
);
2270 tcc_output_binary(s1
, f
, sec_order
);
2276 #ifndef ELF_OBJ_ONLY
2277 /* Sort section headers by assigned sh_addr, remove sections
2278 that we aren't going to output. */
2279 static void tidy_section_headers(TCCState
*s1
, int *sec_order
)
2281 int i
, nnew
, l
, *backmap
;
2285 snew
= tcc_malloc(s1
->nb_sections
* sizeof(snew
[0]));
2286 backmap
= tcc_malloc(s1
->nb_sections
* sizeof(backmap
[0]));
2287 for (i
= 0, nnew
= 0, l
= s1
->nb_sections
; i
< s1
->nb_sections
; i
++) {
2288 s
= s1
->sections
[sec_order
[i
]];
2289 if (!i
|| s
->sh_name
) {
2290 backmap
[sec_order
[i
]] = nnew
;
2294 backmap
[sec_order
[i
]] = 0;
2298 for (i
= 0; i
< nnew
; i
++) {
2302 if (s
->sh_type
== SHT_RELX
)
2303 s
->sh_info
= backmap
[s
->sh_info
];
2307 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
))
2308 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2309 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2310 if( !s1
->static_link
) {
2311 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
))
2312 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2313 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2315 for (i
= 0; i
< s1
->nb_sections
; i
++)
2317 tcc_free(s1
->sections
);
2318 s1
->sections
= snew
;
2319 s1
->nb_sections
= nnew
;
2324 /* Output an elf, coff or binary file */
2325 /* XXX: suppress unneeded sections */
2326 static int elf_output_file(TCCState
*s1
, const char *filename
)
2328 int ret
, phnum
, shnum
, file_type
, file_offset
, *sec_order
;
2329 struct dyn_inf dyninf
= {0};
2331 Section
*strsec
, *interp
, *dynamic
, *dynstr
;
2333 file_type
= s1
->output_type
;
2338 interp
= dynamic
= dynstr
= NULL
; /* avoid warning */
2340 #ifndef ELF_OBJ_ONLY
2341 if (file_type
!= TCC_OUTPUT_OBJ
) {
2342 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2343 tcc_add_runtime(s1
);
2344 resolve_common_syms(s1
);
2346 if (!s1
->static_link
) {
2347 if (file_type
== TCC_OUTPUT_EXE
) {
2349 /* allow override the dynamic loader */
2350 const char *elfint
= getenv("LD_SO");
2352 elfint
= DEFAULT_ELFINTERP(s1
);
2353 /* add interpreter section only if executable */
2354 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
2355 interp
->sh_addralign
= 1;
2356 ptr
= section_ptr_add(interp
, 1 + strlen(elfint
));
2357 strcpy(ptr
, elfint
);
2360 /* add dynamic symbol table */
2361 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
2363 ".hash", SHF_ALLOC
);
2364 dynstr
= s1
->dynsym
->link
;
2365 /* add dynamic section */
2366 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
2367 SHF_ALLOC
| SHF_WRITE
);
2368 dynamic
->link
= dynstr
;
2369 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
2373 if (file_type
== TCC_OUTPUT_EXE
) {
2374 bind_exe_dynsyms(s1
);
2377 bind_libs_dynsyms(s1
);
2379 /* shared library case: simply export all global symbols */
2380 export_global_syms(s1
);
2383 build_got_entries(s1
);
2388 /* we add a section for symbols */
2389 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
2390 put_elf_str(strsec
, "");
2392 /* Allocate strings for section names */
2393 ret
= alloc_sec_names(s1
, file_type
, strsec
);
2395 #ifndef ELF_OBJ_ONLY
2398 /* add a list of needed dlls */
2399 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2400 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
2401 if (dllref
->level
== 0)
2402 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
2406 put_dt(dynamic
, s1
->enable_new_dtags
? DT_RUNPATH
: DT_RPATH
,
2407 put_elf_str(dynstr
, s1
->rpath
));
2409 if (file_type
== TCC_OUTPUT_DLL
) {
2411 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
2412 /* XXX: currently, since we do not handle PIC code, we
2413 must relocate the readonly segments */
2415 put_dt(dynamic
, DT_TEXTREL
, 0);
2419 put_dt(dynamic
, DT_SYMBOLIC
, 0);
2421 dyninf
.dynamic
= dynamic
;
2422 dyninf
.dynstr
= dynstr
;
2423 /* remember offset and reserve space for 2nd call below */
2424 dyninf
.data_offset
= dynamic
->data_offset
;
2425 fill_dynamic(s1
, &dyninf
);
2426 dynamic
->sh_size
= dynamic
->data_offset
;
2427 dynstr
->sh_size
= dynstr
->data_offset
;
2431 /* compute number of program headers */
2432 if (file_type
== TCC_OUTPUT_OBJ
)
2434 else if (file_type
== TCC_OUTPUT_DLL
)
2436 else if (s1
->static_link
)
2441 /* allocate program segment headers */
2442 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
2444 /* compute number of sections */
2445 shnum
= s1
->nb_sections
;
2447 /* this array is used to reorder sections in the output file */
2448 sec_order
= tcc_malloc(sizeof(int) * shnum
);
2451 /* compute section to program header mapping */
2452 file_offset
= layout_sections(s1
, phdr
, phnum
, interp
, strsec
, &dyninf
,
2455 #ifndef ELF_OBJ_ONLY
2456 /* Fill remaining program header and finalize relocation related to dynamic
2458 if (file_type
!= TCC_OUTPUT_OBJ
) {
2459 fill_unloadable_phdr(phdr
, phnum
, interp
, dynamic
);
2462 dynamic
->data_offset
= dyninf
.data_offset
;
2463 fill_dynamic(s1
, &dyninf
);
2465 /* put in GOT the dynamic section address and relocate PLT */
2466 write32le(s1
->got
->data
, dynamic
->sh_addr
);
2467 if (file_type
== TCC_OUTPUT_EXE
2468 || (RELOCATE_DLLPLT
&& file_type
== TCC_OUTPUT_DLL
))
2471 /* relocate symbols in .dynsym now that final addresses are known */
2472 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
)) {
2473 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
) {
2474 /* do symbol relocation */
2475 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
2480 /* if building executable or DLL, then relocate each section
2481 except the GOT which is already relocated */
2482 ret
= final_sections_reloc(s1
);
2485 tidy_section_headers(s1
, sec_order
);
2487 /* Perform relocation to GOT or PLT entries */
2488 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2491 fill_local_got_entries(s1
);
2495 /* Create the ELF file with name 'filename' */
2496 ret
= tcc_write_elf_file(s1
, filename
, phnum
, phdr
, file_offset
, sec_order
);
2497 s1
->nb_sections
= shnum
;
2500 tcc_free(sec_order
);
2505 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2508 #ifdef TCC_TARGET_PE
2509 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2510 ret
= pe_output_file(s
, filename
);
2513 ret
= elf_output_file(s
, filename
);
2517 ssize_t
full_read(int fd
, void *buf
, size_t count
) {
2521 ssize_t num
= read(fd
, cbuf
, count
-rnum
);
2522 if (num
< 0) return num
;
2523 if (num
== 0) return rnum
;
2529 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2533 data
= tcc_malloc(size
);
2534 lseek(fd
, file_offset
, SEEK_SET
);
2535 full_read(fd
, data
, size
);
2539 typedef struct SectionMergeInfo
{
2540 Section
*s
; /* corresponding existing section */
2541 unsigned long offset
; /* offset of the new section in the existing section */
2542 uint8_t new_section
; /* true if section 's' was added */
2543 uint8_t link_once
; /* true if link once section */
2546 ST_FUNC
int tcc_object_type(int fd
, ElfW(Ehdr
) *h
)
2548 int size
= full_read(fd
, h
, sizeof *h
);
2549 if (size
== sizeof *h
&& 0 == memcmp(h
, ELFMAG
, 4)) {
2550 if (h
->e_type
== ET_REL
)
2551 return AFF_BINTYPE_REL
;
2552 if (h
->e_type
== ET_DYN
)
2553 return AFF_BINTYPE_DYN
;
2554 } else if (size
>= 8) {
2555 if (0 == memcmp(h
, ARMAG
, 8))
2556 return AFF_BINTYPE_AR
;
2557 #ifdef TCC_TARGET_COFF
2558 if (((struct filehdr
*)h
)->f_magic
== COFF_C67_MAGIC
)
2559 return AFF_BINTYPE_C67
;
2565 /* load an object file and merge it with current files */
2566 /* XXX: handle correctly stab (debug) info */
2567 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
2568 int fd
, unsigned long file_offset
)
2571 ElfW(Shdr
) *shdr
, *sh
;
2572 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
, seencompressed
;
2573 char *strsec
, *strtab
;
2574 int stab_index
, stabstr_index
;
2575 int *old_to_new_syms
;
2576 char *sh_name
, *name
;
2577 SectionMergeInfo
*sm_table
, *sm
;
2578 ElfW(Sym
) *sym
, *symtab
;
2582 lseek(fd
, file_offset
, SEEK_SET
);
2583 if (tcc_object_type(fd
, &ehdr
) != AFF_BINTYPE_REL
)
2585 /* test CPU specific stuff */
2586 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2587 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2589 tcc_error_noabort("invalid object file");
2593 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2594 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2595 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2597 /* load section names */
2598 sh
= &shdr
[ehdr
.e_shstrndx
];
2599 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2601 /* load symtab and strtab */
2602 old_to_new_syms
= NULL
;
2607 stab_index
= stabstr_index
= 0;
2609 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2611 if (sh
->sh_type
== SHT_SYMTAB
) {
2613 tcc_error_noabort("object must contain only one symtab");
2618 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2619 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2620 sm_table
[i
].s
= symtab_section
;
2622 /* now load strtab */
2623 sh
= &shdr
[sh
->sh_link
];
2624 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2626 if (sh
->sh_flags
& SHF_COMPRESSED
)
2630 /* now examine each section and try to merge its content with the
2632 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2633 /* no need to examine section name strtab */
2634 if (i
== ehdr
.e_shstrndx
)
2637 if (sh
->sh_type
== SHT_RELX
)
2638 sh
= &shdr
[sh
->sh_info
];
2639 /* ignore sections types we do not handle (plus relocs to those) */
2640 if (sh
->sh_type
!= SHT_PROGBITS
&&
2642 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2644 sh
->sh_type
!= SHT_NOBITS
&&
2645 sh
->sh_type
!= SHT_PREINIT_ARRAY
&&
2646 sh
->sh_type
!= SHT_INIT_ARRAY
&&
2647 sh
->sh_type
!= SHT_FINI_ARRAY
&&
2648 strcmp(strsec
+ sh
->sh_name
, ".stabstr")
2652 && !strncmp(strsec
+ sh
->sh_name
, ".debug_", sizeof(".debug_")-1))
2656 sh_name
= strsec
+ sh
->sh_name
;
2657 if (sh
->sh_addralign
< 1)
2658 sh
->sh_addralign
= 1;
2659 /* find corresponding section, if any */
2660 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2661 s
= s1
->sections
[j
];
2662 if (!strcmp(s
->name
, sh_name
)) {
2663 if (!strncmp(sh_name
, ".gnu.linkonce",
2664 sizeof(".gnu.linkonce") - 1)) {
2665 /* if a 'linkonce' section is already present, we
2666 do not add it again. It is a little tricky as
2667 symbols can still be defined in
2669 sm_table
[i
].link_once
= 1;
2673 if (s
== stab_section
)
2675 if (s
== stab_section
->link
)
2681 /* not found: create new section */
2682 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
& ~SHF_GROUP
);
2683 /* take as much info as possible from the section. sh_link and
2684 sh_info will be updated later */
2685 s
->sh_addralign
= sh
->sh_addralign
;
2686 s
->sh_entsize
= sh
->sh_entsize
;
2687 sm_table
[i
].new_section
= 1;
2689 if (sh
->sh_type
!= s
->sh_type
) {
2690 tcc_error_noabort("invalid section type");
2693 /* align start of section */
2694 s
->data_offset
+= -s
->data_offset
& (sh
->sh_addralign
- 1);
2695 if (sh
->sh_addralign
> s
->sh_addralign
)
2696 s
->sh_addralign
= sh
->sh_addralign
;
2697 sm_table
[i
].offset
= s
->data_offset
;
2699 /* concatenate sections */
2701 if (sh
->sh_type
!= SHT_NOBITS
) {
2703 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2704 ptr
= section_ptr_add(s
, size
);
2705 full_read(fd
, ptr
, size
);
2707 s
->data_offset
+= size
;
2712 /* gr relocate stab strings */
2713 if (stab_index
&& stabstr_index
) {
2716 s
= sm_table
[stab_index
].s
;
2717 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2718 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2719 o
= sm_table
[stabstr_index
].offset
;
2727 /* second short pass to update sh_link and sh_info fields of new
2729 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2731 if (!s
|| !sm_table
[i
].new_section
)
2734 if (sh
->sh_link
> 0)
2735 s
->link
= sm_table
[sh
->sh_link
].s
;
2736 if (sh
->sh_type
== SHT_RELX
) {
2737 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2738 /* update backward link */
2739 s1
->sections
[s
->sh_info
]->reloc
= s
;
2743 /* resolve symbols */
2744 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2747 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2748 if (sym
->st_shndx
!= SHN_UNDEF
&&
2749 sym
->st_shndx
< SHN_LORESERVE
) {
2750 sm
= &sm_table
[sym
->st_shndx
];
2751 if (sm
->link_once
) {
2752 /* if a symbol is in a link once section, we use the
2753 already defined symbol. It is very important to get
2754 correct relocations */
2755 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2756 name
= strtab
+ sym
->st_name
;
2757 sym_index
= find_elf_sym(symtab_section
, name
);
2759 old_to_new_syms
[i
] = sym_index
;
2763 /* if no corresponding section added, no need to add symbol */
2766 /* convert section number */
2767 sym
->st_shndx
= sm
->s
->sh_num
;
2769 sym
->st_value
+= sm
->offset
;
2772 name
= strtab
+ sym
->st_name
;
2773 sym_index
= set_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2774 sym
->st_info
, sym
->st_other
,
2775 sym
->st_shndx
, name
);
2776 old_to_new_syms
[i
] = sym_index
;
2779 /* third pass to patch relocation entries */
2780 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2785 offset
= sm_table
[i
].offset
;
2786 switch(s
->sh_type
) {
2788 /* take relocation offset information */
2789 offseti
= sm_table
[sh
->sh_info
].offset
;
2790 for_each_elem(s
, (offset
/ sizeof(*rel
)), rel
, ElfW_Rel
) {
2793 /* convert symbol index */
2794 type
= ELFW(R_TYPE
)(rel
->r_info
);
2795 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2796 /* NOTE: only one symtab assumed */
2797 if (sym_index
>= nb_syms
)
2799 sym_index
= old_to_new_syms
[sym_index
];
2800 /* ignore link_once in rel section. */
2801 if (!sym_index
&& !sm_table
[sh
->sh_info
].link_once
2802 #ifdef TCC_TARGET_ARM
2803 && type
!= R_ARM_V4BX
2804 #elif defined TCC_TARGET_RISCV64
2805 && type
!= R_RISCV_ALIGN
2806 && type
!= R_RISCV_RELAX
2810 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2811 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2814 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2815 /* offset the relocation offset */
2816 rel
->r_offset
+= offseti
;
2817 #ifdef TCC_TARGET_ARM
2818 /* Jumps and branches from a Thumb code to a PLT entry need
2819 special handling since PLT entries are ARM code.
2820 Unconditional bl instructions referencing PLT entries are
2821 handled by converting these instructions into blx
2822 instructions. Other case of instructions referencing a PLT
2823 entry require to add a Thumb stub before the PLT entry to
2824 switch to ARM mode. We set bit plt_thumb_stub of the
2825 attribute of a symbol to indicate such a case. */
2826 if (type
== R_ARM_THM_JUMP24
)
2827 get_sym_attr(s1
, sym_index
, 1)->plt_thumb_stub
= 1;
2840 tcc_free(old_to_new_syms
);
2847 typedef struct ArchiveHeader
{
2848 char ar_name
[16]; /* name of this member */
2849 char ar_date
[12]; /* file mtime */
2850 char ar_uid
[6]; /* owner uid; printed as decimal */
2851 char ar_gid
[6]; /* owner gid; printed as decimal */
2852 char ar_mode
[8]; /* file mode, printed as octal */
2853 char ar_size
[10]; /* file size, printed as decimal */
2854 char ar_fmag
[2]; /* should contain ARFMAG */
2857 #define ARFMAG "`\n"
2859 static unsigned long long get_be(const uint8_t *b
, int n
)
2861 unsigned long long ret
= 0;
2863 ret
= (ret
<< 8) | *b
++, --n
;
2867 static int read_ar_header(int fd
, int offset
, ArchiveHeader
*hdr
)
2871 lseek(fd
, offset
, SEEK_SET
);
2872 len
= full_read(fd
, hdr
, sizeof(ArchiveHeader
));
2873 if (len
!= sizeof(ArchiveHeader
))
2874 return len
? -1 : 0;
2876 for (e
= p
+ sizeof hdr
->ar_name
; e
> p
&& e
[-1] == ' ';)
2879 hdr
->ar_size
[sizeof hdr
->ar_size
-1] = 0;
2883 /* load only the objects which resolve undefined symbols */
2884 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
, int entrysize
)
2886 int i
, bound
, nsyms
, sym_index
, len
, ret
= -1;
2887 unsigned long long off
;
2889 const char *ar_names
, *p
;
2890 const uint8_t *ar_index
;
2894 data
= tcc_malloc(size
);
2895 if (full_read(fd
, data
, size
) != size
)
2897 nsyms
= get_be(data
, entrysize
);
2898 ar_index
= data
+ entrysize
;
2899 ar_names
= (char *) ar_index
+ nsyms
* entrysize
;
2903 for (p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2904 Section
*s
= symtab_section
;
2905 sym_index
= find_elf_sym(s
, p
);
2908 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
2909 if(sym
->st_shndx
!= SHN_UNDEF
)
2911 off
= get_be(ar_index
+ i
* entrysize
, entrysize
);
2912 len
= read_ar_header(fd
, off
, &hdr
);
2913 if (len
<= 0 || memcmp(hdr
.ar_fmag
, ARFMAG
, 2)) {
2914 tcc_error_noabort("invalid archive");
2918 if (s1
->verbose
== 2)
2919 printf(" -> %s\n", hdr
.ar_name
);
2920 if (tcc_load_object_file(s1
, fd
, off
) < 0)
2931 /* load a '.a' file */
2932 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
, int alacarte
)
2935 /* char magic[8]; */
2937 unsigned long file_offset
;
2940 /* skip magic which was already checked */
2941 /* full_read(fd, magic, sizeof(magic)); */
2942 file_offset
= sizeof ARMAG
- 1;
2945 len
= read_ar_header(fd
, file_offset
, &hdr
);
2949 tcc_error_noabort("invalid archive");
2953 size
= strtol(hdr
.ar_size
, NULL
, 0);
2955 size
= (size
+ 1) & ~1;
2957 /* coff symbol table : we handle it */
2958 if (!strcmp(hdr
.ar_name
, "/"))
2959 return tcc_load_alacarte(s1
, fd
, size
, 4);
2960 if (!strcmp(hdr
.ar_name
, "/SYM64/"))
2961 return tcc_load_alacarte(s1
, fd
, size
, 8);
2962 } else if (tcc_object_type(fd
, &ehdr
) == AFF_BINTYPE_REL
) {
2963 if (s1
->verbose
== 2)
2964 printf(" -> %s\n", hdr
.ar_name
);
2965 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2968 file_offset
+= size
;
2972 #ifndef ELF_OBJ_ONLY
2973 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
2974 LV, maybe create a new entry for (LIB,VERSION). */
2975 static void set_ver_to_ver(TCCState
*s1
, int *n
, int **lv
, int i
, char *lib
, char *version
)
2978 *lv
= tcc_realloc(*lv
, (*n
+ 1) * sizeof(**lv
));
2981 if ((*lv
)[i
] == -1) {
2982 int v
, prev_same_lib
= -1;
2983 for (v
= 0; v
< nb_sym_versions
; v
++) {
2984 if (strcmp(sym_versions
[v
].lib
, lib
))
2987 if (!strcmp(sym_versions
[v
].version
, version
))
2990 if (v
== nb_sym_versions
) {
2991 sym_versions
= tcc_realloc (sym_versions
,
2992 (v
+ 1) * sizeof(*sym_versions
));
2993 sym_versions
[v
].lib
= tcc_strdup(lib
);
2994 sym_versions
[v
].version
= tcc_strdup(version
);
2995 sym_versions
[v
].out_index
= 0;
2996 sym_versions
[v
].prev_same_lib
= prev_same_lib
;
3003 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3006 set_sym_version(TCCState
*s1
, int sym_index
, int verndx
)
3008 if (sym_index
>= nb_sym_to_version
) {
3009 int newelems
= sym_index
? sym_index
* 2 : 1;
3010 sym_to_version
= tcc_realloc(sym_to_version
,
3011 newelems
* sizeof(*sym_to_version
));
3012 memset(sym_to_version
+ nb_sym_to_version
, -1,
3013 (newelems
- nb_sym_to_version
) * sizeof(*sym_to_version
));
3014 nb_sym_to_version
= newelems
;
3016 if (sym_to_version
[sym_index
] < 0)
3017 sym_to_version
[sym_index
] = verndx
;
3020 struct versym_info
{
3022 ElfW(Verdef
) *verdef
;
3023 ElfW(Verneed
) *verneed
;
3025 int nb_local_ver
, *local_ver
;
3029 static void store_version(TCCState
*s1
, struct versym_info
*v
, char *dynstr
)
3031 char *lib
, *version
;
3035 #define DEBUG_VERSION 0
3037 if (v
->versym
&& v
->verdef
) {
3038 ElfW(Verdef
) *vdef
= v
->verdef
;
3041 ElfW(Verdaux
) *verdaux
=
3042 (ElfW(Verdaux
) *) (((char *) vdef
) + vdef
->vd_aux
);
3045 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3046 vdef
->vd_version
, vdef
->vd_flags
, vdef
->vd_ndx
,
3050 version
= dynstr
+ verdaux
->vda_name
;
3055 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vdef
->vd_ndx
,
3058 printf (" verdaux(%u): %s\n", vdef
->vd_ndx
, version
);
3061 next
= vdef
->vd_next
;
3062 vdef
= (ElfW(Verdef
) *) (((char *) vdef
) + next
);
3065 if (v
->versym
&& v
->verneed
) {
3066 ElfW(Verneed
) *vneed
= v
->verneed
;
3068 ElfW(Vernaux
) *vernaux
=
3069 (ElfW(Vernaux
) *) (((char *) vneed
) + vneed
->vn_aux
);
3071 lib
= dynstr
+ vneed
->vn_file
;
3073 printf ("verneed: %u %s\n", vneed
->vn_version
, lib
);
3075 for (i
= 0; i
< vneed
->vn_cnt
; i
++) {
3076 if ((vernaux
->vna_other
& 0x8000) == 0) { /* hidden */
3077 version
= dynstr
+ vernaux
->vna_name
;
3078 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vernaux
->vna_other
,
3081 printf (" vernaux(%u): %u %u %s\n",
3082 vernaux
->vna_other
, vernaux
->vna_hash
,
3083 vernaux
->vna_flags
, version
);
3086 vernaux
= (ElfW(Vernaux
) *) (((char *) vernaux
) + vernaux
->vna_next
);
3088 next
= vneed
->vn_next
;
3089 vneed
= (ElfW(Verneed
) *) (((char *) vneed
) + next
);
3094 for (i
= 0; i
< v
->nb_local_ver
; i
++) {
3095 if (v
->local_ver
[i
] > 0) {
3096 printf ("%d: lib: %s, version %s\n",
3097 i
, sym_versions
[v
->local_ver
[i
]].lib
,
3098 sym_versions
[v
->local_ver
[i
]].version
);
3104 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3105 is referenced by the user (so it should be added as DT_NEEDED in
3106 the generated ELF file) */
3107 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
3110 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
3111 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
3112 ElfW(Sym
) *sym
, *dynsym
;
3113 ElfW(Dyn
) *dt
, *dynamic
;
3117 const char *name
, *soname
;
3118 DLLReference
*dllref
;
3119 struct versym_info v
;
3121 full_read(fd
, &ehdr
, sizeof(ehdr
));
3123 /* test CPU specific stuff */
3124 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
3125 ehdr
.e_machine
!= EM_TCC_TARGET
) {
3126 tcc_error_noabort("bad architecture");
3131 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
3133 /* load dynamic section and dynamic symbols */
3137 dynsym
= NULL
; /* avoid warning */
3138 dynstr
= NULL
; /* avoid warning */
3139 memset(&v
, 0, sizeof v
);
3141 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
3142 switch(sh
->sh_type
) {
3144 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
3145 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3148 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
3149 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3150 sh1
= &shdr
[sh
->sh_link
];
3151 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
3153 case SHT_GNU_verdef
:
3154 v
.verdef
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3156 case SHT_GNU_verneed
:
3157 v
.verneed
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3159 case SHT_GNU_versym
:
3160 v
.nb_versyms
= sh
->sh_size
/ sizeof(ElfW(Half
));
3161 v
.versym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3168 /* compute the real library name */
3169 soname
= tcc_basename(filename
);
3171 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3172 if (dt
->d_tag
== DT_SONAME
) {
3173 soname
= dynstr
+ dt
->d_un
.d_val
;
3177 /* if the dll is already loaded, do not load it */
3178 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
3179 dllref
= s1
->loaded_dlls
[i
];
3180 if (!strcmp(soname
, dllref
->name
)) {
3181 /* but update level if needed */
3182 if (level
< dllref
->level
)
3183 dllref
->level
= level
;
3189 if (v
.nb_versyms
!= nb_syms
)
3190 tcc_free (v
.versym
), v
.versym
= NULL
;
3192 store_version(s1
, &v
, dynstr
);
3194 /* add the dll and its level */
3195 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
3196 dllref
->level
= level
;
3197 strcpy(dllref
->name
, soname
);
3198 dynarray_add(&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
3200 /* add dynamic symbols in dynsym_section */
3201 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
3202 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
3203 if (sym_bind
== STB_LOCAL
)
3205 name
= dynstr
+ sym
->st_name
;
3206 sym_index
= set_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
3207 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
3209 ElfW(Half
) vsym
= v
.versym
[i
];
3210 if ((vsym
& 0x8000) == 0 && vsym
> 0 && vsym
< v
.nb_local_ver
)
3211 set_sym_version(s1
, sym_index
, v
.local_ver
[vsym
]);
3215 /* load all referenced DLLs */
3216 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3219 name
= dynstr
+ dt
->d_un
.d_val
;
3220 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
3221 dllref
= s1
->loaded_dlls
[j
];
3222 if (!strcmp(name
, dllref
->name
))
3223 goto already_loaded
;
3225 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
3226 tcc_error_noabort("referenced dll '%s' not found", name
);
3240 tcc_free(v
.local_ver
);
3242 tcc_free(v
.verneed
);
3247 #define LD_TOK_NAME 256
3248 #define LD_TOK_EOF (-1)
3250 static int ld_inp(TCCState
*s1
)
3258 if (1 == read(s1
->fd
, &b
, 1))
3263 /* return next ld script token */
3264 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
3281 if (ch
== '*') { /* comment */
3282 for (d
= 0;; d
= ch
) {
3284 if (ch
== CH_EOF
|| (ch
== '/' && d
== '*'))
3295 /* case 'a' ... 'z': */
3322 /* case 'A' ... 'z': */
3356 if (!((ch
>= 'a' && ch
<= 'z') ||
3357 (ch
>= 'A' && ch
<= 'Z') ||
3358 (ch
>= '0' && ch
<= '9') ||
3359 strchr("/.-_+=$:\\,~", ch
)))
3361 if ((q
- name
) < name_size
- 1) {
3380 static int ld_add_file(TCCState
*s1
, const char filename
[])
3382 if (filename
[0] == '/') {
3383 if (CONFIG_SYSROOT
[0] == '\0'
3384 && tcc_add_file_internal(s1
, filename
, AFF_TYPE_BIN
) == 0)
3386 filename
= tcc_basename(filename
);
3388 return tcc_add_dll(s1
, filename
, 0);
3391 static int ld_add_file_list(TCCState
*s1
, const char *cmd
, int as_needed
)
3393 char filename
[1024], libname
[1024];
3394 int t
, group
, nblibs
= 0, ret
= 0;
3397 group
= !strcmp(cmd
, "GROUP");
3399 s1
->new_undef_sym
= 0;
3400 t
= ld_next(s1
, filename
, sizeof(filename
));
3402 tcc_error_noabort("( expected");
3404 goto lib_parse_error
;
3406 t
= ld_next(s1
, filename
, sizeof(filename
));
3409 if (t
== LD_TOK_EOF
) {
3410 tcc_error_noabort("unexpected end of file");
3412 goto lib_parse_error
;
3413 } else if (t
== ')') {
3415 } else if (t
== '-') {
3416 t
= ld_next(s1
, filename
, sizeof(filename
));
3417 if ((t
!= LD_TOK_NAME
) || (filename
[0] != 'l')) {
3418 tcc_error_noabort("library name expected");
3420 goto lib_parse_error
;
3422 pstrcpy(libname
, sizeof libname
, &filename
[1]);
3423 if (s1
->static_link
) {
3424 snprintf(filename
, sizeof filename
, "lib%s.a", libname
);
3426 snprintf(filename
, sizeof filename
, "lib%s.so", libname
);
3428 } else if (t
!= LD_TOK_NAME
) {
3429 tcc_error_noabort("filename expected");
3431 goto lib_parse_error
;
3433 if (!strcmp(filename
, "AS_NEEDED")) {
3434 ret
= ld_add_file_list(s1
, cmd
, 1);
3436 goto lib_parse_error
;
3438 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3440 ret
= ld_add_file(s1
, filename
);
3442 goto lib_parse_error
;
3444 /* Add the filename *and* the libname to avoid future conversions */
3445 dynarray_add(&libs
, &nblibs
, tcc_strdup(filename
));
3446 if (libname
[0] != '\0')
3447 dynarray_add(&libs
, &nblibs
, tcc_strdup(libname
));
3451 t
= ld_next(s1
, filename
, sizeof(filename
));
3453 t
= ld_next(s1
, filename
, sizeof(filename
));
3456 if (group
&& !as_needed
) {
3457 while (s1
->new_undef_sym
) {
3459 s1
->new_undef_sym
= 0;
3460 for (i
= 0; i
< nblibs
; i
++)
3461 ld_add_file(s1
, libs
[i
]);
3465 dynarray_reset(&libs
, &nblibs
);
3469 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3471 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
, int fd
)
3474 char filename
[1024];
3480 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3481 if (t
== LD_TOK_EOF
)
3483 else if (t
!= LD_TOK_NAME
)
3485 if (!strcmp(cmd
, "INPUT") ||
3486 !strcmp(cmd
, "GROUP")) {
3487 ret
= ld_add_file_list(s1
, cmd
, 0);
3490 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
3491 !strcmp(cmd
, "TARGET")) {
3492 /* ignore some commands */
3493 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3495 tcc_error_noabort("( expected");
3499 t
= ld_next(s1
, filename
, sizeof(filename
));
3500 if (t
== LD_TOK_EOF
) {
3501 tcc_error_noabort("unexpected end of file");
3503 } else if (t
== ')') {
3513 #endif /* !ELF_OBJ_ONLY */