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*)(long)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
237 && (sh_num
< SHN_LORESERVE
|| sh_num
== SHN_COMMON
)) {
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
= s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
;
485 s1
->runtime_plt_and_got_offset
+= JMP_TABLE_ENTRY_SIZE
;
490 *(unsigned long *)(p
+ 6) = val
;
491 return (unsigned long)p
;
494 static unsigned long add_got_table(TCCState
*s1
, unsigned long val
)
496 unsigned long *p
=(unsigned long *)(s1
->runtime_plt_and_got
+
497 s1
->runtime_plt_and_got_offset
);
498 s1
->runtime_plt_and_got_offset
+= sizeof(void *);
500 return (unsigned long)p
;
504 /* relocate a given section (CPU dependent) */
505 static void relocate_section(TCCState
*s1
, Section
*s
)
508 ElfW_Rel
*rel
, *rel_end
, *qrel
;
512 unsigned long val
, addr
;
513 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
518 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
519 qrel
= (ElfW_Rel
*)sr
->data
;
523 ptr
= s
->data
+ rel
->r_offset
;
525 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
526 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
528 #ifdef TCC_TARGET_X86_64
529 /* XXX: not tested */
530 val
+= rel
->r_addend
;
532 type
= ELFW(R_TYPE
)(rel
->r_info
);
533 addr
= s
->sh_addr
+ rel
->r_offset
;
537 #if defined(TCC_TARGET_I386)
539 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
540 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
541 qrel
->r_offset
= rel
->r_offset
;
543 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_32
);
547 qrel
->r_info
= ELFW(R_INFO
)(0, R_386_RELATIVE
);
554 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
556 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
558 qrel
->r_offset
= rel
->r_offset
;
559 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_PC32
);
564 *(int *)ptr
+= val
- addr
;
567 *(int *)ptr
+= val
- addr
;
574 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
577 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
580 /* we load the got offset */
581 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
583 #elif defined(TCC_TARGET_ARM)
590 x
= (*(int *)ptr
)&0xffffff;
591 (*(int *)ptr
) &= 0xff000000;
596 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
597 error("can't relocate value at %x",addr
);
606 x
= (*(int *)ptr
) & 0x7fffffff;
607 (*(int *)ptr
) &= 0x80000000;
610 if((x
^(x
>>1))&0x40000000)
611 error("can't relocate value at %x",addr
);
612 (*(int *)ptr
) |= x
& 0x7fffffff;
617 case R_ARM_BASE_PREL
:
618 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
621 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
624 /* we load the got offset */
625 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
630 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
631 type
,addr
,(unsigned int )ptr
,val
);
633 #elif defined(TCC_TARGET_C67)
641 /* put the low 16 bits of the absolute address */
642 // add to what is already there
644 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
645 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
647 //patch both at once - assumes always in pairs Low - High
649 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
650 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
656 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
657 type
,addr
,(unsigned int )ptr
,val
);
659 #elif defined(TCC_TARGET_X86_64)
661 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
662 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
663 qrel
->r_addend
= *(long long *)ptr
+ val
;
666 *(long long *)ptr
+= val
;
670 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
671 /* XXX: this logic may depend on TCC's codegen
672 now TCC uses R_X86_64_32 even for a 64bit pointer */
673 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
674 qrel
->r_addend
= *(int *)ptr
+ val
;
679 case R_X86_64_PC32
: {
680 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
682 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
684 qrel
->r_offset
= rel
->r_offset
;
685 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_X86_64_PC32
);
686 qrel
->r_addend
= *(int *)ptr
;
691 long diff
= val
- addr
;
692 if (diff
<= -2147483647 || diff
> 2147483647) {
693 /* XXX: naive support for over 32bit jump */
694 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
695 val
= add_jmp_table(s1
, val
);
698 if (diff
<= -2147483647 || diff
> 2147483647) {
699 error("internal error: relocation failed");
706 *(int *)ptr
+= val
- addr
;
708 case R_X86_64_GLOB_DAT
:
709 case R_X86_64_JUMP_SLOT
:
712 case R_X86_64_GOTPCREL
:
713 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
714 val
= add_got_table(s1
, val
- rel
->r_addend
) + rel
->r_addend
;
715 *(int *)ptr
+= val
- addr
;
718 *(int *)ptr
+= (s1
->got
->sh_addr
- addr
+
719 s1
->got_offsets
[sym_index
] - 4);
721 case R_X86_64_GOTTPOFF
:
722 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
725 /* we load the got offset */
726 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
729 #error unsupported processor
733 /* if the relocation is allocated, we change its symbol table */
734 if (sr
->sh_flags
& SHF_ALLOC
)
735 sr
->link
= s1
->dynsym
;
738 /* relocate relocation table in 'sr' */
739 static void relocate_rel(TCCState
*s1
, Section
*sr
)
742 ElfW_Rel
*rel
, *rel_end
;
744 s
= s1
->sections
[sr
->sh_info
];
745 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
746 for(rel
= (ElfW_Rel
*)sr
->data
;
749 rel
->r_offset
+= s
->sh_addr
;
753 /* count the number of dynamic relocations so that we can reserve
755 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
757 ElfW_Rel
*rel
, *rel_end
;
758 int sym_index
, esym_index
, type
, count
;
761 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
762 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
763 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
764 type
= ELFW(R_TYPE
)(rel
->r_info
);
766 #if defined(TCC_TARGET_I386)
768 #elif defined(TCC_TARGET_X86_64)
775 #if defined(TCC_TARGET_I386)
777 #elif defined(TCC_TARGET_X86_64)
780 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
789 /* allocate the section */
790 sr
->sh_flags
|= SHF_ALLOC
;
791 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
796 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
801 if (index
>= s1
->nb_got_offsets
) {
802 /* find immediately bigger power of 2 and reallocate array */
806 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
808 error("memory full");
809 s1
->got_offsets
= tab
;
810 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
811 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
812 s1
->nb_got_offsets
= n
;
814 s1
->got_offsets
[index
] = val
;
817 /* XXX: suppress that */
818 static void put32(unsigned char *p
, uint32_t val
)
826 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
827 defined(TCC_TARGET_X86_64)
828 static uint32_t get32(unsigned char *p
)
830 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
834 static void build_got(TCCState
*s1
)
838 /* if no got, then create it */
839 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
840 s1
->got
->sh_entsize
= 4;
841 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
842 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
843 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
845 /* keep space for _DYNAMIC pointer, if present */
847 /* two dummy got entries */
851 /* keep space for _DYNAMIC pointer, if present */
854 /* two dummy got entries */
862 /* put a got entry corresponding to a symbol in symtab_section. 'size'
863 and 'info' can be modifed if more precise info comes from the DLL */
864 static void put_got_entry(TCCState
*s1
,
865 int reloc_type
, unsigned long size
, int info
,
871 unsigned long offset
;
877 /* if a got entry already exists for that symbol, no need to add one */
878 if (sym_index
< s1
->nb_got_offsets
&&
879 s1
->got_offsets
[sym_index
] != 0)
882 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
885 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
886 name
= symtab_section
->link
->data
+ sym
->st_name
;
887 offset
= sym
->st_value
;
888 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
890 #ifdef TCC_TARGET_X86_64
900 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
903 /* if we build a DLL, we add a %ebx offset */
904 if (s1
->output_type
== TCC_OUTPUT_DLL
)
910 /* add a PLT entry */
912 if (plt
->data_offset
== 0) {
913 /* first plt entry */
914 p
= section_ptr_add(plt
, 16);
915 p
[0] = 0xff; /* pushl got + PTR_SIZE */
917 put32(p
+ 2, PTR_SIZE
);
918 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
920 put32(p
+ 8, PTR_SIZE
* 2);
923 p
= section_ptr_add(plt
, 16);
924 p
[0] = 0xff; /* jmp *(got + x) */
926 put32(p
+ 2, s1
->got
->data_offset
);
927 p
[6] = 0x68; /* push $xxx */
928 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
929 p
[11] = 0xe9; /* jmp plt_start */
930 put32(p
+ 12, -(plt
->data_offset
));
932 /* the symbol is modified so that it will be relocated to
934 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
935 if (s1
->output_type
== TCC_OUTPUT_EXE
)
937 offset
= plt
->data_offset
- 16;
939 #elif defined(TCC_TARGET_ARM)
940 if (reloc_type
== R_ARM_JUMP_SLOT
) {
944 /* if we build a DLL, we add a %ebx offset */
945 if (s1
->output_type
== TCC_OUTPUT_DLL
)
946 error("DLLs unimplemented!");
948 /* add a PLT entry */
950 if (plt
->data_offset
== 0) {
951 /* first plt entry */
952 p
= section_ptr_add(plt
, 16);
953 put32(p
, 0xe52de004);
954 put32(p
+ 4, 0xe59fe010);
955 put32(p
+ 8, 0xe08fe00e);
956 put32(p
+ 12, 0xe5bef008);
959 p
= section_ptr_add(plt
, 16);
960 put32(p
, 0xe59fc004);
961 put32(p
+4, 0xe08fc00c);
962 put32(p
+8, 0xe59cf000);
963 put32(p
+12, s1
->got
->data_offset
);
965 /* the symbol is modified so that it will be relocated to
967 if (s1
->output_type
== TCC_OUTPUT_EXE
)
968 offset
= plt
->data_offset
- 16;
970 #elif defined(TCC_TARGET_C67)
971 error("C67 got not implemented");
973 #error unsupported CPU
975 index
= put_elf_sym(s1
->dynsym
, offset
,
976 size
, info
, 0, sym
->st_shndx
, name
);
977 /* put a got entry */
978 put_elf_reloc(s1
->dynsym
, s1
->got
,
979 s1
->got
->data_offset
,
982 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
986 /* build GOT and PLT entries */
987 static void build_got_entries(TCCState
*s1
)
990 ElfW_Rel
*rel
, *rel_end
;
992 int i
, type
, reloc_type
, sym_index
;
994 for(i
= 1; i
< s1
->nb_sections
; i
++) {
996 if (s
->sh_type
!= SHT_RELX
)
998 /* no need to handle got relocations */
999 if (s
->link
!= symtab_section
)
1002 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
1003 for(rel
= (ElfW_Rel
*)s
->data
;
1006 type
= ELFW(R_TYPE
)(rel
->r_info
);
1008 #if defined(TCC_TARGET_I386)
1015 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1016 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1017 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1018 /* look at the symbol got offset. If none, then add one */
1019 if (type
== R_386_GOT32
)
1020 reloc_type
= R_386_GLOB_DAT
;
1022 reloc_type
= R_386_JMP_SLOT
;
1023 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1027 #elif defined(TCC_TARGET_ARM)
1028 case R_ARM_GOT_BREL
:
1029 case R_ARM_GOTOFF32
:
1030 case R_ARM_BASE_PREL
:
1034 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1035 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1036 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1037 /* look at the symbol got offset. If none, then add one */
1038 if (type
== R_ARM_GOT_BREL
)
1039 reloc_type
= R_ARM_GLOB_DAT
;
1041 reloc_type
= R_ARM_JUMP_SLOT
;
1042 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1046 #elif defined(TCC_TARGET_C67)
1053 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1054 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1055 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1056 /* look at the symbol got offset. If none, then add one */
1057 if (type
== R_C60_GOT32
)
1058 reloc_type
= R_C60_GLOB_DAT
;
1060 reloc_type
= R_C60_JMP_SLOT
;
1061 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1065 #elif defined(TCC_TARGET_X86_64)
1066 case R_X86_64_GOT32
:
1067 case R_X86_64_GOTTPOFF
:
1068 case R_X86_64_GOTPCREL
:
1069 case R_X86_64_PLT32
:
1072 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
||
1073 type
== R_X86_64_PLT32
) {
1074 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1075 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1076 /* look at the symbol got offset. If none, then add one */
1077 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
)
1078 reloc_type
= R_X86_64_GLOB_DAT
;
1080 reloc_type
= R_X86_64_JUMP_SLOT
;
1081 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1086 #error unsupported CPU
1095 static Section
*new_symtab(TCCState
*s1
,
1096 const char *symtab_name
, int sh_type
, int sh_flags
,
1097 const char *strtab_name
,
1098 const char *hash_name
, int hash_sh_flags
)
1100 Section
*symtab
, *strtab
, *hash
;
1101 int *ptr
, nb_buckets
;
1103 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1104 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1105 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1106 put_elf_str(strtab
, "");
1107 symtab
->link
= strtab
;
1108 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1112 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1113 hash
->sh_entsize
= sizeof(int);
1114 symtab
->hash
= hash
;
1115 hash
->link
= symtab
;
1117 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1118 ptr
[0] = nb_buckets
;
1120 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1124 /* put dynamic tag */
1125 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1128 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1130 dyn
->d_un
.d_val
= val
;
1133 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1137 char sym_start
[1024];
1140 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1141 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1143 s
= find_section(s1
, section_name
);
1148 end_offset
= s
->data_offset
;
1151 add_elf_sym(symtab_section
,
1153 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1154 s
->sh_num
, sym_start
);
1155 add_elf_sym(symtab_section
,
1157 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1158 s
->sh_num
, sym_end
);
1161 /* add tcc runtime libraries */
1162 static void tcc_add_runtime(TCCState
*s1
)
1164 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1168 #ifdef CONFIG_TCC_BCHECK
1169 if (s1
->do_bounds_check
) {
1171 Section
*init_section
;
1172 unsigned char *pinit
;
1175 /* XXX: add an object file to do that */
1176 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1178 add_elf_sym(symtab_section
, 0, 0,
1179 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1180 bounds_section
->sh_num
, "__bounds_start");
1181 /* add bound check code */
1182 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "bcheck.o");
1183 tcc_add_file(s1
, buf
);
1184 #ifdef TCC_TARGET_I386
1185 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1186 /* add 'call __bound_init()' in .init section */
1187 init_section
= find_section(s1
, ".init");
1188 pinit
= section_ptr_add(init_section
, 5);
1190 put32(pinit
+ 1, -4);
1191 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1192 put_elf_reloc(symtab_section
, init_section
,
1193 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1199 if (!s1
->nostdlib
) {
1200 tcc_add_library(s1
, "c");
1202 #ifdef CONFIG_USE_LIBGCC
1203 tcc_add_file(s1
, CONFIG_SYSROOT
"/lib/libgcc_s.so.1");
1205 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "libtcc1.a");
1206 tcc_add_file(s1
, buf
);
1209 /* add crt end if not memory output */
1210 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1211 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1215 /* add various standard linker symbols (must be done after the
1216 sections are filled (for example after allocating common
1218 static void tcc_add_linker_symbols(TCCState
*s1
)
1224 add_elf_sym(symtab_section
,
1225 text_section
->data_offset
, 0,
1226 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1227 text_section
->sh_num
, "_etext");
1228 add_elf_sym(symtab_section
,
1229 data_section
->data_offset
, 0,
1230 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1231 data_section
->sh_num
, "_edata");
1232 add_elf_sym(symtab_section
,
1233 bss_section
->data_offset
, 0,
1234 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1235 bss_section
->sh_num
, "_end");
1236 /* horrible new standard ldscript defines */
1237 add_init_array_defines(s1
, ".preinit_array");
1238 add_init_array_defines(s1
, ".init_array");
1239 add_init_array_defines(s1
, ".fini_array");
1241 /* add start and stop symbols for sections whose name can be
1243 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1244 s
= s1
->sections
[i
];
1245 if (s
->sh_type
== SHT_PROGBITS
&&
1246 (s
->sh_flags
& SHF_ALLOC
)) {
1250 /* check if section name can be expressed in C */
1256 if (!isid(ch
) && !isnum(ch
))
1260 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1261 add_elf_sym(symtab_section
,
1263 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1265 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1266 add_elf_sym(symtab_section
,
1268 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1275 /* name of ELF interpreter */
1276 #if defined __FreeBSD__
1277 static char elf_interp
[] = "/usr/libexec/ld-elf.so.1";
1278 #elif defined TCC_ARM_EABI
1279 static char elf_interp
[] = "/lib/ld-linux.so.3";
1280 #elif defined(TCC_TARGET_X86_64)
1281 static char elf_interp
[] = "/lib/ld-linux-x86-64.so.2";
1282 #elif defined(TCC_UCLIBC)
1283 static char elf_interp
[] = "/lib/ld-uClibc.so.0";
1285 static char elf_interp
[] = "/lib/ld-linux.so.2";
1288 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1289 const int *section_order
)
1292 int i
, offset
, size
;
1295 for(i
=1;i
<s1
->nb_sections
;i
++) {
1296 s
= s1
->sections
[section_order
[i
]];
1297 if (s
->sh_type
!= SHT_NOBITS
&&
1298 (s
->sh_flags
& SHF_ALLOC
)) {
1299 while (offset
< s
->sh_offset
) {
1304 fwrite(s
->data
, 1, size
, f
);
1310 /* output an ELF file */
1311 /* XXX: suppress unneeded sections */
1312 int elf_output_file(TCCState
*s1
, const char *filename
)
1318 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1320 Section
*strsec
, *s
;
1321 ElfW(Shdr
) shdr
, *sh
;
1322 ElfW(Phdr
) *phdr
, *ph
;
1323 Section
*interp
, *dynamic
, *dynstr
;
1324 unsigned long saved_dynamic_data_offset
;
1326 int type
, file_type
;
1327 unsigned long rel_addr
, rel_size
;
1329 file_type
= s1
->output_type
;
1332 if (file_type
!= TCC_OUTPUT_OBJ
) {
1333 tcc_add_runtime(s1
);
1337 section_order
= NULL
;
1340 dynstr
= NULL
; /* avoid warning */
1341 saved_dynamic_data_offset
= 0; /* avoid warning */
1343 if (file_type
!= TCC_OUTPUT_OBJ
) {
1344 relocate_common_syms();
1346 tcc_add_linker_symbols(s1
);
1348 if (!s1
->static_link
) {
1350 int sym_index
, index
;
1351 ElfW(Sym
) *esym
, *sym_end
;
1353 if (file_type
== TCC_OUTPUT_EXE
) {
1355 /* add interpreter section only if executable */
1356 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1357 interp
->sh_addralign
= 1;
1358 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
1359 strcpy(ptr
, elf_interp
);
1362 /* add dynamic symbol table */
1363 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1365 ".hash", SHF_ALLOC
);
1366 dynstr
= s1
->dynsym
->link
;
1368 /* add dynamic section */
1369 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1370 SHF_ALLOC
| SHF_WRITE
);
1371 dynamic
->link
= dynstr
;
1372 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1375 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1376 SHF_ALLOC
| SHF_EXECINSTR
);
1377 s1
->plt
->sh_entsize
= 4;
1381 /* scan for undefined symbols and see if they are in the
1382 dynamic symbols. If a symbol STT_FUNC is found, then we
1383 add it in the PLT. If a symbol STT_OBJECT is found, we
1384 add it in the .bss section with a suitable relocation */
1385 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1386 symtab_section
->data_offset
);
1387 if (file_type
== TCC_OUTPUT_EXE
) {
1388 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1391 if (sym
->st_shndx
== SHN_UNDEF
) {
1392 name
= symtab_section
->link
->data
+ sym
->st_name
;
1393 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1395 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1396 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1397 if (type
== STT_FUNC
) {
1398 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1400 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1401 } else if (type
== STT_OBJECT
) {
1402 unsigned long offset
;
1403 offset
= bss_section
->data_offset
;
1404 /* XXX: which alignment ? */
1405 offset
= (offset
+ 16 - 1) & -16;
1406 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1408 bss_section
->sh_num
, name
);
1409 put_elf_reloc(s1
->dynsym
, bss_section
,
1410 offset
, R_COPY
, index
);
1411 offset
+= esym
->st_size
;
1412 bss_section
->data_offset
= offset
;
1415 /* STB_WEAK undefined symbols are accepted */
1416 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1418 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1419 !strcmp(name
, "_fp_hw")) {
1421 error_noabort("undefined symbol '%s'", name
);
1424 } else if (s1
->rdynamic
&&
1425 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1426 /* if -rdynamic option, then export all non
1428 name
= symtab_section
->link
->data
+ sym
->st_name
;
1429 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1431 sym
->st_shndx
, name
);
1438 /* now look at unresolved dynamic symbols and export
1439 corresponding symbol */
1440 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1441 s1
->dynsymtab_section
->data_offset
);
1442 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1445 if (esym
->st_shndx
== SHN_UNDEF
) {
1446 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1447 sym_index
= find_elf_sym(symtab_section
, name
);
1449 /* XXX: avoid adding a symbol if already
1450 present because of -rdynamic ? */
1451 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1452 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1454 sym
->st_shndx
, name
);
1456 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1457 /* weak symbols can stay undefined */
1459 warning("undefined dynamic symbol '%s'", name
);
1466 /* shared library case : we simply export all the global symbols */
1467 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1468 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1469 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1472 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1473 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1474 if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
&&
1475 sym
->st_shndx
== SHN_UNDEF
) {
1476 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1478 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1480 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1481 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1483 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1488 name
= symtab_section
->link
->data
+ sym
->st_name
;
1489 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1491 sym
->st_shndx
, name
);
1492 s1
->symtab_to_dynsym
[sym
-
1493 (ElfW(Sym
) *)symtab_section
->data
] =
1500 build_got_entries(s1
);
1502 /* add a list of needed dlls */
1503 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1504 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1505 if (dllref
->level
== 0)
1506 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1508 /* XXX: currently, since we do not handle PIC code, we
1509 must relocate the readonly segments */
1510 if (file_type
== TCC_OUTPUT_DLL
) {
1512 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1513 put_dt(dynamic
, DT_TEXTREL
, 0);
1516 /* add necessary space for other entries */
1517 saved_dynamic_data_offset
= dynamic
->data_offset
;
1518 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * 9;
1520 /* still need to build got entries in case of static link */
1521 build_got_entries(s1
);
1525 memset(&ehdr
, 0, sizeof(ehdr
));
1527 /* we add a section for symbols */
1528 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1529 put_elf_str(strsec
, "");
1531 /* compute number of sections */
1532 shnum
= s1
->nb_sections
;
1534 /* this array is used to reorder sections in the output file */
1535 section_order
= tcc_malloc(sizeof(int) * shnum
);
1536 section_order
[0] = 0;
1539 /* compute number of program headers */
1542 case TCC_OUTPUT_OBJ
:
1545 case TCC_OUTPUT_EXE
:
1546 if (!s1
->static_link
)
1551 case TCC_OUTPUT_DLL
:
1556 /* allocate strings for section names and decide if an unallocated
1557 section should be output */
1558 /* NOTE: the strsec section comes last, so its size is also
1560 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1561 s
= s1
->sections
[i
];
1562 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1564 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1569 s
->reloc
? s
->reloc
->name
: "n"
1572 /* when generating a DLL, we include relocations but we may
1574 if (file_type
== TCC_OUTPUT_DLL
&&
1575 s
->sh_type
== SHT_RELX
&&
1576 !(s
->sh_flags
& SHF_ALLOC
)) {
1577 /* //gr: avoid bogus relocs for empty (debug) sections */
1578 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1579 prepare_dynamic_rel(s1
, s
);
1580 else if (s1
->do_debug
)
1581 s
->sh_size
= s
->data_offset
;
1582 } else if (s1
->do_debug
||
1583 file_type
== TCC_OUTPUT_OBJ
||
1584 (s
->sh_flags
& SHF_ALLOC
) ||
1585 i
== (s1
->nb_sections
- 1)) {
1586 /* we output all sections if debug or object file */
1587 s
->sh_size
= s
->data_offset
;
1591 /* allocate program segment headers */
1592 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1594 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1595 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1600 /* compute section to program header mapping */
1601 if (s1
->has_text_addr
) {
1602 int a_offset
, p_offset
;
1603 addr
= s1
->text_addr
;
1604 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1606 a_offset
= addr
& (ELF_PAGE_SIZE
- 1);
1607 p_offset
= file_offset
& (ELF_PAGE_SIZE
- 1);
1608 if (a_offset
< p_offset
)
1609 a_offset
+= ELF_PAGE_SIZE
;
1610 file_offset
+= (a_offset
- p_offset
);
1612 if (file_type
== TCC_OUTPUT_DLL
)
1615 addr
= ELF_START_ADDR
;
1616 /* compute address after headers */
1617 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1620 /* dynamic relocation table information, for .dynamic section */
1624 /* leave one program header for the program interpreter */
1629 for(j
= 0; j
< 2; j
++) {
1630 ph
->p_type
= PT_LOAD
;
1632 ph
->p_flags
= PF_R
| PF_X
;
1634 ph
->p_flags
= PF_R
| PF_W
;
1635 ph
->p_align
= ELF_PAGE_SIZE
;
1637 /* we do the following ordering: interp, symbol tables,
1638 relocations, progbits, nobits */
1639 /* XXX: do faster and simpler sorting */
1640 for(k
= 0; k
< 5; k
++) {
1641 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1642 s
= s1
->sections
[i
];
1643 /* compute if section should be included */
1645 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1649 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1650 (SHF_ALLOC
| SHF_WRITE
))
1656 } else if (s
->sh_type
== SHT_DYNSYM
||
1657 s
->sh_type
== SHT_STRTAB
||
1658 s
->sh_type
== SHT_HASH
) {
1661 } else if (s
->sh_type
== SHT_RELX
) {
1664 } else if (s
->sh_type
== SHT_NOBITS
) {
1671 section_order
[sh_order_index
++] = i
;
1673 /* section matches: we align it and add its size */
1675 addr
= (addr
+ s
->sh_addralign
- 1) &
1676 ~(s
->sh_addralign
- 1);
1677 file_offset
+= addr
- tmp
;
1678 s
->sh_offset
= file_offset
;
1681 /* update program header infos */
1682 if (ph
->p_offset
== 0) {
1683 ph
->p_offset
= file_offset
;
1685 ph
->p_paddr
= ph
->p_vaddr
;
1687 /* update dynamic relocation infos */
1688 if (s
->sh_type
== SHT_RELX
) {
1691 rel_size
+= s
->sh_size
;
1694 if (s
->sh_type
!= SHT_NOBITS
)
1695 file_offset
+= s
->sh_size
;
1698 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1699 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1702 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1703 /* if in the middle of a page, we duplicate the page in
1704 memory so that one copy is RX and the other is RW */
1705 if ((addr
& (ELF_PAGE_SIZE
- 1)) != 0)
1706 addr
+= ELF_PAGE_SIZE
;
1708 addr
= (addr
+ ELF_PAGE_SIZE
- 1) & ~(ELF_PAGE_SIZE
- 1);
1709 file_offset
= (file_offset
+ ELF_PAGE_SIZE
- 1) &
1710 ~(ELF_PAGE_SIZE
- 1);
1715 /* if interpreter, then add corresponing program header */
1719 ph
->p_type
= PT_INTERP
;
1720 ph
->p_offset
= interp
->sh_offset
;
1721 ph
->p_vaddr
= interp
->sh_addr
;
1722 ph
->p_paddr
= ph
->p_vaddr
;
1723 ph
->p_filesz
= interp
->sh_size
;
1724 ph
->p_memsz
= interp
->sh_size
;
1726 ph
->p_align
= interp
->sh_addralign
;
1729 /* if dynamic section, then add corresponing program header */
1733 ph
= &phdr
[phnum
- 1];
1735 ph
->p_type
= PT_DYNAMIC
;
1736 ph
->p_offset
= dynamic
->sh_offset
;
1737 ph
->p_vaddr
= dynamic
->sh_addr
;
1738 ph
->p_paddr
= ph
->p_vaddr
;
1739 ph
->p_filesz
= dynamic
->sh_size
;
1740 ph
->p_memsz
= dynamic
->sh_size
;
1741 ph
->p_flags
= PF_R
| PF_W
;
1742 ph
->p_align
= dynamic
->sh_addralign
;
1744 /* put GOT dynamic section address */
1745 put32(s1
->got
->data
, dynamic
->sh_addr
);
1747 /* relocate the PLT */
1748 if (file_type
== TCC_OUTPUT_EXE
1749 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1750 || file_type
== TCC_OUTPUT_DLL
1756 p_end
= p
+ s1
->plt
->data_offset
;
1758 #if defined(TCC_TARGET_I386)
1759 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1760 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1763 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1766 #elif defined(TCC_TARGET_X86_64)
1767 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1768 put32(p
+ 2, get32(p
+ 2) + x
);
1769 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1772 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1775 #elif defined(TCC_TARGET_ARM)
1777 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1780 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1783 #elif defined(TCC_TARGET_C67)
1786 #error unsupported CPU
1791 /* relocate symbols in .dynsym */
1792 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1793 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1796 if (sym
->st_shndx
== SHN_UNDEF
) {
1797 /* relocate to the PLT if the symbol corresponds
1800 sym
->st_value
+= s1
->plt
->sh_addr
;
1801 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1802 /* do symbol relocation */
1803 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1807 /* put dynamic section entries */
1808 dynamic
->data_offset
= saved_dynamic_data_offset
;
1809 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1810 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1811 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1812 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1813 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1814 #ifdef TCC_TARGET_X86_64
1815 put_dt(dynamic
, DT_RELA
, rel_addr
);
1816 put_dt(dynamic
, DT_RELASZ
, rel_size
);
1817 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1819 put_dt(dynamic
, DT_REL
, rel_addr
);
1820 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1821 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1824 put_dt(dynamic
, DT_DEBUG
, 0);
1825 put_dt(dynamic
, DT_NULL
, 0);
1828 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1829 ehdr
.e_phnum
= phnum
;
1830 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1833 /* all other sections come after */
1834 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1835 s
= s1
->sections
[i
];
1836 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1838 section_order
[sh_order_index
++] = i
;
1840 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1841 ~(s
->sh_addralign
- 1);
1842 s
->sh_offset
= file_offset
;
1843 if (s
->sh_type
!= SHT_NOBITS
)
1844 file_offset
+= s
->sh_size
;
1847 /* if building executable or DLL, then relocate each section
1848 except the GOT which is already relocated */
1849 if (file_type
!= TCC_OUTPUT_OBJ
) {
1850 relocate_syms(s1
, 0);
1852 if (s1
->nb_errors
!= 0) {
1858 /* relocate sections */
1859 /* XXX: ignore sections with allocated relocations ? */
1860 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1861 s
= s1
->sections
[i
];
1862 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1863 relocate_section(s1
, s
);
1866 /* relocate relocation entries if the relocation tables are
1867 allocated in the executable */
1868 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1869 s
= s1
->sections
[i
];
1870 if ((s
->sh_flags
& SHF_ALLOC
) &&
1871 s
->sh_type
== SHT_RELX
) {
1872 relocate_rel(s1
, s
);
1876 /* get entry point address */
1877 if (file_type
== TCC_OUTPUT_EXE
)
1878 ehdr
.e_entry
= (unsigned long)tcc_get_symbol_err(s1
, "_start");
1880 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1883 /* write elf file */
1884 if (file_type
== TCC_OUTPUT_OBJ
)
1888 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1890 error_noabort("could not write '%s'", filename
);
1893 f
= fdopen(fd
, "wb");
1895 printf("<- %s\n", filename
);
1897 #ifdef TCC_TARGET_COFF
1898 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1899 tcc_output_coff(s1
, f
);
1902 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1903 sort_syms(s1
, symtab_section
);
1906 file_offset
= (file_offset
+ 3) & -4;
1909 ehdr
.e_ident
[0] = ELFMAG0
;
1910 ehdr
.e_ident
[1] = ELFMAG1
;
1911 ehdr
.e_ident
[2] = ELFMAG2
;
1912 ehdr
.e_ident
[3] = ELFMAG3
;
1913 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
1914 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1915 ehdr
.e_ident
[6] = EV_CURRENT
;
1917 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1919 #ifdef TCC_TARGET_ARM
1921 ehdr
.e_ident
[EI_OSABI
] = 0;
1922 ehdr
.e_flags
= 4 << 24;
1924 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
1929 case TCC_OUTPUT_EXE
:
1930 ehdr
.e_type
= ET_EXEC
;
1932 case TCC_OUTPUT_DLL
:
1933 ehdr
.e_type
= ET_DYN
;
1935 case TCC_OUTPUT_OBJ
:
1936 ehdr
.e_type
= ET_REL
;
1939 ehdr
.e_machine
= EM_TCC_TARGET
;
1940 ehdr
.e_version
= EV_CURRENT
;
1941 ehdr
.e_shoff
= file_offset
;
1942 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
1943 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
1944 ehdr
.e_shnum
= shnum
;
1945 ehdr
.e_shstrndx
= shnum
- 1;
1947 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
1948 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
1949 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1951 for(i
=1;i
<s1
->nb_sections
;i
++) {
1952 s
= s1
->sections
[section_order
[i
]];
1953 if (s
->sh_type
!= SHT_NOBITS
) {
1954 while (offset
< s
->sh_offset
) {
1959 fwrite(s
->data
, 1, size
, f
);
1964 /* output section headers */
1965 while (offset
< ehdr
.e_shoff
) {
1970 for(i
=0;i
<s1
->nb_sections
;i
++) {
1972 memset(sh
, 0, sizeof(ElfW(Shdr
)));
1973 s
= s1
->sections
[i
];
1975 sh
->sh_name
= s
->sh_name
;
1976 sh
->sh_type
= s
->sh_type
;
1977 sh
->sh_flags
= s
->sh_flags
;
1978 sh
->sh_entsize
= s
->sh_entsize
;
1979 sh
->sh_info
= s
->sh_info
;
1981 sh
->sh_link
= s
->link
->sh_num
;
1982 sh
->sh_addralign
= s
->sh_addralign
;
1983 sh
->sh_addr
= s
->sh_addr
;
1984 sh
->sh_offset
= s
->sh_offset
;
1985 sh
->sh_size
= s
->sh_size
;
1987 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
1990 tcc_output_binary(s1
, f
, section_order
);
1996 tcc_free(s1
->symtab_to_dynsym
);
1997 tcc_free(section_order
);
1999 tcc_free(s1
->got_offsets
);
2003 int tcc_output_file(TCCState
*s
, const char *filename
)
2006 #ifdef TCC_TARGET_PE
2007 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2008 ret
= pe_output_file(s
, filename
);
2012 ret
= elf_output_file(s
, filename
);
2017 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2021 data
= tcc_malloc(size
);
2022 lseek(fd
, file_offset
, SEEK_SET
);
2023 read(fd
, data
, size
);
2027 typedef struct SectionMergeInfo
{
2028 Section
*s
; /* corresponding existing section */
2029 unsigned long offset
; /* offset of the new section in the existing section */
2030 uint8_t new_section
; /* true if section 's' was added */
2031 uint8_t link_once
; /* true if link once section */
2034 /* load an object file and merge it with current files */
2035 /* XXX: handle correctly stab (debug) info */
2036 static int tcc_load_object_file(TCCState
*s1
,
2037 int fd
, unsigned long file_offset
)
2040 ElfW(Shdr
) *shdr
, *sh
;
2041 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2042 unsigned char *strsec
, *strtab
;
2043 int *old_to_new_syms
;
2044 char *sh_name
, *name
;
2045 SectionMergeInfo
*sm_table
, *sm
;
2046 ElfW(Sym
) *sym
, *symtab
;
2047 ElfW_Rel
*rel
, *rel_end
;
2053 stab_index
= stabstr_index
= 0;
2055 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2057 if (ehdr
.e_ident
[0] != ELFMAG0
||
2058 ehdr
.e_ident
[1] != ELFMAG1
||
2059 ehdr
.e_ident
[2] != ELFMAG2
||
2060 ehdr
.e_ident
[3] != ELFMAG3
)
2062 /* test if object file */
2063 if (ehdr
.e_type
!= ET_REL
)
2065 /* test CPU specific stuff */
2066 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2067 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2069 error_noabort("invalid object file");
2073 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2074 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2075 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2077 /* load section names */
2078 sh
= &shdr
[ehdr
.e_shstrndx
];
2079 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2081 /* load symtab and strtab */
2082 old_to_new_syms
= NULL
;
2086 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2088 if (sh
->sh_type
== SHT_SYMTAB
) {
2090 error_noabort("object must contain only one symtab");
2095 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2096 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2097 sm_table
[i
].s
= symtab_section
;
2099 /* now load strtab */
2100 sh
= &shdr
[sh
->sh_link
];
2101 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2105 /* now examine each section and try to merge its content with the
2107 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2108 /* no need to examine section name strtab */
2109 if (i
== ehdr
.e_shstrndx
)
2112 sh_name
= strsec
+ sh
->sh_name
;
2113 /* ignore sections types we do not handle */
2114 if (sh
->sh_type
!= SHT_PROGBITS
&&
2115 sh
->sh_type
!= SHT_RELX
&&
2117 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2119 sh
->sh_type
!= SHT_NOBITS
&&
2120 strcmp(sh_name
, ".stabstr")
2123 if (sh
->sh_addralign
< 1)
2124 sh
->sh_addralign
= 1;
2125 /* find corresponding section, if any */
2126 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2127 s
= s1
->sections
[j
];
2128 if (!strcmp(s
->name
, sh_name
)) {
2129 if (!strncmp(sh_name
, ".gnu.linkonce",
2130 sizeof(".gnu.linkonce") - 1)) {
2131 /* if a 'linkonce' section is already present, we
2132 do not add it again. It is a little tricky as
2133 symbols can still be defined in
2135 sm_table
[i
].link_once
= 1;
2142 /* not found: create new section */
2143 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2144 /* take as much info as possible from the section. sh_link and
2145 sh_info will be updated later */
2146 s
->sh_addralign
= sh
->sh_addralign
;
2147 s
->sh_entsize
= sh
->sh_entsize
;
2148 sm_table
[i
].new_section
= 1;
2150 if (sh
->sh_type
!= s
->sh_type
) {
2151 error_noabort("invalid section type");
2155 /* align start of section */
2156 offset
= s
->data_offset
;
2158 if (0 == strcmp(sh_name
, ".stab")) {
2162 if (0 == strcmp(sh_name
, ".stabstr")) {
2167 size
= sh
->sh_addralign
- 1;
2168 offset
= (offset
+ size
) & ~size
;
2169 if (sh
->sh_addralign
> s
->sh_addralign
)
2170 s
->sh_addralign
= sh
->sh_addralign
;
2171 s
->data_offset
= offset
;
2173 sm_table
[i
].offset
= offset
;
2175 /* concatenate sections */
2177 if (sh
->sh_type
!= SHT_NOBITS
) {
2179 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2180 ptr
= section_ptr_add(s
, size
);
2181 read(fd
, ptr
, size
);
2183 s
->data_offset
+= size
;
2188 /* //gr relocate stab strings */
2189 if (stab_index
&& stabstr_index
) {
2192 s
= sm_table
[stab_index
].s
;
2193 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2194 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2195 o
= sm_table
[stabstr_index
].offset
;
2197 a
->n_strx
+= o
, a
++;
2200 /* second short pass to update sh_link and sh_info fields of new
2202 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2204 if (!s
|| !sm_table
[i
].new_section
)
2207 if (sh
->sh_link
> 0)
2208 s
->link
= sm_table
[sh
->sh_link
].s
;
2209 if (sh
->sh_type
== SHT_RELX
) {
2210 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2211 /* update backward link */
2212 s1
->sections
[s
->sh_info
]->reloc
= s
;
2217 /* resolve symbols */
2218 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2221 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2222 if (sym
->st_shndx
!= SHN_UNDEF
&&
2223 sym
->st_shndx
< SHN_LORESERVE
) {
2224 sm
= &sm_table
[sym
->st_shndx
];
2225 if (sm
->link_once
) {
2226 /* if a symbol is in a link once section, we use the
2227 already defined symbol. It is very important to get
2228 correct relocations */
2229 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2230 name
= strtab
+ sym
->st_name
;
2231 sym_index
= find_elf_sym(symtab_section
, name
);
2233 old_to_new_syms
[i
] = sym_index
;
2237 /* if no corresponding section added, no need to add symbol */
2240 /* convert section number */
2241 sym
->st_shndx
= sm
->s
->sh_num
;
2243 sym
->st_value
+= sm
->offset
;
2246 name
= strtab
+ sym
->st_name
;
2247 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2248 sym
->st_info
, sym
->st_other
,
2249 sym
->st_shndx
, name
);
2250 old_to_new_syms
[i
] = sym_index
;
2253 /* third pass to patch relocation entries */
2254 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2259 offset
= sm_table
[i
].offset
;
2260 switch(s
->sh_type
) {
2262 /* take relocation offset information */
2263 offseti
= sm_table
[sh
->sh_info
].offset
;
2264 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2265 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2270 /* convert symbol index */
2271 type
= ELFW(R_TYPE
)(rel
->r_info
);
2272 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2273 /* NOTE: only one symtab assumed */
2274 if (sym_index
>= nb_syms
)
2276 sym_index
= old_to_new_syms
[sym_index
];
2277 /* ignore link_once in rel section. */
2278 if (!sym_index
&& !sm
->link_once
) {
2280 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2281 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2284 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2285 /* offset the relocation offset */
2286 rel
->r_offset
+= offseti
;
2298 tcc_free(old_to_new_syms
);
2305 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2307 typedef struct ArchiveHeader
{
2308 char ar_name
[16]; /* name of this member */
2309 char ar_date
[12]; /* file mtime */
2310 char ar_uid
[6]; /* owner uid; printed as decimal */
2311 char ar_gid
[6]; /* owner gid; printed as decimal */
2312 char ar_mode
[8]; /* file mode, printed as octal */
2313 char ar_size
[10]; /* file size, printed as decimal */
2314 char ar_fmag
[2]; /* should contain ARFMAG */
2317 static int get_be32(const uint8_t *b
)
2319 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2322 /* load only the objects which resolve undefined symbols */
2323 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2325 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2327 const char *ar_names
, *p
;
2328 const uint8_t *ar_index
;
2331 data
= tcc_malloc(size
);
2332 if (read(fd
, data
, size
) != size
)
2334 nsyms
= get_be32(data
);
2335 ar_index
= data
+ 4;
2336 ar_names
= ar_index
+ nsyms
* 4;
2340 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2341 sym_index
= find_elf_sym(symtab_section
, p
);
2343 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2344 if(sym
->st_shndx
== SHN_UNDEF
) {
2345 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2347 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2350 lseek(fd
, off
, SEEK_SET
);
2351 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2366 /* load a '.a' file */
2367 static int tcc_load_archive(TCCState
*s1
, int fd
)
2374 unsigned long file_offset
;
2376 /* skip magic which was already checked */
2377 read(fd
, magic
, sizeof(magic
));
2380 len
= read(fd
, &hdr
, sizeof(hdr
));
2383 if (len
!= sizeof(hdr
)) {
2384 error_noabort("invalid archive");
2387 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2388 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2389 size
= strtol(ar_size
, NULL
, 0);
2390 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2391 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2392 if (ar_name
[i
] != ' ')
2395 ar_name
[i
+ 1] = '\0';
2396 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2397 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2399 size
= (size
+ 1) & ~1;
2400 if (!strcmp(ar_name
, "/")) {
2401 /* coff symbol table : we handle it */
2402 if(s1
->alacarte_link
)
2403 return tcc_load_alacarte(s1
, fd
, size
);
2404 } else if (!strcmp(ar_name
, "//") ||
2405 !strcmp(ar_name
, "__.SYMDEF") ||
2406 !strcmp(ar_name
, "__.SYMDEF/") ||
2407 !strcmp(ar_name
, "ARFILENAMES/")) {
2408 /* skip symbol table or archive names */
2410 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2413 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2418 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2419 is referenced by the user (so it should be added as DT_NEEDED in
2420 the generated ELF file) */
2421 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2424 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2425 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2426 ElfW(Sym
) *sym
, *dynsym
;
2427 ElfW(Dyn
) *dt
, *dynamic
;
2428 unsigned char *dynstr
;
2429 const char *name
, *soname
;
2430 DLLReference
*dllref
;
2432 read(fd
, &ehdr
, sizeof(ehdr
));
2434 /* test CPU specific stuff */
2435 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2436 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2437 error_noabort("bad architecture");
2442 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2444 /* load dynamic section and dynamic symbols */
2448 dynsym
= NULL
; /* avoid warning */
2449 dynstr
= NULL
; /* avoid warning */
2450 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2451 switch(sh
->sh_type
) {
2453 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2454 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2457 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2458 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2459 sh1
= &shdr
[sh
->sh_link
];
2460 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2467 /* compute the real library name */
2468 soname
= tcc_basename(filename
);
2470 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2471 if (dt
->d_tag
== DT_SONAME
) {
2472 soname
= dynstr
+ dt
->d_un
.d_val
;
2476 /* if the dll is already loaded, do not load it */
2477 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2478 dllref
= s1
->loaded_dlls
[i
];
2479 if (!strcmp(soname
, dllref
->name
)) {
2480 /* but update level if needed */
2481 if (level
< dllref
->level
)
2482 dllref
->level
= level
;
2488 // printf("loading dll '%s'\n", soname);
2490 /* add the dll and its level */
2491 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2492 dllref
->level
= level
;
2493 strcpy(dllref
->name
, soname
);
2494 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2496 /* add dynamic symbols in dynsym_section */
2497 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2498 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2499 if (sym_bind
== STB_LOCAL
)
2501 name
= dynstr
+ sym
->st_name
;
2502 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2503 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2506 /* load all referenced DLLs */
2507 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2510 name
= dynstr
+ dt
->d_un
.d_val
;
2511 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2512 dllref
= s1
->loaded_dlls
[j
];
2513 if (!strcmp(name
, dllref
->name
))
2514 goto already_loaded
;
2516 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2517 error_noabort("referenced dll '%s' not found", name
);
2534 #define LD_TOK_NAME 256
2535 #define LD_TOK_EOF (-1)
2537 /* return next ld script token */
2538 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2556 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2557 ch
= file
->buf_ptr
[0];
2565 /* case 'a' ... 'z': */
2592 /* case 'A' ... 'z': */
2627 if (!((ch
>= 'a' && ch
<= 'z') ||
2628 (ch
>= 'A' && ch
<= 'Z') ||
2629 (ch
>= '0' && ch
<= '9') ||
2630 strchr("/.-_+=$:\\,~", ch
)))
2632 if ((q
- name
) < name_size
- 1) {
2649 printf("tok=%c %d\n", c
, c
);
2650 if (c
== LD_TOK_NAME
)
2651 printf(" name=%s\n", name
);
2656 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2658 char filename
[1024];
2661 t
= ld_next(s1
, filename
, sizeof(filename
));
2664 t
= ld_next(s1
, filename
, sizeof(filename
));
2666 if (t
== LD_TOK_EOF
) {
2667 error_noabort("unexpected end of file");
2669 } else if (t
== ')') {
2671 } else if (t
!= LD_TOK_NAME
) {
2672 error_noabort("filename expected");
2675 if (!strcmp(filename
, "AS_NEEDED")) {
2676 ret
= ld_add_file_list(s1
, 1);
2680 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2682 tcc_add_file(s1
, filename
);
2684 t
= ld_next(s1
, filename
, sizeof(filename
));
2686 t
= ld_next(s1
, filename
, sizeof(filename
));
2692 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2694 static int tcc_load_ldscript(TCCState
*s1
)
2697 char filename
[1024];
2700 ch
= file
->buf_ptr
[0];
2703 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2704 if (t
== LD_TOK_EOF
)
2706 else if (t
!= LD_TOK_NAME
)
2708 if (!strcmp(cmd
, "INPUT") ||
2709 !strcmp(cmd
, "GROUP")) {
2710 ret
= ld_add_file_list(s1
, 0);
2713 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2714 !strcmp(cmd
, "TARGET")) {
2715 /* ignore some commands */
2716 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2720 t
= ld_next(s1
, filename
, sizeof(filename
));
2721 if (t
== LD_TOK_EOF
) {
2722 error_noabort("unexpected end of file");
2724 } else if (t
== ')') {