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 static int new_undef_sym
= 0; /* Is there a new undefined sym since last new_undef_sym() */
25 ST_FUNC
int put_elf_str(Section
*s
, const char *sym
)
30 len
= strlen(sym
) + 1;
31 offset
= s
->data_offset
;
32 ptr
= section_ptr_add(s
, len
);
33 memcpy(ptr
, sym
, len
);
37 /* elf symbol hashing function */
38 static unsigned long elf_hash(const unsigned char *name
)
40 unsigned long h
= 0, g
;
43 h
= (h
<< 4) + *name
++;
52 /* rebuild hash table of section s */
53 /* NOTE: we do factorize the hash table code to go faster */
54 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
57 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
60 strtab
= s
->link
->data
;
61 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
63 s
->hash
->data_offset
= 0;
64 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
69 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
70 ptr
+= nb_buckets
+ 1;
72 sym
= (ElfW(Sym
) *)s
->data
+ 1;
73 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
74 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
75 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
86 /* return the symbol number */
87 ST_FUNC
int put_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
88 int info
, int other
, int shndx
, const char *name
)
90 int name_offset
, sym_index
;
95 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
97 name_offset
= put_elf_str(s
->link
, name
);
100 /* XXX: endianness */
101 sym
->st_name
= name_offset
;
102 sym
->st_value
= value
;
105 sym
->st_other
= other
;
106 sym
->st_shndx
= shndx
;
107 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
111 ptr
= section_ptr_add(hs
, sizeof(int));
112 base
= (int *)hs
->data
;
113 /* only add global or weak symbols */
114 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
115 /* add another hashing entry */
117 h
= elf_hash(name
) % nbuckets
;
119 base
[2 + h
] = sym_index
;
121 /* we resize the hash table */
122 hs
->nb_hashed_syms
++;
123 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
124 rebuild_hash(s
, 2 * nbuckets
);
134 /* find global ELF symbol 'name' and return its index. Return 0 if not
136 ST_FUNC
int find_elf_sym(Section
*s
, const char *name
)
140 int nbuckets
, sym_index
, h
;
146 nbuckets
= ((int *)hs
->data
)[0];
147 h
= elf_hash(name
) % nbuckets
;
148 sym_index
= ((int *)hs
->data
)[2 + h
];
149 while (sym_index
!= 0) {
150 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
151 name1
= s
->link
->data
+ sym
->st_name
;
152 if (!strcmp(name
, name1
))
154 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
159 /* return elf symbol value, signal error if 'err' is nonzero */
160 ST_FUNC addr_t
get_elf_sym_addr(TCCState
*s
, const char *name
, int err
)
165 sym_index
= find_elf_sym(s
->symtab
, name
);
166 sym
= &((ElfW(Sym
) *)s
->symtab
->data
)[sym_index
];
167 if (!sym_index
|| sym
->st_shndx
== SHN_UNDEF
) {
169 tcc_error("%s not defined", name
);
172 return sym
->st_value
;
175 /* return elf symbol value */
176 LIBTCCAPI
void *tcc_get_symbol(TCCState
*s
, const char *name
)
178 return (void*)(uintptr_t)get_elf_sym_addr(s
, name
, 0);
182 /* return elf symbol value or error */
183 ST_FUNC
void* tcc_get_symbol_err(TCCState
*s
, const char *name
)
185 return (void*)get_elf_sym_addr(s
, name
, 1);
189 /* add an elf symbol : check if it is already defined and patch
190 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
191 ST_FUNC
int add_elf_sym(Section
*s
, addr_t value
, unsigned long size
,
192 int info
, int other
, int sh_num
, const char *name
)
195 int sym_bind
, sym_index
, sym_type
, esym_bind
;
196 unsigned char sym_vis
, esym_vis
, new_vis
;
198 sym_bind
= ELFW(ST_BIND
)(info
);
199 sym_type
= ELFW(ST_TYPE
)(info
);
200 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
202 if (sym_bind
!= STB_LOCAL
) {
203 /* we search global or weak symbols */
204 sym_index
= find_elf_sym(s
, name
);
207 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
208 if (esym
->st_shndx
!= SHN_UNDEF
) {
209 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
210 /* propagate the most constraining visibility */
211 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
212 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
213 if (esym_vis
== STV_DEFAULT
) {
215 } else if (sym_vis
== STV_DEFAULT
) {
218 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
220 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
222 other
= esym
->st_other
; /* in case we have to patch esym */
223 if (sh_num
== SHN_UNDEF
) {
224 /* ignore adding of undefined symbol if the
225 corresponding symbol is already defined */
226 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
227 /* global overrides weak, so patch */
229 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
230 /* weak is ignored if already global */
231 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_WEAK
) {
232 /* keep first-found weak definition, ignore subsequents */
233 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
234 /* ignore hidden symbols after */
235 } else if (esym
->st_shndx
== SHN_COMMON
236 && (sh_num
< SHN_LORESERVE
|| sh_num
== SHN_COMMON
)) {
237 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
238 No idea if this is the correct solution ... */
240 } else if (s
== tcc_state
->dynsymtab_section
) {
241 /* we accept that two DLL define the same symbol */
244 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
245 sym_bind
, sh_num
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
247 tcc_error_noabort("'%s' defined twice", name
);
251 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
252 esym
->st_shndx
= sh_num
;
254 esym
->st_value
= value
;
255 esym
->st_size
= size
;
256 esym
->st_other
= other
;
260 sym_index
= put_elf_sym(s
, value
, size
,
261 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
268 ST_FUNC
void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
269 int type
, int symbol
)
277 /* if no relocation section, create it */
278 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
279 /* if the symtab is allocated, then we consider the relocation
281 sr
= new_section(tcc_state
, buf
, SHT_RELX
, symtab
->sh_flags
);
282 sr
->sh_entsize
= sizeof(ElfW_Rel
);
284 sr
->sh_info
= s
->sh_num
;
287 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
288 rel
->r_offset
= offset
;
289 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
290 #ifdef TCC_TARGET_X86_64
295 /* put stab debug information */
297 ST_FUNC
void put_stabs(const char *str
, int type
, int other
, int desc
,
302 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
304 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
309 sym
->n_other
= other
;
311 sym
->n_value
= value
;
314 ST_FUNC
void put_stabs_r(const char *str
, int type
, int other
, int desc
,
315 unsigned long value
, Section
*sec
, int sym_index
)
317 put_stabs(str
, type
, other
, desc
, value
);
318 put_elf_reloc(symtab_section
, stab_section
,
319 stab_section
->data_offset
- sizeof(unsigned int),
320 R_DATA_32
, sym_index
);
323 ST_FUNC
void put_stabn(int type
, int other
, int desc
, int value
)
325 put_stabs(NULL
, type
, other
, desc
, value
);
328 ST_FUNC
void put_stabd(int type
, int other
, int desc
)
330 put_stabs(NULL
, type
, other
, desc
, 0);
333 /* In an ELF file symbol table, the local symbols must appear below
334 the global and weak ones. Since TCC cannot sort it while generating
335 the code, we must do it after. All the relocation tables are also
336 modified to take into account the symbol table sorting */
337 static void sort_syms(TCCState
*s1
, Section
*s
)
339 int *old_to_new_syms
;
343 ElfW_Rel
*rel
, *rel_end
;
347 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
348 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
349 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
351 /* first pass for local symbols */
352 p
= (ElfW(Sym
) *)s
->data
;
354 for(i
= 0; i
< nb_syms
; i
++) {
355 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
356 old_to_new_syms
[i
] = q
- new_syms
;
361 /* save the number of local symbols in section header */
362 s
->sh_info
= q
- new_syms
;
364 /* then second pass for non local symbols */
365 p
= (ElfW(Sym
) *)s
->data
;
366 for(i
= 0; i
< nb_syms
; i
++) {
367 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
368 old_to_new_syms
[i
] = q
- new_syms
;
374 /* we copy the new symbols to the old */
375 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
378 /* now we modify all the relocations */
379 for(i
= 1; i
< s1
->nb_sections
; i
++) {
380 sr
= s1
->sections
[i
];
381 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
382 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
383 for(rel
= (ElfW_Rel
*)sr
->data
;
386 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
387 type
= ELFW(R_TYPE
)(rel
->r_info
);
388 sym_index
= old_to_new_syms
[sym_index
];
389 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
394 tcc_free(old_to_new_syms
);
397 /* relocate common symbols in the .bss section */
398 ST_FUNC
void relocate_common_syms(void)
400 ElfW(Sym
) *sym
, *sym_end
;
401 unsigned long offset
, align
;
403 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
404 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
407 if (sym
->st_shndx
== SHN_COMMON
) {
409 align
= sym
->st_value
;
410 offset
= bss_section
->data_offset
;
411 offset
= (offset
+ align
- 1) & -align
;
412 sym
->st_value
= offset
;
413 sym
->st_shndx
= bss_section
->sh_num
;
414 offset
+= sym
->st_size
;
415 bss_section
->data_offset
= offset
;
420 /* relocate symbol table, resolve undefined symbols if do_resolve is
421 true and output error if undefined symbol. */
422 ST_FUNC
void relocate_syms(TCCState
*s1
, int do_resolve
)
424 ElfW(Sym
) *sym
, *esym
, *sym_end
;
425 int sym_bind
, sh_num
, sym_index
;
428 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
429 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
432 sh_num
= sym
->st_shndx
;
433 if (sh_num
== SHN_UNDEF
) {
434 name
= strtab_section
->data
+ sym
->st_name
;
436 #if defined TCC_IS_NATIVE && !defined _WIN32
438 name
= symtab_section
->link
->data
+ sym
->st_name
;
439 addr
= resolve_sym(s1
, name
);
441 sym
->st_value
= (addr_t
)addr
;
445 } else if (s1
->dynsym
) {
446 /* if dynamic symbol exist, then use it */
447 sym_index
= find_elf_sym(s1
->dynsym
, name
);
449 esym
= &((ElfW(Sym
) *)s1
->dynsym
->data
)[sym_index
];
450 sym
->st_value
= esym
->st_value
;
454 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
456 if (!strcmp(name
, "_fp_hw"))
458 /* only weak symbols are accepted to be undefined. Their
460 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
461 if (sym_bind
== STB_WEAK
) {
464 tcc_error_noabort("undefined symbol '%s'", name
);
466 } else if (sh_num
< SHN_LORESERVE
) {
467 /* add section base */
468 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
474 #ifdef TCC_HAS_RUNTIME_PLTGOT
475 #ifdef TCC_TARGET_X86_64
476 #define JMP_TABLE_ENTRY_SIZE 14
477 static addr_t
add_jmp_table(TCCState
*s1
, addr_t val
)
479 char *p
= s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
;
480 s1
->runtime_plt_and_got_offset
+= JMP_TABLE_ENTRY_SIZE
;
485 *(addr_t
*)(p
+ 6) = val
;
489 static addr_t
add_got_table(TCCState
*s1
, addr_t val
)
491 addr_t
*p
= (addr_t
*)(s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
);
492 s1
->runtime_plt_and_got_offset
+= sizeof(addr_t
);
496 #elif defined TCC_TARGET_ARM
497 #define JMP_TABLE_ENTRY_SIZE 8
498 static addr_t
add_jmp_table(TCCState
*s1
, int val
)
500 uint32_t *p
= (uint32_t *)(s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
);
501 s1
->runtime_plt_and_got_offset
+= JMP_TABLE_ENTRY_SIZE
;
502 /* ldr pc, [pc, #-4] */
508 #endif /* def TCC_HAS_RUNTIME_PLTGOT */
510 /* relocate a given section (CPU dependent) */
511 ST_FUNC
void relocate_section(TCCState
*s1
, Section
*s
)
514 ElfW_Rel
*rel
, *rel_end
, *qrel
;
519 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
524 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
525 qrel
= (ElfW_Rel
*)sr
->data
;
529 ptr
= s
->data
+ rel
->r_offset
;
531 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
532 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
534 #ifdef TCC_TARGET_X86_64
535 val
+= rel
->r_addend
;
537 type
= ELFW(R_TYPE
)(rel
->r_info
);
538 addr
= s
->sh_addr
+ rel
->r_offset
;
542 #if defined(TCC_TARGET_I386)
544 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
545 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
546 qrel
->r_offset
= rel
->r_offset
;
548 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_32
);
552 qrel
->r_info
= ELFW(R_INFO
)(0, R_386_RELATIVE
);
559 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
561 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
563 qrel
->r_offset
= rel
->r_offset
;
564 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_PC32
);
569 *(int *)ptr
+= val
- addr
;
572 *(int *)ptr
+= val
- addr
;
579 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
582 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
585 /* we load the got offset */
586 *(int *)ptr
+= s1
->sym_attrs
[sym_index
].got_offset
;
589 if (s1
->output_format
!= TCC_OUTPUT_FORMAT_BINARY
) {
591 tcc_error("can only produce 16-bit binary files");
593 *(short *)ptr
+= val
;
596 if (s1
->output_format
!= TCC_OUTPUT_FORMAT_BINARY
)
598 *(short *)ptr
+= val
- addr
;
600 #elif defined(TCC_TARGET_ARM)
606 int x
, is_thumb
, is_call
, h
, blx_avail
;
607 x
= (*(int *)ptr
)&0xffffff;
608 (*(int *)ptr
) &= 0xff000000;
612 blx_avail
= (TCC_ARM_VERSION
>= 5);
614 is_call
= (type
== R_ARM_CALL
);
617 #ifdef TCC_HAS_RUNTIME_PLTGOT
618 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
619 if ((x
& 3) || x
>= 0x2000000 || x
< -0x2000000)
620 if (!(x
& 3) || !blx_avail
|| !is_call
) {
621 x
+= add_jmp_table(s1
, val
) - val
; /* add veneer */
622 is_thumb
= 0; /* Veneer uses ARM instructions */
626 if ((x
& 3) || x
>= 0x2000000 || x
< -0x2000000)
627 if (!(x
& 3) || !blx_avail
|| !is_call
)
628 tcc_error("can't relocate value at %x",addr
);
631 /* Only reached if blx is avail and it is a call */
634 (*(int *)ptr
) = 0xfa << 24; /* bl -> blx */
639 /* Since these relocations only concern Thumb-2 and blx instruction was
640 introduced before Thumb-2, we can assume blx is available and not
643 case R_ARM_THM_JUMP24
:
645 int x
, hi
, lo
, s
, j1
, j2
, i1
, i2
, imm10
, imm11
;
646 int to_thumb
, is_call
, to_plt
, blx_bit
= 1 << 12;
650 if (sym
->st_shndx
== SHN_UNDEF
&&
651 ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
)
654 /* Get initial offset */
655 hi
= (*(uint16_t *)ptr
);
656 lo
= (*(uint16_t *)(ptr
+2));
664 x
= (s
<< 24) | (i1
<< 23) | (i2
<< 22) |
665 (imm10
<< 12) | (imm11
<< 1);
669 /* Relocation infos */
672 to_plt
= (val
>= plt
->sh_addr
) &&
673 (val
< plt
->sh_addr
+ plt
->data_offset
);
674 is_call
= (type
== R_ARM_THM_CALL
);
676 /* Compute final offset */
677 if (to_plt
&& !is_call
) /* Point to 1st instr of Thumb stub */
680 if (!to_thumb
&& is_call
) {
681 blx_bit
= 0; /* bl -> blx */
682 x
= (x
+ 3) & -4; /* Compute offset from aligned PC */
685 /* Check that relocation is possible
686 * offset must not be out of range
687 * if target is to be entered in arm mode:
689 - instruction must be a call (bl) or a jump to PLT */
690 if (!to_thumb
|| x
>= 0x1000000 || x
< -0x1000000)
691 if (to_thumb
|| (val
& 2) || (!is_call
&& !to_plt
))
692 tcc_error("can't relocate value at %x",addr
);
694 /* Compute and store final offset */
700 imm10
= (x
>> 12) & 0x3ff;
701 imm11
= (x
>> 1) & 0x7ff;
702 (*(uint16_t *)ptr
) = (uint16_t) ((hi
& 0xf800) |
704 (*(uint16_t *)(ptr
+2)) = (uint16_t) ((lo
& 0xc000) |
705 (j1
<< 13) | blx_bit
| (j2
<< 11) |
710 case R_ARM_MOVW_ABS_NC
:
713 if (type
== R_ARM_MOVT_ABS
)
716 imm4
= (val
>> 12) & 0xf;
717 x
= (imm4
<< 16) | imm12
;
718 if (type
== R_ARM_THM_MOVT_ABS
)
724 case R_ARM_THM_MOVT_ABS
:
725 case R_ARM_THM_MOVW_ABS_NC
:
727 int x
, i
, imm4
, imm3
, imm8
;
728 if (type
== R_ARM_THM_MOVT_ABS
)
731 imm3
= (val
>> 8) & 0x7;
733 imm4
= (val
>> 12) & 0xf;
734 x
= (imm3
<< 28) | (imm8
<< 16) | (i
<< 10) | imm4
;
735 if (type
== R_ARM_THM_MOVT_ABS
)
744 x
= (*(int *)ptr
) & 0x7fffffff;
745 (*(int *)ptr
) &= 0x80000000;
748 if((x
^(x
>>1))&0x40000000)
749 tcc_error("can't relocate value at %x",addr
);
750 (*(int *)ptr
) |= x
& 0x7fffffff;
756 *(int *)ptr
+= val
- addr
;
758 case R_ARM_BASE_PREL
:
759 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
762 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
765 /* we load the got offset */
766 *(int *)ptr
+= s1
->sym_attrs
[sym_index
].got_offset
;
771 /* trade Thumb support for ARMv4 support */
772 if ((0x0ffffff0 & *(int*)ptr
) == 0x012FFF10)
773 *(int*)ptr
^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */
776 fprintf(stderr
,"FIXME: handle reloc type %x at %x [%p] to %x\n",
777 type
, (unsigned)addr
, ptr
, (unsigned)val
);
779 #elif defined(TCC_TARGET_C67)
787 /* put the low 16 bits of the absolute address */
788 // add to what is already there
790 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
791 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
793 //patch both at once - assumes always in pairs Low - High
795 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
796 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
802 fprintf(stderr
,"FIXME: handle reloc type %x at %x [%p] to %x\n",
803 type
, (unsigned)addr
, ptr
, (unsigned)val
);
805 #elif defined(TCC_TARGET_X86_64)
807 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
808 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
809 qrel
->r_addend
= *(long long *)ptr
+ val
;
812 *(long long *)ptr
+= val
;
816 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
817 /* XXX: this logic may depend on TCC's codegen
818 now TCC uses R_X86_64_32 even for a 64bit pointer */
819 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
820 qrel
->r_addend
= *(int *)ptr
+ val
;
827 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
829 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
831 qrel
->r_offset
= rel
->r_offset
;
832 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_X86_64_PC32
);
833 qrel
->r_addend
= *(int *)ptr
;
839 case R_X86_64_PLT32
: {
841 diff
= (long long)val
- addr
;
842 if (diff
<= -2147483647 || diff
> 2147483647) {
843 #ifdef TCC_HAS_RUNTIME_PLTGOT
844 /* XXX: naive support for over 32bit jump */
845 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
846 val
= (add_jmp_table(s1
, val
- rel
->r_addend
) +
851 if (diff
<= -2147483647 || diff
> 2147483647) {
852 tcc_error("internal error: relocation failed");
858 case R_X86_64_GLOB_DAT
:
859 case R_X86_64_JUMP_SLOT
:
860 /* They don't need addend */
861 *(int *)ptr
= val
- rel
->r_addend
;
863 case R_X86_64_GOTPCREL
:
864 #ifdef TCC_HAS_RUNTIME_PLTGOT
865 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
866 val
= add_got_table(s1
, val
- rel
->r_addend
) + rel
->r_addend
;
867 *(int *)ptr
+= val
- addr
;
871 *(int *)ptr
+= (s1
->got
->sh_addr
- addr
+
872 s1
->sym_attrs
[sym_index
].got_offset
- 4);
874 case R_X86_64_GOTTPOFF
:
875 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
878 /* we load the got offset */
879 *(int *)ptr
+= s1
->sym_attrs
[sym_index
].got_offset
;
882 #error unsupported processor
886 /* if the relocation is allocated, we change its symbol table */
887 if (sr
->sh_flags
& SHF_ALLOC
)
888 sr
->link
= s1
->dynsym
;
891 /* relocate relocation table in 'sr' */
892 static void relocate_rel(TCCState
*s1
, Section
*sr
)
895 ElfW_Rel
*rel
, *rel_end
;
897 s
= s1
->sections
[sr
->sh_info
];
898 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
899 for(rel
= (ElfW_Rel
*)sr
->data
;
902 rel
->r_offset
+= s
->sh_addr
;
906 /* count the number of dynamic relocations so that we can reserve
908 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
910 ElfW_Rel
*rel
, *rel_end
;
911 int sym_index
, esym_index
, type
, count
;
914 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
915 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
916 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
917 type
= ELFW(R_TYPE
)(rel
->r_info
);
919 #if defined(TCC_TARGET_I386)
921 #elif defined(TCC_TARGET_X86_64)
928 #if defined(TCC_TARGET_I386)
930 #elif defined(TCC_TARGET_X86_64)
933 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
942 /* allocate the section */
943 sr
->sh_flags
|= SHF_ALLOC
;
944 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
949 static struct sym_attr
*alloc_sym_attr(TCCState
*s1
, int index
)
952 struct sym_attr
*tab
;
954 if (index
>= s1
->nb_sym_attrs
) {
955 /* find immediately bigger power of 2 and reallocate array */
959 tab
= tcc_realloc(s1
->sym_attrs
, n
* sizeof(*s1
->sym_attrs
));
961 memset(s1
->sym_attrs
+ s1
->nb_sym_attrs
, 0,
962 (n
- s1
->nb_sym_attrs
) * sizeof(*s1
->sym_attrs
));
963 s1
->nb_sym_attrs
= n
;
965 return &s1
->sym_attrs
[index
];
968 /* XXX: suppress that */
969 static void put32(unsigned char *p
, uint32_t val
)
977 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
978 defined(TCC_TARGET_X86_64)
979 static uint32_t get32(unsigned char *p
)
981 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
985 static void build_got(TCCState
*s1
)
989 /* if no got, then create it */
990 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
991 s1
->got
->sh_entsize
= 4;
992 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
993 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
994 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
996 /* keep space for _DYNAMIC pointer, if present */
998 /* two dummy got entries */
1002 /* keep space for _DYNAMIC pointer, if present */
1005 /* two dummy got entries */
1013 /* put a got entry corresponding to a symbol in symtab_section. 'size'
1014 and 'info' can be modifed if more precise info comes from the DLL */
1015 static void put_got_entry(TCCState
*s1
,
1016 int reloc_type
, unsigned long size
, int info
,
1022 unsigned long offset
;
1028 /* if a got entry already exists for that symbol, no need to add one */
1029 if (sym_index
< s1
->nb_sym_attrs
&&
1030 s1
->sym_attrs
[sym_index
].got_offset
)
1033 alloc_sym_attr(s1
, sym_index
)->got_offset
= s1
->got
->data_offset
;
1036 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1037 name
= symtab_section
->link
->data
+ sym
->st_name
;
1038 offset
= sym
->st_value
;
1039 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1041 #ifdef TCC_TARGET_X86_64
1051 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1054 /* if we build a DLL, we add a %ebx offset */
1055 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1061 /* add a PLT entry */
1063 if (plt
->data_offset
== 0) {
1064 /* first plt entry */
1065 p
= section_ptr_add(plt
, 16);
1066 p
[0] = 0xff; /* pushl got + PTR_SIZE */
1067 p
[1] = modrm
+ 0x10;
1068 put32(p
+ 2, PTR_SIZE
);
1069 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
1071 put32(p
+ 8, PTR_SIZE
* 2);
1074 p
= section_ptr_add(plt
, 16);
1075 p
[0] = 0xff; /* jmp *(got + x) */
1077 put32(p
+ 2, s1
->got
->data_offset
);
1078 p
[6] = 0x68; /* push $xxx */
1079 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
1080 p
[11] = 0xe9; /* jmp plt_start */
1081 put32(p
+ 12, -(plt
->data_offset
));
1083 /* the symbol is modified so that it will be relocated to
1085 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
1086 if (s1
->output_type
== TCC_OUTPUT_EXE
)
1088 offset
= plt
->data_offset
- 16;
1090 #elif defined(TCC_TARGET_ARM)
1091 if (reloc_type
== R_ARM_JUMP_SLOT
) {
1095 /* if we build a DLL, we add a %ebx offset */
1096 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1097 tcc_error("DLLs unimplemented!");
1099 /* add a PLT entry */
1101 if (plt
->data_offset
== 0) {
1102 /* first plt entry */
1103 p
= section_ptr_add(plt
, 16);
1104 put32(p
, 0xe52de004);
1105 put32(p
+ 4, 0xe59fe010);
1106 put32(p
+ 8, 0xe08fe00e);
1107 put32(p
+ 12, 0xe5bef008);
1110 if (s1
->sym_attrs
[sym_index
].plt_thumb_stub
) {
1111 p
= section_ptr_add(plt
, 20);
1112 put32(p
, 0x4778); // bx pc
1113 put32(p
+2, 0x46c0); // nop
1116 p
= section_ptr_add(plt
, 16);
1117 put32(p
, 0xe59fc004); // ldr ip, [pc, #4] // offset in GOT
1118 put32(p
+4, 0xe08fc00c); // add ip, pc, ip // absolute address or offset
1119 put32(p
+8, 0xe59cf000); // ldr pc, [ip] // load absolute address or load offset
1120 put32(p
+12, s1
->got
->data_offset
);
1122 /* the symbol is modified so that it will be relocated to
1124 if (s1
->output_type
== TCC_OUTPUT_EXE
)
1125 offset
= plt
->data_offset
- 16;
1127 #elif defined(TCC_TARGET_C67)
1128 tcc_error("C67 got not implemented");
1130 #error unsupported CPU
1132 index
= put_elf_sym(s1
->dynsym
, offset
,
1133 size
, info
, 0, sym
->st_shndx
, name
);
1134 /* put a got entry */
1135 put_elf_reloc(s1
->dynsym
, s1
->got
,
1136 s1
->got
->data_offset
,
1139 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
1143 /* build GOT and PLT entries */
1144 ST_FUNC
void build_got_entries(TCCState
*s1
)
1147 ElfW_Rel
*rel
, *rel_end
;
1149 int i
, type
, reloc_type
, sym_index
;
1151 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1152 s
= s1
->sections
[i
];
1153 if (s
->sh_type
!= SHT_RELX
)
1155 /* no need to handle got relocations */
1156 if (s
->link
!= symtab_section
)
1158 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
1159 for(rel
= (ElfW_Rel
*)s
->data
;
1162 type
= ELFW(R_TYPE
)(rel
->r_info
);
1164 #if defined(TCC_TARGET_I386)
1171 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1172 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1173 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1174 /* look at the symbol got offset. If none, then add one */
1175 if (type
== R_386_GOT32
)
1176 reloc_type
= R_386_GLOB_DAT
;
1178 reloc_type
= R_386_JMP_SLOT
;
1179 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1183 #elif defined(TCC_TARGET_ARM)
1184 case R_ARM_GOT_BREL
:
1185 case R_ARM_GOTOFF32
:
1186 case R_ARM_BASE_PREL
:
1190 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1191 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1192 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1193 /* look at the symbol got offset. If none, then add one */
1194 if (type
== R_ARM_GOT_BREL
)
1195 reloc_type
= R_ARM_GLOB_DAT
;
1197 reloc_type
= R_ARM_JUMP_SLOT
;
1198 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1202 #elif defined(TCC_TARGET_C67)
1209 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1210 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1211 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1212 /* look at the symbol got offset. If none, then add one */
1213 if (type
== R_C60_GOT32
)
1214 reloc_type
= R_C60_GLOB_DAT
;
1216 reloc_type
= R_C60_JMP_SLOT
;
1217 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1221 #elif defined(TCC_TARGET_X86_64)
1222 case R_X86_64_GOT32
:
1223 case R_X86_64_GOTTPOFF
:
1224 case R_X86_64_GOTPCREL
:
1225 case R_X86_64_PLT32
:
1228 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
||
1229 type
== R_X86_64_PLT32
) {
1230 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1231 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1232 /* look at the symbol got offset. If none, then add one */
1233 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
)
1234 reloc_type
= R_X86_64_GLOB_DAT
;
1236 reloc_type
= R_X86_64_JUMP_SLOT
;
1237 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1242 #error unsupported CPU
1251 ST_FUNC Section
*new_symtab(TCCState
*s1
,
1252 const char *symtab_name
, int sh_type
, int sh_flags
,
1253 const char *strtab_name
,
1254 const char *hash_name
, int hash_sh_flags
)
1256 Section
*symtab
, *strtab
, *hash
;
1257 int *ptr
, nb_buckets
;
1259 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1260 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1261 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1262 put_elf_str(strtab
, "");
1263 symtab
->link
= strtab
;
1264 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1268 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1269 hash
->sh_entsize
= sizeof(int);
1270 symtab
->hash
= hash
;
1271 hash
->link
= symtab
;
1273 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1274 ptr
[0] = nb_buckets
;
1276 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1280 /* put dynamic tag */
1281 static void put_dt(Section
*dynamic
, int dt
, addr_t val
)
1284 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1286 dyn
->d_un
.d_val
= val
;
1289 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1293 char sym_start
[1024];
1296 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1297 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1299 s
= find_section(s1
, section_name
);
1304 end_offset
= s
->data_offset
;
1307 add_elf_sym(symtab_section
,
1309 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1310 s
->sh_num
, sym_start
);
1311 add_elf_sym(symtab_section
,
1313 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1314 s
->sh_num
, sym_end
);
1317 ST_FUNC
void tcc_add_bcheck(TCCState
*s1
)
1319 #ifdef CONFIG_TCC_BCHECK
1321 Section
*init_section
;
1322 unsigned char *pinit
;
1325 if (0 == s1
->do_bounds_check
)
1328 /* XXX: add an object file to do that */
1329 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1331 add_elf_sym(symtab_section
, 0, 0,
1332 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1333 bounds_section
->sh_num
, "__bounds_start");
1334 #ifdef TCC_TARGET_I386
1335 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1336 /* add 'call __bound_init()' in .init section */
1337 init_section
= find_section(s1
, ".init");
1338 pinit
= section_ptr_add(init_section
, 5);
1340 put32(pinit
+ 1, -4);
1341 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1342 put_elf_reloc(symtab_section
, init_section
,
1343 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1349 static inline int tcc_add_support(TCCState
*s1
, const char *filename
)
1352 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, filename
);
1353 return tcc_add_file(s1
, buf
);
1356 /* add tcc runtime libraries */
1357 ST_FUNC
void tcc_add_runtime(TCCState
*s1
)
1362 if (!s1
->nostdlib
) {
1363 tcc_add_library(s1
, "c");
1364 #ifdef CONFIG_USE_LIBGCC
1365 tcc_add_file(s1
, TCC_LIBGCC
);
1366 #elif !defined WITHOUT_LIBTCC
1367 tcc_add_support(s1
, "libtcc1.a");
1369 /* add crt end if not memory output */
1370 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
)
1371 tcc_add_crt(s1
, "crtn.o");
1375 /* add various standard linker symbols (must be done after the
1376 sections are filled (for example after allocating common
1378 ST_FUNC
void tcc_add_linker_symbols(TCCState
*s1
)
1384 add_elf_sym(symtab_section
,
1385 text_section
->data_offset
, 0,
1386 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1387 text_section
->sh_num
, "_etext");
1388 add_elf_sym(symtab_section
,
1389 data_section
->data_offset
, 0,
1390 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1391 data_section
->sh_num
, "_edata");
1392 add_elf_sym(symtab_section
,
1393 bss_section
->data_offset
, 0,
1394 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1395 bss_section
->sh_num
, "_end");
1396 /* horrible new standard ldscript defines */
1397 add_init_array_defines(s1
, ".preinit_array");
1398 add_init_array_defines(s1
, ".init_array");
1399 add_init_array_defines(s1
, ".fini_array");
1401 /* add start and stop symbols for sections whose name can be
1403 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1404 s
= s1
->sections
[i
];
1405 if (s
->sh_type
== SHT_PROGBITS
&&
1406 (s
->sh_flags
& SHF_ALLOC
)) {
1410 /* check if section name can be expressed in C */
1416 if (!isid(ch
) && !isnum(ch
))
1420 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1421 add_elf_sym(symtab_section
,
1423 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1425 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1426 add_elf_sym(symtab_section
,
1428 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1435 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1436 const int *section_order
)
1439 int i
, offset
, size
;
1442 for(i
=1;i
<s1
->nb_sections
;i
++) {
1443 s
= s1
->sections
[section_order
[i
]];
1444 if (s
->sh_type
!= SHT_NOBITS
&&
1445 (s
->sh_flags
& SHF_ALLOC
)) {
1446 while (offset
< s
->sh_offset
) {
1451 fwrite(s
->data
, 1, size
, f
);
1457 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1459 #define EXTRA_RELITEMS 14
1461 /* move the relocation value from .dynsym to .got */
1462 void patch_dynsym_undef(TCCState
*s1
, Section
*s
)
1464 uint32_t *gotd
= (void *)s1
->got
->data
;
1465 ElfW(Sym
) *sym
, *sym_end
;
1467 gotd
+= 3; // dummy entries in .got
1468 /* relocate symbols in .dynsym */
1469 sym_end
= (ElfW(Sym
) *)(s
->data
+ s
->data_offset
);
1470 for (sym
= (ElfW(Sym
) *)s
->data
+ 1; sym
< sym_end
; sym
++) {
1471 if (sym
->st_shndx
== SHN_UNDEF
) {
1472 *gotd
++ = sym
->st_value
+ 6; // XXX 6 is magic ?
1479 #define EXTRA_RELITEMS 9
1481 /* zero plt offsets of weak symbols in .dynsym */
1482 void patch_dynsym_undef(TCCState
*s1
, Section
*s
)
1484 ElfW(Sym
) *sym
, *sym_end
;
1486 sym_end
= (ElfW(Sym
) *)(s
->data
+ s
->data_offset
);
1487 for (sym
= (ElfW(Sym
) *)s
->data
+ 1; sym
< sym_end
; sym
++)
1488 if (sym
->st_shndx
== SHN_UNDEF
&& ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
)
1493 ST_FUNC
void fill_got_entry(TCCState
*s1
, ElfW_Rel
*rel
)
1495 int sym_index
= ELFW(R_SYM
) (rel
->r_info
);
1496 ElfW(Sym
) *sym
= &((ElfW(Sym
) *) symtab_section
->data
)[sym_index
];
1497 unsigned long offset
;
1499 if (sym_index
>= s1
->nb_sym_attrs
)
1501 offset
= s1
->sym_attrs
[sym_index
].got_offset
;
1502 section_reserve(s1
->got
, offset
+ PTR_SIZE
);
1503 #ifdef TCC_TARGET_X86_64
1504 /* only works for x86-64 */
1505 put32(s1
->got
->data
+ offset
+ 4, sym
->st_value
>> 32);
1507 put32(s1
->got
->data
+ offset
, sym
->st_value
& 0xffffffff);
1510 ST_FUNC
void fill_got(TCCState
*s1
)
1513 ElfW_Rel
*rel
, *rel_end
;
1516 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1517 s
= s1
->sections
[i
];
1518 if (s
->sh_type
!= SHT_RELX
)
1520 /* no need to handle got relocations */
1521 if (s
->link
!= symtab_section
)
1523 rel_end
= (ElfW_Rel
*) (s
->data
+ s
->data_offset
);
1524 for(rel
= (ElfW_Rel
*) s
->data
; rel
< rel_end
; rel
++) {
1525 switch (ELFW(R_TYPE
) (rel
->r_info
)) {
1526 case R_X86_64_GOT32
:
1527 case R_X86_64_GOTPCREL
:
1528 case R_X86_64_PLT32
:
1529 fill_got_entry(s1
, rel
);
1537 /* output an ELF file */
1538 /* XXX: suppress unneeded sections */
1539 static int elf_output_file(TCCState
*s1
, const char *filename
)
1545 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, sh_order_index
, k
;
1548 Section
*strsec
, *s
;
1549 ElfW(Shdr
) shdr
, *sh
;
1550 ElfW(Phdr
) *phdr
, *ph
;
1551 Section
*interp
, *dynamic
, *dynstr
;
1552 unsigned long saved_dynamic_data_offset
;
1554 int type
, file_type
;
1555 addr_t rel_addr
, rel_size
;
1556 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1557 addr_t bss_addr
, bss_size
;
1560 file_type
= s1
->output_type
;
1563 if (file_type
!= TCC_OUTPUT_OBJ
) {
1564 tcc_add_runtime(s1
);
1568 section_order
= NULL
;
1571 dynstr
= NULL
; /* avoid warning */
1572 saved_dynamic_data_offset
= 0; /* avoid warning */
1574 if (file_type
!= TCC_OUTPUT_OBJ
) {
1575 relocate_common_syms();
1577 tcc_add_linker_symbols(s1
);
1579 if (!s1
->static_link
) {
1581 int sym_index
, index
;
1582 ElfW(Sym
) *esym
, *sym_end
;
1584 if (file_type
== TCC_OUTPUT_EXE
) {
1586 /* allow override the dynamic loader */
1587 const char *elfint
= getenv("LD_SO");
1589 elfint
= CONFIG_TCC_ELFINTERP
;
1590 /* add interpreter section only if executable */
1591 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1592 interp
->sh_addralign
= 1;
1593 ptr
= section_ptr_add(interp
, 1+strlen(elfint
));
1594 strcpy(ptr
, elfint
);
1597 /* add dynamic symbol table */
1598 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1600 ".hash", SHF_ALLOC
);
1601 dynstr
= s1
->dynsym
->link
;
1603 /* add dynamic section */
1604 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1605 SHF_ALLOC
| SHF_WRITE
);
1606 dynamic
->link
= dynstr
;
1607 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1610 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1611 SHF_ALLOC
| SHF_EXECINSTR
);
1612 s1
->plt
->sh_entsize
= 4;
1616 /* scan for undefined symbols and see if they are in the
1617 dynamic symbols. If a symbol STT_FUNC or STT_GNU_IFUNC
1618 is found, then we add it in the PLT. If a symbol
1619 STT_OBJECT is found, we add it in the .bss section with
1620 a suitable relocation */
1621 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1622 symtab_section
->data_offset
);
1623 if (file_type
== TCC_OUTPUT_EXE
) {
1624 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1627 if (sym
->st_shndx
== SHN_UNDEF
) {
1628 name
= 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
1635 * in executable dynsym section. Indeed, a dlsym
1636 * call following a lazy resolution would pick
1637 * the symbol value from the executable dynsym
1638 * entry which would contain the address of the
1639 * function wanted by the caller of dlsym
1640 * instead of the address of the function that
1641 * would return that address */
1642 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1643 ELFW(ST_INFO
)(STB_GLOBAL
,STT_FUNC
),
1644 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1645 } else if (type
== STT_OBJECT
) {
1646 unsigned long offset
;
1647 ElfW(Sym
) *dynsym
, *dynsym_end
;
1648 offset
= bss_section
->data_offset
;
1649 /* XXX: which alignment ? */
1650 offset
= (offset
+ 16 - 1) & -16;
1651 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1653 bss_section
->sh_num
, name
);
1654 // Ensure R_COPY works for weak symbol aliases
1655 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1656 dynsym_end
= (ElfW(Sym
) *)
1657 (s1
->dynsymtab_section
->data
+
1658 s1
->dynsymtab_section
->data_offset
);
1659 for(dynsym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1660 dynsym
< dynsym_end
; dynsym
++) {
1661 if ((dynsym
->st_value
== esym
->st_value
)
1662 && (ELFW(ST_BIND
)(dynsym
->st_info
) == STB_GLOBAL
)) {
1664 dynname
= s1
->dynsymtab_section
->link
->data
1666 put_elf_sym(s1
->dynsym
, offset
,
1669 bss_section
->sh_num
,
1675 put_elf_reloc(s1
->dynsym
, bss_section
,
1676 offset
, R_COPY
, index
);
1677 offset
+= esym
->st_size
;
1678 bss_section
->data_offset
= offset
;
1681 /* STB_WEAK undefined symbols are accepted */
1682 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
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
&&
1691 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1692 /* if -rdynamic option, then export all non
1694 name
= symtab_section
->link
->data
+ sym
->st_name
;
1695 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1697 sym
->st_shndx
, name
);
1704 /* now look at unresolved dynamic symbols and export
1705 corresponding symbol */
1706 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1707 s1
->dynsymtab_section
->data_offset
);
1708 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1711 if (esym
->st_shndx
== SHN_UNDEF
) {
1712 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1713 sym_index
= find_elf_sym(symtab_section
, name
);
1715 /* XXX: avoid adding a symbol if already
1716 present because of -rdynamic ? */
1717 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1718 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1720 sym
->st_shndx
, name
);
1722 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1723 /* weak symbols can stay undefined */
1725 tcc_warning("undefined dynamic symbol '%s'", name
);
1732 /* shared library case : we simply export all the global symbols */
1733 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1734 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1735 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1738 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1739 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1740 if ((ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
||
1741 ELFW(ST_TYPE
)(sym
->st_info
) == STT_GNU_IFUNC
)
1742 && sym
->st_shndx
== SHN_UNDEF
) {
1743 int visibility
= ELFW(ST_BIND
)(sym
->st_info
);
1744 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1745 ELFW(ST_INFO
)(visibility
,STT_FUNC
),
1746 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1748 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1749 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1751 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1756 name
= symtab_section
->link
->data
+ sym
->st_name
;
1757 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1759 sym
->st_shndx
, name
);
1760 s1
->symtab_to_dynsym
[sym
-
1761 (ElfW(Sym
) *)symtab_section
->data
] =
1768 build_got_entries(s1
);
1770 /* add a list of needed dlls */
1771 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1772 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1773 if (dllref
->level
== 0)
1774 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1778 put_dt(dynamic
, DT_RPATH
, put_elf_str(dynstr
, s1
->rpath
));
1780 /* XXX: currently, since we do not handle PIC code, we
1781 must relocate the readonly segments */
1782 if (file_type
== TCC_OUTPUT_DLL
) {
1784 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1785 put_dt(dynamic
, DT_TEXTREL
, 0);
1789 put_dt(dynamic
, DT_SYMBOLIC
, 0);
1791 /* add necessary space for other entries */
1792 saved_dynamic_data_offset
= dynamic
->data_offset
;
1793 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * EXTRA_RELITEMS
;
1795 /* still need to build got entries in case of static link */
1796 build_got_entries(s1
);
1800 memset(&ehdr
, 0, sizeof(ehdr
));
1802 /* we add a section for symbols */
1803 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1804 put_elf_str(strsec
, "");
1806 /* compute number of sections */
1807 shnum
= s1
->nb_sections
;
1809 /* this array is used to reorder sections in the output file */
1810 section_order
= tcc_malloc(sizeof(int) * shnum
);
1811 section_order
[0] = 0;
1814 /* compute number of program headers */
1817 case TCC_OUTPUT_OBJ
:
1820 case TCC_OUTPUT_EXE
:
1821 if (!s1
->static_link
)
1822 phnum
= 4 + HAVE_PHDR
;
1826 case TCC_OUTPUT_DLL
:
1831 /* allocate strings for section names and decide if an unallocated
1832 section should be output */
1833 /* NOTE: the strsec section comes last, so its size is also
1835 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1836 s
= s1
->sections
[i
];
1837 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1839 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1844 s
->reloc
? s
->reloc
->name
: "n"
1847 /* when generating a DLL, we include relocations but we may
1849 if (file_type
== TCC_OUTPUT_DLL
&&
1850 s
->sh_type
== SHT_RELX
&&
1851 !(s
->sh_flags
& SHF_ALLOC
)) {
1852 /* //gr: avoid bogus relocs for empty (debug) sections */
1853 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1854 prepare_dynamic_rel(s1
, s
);
1855 else if (s1
->do_debug
)
1856 s
->sh_size
= s
->data_offset
;
1857 } else if (s1
->do_debug
||
1858 file_type
== TCC_OUTPUT_OBJ
||
1859 (s
->sh_flags
& SHF_ALLOC
) ||
1860 i
== (s1
->nb_sections
- 1)) {
1861 /* we output all sections if debug or object file */
1862 s
->sh_size
= s
->data_offset
;
1866 /* allocate program segment headers */
1867 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1869 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1870 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1875 /* compute section to program header mapping */
1876 if (s1
->has_text_addr
) {
1877 int a_offset
, p_offset
;
1878 addr
= s1
->text_addr
;
1879 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1881 a_offset
= (int) (addr
& (s1
->section_align
- 1));
1882 p_offset
= file_offset
& (s1
->section_align
- 1);
1883 if (a_offset
< p_offset
)
1884 a_offset
+= s1
->section_align
;
1885 file_offset
+= (a_offset
- p_offset
);
1887 if (file_type
== TCC_OUTPUT_DLL
)
1890 addr
= ELF_START_ADDR
;
1891 /* compute address after headers */
1892 addr
+= (file_offset
& (s1
->section_align
- 1));
1895 /* dynamic relocation table information, for .dynamic section */
1899 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1900 bss_addr
= bss_size
= 0;
1902 /* leave one program header for the program interpreter */
1905 ph
+= 1 + HAVE_PHDR
;
1907 for(j
= 0; j
< 2; j
++) {
1908 ph
->p_type
= PT_LOAD
;
1910 ph
->p_flags
= PF_R
| PF_X
;
1912 ph
->p_flags
= PF_R
| PF_W
;
1913 ph
->p_align
= s1
->section_align
;
1915 /* we do the following ordering: interp, symbol tables,
1916 relocations, progbits, nobits */
1917 /* XXX: do faster and simpler sorting */
1918 for(k
= 0; k
< 5; k
++) {
1919 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1920 s
= s1
->sections
[i
];
1921 /* compute if section should be included */
1923 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1927 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1928 (SHF_ALLOC
| SHF_WRITE
))
1934 } else if (s
->sh_type
== SHT_DYNSYM
||
1935 s
->sh_type
== SHT_STRTAB
||
1936 s
->sh_type
== SHT_HASH
) {
1939 } else if (s
->sh_type
== SHT_RELX
) {
1942 } else if (s
->sh_type
== SHT_NOBITS
) {
1949 section_order
[sh_order_index
++] = i
;
1951 /* section matches: we align it and add its size */
1953 addr
= (addr
+ s
->sh_addralign
- 1) &
1954 ~(s
->sh_addralign
- 1);
1955 file_offset
+= (int) ( addr
- tmp
);
1956 s
->sh_offset
= file_offset
;
1959 /* update program header infos */
1960 if (ph
->p_offset
== 0) {
1961 ph
->p_offset
= file_offset
;
1963 ph
->p_paddr
= ph
->p_vaddr
;
1965 /* update dynamic relocation infos */
1966 if (s
->sh_type
== SHT_RELX
) {
1967 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1968 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.got")) { // rel_size == 0) {
1970 rel_size
+= s
->sh_size
; // XXX only first rel.
1972 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.bss")) { // rel_size == 0) {
1974 bss_size
= s
->sh_size
; // XXX only first rel.
1979 rel_size
+= s
->sh_size
;
1983 if (s
->sh_type
!= SHT_NOBITS
)
1984 file_offset
+= s
->sh_size
;
1987 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1988 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1991 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1992 /* if in the middle of a page, we duplicate the page in
1993 memory so that one copy is RX and the other is RW */
1994 if ((addr
& (s1
->section_align
- 1)) != 0)
1995 addr
+= s1
->section_align
;
1997 addr
= (addr
+ s1
->section_align
- 1) & ~(s1
->section_align
- 1);
1998 file_offset
= (file_offset
+ s1
->section_align
- 1) &
1999 ~(s1
->section_align
- 1);
2004 /* if interpreter, then add corresponing program header */
2008 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2010 int len
= phnum
* sizeof(ElfW(Phdr
));
2012 ph
->p_type
= PT_PHDR
;
2013 ph
->p_offset
= sizeof(ElfW(Ehdr
));
2014 ph
->p_vaddr
= interp
->sh_addr
- len
;
2015 ph
->p_paddr
= ph
->p_vaddr
;
2016 ph
->p_filesz
= ph
->p_memsz
= len
;
2017 ph
->p_flags
= PF_R
| PF_X
;
2018 ph
->p_align
= 4; // interp->sh_addralign;
2023 ph
->p_type
= PT_INTERP
;
2024 ph
->p_offset
= interp
->sh_offset
;
2025 ph
->p_vaddr
= interp
->sh_addr
;
2026 ph
->p_paddr
= ph
->p_vaddr
;
2027 ph
->p_filesz
= interp
->sh_size
;
2028 ph
->p_memsz
= interp
->sh_size
;
2030 ph
->p_align
= interp
->sh_addralign
;
2033 /* if dynamic section, then add corresponing program header */
2037 ph
= &phdr
[phnum
- 1];
2039 ph
->p_type
= PT_DYNAMIC
;
2040 ph
->p_offset
= dynamic
->sh_offset
;
2041 ph
->p_vaddr
= dynamic
->sh_addr
;
2042 ph
->p_paddr
= ph
->p_vaddr
;
2043 ph
->p_filesz
= dynamic
->sh_size
;
2044 ph
->p_memsz
= dynamic
->sh_size
;
2045 ph
->p_flags
= PF_R
| PF_W
;
2046 ph
->p_align
= dynamic
->sh_addralign
;
2048 /* put GOT dynamic section address */
2049 put32(s1
->got
->data
, dynamic
->sh_addr
);
2051 /* relocate the PLT */
2052 if (file_type
== TCC_OUTPUT_EXE
2053 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
2054 || file_type
== TCC_OUTPUT_DLL
2060 p_end
= p
+ s1
->plt
->data_offset
;
2062 #if defined(TCC_TARGET_I386)
2063 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
2064 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
2067 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
2070 #elif defined(TCC_TARGET_X86_64)
2071 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
2072 put32(p
+ 2, get32(p
+ 2) + x
);
2073 put32(p
+ 8, get32(p
+ 8) + x
- 6);
2076 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
2079 #elif defined(TCC_TARGET_ARM)
2081 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
2084 if (get32(p
) == 0x46c04778) /* PLT Thumb stub present */
2086 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
2089 #elif defined(TCC_TARGET_C67)
2092 #error unsupported CPU
2097 /* relocate symbols in .dynsym */
2098 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
2099 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
2102 if (sym
->st_shndx
== SHN_UNDEF
) {
2103 /* relocate to the PLT if the symbol corresponds
2106 sym
->st_value
+= s1
->plt
->sh_addr
;
2107 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
2108 /* do symbol relocation */
2109 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
2113 /* put dynamic section entries */
2114 dynamic
->data_offset
= saved_dynamic_data_offset
;
2115 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
2116 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
2117 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
2118 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
2119 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
2120 #ifdef TCC_TARGET_X86_64
2121 put_dt(dynamic
, DT_RELA
, rel_addr
);
2122 put_dt(dynamic
, DT_RELASZ
, rel_size
);
2123 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
2125 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2126 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2127 put_dt(dynamic
, DT_PLTRELSZ
, rel_size
);
2128 put_dt(dynamic
, DT_JMPREL
, rel_addr
);
2129 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
2130 put_dt(dynamic
, DT_REL
, bss_addr
);
2131 put_dt(dynamic
, DT_RELSZ
, bss_size
);
2133 put_dt(dynamic
, DT_REL
, rel_addr
);
2134 put_dt(dynamic
, DT_RELSZ
, rel_size
);
2135 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
2139 put_dt(dynamic
, DT_DEBUG
, 0);
2140 put_dt(dynamic
, DT_NULL
, 0);
2143 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2144 ehdr
.e_phnum
= phnum
;
2145 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2148 /* all other sections come after */
2149 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2150 s
= s1
->sections
[i
];
2151 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
2153 section_order
[sh_order_index
++] = i
;
2155 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
2156 ~(s
->sh_addralign
- 1);
2157 s
->sh_offset
= file_offset
;
2158 if (s
->sh_type
!= SHT_NOBITS
)
2159 file_offset
+= s
->sh_size
;
2162 /* if building executable or DLL, then relocate each section
2163 except the GOT which is already relocated */
2164 if (file_type
!= TCC_OUTPUT_OBJ
) {
2165 relocate_syms(s1
, 0);
2167 if (s1
->nb_errors
!= 0) {
2173 /* relocate sections */
2174 /* XXX: ignore sections with allocated relocations ? */
2175 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2176 s
= s1
->sections
[i
];
2177 if (s
->reloc
&& s
!= s1
->got
)
2178 relocate_section(s1
, s
);
2181 /* relocate relocation entries if the relocation tables are
2182 allocated in the executable */
2183 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2184 s
= s1
->sections
[i
];
2185 if ((s
->sh_flags
& SHF_ALLOC
) &&
2186 s
->sh_type
== SHT_RELX
) {
2187 relocate_rel(s1
, s
);
2191 /* get entry point address */
2192 if (file_type
== TCC_OUTPUT_EXE
)
2193 ehdr
.e_entry
= get_elf_sym_addr(s1
, "_start", 1);
2195 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
2197 if (file_type
== TCC_OUTPUT_EXE
&& s1
->static_link
)
2200 /* write elf file */
2201 if (file_type
== TCC_OUTPUT_OBJ
)
2206 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2208 tcc_error_noabort("could not write '%s'", filename
);
2211 f
= fdopen(fd
, "wb");
2213 printf("<- %s\n", filename
);
2215 #ifdef TCC_TARGET_COFF
2216 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
2217 tcc_output_coff(s1
, f
);
2220 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
2221 sort_syms(s1
, symtab_section
);
2224 file_offset
= (file_offset
+ 3) & -4;
2227 ehdr
.e_ident
[0] = ELFMAG0
;
2228 ehdr
.e_ident
[1] = ELFMAG1
;
2229 ehdr
.e_ident
[2] = ELFMAG2
;
2230 ehdr
.e_ident
[3] = ELFMAG3
;
2231 ehdr
.e_ident
[4] = ELFCLASSW
;
2232 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2233 ehdr
.e_ident
[6] = EV_CURRENT
;
2234 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2235 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2237 #ifdef TCC_TARGET_ARM
2239 ehdr
.e_ident
[EI_OSABI
] = 0;
2240 ehdr
.e_flags
= 4 << 24;
2242 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2247 case TCC_OUTPUT_EXE
:
2248 ehdr
.e_type
= ET_EXEC
;
2250 case TCC_OUTPUT_DLL
:
2251 ehdr
.e_type
= ET_DYN
;
2253 case TCC_OUTPUT_OBJ
:
2254 ehdr
.e_type
= ET_REL
;
2257 ehdr
.e_machine
= EM_TCC_TARGET
;
2258 ehdr
.e_version
= EV_CURRENT
;
2259 ehdr
.e_shoff
= file_offset
;
2260 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2261 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2262 ehdr
.e_shnum
= shnum
;
2263 ehdr
.e_shstrndx
= shnum
- 1;
2265 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2266 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2267 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2269 for(i
=1;i
<s1
->nb_sections
;i
++) {
2270 s
= s1
->sections
[section_order
[i
]];
2271 if (s
->sh_type
!= SHT_NOBITS
) {
2272 if (s
->sh_type
== SHT_DYNSYM
)
2273 patch_dynsym_undef(s1
, s
);
2274 while (offset
< s
->sh_offset
) {
2279 fwrite(s
->data
, 1, size
, f
);
2284 /* output section headers */
2285 while (offset
< ehdr
.e_shoff
) {
2290 for(i
=0;i
<s1
->nb_sections
;i
++) {
2292 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2293 s
= s1
->sections
[i
];
2295 sh
->sh_name
= s
->sh_name
;
2296 sh
->sh_type
= s
->sh_type
;
2297 sh
->sh_flags
= s
->sh_flags
;
2298 sh
->sh_entsize
= s
->sh_entsize
;
2299 sh
->sh_info
= s
->sh_info
;
2301 sh
->sh_link
= s
->link
->sh_num
;
2302 sh
->sh_addralign
= s
->sh_addralign
;
2303 sh
->sh_addr
= s
->sh_addr
;
2304 sh
->sh_offset
= s
->sh_offset
;
2305 sh
->sh_size
= s
->sh_size
;
2307 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2310 tcc_output_binary(s1
, f
, section_order
);
2316 tcc_free(s1
->symtab_to_dynsym
);
2317 tcc_free(section_order
);
2319 tcc_free(s1
->sym_attrs
);
2323 LIBTCCAPI
int tcc_output_file(TCCState
*s
, const char *filename
)
2326 #ifdef TCC_TARGET_PE
2327 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2328 ret
= pe_output_file(s
, filename
);
2332 ret
= elf_output_file(s
, filename
);
2337 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2341 data
= tcc_malloc(size
);
2342 lseek(fd
, file_offset
, SEEK_SET
);
2343 read(fd
, data
, size
);
2347 typedef struct SectionMergeInfo
{
2348 Section
*s
; /* corresponding existing section */
2349 unsigned long offset
; /* offset of the new section in the existing section */
2350 uint8_t new_section
; /* true if section 's' was added */
2351 uint8_t link_once
; /* true if link once section */
2354 /* load an object file and merge it with current files */
2355 /* XXX: handle correctly stab (debug) info */
2356 ST_FUNC
int tcc_load_object_file(TCCState
*s1
,
2357 int fd
, unsigned long file_offset
)
2360 ElfW(Shdr
) *shdr
, *sh
;
2361 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2362 unsigned char *strsec
, *strtab
;
2363 int *old_to_new_syms
;
2364 char *sh_name
, *name
;
2365 SectionMergeInfo
*sm_table
, *sm
;
2366 ElfW(Sym
) *sym
, *symtab
;
2367 ElfW_Rel
*rel
, *rel_end
;
2373 stab_index
= stabstr_index
= 0;
2375 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2377 if (ehdr
.e_ident
[0] != ELFMAG0
||
2378 ehdr
.e_ident
[1] != ELFMAG1
||
2379 ehdr
.e_ident
[2] != ELFMAG2
||
2380 ehdr
.e_ident
[3] != ELFMAG3
)
2382 /* test if object file */
2383 if (ehdr
.e_type
!= ET_REL
)
2385 /* test CPU specific stuff */
2386 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2387 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2389 tcc_error_noabort("invalid object file");
2393 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2394 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2395 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2397 /* load section names */
2398 sh
= &shdr
[ehdr
.e_shstrndx
];
2399 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2401 /* load symtab and strtab */
2402 old_to_new_syms
= NULL
;
2406 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2408 if (sh
->sh_type
== SHT_SYMTAB
) {
2410 tcc_error_noabort("object must contain only one symtab");
2415 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2416 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2417 sm_table
[i
].s
= symtab_section
;
2419 /* now load strtab */
2420 sh
= &shdr
[sh
->sh_link
];
2421 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2425 /* now examine each section and try to merge its content with the
2427 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2428 /* no need to examine section name strtab */
2429 if (i
== ehdr
.e_shstrndx
)
2432 sh_name
= strsec
+ sh
->sh_name
;
2433 /* ignore sections types we do not handle */
2434 if (sh
->sh_type
!= SHT_PROGBITS
&&
2435 sh
->sh_type
!= SHT_RELX
&&
2437 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2439 sh
->sh_type
!= SHT_NOBITS
&&
2440 sh
->sh_type
!= SHT_PREINIT_ARRAY
&&
2441 sh
->sh_type
!= SHT_INIT_ARRAY
&&
2442 sh
->sh_type
!= SHT_FINI_ARRAY
&&
2443 strcmp(sh_name
, ".stabstr")
2446 if (sh
->sh_addralign
< 1)
2447 sh
->sh_addralign
= 1;
2448 /* find corresponding section, if any */
2449 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2450 s
= s1
->sections
[j
];
2451 if (!strcmp(s
->name
, sh_name
)) {
2452 if (!strncmp(sh_name
, ".gnu.linkonce",
2453 sizeof(".gnu.linkonce") - 1)) {
2454 /* if a 'linkonce' section is already present, we
2455 do not add it again. It is a little tricky as
2456 symbols can still be defined in
2458 sm_table
[i
].link_once
= 1;
2465 /* not found: create new section */
2466 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2467 /* take as much info as possible from the section. sh_link and
2468 sh_info will be updated later */
2469 s
->sh_addralign
= sh
->sh_addralign
;
2470 s
->sh_entsize
= sh
->sh_entsize
;
2471 sm_table
[i
].new_section
= 1;
2473 if (sh
->sh_type
!= s
->sh_type
) {
2474 tcc_error_noabort("invalid section type");
2478 /* align start of section */
2479 offset
= s
->data_offset
;
2481 if (0 == strcmp(sh_name
, ".stab")) {
2485 if (0 == strcmp(sh_name
, ".stabstr")) {
2490 size
= sh
->sh_addralign
- 1;
2491 offset
= (offset
+ size
) & ~size
;
2492 if (sh
->sh_addralign
> s
->sh_addralign
)
2493 s
->sh_addralign
= sh
->sh_addralign
;
2494 s
->data_offset
= offset
;
2496 sm_table
[i
].offset
= offset
;
2498 /* concatenate sections */
2500 if (sh
->sh_type
!= SHT_NOBITS
) {
2502 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2503 ptr
= section_ptr_add(s
, size
);
2504 read(fd
, ptr
, size
);
2506 s
->data_offset
+= size
;
2511 /* //gr relocate stab strings */
2512 if (stab_index
&& stabstr_index
) {
2515 s
= sm_table
[stab_index
].s
;
2516 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2517 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2518 o
= sm_table
[stabstr_index
].offset
;
2520 a
->n_strx
+= o
, a
++;
2523 /* second short pass to update sh_link and sh_info fields of new
2525 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2527 if (!s
|| !sm_table
[i
].new_section
)
2530 if (sh
->sh_link
> 0)
2531 s
->link
= sm_table
[sh
->sh_link
].s
;
2532 if (sh
->sh_type
== SHT_RELX
) {
2533 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2534 /* update backward link */
2535 s1
->sections
[s
->sh_info
]->reloc
= s
;
2540 /* resolve symbols */
2541 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2544 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2545 if (sym
->st_shndx
!= SHN_UNDEF
&&
2546 sym
->st_shndx
< SHN_LORESERVE
) {
2547 sm
= &sm_table
[sym
->st_shndx
];
2548 if (sm
->link_once
) {
2549 /* if a symbol is in a link once section, we use the
2550 already defined symbol. It is very important to get
2551 correct relocations */
2552 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2553 name
= strtab
+ sym
->st_name
;
2554 sym_index
= find_elf_sym(symtab_section
, name
);
2556 old_to_new_syms
[i
] = sym_index
;
2560 /* if no corresponding section added, no need to add symbol */
2563 /* convert section number */
2564 sym
->st_shndx
= sm
->s
->sh_num
;
2566 sym
->st_value
+= sm
->offset
;
2569 name
= strtab
+ sym
->st_name
;
2570 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2571 sym
->st_info
, sym
->st_other
,
2572 sym
->st_shndx
, name
);
2573 old_to_new_syms
[i
] = sym_index
;
2576 /* third pass to patch relocation entries */
2577 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2582 offset
= sm_table
[i
].offset
;
2583 switch(s
->sh_type
) {
2585 /* take relocation offset information */
2586 offseti
= sm_table
[sh
->sh_info
].offset
;
2587 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2588 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2593 /* convert symbol index */
2594 type
= ELFW(R_TYPE
)(rel
->r_info
);
2595 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2596 /* NOTE: only one symtab assumed */
2597 if (sym_index
>= nb_syms
)
2599 sym_index
= old_to_new_syms
[sym_index
];
2600 /* ignore link_once in rel section. */
2601 if (!sym_index
&& !sm
->link_once
2602 #ifdef TCC_TARGET_ARM
2603 && type
!= R_ARM_V4BX
2607 tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2608 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2611 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2612 /* offset the relocation offset */
2613 rel
->r_offset
+= offseti
;
2614 #ifdef TCC_TARGET_ARM
2615 /* Jumps and branches from a Thumb code to a PLT entry need
2616 special handling since PLT entries are ARM code.
2617 Unconditional bl instructions referencing PLT entries are
2618 handled by converting these instructions into blx
2619 instructions. Other case of instructions referencing a PLT
2620 entry require to add a Thumb stub before the PLT entry to
2621 switch to ARM mode. We set bit 0 of the got offset of a
2622 symbol to indicate such a case. */
2623 if (type
== R_ARM_THM_JUMP24
)
2624 alloc_sym_attr(s1
, sym_index
)->plt_thumb_stub
= 1;
2637 tcc_free(old_to_new_syms
);
2644 typedef struct ArchiveHeader
{
2645 char ar_name
[16]; /* name of this member */
2646 char ar_date
[12]; /* file mtime */
2647 char ar_uid
[6]; /* owner uid; printed as decimal */
2648 char ar_gid
[6]; /* owner gid; printed as decimal */
2649 char ar_mode
[8]; /* file mode, printed as octal */
2650 char ar_size
[10]; /* file size, printed as decimal */
2651 char ar_fmag
[2]; /* should contain ARFMAG */
2654 static int get_be32(const uint8_t *b
)
2656 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2659 /* load only the objects which resolve undefined symbols */
2660 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2662 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2664 const char *ar_names
, *p
;
2665 const uint8_t *ar_index
;
2668 data
= tcc_malloc(size
);
2669 if (read(fd
, data
, size
) != size
)
2671 nsyms
= get_be32(data
);
2672 ar_index
= data
+ 4;
2673 ar_names
= ar_index
+ nsyms
* 4;
2677 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2678 sym_index
= find_elf_sym(symtab_section
, p
);
2680 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2681 if(sym
->st_shndx
== SHN_UNDEF
) {
2682 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2684 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2687 lseek(fd
, off
, SEEK_SET
);
2688 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2703 /* load a '.a' file */
2704 ST_FUNC
int tcc_load_archive(TCCState
*s1
, int fd
)
2711 unsigned long file_offset
;
2713 /* skip magic which was already checked */
2714 read(fd
, magic
, sizeof(magic
));
2717 len
= read(fd
, &hdr
, sizeof(hdr
));
2720 if (len
!= sizeof(hdr
)) {
2721 tcc_error_noabort("invalid archive");
2724 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2725 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2726 size
= strtol(ar_size
, NULL
, 0);
2727 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2728 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2729 if (ar_name
[i
] != ' ')
2732 ar_name
[i
+ 1] = '\0';
2733 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2734 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2736 size
= (size
+ 1) & ~1;
2737 if (!strcmp(ar_name
, "/")) {
2738 /* coff symbol table : we handle it */
2739 if(s1
->alacarte_link
)
2740 return tcc_load_alacarte(s1
, fd
, size
);
2741 } else if (!strcmp(ar_name
, "//") ||
2742 !strcmp(ar_name
, "__.SYMDEF") ||
2743 !strcmp(ar_name
, "__.SYMDEF/") ||
2744 !strcmp(ar_name
, "ARFILENAMES/")) {
2745 /* skip symbol table or archive names */
2747 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2750 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2755 #ifndef TCC_TARGET_PE
2756 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2757 is referenced by the user (so it should be added as DT_NEEDED in
2758 the generated ELF file) */
2759 ST_FUNC
int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2762 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2763 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2764 ElfW(Sym
) *sym
, *dynsym
;
2765 ElfW(Dyn
) *dt
, *dynamic
;
2766 unsigned char *dynstr
;
2767 const char *name
, *soname
;
2768 DLLReference
*dllref
;
2770 read(fd
, &ehdr
, sizeof(ehdr
));
2772 /* test CPU specific stuff */
2773 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2774 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2775 tcc_error_noabort("bad architecture");
2780 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2782 /* load dynamic section and dynamic symbols */
2786 dynsym
= NULL
; /* avoid warning */
2787 dynstr
= NULL
; /* avoid warning */
2788 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2789 switch(sh
->sh_type
) {
2791 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2792 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2795 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2796 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2797 sh1
= &shdr
[sh
->sh_link
];
2798 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2805 /* compute the real library name */
2806 soname
= tcc_basename(filename
);
2808 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2809 if (dt
->d_tag
== DT_SONAME
) {
2810 soname
= dynstr
+ dt
->d_un
.d_val
;
2814 /* if the dll is already loaded, do not load it */
2815 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2816 dllref
= s1
->loaded_dlls
[i
];
2817 if (!strcmp(soname
, dllref
->name
)) {
2818 /* but update level if needed */
2819 if (level
< dllref
->level
)
2820 dllref
->level
= level
;
2826 // printf("loading dll '%s'\n", soname);
2828 /* add the dll and its level */
2829 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2830 dllref
->level
= level
;
2831 strcpy(dllref
->name
, soname
);
2832 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2834 /* add dynamic symbols in dynsym_section */
2835 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2836 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2837 if (sym_bind
== STB_LOCAL
)
2839 name
= dynstr
+ sym
->st_name
;
2840 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2841 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2844 /* load all referenced DLLs */
2845 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2848 name
= dynstr
+ dt
->d_un
.d_val
;
2849 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2850 dllref
= s1
->loaded_dlls
[j
];
2851 if (!strcmp(name
, dllref
->name
))
2852 goto already_loaded
;
2854 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2855 tcc_error_noabort("referenced dll '%s' not found", name
);
2872 #define LD_TOK_NAME 256
2873 #define LD_TOK_EOF (-1)
2875 /* return next ld script token */
2876 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2894 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2895 ch
= file
->buf_ptr
[0];
2903 /* case 'a' ... 'z': */
2930 /* case 'A' ... 'z': */
2965 if (!((ch
>= 'a' && ch
<= 'z') ||
2966 (ch
>= 'A' && ch
<= 'Z') ||
2967 (ch
>= '0' && ch
<= '9') ||
2968 strchr("/.-_+=$:\\,~", ch
)))
2970 if ((q
- name
) < name_size
- 1) {
2987 printf("tok=%c %d\n", c
, c
);
2988 if (c
== LD_TOK_NAME
)
2989 printf(" name=%s\n", name
);
2994 static int ld_add_file(TCCState
*s1
, const char filename
[])
2998 ret
= tcc_add_file_internal(s1
, filename
, 0);
3000 ret
= tcc_add_dll(s1
, filename
, 0);
3004 static inline int new_undef_syms(void)
3007 ret
= new_undef_sym
;
3012 static int ld_add_file_list(TCCState
*s1
, const char *cmd
, int as_needed
)
3014 char filename
[1024], libname
[1024];
3015 int t
, group
, nblibs
= 0, ret
= 0;
3018 group
= !strcmp(cmd
, "GROUP");
3021 t
= ld_next(s1
, filename
, sizeof(filename
));
3024 t
= ld_next(s1
, filename
, sizeof(filename
));
3027 if (t
== LD_TOK_EOF
) {
3028 tcc_error_noabort("unexpected end of file");
3030 goto lib_parse_error
;
3031 } else if (t
== ')') {
3033 } else if (t
== '-') {
3034 t
= ld_next(s1
, filename
, sizeof(filename
));
3035 if ((t
!= LD_TOK_NAME
) || (filename
[0] != 'l')) {
3036 tcc_error_noabort("library name expected");
3038 goto lib_parse_error
;
3040 pstrcpy(libname
, sizeof libname
, &filename
[1]);
3041 if (s1
->static_link
) {
3042 snprintf(filename
, sizeof filename
, "lib%s.a", libname
);
3044 snprintf(filename
, sizeof filename
, "lib%s.so", libname
);
3046 } else if (t
!= LD_TOK_NAME
) {
3047 tcc_error_noabort("filename expected");
3049 goto lib_parse_error
;
3051 if (!strcmp(filename
, "AS_NEEDED")) {
3052 ret
= ld_add_file_list(s1
, cmd
, 1);
3054 goto lib_parse_error
;
3056 /* TODO: Implement AS_NEEDED support. Ignore it for now */
3058 ret
= ld_add_file(s1
, filename
);
3060 goto lib_parse_error
;
3062 /* Add the filename *and* the libname to avoid future conversions */
3063 dynarray_add((void ***) &libs
, &nblibs
, tcc_strdup(filename
));
3064 if (libname
[0] != '\0')
3065 dynarray_add((void ***) &libs
, &nblibs
, tcc_strdup(libname
));
3069 t
= ld_next(s1
, filename
, sizeof(filename
));
3071 t
= ld_next(s1
, filename
, sizeof(filename
));
3074 if (group
&& !as_needed
) {
3075 while (new_undef_syms()) {
3078 for (i
= 0; i
< nblibs
; i
++)
3079 ld_add_file(s1
, libs
[i
]);
3083 dynarray_reset(&libs
, &nblibs
);
3087 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
3089 ST_FUNC
int tcc_load_ldscript(TCCState
*s1
)
3092 char filename
[1024];
3095 ch
= file
->buf_ptr
[0];
3098 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3099 if (t
== LD_TOK_EOF
)
3101 else if (t
!= LD_TOK_NAME
)
3103 if (!strcmp(cmd
, "INPUT") ||
3104 !strcmp(cmd
, "GROUP")) {
3105 ret
= ld_add_file_list(s1
, cmd
, 0);
3108 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
3109 !strcmp(cmd
, "TARGET")) {
3110 /* ignore some commands */
3111 t
= ld_next(s1
, cmd
, sizeof(cmd
));
3115 t
= ld_next(s1
, filename
, sizeof(filename
));
3116 if (t
== LD_TOK_EOF
) {
3117 tcc_error_noabort("unexpected end of file");
3119 } else if (t
== ')') {
3129 #endif /* ndef TCC_TARGET_PE */