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
21 #ifdef TCC_TARGET_X86_64
22 #define ElfW_Rel ElfW(Rela)
23 #define SHT_RELX SHT_RELA
24 #define REL_SECTION_FMT ".rela%s"
25 /* x86-64 requires PLT for DLLs */
26 #define TCC_OUTPUT_DLL_WITH_PLT
28 #define ElfW_Rel ElfW(Rel)
29 #define SHT_RELX SHT_REL
30 #define REL_SECTION_FMT ".rel%s"
33 /* XXX: DLL with PLT would only work with x86-64 for now */
34 //#define TCC_OUTPUT_DLL_WITH_PLT
36 static int put_elf_str(Section
*s
, const char *sym
)
41 len
= strlen(sym
) + 1;
42 offset
= s
->data_offset
;
43 ptr
= section_ptr_add(s
, len
);
44 memcpy(ptr
, sym
, len
);
48 /* elf symbol hashing function */
49 static unsigned long elf_hash(const unsigned char *name
)
51 unsigned long h
= 0, g
;
54 h
= (h
<< 4) + *name
++;
63 /* rebuild hash table of section s */
64 /* NOTE: we do factorize the hash table code to go faster */
65 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
68 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
71 strtab
= s
->link
->data
;
72 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
74 s
->hash
->data_offset
= 0;
75 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
80 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
81 ptr
+= nb_buckets
+ 1;
83 sym
= (ElfW(Sym
) *)s
->data
+ 1;
84 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
85 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
86 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
97 /* return the symbol number */
98 static int put_elf_sym(Section
*s
,
99 unsigned long value
, unsigned long size
,
100 int info
, int other
, int shndx
, const char *name
)
102 int name_offset
, sym_index
;
107 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
109 name_offset
= put_elf_str(s
->link
, name
);
112 /* XXX: endianness */
113 sym
->st_name
= name_offset
;
114 sym
->st_value
= value
;
117 sym
->st_other
= other
;
118 sym
->st_shndx
= shndx
;
119 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
123 ptr
= section_ptr_add(hs
, sizeof(int));
124 base
= (int *)hs
->data
;
125 /* only add global or weak symbols */
126 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
127 /* add another hashing entry */
129 h
= elf_hash(name
) % nbuckets
;
131 base
[2 + h
] = sym_index
;
133 /* we resize the hash table */
134 hs
->nb_hashed_syms
++;
135 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
136 rebuild_hash(s
, 2 * nbuckets
);
146 /* find global ELF symbol 'name' and return its index. Return 0 if not
148 static int find_elf_sym(Section
*s
, const char *name
)
152 int nbuckets
, sym_index
, h
;
158 nbuckets
= ((int *)hs
->data
)[0];
159 h
= elf_hash(name
) % nbuckets
;
160 sym_index
= ((int *)hs
->data
)[2 + h
];
161 while (sym_index
!= 0) {
162 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
163 name1
= s
->link
->data
+ sym
->st_name
;
164 if (!strcmp(name
, name1
))
166 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
171 /* return elf symbol value or error */
172 int tcc_get_symbol(TCCState
*s
, unsigned long *pval
, const char *name
)
177 sym_index
= find_elf_sym(symtab_section
, name
);
180 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
181 *pval
= sym
->st_value
;
185 void *tcc_get_symbol_err(TCCState
*s
, const char *name
)
188 if (tcc_get_symbol(s
, &val
, name
) < 0)
189 error("%s not defined", name
);
193 /* add an elf symbol : check if it is already defined and patch
194 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
195 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
196 int info
, int other
, int sh_num
, const char *name
)
199 int sym_bind
, sym_index
, sym_type
, esym_bind
;
200 unsigned char sym_vis
, esym_vis
, new_vis
;
202 sym_bind
= ELFW(ST_BIND
)(info
);
203 sym_type
= ELFW(ST_TYPE
)(info
);
204 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
206 if (sym_bind
!= STB_LOCAL
) {
207 /* we search global or weak symbols */
208 sym_index
= find_elf_sym(s
, name
);
211 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
212 if (esym
->st_shndx
!= SHN_UNDEF
) {
213 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
214 /* propagate the most constraining visibility */
215 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
216 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
217 if (esym_vis
== STV_DEFAULT
) {
219 } else if (sym_vis
== STV_DEFAULT
) {
222 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
224 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
226 other
= esym
->st_other
; /* in case we have to patch esym */
227 if (sh_num
== SHN_UNDEF
) {
228 /* ignore adding of undefined symbol if the
229 corresponding symbol is already defined */
230 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
231 /* global overrides weak, so patch */
233 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
234 /* weak is ignored if already global */
235 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
236 /* ignore hidden symbols after */
237 } else if (esym
->st_shndx
== SHN_COMMON
&& sh_num
< SHN_LORESERVE
) {
238 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
239 No idea if this is the correct solution ... */
241 } else if (s
== tcc_state
->dynsymtab_section
) {
242 /* we accept that two DLL define the same symbol */
245 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
246 sym_bind
, sh_num
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
248 error_noabort("'%s' defined twice", name
);
252 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
253 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 static 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 */
298 unsigned int n_strx
; /* index into string table of name */
299 unsigned char n_type
; /* type of symbol */
300 unsigned char n_other
; /* misc info (usually empty) */
301 unsigned short n_desc
; /* description field */
302 unsigned int n_value
; /* value of symbol */
305 static void put_stabs(const char *str
, int type
, int other
, int desc
,
310 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
312 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
317 sym
->n_other
= other
;
319 sym
->n_value
= value
;
322 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
323 unsigned long value
, Section
*sec
, int sym_index
)
325 put_stabs(str
, type
, other
, desc
, value
);
326 put_elf_reloc(symtab_section
, stab_section
,
327 stab_section
->data_offset
- sizeof(unsigned int),
328 R_DATA_32
, sym_index
);
331 static void put_stabn(int type
, int other
, int desc
, int value
)
333 put_stabs(NULL
, type
, other
, desc
, value
);
336 static void put_stabd(int type
, int other
, int desc
)
338 put_stabs(NULL
, type
, other
, desc
, 0);
341 /* In an ELF file symbol table, the local symbols must appear below
342 the global and weak ones. Since TCC cannot sort it while generating
343 the code, we must do it after. All the relocation tables are also
344 modified to take into account the symbol table sorting */
345 static void sort_syms(TCCState
*s1
, Section
*s
)
347 int *old_to_new_syms
;
351 ElfW_Rel
*rel
, *rel_end
;
355 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
356 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
357 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
359 /* first pass for local symbols */
360 p
= (ElfW(Sym
) *)s
->data
;
362 for(i
= 0; i
< nb_syms
; i
++) {
363 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
364 old_to_new_syms
[i
] = q
- new_syms
;
369 /* save the number of local symbols in section header */
370 s
->sh_info
= q
- new_syms
;
372 /* then second pass for non local symbols */
373 p
= (ElfW(Sym
) *)s
->data
;
374 for(i
= 0; i
< nb_syms
; i
++) {
375 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
376 old_to_new_syms
[i
] = q
- new_syms
;
382 /* we copy the new symbols to the old */
383 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
386 /* now we modify all the relocations */
387 for(i
= 1; i
< s1
->nb_sections
; i
++) {
388 sr
= s1
->sections
[i
];
389 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
390 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
391 for(rel
= (ElfW_Rel
*)sr
->data
;
394 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
395 type
= ELFW(R_TYPE
)(rel
->r_info
);
396 sym_index
= old_to_new_syms
[sym_index
];
397 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
402 tcc_free(old_to_new_syms
);
405 /* relocate common symbols in the .bss section */
406 static void relocate_common_syms(void)
408 ElfW(Sym
) *sym
, *sym_end
;
409 unsigned long offset
, align
;
411 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
412 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
415 if (sym
->st_shndx
== SHN_COMMON
) {
417 align
= sym
->st_value
;
418 offset
= bss_section
->data_offset
;
419 offset
= (offset
+ align
- 1) & -align
;
420 sym
->st_value
= offset
;
421 sym
->st_shndx
= bss_section
->sh_num
;
422 offset
+= sym
->st_size
;
423 bss_section
->data_offset
= offset
;
428 /* relocate symbol table, resolve undefined symbols if do_resolve is
429 true and output error if undefined symbol. */
430 static void relocate_syms(TCCState
*s1
, int do_resolve
)
432 ElfW(Sym
) *sym
, *esym
, *sym_end
;
433 int sym_bind
, sh_num
, sym_index
;
437 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
438 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
441 sh_num
= sym
->st_shndx
;
442 if (sh_num
== SHN_UNDEF
) {
443 name
= strtab_section
->data
+ sym
->st_name
;
445 name
= symtab_section
->link
->data
+ sym
->st_name
;
446 addr
= (unsigned long)resolve_sym(s1
, name
, ELFW(ST_TYPE
)(sym
->st_info
));
448 sym
->st_value
= addr
;
451 } else if (s1
->dynsym
) {
452 /* if dynamic symbol exist, then use it */
453 sym_index
= find_elf_sym(s1
->dynsym
, name
);
455 esym
= &((ElfW(Sym
) *)s1
->dynsym
->data
)[sym_index
];
456 sym
->st_value
= esym
->st_value
;
460 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
462 if (!strcmp(name
, "_fp_hw"))
464 /* only weak symbols are accepted to be undefined. Their
466 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
467 if (sym_bind
== STB_WEAK
) {
470 error_noabort("undefined symbol '%s'", name
);
472 } else if (sh_num
< SHN_LORESERVE
) {
473 /* add section base */
474 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
480 #ifdef TCC_TARGET_X86_64
481 #define JMP_TABLE_ENTRY_SIZE 14
482 static unsigned long add_jmp_table(TCCState
*s1
, unsigned long val
)
484 char *p
= (char *)section_ptr_add(text_section
, JMP_TABLE_ENTRY_SIZE
);
489 *(unsigned long *)(p
+ 6) = val
;
490 return (unsigned long)p
;
493 static unsigned long add_got_table(TCCState
*s1
, unsigned long val
)
496 (unsigned long *)section_ptr_add(text_section
, sizeof(void *));
498 return (unsigned long)p
;
502 /* relocate a given section (CPU dependent) */
503 static void relocate_section(TCCState
*s1
, Section
*s
)
506 ElfW_Rel
*rel
, *rel_end
, *qrel
;
510 unsigned long val
, addr
;
514 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
515 qrel
= (ElfW_Rel
*)sr
->data
;
519 ptr
= s
->data
+ rel
->r_offset
;
521 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
522 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
524 #ifdef TCC_TARGET_X86_64
525 /* XXX: not tested */
526 val
+= rel
->r_addend
;
528 type
= ELFW(R_TYPE
)(rel
->r_info
);
529 addr
= s
->sh_addr
+ rel
->r_offset
;
533 #if defined(TCC_TARGET_I386)
535 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
536 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
537 qrel
->r_offset
= rel
->r_offset
;
539 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_32
);
543 qrel
->r_info
= ELFW(R_INFO
)(0, R_386_RELATIVE
);
550 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
552 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
554 qrel
->r_offset
= rel
->r_offset
;
555 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_PC32
);
560 *(int *)ptr
+= val
- addr
;
563 *(int *)ptr
+= val
- addr
;
570 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
573 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
576 /* we load the got offset */
577 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
579 #elif defined(TCC_TARGET_ARM)
586 x
= (*(int *)ptr
)&0xffffff;
587 (*(int *)ptr
) &= 0xff000000;
592 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
593 error("can't relocate value at %x",addr
);
602 x
= (*(int *)ptr
) & 0x7fffffff;
603 (*(int *)ptr
) &= 0x80000000;
606 if((x
^(x
>>1))&0x40000000)
607 error("can't relocate value at %x",addr
);
608 (*(int *)ptr
) |= x
& 0x7fffffff;
613 case R_ARM_BASE_PREL
:
614 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
617 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
620 /* we load the got offset */
621 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
626 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
627 type
,addr
,(unsigned int )ptr
,val
);
629 #elif defined(TCC_TARGET_C67)
637 /* put the low 16 bits of the absolute address */
638 // add to what is already there
640 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
641 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
643 //patch both at once - assumes always in pairs Low - High
645 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
646 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
652 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
653 type
,addr
,(unsigned int )ptr
,val
);
655 #elif defined(TCC_TARGET_X86_64)
657 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
658 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
659 qrel
->r_addend
= *(long long *)ptr
+ val
;
662 *(long long *)ptr
+= val
;
666 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
667 /* XXX: this logic may depend on TCC's codegen
668 now TCC uses R_X86_64_32 even for a 64bit pointer */
669 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
670 qrel
->r_addend
= *(int *)ptr
+ val
;
675 case R_X86_64_PC32
: {
676 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
678 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
680 qrel
->r_offset
= rel
->r_offset
;
681 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_X86_64_PC32
);
682 qrel
->r_addend
= *(int *)ptr
;
687 long diff
= val
- addr
;
688 if (diff
<= -2147483647 || diff
> 2147483647) {
689 /* XXX: naive support for over 32bit jump */
690 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
691 val
= add_jmp_table(s1
, val
);
694 if (diff
<= -2147483647 || diff
> 2147483647) {
695 error("internal error: relocation failed");
702 *(int *)ptr
+= val
- addr
;
704 case R_X86_64_GLOB_DAT
:
705 case R_X86_64_JUMP_SLOT
:
708 case R_X86_64_GOTPCREL
:
709 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
710 val
= add_got_table(s1
, val
- rel
->r_addend
) + rel
->r_addend
;
711 *(int *)ptr
+= val
- addr
;
714 *(int *)ptr
+= (s1
->got
->sh_addr
- addr
+
715 s1
->got_offsets
[sym_index
] - 4);
717 case R_X86_64_GOTTPOFF
:
718 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
721 /* we load the got offset */
722 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
725 #error unsupported processor
729 /* if the relocation is allocated, we change its symbol table */
730 if (sr
->sh_flags
& SHF_ALLOC
)
731 sr
->link
= s1
->dynsym
;
734 /* relocate relocation table in 'sr' */
735 static void relocate_rel(TCCState
*s1
, Section
*sr
)
738 ElfW_Rel
*rel
, *rel_end
;
740 s
= s1
->sections
[sr
->sh_info
];
741 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
742 for(rel
= (ElfW_Rel
*)sr
->data
;
745 rel
->r_offset
+= s
->sh_addr
;
749 /* count the number of dynamic relocations so that we can reserve
751 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
753 ElfW_Rel
*rel
, *rel_end
;
754 int sym_index
, esym_index
, type
, count
;
757 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
758 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
759 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
760 type
= ELFW(R_TYPE
)(rel
->r_info
);
762 #if defined(TCC_TARGET_I386)
764 #elif defined(TCC_TARGET_X86_64)
771 #if defined(TCC_TARGET_I386)
773 #elif defined(TCC_TARGET_X86_64)
776 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
785 /* allocate the section */
786 sr
->sh_flags
|= SHF_ALLOC
;
787 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
792 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
797 if (index
>= s1
->nb_got_offsets
) {
798 /* find immediately bigger power of 2 and reallocate array */
802 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
804 error("memory full");
805 s1
->got_offsets
= tab
;
806 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
807 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
808 s1
->nb_got_offsets
= n
;
810 s1
->got_offsets
[index
] = val
;
813 /* XXX: suppress that */
814 static void put32(unsigned char *p
, uint32_t val
)
822 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
823 defined(TCC_TARGET_X86_64)
824 static uint32_t get32(unsigned char *p
)
826 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
830 static void build_got(TCCState
*s1
)
834 /* if no got, then create it */
835 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
836 s1
->got
->sh_entsize
= 4;
837 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
838 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
839 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
841 /* keep space for _DYNAMIC pointer, if present */
843 /* two dummy got entries */
847 /* keep space for _DYNAMIC pointer, if present */
850 /* two dummy got entries */
858 /* put a got entry corresponding to a symbol in symtab_section. 'size'
859 and 'info' can be modifed if more precise info comes from the DLL */
860 static void put_got_entry(TCCState
*s1
,
861 int reloc_type
, unsigned long size
, int info
,
867 unsigned long offset
;
873 /* if a got entry already exists for that symbol, no need to add one */
874 if (sym_index
< s1
->nb_got_offsets
&&
875 s1
->got_offsets
[sym_index
] != 0)
878 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
881 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
882 name
= symtab_section
->link
->data
+ sym
->st_name
;
883 offset
= sym
->st_value
;
884 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
886 #ifdef TCC_TARGET_X86_64
896 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
899 /* if we build a DLL, we add a %ebx offset */
900 if (s1
->output_type
== TCC_OUTPUT_DLL
)
906 /* add a PLT entry */
908 if (plt
->data_offset
== 0) {
909 /* first plt entry */
910 p
= section_ptr_add(plt
, 16);
911 p
[0] = 0xff; /* pushl got + PTR_SIZE */
913 put32(p
+ 2, PTR_SIZE
);
914 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
916 put32(p
+ 8, PTR_SIZE
* 2);
919 p
= section_ptr_add(plt
, 16);
920 p
[0] = 0xff; /* jmp *(got + x) */
922 put32(p
+ 2, s1
->got
->data_offset
);
923 p
[6] = 0x68; /* push $xxx */
924 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
925 p
[11] = 0xe9; /* jmp plt_start */
926 put32(p
+ 12, -(plt
->data_offset
));
928 /* the symbol is modified so that it will be relocated to
930 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
931 if (s1
->output_type
== TCC_OUTPUT_EXE
)
933 offset
= plt
->data_offset
- 16;
935 #elif defined(TCC_TARGET_ARM)
936 if (reloc_type
== R_ARM_JUMP_SLOT
) {
940 /* if we build a DLL, we add a %ebx offset */
941 if (s1
->output_type
== TCC_OUTPUT_DLL
)
942 error("DLLs unimplemented!");
944 /* add a PLT entry */
946 if (plt
->data_offset
== 0) {
947 /* first plt entry */
948 p
= section_ptr_add(plt
, 16);
949 put32(p
, 0xe52de004);
950 put32(p
+ 4, 0xe59fe010);
951 put32(p
+ 8, 0xe08fe00e);
952 put32(p
+ 12, 0xe5bef008);
955 p
= section_ptr_add(plt
, 16);
956 put32(p
, 0xe59fc004);
957 put32(p
+4, 0xe08fc00c);
958 put32(p
+8, 0xe59cf000);
959 put32(p
+12, s1
->got
->data_offset
);
961 /* the symbol is modified so that it will be relocated to
963 if (s1
->output_type
== TCC_OUTPUT_EXE
)
964 offset
= plt
->data_offset
- 16;
966 #elif defined(TCC_TARGET_C67)
967 error("C67 got not implemented");
969 #error unsupported CPU
971 index
= put_elf_sym(s1
->dynsym
, offset
,
972 size
, info
, 0, sym
->st_shndx
, name
);
973 /* put a got entry */
974 put_elf_reloc(s1
->dynsym
, s1
->got
,
975 s1
->got
->data_offset
,
978 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
982 /* build GOT and PLT entries */
983 static void build_got_entries(TCCState
*s1
)
986 ElfW_Rel
*rel
, *rel_end
;
988 int i
, type
, reloc_type
, sym_index
;
990 for(i
= 1; i
< s1
->nb_sections
; i
++) {
992 if (s
->sh_type
!= SHT_RELX
)
994 /* no need to handle got relocations */
995 if (s
->link
!= symtab_section
)
998 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
999 for(rel
= (ElfW_Rel
*)s
->data
;
1002 type
= ELFW(R_TYPE
)(rel
->r_info
);
1004 #if defined(TCC_TARGET_I386)
1011 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1012 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1013 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1014 /* look at the symbol got offset. If none, then add one */
1015 if (type
== R_386_GOT32
)
1016 reloc_type
= R_386_GLOB_DAT
;
1018 reloc_type
= R_386_JMP_SLOT
;
1019 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1023 #elif defined(TCC_TARGET_ARM)
1024 case R_ARM_GOT_BREL
:
1025 case R_ARM_GOTOFF32
:
1026 case R_ARM_BASE_PREL
:
1030 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1031 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1032 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1033 /* look at the symbol got offset. If none, then add one */
1034 if (type
== R_ARM_GOT_BREL
)
1035 reloc_type
= R_ARM_GLOB_DAT
;
1037 reloc_type
= R_ARM_JUMP_SLOT
;
1038 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1042 #elif defined(TCC_TARGET_C67)
1049 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1050 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1051 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1052 /* look at the symbol got offset. If none, then add one */
1053 if (type
== R_C60_GOT32
)
1054 reloc_type
= R_C60_GLOB_DAT
;
1056 reloc_type
= R_C60_JMP_SLOT
;
1057 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1061 #elif defined(TCC_TARGET_X86_64)
1062 case R_X86_64_GOT32
:
1063 case R_X86_64_GOTTPOFF
:
1064 case R_X86_64_GOTPCREL
:
1065 case R_X86_64_PLT32
:
1068 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
||
1069 type
== R_X86_64_PLT32
) {
1070 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1071 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1072 /* look at the symbol got offset. If none, then add one */
1073 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
)
1074 reloc_type
= R_X86_64_GLOB_DAT
;
1076 reloc_type
= R_X86_64_JUMP_SLOT
;
1077 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1082 #error unsupported CPU
1091 static Section
*new_symtab(TCCState
*s1
,
1092 const char *symtab_name
, int sh_type
, int sh_flags
,
1093 const char *strtab_name
,
1094 const char *hash_name
, int hash_sh_flags
)
1096 Section
*symtab
, *strtab
, *hash
;
1097 int *ptr
, nb_buckets
;
1099 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1100 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1101 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1102 put_elf_str(strtab
, "");
1103 symtab
->link
= strtab
;
1104 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1108 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1109 hash
->sh_entsize
= sizeof(int);
1110 symtab
->hash
= hash
;
1111 hash
->link
= symtab
;
1113 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1114 ptr
[0] = nb_buckets
;
1116 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1120 /* put dynamic tag */
1121 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1124 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1126 dyn
->d_un
.d_val
= val
;
1129 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1133 char sym_start
[1024];
1136 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1137 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1139 s
= find_section(s1
, section_name
);
1144 end_offset
= s
->data_offset
;
1147 add_elf_sym(symtab_section
,
1149 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1150 s
->sh_num
, sym_start
);
1151 add_elf_sym(symtab_section
,
1153 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1154 s
->sh_num
, sym_end
);
1157 /* add tcc runtime libraries */
1158 static void tcc_add_runtime(TCCState
*s1
)
1160 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1164 #ifdef CONFIG_TCC_BCHECK
1165 if (do_bounds_check
) {
1167 Section
*init_section
;
1168 unsigned char *pinit
;
1171 /* XXX: add an object file to do that */
1172 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1174 add_elf_sym(symtab_section
, 0, 0,
1175 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1176 bounds_section
->sh_num
, "__bounds_start");
1177 /* add bound check code */
1178 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "bcheck.o");
1179 tcc_add_file(s1
, buf
);
1180 #ifdef TCC_TARGET_I386
1181 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1182 /* add 'call __bound_init()' in .init section */
1183 init_section
= find_section(s1
, ".init");
1184 pinit
= section_ptr_add(init_section
, 5);
1186 put32(pinit
+ 1, -4);
1187 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1188 put_elf_reloc(symtab_section
, init_section
,
1189 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1195 if (!s1
->nostdlib
) {
1196 tcc_add_library(s1
, "c");
1198 #ifdef CONFIG_USE_LIBGCC
1199 tcc_add_file(s1
, CONFIG_SYSROOT
"/lib/libgcc_s.so.1");
1201 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "libtcc1.a");
1202 tcc_add_file(s1
, buf
);
1205 /* add crt end if not memory output */
1206 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1207 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1211 /* add various standard linker symbols (must be done after the
1212 sections are filled (for example after allocating common
1214 static void tcc_add_linker_symbols(TCCState
*s1
)
1220 add_elf_sym(symtab_section
,
1221 text_section
->data_offset
, 0,
1222 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1223 text_section
->sh_num
, "_etext");
1224 add_elf_sym(symtab_section
,
1225 data_section
->data_offset
, 0,
1226 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1227 data_section
->sh_num
, "_edata");
1228 add_elf_sym(symtab_section
,
1229 bss_section
->data_offset
, 0,
1230 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1231 bss_section
->sh_num
, "_end");
1232 /* horrible new standard ldscript defines */
1233 add_init_array_defines(s1
, ".preinit_array");
1234 add_init_array_defines(s1
, ".init_array");
1235 add_init_array_defines(s1
, ".fini_array");
1237 /* add start and stop symbols for sections whose name can be
1239 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1240 s
= s1
->sections
[i
];
1241 if (s
->sh_type
== SHT_PROGBITS
&&
1242 (s
->sh_flags
& SHF_ALLOC
)) {
1246 /* check if section name can be expressed in C */
1252 if (!isid(ch
) && !isnum(ch
))
1256 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1257 add_elf_sym(symtab_section
,
1259 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1261 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1262 add_elf_sym(symtab_section
,
1264 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1271 /* name of ELF interpreter */
1273 static char elf_interp
[] = "/usr/libexec/ld-elf.so.1";
1276 static char elf_interp
[] = "/lib/ld-linux.so.3";
1277 #elif defined(TCC_TARGET_X86_64)
1278 static char elf_interp
[] = "/lib/ld-linux-x86-64.so.2";
1280 static char elf_interp
[] = "/lib/ld-linux.so.2";
1284 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1285 const int *section_order
)
1288 int i
, offset
, size
;
1291 for(i
=1;i
<s1
->nb_sections
;i
++) {
1292 s
= s1
->sections
[section_order
[i
]];
1293 if (s
->sh_type
!= SHT_NOBITS
&&
1294 (s
->sh_flags
& SHF_ALLOC
)) {
1295 while (offset
< s
->sh_offset
) {
1300 fwrite(s
->data
, 1, size
, f
);
1306 /* output an ELF file */
1307 /* XXX: suppress unneeded sections */
1308 int elf_output_file(TCCState
*s1
, const char *filename
)
1314 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1316 Section
*strsec
, *s
;
1317 ElfW(Shdr
) shdr
, *sh
;
1318 ElfW(Phdr
) *phdr
, *ph
;
1319 Section
*interp
, *dynamic
, *dynstr
;
1320 unsigned long saved_dynamic_data_offset
;
1322 int type
, file_type
;
1323 unsigned long rel_addr
, rel_size
;
1325 file_type
= s1
->output_type
;
1328 if (file_type
!= TCC_OUTPUT_OBJ
) {
1329 tcc_add_runtime(s1
);
1333 section_order
= NULL
;
1336 dynstr
= NULL
; /* avoid warning */
1337 saved_dynamic_data_offset
= 0; /* avoid warning */
1339 if (file_type
!= TCC_OUTPUT_OBJ
) {
1340 relocate_common_syms();
1342 tcc_add_linker_symbols(s1
);
1344 if (!s1
->static_link
) {
1346 int sym_index
, index
;
1347 ElfW(Sym
) *esym
, *sym_end
;
1349 if (file_type
== TCC_OUTPUT_EXE
) {
1351 /* add interpreter section only if executable */
1352 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1353 interp
->sh_addralign
= 1;
1354 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
1355 strcpy(ptr
, elf_interp
);
1358 /* add dynamic symbol table */
1359 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1361 ".hash", SHF_ALLOC
);
1362 dynstr
= s1
->dynsym
->link
;
1364 /* add dynamic section */
1365 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1366 SHF_ALLOC
| SHF_WRITE
);
1367 dynamic
->link
= dynstr
;
1368 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1371 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1372 SHF_ALLOC
| SHF_EXECINSTR
);
1373 s1
->plt
->sh_entsize
= 4;
1377 /* scan for undefined symbols and see if they are in the
1378 dynamic symbols. If a symbol STT_FUNC is found, then we
1379 add it in the PLT. If a symbol STT_OBJECT is found, we
1380 add it in the .bss section with a suitable relocation */
1381 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1382 symtab_section
->data_offset
);
1383 if (file_type
== TCC_OUTPUT_EXE
) {
1384 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1387 if (sym
->st_shndx
== SHN_UNDEF
) {
1388 name
= symtab_section
->link
->data
+ sym
->st_name
;
1389 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1391 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1392 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1393 if (type
== STT_FUNC
) {
1394 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1396 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1397 } else if (type
== STT_OBJECT
) {
1398 unsigned long offset
;
1399 offset
= bss_section
->data_offset
;
1400 /* XXX: which alignment ? */
1401 offset
= (offset
+ 16 - 1) & -16;
1402 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1404 bss_section
->sh_num
, name
);
1405 put_elf_reloc(s1
->dynsym
, bss_section
,
1406 offset
, R_COPY
, index
);
1407 offset
+= esym
->st_size
;
1408 bss_section
->data_offset
= offset
;
1411 /* STB_WEAK undefined symbols are accepted */
1412 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1414 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1415 !strcmp(name
, "_fp_hw")) {
1417 error_noabort("undefined symbol '%s'", name
);
1420 } else if (s1
->rdynamic
&&
1421 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1422 /* if -rdynamic option, then export all non
1424 name
= symtab_section
->link
->data
+ sym
->st_name
;
1425 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1427 sym
->st_shndx
, name
);
1434 /* now look at unresolved dynamic symbols and export
1435 corresponding symbol */
1436 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1437 s1
->dynsymtab_section
->data_offset
);
1438 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1441 if (esym
->st_shndx
== SHN_UNDEF
) {
1442 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1443 sym_index
= find_elf_sym(symtab_section
, name
);
1445 /* XXX: avoid adding a symbol if already
1446 present because of -rdynamic ? */
1447 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1448 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1450 sym
->st_shndx
, name
);
1452 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1453 /* weak symbols can stay undefined */
1455 warning("undefined dynamic symbol '%s'", name
);
1462 /* shared library case : we simply export all the global symbols */
1463 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1464 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1465 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1468 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1469 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1470 if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
&&
1471 sym
->st_shndx
== SHN_UNDEF
) {
1472 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1474 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1476 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1477 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1479 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1484 name
= symtab_section
->link
->data
+ sym
->st_name
;
1485 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1487 sym
->st_shndx
, name
);
1488 s1
->symtab_to_dynsym
[sym
-
1489 (ElfW(Sym
) *)symtab_section
->data
] =
1496 build_got_entries(s1
);
1498 /* add a list of needed dlls */
1499 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1500 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1501 if (dllref
->level
== 0)
1502 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1504 /* XXX: currently, since we do not handle PIC code, we
1505 must relocate the readonly segments */
1506 if (file_type
== TCC_OUTPUT_DLL
) {
1508 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1509 put_dt(dynamic
, DT_TEXTREL
, 0);
1512 /* add necessary space for other entries */
1513 saved_dynamic_data_offset
= dynamic
->data_offset
;
1514 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * 9;
1516 /* still need to build got entries in case of static link */
1517 build_got_entries(s1
);
1521 memset(&ehdr
, 0, sizeof(ehdr
));
1523 /* we add a section for symbols */
1524 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1525 put_elf_str(strsec
, "");
1527 /* compute number of sections */
1528 shnum
= s1
->nb_sections
;
1530 /* this array is used to reorder sections in the output file */
1531 section_order
= tcc_malloc(sizeof(int) * shnum
);
1532 section_order
[0] = 0;
1535 /* compute number of program headers */
1538 case TCC_OUTPUT_OBJ
:
1541 case TCC_OUTPUT_EXE
:
1542 if (!s1
->static_link
)
1547 case TCC_OUTPUT_DLL
:
1552 /* allocate strings for section names and decide if an unallocated
1553 section should be output */
1554 /* NOTE: the strsec section comes last, so its size is also
1556 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1557 s
= s1
->sections
[i
];
1558 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1560 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1565 s
->reloc
? s
->reloc
->name
: "n"
1568 /* when generating a DLL, we include relocations but we may
1570 if (file_type
== TCC_OUTPUT_DLL
&&
1571 s
->sh_type
== SHT_RELX
&&
1572 !(s
->sh_flags
& SHF_ALLOC
)) {
1573 /* //gr: avoid bogus relocs for empty (debug) sections */
1574 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1575 prepare_dynamic_rel(s1
, s
);
1577 s
->sh_size
= s
->data_offset
;
1578 } else if (do_debug
||
1579 file_type
== TCC_OUTPUT_OBJ
||
1580 (s
->sh_flags
& SHF_ALLOC
) ||
1581 i
== (s1
->nb_sections
- 1)) {
1582 /* we output all sections if debug or object file */
1583 s
->sh_size
= s
->data_offset
;
1587 /* allocate program segment headers */
1588 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1590 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1591 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1596 /* compute section to program header mapping */
1597 if (s1
->has_text_addr
) {
1598 int a_offset
, p_offset
;
1599 addr
= s1
->text_addr
;
1600 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1602 a_offset
= addr
& (ELF_PAGE_SIZE
- 1);
1603 p_offset
= file_offset
& (ELF_PAGE_SIZE
- 1);
1604 if (a_offset
< p_offset
)
1605 a_offset
+= ELF_PAGE_SIZE
;
1606 file_offset
+= (a_offset
- p_offset
);
1608 if (file_type
== TCC_OUTPUT_DLL
)
1611 addr
= ELF_START_ADDR
;
1612 /* compute address after headers */
1613 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1616 /* dynamic relocation table information, for .dynamic section */
1620 /* leave one program header for the program interpreter */
1625 for(j
= 0; j
< 2; j
++) {
1626 ph
->p_type
= PT_LOAD
;
1628 ph
->p_flags
= PF_R
| PF_X
;
1630 ph
->p_flags
= PF_R
| PF_W
;
1631 ph
->p_align
= ELF_PAGE_SIZE
;
1633 /* we do the following ordering: interp, symbol tables,
1634 relocations, progbits, nobits */
1635 /* XXX: do faster and simpler sorting */
1636 for(k
= 0; k
< 5; k
++) {
1637 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1638 s
= s1
->sections
[i
];
1639 /* compute if section should be included */
1641 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1645 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1646 (SHF_ALLOC
| SHF_WRITE
))
1652 } else if (s
->sh_type
== SHT_DYNSYM
||
1653 s
->sh_type
== SHT_STRTAB
||
1654 s
->sh_type
== SHT_HASH
) {
1657 } else if (s
->sh_type
== SHT_RELX
) {
1660 } else if (s
->sh_type
== SHT_NOBITS
) {
1667 section_order
[sh_order_index
++] = i
;
1669 /* section matches: we align it and add its size */
1671 addr
= (addr
+ s
->sh_addralign
- 1) &
1672 ~(s
->sh_addralign
- 1);
1673 file_offset
+= addr
- tmp
;
1674 s
->sh_offset
= file_offset
;
1677 /* update program header infos */
1678 if (ph
->p_offset
== 0) {
1679 ph
->p_offset
= file_offset
;
1681 ph
->p_paddr
= ph
->p_vaddr
;
1683 /* update dynamic relocation infos */
1684 if (s
->sh_type
== SHT_RELX
) {
1687 rel_size
+= s
->sh_size
;
1690 if (s
->sh_type
!= SHT_NOBITS
)
1691 file_offset
+= s
->sh_size
;
1694 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1695 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1698 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1699 /* if in the middle of a page, we duplicate the page in
1700 memory so that one copy is RX and the other is RW */
1701 if ((addr
& (ELF_PAGE_SIZE
- 1)) != 0)
1702 addr
+= ELF_PAGE_SIZE
;
1704 addr
= (addr
+ ELF_PAGE_SIZE
- 1) & ~(ELF_PAGE_SIZE
- 1);
1705 file_offset
= (file_offset
+ ELF_PAGE_SIZE
- 1) &
1706 ~(ELF_PAGE_SIZE
- 1);
1711 /* if interpreter, then add corresponing program header */
1715 ph
->p_type
= PT_INTERP
;
1716 ph
->p_offset
= interp
->sh_offset
;
1717 ph
->p_vaddr
= interp
->sh_addr
;
1718 ph
->p_paddr
= ph
->p_vaddr
;
1719 ph
->p_filesz
= interp
->sh_size
;
1720 ph
->p_memsz
= interp
->sh_size
;
1722 ph
->p_align
= interp
->sh_addralign
;
1725 /* if dynamic section, then add corresponing program header */
1729 ph
= &phdr
[phnum
- 1];
1731 ph
->p_type
= PT_DYNAMIC
;
1732 ph
->p_offset
= dynamic
->sh_offset
;
1733 ph
->p_vaddr
= dynamic
->sh_addr
;
1734 ph
->p_paddr
= ph
->p_vaddr
;
1735 ph
->p_filesz
= dynamic
->sh_size
;
1736 ph
->p_memsz
= dynamic
->sh_size
;
1737 ph
->p_flags
= PF_R
| PF_W
;
1738 ph
->p_align
= dynamic
->sh_addralign
;
1740 /* put GOT dynamic section address */
1741 put32(s1
->got
->data
, dynamic
->sh_addr
);
1743 /* relocate the PLT */
1744 if (file_type
== TCC_OUTPUT_EXE
1745 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1746 || file_type
== TCC_OUTPUT_DLL
1752 p_end
= p
+ s1
->plt
->data_offset
;
1754 #if defined(TCC_TARGET_I386)
1755 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1756 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1759 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1762 #elif defined(TCC_TARGET_X86_64)
1763 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1764 put32(p
+ 2, get32(p
+ 2) + x
);
1765 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1768 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1771 #elif defined(TCC_TARGET_ARM)
1773 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1776 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1779 #elif defined(TCC_TARGET_C67)
1782 #error unsupported CPU
1787 /* relocate symbols in .dynsym */
1788 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1789 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1792 if (sym
->st_shndx
== SHN_UNDEF
) {
1793 /* relocate to the PLT if the symbol corresponds
1796 sym
->st_value
+= s1
->plt
->sh_addr
;
1797 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1798 /* do symbol relocation */
1799 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1803 /* put dynamic section entries */
1804 dynamic
->data_offset
= saved_dynamic_data_offset
;
1805 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1806 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1807 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1808 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1809 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1810 #ifdef TCC_TARGET_X86_64
1811 put_dt(dynamic
, DT_RELA
, rel_addr
);
1812 put_dt(dynamic
, DT_RELASZ
, rel_size
);
1813 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1815 put_dt(dynamic
, DT_REL
, rel_addr
);
1816 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1817 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1820 put_dt(dynamic
, DT_DEBUG
, 0);
1821 put_dt(dynamic
, DT_NULL
, 0);
1824 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1825 ehdr
.e_phnum
= phnum
;
1826 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1829 /* all other sections come after */
1830 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1831 s
= s1
->sections
[i
];
1832 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1834 section_order
[sh_order_index
++] = i
;
1836 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1837 ~(s
->sh_addralign
- 1);
1838 s
->sh_offset
= file_offset
;
1839 if (s
->sh_type
!= SHT_NOBITS
)
1840 file_offset
+= s
->sh_size
;
1843 /* if building executable or DLL, then relocate each section
1844 except the GOT which is already relocated */
1845 if (file_type
!= TCC_OUTPUT_OBJ
) {
1846 relocate_syms(s1
, 0);
1848 if (s1
->nb_errors
!= 0) {
1854 /* relocate sections */
1855 /* XXX: ignore sections with allocated relocations ? */
1856 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1857 s
= s1
->sections
[i
];
1858 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1859 relocate_section(s1
, s
);
1862 /* relocate relocation entries if the relocation tables are
1863 allocated in the executable */
1864 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1865 s
= s1
->sections
[i
];
1866 if ((s
->sh_flags
& SHF_ALLOC
) &&
1867 s
->sh_type
== SHT_RELX
) {
1868 relocate_rel(s1
, s
);
1872 /* get entry point address */
1873 if (file_type
== TCC_OUTPUT_EXE
)
1874 ehdr
.e_entry
= (unsigned long)tcc_get_symbol_err(s1
, "_start");
1876 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1879 /* write elf file */
1880 if (file_type
== TCC_OUTPUT_OBJ
)
1884 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1886 error_noabort("could not write '%s'", filename
);
1889 f
= fdopen(fd
, "wb");
1891 printf("<- %s\n", filename
);
1893 #ifdef TCC_TARGET_COFF
1894 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1895 tcc_output_coff(s1
, f
);
1898 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1899 sort_syms(s1
, symtab_section
);
1902 file_offset
= (file_offset
+ 3) & -4;
1905 ehdr
.e_ident
[0] = ELFMAG0
;
1906 ehdr
.e_ident
[1] = ELFMAG1
;
1907 ehdr
.e_ident
[2] = ELFMAG2
;
1908 ehdr
.e_ident
[3] = ELFMAG3
;
1909 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
1910 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1911 ehdr
.e_ident
[6] = EV_CURRENT
;
1913 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1915 #ifdef TCC_TARGET_ARM
1917 ehdr
.e_ident
[EI_OSABI
] = 0;
1918 ehdr
.e_flags
= 4 << 24;
1920 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
1925 case TCC_OUTPUT_EXE
:
1926 ehdr
.e_type
= ET_EXEC
;
1928 case TCC_OUTPUT_DLL
:
1929 ehdr
.e_type
= ET_DYN
;
1931 case TCC_OUTPUT_OBJ
:
1932 ehdr
.e_type
= ET_REL
;
1935 ehdr
.e_machine
= EM_TCC_TARGET
;
1936 ehdr
.e_version
= EV_CURRENT
;
1937 ehdr
.e_shoff
= file_offset
;
1938 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
1939 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
1940 ehdr
.e_shnum
= shnum
;
1941 ehdr
.e_shstrndx
= shnum
- 1;
1943 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
1944 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
1945 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1947 for(i
=1;i
<s1
->nb_sections
;i
++) {
1948 s
= s1
->sections
[section_order
[i
]];
1949 if (s
->sh_type
!= SHT_NOBITS
) {
1950 while (offset
< s
->sh_offset
) {
1955 fwrite(s
->data
, 1, size
, f
);
1960 /* output section headers */
1961 while (offset
< ehdr
.e_shoff
) {
1966 for(i
=0;i
<s1
->nb_sections
;i
++) {
1968 memset(sh
, 0, sizeof(ElfW(Shdr
)));
1969 s
= s1
->sections
[i
];
1971 sh
->sh_name
= s
->sh_name
;
1972 sh
->sh_type
= s
->sh_type
;
1973 sh
->sh_flags
= s
->sh_flags
;
1974 sh
->sh_entsize
= s
->sh_entsize
;
1975 sh
->sh_info
= s
->sh_info
;
1977 sh
->sh_link
= s
->link
->sh_num
;
1978 sh
->sh_addralign
= s
->sh_addralign
;
1979 sh
->sh_addr
= s
->sh_addr
;
1980 sh
->sh_offset
= s
->sh_offset
;
1981 sh
->sh_size
= s
->sh_size
;
1983 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
1986 tcc_output_binary(s1
, f
, section_order
);
1992 tcc_free(s1
->symtab_to_dynsym
);
1993 tcc_free(section_order
);
1995 tcc_free(s1
->got_offsets
);
1999 int tcc_output_file(TCCState
*s
, const char *filename
)
2002 #ifdef TCC_TARGET_PE
2003 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2004 ret
= pe_output_file(s
, filename
);
2008 ret
= elf_output_file(s
, filename
);
2013 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2017 data
= tcc_malloc(size
);
2018 lseek(fd
, file_offset
, SEEK_SET
);
2019 read(fd
, data
, size
);
2023 typedef struct SectionMergeInfo
{
2024 Section
*s
; /* corresponding existing section */
2025 unsigned long offset
; /* offset of the new section in the existing section */
2026 uint8_t new_section
; /* true if section 's' was added */
2027 uint8_t link_once
; /* true if link once section */
2030 /* load an object file and merge it with current files */
2031 /* XXX: handle correctly stab (debug) info */
2032 static int tcc_load_object_file(TCCState
*s1
,
2033 int fd
, unsigned long file_offset
)
2036 ElfW(Shdr
) *shdr
, *sh
;
2037 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2038 unsigned char *strsec
, *strtab
;
2039 int *old_to_new_syms
;
2040 char *sh_name
, *name
;
2041 SectionMergeInfo
*sm_table
, *sm
;
2042 ElfW(Sym
) *sym
, *symtab
;
2043 ElfW_Rel
*rel
, *rel_end
;
2049 stab_index
= stabstr_index
= 0;
2051 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2053 if (ehdr
.e_ident
[0] != ELFMAG0
||
2054 ehdr
.e_ident
[1] != ELFMAG1
||
2055 ehdr
.e_ident
[2] != ELFMAG2
||
2056 ehdr
.e_ident
[3] != ELFMAG3
)
2058 /* test if object file */
2059 if (ehdr
.e_type
!= ET_REL
)
2061 /* test CPU specific stuff */
2062 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2063 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2065 error_noabort("invalid object file");
2069 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2070 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2071 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2073 /* load section names */
2074 sh
= &shdr
[ehdr
.e_shstrndx
];
2075 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2077 /* load symtab and strtab */
2078 old_to_new_syms
= NULL
;
2082 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2084 if (sh
->sh_type
== SHT_SYMTAB
) {
2086 error_noabort("object must contain only one symtab");
2091 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2092 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2093 sm_table
[i
].s
= symtab_section
;
2095 /* now load strtab */
2096 sh
= &shdr
[sh
->sh_link
];
2097 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2101 /* now examine each section and try to merge its content with the
2103 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2104 /* no need to examine section name strtab */
2105 if (i
== ehdr
.e_shstrndx
)
2108 sh_name
= strsec
+ sh
->sh_name
;
2109 /* ignore sections types we do not handle */
2110 if (sh
->sh_type
!= SHT_PROGBITS
&&
2111 sh
->sh_type
!= SHT_RELX
&&
2113 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2115 sh
->sh_type
!= SHT_NOBITS
&&
2116 strcmp(sh_name
, ".stabstr")
2119 if (sh
->sh_addralign
< 1)
2120 sh
->sh_addralign
= 1;
2121 /* find corresponding section, if any */
2122 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2123 s
= s1
->sections
[j
];
2124 if (!strcmp(s
->name
, sh_name
)) {
2125 if (!strncmp(sh_name
, ".gnu.linkonce",
2126 sizeof(".gnu.linkonce") - 1)) {
2127 /* if a 'linkonce' section is already present, we
2128 do not add it again. It is a little tricky as
2129 symbols can still be defined in
2131 sm_table
[i
].link_once
= 1;
2138 /* not found: create new section */
2139 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2140 /* take as much info as possible from the section. sh_link and
2141 sh_info will be updated later */
2142 s
->sh_addralign
= sh
->sh_addralign
;
2143 s
->sh_entsize
= sh
->sh_entsize
;
2144 sm_table
[i
].new_section
= 1;
2146 if (sh
->sh_type
!= s
->sh_type
) {
2147 error_noabort("invalid section type");
2151 /* align start of section */
2152 offset
= s
->data_offset
;
2154 if (0 == strcmp(sh_name
, ".stab")) {
2158 if (0 == strcmp(sh_name
, ".stabstr")) {
2163 size
= sh
->sh_addralign
- 1;
2164 offset
= (offset
+ size
) & ~size
;
2165 if (sh
->sh_addralign
> s
->sh_addralign
)
2166 s
->sh_addralign
= sh
->sh_addralign
;
2167 s
->data_offset
= offset
;
2169 sm_table
[i
].offset
= offset
;
2171 /* concatenate sections */
2173 if (sh
->sh_type
!= SHT_NOBITS
) {
2175 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2176 ptr
= section_ptr_add(s
, size
);
2177 read(fd
, ptr
, size
);
2179 s
->data_offset
+= size
;
2184 /* //gr relocate stab strings */
2185 if (stab_index
&& stabstr_index
) {
2188 s
= sm_table
[stab_index
].s
;
2189 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2190 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2191 o
= sm_table
[stabstr_index
].offset
;
2193 a
->n_strx
+= o
, a
++;
2196 /* second short pass to update sh_link and sh_info fields of new
2198 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2200 if (!s
|| !sm_table
[i
].new_section
)
2203 if (sh
->sh_link
> 0)
2204 s
->link
= sm_table
[sh
->sh_link
].s
;
2205 if (sh
->sh_type
== SHT_RELX
) {
2206 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2207 /* update backward link */
2208 s1
->sections
[s
->sh_info
]->reloc
= s
;
2213 /* resolve symbols */
2214 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2217 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2218 if (sym
->st_shndx
!= SHN_UNDEF
&&
2219 sym
->st_shndx
< SHN_LORESERVE
) {
2220 sm
= &sm_table
[sym
->st_shndx
];
2221 if (sm
->link_once
) {
2222 /* if a symbol is in a link once section, we use the
2223 already defined symbol. It is very important to get
2224 correct relocations */
2225 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2226 name
= strtab
+ sym
->st_name
;
2227 sym_index
= find_elf_sym(symtab_section
, name
);
2229 old_to_new_syms
[i
] = sym_index
;
2233 /* if no corresponding section added, no need to add symbol */
2236 /* convert section number */
2237 sym
->st_shndx
= sm
->s
->sh_num
;
2239 sym
->st_value
+= sm
->offset
;
2242 name
= strtab
+ sym
->st_name
;
2243 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2244 sym
->st_info
, sym
->st_other
,
2245 sym
->st_shndx
, name
);
2246 old_to_new_syms
[i
] = sym_index
;
2249 /* third pass to patch relocation entries */
2250 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2255 offset
= sm_table
[i
].offset
;
2256 switch(s
->sh_type
) {
2258 /* take relocation offset information */
2259 offseti
= sm_table
[sh
->sh_info
].offset
;
2260 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2261 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2266 /* convert symbol index */
2267 type
= ELFW(R_TYPE
)(rel
->r_info
);
2268 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2269 /* NOTE: only one symtab assumed */
2270 if (sym_index
>= nb_syms
)
2272 sym_index
= old_to_new_syms
[sym_index
];
2273 /* ignore link_once in rel section. */
2274 if (!sym_index
&& !sm
->link_once
) {
2276 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2277 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2280 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2281 /* offset the relocation offset */
2282 rel
->r_offset
+= offseti
;
2294 tcc_free(old_to_new_syms
);
2301 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2303 typedef struct ArchiveHeader
{
2304 char ar_name
[16]; /* name of this member */
2305 char ar_date
[12]; /* file mtime */
2306 char ar_uid
[6]; /* owner uid; printed as decimal */
2307 char ar_gid
[6]; /* owner gid; printed as decimal */
2308 char ar_mode
[8]; /* file mode, printed as octal */
2309 char ar_size
[10]; /* file size, printed as decimal */
2310 char ar_fmag
[2]; /* should contain ARFMAG */
2313 static int get_be32(const uint8_t *b
)
2315 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2318 /* load only the objects which resolve undefined symbols */
2319 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2321 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2323 const char *ar_names
, *p
;
2324 const uint8_t *ar_index
;
2327 data
= tcc_malloc(size
);
2328 if (read(fd
, data
, size
) != size
)
2330 nsyms
= get_be32(data
);
2331 ar_index
= data
+ 4;
2332 ar_names
= ar_index
+ nsyms
* 4;
2336 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2337 sym_index
= find_elf_sym(symtab_section
, p
);
2339 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2340 if(sym
->st_shndx
== SHN_UNDEF
) {
2341 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2343 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2346 lseek(fd
, off
, SEEK_SET
);
2347 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2362 /* load a '.a' file */
2363 static int tcc_load_archive(TCCState
*s1
, int fd
)
2370 unsigned long file_offset
;
2372 /* skip magic which was already checked */
2373 read(fd
, magic
, sizeof(magic
));
2376 len
= read(fd
, &hdr
, sizeof(hdr
));
2379 if (len
!= sizeof(hdr
)) {
2380 error_noabort("invalid archive");
2383 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2384 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2385 size
= strtol(ar_size
, NULL
, 0);
2386 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2387 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2388 if (ar_name
[i
] != ' ')
2391 ar_name
[i
+ 1] = '\0';
2392 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2393 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2395 size
= (size
+ 1) & ~1;
2396 if (!strcmp(ar_name
, "/")) {
2397 /* coff symbol table : we handle it */
2398 if(s1
->alacarte_link
)
2399 return tcc_load_alacarte(s1
, fd
, size
);
2400 } else if (!strcmp(ar_name
, "//") ||
2401 !strcmp(ar_name
, "__.SYMDEF") ||
2402 !strcmp(ar_name
, "__.SYMDEF/") ||
2403 !strcmp(ar_name
, "ARFILENAMES/")) {
2404 /* skip symbol table or archive names */
2406 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2409 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2414 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2415 is referenced by the user (so it should be added as DT_NEEDED in
2416 the generated ELF file) */
2417 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2420 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2421 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2422 ElfW(Sym
) *sym
, *dynsym
;
2423 ElfW(Dyn
) *dt
, *dynamic
;
2424 unsigned char *dynstr
;
2425 const char *name
, *soname
;
2426 DLLReference
*dllref
;
2428 read(fd
, &ehdr
, sizeof(ehdr
));
2430 /* test CPU specific stuff */
2431 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2432 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2433 error_noabort("bad architecture");
2438 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2440 /* load dynamic section and dynamic symbols */
2444 dynsym
= NULL
; /* avoid warning */
2445 dynstr
= NULL
; /* avoid warning */
2446 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2447 switch(sh
->sh_type
) {
2449 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2450 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2453 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2454 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2455 sh1
= &shdr
[sh
->sh_link
];
2456 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2463 /* compute the real library name */
2464 soname
= tcc_basename(filename
);
2466 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2467 if (dt
->d_tag
== DT_SONAME
) {
2468 soname
= dynstr
+ dt
->d_un
.d_val
;
2472 /* if the dll is already loaded, do not load it */
2473 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2474 dllref
= s1
->loaded_dlls
[i
];
2475 if (!strcmp(soname
, dllref
->name
)) {
2476 /* but update level if needed */
2477 if (level
< dllref
->level
)
2478 dllref
->level
= level
;
2484 // printf("loading dll '%s'\n", soname);
2486 /* add the dll and its level */
2487 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2488 dllref
->level
= level
;
2489 strcpy(dllref
->name
, soname
);
2490 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2492 /* add dynamic symbols in dynsym_section */
2493 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2494 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2495 if (sym_bind
== STB_LOCAL
)
2497 name
= dynstr
+ sym
->st_name
;
2498 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2499 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2502 /* load all referenced DLLs */
2503 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2506 name
= dynstr
+ dt
->d_un
.d_val
;
2507 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2508 dllref
= s1
->loaded_dlls
[j
];
2509 if (!strcmp(name
, dllref
->name
))
2510 goto already_loaded
;
2512 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2513 error_noabort("referenced dll '%s' not found", name
);
2530 #define LD_TOK_NAME 256
2531 #define LD_TOK_EOF (-1)
2533 /* return next ld script token */
2534 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2552 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2553 ch
= file
->buf_ptr
[0];
2561 /* case 'a' ... 'z': */
2588 /* case 'A' ... 'z': */
2623 if (!((ch
>= 'a' && ch
<= 'z') ||
2624 (ch
>= 'A' && ch
<= 'Z') ||
2625 (ch
>= '0' && ch
<= '9') ||
2626 strchr("/.-_+=$:\\,~", ch
)))
2628 if ((q
- name
) < name_size
- 1) {
2645 printf("tok=%c %d\n", c
, c
);
2646 if (c
== LD_TOK_NAME
)
2647 printf(" name=%s\n", name
);
2652 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2654 char filename
[1024];
2657 t
= ld_next(s1
, filename
, sizeof(filename
));
2660 t
= ld_next(s1
, filename
, sizeof(filename
));
2662 if (t
== LD_TOK_EOF
) {
2663 error_noabort("unexpected end of file");
2665 } else if (t
== ')') {
2667 } else if (t
!= LD_TOK_NAME
) {
2668 error_noabort("filename expected");
2671 if (!strcmp(filename
, "AS_NEEDED")) {
2672 ret
= ld_add_file_list(s1
, 1);
2676 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2678 tcc_add_file(s1
, filename
);
2680 t
= ld_next(s1
, filename
, sizeof(filename
));
2682 t
= ld_next(s1
, filename
, sizeof(filename
));
2688 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2690 static int tcc_load_ldscript(TCCState
*s1
)
2693 char filename
[1024];
2696 ch
= file
->buf_ptr
[0];
2699 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2700 if (t
== LD_TOK_EOF
)
2702 else if (t
!= LD_TOK_NAME
)
2704 if (!strcmp(cmd
, "INPUT") ||
2705 !strcmp(cmd
, "GROUP")) {
2706 ret
= ld_add_file_list(s1
, 0);
2709 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2710 !strcmp(cmd
, "TARGET")) {
2711 /* ignore some commands */
2712 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2716 t
= ld_next(s1
, filename
, sizeof(filename
));
2717 if (t
== LD_TOK_EOF
) {
2718 error_noabort("unexpected end of file");
2720 } else if (t
== ')') {