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 if (s1
->option_pthread
)
1421 tcc_add_library_err(s1
, "pthread");
1422 tcc_add_library_err(s1
, "c");
1424 if (!s1
->static_link
) {
1425 if (TCC_LIBGCC
[0] == '/')
1426 tcc_add_file(s1
, TCC_LIBGCC
);
1428 tcc_add_dll(s1
, TCC_LIBGCC
, 0);
1431 #ifdef CONFIG_TCC_BCHECK
1432 if (s1
->do_bounds_check
&& s1
->output_type
!= TCC_OUTPUT_DLL
) {
1433 tcc_add_library_err(s1
, "pthread");
1434 tcc_add_library_err(s1
, "dl");
1435 tcc_add_support(s1
, "bcheck.o");
1438 #ifdef CONFIG_TCC_BACKTRACE
1439 if (s1
->do_backtrace
) {
1440 if (s1
->output_type
== TCC_OUTPUT_EXE
)
1441 tcc_add_support(s1
, "bt-exe.o");
1442 if (s1
->output_type
!= TCC_OUTPUT_DLL
)
1443 tcc_add_support(s1
, "bt-log.o");
1444 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1448 tcc_add_support(s1
, TCC_LIBTCC1
);
1449 /* add crt end if not memory output */
1450 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1451 tcc_add_crt(s1
, "crtn.o");
1456 /* add various standard linker symbols (must be done after the
1457 sections are filled (for example after allocating common
1459 static void tcc_add_linker_symbols(TCCState
*s1
)
1465 set_global_sym(s1
, "_etext", text_section
, -1);
1466 set_global_sym(s1
, "_edata", data_section
, -1);
1467 set_global_sym(s1
, "_end", bss_section
, -1);
1468 #ifdef TCC_TARGET_RISCV64
1469 /* XXX should be .sdata+0x800, not .data+0x800 */
1470 set_global_sym(s1
, "__global_pointer$", data_section
, 0x800);
1472 /* horrible new standard ldscript defines */
1473 add_init_array_defines(s1
, ".preinit_array");
1474 add_init_array_defines(s1
, ".init_array");
1475 add_init_array_defines(s1
, ".fini_array");
1476 /* add start and stop symbols for sections whose name can be
1478 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1479 s
= s1
->sections
[i
];
1480 if ((s
->sh_flags
& SHF_ALLOC
)
1481 && (s
->sh_type
== SHT_PROGBITS
1482 || s
->sh_type
== SHT_STRTAB
)) {
1484 /* check if section name can be expressed in C */
1490 if (!isid(c
) && !isnum(c
))
1494 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1495 set_global_sym(s1
, buf
, s
, 0);
1496 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1497 set_global_sym(s1
, buf
, s
, -1);
1503 ST_FUNC
void resolve_common_syms(TCCState
*s1
)
1507 /* Allocate common symbols in BSS. */
1508 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1509 if (sym
->st_shndx
== SHN_COMMON
) {
1510 /* symbol alignment is in st_value for SHN_COMMONs */
1511 sym
->st_value
= section_add(bss_section
, sym
->st_size
,
1513 sym
->st_shndx
= bss_section
->sh_num
;
1517 /* Now assign linker provided symbols their value. */
1518 tcc_add_linker_symbols(s1
);
1521 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1522 const int *sec_order
)
1525 int i
, offset
, size
;
1528 for(i
=1;i
<s1
->nb_sections
;i
++) {
1529 s
= s1
->sections
[sec_order
[i
]];
1530 if (s
->sh_type
!= SHT_NOBITS
&&
1531 (s
->sh_flags
& SHF_ALLOC
)) {
1532 while (offset
< s
->sh_offset
) {
1537 fwrite(s
->data
, 1, size
, f
);
1543 #ifndef ELF_OBJ_ONLY
1544 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1546 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1547 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1548 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1549 unsigned offset
= attr
->got_offset
;
1553 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1554 #ifdef TCC_TARGET_X86_64
1555 write64le(s1
->got
->data
+ offset
, sym
->st_value
);
1557 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1561 /* Perform relocation to GOT or PLT entries */
1562 ST_FUNC
void fill_got(TCCState
*s1
)
1568 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1569 s
= s1
->sections
[i
];
1570 if (s
->sh_type
!= SHT_RELX
)
1572 /* no need to handle got relocations */
1573 if (s
->link
!= symtab_section
)
1575 for_each_elem(s
, 0, rel
, ElfW_Rel
) {
1576 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1577 case R_X86_64_GOT32
:
1578 case R_X86_64_GOTPCREL
:
1579 case R_X86_64_GOTPCRELX
:
1580 case R_X86_64_REX_GOTPCRELX
:
1581 case R_X86_64_PLT32
:
1582 fill_got_entry(s1
, rel
);
1589 /* See put_got_entry for a description. This is the second stage
1590 where GOT references to local defined symbols are rewritten. */
1591 static void fill_local_got_entries(TCCState
*s1
)
1594 if (!s1
->got
->reloc
)
1596 for_each_elem(s1
->got
->reloc
, 0, rel
, ElfW_Rel
) {
1597 if (ELFW(R_TYPE
)(rel
->r_info
) == R_RELATIVE
) {
1598 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1599 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1600 struct sym_attr
*attr
= get_sym_attr(s1
, sym_index
, 0);
1601 unsigned offset
= attr
->got_offset
;
1602 if (offset
!= rel
->r_offset
- s1
->got
->sh_addr
)
1603 tcc_error_noabort("huh");
1604 rel
->r_info
= ELFW(R_INFO
)(0, R_RELATIVE
);
1605 #if SHT_RELX == SHT_RELA
1606 rel
->r_addend
= sym
->st_value
;
1608 /* All our REL architectures also happen to be 32bit LE. */
1609 write32le(s1
->got
->data
+ offset
, sym
->st_value
);
1615 /* Bind symbols of executable: resolve undefined symbols from exported symbols
1616 in shared libraries and export non local defined symbols to shared libraries
1617 if -rdynamic switch was given on command line */
1618 static void bind_exe_dynsyms(TCCState
*s1
)
1621 int sym_index
, index
;
1622 ElfW(Sym
) *sym
, *esym
;
1625 /* Resolve undefined symbols from dynamic symbols. When there is a match:
1626 - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
1627 - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
1628 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1629 if (sym
->st_shndx
== SHN_UNDEF
) {
1630 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1631 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1633 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1634 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1635 if ((type
== STT_FUNC
) || (type
== STT_GNU_IFUNC
)) {
1636 /* Indirect functions shall have STT_FUNC type in executable
1637 * dynsym section. Indeed, a dlsym call following a lazy
1638 * resolution would pick the symbol value from the
1639 * executable dynsym entry which would contain the address
1640 * of the function wanted by the caller of dlsym instead of
1641 * the address of the function that would return that
1644 = put_elf_sym(s1
->dynsym
, 0, esym
->st_size
,
1645 ELFW(ST_INFO
)(STB_GLOBAL
,STT_FUNC
), 0, 0,
1647 int index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1648 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1649 } else if (type
== STT_OBJECT
) {
1650 unsigned long offset
;
1652 offset
= bss_section
->data_offset
;
1653 /* XXX: which alignment ? */
1654 offset
= (offset
+ 16 - 1) & -16;
1655 set_elf_sym (s1
->symtab
, offset
, esym
->st_size
,
1656 esym
->st_info
, 0, bss_section
->sh_num
, name
);
1657 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1658 esym
->st_info
, 0, bss_section
->sh_num
,
1661 /* Ensure R_COPY works for weak symbol aliases */
1662 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1663 for_each_elem(s1
->dynsymtab_section
, 1, dynsym
, ElfW(Sym
)) {
1664 if ((dynsym
->st_value
== esym
->st_value
)
1665 && (ELFW(ST_BIND
)(dynsym
->st_info
) == STB_GLOBAL
)) {
1666 char *dynname
= (char *) s1
->dynsymtab_section
->link
->data
1668 put_elf_sym(s1
->dynsym
, offset
, dynsym
->st_size
,
1670 bss_section
->sh_num
, dynname
);
1676 put_elf_reloc(s1
->dynsym
, bss_section
,
1677 offset
, R_COPY
, index
);
1678 offset
+= esym
->st_size
;
1679 bss_section
->data_offset
= offset
;
1682 /* STB_WEAK undefined symbols are accepted */
1683 /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
1684 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1685 !strcmp(name
, "_fp_hw")) {
1687 tcc_error_noabort("undefined symbol '%s'", name
);
1690 } else if (s1
->rdynamic
&& ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1691 /* if -rdynamic option, then export all non local symbols */
1692 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1693 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
, sym
->st_info
,
1694 0, sym
->st_shndx
, name
);
1699 /* Bind symbols of libraries: export all non local symbols of executable that
1700 are referenced by shared libraries. The reason is that the dynamic loader
1701 search symbol first in executable and then in libraries. Therefore a
1702 reference to a symbol already defined by a library can still be resolved by
1703 a symbol in the executable. */
1704 static void bind_libs_dynsyms(TCCState
*s1
)
1708 ElfW(Sym
) *sym
, *esym
;
1710 for_each_elem(s1
->dynsymtab_section
, 1, esym
, ElfW(Sym
)) {
1711 name
= (char *) s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1712 sym_index
= find_elf_sym(symtab_section
, name
);
1713 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1714 if (sym_index
&& sym
->st_shndx
!= SHN_UNDEF
1715 && ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1716 set_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1717 sym
->st_info
, 0, sym
->st_shndx
, name
);
1718 } else if (esym
->st_shndx
== SHN_UNDEF
) {
1719 /* weak symbols can stay undefined */
1720 if (ELFW(ST_BIND
)(esym
->st_info
) != STB_WEAK
)
1721 tcc_warning("undefined dynamic symbol '%s'", name
);
1726 /* Export all non local symbols. This is used by shared libraries so that the
1727 non local symbols they define can resolve a reference in another shared
1728 library or in the executable. Correspondingly, it allows undefined local
1729 symbols to be resolved by other shared libraries or by the executable. */
1730 static void export_global_syms(TCCState
*s1
)
1732 int dynindex
, index
;
1736 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
)) {
1737 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1738 name
= (char *) symtab_section
->link
->data
+ sym
->st_name
;
1739 dynindex
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1740 sym
->st_info
, 0, sym
->st_shndx
, name
);
1741 index
= sym
- (ElfW(Sym
) *) symtab_section
->data
;
1742 get_sym_attr(s1
, index
, 1)->dyn_index
= dynindex
;
1748 /* Allocate strings for section names and decide if an unallocated section
1750 NOTE: the strsec section comes last, so its size is also correct ! */
1751 static int alloc_sec_names(TCCState
*s1
, int file_type
, Section
*strsec
)
1757 /* Allocate strings for section names */
1758 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1759 s
= s1
->sections
[i
];
1760 /* when generating a DLL, we include relocations but we may
1762 #ifndef ELF_OBJ_ONLY
1763 if (file_type
== TCC_OUTPUT_DLL
&&
1764 s
->sh_type
== SHT_RELX
&&
1765 !(s
->sh_flags
& SHF_ALLOC
) &&
1766 (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
) &&
1767 prepare_dynamic_rel(s1
, s
)) {
1768 if (!(s1
->sections
[s
->sh_info
]->sh_flags
& SHF_WRITE
))
1772 if ((s1
->do_debug
&& s
->sh_type
!= SHT_RELX
) ||
1773 file_type
== TCC_OUTPUT_OBJ
||
1774 (s
->sh_flags
& SHF_ALLOC
) ||
1775 i
== (s1
->nb_sections
- 1)) {
1776 /* we output all sections if debug or object file */
1777 s
->sh_size
= s
->data_offset
;
1779 if (s
->sh_size
|| (s
->sh_flags
& SHF_ALLOC
))
1780 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1782 strsec
->sh_size
= strsec
->data_offset
;
1786 /* Info to be copied in dynamic section */
1790 unsigned long data_offset
;
1793 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1799 /* Assign sections to segments and decide how are sections laid out when loaded
1800 in memory. This function also fills corresponding program headers. */
1801 static int layout_sections(TCCState
*s1
, ElfW(Phdr
) *phdr
, int phnum
,
1802 Section
*interp
, Section
* strsec
,
1803 struct dyn_inf
*dyninf
, int *sec_order
)
1805 int i
, j
, k
, file_type
, sh_order_index
, file_offset
;
1806 unsigned long s_align
;
1812 file_type
= s1
->output_type
;
1815 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
1816 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1817 s_align
= ELF_PAGE_SIZE
;
1818 if (s1
->section_align
)
1819 s_align
= s1
->section_align
;
1822 if (s1
->has_text_addr
) {
1823 int a_offset
, p_offset
;
1824 addr
= s1
->text_addr
;
1825 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1827 a_offset
= (int) (addr
& (s_align
- 1));
1828 p_offset
= file_offset
& (s_align
- 1);
1829 if (a_offset
< p_offset
)
1830 a_offset
+= s_align
;
1831 file_offset
+= (a_offset
- p_offset
);
1833 if (file_type
== TCC_OUTPUT_DLL
)
1836 addr
= ELF_START_ADDR
;
1837 /* compute address after headers */
1838 addr
+= (file_offset
& (s_align
- 1));
1842 /* Leave one program headers for the program interpreter and one for
1843 the program header table itself if needed. These are done later as
1844 they require section layout to be done first. */
1848 /* dynamic relocation table information, for .dynamic section */
1849 dyninf
->rel_addr
= dyninf
->rel_size
= 0;
1850 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1851 dyninf
->bss_addr
= dyninf
->bss_size
= 0;
1854 for(j
= 0; j
< 2; j
++) {
1855 ph
->p_type
= PT_LOAD
;
1857 ph
->p_flags
= PF_R
| PF_X
;
1859 ph
->p_flags
= PF_R
| PF_W
;
1860 ph
->p_align
= s_align
;
1862 /* Decide the layout of sections loaded in memory. This must
1863 be done before program headers are filled since they contain
1864 info about the layout. We do the following ordering: interp,
1865 symbol tables, relocations, progbits, nobits */
1866 /* XXX: do faster and simpler sorting */
1867 for(k
= 0; k
< 5; k
++) {
1868 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1869 s
= s1
->sections
[i
];
1870 /* compute if section should be included */
1872 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1876 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1877 (SHF_ALLOC
| SHF_WRITE
))
1883 } else if ((s
->sh_type
== SHT_DYNSYM
||
1884 s
->sh_type
== SHT_STRTAB
||
1885 s
->sh_type
== SHT_HASH
)
1886 && !strstr(s
->name
, ".stab")) {
1889 } else if (s
->sh_type
== SHT_RELX
) {
1892 } else if (s
->sh_type
== SHT_NOBITS
) {
1899 sec_order
[sh_order_index
++] = i
;
1901 /* section matches: we align it and add its size */
1903 addr
= (addr
+ s
->sh_addralign
- 1) &
1904 ~(s
->sh_addralign
- 1);
1905 file_offset
+= (int) ( addr
- tmp
);
1906 s
->sh_offset
= file_offset
;
1909 /* update program header infos */
1910 if (ph
->p_offset
== 0) {
1911 ph
->p_offset
= file_offset
;
1913 ph
->p_paddr
= ph
->p_vaddr
;
1915 /* update dynamic relocation infos */
1916 if (s
->sh_type
== SHT_RELX
) {
1917 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1918 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.got")) {
1919 dyninf
->rel_addr
= addr
;
1920 dyninf
->rel_size
+= s
->sh_size
; /* XXX only first rel. */
1922 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.bss")) {
1923 dyninf
->bss_addr
= addr
;
1924 dyninf
->bss_size
= s
->sh_size
; /* XXX only first rel. */
1927 if (dyninf
->rel_size
== 0)
1928 dyninf
->rel_addr
= addr
;
1929 dyninf
->rel_size
+= s
->sh_size
;
1933 if (s
->sh_type
!= SHT_NOBITS
)
1934 file_offset
+= s
->sh_size
;
1938 /* Make the first PT_LOAD segment include the program
1939 headers itself (and the ELF header as well), it'll
1940 come out with same memory use but will make various
1941 tools like binutils strip work better. */
1942 ph
->p_offset
&= ~(ph
->p_align
- 1);
1943 ph
->p_vaddr
&= ~(ph
->p_align
- 1);
1944 ph
->p_paddr
&= ~(ph
->p_align
- 1);
1946 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1947 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1950 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1951 /* if in the middle of a page, we duplicate the page in
1952 memory so that one copy is RX and the other is RW */
1953 if ((addr
& (s_align
- 1)) != 0)
1956 addr
= (addr
+ s_align
- 1) & ~(s_align
- 1);
1957 file_offset
= (file_offset
+ s_align
- 1) & ~(s_align
- 1);
1963 /* all other sections come after */
1964 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1965 s
= s1
->sections
[i
];
1966 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1968 sec_order
[sh_order_index
++] = i
;
1970 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1971 ~(s
->sh_addralign
- 1);
1972 s
->sh_offset
= file_offset
;
1973 if (s
->sh_type
!= SHT_NOBITS
)
1974 file_offset
+= s
->sh_size
;
1980 #ifndef ELF_OBJ_ONLY
1981 static void fill_unloadable_phdr(ElfW(Phdr
) *phdr
, int phnum
, Section
*interp
,
1986 /* if interpreter, then add corresponding program header */
1990 ph
->p_type
= PT_PHDR
;
1991 ph
->p_offset
= sizeof(ElfW(Ehdr
));
1992 ph
->p_filesz
= ph
->p_memsz
= phnum
* sizeof(ElfW(Phdr
));
1993 ph
->p_vaddr
= interp
->sh_addr
- ph
->p_filesz
;
1994 ph
->p_paddr
= ph
->p_vaddr
;
1995 ph
->p_flags
= PF_R
| PF_X
;
1996 ph
->p_align
= 4; /* interp->sh_addralign; */
1999 ph
->p_type
= PT_INTERP
;
2000 ph
->p_offset
= interp
->sh_offset
;
2001 ph
->p_vaddr
= interp
->sh_addr
;
2002 ph
->p_paddr
= ph
->p_vaddr
;
2003 ph
->p_filesz
= interp
->sh_size
;
2004 ph
->p_memsz
= interp
->sh_size
;
2006 ph
->p_align
= interp
->sh_addralign
;
2009 /* if dynamic section, then add corresponding program header */
2011 ph
= &phdr
[phnum
- 1];
2013 ph
->p_type
= PT_DYNAMIC
;
2014 ph
->p_offset
= dynamic
->sh_offset
;
2015 ph
->p_vaddr
= dynamic
->sh_addr
;
2016 ph
->p_paddr
= ph
->p_vaddr
;
2017 ph
->p_filesz
= dynamic
->sh_size
;
2018 ph
->p_memsz
= dynamic
->sh_size
;
2019 ph
->p_flags
= PF_R
| PF_W
;
2020 ph
->p_align
= dynamic
->sh_addralign
;
2024 /* Fill the dynamic section with tags describing the address and size of
2026 static void fill_dynamic(TCCState
*s1
, struct dyn_inf
*dyninf
)
2028 Section
*dynamic
= dyninf
->dynamic
;
2031 /* put dynamic section entries */
2032 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
2033 put_dt(dynamic
, DT_STRTAB
, dyninf
->dynstr
->sh_addr
);
2034 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
2035 put_dt(dynamic
, DT_STRSZ
, dyninf
->dynstr
->data_offset
);
2036 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
2038 put_dt(dynamic
, DT_RELA
, dyninf
->rel_addr
);
2039 put_dt(dynamic
, DT_RELASZ
, dyninf
->rel_size
);
2040 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
2042 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2043 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2044 put_dt(dynamic
, DT_PLTRELSZ
, dyninf
->rel_size
);
2045 put_dt(dynamic
, DT_JMPREL
, dyninf
->rel_addr
);
2046 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
2047 put_dt(dynamic
, DT_REL
, dyninf
->bss_addr
);
2048 put_dt(dynamic
, DT_RELSZ
, dyninf
->bss_size
);
2050 put_dt(dynamic
, DT_REL
, dyninf
->rel_addr
);
2051 put_dt(dynamic
, DT_RELSZ
, dyninf
->rel_size
);
2052 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
2056 put_dt(dynamic
, DT_VERSYM
, versym_section
->sh_addr
);
2057 if (verneed_section
) {
2058 put_dt(dynamic
, DT_VERNEED
, verneed_section
->sh_addr
);
2059 put_dt(dynamic
, DT_VERNEEDNUM
, dt_verneednum
);
2061 s
= find_section_create (s1
, ".preinit_array", 0);
2062 if (s
&& s
->data_offset
) {
2063 put_dt(dynamic
, DT_PREINIT_ARRAY
, s
->sh_addr
);
2064 put_dt(dynamic
, DT_PREINIT_ARRAYSZ
, s
->data_offset
);
2066 s
= find_section_create (s1
, ".init_array", 0);
2067 if (s
&& s
->data_offset
) {
2068 put_dt(dynamic
, DT_INIT_ARRAY
, s
->sh_addr
);
2069 put_dt(dynamic
, DT_INIT_ARRAYSZ
, s
->data_offset
);
2071 s
= find_section_create (s1
, ".fini_array", 0);
2072 if (s
&& s
->data_offset
) {
2073 put_dt(dynamic
, DT_FINI_ARRAY
, s
->sh_addr
);
2074 put_dt(dynamic
, DT_FINI_ARRAYSZ
, s
->data_offset
);
2076 s
= find_section_create (s1
, ".init", 0);
2077 if (s
&& s
->data_offset
) {
2078 put_dt(dynamic
, DT_INIT
, s
->sh_addr
);
2080 s
= find_section_create (s1
, ".fini", 0);
2081 if (s
&& s
->data_offset
) {
2082 put_dt(dynamic
, DT_FINI
, s
->sh_addr
);
2085 put_dt(dynamic
, DT_DEBUG
, 0);
2086 put_dt(dynamic
, DT_NULL
, 0);
2089 /* Relocate remaining sections and symbols (that is those not related to
2091 static int final_sections_reloc(TCCState
*s1
)
2096 relocate_syms(s1
, s1
->symtab
, 0);
2098 if (s1
->nb_errors
!= 0)
2101 /* relocate sections */
2102 /* XXX: ignore sections with allocated relocations ? */
2103 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2104 s
= s1
->sections
[i
];
2105 if (s
->reloc
&& (s
!= s1
->got
|| s1
->static_link
))
2106 relocate_section(s1
, s
);
2109 /* relocate relocation entries if the relocation tables are
2110 allocated in the executable */
2111 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2112 s
= s1
->sections
[i
];
2113 if ((s
->sh_flags
& SHF_ALLOC
) &&
2114 s
->sh_type
== SHT_RELX
) {
2115 relocate_rel(s1
, s
);
2122 /* Create an ELF file on disk.
2123 This function handle ELF specific layout requirements */
2124 static void tcc_output_elf(TCCState
*s1
, FILE *f
, int phnum
, ElfW(Phdr
) *phdr
,
2125 int file_offset
, int *sec_order
)
2127 int i
, shnum
, offset
, size
, file_type
;
2130 ElfW(Shdr
) shdr
, *sh
;
2132 file_type
= s1
->output_type
;
2133 shnum
= s1
->nb_sections
;
2135 memset(&ehdr
, 0, sizeof(ehdr
));
2138 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2139 ehdr
.e_phnum
= phnum
;
2140 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2144 file_offset
= (file_offset
+ 3) & -4;
2147 ehdr
.e_ident
[0] = ELFMAG0
;
2148 ehdr
.e_ident
[1] = ELFMAG1
;
2149 ehdr
.e_ident
[2] = ELFMAG2
;
2150 ehdr
.e_ident
[3] = ELFMAG3
;
2151 ehdr
.e_ident
[4] = ELFCLASSW
;
2152 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2153 ehdr
.e_ident
[6] = EV_CURRENT
;
2154 #if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
2155 /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
2156 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2158 #ifdef TCC_TARGET_ARM
2160 ehdr
.e_ident
[EI_OSABI
] = 0;
2161 ehdr
.e_flags
= EF_ARM_EABI_VER4
;
2162 if (file_type
== TCC_OUTPUT_EXE
|| file_type
== TCC_OUTPUT_DLL
)
2163 ehdr
.e_flags
|= EF_ARM_HASENTRY
;
2164 if (s1
->float_abi
== ARM_HARD_FLOAT
)
2165 ehdr
.e_flags
|= EF_ARM_VFP_FLOAT
;
2167 ehdr
.e_flags
|= EF_ARM_SOFT_FLOAT
;
2169 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2171 #elif defined TCC_TARGET_RISCV64
2172 ehdr
.e_flags
= EF_RISCV_FLOAT_ABI_DOUBLE
;
2176 case TCC_OUTPUT_EXE
:
2177 ehdr
.e_type
= ET_EXEC
;
2178 ehdr
.e_entry
= get_elf_sym_addr(s1
, "_start", 1);
2180 case TCC_OUTPUT_DLL
:
2181 ehdr
.e_type
= ET_DYN
;
2182 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
2184 case TCC_OUTPUT_OBJ
:
2185 ehdr
.e_type
= ET_REL
;
2188 ehdr
.e_machine
= EM_TCC_TARGET
;
2189 ehdr
.e_version
= EV_CURRENT
;
2190 ehdr
.e_shoff
= file_offset
;
2191 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2192 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2193 ehdr
.e_shnum
= shnum
;
2194 ehdr
.e_shstrndx
= shnum
- 1;
2196 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2197 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2198 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2200 sort_syms(s1
, symtab_section
);
2201 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2202 s
= s1
->sections
[sec_order
[i
]];
2203 if (s
->sh_type
!= SHT_NOBITS
) {
2204 while (offset
< s
->sh_offset
) {
2210 fwrite(s
->data
, 1, size
, f
);
2215 /* output section headers */
2216 while (offset
< ehdr
.e_shoff
) {
2221 for(i
= 0; i
< s1
->nb_sections
; i
++) {
2223 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2224 s
= s1
->sections
[i
];
2226 sh
->sh_name
= s
->sh_name
;
2227 sh
->sh_type
= s
->sh_type
;
2228 sh
->sh_flags
= s
->sh_flags
;
2229 sh
->sh_entsize
= s
->sh_entsize
;
2230 sh
->sh_info
= s
->sh_info
;
2232 sh
->sh_link
= s
->link
->sh_num
;
2233 sh
->sh_addralign
= s
->sh_addralign
;
2234 sh
->sh_addr
= s
->sh_addr
;
2235 sh
->sh_offset
= s
->sh_offset
;
2236 sh
->sh_size
= s
->sh_size
;
2238 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2242 /* Write an elf, coff or "binary" file */
2243 static int tcc_write_elf_file(TCCState
*s1
, const char *filename
, int phnum
,
2244 ElfW(Phdr
) *phdr
, int file_offset
, int *sec_order
)
2246 int fd
, mode
, file_type
;
2249 file_type
= s1
->output_type
;
2250 if (file_type
== TCC_OUTPUT_OBJ
)
2255 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2257 tcc_error_noabort("could not write '%s'", filename
);
2260 f
= fdopen(fd
, "wb");
2262 printf("<- %s\n", filename
);
2264 #ifdef TCC_TARGET_COFF
2265 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
)
2266 tcc_output_coff(s1
, f
);
2269 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
)
2270 tcc_output_elf(s1
, f
, phnum
, phdr
, file_offset
, sec_order
);
2272 tcc_output_binary(s1
, f
, sec_order
);
2278 #ifndef ELF_OBJ_ONLY
2279 /* Sort section headers by assigned sh_addr, remove sections
2280 that we aren't going to output. */
2281 static void tidy_section_headers(TCCState
*s1
, int *sec_order
)
2283 int i
, nnew
, l
, *backmap
;
2287 snew
= tcc_malloc(s1
->nb_sections
* sizeof(snew
[0]));
2288 backmap
= tcc_malloc(s1
->nb_sections
* sizeof(backmap
[0]));
2289 for (i
= 0, nnew
= 0, l
= s1
->nb_sections
; i
< s1
->nb_sections
; i
++) {
2290 s
= s1
->sections
[sec_order
[i
]];
2291 if (!i
|| s
->sh_name
) {
2292 backmap
[sec_order
[i
]] = nnew
;
2296 backmap
[sec_order
[i
]] = 0;
2300 for (i
= 0; i
< nnew
; i
++) {
2304 if (s
->sh_type
== SHT_RELX
)
2305 s
->sh_info
= backmap
[s
->sh_info
];
2309 for_each_elem(symtab_section
, 1, sym
, ElfW(Sym
))
2310 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2311 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2312 if( !s1
->static_link
) {
2313 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
))
2314 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
)
2315 sym
->st_shndx
= backmap
[sym
->st_shndx
];
2317 for (i
= 0; i
< s1
->nb_sections
; i
++)
2319 tcc_free(s1
->sections
);
2320 s1
->sections
= snew
;
2321 s1
->nb_sections
= nnew
;
2326 /* Output an elf, coff or binary file */
2327 /* XXX: suppress unneeded sections */
2328 static int elf_output_file(TCCState
*s1
, const char *filename
)
2330 int ret
, phnum
, shnum
, file_type
, file_offset
, *sec_order
;
2331 struct dyn_inf dyninf
= {0};
2333 Section
*strsec
, *interp
, *dynamic
, *dynstr
;
2335 file_type
= s1
->output_type
;
2340 interp
= dynamic
= dynstr
= NULL
; /* avoid warning */
2342 #ifndef ELF_OBJ_ONLY
2343 if (file_type
!= TCC_OUTPUT_OBJ
) {
2344 /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
2345 tcc_add_runtime(s1
);
2346 resolve_common_syms(s1
);
2348 if (!s1
->static_link
) {
2349 if (file_type
== TCC_OUTPUT_EXE
) {
2351 /* allow override the dynamic loader */
2352 const char *elfint
= getenv("LD_SO");
2354 elfint
= DEFAULT_ELFINTERP(s1
);
2355 /* add interpreter section only if executable */
2356 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
2357 interp
->sh_addralign
= 1;
2358 ptr
= section_ptr_add(interp
, 1 + strlen(elfint
));
2359 strcpy(ptr
, elfint
);
2362 /* add dynamic symbol table */
2363 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
2365 ".hash", SHF_ALLOC
);
2366 dynstr
= s1
->dynsym
->link
;
2367 /* add dynamic section */
2368 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
2369 SHF_ALLOC
| SHF_WRITE
);
2370 dynamic
->link
= dynstr
;
2371 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
2375 if (file_type
== TCC_OUTPUT_EXE
) {
2376 bind_exe_dynsyms(s1
);
2379 bind_libs_dynsyms(s1
);
2381 /* shared library case: simply export all global symbols */
2382 export_global_syms(s1
);
2385 build_got_entries(s1
);
2390 /* we add a section for symbols */
2391 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
2392 put_elf_str(strsec
, "");
2394 /* Allocate strings for section names */
2395 ret
= alloc_sec_names(s1
, file_type
, strsec
);
2397 #ifndef ELF_OBJ_ONLY
2400 /* add a list of needed dlls */
2401 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2402 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
2403 if (dllref
->level
== 0)
2404 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
2408 put_dt(dynamic
, s1
->enable_new_dtags
? DT_RUNPATH
: DT_RPATH
,
2409 put_elf_str(dynstr
, s1
->rpath
));
2411 if (file_type
== TCC_OUTPUT_DLL
) {
2413 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
2414 /* XXX: currently, since we do not handle PIC code, we
2415 must relocate the readonly segments */
2417 put_dt(dynamic
, DT_TEXTREL
, 0);
2421 put_dt(dynamic
, DT_SYMBOLIC
, 0);
2423 dyninf
.dynamic
= dynamic
;
2424 dyninf
.dynstr
= dynstr
;
2425 /* remember offset and reserve space for 2nd call below */
2426 dyninf
.data_offset
= dynamic
->data_offset
;
2427 fill_dynamic(s1
, &dyninf
);
2428 dynamic
->sh_size
= dynamic
->data_offset
;
2429 dynstr
->sh_size
= dynstr
->data_offset
;
2433 /* compute number of program headers */
2434 if (file_type
== TCC_OUTPUT_OBJ
)
2436 else if (file_type
== TCC_OUTPUT_DLL
)
2438 else if (s1
->static_link
)
2443 /* allocate program segment headers */
2444 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
2446 /* compute number of sections */
2447 shnum
= s1
->nb_sections
;
2449 /* this array is used to reorder sections in the output file */
2450 sec_order
= tcc_malloc(sizeof(int) * shnum
);
2453 /* compute section to program header mapping */
2454 file_offset
= layout_sections(s1
, phdr
, phnum
, interp
, strsec
, &dyninf
,
2457 #ifndef ELF_OBJ_ONLY
2458 /* Fill remaining program header and finalize relocation related to dynamic
2460 if (file_type
!= TCC_OUTPUT_OBJ
) {
2461 fill_unloadable_phdr(phdr
, phnum
, interp
, dynamic
);
2464 dynamic
->data_offset
= dyninf
.data_offset
;
2465 fill_dynamic(s1
, &dyninf
);
2467 /* put in GOT the dynamic section address and relocate PLT */
2468 write32le(s1
->got
->data
, dynamic
->sh_addr
);
2469 if (file_type
== TCC_OUTPUT_EXE
2470 || (RELOCATE_DLLPLT
&& file_type
== TCC_OUTPUT_DLL
))
2473 /* relocate symbols in .dynsym now that final addresses are known */
2474 for_each_elem(s1
->dynsym
, 1, sym
, ElfW(Sym
)) {
2475 if (sym
->st_shndx
!= SHN_UNDEF
&& sym
->st_shndx
< SHN_LORESERVE
) {
2476 /* do symbol relocation */
2477 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
2482 /* if building executable or DLL, then relocate each section
2483 except the GOT which is already relocated */
2484 ret
= final_sections_reloc(s1
);
2487 tidy_section_headers(s1
, sec_order
);
2489 /* Perform relocation to GOT or PLT entries */
2490 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2493 fill_local_got_entries(s1
);
2497 /* Create the ELF file with name 'filename' */
2498 ret
= tcc_write_elf_file(s1
, filename
, phnum
, phdr
, file_offset
, sec_order
);
2499 s1
->nb_sections
= shnum
;
2502 tcc_free(sec_order
);
2507 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2510 #ifdef TCC_TARGET_PE
2511 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2512 ret
= pe_output_file(s
, filename
);
2515 ret
= elf_output_file(s
, filename
);
2519 ssize_t
full_read(int fd
, void *buf
, size_t count
) {
2523 ssize_t num
= read(fd
, cbuf
, count
-rnum
);
2524 if (num
< 0) return num
;
2525 if (num
== 0) return rnum
;
2531 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2535 data
= tcc_malloc(size
);
2536 lseek(fd
, file_offset
, SEEK_SET
);
2537 full_read(fd
, data
, size
);
2541 typedef struct SectionMergeInfo
{
2542 Section
*s
; /* corresponding existing section */
2543 unsigned long offset
; /* offset of the new section in the existing section */
2544 uint8_t new_section
; /* true if section 's' was added */
2545 uint8_t link_once
; /* true if link once section */
2548 ST_FUNC
int tcc_object_type(int fd
, ElfW(Ehdr
) *h
)
2550 int size
= full_read(fd
, h
, sizeof *h
);
2551 if (size
== sizeof *h
&& 0 == memcmp(h
, ELFMAG
, 4)) {
2552 if (h
->e_type
== ET_REL
)
2553 return AFF_BINTYPE_REL
;
2554 if (h
->e_type
== ET_DYN
)
2555 return AFF_BINTYPE_DYN
;
2556 } else if (size
>= 8) {
2557 if (0 == memcmp(h
, ARMAG
, 8))
2558 return AFF_BINTYPE_AR
;
2559 #ifdef TCC_TARGET_COFF
2560 if (((struct filehdr
*)h
)->f_magic
== COFF_C67_MAGIC
)
2561 return AFF_BINTYPE_C67
;
2567 /* load an object file and merge it with current files */
2568 /* XXX: handle correctly stab (debug) info */
2569 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
2570 int fd
, unsigned long file_offset
)
2573 ElfW(Shdr
) *shdr
, *sh
;
2574 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
, seencompressed
;
2575 char *strsec
, *strtab
;
2576 int stab_index
, stabstr_index
;
2577 int *old_to_new_syms
;
2578 char *sh_name
, *name
;
2579 SectionMergeInfo
*sm_table
, *sm
;
2580 ElfW(Sym
) *sym
, *symtab
;
2584 lseek(fd
, file_offset
, SEEK_SET
);
2585 if (tcc_object_type(fd
, &ehdr
) != AFF_BINTYPE_REL
)
2587 /* test CPU specific stuff */
2588 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2589 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2591 tcc_error_noabort("invalid object file");
2595 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2596 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2597 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2599 /* load section names */
2600 sh
= &shdr
[ehdr
.e_shstrndx
];
2601 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2603 /* load symtab and strtab */
2604 old_to_new_syms
= NULL
;
2609 stab_index
= stabstr_index
= 0;
2611 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2613 if (sh
->sh_type
== SHT_SYMTAB
) {
2615 tcc_error_noabort("object must contain only one symtab");
2620 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2621 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2622 sm_table
[i
].s
= symtab_section
;
2624 /* now load strtab */
2625 sh
= &shdr
[sh
->sh_link
];
2626 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2628 if (sh
->sh_flags
& SHF_COMPRESSED
)
2632 /* now examine each section and try to merge its content with the
2634 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2635 /* no need to examine section name strtab */
2636 if (i
== ehdr
.e_shstrndx
)
2639 if (sh
->sh_type
== SHT_RELX
)
2640 sh
= &shdr
[sh
->sh_info
];
2641 /* ignore sections types we do not handle (plus relocs to those) */
2642 if (sh
->sh_type
!= SHT_PROGBITS
&&
2644 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2646 sh
->sh_type
!= SHT_NOBITS
&&
2647 sh
->sh_type
!= SHT_PREINIT_ARRAY
&&
2648 sh
->sh_type
!= SHT_INIT_ARRAY
&&
2649 sh
->sh_type
!= SHT_FINI_ARRAY
&&
2650 strcmp(strsec
+ sh
->sh_name
, ".stabstr")
2654 && !strncmp(strsec
+ sh
->sh_name
, ".debug_", sizeof(".debug_")-1))
2658 sh_name
= strsec
+ sh
->sh_name
;
2659 if (sh
->sh_addralign
< 1)
2660 sh
->sh_addralign
= 1;
2661 /* find corresponding section, if any */
2662 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2663 s
= s1
->sections
[j
];
2664 if (!strcmp(s
->name
, sh_name
)) {
2665 if (!strncmp(sh_name
, ".gnu.linkonce",
2666 sizeof(".gnu.linkonce") - 1)) {
2667 /* if a 'linkonce' section is already present, we
2668 do not add it again. It is a little tricky as
2669 symbols can still be defined in
2671 sm_table
[i
].link_once
= 1;
2675 if (s
== stab_section
)
2677 if (s
== stab_section
->link
)
2683 /* not found: create new section */
2684 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
& ~SHF_GROUP
);
2685 /* take as much info as possible from the section. sh_link and
2686 sh_info will be updated later */
2687 s
->sh_addralign
= sh
->sh_addralign
;
2688 s
->sh_entsize
= sh
->sh_entsize
;
2689 sm_table
[i
].new_section
= 1;
2691 if (sh
->sh_type
!= s
->sh_type
) {
2692 tcc_error_noabort("invalid section type");
2695 /* align start of section */
2696 s
->data_offset
+= -s
->data_offset
& (sh
->sh_addralign
- 1);
2697 if (sh
->sh_addralign
> s
->sh_addralign
)
2698 s
->sh_addralign
= sh
->sh_addralign
;
2699 sm_table
[i
].offset
= s
->data_offset
;
2701 /* concatenate sections */
2703 if (sh
->sh_type
!= SHT_NOBITS
) {
2705 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2706 ptr
= section_ptr_add(s
, size
);
2707 full_read(fd
, ptr
, size
);
2709 s
->data_offset
+= size
;
2714 /* gr relocate stab strings */
2715 if (stab_index
&& stabstr_index
) {
2718 s
= sm_table
[stab_index
].s
;
2719 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2720 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2721 o
= sm_table
[stabstr_index
].offset
;
2729 /* second short pass to update sh_link and sh_info fields of new
2731 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2733 if (!s
|| !sm_table
[i
].new_section
)
2736 if (sh
->sh_link
> 0)
2737 s
->link
= sm_table
[sh
->sh_link
].s
;
2738 if (sh
->sh_type
== SHT_RELX
) {
2739 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2740 /* update backward link */
2741 s1
->sections
[s
->sh_info
]->reloc
= s
;
2745 /* resolve symbols */
2746 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2749 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2750 if (sym
->st_shndx
!= SHN_UNDEF
&&
2751 sym
->st_shndx
< SHN_LORESERVE
) {
2752 sm
= &sm_table
[sym
->st_shndx
];
2753 if (sm
->link_once
) {
2754 /* if a symbol is in a link once section, we use the
2755 already defined symbol. It is very important to get
2756 correct relocations */
2757 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2758 name
= strtab
+ sym
->st_name
;
2759 sym_index
= find_elf_sym(symtab_section
, name
);
2761 old_to_new_syms
[i
] = sym_index
;
2765 /* if no corresponding section added, no need to add symbol */
2768 /* convert section number */
2769 sym
->st_shndx
= sm
->s
->sh_num
;
2771 sym
->st_value
+= sm
->offset
;
2774 name
= strtab
+ sym
->st_name
;
2775 sym_index
= set_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2776 sym
->st_info
, sym
->st_other
,
2777 sym
->st_shndx
, name
);
2778 old_to_new_syms
[i
] = sym_index
;
2781 /* third pass to patch relocation entries */
2782 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2787 offset
= sm_table
[i
].offset
;
2788 switch(s
->sh_type
) {
2790 /* take relocation offset information */
2791 offseti
= sm_table
[sh
->sh_info
].offset
;
2792 for_each_elem(s
, (offset
/ sizeof(*rel
)), rel
, ElfW_Rel
) {
2795 /* convert symbol index */
2796 type
= ELFW(R_TYPE
)(rel
->r_info
);
2797 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2798 /* NOTE: only one symtab assumed */
2799 if (sym_index
>= nb_syms
)
2801 sym_index
= old_to_new_syms
[sym_index
];
2802 /* ignore link_once in rel section. */
2803 if (!sym_index
&& !sm_table
[sh
->sh_info
].link_once
2804 #ifdef TCC_TARGET_ARM
2805 && type
!= R_ARM_V4BX
2806 #elif defined TCC_TARGET_RISCV64
2807 && type
!= R_RISCV_ALIGN
2808 && type
!= R_RISCV_RELAX
2812 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2813 i
, strsec
+ sh
->sh_name
, (int)rel
->r_offset
);
2816 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2817 /* offset the relocation offset */
2818 rel
->r_offset
+= offseti
;
2819 #ifdef TCC_TARGET_ARM
2820 /* Jumps and branches from a Thumb code to a PLT entry need
2821 special handling since PLT entries are ARM code.
2822 Unconditional bl instructions referencing PLT entries are
2823 handled by converting these instructions into blx
2824 instructions. Other case of instructions referencing a PLT
2825 entry require to add a Thumb stub before the PLT entry to
2826 switch to ARM mode. We set bit plt_thumb_stub of the
2827 attribute of a symbol to indicate such a case. */
2828 if (type
== R_ARM_THM_JUMP24
)
2829 get_sym_attr(s1
, sym_index
, 1)->plt_thumb_stub
= 1;
2842 tcc_free(old_to_new_syms
);
2849 typedef struct ArchiveHeader
{
2850 char ar_name
[16]; /* name of this member */
2851 char ar_date
[12]; /* file mtime */
2852 char ar_uid
[6]; /* owner uid; printed as decimal */
2853 char ar_gid
[6]; /* owner gid; printed as decimal */
2854 char ar_mode
[8]; /* file mode, printed as octal */
2855 char ar_size
[10]; /* file size, printed as decimal */
2856 char ar_fmag
[2]; /* should contain ARFMAG */
2859 #define ARFMAG "`\n"
2861 static unsigned long long get_be(const uint8_t *b
, int n
)
2863 unsigned long long ret
= 0;
2865 ret
= (ret
<< 8) | *b
++, --n
;
2869 static int read_ar_header(int fd
, int offset
, ArchiveHeader
*hdr
)
2873 lseek(fd
, offset
, SEEK_SET
);
2874 len
= full_read(fd
, hdr
, sizeof(ArchiveHeader
));
2875 if (len
!= sizeof(ArchiveHeader
))
2876 return len
? -1 : 0;
2878 for (e
= p
+ sizeof hdr
->ar_name
; e
> p
&& e
[-1] == ' ';)
2881 hdr
->ar_size
[sizeof hdr
->ar_size
-1] = 0;
2885 /* load only the objects which resolve undefined symbols */
2886 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
, int entrysize
)
2888 int i
, bound
, nsyms
, sym_index
, len
, ret
= -1;
2889 unsigned long long off
;
2891 const char *ar_names
, *p
;
2892 const uint8_t *ar_index
;
2896 data
= tcc_malloc(size
);
2897 if (full_read(fd
, data
, size
) != size
)
2899 nsyms
= get_be(data
, entrysize
);
2900 ar_index
= data
+ entrysize
;
2901 ar_names
= (char *) ar_index
+ nsyms
* entrysize
;
2905 for (p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2906 Section
*s
= symtab_section
;
2907 sym_index
= find_elf_sym(s
, p
);
2910 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
2911 if(sym
->st_shndx
!= SHN_UNDEF
)
2913 off
= get_be(ar_index
+ i
* entrysize
, entrysize
);
2914 len
= read_ar_header(fd
, off
, &hdr
);
2915 if (len
<= 0 || memcmp(hdr
.ar_fmag
, ARFMAG
, 2)) {
2916 tcc_error_noabort("invalid archive");
2920 if (s1
->verbose
== 2)
2921 printf(" -> %s\n", hdr
.ar_name
);
2922 if (tcc_load_object_file(s1
, fd
, off
) < 0)
2933 /* load a '.a' file */
2934 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
, int alacarte
)
2937 /* char magic[8]; */
2939 unsigned long file_offset
;
2942 /* skip magic which was already checked */
2943 /* full_read(fd, magic, sizeof(magic)); */
2944 file_offset
= sizeof ARMAG
- 1;
2947 len
= read_ar_header(fd
, file_offset
, &hdr
);
2951 tcc_error_noabort("invalid archive");
2955 size
= strtol(hdr
.ar_size
, NULL
, 0);
2957 size
= (size
+ 1) & ~1;
2959 /* coff symbol table : we handle it */
2960 if (!strcmp(hdr
.ar_name
, "/"))
2961 return tcc_load_alacarte(s1
, fd
, size
, 4);
2962 if (!strcmp(hdr
.ar_name
, "/SYM64/"))
2963 return tcc_load_alacarte(s1
, fd
, size
, 8);
2964 } else if (tcc_object_type(fd
, &ehdr
) == AFF_BINTYPE_REL
) {
2965 if (s1
->verbose
== 2)
2966 printf(" -> %s\n", hdr
.ar_name
);
2967 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2970 file_offset
+= size
;
2974 #ifndef ELF_OBJ_ONLY
2975 /* Set LV[I] to the global index of sym-version (LIB,VERSION). Maybe resizes
2976 LV, maybe create a new entry for (LIB,VERSION). */
2977 static void set_ver_to_ver(TCCState
*s1
, int *n
, int **lv
, int i
, char *lib
, char *version
)
2980 *lv
= tcc_realloc(*lv
, (*n
+ 1) * sizeof(**lv
));
2983 if ((*lv
)[i
] == -1) {
2984 int v
, prev_same_lib
= -1;
2985 for (v
= 0; v
< nb_sym_versions
; v
++) {
2986 if (strcmp(sym_versions
[v
].lib
, lib
))
2989 if (!strcmp(sym_versions
[v
].version
, version
))
2992 if (v
== nb_sym_versions
) {
2993 sym_versions
= tcc_realloc (sym_versions
,
2994 (v
+ 1) * sizeof(*sym_versions
));
2995 sym_versions
[v
].lib
= tcc_strdup(lib
);
2996 sym_versions
[v
].version
= tcc_strdup(version
);
2997 sym_versions
[v
].out_index
= 0;
2998 sym_versions
[v
].prev_same_lib
= prev_same_lib
;
3005 /* Associates symbol SYM_INDEX (in dynsymtab) with sym-version index
3008 set_sym_version(TCCState
*s1
, int sym_index
, int verndx
)
3010 if (sym_index
>= nb_sym_to_version
) {
3011 int newelems
= sym_index
? sym_index
* 2 : 1;
3012 sym_to_version
= tcc_realloc(sym_to_version
,
3013 newelems
* sizeof(*sym_to_version
));
3014 memset(sym_to_version
+ nb_sym_to_version
, -1,
3015 (newelems
- nb_sym_to_version
) * sizeof(*sym_to_version
));
3016 nb_sym_to_version
= newelems
;
3018 if (sym_to_version
[sym_index
] < 0)
3019 sym_to_version
[sym_index
] = verndx
;
3022 struct versym_info
{
3024 ElfW(Verdef
) *verdef
;
3025 ElfW(Verneed
) *verneed
;
3027 int nb_local_ver
, *local_ver
;
3031 static void store_version(TCCState
*s1
, struct versym_info
*v
, char *dynstr
)
3033 char *lib
, *version
;
3037 #define DEBUG_VERSION 0
3039 if (v
->versym
&& v
->verdef
) {
3040 ElfW(Verdef
) *vdef
= v
->verdef
;
3043 ElfW(Verdaux
) *verdaux
=
3044 (ElfW(Verdaux
) *) (((char *) vdef
) + vdef
->vd_aux
);
3047 printf ("verdef: version:%u flags:%u index:%u, hash:%u\n",
3048 vdef
->vd_version
, vdef
->vd_flags
, vdef
->vd_ndx
,
3052 version
= dynstr
+ verdaux
->vda_name
;
3057 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vdef
->vd_ndx
,
3060 printf (" verdaux(%u): %s\n", vdef
->vd_ndx
, version
);
3063 next
= vdef
->vd_next
;
3064 vdef
= (ElfW(Verdef
) *) (((char *) vdef
) + next
);
3067 if (v
->versym
&& v
->verneed
) {
3068 ElfW(Verneed
) *vneed
= v
->verneed
;
3070 ElfW(Vernaux
) *vernaux
=
3071 (ElfW(Vernaux
) *) (((char *) vneed
) + vneed
->vn_aux
);
3073 lib
= dynstr
+ vneed
->vn_file
;
3075 printf ("verneed: %u %s\n", vneed
->vn_version
, lib
);
3077 for (i
= 0; i
< vneed
->vn_cnt
; i
++) {
3078 if ((vernaux
->vna_other
& 0x8000) == 0) { /* hidden */
3079 version
= dynstr
+ vernaux
->vna_name
;
3080 set_ver_to_ver(s1
, &v
->nb_local_ver
, &v
->local_ver
, vernaux
->vna_other
,
3083 printf (" vernaux(%u): %u %u %s\n",
3084 vernaux
->vna_other
, vernaux
->vna_hash
,
3085 vernaux
->vna_flags
, version
);
3088 vernaux
= (ElfW(Vernaux
) *) (((char *) vernaux
) + vernaux
->vna_next
);
3090 next
= vneed
->vn_next
;
3091 vneed
= (ElfW(Verneed
) *) (((char *) vneed
) + next
);
3096 for (i
= 0; i
< v
->nb_local_ver
; i
++) {
3097 if (v
->local_ver
[i
] > 0) {
3098 printf ("%d: lib: %s, version %s\n",
3099 i
, sym_versions
[v
->local_ver
[i
]].lib
,
3100 sym_versions
[v
->local_ver
[i
]].version
);
3106 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
3107 is referenced by the user (so it should be added as DT_NEEDED in
3108 the generated ELF file) */
3109 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
3112 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
3113 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
3114 ElfW(Sym
) *sym
, *dynsym
;
3115 ElfW(Dyn
) *dt
, *dynamic
;
3119 const char *name
, *soname
;
3120 DLLReference
*dllref
;
3121 struct versym_info v
;
3123 full_read(fd
, &ehdr
, sizeof(ehdr
));
3125 /* test CPU specific stuff */
3126 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
3127 ehdr
.e_machine
!= EM_TCC_TARGET
) {
3128 tcc_error_noabort("bad architecture");
3133 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
3135 /* load dynamic section and dynamic symbols */
3139 dynsym
= NULL
; /* avoid warning */
3140 dynstr
= NULL
; /* avoid warning */
3141 memset(&v
, 0, sizeof v
);
3143 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
3144 switch(sh
->sh_type
) {
3146 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
3147 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3150 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
3151 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3152 sh1
= &shdr
[sh
->sh_link
];
3153 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
3155 case SHT_GNU_verdef
:
3156 v
.verdef
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3158 case SHT_GNU_verneed
:
3159 v
.verneed
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3161 case SHT_GNU_versym
:
3162 v
.nb_versyms
= sh
->sh_size
/ sizeof(ElfW(Half
));
3163 v
.versym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
3170 /* compute the real library name */
3171 soname
= tcc_basename(filename
);
3173 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3174 if (dt
->d_tag
== DT_SONAME
) {
3175 soname
= dynstr
+ dt
->d_un
.d_val
;
3179 /* if the dll is already loaded, do not load it */
3180 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
3181 dllref
= s1
->loaded_dlls
[i
];
3182 if (!strcmp(soname
, dllref
->name
)) {
3183 /* but update level if needed */
3184 if (level
< dllref
->level
)
3185 dllref
->level
= level
;
3191 if (v
.nb_versyms
!= nb_syms
)
3192 tcc_free (v
.versym
), v
.versym
= NULL
;
3194 store_version(s1
, &v
, dynstr
);
3196 /* add the dll and its level */
3197 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
3198 dllref
->level
= level
;
3199 strcpy(dllref
->name
, soname
);
3200 dynarray_add(&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
3202 /* add dynamic symbols in dynsym_section */
3203 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
3204 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
3205 if (sym_bind
== STB_LOCAL
)
3207 name
= dynstr
+ sym
->st_name
;
3208 sym_index
= set_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
3209 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
3211 ElfW(Half
) vsym
= v
.versym
[i
];
3212 if ((vsym
& 0x8000) == 0 && vsym
> 0 && vsym
< v
.nb_local_ver
)
3213 set_sym_version(s1
, sym_index
, v
.local_ver
[vsym
]);
3217 /* load all referenced DLLs */
3218 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
3221 name
= dynstr
+ dt
->d_un
.d_val
;
3222 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
3223 dllref
= s1
->loaded_dlls
[j
];
3224 if (!strcmp(name
, dllref
->name
))
3225 goto already_loaded
;
3227 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
3228 tcc_error_noabort("referenced dll '%s' not found", name
);
3242 tcc_free(v
.local_ver
);
3244 tcc_free(v
.verneed
);
3249 #define LD_TOK_NAME 256
3250 #define LD_TOK_EOF (-1)
3252 static int ld_inp(TCCState
*s1
)
3260 if (1 == read(s1
->fd
, &b
, 1))
3265 /* return next ld script token */
3266 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
3283 if (ch
== '*') { /* comment */
3284 for (d
= 0;; d
= ch
) {
3286 if (ch
== CH_EOF
|| (ch
== '/' && d
== '*'))
3297 /* case 'a' ... 'z': */
3324 /* case 'A' ... 'z': */
3358 if (!((ch
>= 'a' && ch
<= 'z') ||
3359 (ch
>= 'A' && ch
<= 'Z') ||
3360 (ch
>= '0' && ch
<= '9') ||
3361 strchr("/.-_+=$:\\,~", ch
)))
3363 if ((q
- name
) < name_size
- 1) {
3382 static int ld_add_file(TCCState
*s1
, const char filename
[])
3384 if (filename
[0] == '/') {
3385 if (CONFIG_SYSROOT
[0] == '\0'
3386 && tcc_add_file_internal(s1
, filename
, AFF_TYPE_BIN
) == 0)
3388 filename
= tcc_basename(filename
);
3390 return tcc_add_dll(s1
, filename
, 0);
3393 static int ld_add_file_list(TCCState
*s1
, const char *cmd
, int as_needed
)
3395 char filename
[1024], libname
[1024];
3396 int t
, group
, nblibs
= 0, ret
= 0;
3399 group
= !strcmp(cmd
, "GROUP");
3401 s1
->new_undef_sym
= 0;
3402 t
= ld_next(s1
, filename
, sizeof(filename
));
3404 tcc_error_noabort("( expected");
3406 goto lib_parse_error
;
3408 t
= ld_next(s1
, filename
, sizeof(filename
));
3411 if (t
== LD_TOK_EOF
) {
3412 tcc_error_noabort("unexpected end of file");
3414 goto lib_parse_error
;
3415 } else if (t
== ')') {
3417 } else if (t
== '-') {
3418 t
= ld_next(s1
, filename
, sizeof(filename
));
3419 if ((t
!= LD_TOK_NAME
) || (filename
[0] != 'l')) {
3420 tcc_error_noabort("library name expected");
3422 goto lib_parse_error
;
3424 pstrcpy(libname
, sizeof libname
, &filename
[1]);
3425 if (s1
->static_link
) {
3426 snprintf(filename
, sizeof filename
, "lib%s.a", libname
);
3428 snprintf(filename
, sizeof filename
, "lib%s.so", libname
);
3430 } else if (t
!= LD_TOK_NAME
) {
3431 tcc_error_noabort("filename expected");
3433 goto lib_parse_error
;
3435 if (!strcmp(filename
, "AS_NEEDED")) {
3436 ret
= ld_add_file_list(s1
, cmd
, 1);
3438 goto lib_parse_error
;
3440 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3442 ret
= ld_add_file(s1
, filename
);
3444 goto lib_parse_error
;
3446 /* Add the filename *and* the libname to avoid future conversions */
3447 dynarray_add(&libs
, &nblibs
, tcc_strdup(filename
));
3448 if (libname
[0] != '\0')
3449 dynarray_add(&libs
, &nblibs
, tcc_strdup(libname
));
3453 t
= ld_next(s1
, filename
, sizeof(filename
));
3455 t
= ld_next(s1
, filename
, sizeof(filename
));
3458 if (group
&& !as_needed
) {
3459 while (s1
->new_undef_sym
) {
3461 s1
->new_undef_sym
= 0;
3462 for (i
= 0; i
< nblibs
; i
++)
3463 ld_add_file(s1
, libs
[i
]);
3467 dynarray_reset(&libs
, &nblibs
);
3471 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3473 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
, int fd
)
3476 char filename
[1024];
3482 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3483 if (t
== LD_TOK_EOF
)
3485 else if (t
!= LD_TOK_NAME
)
3487 if (!strcmp(cmd
, "INPUT") ||
3488 !strcmp(cmd
, "GROUP")) {
3489 ret
= ld_add_file_list(s1
, cmd
, 0);
3492 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
3493 !strcmp(cmd
, "TARGET")) {
3494 /* ignore some commands */
3495 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3497 tcc_error_noabort("( expected");
3501 t
= ld_next(s1
, filename
, sizeof(filename
));
3502 if (t
== LD_TOK_EOF
) {
3503 tcc_error_noabort("unexpected end of file");
3505 } else if (t
== ')') {
3515 #endif /* !ELF_OBJ_ONLY */