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*)(uplong
)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
, uplong 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
;
436 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
437 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
440 sh_num
= sym
->st_shndx
;
441 if (sh_num
== SHN_UNDEF
) {
442 name
= strtab_section
->data
+ sym
->st_name
;
446 name
= symtab_section
->link
->data
+ sym
->st_name
;
447 addr
= resolve_sym(s1
, name
);
449 sym
->st_value
= (uplong
)addr
;
453 } else if (s1
->dynsym
) {
454 /* if dynamic symbol exist, then use it */
455 sym_index
= find_elf_sym(s1
->dynsym
, name
);
457 esym
= &((ElfW(Sym
) *)s1
->dynsym
->data
)[sym_index
];
458 sym
->st_value
= esym
->st_value
;
462 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
464 if (!strcmp(name
, "_fp_hw"))
466 /* only weak symbols are accepted to be undefined. Their
468 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
469 if (sym_bind
== STB_WEAK
) {
472 error_noabort("undefined symbol '%s'", name
);
474 } else if (sh_num
< SHN_LORESERVE
) {
475 /* add section base */
476 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
482 #ifndef TCC_TARGET_PE
483 #ifdef TCC_TARGET_X86_64
484 #define JMP_TABLE_ENTRY_SIZE 14
485 static unsigned long add_jmp_table(TCCState
*s1
, unsigned long val
)
487 char *p
= s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
;
488 s1
->runtime_plt_and_got_offset
+= JMP_TABLE_ENTRY_SIZE
;
493 *(unsigned long *)(p
+ 6) = val
;
494 return (unsigned long)p
;
497 static unsigned long add_got_table(TCCState
*s1
, unsigned long val
)
499 unsigned long *p
=(unsigned long *)(s1
->runtime_plt_and_got
+
500 s1
->runtime_plt_and_got_offset
);
501 s1
->runtime_plt_and_got_offset
+= sizeof(void *);
503 return (unsigned long)p
;
508 /* relocate a given section (CPU dependent) */
509 static void relocate_section(TCCState
*s1
, Section
*s
)
512 ElfW_Rel
*rel
, *rel_end
, *qrel
;
516 unsigned long val
, addr
;
517 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
522 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
523 qrel
= (ElfW_Rel
*)sr
->data
;
527 ptr
= s
->data
+ rel
->r_offset
;
529 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
530 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
532 #ifdef TCC_TARGET_X86_64
533 /* XXX: not tested */
534 val
+= rel
->r_addend
;
536 type
= ELFW(R_TYPE
)(rel
->r_info
);
537 addr
= s
->sh_addr
+ rel
->r_offset
;
541 #if defined(TCC_TARGET_I386)
543 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
544 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
545 qrel
->r_offset
= rel
->r_offset
;
547 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_32
);
551 qrel
->r_info
= ELFW(R_INFO
)(0, R_386_RELATIVE
);
558 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
560 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
562 qrel
->r_offset
= rel
->r_offset
;
563 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_PC32
);
568 *(int *)ptr
+= val
- addr
;
571 *(int *)ptr
+= val
- addr
;
578 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
581 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
584 /* we load the got offset */
585 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
587 #elif defined(TCC_TARGET_ARM)
594 x
= (*(int *)ptr
)&0xffffff;
595 (*(int *)ptr
) &= 0xff000000;
600 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
601 error("can't relocate value at %x",addr
);
610 x
= (*(int *)ptr
) & 0x7fffffff;
611 (*(int *)ptr
) &= 0x80000000;
614 if((x
^(x
>>1))&0x40000000)
615 error("can't relocate value at %x",addr
);
616 (*(int *)ptr
) |= x
& 0x7fffffff;
621 case R_ARM_BASE_PREL
:
622 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
625 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
628 /* we load the got offset */
629 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
634 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
635 type
,addr
,(unsigned int )ptr
,val
);
637 #elif defined(TCC_TARGET_C67)
645 /* put the low 16 bits of the absolute address */
646 // add to what is already there
648 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
649 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
651 //patch both at once - assumes always in pairs Low - High
653 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
654 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
660 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
661 type
,addr
,(unsigned int )ptr
,val
);
663 #elif defined(TCC_TARGET_X86_64)
665 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
666 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
667 qrel
->r_addend
= *(long long *)ptr
+ val
;
670 *(long long *)ptr
+= val
;
674 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
675 /* XXX: this logic may depend on TCC's codegen
676 now TCC uses R_X86_64_32 even for a 64bit pointer */
677 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
678 qrel
->r_addend
= *(int *)ptr
+ val
;
683 case R_X86_64_PC32
: {
685 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
687 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
689 qrel
->r_offset
= rel
->r_offset
;
690 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_X86_64_PC32
);
691 qrel
->r_addend
= *(int *)ptr
;
696 diff
= (long long)val
- addr
;
697 if (diff
<= -2147483647 || diff
> 2147483647) {
698 #ifndef TCC_TARGET_PE
699 /* XXX: naive support for over 32bit jump */
700 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
701 val
= add_jmp_table(s1
, val
);
705 if (diff
<= -2147483647 || diff
> 2147483647) {
706 error("internal error: relocation failed");
713 *(int *)ptr
+= val
- addr
;
715 case R_X86_64_GLOB_DAT
:
716 case R_X86_64_JUMP_SLOT
:
719 case R_X86_64_GOTPCREL
:
720 #ifndef TCC_TARGET_PE
721 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
722 val
= add_got_table(s1
, val
- rel
->r_addend
) + rel
->r_addend
;
723 *(int *)ptr
+= val
- addr
;
727 *(int *)ptr
+= (s1
->got
->sh_addr
- addr
+
728 s1
->got_offsets
[sym_index
] - 4);
730 case R_X86_64_GOTTPOFF
:
731 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
734 /* we load the got offset */
735 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
738 #error unsupported processor
742 /* if the relocation is allocated, we change its symbol table */
743 if (sr
->sh_flags
& SHF_ALLOC
)
744 sr
->link
= s1
->dynsym
;
747 /* relocate relocation table in 'sr' */
748 static void relocate_rel(TCCState
*s1
, Section
*sr
)
751 ElfW_Rel
*rel
, *rel_end
;
753 s
= s1
->sections
[sr
->sh_info
];
754 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
755 for(rel
= (ElfW_Rel
*)sr
->data
;
758 rel
->r_offset
+= s
->sh_addr
;
762 /* count the number of dynamic relocations so that we can reserve
764 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
766 ElfW_Rel
*rel
, *rel_end
;
767 int sym_index
, esym_index
, type
, count
;
770 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
771 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
772 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
773 type
= ELFW(R_TYPE
)(rel
->r_info
);
775 #if defined(TCC_TARGET_I386)
777 #elif defined(TCC_TARGET_X86_64)
784 #if defined(TCC_TARGET_I386)
786 #elif defined(TCC_TARGET_X86_64)
789 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
798 /* allocate the section */
799 sr
->sh_flags
|= SHF_ALLOC
;
800 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
805 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
810 if (index
>= s1
->nb_got_offsets
) {
811 /* find immediately bigger power of 2 and reallocate array */
815 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
817 error("memory full");
818 s1
->got_offsets
= tab
;
819 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
820 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
821 s1
->nb_got_offsets
= n
;
823 s1
->got_offsets
[index
] = val
;
826 /* XXX: suppress that */
827 static void put32(unsigned char *p
, uint32_t val
)
835 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
836 defined(TCC_TARGET_X86_64)
837 static uint32_t get32(unsigned char *p
)
839 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
843 static void build_got(TCCState
*s1
)
847 /* if no got, then create it */
848 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
849 s1
->got
->sh_entsize
= 4;
850 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
851 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
852 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
854 /* keep space for _DYNAMIC pointer, if present */
856 /* two dummy got entries */
860 /* keep space for _DYNAMIC pointer, if present */
863 /* two dummy got entries */
871 /* put a got entry corresponding to a symbol in symtab_section. 'size'
872 and 'info' can be modifed if more precise info comes from the DLL */
873 static void put_got_entry(TCCState
*s1
,
874 int reloc_type
, unsigned long size
, int info
,
880 unsigned long offset
;
886 /* if a got entry already exists for that symbol, no need to add one */
887 if (sym_index
< s1
->nb_got_offsets
&&
888 s1
->got_offsets
[sym_index
] != 0)
891 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
894 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
895 name
= symtab_section
->link
->data
+ sym
->st_name
;
896 offset
= sym
->st_value
;
897 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
899 #ifdef TCC_TARGET_X86_64
909 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
912 /* if we build a DLL, we add a %ebx offset */
913 if (s1
->output_type
== TCC_OUTPUT_DLL
)
919 /* add a PLT entry */
921 if (plt
->data_offset
== 0) {
922 /* first plt entry */
923 p
= section_ptr_add(plt
, 16);
924 p
[0] = 0xff; /* pushl got + PTR_SIZE */
926 put32(p
+ 2, PTR_SIZE
);
927 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
929 put32(p
+ 8, PTR_SIZE
* 2);
932 p
= section_ptr_add(plt
, 16);
933 p
[0] = 0xff; /* jmp *(got + x) */
935 put32(p
+ 2, s1
->got
->data_offset
);
936 p
[6] = 0x68; /* push $xxx */
937 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
938 p
[11] = 0xe9; /* jmp plt_start */
939 put32(p
+ 12, -(plt
->data_offset
));
941 /* the symbol is modified so that it will be relocated to
943 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
944 if (s1
->output_type
== TCC_OUTPUT_EXE
)
946 offset
= plt
->data_offset
- 16;
948 #elif defined(TCC_TARGET_ARM)
949 if (reloc_type
== R_ARM_JUMP_SLOT
) {
953 /* if we build a DLL, we add a %ebx offset */
954 if (s1
->output_type
== TCC_OUTPUT_DLL
)
955 error("DLLs unimplemented!");
957 /* add a PLT entry */
959 if (plt
->data_offset
== 0) {
960 /* first plt entry */
961 p
= section_ptr_add(plt
, 16);
962 put32(p
, 0xe52de004);
963 put32(p
+ 4, 0xe59fe010);
964 put32(p
+ 8, 0xe08fe00e);
965 put32(p
+ 12, 0xe5bef008);
968 p
= section_ptr_add(plt
, 16);
969 put32(p
, 0xe59fc004);
970 put32(p
+4, 0xe08fc00c);
971 put32(p
+8, 0xe59cf000);
972 put32(p
+12, s1
->got
->data_offset
);
974 /* the symbol is modified so that it will be relocated to
976 if (s1
->output_type
== TCC_OUTPUT_EXE
)
977 offset
= plt
->data_offset
- 16;
979 #elif defined(TCC_TARGET_C67)
980 error("C67 got not implemented");
982 #error unsupported CPU
984 index
= put_elf_sym(s1
->dynsym
, offset
,
985 size
, info
, 0, sym
->st_shndx
, name
);
986 /* put a got entry */
987 put_elf_reloc(s1
->dynsym
, s1
->got
,
988 s1
->got
->data_offset
,
991 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
995 /* build GOT and PLT entries */
996 static void build_got_entries(TCCState
*s1
)
999 ElfW_Rel
*rel
, *rel_end
;
1001 int i
, type
, reloc_type
, sym_index
;
1003 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1004 s
= s1
->sections
[i
];
1005 if (s
->sh_type
!= SHT_RELX
)
1007 /* no need to handle got relocations */
1008 if (s
->link
!= symtab_section
)
1011 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
1012 for(rel
= (ElfW_Rel
*)s
->data
;
1015 type
= ELFW(R_TYPE
)(rel
->r_info
);
1017 #if defined(TCC_TARGET_I386)
1024 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1025 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1026 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1027 /* look at the symbol got offset. If none, then add one */
1028 if (type
== R_386_GOT32
)
1029 reloc_type
= R_386_GLOB_DAT
;
1031 reloc_type
= R_386_JMP_SLOT
;
1032 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1036 #elif defined(TCC_TARGET_ARM)
1037 case R_ARM_GOT_BREL
:
1038 case R_ARM_GOTOFF32
:
1039 case R_ARM_BASE_PREL
:
1043 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1044 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1045 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1046 /* look at the symbol got offset. If none, then add one */
1047 if (type
== R_ARM_GOT_BREL
)
1048 reloc_type
= R_ARM_GLOB_DAT
;
1050 reloc_type
= R_ARM_JUMP_SLOT
;
1051 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1055 #elif defined(TCC_TARGET_C67)
1062 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1063 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1064 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1065 /* look at the symbol got offset. If none, then add one */
1066 if (type
== R_C60_GOT32
)
1067 reloc_type
= R_C60_GLOB_DAT
;
1069 reloc_type
= R_C60_JMP_SLOT
;
1070 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1074 #elif defined(TCC_TARGET_X86_64)
1075 case R_X86_64_GOT32
:
1076 case R_X86_64_GOTTPOFF
:
1077 case R_X86_64_GOTPCREL
:
1078 case R_X86_64_PLT32
:
1081 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
||
1082 type
== R_X86_64_PLT32
) {
1083 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1084 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1085 /* look at the symbol got offset. If none, then add one */
1086 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
)
1087 reloc_type
= R_X86_64_GLOB_DAT
;
1089 reloc_type
= R_X86_64_JUMP_SLOT
;
1090 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1095 #error unsupported CPU
1104 static Section
*new_symtab(TCCState
*s1
,
1105 const char *symtab_name
, int sh_type
, int sh_flags
,
1106 const char *strtab_name
,
1107 const char *hash_name
, int hash_sh_flags
)
1109 Section
*symtab
, *strtab
, *hash
;
1110 int *ptr
, nb_buckets
;
1112 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1113 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1114 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1115 put_elf_str(strtab
, "");
1116 symtab
->link
= strtab
;
1117 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1121 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1122 hash
->sh_entsize
= sizeof(int);
1123 symtab
->hash
= hash
;
1124 hash
->link
= symtab
;
1126 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1127 ptr
[0] = nb_buckets
;
1129 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1133 /* put dynamic tag */
1134 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1137 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1139 dyn
->d_un
.d_val
= val
;
1142 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1146 char sym_start
[1024];
1149 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1150 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1152 s
= find_section(s1
, section_name
);
1157 end_offset
= s
->data_offset
;
1160 add_elf_sym(symtab_section
,
1162 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1163 s
->sh_num
, sym_start
);
1164 add_elf_sym(symtab_section
,
1166 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1167 s
->sh_num
, sym_end
);
1170 /* add tcc runtime libraries */
1171 static void tcc_add_runtime(TCCState
*s1
)
1173 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1177 #ifdef CONFIG_TCC_BCHECK
1178 if (s1
->do_bounds_check
) {
1180 Section
*init_section
;
1181 unsigned char *pinit
;
1184 /* XXX: add an object file to do that */
1185 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1187 add_elf_sym(symtab_section
, 0, 0,
1188 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1189 bounds_section
->sh_num
, "__bounds_start");
1190 /* add bound check code */
1191 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "bcheck.o");
1192 tcc_add_file(s1
, buf
);
1193 #ifdef TCC_TARGET_I386
1194 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1195 /* add 'call __bound_init()' in .init section */
1196 init_section
= find_section(s1
, ".init");
1197 pinit
= section_ptr_add(init_section
, 5);
1199 put32(pinit
+ 1, -4);
1200 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1201 put_elf_reloc(symtab_section
, init_section
,
1202 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1208 if (!s1
->nostdlib
) {
1209 tcc_add_library(s1
, "c");
1211 #ifdef CONFIG_USE_LIBGCC
1212 tcc_add_file(s1
, CONFIG_SYSROOT
"/lib/libgcc_s.so.1");
1214 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "libtcc1.a");
1215 tcc_add_file(s1
, buf
);
1218 /* add crt end if not memory output */
1219 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1220 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1224 /* add various standard linker symbols (must be done after the
1225 sections are filled (for example after allocating common
1227 static void tcc_add_linker_symbols(TCCState
*s1
)
1233 add_elf_sym(symtab_section
,
1234 text_section
->data_offset
, 0,
1235 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1236 text_section
->sh_num
, "_etext");
1237 add_elf_sym(symtab_section
,
1238 data_section
->data_offset
, 0,
1239 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1240 data_section
->sh_num
, "_edata");
1241 add_elf_sym(symtab_section
,
1242 bss_section
->data_offset
, 0,
1243 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1244 bss_section
->sh_num
, "_end");
1245 /* horrible new standard ldscript defines */
1246 add_init_array_defines(s1
, ".preinit_array");
1247 add_init_array_defines(s1
, ".init_array");
1248 add_init_array_defines(s1
, ".fini_array");
1250 /* add start and stop symbols for sections whose name can be
1252 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1253 s
= s1
->sections
[i
];
1254 if (s
->sh_type
== SHT_PROGBITS
&&
1255 (s
->sh_flags
& SHF_ALLOC
)) {
1259 /* check if section name can be expressed in C */
1265 if (!isid(ch
) && !isnum(ch
))
1269 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1270 add_elf_sym(symtab_section
,
1272 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1274 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1275 add_elf_sym(symtab_section
,
1277 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1284 /* name of ELF interpreter */
1285 #if defined __FreeBSD__
1286 static char elf_interp
[] = "/usr/libexec/ld-elf.so.1";
1287 #elif defined TCC_ARM_EABI
1288 static char elf_interp
[] = "/lib/ld-linux.so.3";
1289 #elif defined(TCC_TARGET_X86_64)
1290 static char elf_interp
[] = "/lib/ld-linux-x86-64.so.2";
1291 #elif defined(TCC_UCLIBC)
1292 static char elf_interp
[] = "/lib/ld-uClibc.so.0";
1294 static char elf_interp
[] = "/lib/ld-linux.so.2";
1297 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1298 const int *section_order
)
1301 int i
, offset
, size
;
1304 for(i
=1;i
<s1
->nb_sections
;i
++) {
1305 s
= s1
->sections
[section_order
[i
]];
1306 if (s
->sh_type
!= SHT_NOBITS
&&
1307 (s
->sh_flags
& SHF_ALLOC
)) {
1308 while (offset
< s
->sh_offset
) {
1313 fwrite(s
->data
, 1, size
, f
);
1319 /* output an ELF file */
1320 /* XXX: suppress unneeded sections */
1321 int elf_output_file(TCCState
*s1
, const char *filename
)
1327 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1329 Section
*strsec
, *s
;
1330 ElfW(Shdr
) shdr
, *sh
;
1331 ElfW(Phdr
) *phdr
, *ph
;
1332 Section
*interp
, *dynamic
, *dynstr
;
1333 unsigned long saved_dynamic_data_offset
;
1335 int type
, file_type
;
1336 unsigned long rel_addr
, rel_size
;
1338 file_type
= s1
->output_type
;
1341 if (file_type
!= TCC_OUTPUT_OBJ
) {
1342 tcc_add_runtime(s1
);
1346 section_order
= NULL
;
1349 dynstr
= NULL
; /* avoid warning */
1350 saved_dynamic_data_offset
= 0; /* avoid warning */
1352 if (file_type
!= TCC_OUTPUT_OBJ
) {
1353 relocate_common_syms();
1355 tcc_add_linker_symbols(s1
);
1357 if (!s1
->static_link
) {
1359 int sym_index
, index
;
1360 ElfW(Sym
) *esym
, *sym_end
;
1362 if (file_type
== TCC_OUTPUT_EXE
) {
1364 /* add interpreter section only if executable */
1365 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1366 interp
->sh_addralign
= 1;
1367 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
1368 strcpy(ptr
, elf_interp
);
1371 /* add dynamic symbol table */
1372 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1374 ".hash", SHF_ALLOC
);
1375 dynstr
= s1
->dynsym
->link
;
1377 /* add dynamic section */
1378 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1379 SHF_ALLOC
| SHF_WRITE
);
1380 dynamic
->link
= dynstr
;
1381 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1384 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1385 SHF_ALLOC
| SHF_EXECINSTR
);
1386 s1
->plt
->sh_entsize
= 4;
1390 /* scan for undefined symbols and see if they are in the
1391 dynamic symbols. If a symbol STT_FUNC is found, then we
1392 add it in the PLT. If a symbol STT_OBJECT is found, we
1393 add it in the .bss section with a suitable relocation */
1394 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1395 symtab_section
->data_offset
);
1396 if (file_type
== TCC_OUTPUT_EXE
) {
1397 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1400 if (sym
->st_shndx
== SHN_UNDEF
) {
1401 name
= symtab_section
->link
->data
+ sym
->st_name
;
1402 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1404 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1405 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1406 if (type
== STT_FUNC
) {
1407 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1409 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1410 } else if (type
== STT_OBJECT
) {
1411 unsigned long offset
;
1412 offset
= bss_section
->data_offset
;
1413 /* XXX: which alignment ? */
1414 offset
= (offset
+ 16 - 1) & -16;
1415 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1417 bss_section
->sh_num
, name
);
1418 put_elf_reloc(s1
->dynsym
, bss_section
,
1419 offset
, R_COPY
, index
);
1420 offset
+= esym
->st_size
;
1421 bss_section
->data_offset
= offset
;
1424 /* STB_WEAK undefined symbols are accepted */
1425 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1427 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1428 !strcmp(name
, "_fp_hw")) {
1430 error_noabort("undefined symbol '%s'", name
);
1433 } else if (s1
->rdynamic
&&
1434 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1435 /* if -rdynamic option, then export all non
1437 name
= symtab_section
->link
->data
+ sym
->st_name
;
1438 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1440 sym
->st_shndx
, name
);
1447 /* now look at unresolved dynamic symbols and export
1448 corresponding symbol */
1449 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1450 s1
->dynsymtab_section
->data_offset
);
1451 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1454 if (esym
->st_shndx
== SHN_UNDEF
) {
1455 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1456 sym_index
= find_elf_sym(symtab_section
, name
);
1458 /* XXX: avoid adding a symbol if already
1459 present because of -rdynamic ? */
1460 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1461 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1463 sym
->st_shndx
, name
);
1465 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1466 /* weak symbols can stay undefined */
1468 warning("undefined dynamic symbol '%s'", name
);
1475 /* shared library case : we simply export all the global symbols */
1476 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1477 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1478 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1481 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1482 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1483 if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
&&
1484 sym
->st_shndx
== SHN_UNDEF
) {
1485 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1487 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1489 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1490 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1492 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1497 name
= symtab_section
->link
->data
+ sym
->st_name
;
1498 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1500 sym
->st_shndx
, name
);
1501 s1
->symtab_to_dynsym
[sym
-
1502 (ElfW(Sym
) *)symtab_section
->data
] =
1509 build_got_entries(s1
);
1511 /* add a list of needed dlls */
1512 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1513 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1514 if (dllref
->level
== 0)
1515 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1517 /* XXX: currently, since we do not handle PIC code, we
1518 must relocate the readonly segments */
1519 if (file_type
== TCC_OUTPUT_DLL
) {
1521 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1522 put_dt(dynamic
, DT_TEXTREL
, 0);
1525 /* add necessary space for other entries */
1526 saved_dynamic_data_offset
= dynamic
->data_offset
;
1527 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * 9;
1529 /* still need to build got entries in case of static link */
1530 build_got_entries(s1
);
1534 memset(&ehdr
, 0, sizeof(ehdr
));
1536 /* we add a section for symbols */
1537 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1538 put_elf_str(strsec
, "");
1540 /* compute number of sections */
1541 shnum
= s1
->nb_sections
;
1543 /* this array is used to reorder sections in the output file */
1544 section_order
= tcc_malloc(sizeof(int) * shnum
);
1545 section_order
[0] = 0;
1548 /* compute number of program headers */
1551 case TCC_OUTPUT_OBJ
:
1554 case TCC_OUTPUT_EXE
:
1555 if (!s1
->static_link
)
1560 case TCC_OUTPUT_DLL
:
1565 /* allocate strings for section names and decide if an unallocated
1566 section should be output */
1567 /* NOTE: the strsec section comes last, so its size is also
1569 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1570 s
= s1
->sections
[i
];
1571 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1573 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1578 s
->reloc
? s
->reloc
->name
: "n"
1581 /* when generating a DLL, we include relocations but we may
1583 if (file_type
== TCC_OUTPUT_DLL
&&
1584 s
->sh_type
== SHT_RELX
&&
1585 !(s
->sh_flags
& SHF_ALLOC
)) {
1586 /* //gr: avoid bogus relocs for empty (debug) sections */
1587 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1588 prepare_dynamic_rel(s1
, s
);
1589 else if (s1
->do_debug
)
1590 s
->sh_size
= s
->data_offset
;
1591 } else if (s1
->do_debug
||
1592 file_type
== TCC_OUTPUT_OBJ
||
1593 (s
->sh_flags
& SHF_ALLOC
) ||
1594 i
== (s1
->nb_sections
- 1)) {
1595 /* we output all sections if debug or object file */
1596 s
->sh_size
= s
->data_offset
;
1600 /* allocate program segment headers */
1601 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1603 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1604 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1609 /* compute section to program header mapping */
1610 if (s1
->has_text_addr
) {
1611 int a_offset
, p_offset
;
1612 addr
= s1
->text_addr
;
1613 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1615 a_offset
= addr
& (ELF_PAGE_SIZE
- 1);
1616 p_offset
= file_offset
& (ELF_PAGE_SIZE
- 1);
1617 if (a_offset
< p_offset
)
1618 a_offset
+= ELF_PAGE_SIZE
;
1619 file_offset
+= (a_offset
- p_offset
);
1621 if (file_type
== TCC_OUTPUT_DLL
)
1624 addr
= ELF_START_ADDR
;
1625 /* compute address after headers */
1626 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1629 /* dynamic relocation table information, for .dynamic section */
1633 /* leave one program header for the program interpreter */
1638 for(j
= 0; j
< 2; j
++) {
1639 ph
->p_type
= PT_LOAD
;
1641 ph
->p_flags
= PF_R
| PF_X
;
1643 ph
->p_flags
= PF_R
| PF_W
;
1644 ph
->p_align
= ELF_PAGE_SIZE
;
1646 /* we do the following ordering: interp, symbol tables,
1647 relocations, progbits, nobits */
1648 /* XXX: do faster and simpler sorting */
1649 for(k
= 0; k
< 5; k
++) {
1650 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1651 s
= s1
->sections
[i
];
1652 /* compute if section should be included */
1654 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1658 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1659 (SHF_ALLOC
| SHF_WRITE
))
1665 } else if (s
->sh_type
== SHT_DYNSYM
||
1666 s
->sh_type
== SHT_STRTAB
||
1667 s
->sh_type
== SHT_HASH
) {
1670 } else if (s
->sh_type
== SHT_RELX
) {
1673 } else if (s
->sh_type
== SHT_NOBITS
) {
1680 section_order
[sh_order_index
++] = i
;
1682 /* section matches: we align it and add its size */
1684 addr
= (addr
+ s
->sh_addralign
- 1) &
1685 ~(s
->sh_addralign
- 1);
1686 file_offset
+= addr
- tmp
;
1687 s
->sh_offset
= file_offset
;
1690 /* update program header infos */
1691 if (ph
->p_offset
== 0) {
1692 ph
->p_offset
= file_offset
;
1694 ph
->p_paddr
= ph
->p_vaddr
;
1696 /* update dynamic relocation infos */
1697 if (s
->sh_type
== SHT_RELX
) {
1700 rel_size
+= s
->sh_size
;
1703 if (s
->sh_type
!= SHT_NOBITS
)
1704 file_offset
+= s
->sh_size
;
1707 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1708 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1711 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1712 /* if in the middle of a page, we duplicate the page in
1713 memory so that one copy is RX and the other is RW */
1714 if ((addr
& (ELF_PAGE_SIZE
- 1)) != 0)
1715 addr
+= ELF_PAGE_SIZE
;
1717 addr
= (addr
+ ELF_PAGE_SIZE
- 1) & ~(ELF_PAGE_SIZE
- 1);
1718 file_offset
= (file_offset
+ ELF_PAGE_SIZE
- 1) &
1719 ~(ELF_PAGE_SIZE
- 1);
1724 /* if interpreter, then add corresponing program header */
1728 ph
->p_type
= PT_INTERP
;
1729 ph
->p_offset
= interp
->sh_offset
;
1730 ph
->p_vaddr
= interp
->sh_addr
;
1731 ph
->p_paddr
= ph
->p_vaddr
;
1732 ph
->p_filesz
= interp
->sh_size
;
1733 ph
->p_memsz
= interp
->sh_size
;
1735 ph
->p_align
= interp
->sh_addralign
;
1738 /* if dynamic section, then add corresponing program header */
1742 ph
= &phdr
[phnum
- 1];
1744 ph
->p_type
= PT_DYNAMIC
;
1745 ph
->p_offset
= dynamic
->sh_offset
;
1746 ph
->p_vaddr
= dynamic
->sh_addr
;
1747 ph
->p_paddr
= ph
->p_vaddr
;
1748 ph
->p_filesz
= dynamic
->sh_size
;
1749 ph
->p_memsz
= dynamic
->sh_size
;
1750 ph
->p_flags
= PF_R
| PF_W
;
1751 ph
->p_align
= dynamic
->sh_addralign
;
1753 /* put GOT dynamic section address */
1754 put32(s1
->got
->data
, dynamic
->sh_addr
);
1756 /* relocate the PLT */
1757 if (file_type
== TCC_OUTPUT_EXE
1758 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1759 || file_type
== TCC_OUTPUT_DLL
1765 p_end
= p
+ s1
->plt
->data_offset
;
1767 #if defined(TCC_TARGET_I386)
1768 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1769 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1772 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1775 #elif defined(TCC_TARGET_X86_64)
1776 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1777 put32(p
+ 2, get32(p
+ 2) + x
);
1778 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1781 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1784 #elif defined(TCC_TARGET_ARM)
1786 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1789 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1792 #elif defined(TCC_TARGET_C67)
1795 #error unsupported CPU
1800 /* relocate symbols in .dynsym */
1801 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1802 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1805 if (sym
->st_shndx
== SHN_UNDEF
) {
1806 /* relocate to the PLT if the symbol corresponds
1809 sym
->st_value
+= s1
->plt
->sh_addr
;
1810 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1811 /* do symbol relocation */
1812 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1816 /* put dynamic section entries */
1817 dynamic
->data_offset
= saved_dynamic_data_offset
;
1818 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1819 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1820 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1821 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1822 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1823 #ifdef TCC_TARGET_X86_64
1824 put_dt(dynamic
, DT_RELA
, rel_addr
);
1825 put_dt(dynamic
, DT_RELASZ
, rel_size
);
1826 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1828 put_dt(dynamic
, DT_REL
, rel_addr
);
1829 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1830 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1833 put_dt(dynamic
, DT_DEBUG
, 0);
1834 put_dt(dynamic
, DT_NULL
, 0);
1837 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1838 ehdr
.e_phnum
= phnum
;
1839 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1842 /* all other sections come after */
1843 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1844 s
= s1
->sections
[i
];
1845 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1847 section_order
[sh_order_index
++] = i
;
1849 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1850 ~(s
->sh_addralign
- 1);
1851 s
->sh_offset
= file_offset
;
1852 if (s
->sh_type
!= SHT_NOBITS
)
1853 file_offset
+= s
->sh_size
;
1856 /* if building executable or DLL, then relocate each section
1857 except the GOT which is already relocated */
1858 if (file_type
!= TCC_OUTPUT_OBJ
) {
1859 relocate_syms(s1
, 0);
1861 if (s1
->nb_errors
!= 0) {
1867 /* relocate sections */
1868 /* XXX: ignore sections with allocated relocations ? */
1869 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1870 s
= s1
->sections
[i
];
1871 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1872 relocate_section(s1
, s
);
1875 /* relocate relocation entries if the relocation tables are
1876 allocated in the executable */
1877 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1878 s
= s1
->sections
[i
];
1879 if ((s
->sh_flags
& SHF_ALLOC
) &&
1880 s
->sh_type
== SHT_RELX
) {
1881 relocate_rel(s1
, s
);
1885 /* get entry point address */
1886 if (file_type
== TCC_OUTPUT_EXE
)
1887 ehdr
.e_entry
= (uplong
)tcc_get_symbol_err(s1
, "_start");
1889 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1892 /* write elf file */
1893 if (file_type
== TCC_OUTPUT_OBJ
)
1897 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1899 error_noabort("could not write '%s'", filename
);
1902 f
= fdopen(fd
, "wb");
1904 printf("<- %s\n", filename
);
1906 #ifdef TCC_TARGET_COFF
1907 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1908 tcc_output_coff(s1
, f
);
1911 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1912 sort_syms(s1
, symtab_section
);
1915 file_offset
= (file_offset
+ 3) & -4;
1918 ehdr
.e_ident
[0] = ELFMAG0
;
1919 ehdr
.e_ident
[1] = ELFMAG1
;
1920 ehdr
.e_ident
[2] = ELFMAG2
;
1921 ehdr
.e_ident
[3] = ELFMAG3
;
1922 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
1923 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1924 ehdr
.e_ident
[6] = EV_CURRENT
;
1926 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1928 #ifdef TCC_TARGET_ARM
1930 ehdr
.e_ident
[EI_OSABI
] = 0;
1931 ehdr
.e_flags
= 4 << 24;
1933 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
1938 case TCC_OUTPUT_EXE
:
1939 ehdr
.e_type
= ET_EXEC
;
1941 case TCC_OUTPUT_DLL
:
1942 ehdr
.e_type
= ET_DYN
;
1944 case TCC_OUTPUT_OBJ
:
1945 ehdr
.e_type
= ET_REL
;
1948 ehdr
.e_machine
= EM_TCC_TARGET
;
1949 ehdr
.e_version
= EV_CURRENT
;
1950 ehdr
.e_shoff
= file_offset
;
1951 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
1952 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
1953 ehdr
.e_shnum
= shnum
;
1954 ehdr
.e_shstrndx
= shnum
- 1;
1956 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
1957 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
1958 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1960 for(i
=1;i
<s1
->nb_sections
;i
++) {
1961 s
= s1
->sections
[section_order
[i
]];
1962 if (s
->sh_type
!= SHT_NOBITS
) {
1963 while (offset
< s
->sh_offset
) {
1968 fwrite(s
->data
, 1, size
, f
);
1973 /* output section headers */
1974 while (offset
< ehdr
.e_shoff
) {
1979 for(i
=0;i
<s1
->nb_sections
;i
++) {
1981 memset(sh
, 0, sizeof(ElfW(Shdr
)));
1982 s
= s1
->sections
[i
];
1984 sh
->sh_name
= s
->sh_name
;
1985 sh
->sh_type
= s
->sh_type
;
1986 sh
->sh_flags
= s
->sh_flags
;
1987 sh
->sh_entsize
= s
->sh_entsize
;
1988 sh
->sh_info
= s
->sh_info
;
1990 sh
->sh_link
= s
->link
->sh_num
;
1991 sh
->sh_addralign
= s
->sh_addralign
;
1992 sh
->sh_addr
= s
->sh_addr
;
1993 sh
->sh_offset
= s
->sh_offset
;
1994 sh
->sh_size
= s
->sh_size
;
1996 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
1999 tcc_output_binary(s1
, f
, section_order
);
2005 tcc_free(s1
->symtab_to_dynsym
);
2006 tcc_free(section_order
);
2008 tcc_free(s1
->got_offsets
);
2012 int tcc_output_file(TCCState
*s
, const char *filename
)
2015 #ifdef TCC_TARGET_PE
2016 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2017 ret
= pe_output_file(s
, filename
);
2021 ret
= elf_output_file(s
, filename
);
2026 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2030 data
= tcc_malloc(size
);
2031 lseek(fd
, file_offset
, SEEK_SET
);
2032 read(fd
, data
, size
);
2036 typedef struct SectionMergeInfo
{
2037 Section
*s
; /* corresponding existing section */
2038 unsigned long offset
; /* offset of the new section in the existing section */
2039 uint8_t new_section
; /* true if section 's' was added */
2040 uint8_t link_once
; /* true if link once section */
2043 /* load an object file and merge it with current files */
2044 /* XXX: handle correctly stab (debug) info */
2045 static int tcc_load_object_file(TCCState
*s1
,
2046 int fd
, unsigned long file_offset
)
2049 ElfW(Shdr
) *shdr
, *sh
;
2050 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2051 unsigned char *strsec
, *strtab
;
2052 int *old_to_new_syms
;
2053 char *sh_name
, *name
;
2054 SectionMergeInfo
*sm_table
, *sm
;
2055 ElfW(Sym
) *sym
, *symtab
;
2056 ElfW_Rel
*rel
, *rel_end
;
2062 stab_index
= stabstr_index
= 0;
2064 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2066 if (ehdr
.e_ident
[0] != ELFMAG0
||
2067 ehdr
.e_ident
[1] != ELFMAG1
||
2068 ehdr
.e_ident
[2] != ELFMAG2
||
2069 ehdr
.e_ident
[3] != ELFMAG3
)
2071 /* test if object file */
2072 if (ehdr
.e_type
!= ET_REL
)
2074 /* test CPU specific stuff */
2075 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2076 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2078 error_noabort("invalid object file");
2082 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2083 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2084 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2086 /* load section names */
2087 sh
= &shdr
[ehdr
.e_shstrndx
];
2088 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2090 /* load symtab and strtab */
2091 old_to_new_syms
= NULL
;
2095 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2097 if (sh
->sh_type
== SHT_SYMTAB
) {
2099 error_noabort("object must contain only one symtab");
2104 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2105 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2106 sm_table
[i
].s
= symtab_section
;
2108 /* now load strtab */
2109 sh
= &shdr
[sh
->sh_link
];
2110 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2114 /* now examine each section and try to merge its content with the
2116 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2117 /* no need to examine section name strtab */
2118 if (i
== ehdr
.e_shstrndx
)
2121 sh_name
= strsec
+ sh
->sh_name
;
2122 /* ignore sections types we do not handle */
2123 if (sh
->sh_type
!= SHT_PROGBITS
&&
2124 sh
->sh_type
!= SHT_RELX
&&
2126 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2128 sh
->sh_type
!= SHT_NOBITS
&&
2129 strcmp(sh_name
, ".stabstr")
2132 if (sh
->sh_addralign
< 1)
2133 sh
->sh_addralign
= 1;
2134 /* find corresponding section, if any */
2135 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2136 s
= s1
->sections
[j
];
2137 if (!strcmp(s
->name
, sh_name
)) {
2138 if (!strncmp(sh_name
, ".gnu.linkonce",
2139 sizeof(".gnu.linkonce") - 1)) {
2140 /* if a 'linkonce' section is already present, we
2141 do not add it again. It is a little tricky as
2142 symbols can still be defined in
2144 sm_table
[i
].link_once
= 1;
2151 /* not found: create new section */
2152 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2153 /* take as much info as possible from the section. sh_link and
2154 sh_info will be updated later */
2155 s
->sh_addralign
= sh
->sh_addralign
;
2156 s
->sh_entsize
= sh
->sh_entsize
;
2157 sm_table
[i
].new_section
= 1;
2159 if (sh
->sh_type
!= s
->sh_type
) {
2160 error_noabort("invalid section type");
2164 /* align start of section */
2165 offset
= s
->data_offset
;
2167 if (0 == strcmp(sh_name
, ".stab")) {
2171 if (0 == strcmp(sh_name
, ".stabstr")) {
2176 size
= sh
->sh_addralign
- 1;
2177 offset
= (offset
+ size
) & ~size
;
2178 if (sh
->sh_addralign
> s
->sh_addralign
)
2179 s
->sh_addralign
= sh
->sh_addralign
;
2180 s
->data_offset
= offset
;
2182 sm_table
[i
].offset
= offset
;
2184 /* concatenate sections */
2186 if (sh
->sh_type
!= SHT_NOBITS
) {
2188 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2189 ptr
= section_ptr_add(s
, size
);
2190 read(fd
, ptr
, size
);
2192 s
->data_offset
+= size
;
2197 /* //gr relocate stab strings */
2198 if (stab_index
&& stabstr_index
) {
2201 s
= sm_table
[stab_index
].s
;
2202 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2203 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2204 o
= sm_table
[stabstr_index
].offset
;
2206 a
->n_strx
+= o
, a
++;
2209 /* second short pass to update sh_link and sh_info fields of new
2211 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2213 if (!s
|| !sm_table
[i
].new_section
)
2216 if (sh
->sh_link
> 0)
2217 s
->link
= sm_table
[sh
->sh_link
].s
;
2218 if (sh
->sh_type
== SHT_RELX
) {
2219 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2220 /* update backward link */
2221 s1
->sections
[s
->sh_info
]->reloc
= s
;
2226 /* resolve symbols */
2227 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2230 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2231 if (sym
->st_shndx
!= SHN_UNDEF
&&
2232 sym
->st_shndx
< SHN_LORESERVE
) {
2233 sm
= &sm_table
[sym
->st_shndx
];
2234 if (sm
->link_once
) {
2235 /* if a symbol is in a link once section, we use the
2236 already defined symbol. It is very important to get
2237 correct relocations */
2238 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2239 name
= strtab
+ sym
->st_name
;
2240 sym_index
= find_elf_sym(symtab_section
, name
);
2242 old_to_new_syms
[i
] = sym_index
;
2246 /* if no corresponding section added, no need to add symbol */
2249 /* convert section number */
2250 sym
->st_shndx
= sm
->s
->sh_num
;
2252 sym
->st_value
+= sm
->offset
;
2255 name
= strtab
+ sym
->st_name
;
2256 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2257 sym
->st_info
, sym
->st_other
,
2258 sym
->st_shndx
, name
);
2259 old_to_new_syms
[i
] = sym_index
;
2262 /* third pass to patch relocation entries */
2263 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2268 offset
= sm_table
[i
].offset
;
2269 switch(s
->sh_type
) {
2271 /* take relocation offset information */
2272 offseti
= sm_table
[sh
->sh_info
].offset
;
2273 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2274 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2279 /* convert symbol index */
2280 type
= ELFW(R_TYPE
)(rel
->r_info
);
2281 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2282 /* NOTE: only one symtab assumed */
2283 if (sym_index
>= nb_syms
)
2285 sym_index
= old_to_new_syms
[sym_index
];
2286 /* ignore link_once in rel section. */
2287 if (!sym_index
&& !sm
->link_once
) {
2289 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2290 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2293 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2294 /* offset the relocation offset */
2295 rel
->r_offset
+= offseti
;
2307 tcc_free(old_to_new_syms
);
2314 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2316 typedef struct ArchiveHeader
{
2317 char ar_name
[16]; /* name of this member */
2318 char ar_date
[12]; /* file mtime */
2319 char ar_uid
[6]; /* owner uid; printed as decimal */
2320 char ar_gid
[6]; /* owner gid; printed as decimal */
2321 char ar_mode
[8]; /* file mode, printed as octal */
2322 char ar_size
[10]; /* file size, printed as decimal */
2323 char ar_fmag
[2]; /* should contain ARFMAG */
2326 static int get_be32(const uint8_t *b
)
2328 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2331 /* load only the objects which resolve undefined symbols */
2332 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2334 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2336 const char *ar_names
, *p
;
2337 const uint8_t *ar_index
;
2340 data
= tcc_malloc(size
);
2341 if (read(fd
, data
, size
) != size
)
2343 nsyms
= get_be32(data
);
2344 ar_index
= data
+ 4;
2345 ar_names
= ar_index
+ nsyms
* 4;
2349 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2350 sym_index
= find_elf_sym(symtab_section
, p
);
2352 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2353 if(sym
->st_shndx
== SHN_UNDEF
) {
2354 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2356 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2359 lseek(fd
, off
, SEEK_SET
);
2360 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2375 /* load a '.a' file */
2376 static int tcc_load_archive(TCCState
*s1
, int fd
)
2383 unsigned long file_offset
;
2385 /* skip magic which was already checked */
2386 read(fd
, magic
, sizeof(magic
));
2389 len
= read(fd
, &hdr
, sizeof(hdr
));
2392 if (len
!= sizeof(hdr
)) {
2393 error_noabort("invalid archive");
2396 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2397 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2398 size
= strtol(ar_size
, NULL
, 0);
2399 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2400 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2401 if (ar_name
[i
] != ' ')
2404 ar_name
[i
+ 1] = '\0';
2405 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2406 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2408 size
= (size
+ 1) & ~1;
2409 if (!strcmp(ar_name
, "/")) {
2410 /* coff symbol table : we handle it */
2411 if(s1
->alacarte_link
)
2412 return tcc_load_alacarte(s1
, fd
, size
);
2413 } else if (!strcmp(ar_name
, "//") ||
2414 !strcmp(ar_name
, "__.SYMDEF") ||
2415 !strcmp(ar_name
, "__.SYMDEF/") ||
2416 !strcmp(ar_name
, "ARFILENAMES/")) {
2417 /* skip symbol table or archive names */
2419 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2422 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2427 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2428 is referenced by the user (so it should be added as DT_NEEDED in
2429 the generated ELF file) */
2430 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2433 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2434 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2435 ElfW(Sym
) *sym
, *dynsym
;
2436 ElfW(Dyn
) *dt
, *dynamic
;
2437 unsigned char *dynstr
;
2438 const char *name
, *soname
;
2439 DLLReference
*dllref
;
2441 read(fd
, &ehdr
, sizeof(ehdr
));
2443 /* test CPU specific stuff */
2444 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2445 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2446 error_noabort("bad architecture");
2451 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2453 /* load dynamic section and dynamic symbols */
2457 dynsym
= NULL
; /* avoid warning */
2458 dynstr
= NULL
; /* avoid warning */
2459 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2460 switch(sh
->sh_type
) {
2462 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2463 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2466 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2467 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2468 sh1
= &shdr
[sh
->sh_link
];
2469 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2476 /* compute the real library name */
2477 soname
= tcc_basename(filename
);
2479 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2480 if (dt
->d_tag
== DT_SONAME
) {
2481 soname
= dynstr
+ dt
->d_un
.d_val
;
2485 /* if the dll is already loaded, do not load it */
2486 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2487 dllref
= s1
->loaded_dlls
[i
];
2488 if (!strcmp(soname
, dllref
->name
)) {
2489 /* but update level if needed */
2490 if (level
< dllref
->level
)
2491 dllref
->level
= level
;
2497 // printf("loading dll '%s'\n", soname);
2499 /* add the dll and its level */
2500 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2501 dllref
->level
= level
;
2502 strcpy(dllref
->name
, soname
);
2503 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2505 /* add dynamic symbols in dynsym_section */
2506 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2507 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2508 if (sym_bind
== STB_LOCAL
)
2510 name
= dynstr
+ sym
->st_name
;
2511 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2512 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2515 /* load all referenced DLLs */
2516 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2519 name
= dynstr
+ dt
->d_un
.d_val
;
2520 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2521 dllref
= s1
->loaded_dlls
[j
];
2522 if (!strcmp(name
, dllref
->name
))
2523 goto already_loaded
;
2525 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2526 error_noabort("referenced dll '%s' not found", name
);
2543 #define LD_TOK_NAME 256
2544 #define LD_TOK_EOF (-1)
2546 /* return next ld script token */
2547 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2565 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2566 ch
= file
->buf_ptr
[0];
2574 /* case 'a' ... 'z': */
2601 /* case 'A' ... 'z': */
2636 if (!((ch
>= 'a' && ch
<= 'z') ||
2637 (ch
>= 'A' && ch
<= 'Z') ||
2638 (ch
>= '0' && ch
<= '9') ||
2639 strchr("/.-_+=$:\\,~", ch
)))
2641 if ((q
- name
) < name_size
- 1) {
2658 printf("tok=%c %d\n", c
, c
);
2659 if (c
== LD_TOK_NAME
)
2660 printf(" name=%s\n", name
);
2665 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2667 char filename
[1024];
2670 t
= ld_next(s1
, filename
, sizeof(filename
));
2673 t
= ld_next(s1
, filename
, sizeof(filename
));
2675 if (t
== LD_TOK_EOF
) {
2676 error_noabort("unexpected end of file");
2678 } else if (t
== ')') {
2680 } else if (t
!= LD_TOK_NAME
) {
2681 error_noabort("filename expected");
2684 if (!strcmp(filename
, "AS_NEEDED")) {
2685 ret
= ld_add_file_list(s1
, 1);
2689 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2691 tcc_add_file(s1
, filename
);
2693 t
= ld_next(s1
, filename
, sizeof(filename
));
2695 t
= ld_next(s1
, filename
, sizeof(filename
));
2701 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2703 static int tcc_load_ldscript(TCCState
*s1
)
2706 char filename
[1024];
2709 ch
= file
->buf_ptr
[0];
2712 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2713 if (t
== LD_TOK_EOF
)
2715 else if (t
!= LD_TOK_NAME
)
2717 if (!strcmp(cmd
, "INPUT") ||
2718 !strcmp(cmd
, "GROUP")) {
2719 ret
= ld_add_file_list(s1
, 0);
2722 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2723 !strcmp(cmd
, "TARGET")) {
2724 /* ignore some commands */
2725 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2729 t
= ld_next(s1
, filename
, sizeof(filename
));
2730 if (t
== LD_TOK_EOF
) {
2731 error_noabort("unexpected end of file");
2733 } else if (t
== ')') {