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
< -2147483648 || 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) {
696 /* output memory map to debug easily */
701 printf("%ld - %ld = %ld\n", val
, addr
, diff
);
702 dladdr((void *)addr
, &di
);
703 printf("addr = %lx = %lx+%lx(%s) ptr=%p\n",
704 addr
, s
->sh_addr
, rel
->r_offset
, di
.dli_sname
,
706 fp
= fopen("/proc/self/maps", "r");
707 size
= fread(buf
, 1, 4095, fp
);
711 error("internal error: relocation failed");
718 *(int *)ptr
+= val
- addr
;
720 case R_X86_64_GLOB_DAT
:
721 case R_X86_64_JUMP_SLOT
:
724 case R_X86_64_GOTPCREL
:
725 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
726 val
= add_got_table(s1
, val
- rel
->r_addend
) + rel
->r_addend
;
727 *(int *)ptr
+= val
- addr
;
730 *(int *)ptr
+= (s1
->got
->sh_addr
- addr
+
731 s1
->got_offsets
[sym_index
] - 4);
733 case R_X86_64_GOTTPOFF
:
734 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
737 /* we load the got offset */
738 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
741 #error unsupported processor
745 /* if the relocation is allocated, we change its symbol table */
746 if (sr
->sh_flags
& SHF_ALLOC
)
747 sr
->link
= s1
->dynsym
;
750 /* relocate relocation table in 'sr' */
751 static void relocate_rel(TCCState
*s1
, Section
*sr
)
754 ElfW_Rel
*rel
, *rel_end
;
756 s
= s1
->sections
[sr
->sh_info
];
757 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
758 for(rel
= (ElfW_Rel
*)sr
->data
;
761 rel
->r_offset
+= s
->sh_addr
;
765 /* count the number of dynamic relocations so that we can reserve
767 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
769 ElfW_Rel
*rel
, *rel_end
;
770 int sym_index
, esym_index
, type
, count
;
773 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
774 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
775 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
776 type
= ELFW(R_TYPE
)(rel
->r_info
);
778 #if defined(TCC_TARGET_I386)
780 #elif defined(TCC_TARGET_X86_64)
787 #if defined(TCC_TARGET_I386)
789 #elif defined(TCC_TARGET_X86_64)
792 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
801 /* allocate the section */
802 sr
->sh_flags
|= SHF_ALLOC
;
803 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
808 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
813 if (index
>= s1
->nb_got_offsets
) {
814 /* find immediately bigger power of 2 and reallocate array */
818 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
820 error("memory full");
821 s1
->got_offsets
= tab
;
822 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
823 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
824 s1
->nb_got_offsets
= n
;
826 s1
->got_offsets
[index
] = val
;
829 /* XXX: suppress that */
830 static void put32(unsigned char *p
, uint32_t val
)
838 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
839 defined(TCC_TARGET_X86_64)
840 static uint32_t get32(unsigned char *p
)
842 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
846 static void build_got(TCCState
*s1
)
850 /* if no got, then create it */
851 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
852 s1
->got
->sh_entsize
= 4;
853 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
854 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
855 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
857 /* keep space for _DYNAMIC pointer, if present */
859 /* two dummy got entries */
863 /* keep space for _DYNAMIC pointer, if present */
866 /* two dummy got entries */
874 /* put a got entry corresponding to a symbol in symtab_section. 'size'
875 and 'info' can be modifed if more precise info comes from the DLL */
876 static void put_got_entry(TCCState
*s1
,
877 int reloc_type
, unsigned long size
, int info
,
883 unsigned long offset
;
889 /* if a got entry already exists for that symbol, no need to add one */
890 if (sym_index
< s1
->nb_got_offsets
&&
891 s1
->got_offsets
[sym_index
] != 0)
894 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
897 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
898 name
= symtab_section
->link
->data
+ sym
->st_name
;
899 offset
= sym
->st_value
;
900 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
902 #ifdef TCC_TARGET_X86_64
912 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
915 /* if we build a DLL, we add a %ebx offset */
916 if (s1
->output_type
== TCC_OUTPUT_DLL
)
922 /* add a PLT entry */
924 if (plt
->data_offset
== 0) {
925 /* first plt entry */
926 p
= section_ptr_add(plt
, 16);
927 p
[0] = 0xff; /* pushl got + PTR_SIZE */
929 put32(p
+ 2, PTR_SIZE
);
930 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
932 put32(p
+ 8, PTR_SIZE
* 2);
935 p
= section_ptr_add(plt
, 16);
936 p
[0] = 0xff; /* jmp *(got + x) */
938 put32(p
+ 2, s1
->got
->data_offset
);
939 p
[6] = 0x68; /* push $xxx */
940 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
941 p
[11] = 0xe9; /* jmp plt_start */
942 put32(p
+ 12, -(plt
->data_offset
));
944 /* the symbol is modified so that it will be relocated to
946 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
947 if (s1
->output_type
== TCC_OUTPUT_EXE
)
949 offset
= plt
->data_offset
- 16;
951 #elif defined(TCC_TARGET_ARM)
952 if (reloc_type
== R_ARM_JUMP_SLOT
) {
956 /* if we build a DLL, we add a %ebx offset */
957 if (s1
->output_type
== TCC_OUTPUT_DLL
)
958 error("DLLs unimplemented!");
960 /* add a PLT entry */
962 if (plt
->data_offset
== 0) {
963 /* first plt entry */
964 p
= section_ptr_add(plt
, 16);
965 put32(p
, 0xe52de004);
966 put32(p
+ 4, 0xe59fe010);
967 put32(p
+ 8, 0xe08fe00e);
968 put32(p
+ 12, 0xe5bef008);
971 p
= section_ptr_add(plt
, 16);
972 put32(p
, 0xe59fc004);
973 put32(p
+4, 0xe08fc00c);
974 put32(p
+8, 0xe59cf000);
975 put32(p
+12, s1
->got
->data_offset
);
977 /* the symbol is modified so that it will be relocated to
979 if (s1
->output_type
== TCC_OUTPUT_EXE
)
980 offset
= plt
->data_offset
- 16;
982 #elif defined(TCC_TARGET_C67)
983 error("C67 got not implemented");
985 #error unsupported CPU
987 index
= put_elf_sym(s1
->dynsym
, offset
,
988 size
, info
, 0, sym
->st_shndx
, name
);
989 /* put a got entry */
990 put_elf_reloc(s1
->dynsym
, s1
->got
,
991 s1
->got
->data_offset
,
994 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
998 /* build GOT and PLT entries */
999 static void build_got_entries(TCCState
*s1
)
1001 Section
*s
, *symtab
;
1002 ElfW_Rel
*rel
, *rel_end
;
1004 int i
, type
, reloc_type
, sym_index
;
1006 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1007 s
= s1
->sections
[i
];
1008 if (s
->sh_type
!= SHT_RELX
)
1010 /* no need to handle got relocations */
1011 if (s
->link
!= symtab_section
)
1014 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
1015 for(rel
= (ElfW_Rel
*)s
->data
;
1018 type
= ELFW(R_TYPE
)(rel
->r_info
);
1020 #if defined(TCC_TARGET_I386)
1027 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1028 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1029 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1030 /* look at the symbol got offset. If none, then add one */
1031 if (type
== R_386_GOT32
)
1032 reloc_type
= R_386_GLOB_DAT
;
1034 reloc_type
= R_386_JMP_SLOT
;
1035 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1039 #elif defined(TCC_TARGET_ARM)
1040 case R_ARM_GOT_BREL
:
1041 case R_ARM_GOTOFF32
:
1042 case R_ARM_BASE_PREL
:
1046 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1047 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1048 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1049 /* look at the symbol got offset. If none, then add one */
1050 if (type
== R_ARM_GOT_BREL
)
1051 reloc_type
= R_ARM_GLOB_DAT
;
1053 reloc_type
= R_ARM_JUMP_SLOT
;
1054 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1058 #elif defined(TCC_TARGET_C67)
1065 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1066 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1067 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1068 /* look at the symbol got offset. If none, then add one */
1069 if (type
== R_C60_GOT32
)
1070 reloc_type
= R_C60_GLOB_DAT
;
1072 reloc_type
= R_C60_JMP_SLOT
;
1073 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1077 #elif defined(TCC_TARGET_X86_64)
1078 case R_X86_64_GOT32
:
1079 case R_X86_64_GOTTPOFF
:
1080 case R_X86_64_GOTPCREL
:
1081 case R_X86_64_PLT32
:
1084 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
||
1085 type
== R_X86_64_PLT32
) {
1086 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1087 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1088 /* look at the symbol got offset. If none, then add one */
1089 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
)
1090 reloc_type
= R_X86_64_GLOB_DAT
;
1092 reloc_type
= R_X86_64_JUMP_SLOT
;
1093 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1098 #error unsupported CPU
1107 static Section
*new_symtab(TCCState
*s1
,
1108 const char *symtab_name
, int sh_type
, int sh_flags
,
1109 const char *strtab_name
,
1110 const char *hash_name
, int hash_sh_flags
)
1112 Section
*symtab
, *strtab
, *hash
;
1113 int *ptr
, nb_buckets
;
1115 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1116 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1117 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1118 put_elf_str(strtab
, "");
1119 symtab
->link
= strtab
;
1120 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1124 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1125 hash
->sh_entsize
= sizeof(int);
1126 symtab
->hash
= hash
;
1127 hash
->link
= symtab
;
1129 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1130 ptr
[0] = nb_buckets
;
1132 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1136 /* put dynamic tag */
1137 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1140 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1142 dyn
->d_un
.d_val
= val
;
1145 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1149 char sym_start
[1024];
1152 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1153 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1155 s
= find_section(s1
, section_name
);
1160 end_offset
= s
->data_offset
;
1163 add_elf_sym(symtab_section
,
1165 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1166 s
->sh_num
, sym_start
);
1167 add_elf_sym(symtab_section
,
1169 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1170 s
->sh_num
, sym_end
);
1173 /* add tcc runtime libraries */
1174 static void tcc_add_runtime(TCCState
*s1
)
1176 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1180 #ifdef CONFIG_TCC_BCHECK
1181 if (do_bounds_check
) {
1183 Section
*init_section
;
1184 unsigned char *pinit
;
1187 /* XXX: add an object file to do that */
1188 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1190 add_elf_sym(symtab_section
, 0, 0,
1191 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1192 bounds_section
->sh_num
, "__bounds_start");
1193 /* add bound check code */
1194 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "bcheck.o");
1195 tcc_add_file(s1
, buf
);
1196 #ifdef TCC_TARGET_I386
1197 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1198 /* add 'call __bound_init()' in .init section */
1199 init_section
= find_section(s1
, ".init");
1200 pinit
= section_ptr_add(init_section
, 5);
1202 put32(pinit
+ 1, -4);
1203 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1204 put_elf_reloc(symtab_section
, init_section
,
1205 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1211 if (!s1
->nostdlib
) {
1212 tcc_add_library(s1
, "c");
1214 #ifdef CONFIG_USE_LIBGCC
1215 tcc_add_file(s1
, CONFIG_SYSROOT
"/lib/libgcc_s.so.1");
1217 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "libtcc1.a");
1218 tcc_add_file(s1
, buf
);
1221 /* add crt end if not memory output */
1222 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1223 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1227 /* add various standard linker symbols (must be done after the
1228 sections are filled (for example after allocating common
1230 static void tcc_add_linker_symbols(TCCState
*s1
)
1236 add_elf_sym(symtab_section
,
1237 text_section
->data_offset
, 0,
1238 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1239 text_section
->sh_num
, "_etext");
1240 add_elf_sym(symtab_section
,
1241 data_section
->data_offset
, 0,
1242 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1243 data_section
->sh_num
, "_edata");
1244 add_elf_sym(symtab_section
,
1245 bss_section
->data_offset
, 0,
1246 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1247 bss_section
->sh_num
, "_end");
1248 /* horrible new standard ldscript defines */
1249 add_init_array_defines(s1
, ".preinit_array");
1250 add_init_array_defines(s1
, ".init_array");
1251 add_init_array_defines(s1
, ".fini_array");
1253 /* add start and stop symbols for sections whose name can be
1255 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1256 s
= s1
->sections
[i
];
1257 if (s
->sh_type
== SHT_PROGBITS
&&
1258 (s
->sh_flags
& SHF_ALLOC
)) {
1262 /* check if section name can be expressed in C */
1268 if (!isid(ch
) && !isnum(ch
))
1272 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1273 add_elf_sym(symtab_section
,
1275 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1277 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1278 add_elf_sym(symtab_section
,
1280 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1287 /* name of ELF interpreter */
1289 static char elf_interp
[] = "/usr/libexec/ld-elf.so.1";
1292 static char elf_interp
[] = "/lib/ld-linux.so.3";
1293 #elif defined(TCC_TARGET_X86_64)
1294 static char elf_interp
[] = "/lib/ld-linux-x86-64.so.2";
1296 static char elf_interp
[] = "/lib/ld-linux.so.2";
1300 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1301 const int *section_order
)
1304 int i
, offset
, size
;
1307 for(i
=1;i
<s1
->nb_sections
;i
++) {
1308 s
= s1
->sections
[section_order
[i
]];
1309 if (s
->sh_type
!= SHT_NOBITS
&&
1310 (s
->sh_flags
& SHF_ALLOC
)) {
1311 while (offset
< s
->sh_offset
) {
1316 fwrite(s
->data
, 1, size
, f
);
1322 /* output an ELF file */
1323 /* XXX: suppress unneeded sections */
1324 int elf_output_file(TCCState
*s1
, const char *filename
)
1330 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1332 Section
*strsec
, *s
;
1333 ElfW(Shdr
) shdr
, *sh
;
1334 ElfW(Phdr
) *phdr
, *ph
;
1335 Section
*interp
, *dynamic
, *dynstr
;
1336 unsigned long saved_dynamic_data_offset
;
1338 int type
, file_type
;
1339 unsigned long rel_addr
, rel_size
;
1341 file_type
= s1
->output_type
;
1344 if (file_type
!= TCC_OUTPUT_OBJ
) {
1345 tcc_add_runtime(s1
);
1349 section_order
= NULL
;
1352 dynstr
= NULL
; /* avoid warning */
1353 saved_dynamic_data_offset
= 0; /* avoid warning */
1355 if (file_type
!= TCC_OUTPUT_OBJ
) {
1356 relocate_common_syms();
1358 tcc_add_linker_symbols(s1
);
1360 if (!s1
->static_link
) {
1362 int sym_index
, index
;
1363 ElfW(Sym
) *esym
, *sym_end
;
1365 if (file_type
== TCC_OUTPUT_EXE
) {
1367 /* add interpreter section only if executable */
1368 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1369 interp
->sh_addralign
= 1;
1370 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
1371 strcpy(ptr
, elf_interp
);
1374 /* add dynamic symbol table */
1375 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1377 ".hash", SHF_ALLOC
);
1378 dynstr
= s1
->dynsym
->link
;
1380 /* add dynamic section */
1381 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1382 SHF_ALLOC
| SHF_WRITE
);
1383 dynamic
->link
= dynstr
;
1384 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1387 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1388 SHF_ALLOC
| SHF_EXECINSTR
);
1389 s1
->plt
->sh_entsize
= 4;
1393 /* scan for undefined symbols and see if they are in the
1394 dynamic symbols. If a symbol STT_FUNC is found, then we
1395 add it in the PLT. If a symbol STT_OBJECT is found, we
1396 add it in the .bss section with a suitable relocation */
1397 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1398 symtab_section
->data_offset
);
1399 if (file_type
== TCC_OUTPUT_EXE
) {
1400 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1403 if (sym
->st_shndx
== SHN_UNDEF
) {
1404 name
= symtab_section
->link
->data
+ sym
->st_name
;
1405 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1407 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1408 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1409 if (type
== STT_FUNC
) {
1410 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1412 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1413 } else if (type
== STT_OBJECT
) {
1414 unsigned long offset
;
1415 offset
= bss_section
->data_offset
;
1416 /* XXX: which alignment ? */
1417 offset
= (offset
+ 16 - 1) & -16;
1418 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1420 bss_section
->sh_num
, name
);
1421 put_elf_reloc(s1
->dynsym
, bss_section
,
1422 offset
, R_COPY
, index
);
1423 offset
+= esym
->st_size
;
1424 bss_section
->data_offset
= offset
;
1427 /* STB_WEAK undefined symbols are accepted */
1428 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1430 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1431 !strcmp(name
, "_fp_hw")) {
1433 error_noabort("undefined symbol '%s'", name
);
1436 } else if (s1
->rdynamic
&&
1437 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1438 /* if -rdynamic option, then export all non
1440 name
= symtab_section
->link
->data
+ sym
->st_name
;
1441 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1443 sym
->st_shndx
, name
);
1450 /* now look at unresolved dynamic symbols and export
1451 corresponding symbol */
1452 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1453 s1
->dynsymtab_section
->data_offset
);
1454 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1457 if (esym
->st_shndx
== SHN_UNDEF
) {
1458 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1459 sym_index
= find_elf_sym(symtab_section
, name
);
1461 /* XXX: avoid adding a symbol if already
1462 present because of -rdynamic ? */
1463 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1464 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1466 sym
->st_shndx
, name
);
1468 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1469 /* weak symbols can stay undefined */
1471 warning("undefined dynamic symbol '%s'", name
);
1478 /* shared library case : we simply export all the global symbols */
1479 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1480 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1481 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1484 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1485 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1486 if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
&&
1487 sym
->st_shndx
== SHN_UNDEF
) {
1488 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1490 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1492 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1493 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1495 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1500 name
= symtab_section
->link
->data
+ sym
->st_name
;
1501 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1503 sym
->st_shndx
, name
);
1504 s1
->symtab_to_dynsym
[sym
-
1505 (ElfW(Sym
) *)symtab_section
->data
] =
1512 build_got_entries(s1
);
1514 /* add a list of needed dlls */
1515 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1516 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1517 if (dllref
->level
== 0)
1518 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1520 /* XXX: currently, since we do not handle PIC code, we
1521 must relocate the readonly segments */
1522 if (file_type
== TCC_OUTPUT_DLL
) {
1524 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1525 put_dt(dynamic
, DT_TEXTREL
, 0);
1528 /* add necessary space for other entries */
1529 saved_dynamic_data_offset
= dynamic
->data_offset
;
1530 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * 9;
1532 /* still need to build got entries in case of static link */
1533 build_got_entries(s1
);
1537 memset(&ehdr
, 0, sizeof(ehdr
));
1539 /* we add a section for symbols */
1540 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1541 put_elf_str(strsec
, "");
1543 /* compute number of sections */
1544 shnum
= s1
->nb_sections
;
1546 /* this array is used to reorder sections in the output file */
1547 section_order
= tcc_malloc(sizeof(int) * shnum
);
1548 section_order
[0] = 0;
1551 /* compute number of program headers */
1554 case TCC_OUTPUT_OBJ
:
1557 case TCC_OUTPUT_EXE
:
1558 if (!s1
->static_link
)
1563 case TCC_OUTPUT_DLL
:
1568 /* allocate strings for section names and decide if an unallocated
1569 section should be output */
1570 /* NOTE: the strsec section comes last, so its size is also
1572 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1573 s
= s1
->sections
[i
];
1574 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1576 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1581 s
->reloc
? s
->reloc
->name
: "n"
1584 /* when generating a DLL, we include relocations but we may
1586 if (file_type
== TCC_OUTPUT_DLL
&&
1587 s
->sh_type
== SHT_RELX
&&
1588 !(s
->sh_flags
& SHF_ALLOC
)) {
1589 /* //gr: avoid bogus relocs for empty (debug) sections */
1590 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1591 prepare_dynamic_rel(s1
, s
);
1593 s
->sh_size
= s
->data_offset
;
1594 } else if (do_debug
||
1595 file_type
== TCC_OUTPUT_OBJ
||
1596 (s
->sh_flags
& SHF_ALLOC
) ||
1597 i
== (s1
->nb_sections
- 1)) {
1598 /* we output all sections if debug or object file */
1599 s
->sh_size
= s
->data_offset
;
1603 /* allocate program segment headers */
1604 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1606 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1607 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1612 /* compute section to program header mapping */
1613 if (s1
->has_text_addr
) {
1614 int a_offset
, p_offset
;
1615 addr
= s1
->text_addr
;
1616 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1618 a_offset
= addr
& (ELF_PAGE_SIZE
- 1);
1619 p_offset
= file_offset
& (ELF_PAGE_SIZE
- 1);
1620 if (a_offset
< p_offset
)
1621 a_offset
+= ELF_PAGE_SIZE
;
1622 file_offset
+= (a_offset
- p_offset
);
1624 if (file_type
== TCC_OUTPUT_DLL
)
1627 addr
= ELF_START_ADDR
;
1628 /* compute address after headers */
1629 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1632 /* dynamic relocation table information, for .dynamic section */
1636 /* leave one program header for the program interpreter */
1641 for(j
= 0; j
< 2; j
++) {
1642 ph
->p_type
= PT_LOAD
;
1644 ph
->p_flags
= PF_R
| PF_X
;
1646 ph
->p_flags
= PF_R
| PF_W
;
1647 ph
->p_align
= ELF_PAGE_SIZE
;
1649 /* we do the following ordering: interp, symbol tables,
1650 relocations, progbits, nobits */
1651 /* XXX: do faster and simpler sorting */
1652 for(k
= 0; k
< 5; k
++) {
1653 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1654 s
= s1
->sections
[i
];
1655 /* compute if section should be included */
1657 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1661 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1662 (SHF_ALLOC
| SHF_WRITE
))
1668 } else if (s
->sh_type
== SHT_DYNSYM
||
1669 s
->sh_type
== SHT_STRTAB
||
1670 s
->sh_type
== SHT_HASH
) {
1673 } else if (s
->sh_type
== SHT_RELX
) {
1676 } else if (s
->sh_type
== SHT_NOBITS
) {
1683 section_order
[sh_order_index
++] = i
;
1685 /* section matches: we align it and add its size */
1687 addr
= (addr
+ s
->sh_addralign
- 1) &
1688 ~(s
->sh_addralign
- 1);
1689 file_offset
+= addr
- tmp
;
1690 s
->sh_offset
= file_offset
;
1693 /* update program header infos */
1694 if (ph
->p_offset
== 0) {
1695 ph
->p_offset
= file_offset
;
1697 ph
->p_paddr
= ph
->p_vaddr
;
1699 /* update dynamic relocation infos */
1700 if (s
->sh_type
== SHT_RELX
) {
1703 rel_size
+= s
->sh_size
;
1706 if (s
->sh_type
!= SHT_NOBITS
)
1707 file_offset
+= s
->sh_size
;
1710 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1711 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1714 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1715 /* if in the middle of a page, we duplicate the page in
1716 memory so that one copy is RX and the other is RW */
1717 if ((addr
& (ELF_PAGE_SIZE
- 1)) != 0)
1718 addr
+= ELF_PAGE_SIZE
;
1720 addr
= (addr
+ ELF_PAGE_SIZE
- 1) & ~(ELF_PAGE_SIZE
- 1);
1721 file_offset
= (file_offset
+ ELF_PAGE_SIZE
- 1) &
1722 ~(ELF_PAGE_SIZE
- 1);
1727 /* if interpreter, then add corresponing program header */
1731 ph
->p_type
= PT_INTERP
;
1732 ph
->p_offset
= interp
->sh_offset
;
1733 ph
->p_vaddr
= interp
->sh_addr
;
1734 ph
->p_paddr
= ph
->p_vaddr
;
1735 ph
->p_filesz
= interp
->sh_size
;
1736 ph
->p_memsz
= interp
->sh_size
;
1738 ph
->p_align
= interp
->sh_addralign
;
1741 /* if dynamic section, then add corresponing program header */
1745 ph
= &phdr
[phnum
- 1];
1747 ph
->p_type
= PT_DYNAMIC
;
1748 ph
->p_offset
= dynamic
->sh_offset
;
1749 ph
->p_vaddr
= dynamic
->sh_addr
;
1750 ph
->p_paddr
= ph
->p_vaddr
;
1751 ph
->p_filesz
= dynamic
->sh_size
;
1752 ph
->p_memsz
= dynamic
->sh_size
;
1753 ph
->p_flags
= PF_R
| PF_W
;
1754 ph
->p_align
= dynamic
->sh_addralign
;
1756 /* put GOT dynamic section address */
1757 put32(s1
->got
->data
, dynamic
->sh_addr
);
1759 /* relocate the PLT */
1760 if (file_type
== TCC_OUTPUT_EXE
1761 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1762 || file_type
== TCC_OUTPUT_DLL
1768 p_end
= p
+ s1
->plt
->data_offset
;
1770 #if defined(TCC_TARGET_I386)
1771 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1772 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1775 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1778 #elif defined(TCC_TARGET_X86_64)
1779 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1780 put32(p
+ 2, get32(p
+ 2) + x
);
1781 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1784 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1787 #elif defined(TCC_TARGET_ARM)
1789 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1792 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1795 #elif defined(TCC_TARGET_C67)
1798 #error unsupported CPU
1803 /* relocate symbols in .dynsym */
1804 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1805 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1808 if (sym
->st_shndx
== SHN_UNDEF
) {
1809 /* relocate to the PLT if the symbol corresponds
1812 sym
->st_value
+= s1
->plt
->sh_addr
;
1813 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1814 /* do symbol relocation */
1815 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1819 /* put dynamic section entries */
1820 dynamic
->data_offset
= saved_dynamic_data_offset
;
1821 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1822 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1823 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1824 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1825 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1826 #ifdef TCC_TARGET_X86_64
1827 put_dt(dynamic
, DT_RELA
, rel_addr
);
1828 put_dt(dynamic
, DT_RELASZ
, rel_size
);
1829 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1831 put_dt(dynamic
, DT_REL
, rel_addr
);
1832 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1833 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1836 put_dt(dynamic
, DT_DEBUG
, 0);
1837 put_dt(dynamic
, DT_NULL
, 0);
1840 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1841 ehdr
.e_phnum
= phnum
;
1842 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1845 /* all other sections come after */
1846 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1847 s
= s1
->sections
[i
];
1848 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1850 section_order
[sh_order_index
++] = i
;
1852 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1853 ~(s
->sh_addralign
- 1);
1854 s
->sh_offset
= file_offset
;
1855 if (s
->sh_type
!= SHT_NOBITS
)
1856 file_offset
+= s
->sh_size
;
1859 /* if building executable or DLL, then relocate each section
1860 except the GOT which is already relocated */
1861 if (file_type
!= TCC_OUTPUT_OBJ
) {
1862 relocate_syms(s1
, 0);
1864 if (s1
->nb_errors
!= 0) {
1870 /* relocate sections */
1871 /* XXX: ignore sections with allocated relocations ? */
1872 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1873 s
= s1
->sections
[i
];
1874 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1875 relocate_section(s1
, s
);
1878 /* relocate relocation entries if the relocation tables are
1879 allocated in the executable */
1880 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1881 s
= s1
->sections
[i
];
1882 if ((s
->sh_flags
& SHF_ALLOC
) &&
1883 s
->sh_type
== SHT_RELX
) {
1884 relocate_rel(s1
, s
);
1888 /* get entry point address */
1889 if (file_type
== TCC_OUTPUT_EXE
)
1890 ehdr
.e_entry
= (unsigned long)tcc_get_symbol_err(s1
, "_start");
1892 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1895 /* write elf file */
1896 if (file_type
== TCC_OUTPUT_OBJ
)
1900 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1902 error_noabort("could not write '%s'", filename
);
1905 f
= fdopen(fd
, "wb");
1907 printf("<- %s\n", filename
);
1909 #ifdef TCC_TARGET_COFF
1910 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1911 tcc_output_coff(s1
, f
);
1914 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1915 sort_syms(s1
, symtab_section
);
1918 file_offset
= (file_offset
+ 3) & -4;
1921 ehdr
.e_ident
[0] = ELFMAG0
;
1922 ehdr
.e_ident
[1] = ELFMAG1
;
1923 ehdr
.e_ident
[2] = ELFMAG2
;
1924 ehdr
.e_ident
[3] = ELFMAG3
;
1925 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
1926 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1927 ehdr
.e_ident
[6] = EV_CURRENT
;
1929 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1931 #ifdef TCC_TARGET_ARM
1933 ehdr
.e_ident
[EI_OSABI
] = 0;
1934 ehdr
.e_flags
= 4 << 24;
1936 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
1941 case TCC_OUTPUT_EXE
:
1942 ehdr
.e_type
= ET_EXEC
;
1944 case TCC_OUTPUT_DLL
:
1945 ehdr
.e_type
= ET_DYN
;
1947 case TCC_OUTPUT_OBJ
:
1948 ehdr
.e_type
= ET_REL
;
1951 ehdr
.e_machine
= EM_TCC_TARGET
;
1952 ehdr
.e_version
= EV_CURRENT
;
1953 ehdr
.e_shoff
= file_offset
;
1954 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
1955 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
1956 ehdr
.e_shnum
= shnum
;
1957 ehdr
.e_shstrndx
= shnum
- 1;
1959 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
1960 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
1961 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1963 for(i
=1;i
<s1
->nb_sections
;i
++) {
1964 s
= s1
->sections
[section_order
[i
]];
1965 if (s
->sh_type
!= SHT_NOBITS
) {
1966 while (offset
< s
->sh_offset
) {
1971 fwrite(s
->data
, 1, size
, f
);
1976 /* output section headers */
1977 while (offset
< ehdr
.e_shoff
) {
1982 for(i
=0;i
<s1
->nb_sections
;i
++) {
1984 memset(sh
, 0, sizeof(ElfW(Shdr
)));
1985 s
= s1
->sections
[i
];
1987 sh
->sh_name
= s
->sh_name
;
1988 sh
->sh_type
= s
->sh_type
;
1989 sh
->sh_flags
= s
->sh_flags
;
1990 sh
->sh_entsize
= s
->sh_entsize
;
1991 sh
->sh_info
= s
->sh_info
;
1993 sh
->sh_link
= s
->link
->sh_num
;
1994 sh
->sh_addralign
= s
->sh_addralign
;
1995 sh
->sh_addr
= s
->sh_addr
;
1996 sh
->sh_offset
= s
->sh_offset
;
1997 sh
->sh_size
= s
->sh_size
;
1999 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2002 tcc_output_binary(s1
, f
, section_order
);
2008 tcc_free(s1
->symtab_to_dynsym
);
2009 tcc_free(section_order
);
2011 tcc_free(s1
->got_offsets
);
2015 int tcc_output_file(TCCState
*s
, const char *filename
)
2018 #ifdef TCC_TARGET_PE
2019 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2020 ret
= pe_output_file(s
, filename
);
2024 ret
= elf_output_file(s
, filename
);
2029 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2033 data
= tcc_malloc(size
);
2034 lseek(fd
, file_offset
, SEEK_SET
);
2035 read(fd
, data
, size
);
2039 typedef struct SectionMergeInfo
{
2040 Section
*s
; /* corresponding existing section */
2041 unsigned long offset
; /* offset of the new section in the existing section */
2042 uint8_t new_section
; /* true if section 's' was added */
2043 uint8_t link_once
; /* true if link once section */
2046 /* load an object file and merge it with current files */
2047 /* XXX: handle correctly stab (debug) info */
2048 static int tcc_load_object_file(TCCState
*s1
,
2049 int fd
, unsigned long file_offset
)
2052 ElfW(Shdr
) *shdr
, *sh
;
2053 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2054 unsigned char *strsec
, *strtab
;
2055 int *old_to_new_syms
;
2056 char *sh_name
, *name
;
2057 SectionMergeInfo
*sm_table
, *sm
;
2058 ElfW(Sym
) *sym
, *symtab
;
2059 ElfW_Rel
*rel
, *rel_end
;
2065 stab_index
= stabstr_index
= 0;
2067 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2069 if (ehdr
.e_ident
[0] != ELFMAG0
||
2070 ehdr
.e_ident
[1] != ELFMAG1
||
2071 ehdr
.e_ident
[2] != ELFMAG2
||
2072 ehdr
.e_ident
[3] != ELFMAG3
)
2074 /* test if object file */
2075 if (ehdr
.e_type
!= ET_REL
)
2077 /* test CPU specific stuff */
2078 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2079 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2081 error_noabort("invalid object file");
2085 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2086 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2087 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2089 /* load section names */
2090 sh
= &shdr
[ehdr
.e_shstrndx
];
2091 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2093 /* load symtab and strtab */
2094 old_to_new_syms
= NULL
;
2098 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2100 if (sh
->sh_type
== SHT_SYMTAB
) {
2102 error_noabort("object must contain only one symtab");
2107 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2108 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2109 sm_table
[i
].s
= symtab_section
;
2111 /* now load strtab */
2112 sh
= &shdr
[sh
->sh_link
];
2113 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2117 /* now examine each section and try to merge its content with the
2119 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2120 /* no need to examine section name strtab */
2121 if (i
== ehdr
.e_shstrndx
)
2124 sh_name
= strsec
+ sh
->sh_name
;
2125 /* ignore sections types we do not handle */
2126 if (sh
->sh_type
!= SHT_PROGBITS
&&
2127 sh
->sh_type
!= SHT_RELX
&&
2129 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2131 sh
->sh_type
!= SHT_NOBITS
&&
2132 strcmp(sh_name
, ".stabstr")
2135 if (sh
->sh_addralign
< 1)
2136 sh
->sh_addralign
= 1;
2137 /* find corresponding section, if any */
2138 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2139 s
= s1
->sections
[j
];
2140 if (!strcmp(s
->name
, sh_name
)) {
2141 if (!strncmp(sh_name
, ".gnu.linkonce",
2142 sizeof(".gnu.linkonce") - 1)) {
2143 /* if a 'linkonce' section is already present, we
2144 do not add it again. It is a little tricky as
2145 symbols can still be defined in
2147 sm_table
[i
].link_once
= 1;
2154 /* not found: create new section */
2155 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2156 /* take as much info as possible from the section. sh_link and
2157 sh_info will be updated later */
2158 s
->sh_addralign
= sh
->sh_addralign
;
2159 s
->sh_entsize
= sh
->sh_entsize
;
2160 sm_table
[i
].new_section
= 1;
2162 if (sh
->sh_type
!= s
->sh_type
) {
2163 error_noabort("invalid section type");
2167 /* align start of section */
2168 offset
= s
->data_offset
;
2170 if (0 == strcmp(sh_name
, ".stab")) {
2174 if (0 == strcmp(sh_name
, ".stabstr")) {
2179 size
= sh
->sh_addralign
- 1;
2180 offset
= (offset
+ size
) & ~size
;
2181 if (sh
->sh_addralign
> s
->sh_addralign
)
2182 s
->sh_addralign
= sh
->sh_addralign
;
2183 s
->data_offset
= offset
;
2185 sm_table
[i
].offset
= offset
;
2187 /* concatenate sections */
2189 if (sh
->sh_type
!= SHT_NOBITS
) {
2191 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2192 ptr
= section_ptr_add(s
, size
);
2193 read(fd
, ptr
, size
);
2195 s
->data_offset
+= size
;
2200 /* //gr relocate stab strings */
2201 if (stab_index
&& stabstr_index
) {
2204 s
= sm_table
[stab_index
].s
;
2205 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2206 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2207 o
= sm_table
[stabstr_index
].offset
;
2209 a
->n_strx
+= o
, a
++;
2212 /* second short pass to update sh_link and sh_info fields of new
2214 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2216 if (!s
|| !sm_table
[i
].new_section
)
2219 if (sh
->sh_link
> 0)
2220 s
->link
= sm_table
[sh
->sh_link
].s
;
2221 if (sh
->sh_type
== SHT_RELX
) {
2222 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2223 /* update backward link */
2224 s1
->sections
[s
->sh_info
]->reloc
= s
;
2229 /* resolve symbols */
2230 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2233 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2234 if (sym
->st_shndx
!= SHN_UNDEF
&&
2235 sym
->st_shndx
< SHN_LORESERVE
) {
2236 sm
= &sm_table
[sym
->st_shndx
];
2237 if (sm
->link_once
) {
2238 /* if a symbol is in a link once section, we use the
2239 already defined symbol. It is very important to get
2240 correct relocations */
2241 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2242 name
= strtab
+ sym
->st_name
;
2243 sym_index
= find_elf_sym(symtab_section
, name
);
2245 old_to_new_syms
[i
] = sym_index
;
2249 /* if no corresponding section added, no need to add symbol */
2252 /* convert section number */
2253 sym
->st_shndx
= sm
->s
->sh_num
;
2255 sym
->st_value
+= sm
->offset
;
2258 name
= strtab
+ sym
->st_name
;
2259 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2260 sym
->st_info
, sym
->st_other
,
2261 sym
->st_shndx
, name
);
2262 old_to_new_syms
[i
] = sym_index
;
2265 /* third pass to patch relocation entries */
2266 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2271 offset
= sm_table
[i
].offset
;
2272 switch(s
->sh_type
) {
2274 /* take relocation offset information */
2275 offseti
= sm_table
[sh
->sh_info
].offset
;
2276 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2277 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2282 /* convert symbol index */
2283 type
= ELFW(R_TYPE
)(rel
->r_info
);
2284 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2285 /* NOTE: only one symtab assumed */
2286 if (sym_index
>= nb_syms
)
2288 sym_index
= old_to_new_syms
[sym_index
];
2289 /* ignore link_once in rel section. */
2290 if (!sym_index
&& !sm
->link_once
) {
2292 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2293 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2296 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2297 /* offset the relocation offset */
2298 rel
->r_offset
+= offseti
;
2310 tcc_free(old_to_new_syms
);
2317 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2319 typedef struct ArchiveHeader
{
2320 char ar_name
[16]; /* name of this member */
2321 char ar_date
[12]; /* file mtime */
2322 char ar_uid
[6]; /* owner uid; printed as decimal */
2323 char ar_gid
[6]; /* owner gid; printed as decimal */
2324 char ar_mode
[8]; /* file mode, printed as octal */
2325 char ar_size
[10]; /* file size, printed as decimal */
2326 char ar_fmag
[2]; /* should contain ARFMAG */
2329 static int get_be32(const uint8_t *b
)
2331 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2334 /* load only the objects which resolve undefined symbols */
2335 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2337 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2339 const char *ar_names
, *p
;
2340 const uint8_t *ar_index
;
2343 data
= tcc_malloc(size
);
2344 if (read(fd
, data
, size
) != size
)
2346 nsyms
= get_be32(data
);
2347 ar_index
= data
+ 4;
2348 ar_names
= ar_index
+ nsyms
* 4;
2352 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2353 sym_index
= find_elf_sym(symtab_section
, p
);
2355 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2356 if(sym
->st_shndx
== SHN_UNDEF
) {
2357 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2359 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2362 lseek(fd
, off
, SEEK_SET
);
2363 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2378 /* load a '.a' file */
2379 static int tcc_load_archive(TCCState
*s1
, int fd
)
2386 unsigned long file_offset
;
2388 /* skip magic which was already checked */
2389 read(fd
, magic
, sizeof(magic
));
2392 len
= read(fd
, &hdr
, sizeof(hdr
));
2395 if (len
!= sizeof(hdr
)) {
2396 error_noabort("invalid archive");
2399 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2400 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2401 size
= strtol(ar_size
, NULL
, 0);
2402 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2403 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2404 if (ar_name
[i
] != ' ')
2407 ar_name
[i
+ 1] = '\0';
2408 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2409 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2411 size
= (size
+ 1) & ~1;
2412 if (!strcmp(ar_name
, "/")) {
2413 /* coff symbol table : we handle it */
2414 if(s1
->alacarte_link
)
2415 return tcc_load_alacarte(s1
, fd
, size
);
2416 } else if (!strcmp(ar_name
, "//") ||
2417 !strcmp(ar_name
, "__.SYMDEF") ||
2418 !strcmp(ar_name
, "__.SYMDEF/") ||
2419 !strcmp(ar_name
, "ARFILENAMES/")) {
2420 /* skip symbol table or archive names */
2422 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2425 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2430 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2431 is referenced by the user (so it should be added as DT_NEEDED in
2432 the generated ELF file) */
2433 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2436 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2437 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2438 ElfW(Sym
) *sym
, *dynsym
;
2439 ElfW(Dyn
) *dt
, *dynamic
;
2440 unsigned char *dynstr
;
2441 const char *name
, *soname
;
2442 DLLReference
*dllref
;
2444 read(fd
, &ehdr
, sizeof(ehdr
));
2446 /* test CPU specific stuff */
2447 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2448 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2449 error_noabort("bad architecture");
2454 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2456 /* load dynamic section and dynamic symbols */
2460 dynsym
= NULL
; /* avoid warning */
2461 dynstr
= NULL
; /* avoid warning */
2462 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2463 switch(sh
->sh_type
) {
2465 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2466 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2469 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2470 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2471 sh1
= &shdr
[sh
->sh_link
];
2472 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2479 /* compute the real library name */
2480 soname
= tcc_basename(filename
);
2482 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2483 if (dt
->d_tag
== DT_SONAME
) {
2484 soname
= dynstr
+ dt
->d_un
.d_val
;
2488 /* if the dll is already loaded, do not load it */
2489 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2490 dllref
= s1
->loaded_dlls
[i
];
2491 if (!strcmp(soname
, dllref
->name
)) {
2492 /* but update level if needed */
2493 if (level
< dllref
->level
)
2494 dllref
->level
= level
;
2500 // printf("loading dll '%s'\n", soname);
2502 /* add the dll and its level */
2503 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2504 dllref
->level
= level
;
2505 strcpy(dllref
->name
, soname
);
2506 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2508 /* add dynamic symbols in dynsym_section */
2509 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2510 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2511 if (sym_bind
== STB_LOCAL
)
2513 name
= dynstr
+ sym
->st_name
;
2514 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2515 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2518 /* load all referenced DLLs */
2519 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2522 name
= dynstr
+ dt
->d_un
.d_val
;
2523 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2524 dllref
= s1
->loaded_dlls
[j
];
2525 if (!strcmp(name
, dllref
->name
))
2526 goto already_loaded
;
2528 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2529 error_noabort("referenced dll '%s' not found", name
);
2546 #define LD_TOK_NAME 256
2547 #define LD_TOK_EOF (-1)
2549 /* return next ld script token */
2550 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2568 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2569 ch
= file
->buf_ptr
[0];
2577 /* case 'a' ... 'z': */
2604 /* case 'A' ... 'z': */
2639 if (!((ch
>= 'a' && ch
<= 'z') ||
2640 (ch
>= 'A' && ch
<= 'Z') ||
2641 (ch
>= '0' && ch
<= '9') ||
2642 strchr("/.-_+=$:\\,~", ch
)))
2644 if ((q
- name
) < name_size
- 1) {
2661 printf("tok=%c %d\n", c
, c
);
2662 if (c
== LD_TOK_NAME
)
2663 printf(" name=%s\n", name
);
2668 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2670 char filename
[1024];
2673 t
= ld_next(s1
, filename
, sizeof(filename
));
2676 t
= ld_next(s1
, filename
, sizeof(filename
));
2678 if (t
== LD_TOK_EOF
) {
2679 error_noabort("unexpected end of file");
2681 } else if (t
== ')') {
2683 } else if (t
!= LD_TOK_NAME
) {
2684 error_noabort("filename expected");
2687 if (!strcmp(filename
, "AS_NEEDED")) {
2688 ret
= ld_add_file_list(s1
, 1);
2692 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2694 tcc_add_file(s1
, filename
);
2696 t
= ld_next(s1
, filename
, sizeof(filename
));
2698 t
= ld_next(s1
, filename
, sizeof(filename
));
2704 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2706 static int tcc_load_ldscript(TCCState
*s1
)
2709 char filename
[1024];
2712 ch
= file
->buf_ptr
[0];
2715 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2716 if (t
== LD_TOK_EOF
)
2718 else if (t
!= LD_TOK_NAME
)
2720 if (!strcmp(cmd
, "INPUT") ||
2721 !strcmp(cmd
, "GROUP")) {
2722 ret
= ld_add_file_list(s1
, 0);
2725 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2726 !strcmp(cmd
, "TARGET")) {
2727 /* ignore some commands */
2728 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2732 t
= ld_next(s1
, filename
, sizeof(filename
));
2733 if (t
== LD_TOK_EOF
) {
2734 error_noabort("unexpected end of file");
2736 } else if (t
== ')') {