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 void *tcc_get_symbol(TCCState
*s
, const char *name
)
176 sym_index
= find_elf_sym(symtab_section
, name
);
179 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
180 return (void*)sym
->st_value
;
183 void *tcc_get_symbol_err(TCCState
*s
, const char *name
)
186 sym
= tcc_get_symbol(s
, name
);
188 error("%s not defined", name
);
192 /* add an elf symbol : check if it is already defined and patch
193 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
194 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
195 int info
, int other
, int sh_num
, const char *name
)
198 int sym_bind
, sym_index
, sym_type
, esym_bind
;
199 unsigned char sym_vis
, esym_vis
, new_vis
;
201 sym_bind
= ELFW(ST_BIND
)(info
);
202 sym_type
= ELFW(ST_TYPE
)(info
);
203 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
205 if (sym_bind
!= STB_LOCAL
) {
206 /* we search global or weak symbols */
207 sym_index
= find_elf_sym(s
, name
);
210 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
211 if (esym
->st_shndx
!= SHN_UNDEF
) {
212 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
213 /* propagate the most constraining visibility */
214 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
215 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
216 if (esym_vis
== STV_DEFAULT
) {
218 } else if (sym_vis
== STV_DEFAULT
) {
221 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
223 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
225 other
= esym
->st_other
; /* in case we have to patch esym */
226 if (sh_num
== SHN_UNDEF
) {
227 /* ignore adding of undefined symbol if the
228 corresponding symbol is already defined */
229 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
230 /* global overrides weak, so patch */
232 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
233 /* weak is ignored if already global */
234 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
235 /* ignore hidden symbols after */
236 } else if (esym
->st_shndx
== SHN_COMMON
&& sh_num
< SHN_LORESERVE
) {
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 error_noabort("'%s' defined twice", name
);
251 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
252 esym
->st_shndx
= sh_num
;
253 esym
->st_value
= value
;
254 esym
->st_size
= size
;
255 esym
->st_other
= other
;
259 sym_index
= put_elf_sym(s
, value
, size
,
260 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
267 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
268 int type
, int symbol
)
276 /* if no relocation section, create it */
277 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
278 /* if the symtab is allocated, then we consider the relocation
280 sr
= new_section(tcc_state
, buf
, SHT_RELX
, symtab
->sh_flags
);
281 sr
->sh_entsize
= sizeof(ElfW_Rel
);
283 sr
->sh_info
= s
->sh_num
;
286 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
287 rel
->r_offset
= offset
;
288 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
289 #ifdef TCC_TARGET_X86_64
294 /* put stab debug information */
297 unsigned int n_strx
; /* index into string table of name */
298 unsigned char n_type
; /* type of symbol */
299 unsigned char n_other
; /* misc info (usually empty) */
300 unsigned short n_desc
; /* description field */
301 unsigned int n_value
; /* value of symbol */
304 static void put_stabs(const char *str
, int type
, int other
, int desc
,
309 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
311 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
316 sym
->n_other
= other
;
318 sym
->n_value
= value
;
321 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
322 unsigned long value
, Section
*sec
, int sym_index
)
324 put_stabs(str
, type
, other
, desc
, value
);
325 put_elf_reloc(symtab_section
, stab_section
,
326 stab_section
->data_offset
- sizeof(unsigned int),
327 R_DATA_32
, sym_index
);
330 static void put_stabn(int type
, int other
, int desc
, int value
)
332 put_stabs(NULL
, type
, other
, desc
, value
);
335 static void put_stabd(int type
, int other
, int desc
)
337 put_stabs(NULL
, type
, other
, desc
, 0);
340 /* In an ELF file symbol table, the local symbols must appear below
341 the global and weak ones. Since TCC cannot sort it while generating
342 the code, we must do it after. All the relocation tables are also
343 modified to take into account the symbol table sorting */
344 static void sort_syms(TCCState
*s1
, Section
*s
)
346 int *old_to_new_syms
;
350 ElfW_Rel
*rel
, *rel_end
;
354 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
355 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
356 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
358 /* first pass for local symbols */
359 p
= (ElfW(Sym
) *)s
->data
;
361 for(i
= 0; i
< nb_syms
; i
++) {
362 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
363 old_to_new_syms
[i
] = q
- new_syms
;
368 /* save the number of local symbols in section header */
369 s
->sh_info
= q
- new_syms
;
371 /* then second pass for non local symbols */
372 p
= (ElfW(Sym
) *)s
->data
;
373 for(i
= 0; i
< nb_syms
; i
++) {
374 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
375 old_to_new_syms
[i
] = q
- new_syms
;
381 /* we copy the new symbols to the old */
382 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
385 /* now we modify all the relocations */
386 for(i
= 1; i
< s1
->nb_sections
; i
++) {
387 sr
= s1
->sections
[i
];
388 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
389 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
390 for(rel
= (ElfW_Rel
*)sr
->data
;
393 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
394 type
= ELFW(R_TYPE
)(rel
->r_info
);
395 sym_index
= old_to_new_syms
[sym_index
];
396 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
401 tcc_free(old_to_new_syms
);
404 /* relocate common symbols in the .bss section */
405 static void relocate_common_syms(void)
407 ElfW(Sym
) *sym
, *sym_end
;
408 unsigned long offset
, align
;
410 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
411 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
414 if (sym
->st_shndx
== SHN_COMMON
) {
416 align
= sym
->st_value
;
417 offset
= bss_section
->data_offset
;
418 offset
= (offset
+ align
- 1) & -align
;
419 sym
->st_value
= offset
;
420 sym
->st_shndx
= bss_section
->sh_num
;
421 offset
+= sym
->st_size
;
422 bss_section
->data_offset
= offset
;
427 /* relocate symbol table, resolve undefined symbols if do_resolve is
428 true and output error if undefined symbol. */
429 static void relocate_syms(TCCState
*s1
, int do_resolve
)
431 ElfW(Sym
) *sym
, *esym
, *sym_end
;
432 int sym_bind
, sh_num
, sym_index
;
436 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
437 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
440 sh_num
= sym
->st_shndx
;
441 if (sh_num
== SHN_UNDEF
) {
442 name
= strtab_section
->data
+ sym
->st_name
;
444 name
= symtab_section
->link
->data
+ sym
->st_name
;
445 addr
= (unsigned long)resolve_sym(s1
, name
, ELFW(ST_TYPE
)(sym
->st_info
));
447 sym
->st_value
= addr
;
450 } else if (s1
->dynsym
) {
451 /* if dynamic symbol exist, then use it */
452 sym_index
= find_elf_sym(s1
->dynsym
, name
);
454 esym
= &((ElfW(Sym
) *)s1
->dynsym
->data
)[sym_index
];
455 sym
->st_value
= esym
->st_value
;
459 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
461 if (!strcmp(name
, "_fp_hw"))
463 /* only weak symbols are accepted to be undefined. Their
465 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
466 if (sym_bind
== STB_WEAK
) {
469 error_noabort("undefined symbol '%s'", name
);
471 } else if (sh_num
< SHN_LORESERVE
) {
472 /* add section base */
473 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
479 #ifdef TCC_TARGET_X86_64
480 #define JMP_TABLE_ENTRY_SIZE 14
481 static unsigned long add_jmp_table(TCCState
*s1
, unsigned long val
)
483 char *p
= (char *)section_ptr_add(text_section
, JMP_TABLE_ENTRY_SIZE
);
488 *(unsigned long *)(p
+ 6) = val
;
489 return (unsigned long)p
;
492 static unsigned long add_got_table(TCCState
*s1
, unsigned long val
)
495 (unsigned long *)section_ptr_add(text_section
, sizeof(void *));
497 return (unsigned long)p
;
501 /* relocate a given section (CPU dependent) */
502 static void relocate_section(TCCState
*s1
, Section
*s
)
505 ElfW_Rel
*rel
, *rel_end
, *qrel
;
509 unsigned long val
, addr
;
513 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
514 qrel
= (ElfW_Rel
*)sr
->data
;
518 ptr
= s
->data
+ rel
->r_offset
;
520 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
521 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
523 #ifdef TCC_TARGET_X86_64
524 /* XXX: not tested */
525 val
+= rel
->r_addend
;
527 type
= ELFW(R_TYPE
)(rel
->r_info
);
528 addr
= s
->sh_addr
+ rel
->r_offset
;
532 #if defined(TCC_TARGET_I386)
534 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
535 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
536 qrel
->r_offset
= rel
->r_offset
;
538 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_32
);
542 qrel
->r_info
= ELFW(R_INFO
)(0, R_386_RELATIVE
);
549 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
551 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
553 qrel
->r_offset
= rel
->r_offset
;
554 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_PC32
);
559 *(int *)ptr
+= val
- addr
;
562 *(int *)ptr
+= val
- addr
;
569 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
572 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
575 /* we load the got offset */
576 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
578 #elif defined(TCC_TARGET_ARM)
585 x
= (*(int *)ptr
)&0xffffff;
586 (*(int *)ptr
) &= 0xff000000;
591 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
592 error("can't relocate value at %x",addr
);
601 x
= (*(int *)ptr
) & 0x7fffffff;
602 (*(int *)ptr
) &= 0x80000000;
605 if((x
^(x
>>1))&0x40000000)
606 error("can't relocate value at %x",addr
);
607 (*(int *)ptr
) |= x
& 0x7fffffff;
612 case R_ARM_BASE_PREL
:
613 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
616 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
619 /* we load the got offset */
620 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
625 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
626 type
,addr
,(unsigned int )ptr
,val
);
628 #elif defined(TCC_TARGET_C67)
636 /* put the low 16 bits of the absolute address */
637 // add to what is already there
639 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
640 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
642 //patch both at once - assumes always in pairs Low - High
644 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
645 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
651 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
652 type
,addr
,(unsigned int )ptr
,val
);
654 #elif defined(TCC_TARGET_X86_64)
656 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
657 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
658 qrel
->r_addend
= *(long long *)ptr
+ val
;
661 *(long long *)ptr
+= val
;
665 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
666 /* XXX: this logic may depend on TCC's codegen
667 now TCC uses R_X86_64_32 even for a 64bit pointer */
668 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
669 qrel
->r_addend
= *(int *)ptr
+ val
;
674 case R_X86_64_PC32
: {
675 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
677 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
679 qrel
->r_offset
= rel
->r_offset
;
680 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_X86_64_PC32
);
681 qrel
->r_addend
= *(int *)ptr
;
686 long diff
= val
- addr
;
687 if (diff
<= -2147483647 || diff
> 2147483647) {
688 /* XXX: naive support for over 32bit jump */
689 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
690 val
= add_jmp_table(s1
, val
);
693 if (diff
<= -2147483647 || diff
> 2147483647) {
694 error("internal error: relocation failed");
701 *(int *)ptr
+= val
- addr
;
703 case R_X86_64_GLOB_DAT
:
704 case R_X86_64_JUMP_SLOT
:
707 case R_X86_64_GOTPCREL
:
708 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
709 val
= add_got_table(s1
, val
- rel
->r_addend
) + rel
->r_addend
;
710 *(int *)ptr
+= val
- addr
;
713 *(int *)ptr
+= (s1
->got
->sh_addr
- addr
+
714 s1
->got_offsets
[sym_index
] - 4);
716 case R_X86_64_GOTTPOFF
:
717 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
720 /* we load the got offset */
721 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
724 #error unsupported processor
728 /* if the relocation is allocated, we change its symbol table */
729 if (sr
->sh_flags
& SHF_ALLOC
)
730 sr
->link
= s1
->dynsym
;
733 /* relocate relocation table in 'sr' */
734 static void relocate_rel(TCCState
*s1
, Section
*sr
)
737 ElfW_Rel
*rel
, *rel_end
;
739 s
= s1
->sections
[sr
->sh_info
];
740 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
741 for(rel
= (ElfW_Rel
*)sr
->data
;
744 rel
->r_offset
+= s
->sh_addr
;
748 /* count the number of dynamic relocations so that we can reserve
750 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
752 ElfW_Rel
*rel
, *rel_end
;
753 int sym_index
, esym_index
, type
, count
;
756 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
757 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
758 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
759 type
= ELFW(R_TYPE
)(rel
->r_info
);
761 #if defined(TCC_TARGET_I386)
763 #elif defined(TCC_TARGET_X86_64)
770 #if defined(TCC_TARGET_I386)
772 #elif defined(TCC_TARGET_X86_64)
775 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
784 /* allocate the section */
785 sr
->sh_flags
|= SHF_ALLOC
;
786 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
791 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
796 if (index
>= s1
->nb_got_offsets
) {
797 /* find immediately bigger power of 2 and reallocate array */
801 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
803 error("memory full");
804 s1
->got_offsets
= tab
;
805 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
806 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
807 s1
->nb_got_offsets
= n
;
809 s1
->got_offsets
[index
] = val
;
812 /* XXX: suppress that */
813 static void put32(unsigned char *p
, uint32_t val
)
821 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
822 defined(TCC_TARGET_X86_64)
823 static uint32_t get32(unsigned char *p
)
825 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
829 static void build_got(TCCState
*s1
)
833 /* if no got, then create it */
834 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
835 s1
->got
->sh_entsize
= 4;
836 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
837 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
838 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
840 /* keep space for _DYNAMIC pointer, if present */
842 /* two dummy got entries */
846 /* keep space for _DYNAMIC pointer, if present */
849 /* two dummy got entries */
857 /* put a got entry corresponding to a symbol in symtab_section. 'size'
858 and 'info' can be modifed if more precise info comes from the DLL */
859 static void put_got_entry(TCCState
*s1
,
860 int reloc_type
, unsigned long size
, int info
,
866 unsigned long offset
;
872 /* if a got entry already exists for that symbol, no need to add one */
873 if (sym_index
< s1
->nb_got_offsets
&&
874 s1
->got_offsets
[sym_index
] != 0)
877 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
880 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
881 name
= symtab_section
->link
->data
+ sym
->st_name
;
882 offset
= sym
->st_value
;
883 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
885 #ifdef TCC_TARGET_X86_64
895 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
898 /* if we build a DLL, we add a %ebx offset */
899 if (s1
->output_type
== TCC_OUTPUT_DLL
)
905 /* add a PLT entry */
907 if (plt
->data_offset
== 0) {
908 /* first plt entry */
909 p
= section_ptr_add(plt
, 16);
910 p
[0] = 0xff; /* pushl got + PTR_SIZE */
912 put32(p
+ 2, PTR_SIZE
);
913 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
915 put32(p
+ 8, PTR_SIZE
* 2);
918 p
= section_ptr_add(plt
, 16);
919 p
[0] = 0xff; /* jmp *(got + x) */
921 put32(p
+ 2, s1
->got
->data_offset
);
922 p
[6] = 0x68; /* push $xxx */
923 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
924 p
[11] = 0xe9; /* jmp plt_start */
925 put32(p
+ 12, -(plt
->data_offset
));
927 /* the symbol is modified so that it will be relocated to
929 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
930 if (s1
->output_type
== TCC_OUTPUT_EXE
)
932 offset
= plt
->data_offset
- 16;
934 #elif defined(TCC_TARGET_ARM)
935 if (reloc_type
== R_ARM_JUMP_SLOT
) {
939 /* if we build a DLL, we add a %ebx offset */
940 if (s1
->output_type
== TCC_OUTPUT_DLL
)
941 error("DLLs unimplemented!");
943 /* add a PLT entry */
945 if (plt
->data_offset
== 0) {
946 /* first plt entry */
947 p
= section_ptr_add(plt
, 16);
948 put32(p
, 0xe52de004);
949 put32(p
+ 4, 0xe59fe010);
950 put32(p
+ 8, 0xe08fe00e);
951 put32(p
+ 12, 0xe5bef008);
954 p
= section_ptr_add(plt
, 16);
955 put32(p
, 0xe59fc004);
956 put32(p
+4, 0xe08fc00c);
957 put32(p
+8, 0xe59cf000);
958 put32(p
+12, s1
->got
->data_offset
);
960 /* the symbol is modified so that it will be relocated to
962 if (s1
->output_type
== TCC_OUTPUT_EXE
)
963 offset
= plt
->data_offset
- 16;
965 #elif defined(TCC_TARGET_C67)
966 error("C67 got not implemented");
968 #error unsupported CPU
970 index
= put_elf_sym(s1
->dynsym
, offset
,
971 size
, info
, 0, sym
->st_shndx
, name
);
972 /* put a got entry */
973 put_elf_reloc(s1
->dynsym
, s1
->got
,
974 s1
->got
->data_offset
,
977 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
981 /* build GOT and PLT entries */
982 static void build_got_entries(TCCState
*s1
)
985 ElfW_Rel
*rel
, *rel_end
;
987 int i
, type
, reloc_type
, sym_index
;
989 for(i
= 1; i
< s1
->nb_sections
; i
++) {
991 if (s
->sh_type
!= SHT_RELX
)
993 /* no need to handle got relocations */
994 if (s
->link
!= symtab_section
)
997 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
998 for(rel
= (ElfW_Rel
*)s
->data
;
1001 type
= ELFW(R_TYPE
)(rel
->r_info
);
1003 #if defined(TCC_TARGET_I386)
1010 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1011 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1012 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1013 /* look at the symbol got offset. If none, then add one */
1014 if (type
== R_386_GOT32
)
1015 reloc_type
= R_386_GLOB_DAT
;
1017 reloc_type
= R_386_JMP_SLOT
;
1018 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1022 #elif defined(TCC_TARGET_ARM)
1023 case R_ARM_GOT_BREL
:
1024 case R_ARM_GOTOFF32
:
1025 case R_ARM_BASE_PREL
:
1029 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1030 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1031 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1032 /* look at the symbol got offset. If none, then add one */
1033 if (type
== R_ARM_GOT_BREL
)
1034 reloc_type
= R_ARM_GLOB_DAT
;
1036 reloc_type
= R_ARM_JUMP_SLOT
;
1037 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1041 #elif defined(TCC_TARGET_C67)
1048 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1049 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1050 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1051 /* look at the symbol got offset. If none, then add one */
1052 if (type
== R_C60_GOT32
)
1053 reloc_type
= R_C60_GLOB_DAT
;
1055 reloc_type
= R_C60_JMP_SLOT
;
1056 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1060 #elif defined(TCC_TARGET_X86_64)
1061 case R_X86_64_GOT32
:
1062 case R_X86_64_GOTTPOFF
:
1063 case R_X86_64_GOTPCREL
:
1064 case R_X86_64_PLT32
:
1067 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
||
1068 type
== R_X86_64_PLT32
) {
1069 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1070 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1071 /* look at the symbol got offset. If none, then add one */
1072 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
)
1073 reloc_type
= R_X86_64_GLOB_DAT
;
1075 reloc_type
= R_X86_64_JUMP_SLOT
;
1076 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1081 #error unsupported CPU
1090 static Section
*new_symtab(TCCState
*s1
,
1091 const char *symtab_name
, int sh_type
, int sh_flags
,
1092 const char *strtab_name
,
1093 const char *hash_name
, int hash_sh_flags
)
1095 Section
*symtab
, *strtab
, *hash
;
1096 int *ptr
, nb_buckets
;
1098 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1099 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1100 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1101 put_elf_str(strtab
, "");
1102 symtab
->link
= strtab
;
1103 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1107 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1108 hash
->sh_entsize
= sizeof(int);
1109 symtab
->hash
= hash
;
1110 hash
->link
= symtab
;
1112 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1113 ptr
[0] = nb_buckets
;
1115 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1119 /* put dynamic tag */
1120 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1123 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1125 dyn
->d_un
.d_val
= val
;
1128 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1132 char sym_start
[1024];
1135 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1136 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1138 s
= find_section(s1
, section_name
);
1143 end_offset
= s
->data_offset
;
1146 add_elf_sym(symtab_section
,
1148 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1149 s
->sh_num
, sym_start
);
1150 add_elf_sym(symtab_section
,
1152 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1153 s
->sh_num
, sym_end
);
1156 /* add tcc runtime libraries */
1157 static void tcc_add_runtime(TCCState
*s1
)
1159 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1163 #ifdef CONFIG_TCC_BCHECK
1164 if (do_bounds_check
) {
1166 Section
*init_section
;
1167 unsigned char *pinit
;
1170 /* XXX: add an object file to do that */
1171 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1173 add_elf_sym(symtab_section
, 0, 0,
1174 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1175 bounds_section
->sh_num
, "__bounds_start");
1176 /* add bound check code */
1177 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "bcheck.o");
1178 tcc_add_file(s1
, buf
);
1179 #ifdef TCC_TARGET_I386
1180 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1181 /* add 'call __bound_init()' in .init section */
1182 init_section
= find_section(s1
, ".init");
1183 pinit
= section_ptr_add(init_section
, 5);
1185 put32(pinit
+ 1, -4);
1186 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1187 put_elf_reloc(symtab_section
, init_section
,
1188 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1194 if (!s1
->nostdlib
) {
1195 tcc_add_library(s1
, "c");
1197 #ifdef CONFIG_USE_LIBGCC
1198 tcc_add_file(s1
, CONFIG_SYSROOT
"/lib/libgcc_s.so.1");
1200 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "libtcc1.a");
1201 tcc_add_file(s1
, buf
);
1204 /* add crt end if not memory output */
1205 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1206 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1210 /* add various standard linker symbols (must be done after the
1211 sections are filled (for example after allocating common
1213 static void tcc_add_linker_symbols(TCCState
*s1
)
1219 add_elf_sym(symtab_section
,
1220 text_section
->data_offset
, 0,
1221 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1222 text_section
->sh_num
, "_etext");
1223 add_elf_sym(symtab_section
,
1224 data_section
->data_offset
, 0,
1225 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1226 data_section
->sh_num
, "_edata");
1227 add_elf_sym(symtab_section
,
1228 bss_section
->data_offset
, 0,
1229 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1230 bss_section
->sh_num
, "_end");
1231 /* horrible new standard ldscript defines */
1232 add_init_array_defines(s1
, ".preinit_array");
1233 add_init_array_defines(s1
, ".init_array");
1234 add_init_array_defines(s1
, ".fini_array");
1236 /* add start and stop symbols for sections whose name can be
1238 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1239 s
= s1
->sections
[i
];
1240 if (s
->sh_type
== SHT_PROGBITS
&&
1241 (s
->sh_flags
& SHF_ALLOC
)) {
1245 /* check if section name can be expressed in C */
1251 if (!isid(ch
) && !isnum(ch
))
1255 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1256 add_elf_sym(symtab_section
,
1258 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1260 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1261 add_elf_sym(symtab_section
,
1263 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1270 /* name of ELF interpreter */
1272 static char elf_interp
[] = "/usr/libexec/ld-elf.so.1";
1275 static char elf_interp
[] = "/lib/ld-linux.so.3";
1276 #elif defined(TCC_TARGET_X86_64)
1277 static char elf_interp
[] = "/lib/ld-linux-x86-64.so.2";
1279 static char elf_interp
[] = "/lib/ld-linux.so.2";
1283 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1284 const int *section_order
)
1287 int i
, offset
, size
;
1290 for(i
=1;i
<s1
->nb_sections
;i
++) {
1291 s
= s1
->sections
[section_order
[i
]];
1292 if (s
->sh_type
!= SHT_NOBITS
&&
1293 (s
->sh_flags
& SHF_ALLOC
)) {
1294 while (offset
< s
->sh_offset
) {
1299 fwrite(s
->data
, 1, size
, f
);
1305 /* output an ELF file */
1306 /* XXX: suppress unneeded sections */
1307 int elf_output_file(TCCState
*s1
, const char *filename
)
1313 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1315 Section
*strsec
, *s
;
1316 ElfW(Shdr
) shdr
, *sh
;
1317 ElfW(Phdr
) *phdr
, *ph
;
1318 Section
*interp
, *dynamic
, *dynstr
;
1319 unsigned long saved_dynamic_data_offset
;
1321 int type
, file_type
;
1322 unsigned long rel_addr
, rel_size
;
1324 file_type
= s1
->output_type
;
1327 if (file_type
!= TCC_OUTPUT_OBJ
) {
1328 tcc_add_runtime(s1
);
1332 section_order
= NULL
;
1335 dynstr
= NULL
; /* avoid warning */
1336 saved_dynamic_data_offset
= 0; /* avoid warning */
1338 if (file_type
!= TCC_OUTPUT_OBJ
) {
1339 relocate_common_syms();
1341 tcc_add_linker_symbols(s1
);
1343 if (!s1
->static_link
) {
1345 int sym_index
, index
;
1346 ElfW(Sym
) *esym
, *sym_end
;
1348 if (file_type
== TCC_OUTPUT_EXE
) {
1350 /* add interpreter section only if executable */
1351 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1352 interp
->sh_addralign
= 1;
1353 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
1354 strcpy(ptr
, elf_interp
);
1357 /* add dynamic symbol table */
1358 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1360 ".hash", SHF_ALLOC
);
1361 dynstr
= s1
->dynsym
->link
;
1363 /* add dynamic section */
1364 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1365 SHF_ALLOC
| SHF_WRITE
);
1366 dynamic
->link
= dynstr
;
1367 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1370 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1371 SHF_ALLOC
| SHF_EXECINSTR
);
1372 s1
->plt
->sh_entsize
= 4;
1376 /* scan for undefined symbols and see if they are in the
1377 dynamic symbols. If a symbol STT_FUNC is found, then we
1378 add it in the PLT. If a symbol STT_OBJECT is found, we
1379 add it in the .bss section with a suitable relocation */
1380 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1381 symtab_section
->data_offset
);
1382 if (file_type
== TCC_OUTPUT_EXE
) {
1383 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1386 if (sym
->st_shndx
== SHN_UNDEF
) {
1387 name
= symtab_section
->link
->data
+ sym
->st_name
;
1388 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1390 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1391 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1392 if (type
== STT_FUNC
) {
1393 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1395 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1396 } else if (type
== STT_OBJECT
) {
1397 unsigned long offset
;
1398 offset
= bss_section
->data_offset
;
1399 /* XXX: which alignment ? */
1400 offset
= (offset
+ 16 - 1) & -16;
1401 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1403 bss_section
->sh_num
, name
);
1404 put_elf_reloc(s1
->dynsym
, bss_section
,
1405 offset
, R_COPY
, index
);
1406 offset
+= esym
->st_size
;
1407 bss_section
->data_offset
= offset
;
1410 /* STB_WEAK undefined symbols are accepted */
1411 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1413 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1414 !strcmp(name
, "_fp_hw")) {
1416 error_noabort("undefined symbol '%s'", name
);
1419 } else if (s1
->rdynamic
&&
1420 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1421 /* if -rdynamic option, then export all non
1423 name
= symtab_section
->link
->data
+ sym
->st_name
;
1424 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1426 sym
->st_shndx
, name
);
1433 /* now look at unresolved dynamic symbols and export
1434 corresponding symbol */
1435 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1436 s1
->dynsymtab_section
->data_offset
);
1437 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1440 if (esym
->st_shndx
== SHN_UNDEF
) {
1441 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1442 sym_index
= find_elf_sym(symtab_section
, name
);
1444 /* XXX: avoid adding a symbol if already
1445 present because of -rdynamic ? */
1446 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1447 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1449 sym
->st_shndx
, name
);
1451 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1452 /* weak symbols can stay undefined */
1454 warning("undefined dynamic symbol '%s'", name
);
1461 /* shared library case : we simply export all the global symbols */
1462 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1463 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1464 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1467 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1468 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1469 if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
&&
1470 sym
->st_shndx
== SHN_UNDEF
) {
1471 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1473 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1475 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1476 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1478 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1483 name
= symtab_section
->link
->data
+ sym
->st_name
;
1484 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1486 sym
->st_shndx
, name
);
1487 s1
->symtab_to_dynsym
[sym
-
1488 (ElfW(Sym
) *)symtab_section
->data
] =
1495 build_got_entries(s1
);
1497 /* add a list of needed dlls */
1498 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1499 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1500 if (dllref
->level
== 0)
1501 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1503 /* XXX: currently, since we do not handle PIC code, we
1504 must relocate the readonly segments */
1505 if (file_type
== TCC_OUTPUT_DLL
) {
1507 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1508 put_dt(dynamic
, DT_TEXTREL
, 0);
1511 /* add necessary space for other entries */
1512 saved_dynamic_data_offset
= dynamic
->data_offset
;
1513 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * 9;
1515 /* still need to build got entries in case of static link */
1516 build_got_entries(s1
);
1520 memset(&ehdr
, 0, sizeof(ehdr
));
1522 /* we add a section for symbols */
1523 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1524 put_elf_str(strsec
, "");
1526 /* compute number of sections */
1527 shnum
= s1
->nb_sections
;
1529 /* this array is used to reorder sections in the output file */
1530 section_order
= tcc_malloc(sizeof(int) * shnum
);
1531 section_order
[0] = 0;
1534 /* compute number of program headers */
1537 case TCC_OUTPUT_OBJ
:
1540 case TCC_OUTPUT_EXE
:
1541 if (!s1
->static_link
)
1546 case TCC_OUTPUT_DLL
:
1551 /* allocate strings for section names and decide if an unallocated
1552 section should be output */
1553 /* NOTE: the strsec section comes last, so its size is also
1555 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1556 s
= s1
->sections
[i
];
1557 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1559 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1564 s
->reloc
? s
->reloc
->name
: "n"
1567 /* when generating a DLL, we include relocations but we may
1569 if (file_type
== TCC_OUTPUT_DLL
&&
1570 s
->sh_type
== SHT_RELX
&&
1571 !(s
->sh_flags
& SHF_ALLOC
)) {
1572 /* //gr: avoid bogus relocs for empty (debug) sections */
1573 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1574 prepare_dynamic_rel(s1
, s
);
1576 s
->sh_size
= s
->data_offset
;
1577 } else if (do_debug
||
1578 file_type
== TCC_OUTPUT_OBJ
||
1579 (s
->sh_flags
& SHF_ALLOC
) ||
1580 i
== (s1
->nb_sections
- 1)) {
1581 /* we output all sections if debug or object file */
1582 s
->sh_size
= s
->data_offset
;
1586 /* allocate program segment headers */
1587 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1589 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1590 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1595 /* compute section to program header mapping */
1596 if (s1
->has_text_addr
) {
1597 int a_offset
, p_offset
;
1598 addr
= s1
->text_addr
;
1599 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1601 a_offset
= addr
& (ELF_PAGE_SIZE
- 1);
1602 p_offset
= file_offset
& (ELF_PAGE_SIZE
- 1);
1603 if (a_offset
< p_offset
)
1604 a_offset
+= ELF_PAGE_SIZE
;
1605 file_offset
+= (a_offset
- p_offset
);
1607 if (file_type
== TCC_OUTPUT_DLL
)
1610 addr
= ELF_START_ADDR
;
1611 /* compute address after headers */
1612 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1615 /* dynamic relocation table information, for .dynamic section */
1619 /* leave one program header for the program interpreter */
1624 for(j
= 0; j
< 2; j
++) {
1625 ph
->p_type
= PT_LOAD
;
1627 ph
->p_flags
= PF_R
| PF_X
;
1629 ph
->p_flags
= PF_R
| PF_W
;
1630 ph
->p_align
= ELF_PAGE_SIZE
;
1632 /* we do the following ordering: interp, symbol tables,
1633 relocations, progbits, nobits */
1634 /* XXX: do faster and simpler sorting */
1635 for(k
= 0; k
< 5; k
++) {
1636 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1637 s
= s1
->sections
[i
];
1638 /* compute if section should be included */
1640 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1644 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1645 (SHF_ALLOC
| SHF_WRITE
))
1651 } else if (s
->sh_type
== SHT_DYNSYM
||
1652 s
->sh_type
== SHT_STRTAB
||
1653 s
->sh_type
== SHT_HASH
) {
1656 } else if (s
->sh_type
== SHT_RELX
) {
1659 } else if (s
->sh_type
== SHT_NOBITS
) {
1666 section_order
[sh_order_index
++] = i
;
1668 /* section matches: we align it and add its size */
1670 addr
= (addr
+ s
->sh_addralign
- 1) &
1671 ~(s
->sh_addralign
- 1);
1672 file_offset
+= addr
- tmp
;
1673 s
->sh_offset
= file_offset
;
1676 /* update program header infos */
1677 if (ph
->p_offset
== 0) {
1678 ph
->p_offset
= file_offset
;
1680 ph
->p_paddr
= ph
->p_vaddr
;
1682 /* update dynamic relocation infos */
1683 if (s
->sh_type
== SHT_RELX
) {
1686 rel_size
+= s
->sh_size
;
1689 if (s
->sh_type
!= SHT_NOBITS
)
1690 file_offset
+= s
->sh_size
;
1693 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1694 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1697 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1698 /* if in the middle of a page, we duplicate the page in
1699 memory so that one copy is RX and the other is RW */
1700 if ((addr
& (ELF_PAGE_SIZE
- 1)) != 0)
1701 addr
+= ELF_PAGE_SIZE
;
1703 addr
= (addr
+ ELF_PAGE_SIZE
- 1) & ~(ELF_PAGE_SIZE
- 1);
1704 file_offset
= (file_offset
+ ELF_PAGE_SIZE
- 1) &
1705 ~(ELF_PAGE_SIZE
- 1);
1710 /* if interpreter, then add corresponing program header */
1714 ph
->p_type
= PT_INTERP
;
1715 ph
->p_offset
= interp
->sh_offset
;
1716 ph
->p_vaddr
= interp
->sh_addr
;
1717 ph
->p_paddr
= ph
->p_vaddr
;
1718 ph
->p_filesz
= interp
->sh_size
;
1719 ph
->p_memsz
= interp
->sh_size
;
1721 ph
->p_align
= interp
->sh_addralign
;
1724 /* if dynamic section, then add corresponing program header */
1728 ph
= &phdr
[phnum
- 1];
1730 ph
->p_type
= PT_DYNAMIC
;
1731 ph
->p_offset
= dynamic
->sh_offset
;
1732 ph
->p_vaddr
= dynamic
->sh_addr
;
1733 ph
->p_paddr
= ph
->p_vaddr
;
1734 ph
->p_filesz
= dynamic
->sh_size
;
1735 ph
->p_memsz
= dynamic
->sh_size
;
1736 ph
->p_flags
= PF_R
| PF_W
;
1737 ph
->p_align
= dynamic
->sh_addralign
;
1739 /* put GOT dynamic section address */
1740 put32(s1
->got
->data
, dynamic
->sh_addr
);
1742 /* relocate the PLT */
1743 if (file_type
== TCC_OUTPUT_EXE
1744 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1745 || file_type
== TCC_OUTPUT_DLL
1751 p_end
= p
+ s1
->plt
->data_offset
;
1753 #if defined(TCC_TARGET_I386)
1754 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1755 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1758 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1761 #elif defined(TCC_TARGET_X86_64)
1762 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1763 put32(p
+ 2, get32(p
+ 2) + x
);
1764 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1767 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1770 #elif defined(TCC_TARGET_ARM)
1772 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1775 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1778 #elif defined(TCC_TARGET_C67)
1781 #error unsupported CPU
1786 /* relocate symbols in .dynsym */
1787 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1788 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1791 if (sym
->st_shndx
== SHN_UNDEF
) {
1792 /* relocate to the PLT if the symbol corresponds
1795 sym
->st_value
+= s1
->plt
->sh_addr
;
1796 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1797 /* do symbol relocation */
1798 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1802 /* put dynamic section entries */
1803 dynamic
->data_offset
= saved_dynamic_data_offset
;
1804 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1805 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1806 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1807 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1808 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1809 #ifdef TCC_TARGET_X86_64
1810 put_dt(dynamic
, DT_RELA
, rel_addr
);
1811 put_dt(dynamic
, DT_RELASZ
, rel_size
);
1812 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1814 put_dt(dynamic
, DT_REL
, rel_addr
);
1815 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1816 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1819 put_dt(dynamic
, DT_DEBUG
, 0);
1820 put_dt(dynamic
, DT_NULL
, 0);
1823 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1824 ehdr
.e_phnum
= phnum
;
1825 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1828 /* all other sections come after */
1829 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1830 s
= s1
->sections
[i
];
1831 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1833 section_order
[sh_order_index
++] = i
;
1835 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1836 ~(s
->sh_addralign
- 1);
1837 s
->sh_offset
= file_offset
;
1838 if (s
->sh_type
!= SHT_NOBITS
)
1839 file_offset
+= s
->sh_size
;
1842 /* if building executable or DLL, then relocate each section
1843 except the GOT which is already relocated */
1844 if (file_type
!= TCC_OUTPUT_OBJ
) {
1845 relocate_syms(s1
, 0);
1847 if (s1
->nb_errors
!= 0) {
1853 /* relocate sections */
1854 /* XXX: ignore sections with allocated relocations ? */
1855 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1856 s
= s1
->sections
[i
];
1857 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1858 relocate_section(s1
, s
);
1861 /* relocate relocation entries if the relocation tables are
1862 allocated in the executable */
1863 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1864 s
= s1
->sections
[i
];
1865 if ((s
->sh_flags
& SHF_ALLOC
) &&
1866 s
->sh_type
== SHT_RELX
) {
1867 relocate_rel(s1
, s
);
1871 /* get entry point address */
1872 if (file_type
== TCC_OUTPUT_EXE
)
1873 ehdr
.e_entry
= (unsigned long)tcc_get_symbol_err(s1
, "_start");
1875 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1878 /* write elf file */
1879 if (file_type
== TCC_OUTPUT_OBJ
)
1883 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1885 error_noabort("could not write '%s'", filename
);
1888 f
= fdopen(fd
, "wb");
1890 printf("<- %s\n", filename
);
1892 #ifdef TCC_TARGET_COFF
1893 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1894 tcc_output_coff(s1
, f
);
1897 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1898 sort_syms(s1
, symtab_section
);
1901 file_offset
= (file_offset
+ 3) & -4;
1904 ehdr
.e_ident
[0] = ELFMAG0
;
1905 ehdr
.e_ident
[1] = ELFMAG1
;
1906 ehdr
.e_ident
[2] = ELFMAG2
;
1907 ehdr
.e_ident
[3] = ELFMAG3
;
1908 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
1909 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1910 ehdr
.e_ident
[6] = EV_CURRENT
;
1912 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1914 #ifdef TCC_TARGET_ARM
1916 ehdr
.e_ident
[EI_OSABI
] = 0;
1917 ehdr
.e_flags
= 4 << 24;
1919 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
1924 case TCC_OUTPUT_EXE
:
1925 ehdr
.e_type
= ET_EXEC
;
1927 case TCC_OUTPUT_DLL
:
1928 ehdr
.e_type
= ET_DYN
;
1930 case TCC_OUTPUT_OBJ
:
1931 ehdr
.e_type
= ET_REL
;
1934 ehdr
.e_machine
= EM_TCC_TARGET
;
1935 ehdr
.e_version
= EV_CURRENT
;
1936 ehdr
.e_shoff
= file_offset
;
1937 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
1938 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
1939 ehdr
.e_shnum
= shnum
;
1940 ehdr
.e_shstrndx
= shnum
- 1;
1942 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
1943 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
1944 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1946 for(i
=1;i
<s1
->nb_sections
;i
++) {
1947 s
= s1
->sections
[section_order
[i
]];
1948 if (s
->sh_type
!= SHT_NOBITS
) {
1949 while (offset
< s
->sh_offset
) {
1954 fwrite(s
->data
, 1, size
, f
);
1959 /* output section headers */
1960 while (offset
< ehdr
.e_shoff
) {
1965 for(i
=0;i
<s1
->nb_sections
;i
++) {
1967 memset(sh
, 0, sizeof(ElfW(Shdr
)));
1968 s
= s1
->sections
[i
];
1970 sh
->sh_name
= s
->sh_name
;
1971 sh
->sh_type
= s
->sh_type
;
1972 sh
->sh_flags
= s
->sh_flags
;
1973 sh
->sh_entsize
= s
->sh_entsize
;
1974 sh
->sh_info
= s
->sh_info
;
1976 sh
->sh_link
= s
->link
->sh_num
;
1977 sh
->sh_addralign
= s
->sh_addralign
;
1978 sh
->sh_addr
= s
->sh_addr
;
1979 sh
->sh_offset
= s
->sh_offset
;
1980 sh
->sh_size
= s
->sh_size
;
1982 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
1985 tcc_output_binary(s1
, f
, section_order
);
1991 tcc_free(s1
->symtab_to_dynsym
);
1992 tcc_free(section_order
);
1994 tcc_free(s1
->got_offsets
);
1998 int tcc_output_file(TCCState
*s
, const char *filename
)
2001 #ifdef TCC_TARGET_PE
2002 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2003 ret
= pe_output_file(s
, filename
);
2007 ret
= elf_output_file(s
, filename
);
2012 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2016 data
= tcc_malloc(size
);
2017 lseek(fd
, file_offset
, SEEK_SET
);
2018 read(fd
, data
, size
);
2022 typedef struct SectionMergeInfo
{
2023 Section
*s
; /* corresponding existing section */
2024 unsigned long offset
; /* offset of the new section in the existing section */
2025 uint8_t new_section
; /* true if section 's' was added */
2026 uint8_t link_once
; /* true if link once section */
2029 /* load an object file and merge it with current files */
2030 /* XXX: handle correctly stab (debug) info */
2031 static int tcc_load_object_file(TCCState
*s1
,
2032 int fd
, unsigned long file_offset
)
2035 ElfW(Shdr
) *shdr
, *sh
;
2036 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2037 unsigned char *strsec
, *strtab
;
2038 int *old_to_new_syms
;
2039 char *sh_name
, *name
;
2040 SectionMergeInfo
*sm_table
, *sm
;
2041 ElfW(Sym
) *sym
, *symtab
;
2042 ElfW_Rel
*rel
, *rel_end
;
2048 stab_index
= stabstr_index
= 0;
2050 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2052 if (ehdr
.e_ident
[0] != ELFMAG0
||
2053 ehdr
.e_ident
[1] != ELFMAG1
||
2054 ehdr
.e_ident
[2] != ELFMAG2
||
2055 ehdr
.e_ident
[3] != ELFMAG3
)
2057 /* test if object file */
2058 if (ehdr
.e_type
!= ET_REL
)
2060 /* test CPU specific stuff */
2061 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2062 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2064 error_noabort("invalid object file");
2068 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2069 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2070 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2072 /* load section names */
2073 sh
= &shdr
[ehdr
.e_shstrndx
];
2074 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2076 /* load symtab and strtab */
2077 old_to_new_syms
= NULL
;
2081 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2083 if (sh
->sh_type
== SHT_SYMTAB
) {
2085 error_noabort("object must contain only one symtab");
2090 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2091 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2092 sm_table
[i
].s
= symtab_section
;
2094 /* now load strtab */
2095 sh
= &shdr
[sh
->sh_link
];
2096 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2100 /* now examine each section and try to merge its content with the
2102 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2103 /* no need to examine section name strtab */
2104 if (i
== ehdr
.e_shstrndx
)
2107 sh_name
= strsec
+ sh
->sh_name
;
2108 /* ignore sections types we do not handle */
2109 if (sh
->sh_type
!= SHT_PROGBITS
&&
2110 sh
->sh_type
!= SHT_RELX
&&
2112 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2114 sh
->sh_type
!= SHT_NOBITS
&&
2115 strcmp(sh_name
, ".stabstr")
2118 if (sh
->sh_addralign
< 1)
2119 sh
->sh_addralign
= 1;
2120 /* find corresponding section, if any */
2121 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2122 s
= s1
->sections
[j
];
2123 if (!strcmp(s
->name
, sh_name
)) {
2124 if (!strncmp(sh_name
, ".gnu.linkonce",
2125 sizeof(".gnu.linkonce") - 1)) {
2126 /* if a 'linkonce' section is already present, we
2127 do not add it again. It is a little tricky as
2128 symbols can still be defined in
2130 sm_table
[i
].link_once
= 1;
2137 /* not found: create new section */
2138 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2139 /* take as much info as possible from the section. sh_link and
2140 sh_info will be updated later */
2141 s
->sh_addralign
= sh
->sh_addralign
;
2142 s
->sh_entsize
= sh
->sh_entsize
;
2143 sm_table
[i
].new_section
= 1;
2145 if (sh
->sh_type
!= s
->sh_type
) {
2146 error_noabort("invalid section type");
2150 /* align start of section */
2151 offset
= s
->data_offset
;
2153 if (0 == strcmp(sh_name
, ".stab")) {
2157 if (0 == strcmp(sh_name
, ".stabstr")) {
2162 size
= sh
->sh_addralign
- 1;
2163 offset
= (offset
+ size
) & ~size
;
2164 if (sh
->sh_addralign
> s
->sh_addralign
)
2165 s
->sh_addralign
= sh
->sh_addralign
;
2166 s
->data_offset
= offset
;
2168 sm_table
[i
].offset
= offset
;
2170 /* concatenate sections */
2172 if (sh
->sh_type
!= SHT_NOBITS
) {
2174 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2175 ptr
= section_ptr_add(s
, size
);
2176 read(fd
, ptr
, size
);
2178 s
->data_offset
+= size
;
2183 /* //gr relocate stab strings */
2184 if (stab_index
&& stabstr_index
) {
2187 s
= sm_table
[stab_index
].s
;
2188 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2189 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2190 o
= sm_table
[stabstr_index
].offset
;
2192 a
->n_strx
+= o
, a
++;
2195 /* second short pass to update sh_link and sh_info fields of new
2197 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2199 if (!s
|| !sm_table
[i
].new_section
)
2202 if (sh
->sh_link
> 0)
2203 s
->link
= sm_table
[sh
->sh_link
].s
;
2204 if (sh
->sh_type
== SHT_RELX
) {
2205 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2206 /* update backward link */
2207 s1
->sections
[s
->sh_info
]->reloc
= s
;
2212 /* resolve symbols */
2213 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2216 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2217 if (sym
->st_shndx
!= SHN_UNDEF
&&
2218 sym
->st_shndx
< SHN_LORESERVE
) {
2219 sm
= &sm_table
[sym
->st_shndx
];
2220 if (sm
->link_once
) {
2221 /* if a symbol is in a link once section, we use the
2222 already defined symbol. It is very important to get
2223 correct relocations */
2224 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2225 name
= strtab
+ sym
->st_name
;
2226 sym_index
= find_elf_sym(symtab_section
, name
);
2228 old_to_new_syms
[i
] = sym_index
;
2232 /* if no corresponding section added, no need to add symbol */
2235 /* convert section number */
2236 sym
->st_shndx
= sm
->s
->sh_num
;
2238 sym
->st_value
+= sm
->offset
;
2241 name
= strtab
+ sym
->st_name
;
2242 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2243 sym
->st_info
, sym
->st_other
,
2244 sym
->st_shndx
, name
);
2245 old_to_new_syms
[i
] = sym_index
;
2248 /* third pass to patch relocation entries */
2249 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2254 offset
= sm_table
[i
].offset
;
2255 switch(s
->sh_type
) {
2257 /* take relocation offset information */
2258 offseti
= sm_table
[sh
->sh_info
].offset
;
2259 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2260 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2265 /* convert symbol index */
2266 type
= ELFW(R_TYPE
)(rel
->r_info
);
2267 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2268 /* NOTE: only one symtab assumed */
2269 if (sym_index
>= nb_syms
)
2271 sym_index
= old_to_new_syms
[sym_index
];
2272 /* ignore link_once in rel section. */
2273 if (!sym_index
&& !sm
->link_once
) {
2275 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2276 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2279 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2280 /* offset the relocation offset */
2281 rel
->r_offset
+= offseti
;
2293 tcc_free(old_to_new_syms
);
2300 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2302 typedef struct ArchiveHeader
{
2303 char ar_name
[16]; /* name of this member */
2304 char ar_date
[12]; /* file mtime */
2305 char ar_uid
[6]; /* owner uid; printed as decimal */
2306 char ar_gid
[6]; /* owner gid; printed as decimal */
2307 char ar_mode
[8]; /* file mode, printed as octal */
2308 char ar_size
[10]; /* file size, printed as decimal */
2309 char ar_fmag
[2]; /* should contain ARFMAG */
2312 static int get_be32(const uint8_t *b
)
2314 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2317 /* load only the objects which resolve undefined symbols */
2318 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2320 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2322 const char *ar_names
, *p
;
2323 const uint8_t *ar_index
;
2326 data
= tcc_malloc(size
);
2327 if (read(fd
, data
, size
) != size
)
2329 nsyms
= get_be32(data
);
2330 ar_index
= data
+ 4;
2331 ar_names
= ar_index
+ nsyms
* 4;
2335 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2336 sym_index
= find_elf_sym(symtab_section
, p
);
2338 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2339 if(sym
->st_shndx
== SHN_UNDEF
) {
2340 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2342 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2345 lseek(fd
, off
, SEEK_SET
);
2346 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2361 /* load a '.a' file */
2362 static int tcc_load_archive(TCCState
*s1
, int fd
)
2369 unsigned long file_offset
;
2371 /* skip magic which was already checked */
2372 read(fd
, magic
, sizeof(magic
));
2375 len
= read(fd
, &hdr
, sizeof(hdr
));
2378 if (len
!= sizeof(hdr
)) {
2379 error_noabort("invalid archive");
2382 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2383 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2384 size
= strtol(ar_size
, NULL
, 0);
2385 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2386 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2387 if (ar_name
[i
] != ' ')
2390 ar_name
[i
+ 1] = '\0';
2391 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2392 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2394 size
= (size
+ 1) & ~1;
2395 if (!strcmp(ar_name
, "/")) {
2396 /* coff symbol table : we handle it */
2397 if(s1
->alacarte_link
)
2398 return tcc_load_alacarte(s1
, fd
, size
);
2399 } else if (!strcmp(ar_name
, "//") ||
2400 !strcmp(ar_name
, "__.SYMDEF") ||
2401 !strcmp(ar_name
, "__.SYMDEF/") ||
2402 !strcmp(ar_name
, "ARFILENAMES/")) {
2403 /* skip symbol table or archive names */
2405 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2408 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2413 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2414 is referenced by the user (so it should be added as DT_NEEDED in
2415 the generated ELF file) */
2416 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2419 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2420 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2421 ElfW(Sym
) *sym
, *dynsym
;
2422 ElfW(Dyn
) *dt
, *dynamic
;
2423 unsigned char *dynstr
;
2424 const char *name
, *soname
;
2425 DLLReference
*dllref
;
2427 read(fd
, &ehdr
, sizeof(ehdr
));
2429 /* test CPU specific stuff */
2430 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2431 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2432 error_noabort("bad architecture");
2437 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2439 /* load dynamic section and dynamic symbols */
2443 dynsym
= NULL
; /* avoid warning */
2444 dynstr
= NULL
; /* avoid warning */
2445 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2446 switch(sh
->sh_type
) {
2448 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2449 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2452 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2453 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2454 sh1
= &shdr
[sh
->sh_link
];
2455 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2462 /* compute the real library name */
2463 soname
= tcc_basename(filename
);
2465 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2466 if (dt
->d_tag
== DT_SONAME
) {
2467 soname
= dynstr
+ dt
->d_un
.d_val
;
2471 /* if the dll is already loaded, do not load it */
2472 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2473 dllref
= s1
->loaded_dlls
[i
];
2474 if (!strcmp(soname
, dllref
->name
)) {
2475 /* but update level if needed */
2476 if (level
< dllref
->level
)
2477 dllref
->level
= level
;
2483 // printf("loading dll '%s'\n", soname);
2485 /* add the dll and its level */
2486 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2487 dllref
->level
= level
;
2488 strcpy(dllref
->name
, soname
);
2489 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2491 /* add dynamic symbols in dynsym_section */
2492 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2493 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2494 if (sym_bind
== STB_LOCAL
)
2496 name
= dynstr
+ sym
->st_name
;
2497 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2498 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2501 /* load all referenced DLLs */
2502 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2505 name
= dynstr
+ dt
->d_un
.d_val
;
2506 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2507 dllref
= s1
->loaded_dlls
[j
];
2508 if (!strcmp(name
, dllref
->name
))
2509 goto already_loaded
;
2511 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2512 error_noabort("referenced dll '%s' not found", name
);
2529 #define LD_TOK_NAME 256
2530 #define LD_TOK_EOF (-1)
2532 /* return next ld script token */
2533 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2551 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2552 ch
= file
->buf_ptr
[0];
2560 /* case 'a' ... 'z': */
2587 /* case 'A' ... 'z': */
2622 if (!((ch
>= 'a' && ch
<= 'z') ||
2623 (ch
>= 'A' && ch
<= 'Z') ||
2624 (ch
>= '0' && ch
<= '9') ||
2625 strchr("/.-_+=$:\\,~", ch
)))
2627 if ((q
- name
) < name_size
- 1) {
2644 printf("tok=%c %d\n", c
, c
);
2645 if (c
== LD_TOK_NAME
)
2646 printf(" name=%s\n", name
);
2651 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2653 char filename
[1024];
2656 t
= ld_next(s1
, filename
, sizeof(filename
));
2659 t
= ld_next(s1
, filename
, sizeof(filename
));
2661 if (t
== LD_TOK_EOF
) {
2662 error_noabort("unexpected end of file");
2664 } else if (t
== ')') {
2666 } else if (t
!= LD_TOK_NAME
) {
2667 error_noabort("filename expected");
2670 if (!strcmp(filename
, "AS_NEEDED")) {
2671 ret
= ld_add_file_list(s1
, 1);
2675 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2677 tcc_add_file(s1
, filename
);
2679 t
= ld_next(s1
, filename
, sizeof(filename
));
2681 t
= ld_next(s1
, filename
, sizeof(filename
));
2687 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2689 static int tcc_load_ldscript(TCCState
*s1
)
2692 char filename
[1024];
2695 ch
= file
->buf_ptr
[0];
2698 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2699 if (t
== LD_TOK_EOF
)
2701 else if (t
!= LD_TOK_NAME
)
2703 if (!strcmp(cmd
, "INPUT") ||
2704 !strcmp(cmd
, "GROUP")) {
2705 ret
= ld_add_file_list(s1
, 0);
2708 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2709 !strcmp(cmd
, "TARGET")) {
2710 /* ignore some commands */
2711 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2715 t
= ld_next(s1
, filename
, sizeof(filename
));
2716 if (t
== LD_TOK_EOF
) {
2717 error_noabort("unexpected end of file");
2719 } else if (t
== ')') {