2 * ELF file handling for TCC
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #ifdef TCC_TARGET_X86_64
22 #define ElfW_Rel ElfW(Rela)
23 #define SHT_RELX SHT_RELA
24 #define REL_SECTION_FMT ".rela%s"
25 /* x86-64 requires PLT for DLLs */
26 #define TCC_OUTPUT_DLL_WITH_PLT
28 #define ElfW_Rel ElfW(Rel)
29 #define SHT_RELX SHT_REL
30 #define REL_SECTION_FMT ".rel%s"
33 /* XXX: DLL with PLT would only work with x86-64 for now */
34 //#define TCC_OUTPUT_DLL_WITH_PLT
36 static int put_elf_str(Section
*s
, const char *sym
)
41 len
= strlen(sym
) + 1;
42 offset
= s
->data_offset
;
43 ptr
= section_ptr_add(s
, len
);
44 memcpy(ptr
, sym
, len
);
48 /* elf symbol hashing function */
49 static unsigned long elf_hash(const unsigned char *name
)
51 unsigned long h
= 0, g
;
54 h
= (h
<< 4) + *name
++;
63 /* rebuild hash table of section s */
64 /* NOTE: we do factorize the hash table code to go faster */
65 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
68 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
71 strtab
= s
->link
->data
;
72 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
74 s
->hash
->data_offset
= 0;
75 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
80 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
81 ptr
+= nb_buckets
+ 1;
83 sym
= (ElfW(Sym
) *)s
->data
+ 1;
84 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
85 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
86 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
97 /* return the symbol number */
98 static int put_elf_sym(Section
*s
,
99 unsigned long value
, unsigned long size
,
100 int info
, int other
, int shndx
, const char *name
)
102 int name_offset
, sym_index
;
107 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
109 name_offset
= put_elf_str(s
->link
, name
);
112 /* XXX: endianness */
113 sym
->st_name
= name_offset
;
114 sym
->st_value
= value
;
117 sym
->st_other
= other
;
118 sym
->st_shndx
= shndx
;
119 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
123 ptr
= section_ptr_add(hs
, sizeof(int));
124 base
= (int *)hs
->data
;
125 /* only add global or weak symbols */
126 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
127 /* add another hashing entry */
129 h
= elf_hash(name
) % nbuckets
;
131 base
[2 + h
] = sym_index
;
133 /* we resize the hash table */
134 hs
->nb_hashed_syms
++;
135 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
136 rebuild_hash(s
, 2 * nbuckets
);
146 /* find global ELF symbol 'name' and return its index. Return 0 if not
148 static int find_elf_sym(Section
*s
, const char *name
)
152 int nbuckets
, sym_index
, h
;
158 nbuckets
= ((int *)hs
->data
)[0];
159 h
= elf_hash(name
) % nbuckets
;
160 sym_index
= ((int *)hs
->data
)[2 + h
];
161 while (sym_index
!= 0) {
162 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
163 name1
= s
->link
->data
+ sym
->st_name
;
164 if (!strcmp(name
, name1
))
166 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
171 /* return elf symbol value or error */
172 void *tcc_get_symbol(TCCState
*s
, const char *name
)
176 sym_index
= find_elf_sym(symtab_section
, name
);
179 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
180 return (void*)sym
->st_value
;
183 void *tcc_get_symbol_err(TCCState
*s
, const char *name
)
186 sym
= tcc_get_symbol(s
, name
);
188 error("%s not defined", name
);
192 /* add an elf symbol : check if it is already defined and patch
193 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
194 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
195 int info
, int other
, int sh_num
, const char *name
)
198 int sym_bind
, sym_index
, sym_type
, esym_bind
;
199 unsigned char sym_vis
, esym_vis
, new_vis
;
201 sym_bind
= ELFW(ST_BIND
)(info
);
202 sym_type
= ELFW(ST_TYPE
)(info
);
203 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
205 if (sym_bind
!= STB_LOCAL
) {
206 /* we search global or weak symbols */
207 sym_index
= find_elf_sym(s
, name
);
210 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
211 if (esym
->st_shndx
!= SHN_UNDEF
) {
212 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
213 /* propagate the most constraining visibility */
214 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
215 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
216 if (esym_vis
== STV_DEFAULT
) {
218 } else if (sym_vis
== STV_DEFAULT
) {
221 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
223 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
225 other
= esym
->st_other
; /* in case we have to patch esym */
226 if (sh_num
== SHN_UNDEF
) {
227 /* ignore adding of undefined symbol if the
228 corresponding symbol is already defined */
229 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
230 /* global overrides weak, so patch */
232 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
233 /* weak is ignored if already global */
234 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
235 /* ignore hidden symbols after */
236 } else if (esym
->st_shndx
== SHN_COMMON
&& sh_num
< SHN_LORESERVE
) {
237 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
238 No idea if this is the correct solution ... */
240 } else if (s
== tcc_state
->dynsymtab_section
) {
241 /* we accept that two DLL define the same symbol */
244 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
245 sym_bind
, sh_num
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
247 error_noabort("'%s' defined twice", name
);
251 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
252 esym
->st_shndx
= sh_num
;
253 esym
->st_value
= value
;
254 esym
->st_size
= size
;
255 esym
->st_other
= other
;
259 sym_index
= put_elf_sym(s
, value
, size
,
260 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
267 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
268 int type
, int symbol
)
276 /* if no relocation section, create it */
277 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
278 /* if the symtab is allocated, then we consider the relocation
280 sr
= new_section(tcc_state
, buf
, SHT_RELX
, symtab
->sh_flags
);
281 sr
->sh_entsize
= sizeof(ElfW_Rel
);
283 sr
->sh_info
= s
->sh_num
;
286 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
287 rel
->r_offset
= offset
;
288 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
289 #ifdef TCC_TARGET_X86_64
294 /* put stab debug information */
297 unsigned int n_strx
; /* index into string table of name */
298 unsigned char n_type
; /* type of symbol */
299 unsigned char n_other
; /* misc info (usually empty) */
300 unsigned short n_desc
; /* description field */
301 unsigned int n_value
; /* value of symbol */
304 static void put_stabs(const char *str
, int type
, int other
, int desc
,
309 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
311 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
316 sym
->n_other
= other
;
318 sym
->n_value
= value
;
321 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
322 unsigned long value
, Section
*sec
, int sym_index
)
324 put_stabs(str
, type
, other
, desc
, value
);
325 put_elf_reloc(symtab_section
, stab_section
,
326 stab_section
->data_offset
- sizeof(unsigned int),
327 R_DATA_32
, sym_index
);
330 static void put_stabn(int type
, int other
, int desc
, int value
)
332 put_stabs(NULL
, type
, other
, desc
, value
);
335 static void put_stabd(int type
, int other
, int desc
)
337 put_stabs(NULL
, type
, other
, desc
, 0);
340 /* In an ELF file symbol table, the local symbols must appear below
341 the global and weak ones. Since TCC cannot sort it while generating
342 the code, we must do it after. All the relocation tables are also
343 modified to take into account the symbol table sorting */
344 static void sort_syms(TCCState
*s1
, Section
*s
)
346 int *old_to_new_syms
;
350 ElfW_Rel
*rel
, *rel_end
;
354 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
355 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
356 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
358 /* first pass for local symbols */
359 p
= (ElfW(Sym
) *)s
->data
;
361 for(i
= 0; i
< nb_syms
; i
++) {
362 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
363 old_to_new_syms
[i
] = q
- new_syms
;
368 /* save the number of local symbols in section header */
369 s
->sh_info
= q
- new_syms
;
371 /* then second pass for non local symbols */
372 p
= (ElfW(Sym
) *)s
->data
;
373 for(i
= 0; i
< nb_syms
; i
++) {
374 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
375 old_to_new_syms
[i
] = q
- new_syms
;
381 /* we copy the new symbols to the old */
382 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
385 /* now we modify all the relocations */
386 for(i
= 1; i
< s1
->nb_sections
; i
++) {
387 sr
= s1
->sections
[i
];
388 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
389 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
390 for(rel
= (ElfW_Rel
*)sr
->data
;
393 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
394 type
= ELFW(R_TYPE
)(rel
->r_info
);
395 sym_index
= old_to_new_syms
[sym_index
];
396 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
401 tcc_free(old_to_new_syms
);
404 /* relocate common symbols in the .bss section */
405 static void relocate_common_syms(void)
407 ElfW(Sym
) *sym
, *sym_end
;
408 unsigned long offset
, align
;
410 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
411 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
414 if (sym
->st_shndx
== SHN_COMMON
) {
416 align
= sym
->st_value
;
417 offset
= bss_section
->data_offset
;
418 offset
= (offset
+ align
- 1) & -align
;
419 sym
->st_value
= offset
;
420 sym
->st_shndx
= bss_section
->sh_num
;
421 offset
+= sym
->st_size
;
422 bss_section
->data_offset
= offset
;
427 /* relocate symbol table, resolve undefined symbols if do_resolve is
428 true and output error if undefined symbol. */
429 static void relocate_syms(TCCState
*s1
, int do_resolve
)
431 ElfW(Sym
) *sym
, *esym
, *sym_end
;
432 int sym_bind
, sh_num
, sym_index
;
436 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
437 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
440 sh_num
= sym
->st_shndx
;
441 if (sh_num
== SHN_UNDEF
) {
442 name
= strtab_section
->data
+ sym
->st_name
;
444 name
= symtab_section
->link
->data
+ sym
->st_name
;
445 addr
= (unsigned long)resolve_sym(s1
, name
, ELFW(ST_TYPE
)(sym
->st_info
));
447 sym
->st_value
= addr
;
450 } else if (s1
->dynsym
) {
451 /* if dynamic symbol exist, then use it */
452 sym_index
= find_elf_sym(s1
->dynsym
, name
);
454 esym
= &((ElfW(Sym
) *)s1
->dynsym
->data
)[sym_index
];
455 sym
->st_value
= esym
->st_value
;
459 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
461 if (!strcmp(name
, "_fp_hw"))
463 /* only weak symbols are accepted to be undefined. Their
465 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
466 if (sym_bind
== STB_WEAK
) {
469 error_noabort("undefined symbol '%s'", name
);
471 } else if (sh_num
< SHN_LORESERVE
) {
472 /* add section base */
473 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
479 #ifdef TCC_TARGET_X86_64
480 #define JMP_TABLE_ENTRY_SIZE 14
481 static unsigned long add_jmp_table(TCCState
*s1
, unsigned long val
)
483 char *p
= s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
;
484 s1
->runtime_plt_and_got_offset
+= JMP_TABLE_ENTRY_SIZE
;
489 *(unsigned long *)(p
+ 6) = val
;
490 return (unsigned long)p
;
493 static unsigned long add_got_table(TCCState
*s1
, unsigned long val
)
495 unsigned long *p
=(unsigned long *)(s1
->runtime_plt_and_got
+
496 s1
->runtime_plt_and_got_offset
);
497 s1
->runtime_plt_and_got_offset
+= sizeof(void *);
499 return (unsigned long)p
;
503 /* relocate a given section (CPU dependent) */
504 static void relocate_section(TCCState
*s1
, Section
*s
)
507 ElfW_Rel
*rel
, *rel_end
, *qrel
;
511 unsigned long val
, addr
;
515 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
516 qrel
= (ElfW_Rel
*)sr
->data
;
520 ptr
= s
->data
+ rel
->r_offset
;
522 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
523 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
525 #ifdef TCC_TARGET_X86_64
526 /* XXX: not tested */
527 val
+= rel
->r_addend
;
529 type
= ELFW(R_TYPE
)(rel
->r_info
);
530 addr
= s
->sh_addr
+ rel
->r_offset
;
534 #if defined(TCC_TARGET_I386)
536 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
537 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
538 qrel
->r_offset
= rel
->r_offset
;
540 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_32
);
544 qrel
->r_info
= ELFW(R_INFO
)(0, R_386_RELATIVE
);
551 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
553 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
555 qrel
->r_offset
= rel
->r_offset
;
556 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_PC32
);
561 *(int *)ptr
+= val
- addr
;
564 *(int *)ptr
+= val
- addr
;
571 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
574 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
577 /* we load the got offset */
578 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
580 #elif defined(TCC_TARGET_ARM)
587 x
= (*(int *)ptr
)&0xffffff;
588 (*(int *)ptr
) &= 0xff000000;
593 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
594 error("can't relocate value at %x",addr
);
603 x
= (*(int *)ptr
) & 0x7fffffff;
604 (*(int *)ptr
) &= 0x80000000;
607 if((x
^(x
>>1))&0x40000000)
608 error("can't relocate value at %x",addr
);
609 (*(int *)ptr
) |= x
& 0x7fffffff;
614 case R_ARM_BASE_PREL
:
615 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
618 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
621 /* we load the got offset */
622 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
627 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
628 type
,addr
,(unsigned int )ptr
,val
);
630 #elif defined(TCC_TARGET_C67)
638 /* put the low 16 bits of the absolute address */
639 // add to what is already there
641 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
642 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
644 //patch both at once - assumes always in pairs Low - High
646 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
647 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
653 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
654 type
,addr
,(unsigned int )ptr
,val
);
656 #elif defined(TCC_TARGET_X86_64)
658 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
659 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
660 qrel
->r_addend
= *(long long *)ptr
+ val
;
663 *(long long *)ptr
+= val
;
667 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
668 /* XXX: this logic may depend on TCC's codegen
669 now TCC uses R_X86_64_32 even for a 64bit pointer */
670 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
671 qrel
->r_addend
= *(int *)ptr
+ val
;
676 case R_X86_64_PC32
: {
677 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
679 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
681 qrel
->r_offset
= rel
->r_offset
;
682 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_X86_64_PC32
);
683 qrel
->r_addend
= *(int *)ptr
;
688 long diff
= val
- addr
;
689 if (diff
<= -2147483647 || diff
> 2147483647) {
690 /* XXX: naive support for over 32bit jump */
691 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
692 val
= add_jmp_table(s1
, val
);
695 if (diff
<= -2147483647 || diff
> 2147483647) {
696 error("internal error: relocation failed");
703 *(int *)ptr
+= val
- addr
;
705 case R_X86_64_GLOB_DAT
:
706 case R_X86_64_JUMP_SLOT
:
709 case R_X86_64_GOTPCREL
:
710 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
711 val
= add_got_table(s1
, val
- rel
->r_addend
) + rel
->r_addend
;
712 *(int *)ptr
+= val
- addr
;
715 *(int *)ptr
+= (s1
->got
->sh_addr
- addr
+
716 s1
->got_offsets
[sym_index
] - 4);
718 case R_X86_64_GOTTPOFF
:
719 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
722 /* we load the got offset */
723 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
726 #error unsupported processor
730 /* if the relocation is allocated, we change its symbol table */
731 if (sr
->sh_flags
& SHF_ALLOC
)
732 sr
->link
= s1
->dynsym
;
735 /* relocate relocation table in 'sr' */
736 static void relocate_rel(TCCState
*s1
, Section
*sr
)
739 ElfW_Rel
*rel
, *rel_end
;
741 s
= s1
->sections
[sr
->sh_info
];
742 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
743 for(rel
= (ElfW_Rel
*)sr
->data
;
746 rel
->r_offset
+= s
->sh_addr
;
750 /* count the number of dynamic relocations so that we can reserve
752 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
754 ElfW_Rel
*rel
, *rel_end
;
755 int sym_index
, esym_index
, type
, count
;
758 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
759 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
760 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
761 type
= ELFW(R_TYPE
)(rel
->r_info
);
763 #if defined(TCC_TARGET_I386)
765 #elif defined(TCC_TARGET_X86_64)
772 #if defined(TCC_TARGET_I386)
774 #elif defined(TCC_TARGET_X86_64)
777 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
786 /* allocate the section */
787 sr
->sh_flags
|= SHF_ALLOC
;
788 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
793 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
798 if (index
>= s1
->nb_got_offsets
) {
799 /* find immediately bigger power of 2 and reallocate array */
803 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
805 error("memory full");
806 s1
->got_offsets
= tab
;
807 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
808 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
809 s1
->nb_got_offsets
= n
;
811 s1
->got_offsets
[index
] = val
;
814 /* XXX: suppress that */
815 static void put32(unsigned char *p
, uint32_t val
)
823 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
824 defined(TCC_TARGET_X86_64)
825 static uint32_t get32(unsigned char *p
)
827 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
831 static void build_got(TCCState
*s1
)
835 /* if no got, then create it */
836 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
837 s1
->got
->sh_entsize
= 4;
838 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
839 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
840 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
842 /* keep space for _DYNAMIC pointer, if present */
844 /* two dummy got entries */
848 /* keep space for _DYNAMIC pointer, if present */
851 /* two dummy got entries */
859 /* put a got entry corresponding to a symbol in symtab_section. 'size'
860 and 'info' can be modifed if more precise info comes from the DLL */
861 static void put_got_entry(TCCState
*s1
,
862 int reloc_type
, unsigned long size
, int info
,
868 unsigned long offset
;
874 /* if a got entry already exists for that symbol, no need to add one */
875 if (sym_index
< s1
->nb_got_offsets
&&
876 s1
->got_offsets
[sym_index
] != 0)
879 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
882 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
883 name
= symtab_section
->link
->data
+ sym
->st_name
;
884 offset
= sym
->st_value
;
885 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
887 #ifdef TCC_TARGET_X86_64
897 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
900 /* if we build a DLL, we add a %ebx offset */
901 if (s1
->output_type
== TCC_OUTPUT_DLL
)
907 /* add a PLT entry */
909 if (plt
->data_offset
== 0) {
910 /* first plt entry */
911 p
= section_ptr_add(plt
, 16);
912 p
[0] = 0xff; /* pushl got + PTR_SIZE */
914 put32(p
+ 2, PTR_SIZE
);
915 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
917 put32(p
+ 8, PTR_SIZE
* 2);
920 p
= section_ptr_add(plt
, 16);
921 p
[0] = 0xff; /* jmp *(got + x) */
923 put32(p
+ 2, s1
->got
->data_offset
);
924 p
[6] = 0x68; /* push $xxx */
925 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
926 p
[11] = 0xe9; /* jmp plt_start */
927 put32(p
+ 12, -(plt
->data_offset
));
929 /* the symbol is modified so that it will be relocated to
931 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
932 if (s1
->output_type
== TCC_OUTPUT_EXE
)
934 offset
= plt
->data_offset
- 16;
936 #elif defined(TCC_TARGET_ARM)
937 if (reloc_type
== R_ARM_JUMP_SLOT
) {
941 /* if we build a DLL, we add a %ebx offset */
942 if (s1
->output_type
== TCC_OUTPUT_DLL
)
943 error("DLLs unimplemented!");
945 /* add a PLT entry */
947 if (plt
->data_offset
== 0) {
948 /* first plt entry */
949 p
= section_ptr_add(plt
, 16);
950 put32(p
, 0xe52de004);
951 put32(p
+ 4, 0xe59fe010);
952 put32(p
+ 8, 0xe08fe00e);
953 put32(p
+ 12, 0xe5bef008);
956 p
= section_ptr_add(plt
, 16);
957 put32(p
, 0xe59fc004);
958 put32(p
+4, 0xe08fc00c);
959 put32(p
+8, 0xe59cf000);
960 put32(p
+12, s1
->got
->data_offset
);
962 /* the symbol is modified so that it will be relocated to
964 if (s1
->output_type
== TCC_OUTPUT_EXE
)
965 offset
= plt
->data_offset
- 16;
967 #elif defined(TCC_TARGET_C67)
968 error("C67 got not implemented");
970 #error unsupported CPU
972 index
= put_elf_sym(s1
->dynsym
, offset
,
973 size
, info
, 0, sym
->st_shndx
, name
);
974 /* put a got entry */
975 put_elf_reloc(s1
->dynsym
, s1
->got
,
976 s1
->got
->data_offset
,
979 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
983 /* build GOT and PLT entries */
984 static void build_got_entries(TCCState
*s1
)
987 ElfW_Rel
*rel
, *rel_end
;
989 int i
, type
, reloc_type
, sym_index
;
991 for(i
= 1; i
< s1
->nb_sections
; i
++) {
993 if (s
->sh_type
!= SHT_RELX
)
995 /* no need to handle got relocations */
996 if (s
->link
!= symtab_section
)
999 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
1000 for(rel
= (ElfW_Rel
*)s
->data
;
1003 type
= ELFW(R_TYPE
)(rel
->r_info
);
1005 #if defined(TCC_TARGET_I386)
1012 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1013 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1014 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1015 /* look at the symbol got offset. If none, then add one */
1016 if (type
== R_386_GOT32
)
1017 reloc_type
= R_386_GLOB_DAT
;
1019 reloc_type
= R_386_JMP_SLOT
;
1020 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1024 #elif defined(TCC_TARGET_ARM)
1025 case R_ARM_GOT_BREL
:
1026 case R_ARM_GOTOFF32
:
1027 case R_ARM_BASE_PREL
:
1031 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1032 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1033 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1034 /* look at the symbol got offset. If none, then add one */
1035 if (type
== R_ARM_GOT_BREL
)
1036 reloc_type
= R_ARM_GLOB_DAT
;
1038 reloc_type
= R_ARM_JUMP_SLOT
;
1039 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1043 #elif defined(TCC_TARGET_C67)
1050 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1051 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1052 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1053 /* look at the symbol got offset. If none, then add one */
1054 if (type
== R_C60_GOT32
)
1055 reloc_type
= R_C60_GLOB_DAT
;
1057 reloc_type
= R_C60_JMP_SLOT
;
1058 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1062 #elif defined(TCC_TARGET_X86_64)
1063 case R_X86_64_GOT32
:
1064 case R_X86_64_GOTTPOFF
:
1065 case R_X86_64_GOTPCREL
:
1066 case R_X86_64_PLT32
:
1069 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
||
1070 type
== R_X86_64_PLT32
) {
1071 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1072 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1073 /* look at the symbol got offset. If none, then add one */
1074 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
)
1075 reloc_type
= R_X86_64_GLOB_DAT
;
1077 reloc_type
= R_X86_64_JUMP_SLOT
;
1078 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1083 #error unsupported CPU
1092 static Section
*new_symtab(TCCState
*s1
,
1093 const char *symtab_name
, int sh_type
, int sh_flags
,
1094 const char *strtab_name
,
1095 const char *hash_name
, int hash_sh_flags
)
1097 Section
*symtab
, *strtab
, *hash
;
1098 int *ptr
, nb_buckets
;
1100 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1101 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1102 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1103 put_elf_str(strtab
, "");
1104 symtab
->link
= strtab
;
1105 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1109 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1110 hash
->sh_entsize
= sizeof(int);
1111 symtab
->hash
= hash
;
1112 hash
->link
= symtab
;
1114 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1115 ptr
[0] = nb_buckets
;
1117 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1121 /* put dynamic tag */
1122 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1125 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1127 dyn
->d_un
.d_val
= val
;
1130 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1134 char sym_start
[1024];
1137 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1138 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1140 s
= find_section(s1
, section_name
);
1145 end_offset
= s
->data_offset
;
1148 add_elf_sym(symtab_section
,
1150 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1151 s
->sh_num
, sym_start
);
1152 add_elf_sym(symtab_section
,
1154 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1155 s
->sh_num
, sym_end
);
1158 /* add tcc runtime libraries */
1159 static void tcc_add_runtime(TCCState
*s1
)
1161 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1165 #ifdef CONFIG_TCC_BCHECK
1166 if (do_bounds_check
) {
1168 Section
*init_section
;
1169 unsigned char *pinit
;
1172 /* XXX: add an object file to do that */
1173 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1175 add_elf_sym(symtab_section
, 0, 0,
1176 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1177 bounds_section
->sh_num
, "__bounds_start");
1178 /* add bound check code */
1179 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "bcheck.o");
1180 tcc_add_file(s1
, buf
);
1181 #ifdef TCC_TARGET_I386
1182 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1183 /* add 'call __bound_init()' in .init section */
1184 init_section
= find_section(s1
, ".init");
1185 pinit
= section_ptr_add(init_section
, 5);
1187 put32(pinit
+ 1, -4);
1188 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1189 put_elf_reloc(symtab_section
, init_section
,
1190 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1196 if (!s1
->nostdlib
) {
1197 tcc_add_library(s1
, "c");
1199 #ifdef CONFIG_USE_LIBGCC
1200 tcc_add_file(s1
, CONFIG_SYSROOT
"/lib/libgcc_s.so.1");
1202 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "libtcc1.a");
1203 tcc_add_file(s1
, buf
);
1206 /* add crt end if not memory output */
1207 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1208 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1212 /* add various standard linker symbols (must be done after the
1213 sections are filled (for example after allocating common
1215 static void tcc_add_linker_symbols(TCCState
*s1
)
1221 add_elf_sym(symtab_section
,
1222 text_section
->data_offset
, 0,
1223 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1224 text_section
->sh_num
, "_etext");
1225 add_elf_sym(symtab_section
,
1226 data_section
->data_offset
, 0,
1227 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1228 data_section
->sh_num
, "_edata");
1229 add_elf_sym(symtab_section
,
1230 bss_section
->data_offset
, 0,
1231 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1232 bss_section
->sh_num
, "_end");
1233 /* horrible new standard ldscript defines */
1234 add_init_array_defines(s1
, ".preinit_array");
1235 add_init_array_defines(s1
, ".init_array");
1236 add_init_array_defines(s1
, ".fini_array");
1238 /* add start and stop symbols for sections whose name can be
1240 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1241 s
= s1
->sections
[i
];
1242 if (s
->sh_type
== SHT_PROGBITS
&&
1243 (s
->sh_flags
& SHF_ALLOC
)) {
1247 /* check if section name can be expressed in C */
1253 if (!isid(ch
) && !isnum(ch
))
1257 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1258 add_elf_sym(symtab_section
,
1260 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1262 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1263 add_elf_sym(symtab_section
,
1265 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1272 /* name of ELF interpreter */
1274 static char elf_interp
[] = "/usr/libexec/ld-elf.so.1";
1277 static char elf_interp
[] = "/lib/ld-linux.so.3";
1278 #elif defined(TCC_TARGET_X86_64)
1279 static char elf_interp
[] = "/lib/ld-linux-x86-64.so.2";
1281 static char elf_interp
[] = "/lib/ld-linux.so.2";
1285 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1286 const int *section_order
)
1289 int i
, offset
, size
;
1292 for(i
=1;i
<s1
->nb_sections
;i
++) {
1293 s
= s1
->sections
[section_order
[i
]];
1294 if (s
->sh_type
!= SHT_NOBITS
&&
1295 (s
->sh_flags
& SHF_ALLOC
)) {
1296 while (offset
< s
->sh_offset
) {
1301 fwrite(s
->data
, 1, size
, f
);
1307 /* output an ELF file */
1308 /* XXX: suppress unneeded sections */
1309 int elf_output_file(TCCState
*s1
, const char *filename
)
1315 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1317 Section
*strsec
, *s
;
1318 ElfW(Shdr
) shdr
, *sh
;
1319 ElfW(Phdr
) *phdr
, *ph
;
1320 Section
*interp
, *dynamic
, *dynstr
;
1321 unsigned long saved_dynamic_data_offset
;
1323 int type
, file_type
;
1324 unsigned long rel_addr
, rel_size
;
1326 file_type
= s1
->output_type
;
1329 if (file_type
!= TCC_OUTPUT_OBJ
) {
1330 tcc_add_runtime(s1
);
1334 section_order
= NULL
;
1337 dynstr
= NULL
; /* avoid warning */
1338 saved_dynamic_data_offset
= 0; /* avoid warning */
1340 if (file_type
!= TCC_OUTPUT_OBJ
) {
1341 relocate_common_syms();
1343 tcc_add_linker_symbols(s1
);
1345 if (!s1
->static_link
) {
1347 int sym_index
, index
;
1348 ElfW(Sym
) *esym
, *sym_end
;
1350 if (file_type
== TCC_OUTPUT_EXE
) {
1352 /* add interpreter section only if executable */
1353 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1354 interp
->sh_addralign
= 1;
1355 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
1356 strcpy(ptr
, elf_interp
);
1359 /* add dynamic symbol table */
1360 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1362 ".hash", SHF_ALLOC
);
1363 dynstr
= s1
->dynsym
->link
;
1365 /* add dynamic section */
1366 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1367 SHF_ALLOC
| SHF_WRITE
);
1368 dynamic
->link
= dynstr
;
1369 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1372 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1373 SHF_ALLOC
| SHF_EXECINSTR
);
1374 s1
->plt
->sh_entsize
= 4;
1378 /* scan for undefined symbols and see if they are in the
1379 dynamic symbols. If a symbol STT_FUNC is found, then we
1380 add it in the PLT. If a symbol STT_OBJECT is found, we
1381 add it in the .bss section with a suitable relocation */
1382 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1383 symtab_section
->data_offset
);
1384 if (file_type
== TCC_OUTPUT_EXE
) {
1385 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1388 if (sym
->st_shndx
== SHN_UNDEF
) {
1389 name
= symtab_section
->link
->data
+ sym
->st_name
;
1390 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1392 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1393 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1394 if (type
== STT_FUNC
) {
1395 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1397 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1398 } else if (type
== STT_OBJECT
) {
1399 unsigned long offset
;
1400 offset
= bss_section
->data_offset
;
1401 /* XXX: which alignment ? */
1402 offset
= (offset
+ 16 - 1) & -16;
1403 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1405 bss_section
->sh_num
, name
);
1406 put_elf_reloc(s1
->dynsym
, bss_section
,
1407 offset
, R_COPY
, index
);
1408 offset
+= esym
->st_size
;
1409 bss_section
->data_offset
= offset
;
1412 /* STB_WEAK undefined symbols are accepted */
1413 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1415 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1416 !strcmp(name
, "_fp_hw")) {
1418 error_noabort("undefined symbol '%s'", name
);
1421 } else if (s1
->rdynamic
&&
1422 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1423 /* if -rdynamic option, then export all non
1425 name
= symtab_section
->link
->data
+ sym
->st_name
;
1426 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1428 sym
->st_shndx
, name
);
1435 /* now look at unresolved dynamic symbols and export
1436 corresponding symbol */
1437 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1438 s1
->dynsymtab_section
->data_offset
);
1439 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1442 if (esym
->st_shndx
== SHN_UNDEF
) {
1443 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1444 sym_index
= find_elf_sym(symtab_section
, name
);
1446 /* XXX: avoid adding a symbol if already
1447 present because of -rdynamic ? */
1448 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1449 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1451 sym
->st_shndx
, name
);
1453 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1454 /* weak symbols can stay undefined */
1456 warning("undefined dynamic symbol '%s'", name
);
1463 /* shared library case : we simply export all the global symbols */
1464 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1465 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1466 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1469 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1470 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1471 if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
&&
1472 sym
->st_shndx
== SHN_UNDEF
) {
1473 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1475 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1477 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1478 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1480 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1485 name
= symtab_section
->link
->data
+ sym
->st_name
;
1486 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1488 sym
->st_shndx
, name
);
1489 s1
->symtab_to_dynsym
[sym
-
1490 (ElfW(Sym
) *)symtab_section
->data
] =
1497 build_got_entries(s1
);
1499 /* add a list of needed dlls */
1500 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1501 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1502 if (dllref
->level
== 0)
1503 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1505 /* XXX: currently, since we do not handle PIC code, we
1506 must relocate the readonly segments */
1507 if (file_type
== TCC_OUTPUT_DLL
) {
1509 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1510 put_dt(dynamic
, DT_TEXTREL
, 0);
1513 /* add necessary space for other entries */
1514 saved_dynamic_data_offset
= dynamic
->data_offset
;
1515 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * 9;
1517 /* still need to build got entries in case of static link */
1518 build_got_entries(s1
);
1522 memset(&ehdr
, 0, sizeof(ehdr
));
1524 /* we add a section for symbols */
1525 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1526 put_elf_str(strsec
, "");
1528 /* compute number of sections */
1529 shnum
= s1
->nb_sections
;
1531 /* this array is used to reorder sections in the output file */
1532 section_order
= tcc_malloc(sizeof(int) * shnum
);
1533 section_order
[0] = 0;
1536 /* compute number of program headers */
1539 case TCC_OUTPUT_OBJ
:
1542 case TCC_OUTPUT_EXE
:
1543 if (!s1
->static_link
)
1548 case TCC_OUTPUT_DLL
:
1553 /* allocate strings for section names and decide if an unallocated
1554 section should be output */
1555 /* NOTE: the strsec section comes last, so its size is also
1557 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1558 s
= s1
->sections
[i
];
1559 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1561 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1566 s
->reloc
? s
->reloc
->name
: "n"
1569 /* when generating a DLL, we include relocations but we may
1571 if (file_type
== TCC_OUTPUT_DLL
&&
1572 s
->sh_type
== SHT_RELX
&&
1573 !(s
->sh_flags
& SHF_ALLOC
)) {
1574 /* //gr: avoid bogus relocs for empty (debug) sections */
1575 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1576 prepare_dynamic_rel(s1
, s
);
1578 s
->sh_size
= s
->data_offset
;
1579 } else if (do_debug
||
1580 file_type
== TCC_OUTPUT_OBJ
||
1581 (s
->sh_flags
& SHF_ALLOC
) ||
1582 i
== (s1
->nb_sections
- 1)) {
1583 /* we output all sections if debug or object file */
1584 s
->sh_size
= s
->data_offset
;
1588 /* allocate program segment headers */
1589 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1591 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1592 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1597 /* compute section to program header mapping */
1598 if (s1
->has_text_addr
) {
1599 int a_offset
, p_offset
;
1600 addr
= s1
->text_addr
;
1601 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1603 a_offset
= addr
& (ELF_PAGE_SIZE
- 1);
1604 p_offset
= file_offset
& (ELF_PAGE_SIZE
- 1);
1605 if (a_offset
< p_offset
)
1606 a_offset
+= ELF_PAGE_SIZE
;
1607 file_offset
+= (a_offset
- p_offset
);
1609 if (file_type
== TCC_OUTPUT_DLL
)
1612 addr
= ELF_START_ADDR
;
1613 /* compute address after headers */
1614 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1617 /* dynamic relocation table information, for .dynamic section */
1621 /* leave one program header for the program interpreter */
1626 for(j
= 0; j
< 2; j
++) {
1627 ph
->p_type
= PT_LOAD
;
1629 ph
->p_flags
= PF_R
| PF_X
;
1631 ph
->p_flags
= PF_R
| PF_W
;
1632 ph
->p_align
= ELF_PAGE_SIZE
;
1634 /* we do the following ordering: interp, symbol tables,
1635 relocations, progbits, nobits */
1636 /* XXX: do faster and simpler sorting */
1637 for(k
= 0; k
< 5; k
++) {
1638 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1639 s
= s1
->sections
[i
];
1640 /* compute if section should be included */
1642 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1646 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1647 (SHF_ALLOC
| SHF_WRITE
))
1653 } else if (s
->sh_type
== SHT_DYNSYM
||
1654 s
->sh_type
== SHT_STRTAB
||
1655 s
->sh_type
== SHT_HASH
) {
1658 } else if (s
->sh_type
== SHT_RELX
) {
1661 } else if (s
->sh_type
== SHT_NOBITS
) {
1668 section_order
[sh_order_index
++] = i
;
1670 /* section matches: we align it and add its size */
1672 addr
= (addr
+ s
->sh_addralign
- 1) &
1673 ~(s
->sh_addralign
- 1);
1674 file_offset
+= addr
- tmp
;
1675 s
->sh_offset
= file_offset
;
1678 /* update program header infos */
1679 if (ph
->p_offset
== 0) {
1680 ph
->p_offset
= file_offset
;
1682 ph
->p_paddr
= ph
->p_vaddr
;
1684 /* update dynamic relocation infos */
1685 if (s
->sh_type
== SHT_RELX
) {
1688 rel_size
+= s
->sh_size
;
1691 if (s
->sh_type
!= SHT_NOBITS
)
1692 file_offset
+= s
->sh_size
;
1695 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1696 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1699 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1700 /* if in the middle of a page, we duplicate the page in
1701 memory so that one copy is RX and the other is RW */
1702 if ((addr
& (ELF_PAGE_SIZE
- 1)) != 0)
1703 addr
+= ELF_PAGE_SIZE
;
1705 addr
= (addr
+ ELF_PAGE_SIZE
- 1) & ~(ELF_PAGE_SIZE
- 1);
1706 file_offset
= (file_offset
+ ELF_PAGE_SIZE
- 1) &
1707 ~(ELF_PAGE_SIZE
- 1);
1712 /* if interpreter, then add corresponing program header */
1716 ph
->p_type
= PT_INTERP
;
1717 ph
->p_offset
= interp
->sh_offset
;
1718 ph
->p_vaddr
= interp
->sh_addr
;
1719 ph
->p_paddr
= ph
->p_vaddr
;
1720 ph
->p_filesz
= interp
->sh_size
;
1721 ph
->p_memsz
= interp
->sh_size
;
1723 ph
->p_align
= interp
->sh_addralign
;
1726 /* if dynamic section, then add corresponing program header */
1730 ph
= &phdr
[phnum
- 1];
1732 ph
->p_type
= PT_DYNAMIC
;
1733 ph
->p_offset
= dynamic
->sh_offset
;
1734 ph
->p_vaddr
= dynamic
->sh_addr
;
1735 ph
->p_paddr
= ph
->p_vaddr
;
1736 ph
->p_filesz
= dynamic
->sh_size
;
1737 ph
->p_memsz
= dynamic
->sh_size
;
1738 ph
->p_flags
= PF_R
| PF_W
;
1739 ph
->p_align
= dynamic
->sh_addralign
;
1741 /* put GOT dynamic section address */
1742 put32(s1
->got
->data
, dynamic
->sh_addr
);
1744 /* relocate the PLT */
1745 if (file_type
== TCC_OUTPUT_EXE
1746 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1747 || file_type
== TCC_OUTPUT_DLL
1753 p_end
= p
+ s1
->plt
->data_offset
;
1755 #if defined(TCC_TARGET_I386)
1756 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1757 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1760 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1763 #elif defined(TCC_TARGET_X86_64)
1764 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1765 put32(p
+ 2, get32(p
+ 2) + x
);
1766 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1769 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1772 #elif defined(TCC_TARGET_ARM)
1774 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1777 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1780 #elif defined(TCC_TARGET_C67)
1783 #error unsupported CPU
1788 /* relocate symbols in .dynsym */
1789 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1790 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1793 if (sym
->st_shndx
== SHN_UNDEF
) {
1794 /* relocate to the PLT if the symbol corresponds
1797 sym
->st_value
+= s1
->plt
->sh_addr
;
1798 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1799 /* do symbol relocation */
1800 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1804 /* put dynamic section entries */
1805 dynamic
->data_offset
= saved_dynamic_data_offset
;
1806 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1807 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1808 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1809 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1810 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1811 #ifdef TCC_TARGET_X86_64
1812 put_dt(dynamic
, DT_RELA
, rel_addr
);
1813 put_dt(dynamic
, DT_RELASZ
, rel_size
);
1814 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1816 put_dt(dynamic
, DT_REL
, rel_addr
);
1817 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1818 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1821 put_dt(dynamic
, DT_DEBUG
, 0);
1822 put_dt(dynamic
, DT_NULL
, 0);
1825 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1826 ehdr
.e_phnum
= phnum
;
1827 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1830 /* all other sections come after */
1831 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1832 s
= s1
->sections
[i
];
1833 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1835 section_order
[sh_order_index
++] = i
;
1837 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1838 ~(s
->sh_addralign
- 1);
1839 s
->sh_offset
= file_offset
;
1840 if (s
->sh_type
!= SHT_NOBITS
)
1841 file_offset
+= s
->sh_size
;
1844 /* if building executable or DLL, then relocate each section
1845 except the GOT which is already relocated */
1846 if (file_type
!= TCC_OUTPUT_OBJ
) {
1847 relocate_syms(s1
, 0);
1849 if (s1
->nb_errors
!= 0) {
1855 /* relocate sections */
1856 /* XXX: ignore sections with allocated relocations ? */
1857 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1858 s
= s1
->sections
[i
];
1859 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1860 relocate_section(s1
, s
);
1863 /* relocate relocation entries if the relocation tables are
1864 allocated in the executable */
1865 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1866 s
= s1
->sections
[i
];
1867 if ((s
->sh_flags
& SHF_ALLOC
) &&
1868 s
->sh_type
== SHT_RELX
) {
1869 relocate_rel(s1
, s
);
1873 /* get entry point address */
1874 if (file_type
== TCC_OUTPUT_EXE
)
1875 ehdr
.e_entry
= (unsigned long)tcc_get_symbol_err(s1
, "_start");
1877 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1880 /* write elf file */
1881 if (file_type
== TCC_OUTPUT_OBJ
)
1885 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1887 error_noabort("could not write '%s'", filename
);
1890 f
= fdopen(fd
, "wb");
1892 printf("<- %s\n", filename
);
1894 #ifdef TCC_TARGET_COFF
1895 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1896 tcc_output_coff(s1
, f
);
1899 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1900 sort_syms(s1
, symtab_section
);
1903 file_offset
= (file_offset
+ 3) & -4;
1906 ehdr
.e_ident
[0] = ELFMAG0
;
1907 ehdr
.e_ident
[1] = ELFMAG1
;
1908 ehdr
.e_ident
[2] = ELFMAG2
;
1909 ehdr
.e_ident
[3] = ELFMAG3
;
1910 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
1911 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1912 ehdr
.e_ident
[6] = EV_CURRENT
;
1914 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1916 #ifdef TCC_TARGET_ARM
1918 ehdr
.e_ident
[EI_OSABI
] = 0;
1919 ehdr
.e_flags
= 4 << 24;
1921 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
1926 case TCC_OUTPUT_EXE
:
1927 ehdr
.e_type
= ET_EXEC
;
1929 case TCC_OUTPUT_DLL
:
1930 ehdr
.e_type
= ET_DYN
;
1932 case TCC_OUTPUT_OBJ
:
1933 ehdr
.e_type
= ET_REL
;
1936 ehdr
.e_machine
= EM_TCC_TARGET
;
1937 ehdr
.e_version
= EV_CURRENT
;
1938 ehdr
.e_shoff
= file_offset
;
1939 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
1940 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
1941 ehdr
.e_shnum
= shnum
;
1942 ehdr
.e_shstrndx
= shnum
- 1;
1944 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
1945 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
1946 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1948 for(i
=1;i
<s1
->nb_sections
;i
++) {
1949 s
= s1
->sections
[section_order
[i
]];
1950 if (s
->sh_type
!= SHT_NOBITS
) {
1951 while (offset
< s
->sh_offset
) {
1956 fwrite(s
->data
, 1, size
, f
);
1961 /* output section headers */
1962 while (offset
< ehdr
.e_shoff
) {
1967 for(i
=0;i
<s1
->nb_sections
;i
++) {
1969 memset(sh
, 0, sizeof(ElfW(Shdr
)));
1970 s
= s1
->sections
[i
];
1972 sh
->sh_name
= s
->sh_name
;
1973 sh
->sh_type
= s
->sh_type
;
1974 sh
->sh_flags
= s
->sh_flags
;
1975 sh
->sh_entsize
= s
->sh_entsize
;
1976 sh
->sh_info
= s
->sh_info
;
1978 sh
->sh_link
= s
->link
->sh_num
;
1979 sh
->sh_addralign
= s
->sh_addralign
;
1980 sh
->sh_addr
= s
->sh_addr
;
1981 sh
->sh_offset
= s
->sh_offset
;
1982 sh
->sh_size
= s
->sh_size
;
1984 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
1987 tcc_output_binary(s1
, f
, section_order
);
1993 tcc_free(s1
->symtab_to_dynsym
);
1994 tcc_free(section_order
);
1996 tcc_free(s1
->got_offsets
);
2000 int tcc_output_file(TCCState
*s
, const char *filename
)
2003 #ifdef TCC_TARGET_PE
2004 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2005 ret
= pe_output_file(s
, filename
);
2009 ret
= elf_output_file(s
, filename
);
2014 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2018 data
= tcc_malloc(size
);
2019 lseek(fd
, file_offset
, SEEK_SET
);
2020 read(fd
, data
, size
);
2024 typedef struct SectionMergeInfo
{
2025 Section
*s
; /* corresponding existing section */
2026 unsigned long offset
; /* offset of the new section in the existing section */
2027 uint8_t new_section
; /* true if section 's' was added */
2028 uint8_t link_once
; /* true if link once section */
2031 /* load an object file and merge it with current files */
2032 /* XXX: handle correctly stab (debug) info */
2033 static int tcc_load_object_file(TCCState
*s1
,
2034 int fd
, unsigned long file_offset
)
2037 ElfW(Shdr
) *shdr
, *sh
;
2038 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2039 unsigned char *strsec
, *strtab
;
2040 int *old_to_new_syms
;
2041 char *sh_name
, *name
;
2042 SectionMergeInfo
*sm_table
, *sm
;
2043 ElfW(Sym
) *sym
, *symtab
;
2044 ElfW_Rel
*rel
, *rel_end
;
2050 stab_index
= stabstr_index
= 0;
2052 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2054 if (ehdr
.e_ident
[0] != ELFMAG0
||
2055 ehdr
.e_ident
[1] != ELFMAG1
||
2056 ehdr
.e_ident
[2] != ELFMAG2
||
2057 ehdr
.e_ident
[3] != ELFMAG3
)
2059 /* test if object file */
2060 if (ehdr
.e_type
!= ET_REL
)
2062 /* test CPU specific stuff */
2063 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2064 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2066 error_noabort("invalid object file");
2070 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2071 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2072 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2074 /* load section names */
2075 sh
= &shdr
[ehdr
.e_shstrndx
];
2076 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2078 /* load symtab and strtab */
2079 old_to_new_syms
= NULL
;
2083 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2085 if (sh
->sh_type
== SHT_SYMTAB
) {
2087 error_noabort("object must contain only one symtab");
2092 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2093 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2094 sm_table
[i
].s
= symtab_section
;
2096 /* now load strtab */
2097 sh
= &shdr
[sh
->sh_link
];
2098 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2102 /* now examine each section and try to merge its content with the
2104 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2105 /* no need to examine section name strtab */
2106 if (i
== ehdr
.e_shstrndx
)
2109 sh_name
= strsec
+ sh
->sh_name
;
2110 /* ignore sections types we do not handle */
2111 if (sh
->sh_type
!= SHT_PROGBITS
&&
2112 sh
->sh_type
!= SHT_RELX
&&
2114 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2116 sh
->sh_type
!= SHT_NOBITS
&&
2117 strcmp(sh_name
, ".stabstr")
2120 if (sh
->sh_addralign
< 1)
2121 sh
->sh_addralign
= 1;
2122 /* find corresponding section, if any */
2123 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2124 s
= s1
->sections
[j
];
2125 if (!strcmp(s
->name
, sh_name
)) {
2126 if (!strncmp(sh_name
, ".gnu.linkonce",
2127 sizeof(".gnu.linkonce") - 1)) {
2128 /* if a 'linkonce' section is already present, we
2129 do not add it again. It is a little tricky as
2130 symbols can still be defined in
2132 sm_table
[i
].link_once
= 1;
2139 /* not found: create new section */
2140 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2141 /* take as much info as possible from the section. sh_link and
2142 sh_info will be updated later */
2143 s
->sh_addralign
= sh
->sh_addralign
;
2144 s
->sh_entsize
= sh
->sh_entsize
;
2145 sm_table
[i
].new_section
= 1;
2147 if (sh
->sh_type
!= s
->sh_type
) {
2148 error_noabort("invalid section type");
2152 /* align start of section */
2153 offset
= s
->data_offset
;
2155 if (0 == strcmp(sh_name
, ".stab")) {
2159 if (0 == strcmp(sh_name
, ".stabstr")) {
2164 size
= sh
->sh_addralign
- 1;
2165 offset
= (offset
+ size
) & ~size
;
2166 if (sh
->sh_addralign
> s
->sh_addralign
)
2167 s
->sh_addralign
= sh
->sh_addralign
;
2168 s
->data_offset
= offset
;
2170 sm_table
[i
].offset
= offset
;
2172 /* concatenate sections */
2174 if (sh
->sh_type
!= SHT_NOBITS
) {
2176 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2177 ptr
= section_ptr_add(s
, size
);
2178 read(fd
, ptr
, size
);
2180 s
->data_offset
+= size
;
2185 /* //gr relocate stab strings */
2186 if (stab_index
&& stabstr_index
) {
2189 s
= sm_table
[stab_index
].s
;
2190 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2191 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2192 o
= sm_table
[stabstr_index
].offset
;
2194 a
->n_strx
+= o
, a
++;
2197 /* second short pass to update sh_link and sh_info fields of new
2199 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2201 if (!s
|| !sm_table
[i
].new_section
)
2204 if (sh
->sh_link
> 0)
2205 s
->link
= sm_table
[sh
->sh_link
].s
;
2206 if (sh
->sh_type
== SHT_RELX
) {
2207 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2208 /* update backward link */
2209 s1
->sections
[s
->sh_info
]->reloc
= s
;
2214 /* resolve symbols */
2215 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2218 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2219 if (sym
->st_shndx
!= SHN_UNDEF
&&
2220 sym
->st_shndx
< SHN_LORESERVE
) {
2221 sm
= &sm_table
[sym
->st_shndx
];
2222 if (sm
->link_once
) {
2223 /* if a symbol is in a link once section, we use the
2224 already defined symbol. It is very important to get
2225 correct relocations */
2226 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2227 name
= strtab
+ sym
->st_name
;
2228 sym_index
= find_elf_sym(symtab_section
, name
);
2230 old_to_new_syms
[i
] = sym_index
;
2234 /* if no corresponding section added, no need to add symbol */
2237 /* convert section number */
2238 sym
->st_shndx
= sm
->s
->sh_num
;
2240 sym
->st_value
+= sm
->offset
;
2243 name
= strtab
+ sym
->st_name
;
2244 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2245 sym
->st_info
, sym
->st_other
,
2246 sym
->st_shndx
, name
);
2247 old_to_new_syms
[i
] = sym_index
;
2250 /* third pass to patch relocation entries */
2251 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2256 offset
= sm_table
[i
].offset
;
2257 switch(s
->sh_type
) {
2259 /* take relocation offset information */
2260 offseti
= sm_table
[sh
->sh_info
].offset
;
2261 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2262 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2267 /* convert symbol index */
2268 type
= ELFW(R_TYPE
)(rel
->r_info
);
2269 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2270 /* NOTE: only one symtab assumed */
2271 if (sym_index
>= nb_syms
)
2273 sym_index
= old_to_new_syms
[sym_index
];
2274 /* ignore link_once in rel section. */
2275 if (!sym_index
&& !sm
->link_once
) {
2277 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2278 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2281 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2282 /* offset the relocation offset */
2283 rel
->r_offset
+= offseti
;
2295 tcc_free(old_to_new_syms
);
2302 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2304 typedef struct ArchiveHeader
{
2305 char ar_name
[16]; /* name of this member */
2306 char ar_date
[12]; /* file mtime */
2307 char ar_uid
[6]; /* owner uid; printed as decimal */
2308 char ar_gid
[6]; /* owner gid; printed as decimal */
2309 char ar_mode
[8]; /* file mode, printed as octal */
2310 char ar_size
[10]; /* file size, printed as decimal */
2311 char ar_fmag
[2]; /* should contain ARFMAG */
2314 static int get_be32(const uint8_t *b
)
2316 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2319 /* load only the objects which resolve undefined symbols */
2320 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2322 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2324 const char *ar_names
, *p
;
2325 const uint8_t *ar_index
;
2328 data
= tcc_malloc(size
);
2329 if (read(fd
, data
, size
) != size
)
2331 nsyms
= get_be32(data
);
2332 ar_index
= data
+ 4;
2333 ar_names
= ar_index
+ nsyms
* 4;
2337 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2338 sym_index
= find_elf_sym(symtab_section
, p
);
2340 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2341 if(sym
->st_shndx
== SHN_UNDEF
) {
2342 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2344 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2347 lseek(fd
, off
, SEEK_SET
);
2348 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2363 /* load a '.a' file */
2364 static int tcc_load_archive(TCCState
*s1
, int fd
)
2371 unsigned long file_offset
;
2373 /* skip magic which was already checked */
2374 read(fd
, magic
, sizeof(magic
));
2377 len
= read(fd
, &hdr
, sizeof(hdr
));
2380 if (len
!= sizeof(hdr
)) {
2381 error_noabort("invalid archive");
2384 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2385 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2386 size
= strtol(ar_size
, NULL
, 0);
2387 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2388 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2389 if (ar_name
[i
] != ' ')
2392 ar_name
[i
+ 1] = '\0';
2393 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2394 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2396 size
= (size
+ 1) & ~1;
2397 if (!strcmp(ar_name
, "/")) {
2398 /* coff symbol table : we handle it */
2399 if(s1
->alacarte_link
)
2400 return tcc_load_alacarte(s1
, fd
, size
);
2401 } else if (!strcmp(ar_name
, "//") ||
2402 !strcmp(ar_name
, "__.SYMDEF") ||
2403 !strcmp(ar_name
, "__.SYMDEF/") ||
2404 !strcmp(ar_name
, "ARFILENAMES/")) {
2405 /* skip symbol table or archive names */
2407 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2410 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2415 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2416 is referenced by the user (so it should be added as DT_NEEDED in
2417 the generated ELF file) */
2418 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2421 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2422 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2423 ElfW(Sym
) *sym
, *dynsym
;
2424 ElfW(Dyn
) *dt
, *dynamic
;
2425 unsigned char *dynstr
;
2426 const char *name
, *soname
;
2427 DLLReference
*dllref
;
2429 read(fd
, &ehdr
, sizeof(ehdr
));
2431 /* test CPU specific stuff */
2432 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2433 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2434 error_noabort("bad architecture");
2439 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2441 /* load dynamic section and dynamic symbols */
2445 dynsym
= NULL
; /* avoid warning */
2446 dynstr
= NULL
; /* avoid warning */
2447 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2448 switch(sh
->sh_type
) {
2450 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2451 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2454 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2455 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2456 sh1
= &shdr
[sh
->sh_link
];
2457 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2464 /* compute the real library name */
2465 soname
= tcc_basename(filename
);
2467 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2468 if (dt
->d_tag
== DT_SONAME
) {
2469 soname
= dynstr
+ dt
->d_un
.d_val
;
2473 /* if the dll is already loaded, do not load it */
2474 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2475 dllref
= s1
->loaded_dlls
[i
];
2476 if (!strcmp(soname
, dllref
->name
)) {
2477 /* but update level if needed */
2478 if (level
< dllref
->level
)
2479 dllref
->level
= level
;
2485 // printf("loading dll '%s'\n", soname);
2487 /* add the dll and its level */
2488 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2489 dllref
->level
= level
;
2490 strcpy(dllref
->name
, soname
);
2491 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2493 /* add dynamic symbols in dynsym_section */
2494 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2495 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2496 if (sym_bind
== STB_LOCAL
)
2498 name
= dynstr
+ sym
->st_name
;
2499 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2500 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2503 /* load all referenced DLLs */
2504 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2507 name
= dynstr
+ dt
->d_un
.d_val
;
2508 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2509 dllref
= s1
->loaded_dlls
[j
];
2510 if (!strcmp(name
, dllref
->name
))
2511 goto already_loaded
;
2513 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2514 error_noabort("referenced dll '%s' not found", name
);
2531 #define LD_TOK_NAME 256
2532 #define LD_TOK_EOF (-1)
2534 /* return next ld script token */
2535 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2553 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2554 ch
= file
->buf_ptr
[0];
2562 /* case 'a' ... 'z': */
2589 /* case 'A' ... 'z': */
2624 if (!((ch
>= 'a' && ch
<= 'z') ||
2625 (ch
>= 'A' && ch
<= 'Z') ||
2626 (ch
>= '0' && ch
<= '9') ||
2627 strchr("/.-_+=$:\\,~", ch
)))
2629 if ((q
- name
) < name_size
- 1) {
2646 printf("tok=%c %d\n", c
, c
);
2647 if (c
== LD_TOK_NAME
)
2648 printf(" name=%s\n", name
);
2653 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2655 char filename
[1024];
2658 t
= ld_next(s1
, filename
, sizeof(filename
));
2661 t
= ld_next(s1
, filename
, sizeof(filename
));
2663 if (t
== LD_TOK_EOF
) {
2664 error_noabort("unexpected end of file");
2666 } else if (t
== ')') {
2668 } else if (t
!= LD_TOK_NAME
) {
2669 error_noabort("filename expected");
2672 if (!strcmp(filename
, "AS_NEEDED")) {
2673 ret
= ld_add_file_list(s1
, 1);
2677 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2679 tcc_add_file(s1
, filename
);
2681 t
= ld_next(s1
, filename
, sizeof(filename
));
2683 t
= ld_next(s1
, filename
, sizeof(filename
));
2689 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2691 static int tcc_load_ldscript(TCCState
*s1
)
2694 char filename
[1024];
2697 ch
= file
->buf_ptr
[0];
2700 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2701 if (t
== LD_TOK_EOF
)
2703 else if (t
!= LD_TOK_NAME
)
2705 if (!strcmp(cmd
, "INPUT") ||
2706 !strcmp(cmd
, "GROUP")) {
2707 ret
= ld_add_file_list(s1
, 0);
2710 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2711 !strcmp(cmd
, "TARGET")) {
2712 /* ignore some commands */
2713 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2717 t
= ld_next(s1
, filename
, sizeof(filename
));
2718 if (t
== LD_TOK_EOF
) {
2719 error_noabort("unexpected end of file");
2721 } else if (t
== ')') {