2 * ELF file handling for TCC
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #ifdef TCC_TARGET_X86_64
22 #define ElfW_Rel ElfW(Rela)
23 #define SHT_RELX SHT_RELA
24 #define REL_SECTION_FMT ".rela%s"
25 /* x86-64 requires PLT for DLLs */
26 #define TCC_OUTPUT_DLL_WITH_PLT
28 #define ElfW_Rel ElfW(Rel)
29 #define SHT_RELX SHT_REL
30 #define REL_SECTION_FMT ".rel%s"
33 /* XXX: DLL with PLT would only work with x86-64 for now */
34 //#define TCC_OUTPUT_DLL_WITH_PLT
36 static int put_elf_str(Section
*s
, const char *sym
)
41 len
= strlen(sym
) + 1;
42 offset
= s
->data_offset
;
43 ptr
= section_ptr_add(s
, len
);
44 memcpy(ptr
, sym
, len
);
48 /* elf symbol hashing function */
49 static unsigned long elf_hash(const unsigned char *name
)
51 unsigned long h
= 0, g
;
54 h
= (h
<< 4) + *name
++;
63 /* rebuild hash table of section s */
64 /* NOTE: we do factorize the hash table code to go faster */
65 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
68 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
71 strtab
= s
->link
->data
;
72 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
74 s
->hash
->data_offset
= 0;
75 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
80 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
81 ptr
+= nb_buckets
+ 1;
83 sym
= (ElfW(Sym
) *)s
->data
+ 1;
84 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
85 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
86 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
97 /* return the symbol number */
98 static int put_elf_sym(Section
*s
,
99 unsigned long value
, unsigned long size
,
100 int info
, int other
, int shndx
, const char *name
)
102 int name_offset
, sym_index
;
107 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
109 name_offset
= put_elf_str(s
->link
, name
);
112 /* XXX: endianness */
113 sym
->st_name
= name_offset
;
114 sym
->st_value
= value
;
117 sym
->st_other
= other
;
118 sym
->st_shndx
= shndx
;
119 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
123 ptr
= section_ptr_add(hs
, sizeof(int));
124 base
= (int *)hs
->data
;
125 /* only add global or weak symbols */
126 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
127 /* add another hashing entry */
129 h
= elf_hash(name
) % nbuckets
;
131 base
[2 + h
] = sym_index
;
133 /* we resize the hash table */
134 hs
->nb_hashed_syms
++;
135 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
136 rebuild_hash(s
, 2 * nbuckets
);
146 /* find global ELF symbol 'name' and return its index. Return 0 if not
148 static int find_elf_sym(Section
*s
, const char *name
)
152 int nbuckets
, sym_index
, h
;
158 nbuckets
= ((int *)hs
->data
)[0];
159 h
= elf_hash(name
) % nbuckets
;
160 sym_index
= ((int *)hs
->data
)[2 + h
];
161 while (sym_index
!= 0) {
162 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
163 name1
= s
->link
->data
+ sym
->st_name
;
164 if (!strcmp(name
, name1
))
166 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
171 /* return elf symbol value or error */
172 void *tcc_get_symbol(TCCState
*s
, const char *name
)
176 sym_index
= find_elf_sym(symtab_section
, name
);
179 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
180 return (void*)(long)sym
->st_value
;
183 void *tcc_get_symbol_err(TCCState
*s
, const char *name
)
186 sym
= tcc_get_symbol(s
, name
);
188 error("%s not defined", name
);
192 /* add an elf symbol : check if it is already defined and patch
193 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
194 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
195 int info
, int other
, int sh_num
, const char *name
)
198 int sym_bind
, sym_index
, sym_type
, esym_bind
;
199 unsigned char sym_vis
, esym_vis
, new_vis
;
201 sym_bind
= ELFW(ST_BIND
)(info
);
202 sym_type
= ELFW(ST_TYPE
)(info
);
203 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
205 if (sym_bind
!= STB_LOCAL
) {
206 /* we search global or weak symbols */
207 sym_index
= find_elf_sym(s
, name
);
210 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
211 if (esym
->st_shndx
!= SHN_UNDEF
) {
212 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
213 /* propagate the most constraining visibility */
214 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
215 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
216 if (esym_vis
== STV_DEFAULT
) {
218 } else if (sym_vis
== STV_DEFAULT
) {
221 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
223 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
225 other
= esym
->st_other
; /* in case we have to patch esym */
226 if (sh_num
== SHN_UNDEF
) {
227 /* ignore adding of undefined symbol if the
228 corresponding symbol is already defined */
229 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
230 /* global overrides weak, so patch */
232 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
233 /* weak is ignored if already global */
234 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
235 /* ignore hidden symbols after */
236 } else if (esym
->st_shndx
== SHN_COMMON
&& 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
;
512 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
517 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
518 qrel
= (ElfW_Rel
*)sr
->data
;
522 ptr
= s
->data
+ rel
->r_offset
;
524 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
525 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
527 #ifdef TCC_TARGET_X86_64
528 /* XXX: not tested */
529 val
+= rel
->r_addend
;
531 type
= ELFW(R_TYPE
)(rel
->r_info
);
532 addr
= s
->sh_addr
+ rel
->r_offset
;
536 #if defined(TCC_TARGET_I386)
538 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
539 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
540 qrel
->r_offset
= rel
->r_offset
;
542 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_32
);
546 qrel
->r_info
= ELFW(R_INFO
)(0, R_386_RELATIVE
);
553 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
555 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
557 qrel
->r_offset
= rel
->r_offset
;
558 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_PC32
);
563 *(int *)ptr
+= val
- addr
;
566 *(int *)ptr
+= val
- addr
;
573 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
576 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
579 /* we load the got offset */
580 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
582 #elif defined(TCC_TARGET_ARM)
589 x
= (*(int *)ptr
)&0xffffff;
590 (*(int *)ptr
) &= 0xff000000;
595 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
596 error("can't relocate value at %x",addr
);
605 x
= (*(int *)ptr
) & 0x7fffffff;
606 (*(int *)ptr
) &= 0x80000000;
609 if((x
^(x
>>1))&0x40000000)
610 error("can't relocate value at %x",addr
);
611 (*(int *)ptr
) |= x
& 0x7fffffff;
616 case R_ARM_BASE_PREL
:
617 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
620 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
623 /* we load the got offset */
624 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
629 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
630 type
,addr
,(unsigned int )ptr
,val
);
632 #elif defined(TCC_TARGET_C67)
640 /* put the low 16 bits of the absolute address */
641 // add to what is already there
643 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
644 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
646 //patch both at once - assumes always in pairs Low - High
648 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
649 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
655 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
656 type
,addr
,(unsigned int )ptr
,val
);
658 #elif defined(TCC_TARGET_X86_64)
660 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
661 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
662 qrel
->r_addend
= *(long long *)ptr
+ val
;
665 *(long long *)ptr
+= val
;
669 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
670 /* XXX: this logic may depend on TCC's codegen
671 now TCC uses R_X86_64_32 even for a 64bit pointer */
672 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
673 qrel
->r_addend
= *(int *)ptr
+ val
;
678 case R_X86_64_PC32
: {
679 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
681 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
683 qrel
->r_offset
= rel
->r_offset
;
684 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_X86_64_PC32
);
685 qrel
->r_addend
= *(int *)ptr
;
690 long diff
= val
- addr
;
691 if (diff
<= -2147483647 || diff
> 2147483647) {
692 /* XXX: naive support for over 32bit jump */
693 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
694 val
= add_jmp_table(s1
, val
);
697 if (diff
<= -2147483647 || diff
> 2147483647) {
698 error("internal error: relocation failed");
705 *(int *)ptr
+= val
- addr
;
707 case R_X86_64_GLOB_DAT
:
708 case R_X86_64_JUMP_SLOT
:
711 case R_X86_64_GOTPCREL
:
712 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
713 val
= add_got_table(s1
, val
- rel
->r_addend
) + rel
->r_addend
;
714 *(int *)ptr
+= val
- addr
;
717 *(int *)ptr
+= (s1
->got
->sh_addr
- addr
+
718 s1
->got_offsets
[sym_index
] - 4);
720 case R_X86_64_GOTTPOFF
:
721 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
724 /* we load the got offset */
725 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
728 #error unsupported processor
732 /* if the relocation is allocated, we change its symbol table */
733 if (sr
->sh_flags
& SHF_ALLOC
)
734 sr
->link
= s1
->dynsym
;
737 /* relocate relocation table in 'sr' */
738 static void relocate_rel(TCCState
*s1
, Section
*sr
)
741 ElfW_Rel
*rel
, *rel_end
;
743 s
= s1
->sections
[sr
->sh_info
];
744 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
745 for(rel
= (ElfW_Rel
*)sr
->data
;
748 rel
->r_offset
+= s
->sh_addr
;
752 /* count the number of dynamic relocations so that we can reserve
754 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
756 ElfW_Rel
*rel
, *rel_end
;
757 int sym_index
, esym_index
, type
, count
;
760 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
761 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
762 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
763 type
= ELFW(R_TYPE
)(rel
->r_info
);
765 #if defined(TCC_TARGET_I386)
767 #elif defined(TCC_TARGET_X86_64)
774 #if defined(TCC_TARGET_I386)
776 #elif defined(TCC_TARGET_X86_64)
779 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
788 /* allocate the section */
789 sr
->sh_flags
|= SHF_ALLOC
;
790 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
795 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
800 if (index
>= s1
->nb_got_offsets
) {
801 /* find immediately bigger power of 2 and reallocate array */
805 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
807 error("memory full");
808 s1
->got_offsets
= tab
;
809 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
810 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
811 s1
->nb_got_offsets
= n
;
813 s1
->got_offsets
[index
] = val
;
816 /* XXX: suppress that */
817 static void put32(unsigned char *p
, uint32_t val
)
825 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
826 defined(TCC_TARGET_X86_64)
827 static uint32_t get32(unsigned char *p
)
829 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
833 static void build_got(TCCState
*s1
)
837 /* if no got, then create it */
838 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
839 s1
->got
->sh_entsize
= 4;
840 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
841 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
842 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
844 /* keep space for _DYNAMIC pointer, if present */
846 /* two dummy got entries */
850 /* keep space for _DYNAMIC pointer, if present */
853 /* two dummy got entries */
861 /* put a got entry corresponding to a symbol in symtab_section. 'size'
862 and 'info' can be modifed if more precise info comes from the DLL */
863 static void put_got_entry(TCCState
*s1
,
864 int reloc_type
, unsigned long size
, int info
,
870 unsigned long offset
;
876 /* if a got entry already exists for that symbol, no need to add one */
877 if (sym_index
< s1
->nb_got_offsets
&&
878 s1
->got_offsets
[sym_index
] != 0)
881 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
884 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
885 name
= symtab_section
->link
->data
+ sym
->st_name
;
886 offset
= sym
->st_value
;
887 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
889 #ifdef TCC_TARGET_X86_64
899 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
902 /* if we build a DLL, we add a %ebx offset */
903 if (s1
->output_type
== TCC_OUTPUT_DLL
)
909 /* add a PLT entry */
911 if (plt
->data_offset
== 0) {
912 /* first plt entry */
913 p
= section_ptr_add(plt
, 16);
914 p
[0] = 0xff; /* pushl got + PTR_SIZE */
916 put32(p
+ 2, PTR_SIZE
);
917 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
919 put32(p
+ 8, PTR_SIZE
* 2);
922 p
= section_ptr_add(plt
, 16);
923 p
[0] = 0xff; /* jmp *(got + x) */
925 put32(p
+ 2, s1
->got
->data_offset
);
926 p
[6] = 0x68; /* push $xxx */
927 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
928 p
[11] = 0xe9; /* jmp plt_start */
929 put32(p
+ 12, -(plt
->data_offset
));
931 /* the symbol is modified so that it will be relocated to
933 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
934 if (s1
->output_type
== TCC_OUTPUT_EXE
)
936 offset
= plt
->data_offset
- 16;
938 #elif defined(TCC_TARGET_ARM)
939 if (reloc_type
== R_ARM_JUMP_SLOT
) {
943 /* if we build a DLL, we add a %ebx offset */
944 if (s1
->output_type
== TCC_OUTPUT_DLL
)
945 error("DLLs unimplemented!");
947 /* add a PLT entry */
949 if (plt
->data_offset
== 0) {
950 /* first plt entry */
951 p
= section_ptr_add(plt
, 16);
952 put32(p
, 0xe52de004);
953 put32(p
+ 4, 0xe59fe010);
954 put32(p
+ 8, 0xe08fe00e);
955 put32(p
+ 12, 0xe5bef008);
958 p
= section_ptr_add(plt
, 16);
959 put32(p
, 0xe59fc004);
960 put32(p
+4, 0xe08fc00c);
961 put32(p
+8, 0xe59cf000);
962 put32(p
+12, s1
->got
->data_offset
);
964 /* the symbol is modified so that it will be relocated to
966 if (s1
->output_type
== TCC_OUTPUT_EXE
)
967 offset
= plt
->data_offset
- 16;
969 #elif defined(TCC_TARGET_C67)
970 error("C67 got not implemented");
972 #error unsupported CPU
974 index
= put_elf_sym(s1
->dynsym
, offset
,
975 size
, info
, 0, sym
->st_shndx
, name
);
976 /* put a got entry */
977 put_elf_reloc(s1
->dynsym
, s1
->got
,
978 s1
->got
->data_offset
,
981 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
985 /* build GOT and PLT entries */
986 static void build_got_entries(TCCState
*s1
)
989 ElfW_Rel
*rel
, *rel_end
;
991 int i
, type
, reloc_type
, sym_index
;
993 for(i
= 1; i
< s1
->nb_sections
; i
++) {
995 if (s
->sh_type
!= SHT_RELX
)
997 /* no need to handle got relocations */
998 if (s
->link
!= symtab_section
)
1001 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
1002 for(rel
= (ElfW_Rel
*)s
->data
;
1005 type
= ELFW(R_TYPE
)(rel
->r_info
);
1007 #if defined(TCC_TARGET_I386)
1014 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1015 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1016 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1017 /* look at the symbol got offset. If none, then add one */
1018 if (type
== R_386_GOT32
)
1019 reloc_type
= R_386_GLOB_DAT
;
1021 reloc_type
= R_386_JMP_SLOT
;
1022 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1026 #elif defined(TCC_TARGET_ARM)
1027 case R_ARM_GOT_BREL
:
1028 case R_ARM_GOTOFF32
:
1029 case R_ARM_BASE_PREL
:
1033 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1034 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1035 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1036 /* look at the symbol got offset. If none, then add one */
1037 if (type
== R_ARM_GOT_BREL
)
1038 reloc_type
= R_ARM_GLOB_DAT
;
1040 reloc_type
= R_ARM_JUMP_SLOT
;
1041 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1045 #elif defined(TCC_TARGET_C67)
1052 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1053 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1054 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1055 /* look at the symbol got offset. If none, then add one */
1056 if (type
== R_C60_GOT32
)
1057 reloc_type
= R_C60_GLOB_DAT
;
1059 reloc_type
= R_C60_JMP_SLOT
;
1060 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1064 #elif defined(TCC_TARGET_X86_64)
1065 case R_X86_64_GOT32
:
1066 case R_X86_64_GOTTPOFF
:
1067 case R_X86_64_GOTPCREL
:
1068 case R_X86_64_PLT32
:
1071 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
||
1072 type
== R_X86_64_PLT32
) {
1073 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1074 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1075 /* look at the symbol got offset. If none, then add one */
1076 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
)
1077 reloc_type
= R_X86_64_GLOB_DAT
;
1079 reloc_type
= R_X86_64_JUMP_SLOT
;
1080 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1085 #error unsupported CPU
1094 static Section
*new_symtab(TCCState
*s1
,
1095 const char *symtab_name
, int sh_type
, int sh_flags
,
1096 const char *strtab_name
,
1097 const char *hash_name
, int hash_sh_flags
)
1099 Section
*symtab
, *strtab
, *hash
;
1100 int *ptr
, nb_buckets
;
1102 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1103 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1104 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1105 put_elf_str(strtab
, "");
1106 symtab
->link
= strtab
;
1107 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1111 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1112 hash
->sh_entsize
= sizeof(int);
1113 symtab
->hash
= hash
;
1114 hash
->link
= symtab
;
1116 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1117 ptr
[0] = nb_buckets
;
1119 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1123 /* put dynamic tag */
1124 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1127 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1129 dyn
->d_un
.d_val
= val
;
1132 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1136 char sym_start
[1024];
1139 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1140 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1142 s
= find_section(s1
, section_name
);
1147 end_offset
= s
->data_offset
;
1150 add_elf_sym(symtab_section
,
1152 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1153 s
->sh_num
, sym_start
);
1154 add_elf_sym(symtab_section
,
1156 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1157 s
->sh_num
, sym_end
);
1160 /* add tcc runtime libraries */
1161 static void tcc_add_runtime(TCCState
*s1
)
1163 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1167 #ifdef CONFIG_TCC_BCHECK
1168 if (s1
->do_bounds_check
) {
1170 Section
*init_section
;
1171 unsigned char *pinit
;
1174 /* XXX: add an object file to do that */
1175 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1177 add_elf_sym(symtab_section
, 0, 0,
1178 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1179 bounds_section
->sh_num
, "__bounds_start");
1180 /* add bound check code */
1181 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "bcheck.o");
1182 tcc_add_file(s1
, buf
);
1183 #ifdef TCC_TARGET_I386
1184 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1185 /* add 'call __bound_init()' in .init section */
1186 init_section
= find_section(s1
, ".init");
1187 pinit
= section_ptr_add(init_section
, 5);
1189 put32(pinit
+ 1, -4);
1190 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1191 put_elf_reloc(symtab_section
, init_section
,
1192 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1198 if (!s1
->nostdlib
) {
1199 tcc_add_library(s1
, "c");
1201 #ifdef CONFIG_USE_LIBGCC
1202 tcc_add_file(s1
, CONFIG_SYSROOT
"/lib/libgcc_s.so.1");
1204 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "libtcc1.a");
1205 tcc_add_file(s1
, buf
);
1208 /* add crt end if not memory output */
1209 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1210 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1214 /* add various standard linker symbols (must be done after the
1215 sections are filled (for example after allocating common
1217 static void tcc_add_linker_symbols(TCCState
*s1
)
1223 add_elf_sym(symtab_section
,
1224 text_section
->data_offset
, 0,
1225 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1226 text_section
->sh_num
, "_etext");
1227 add_elf_sym(symtab_section
,
1228 data_section
->data_offset
, 0,
1229 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1230 data_section
->sh_num
, "_edata");
1231 add_elf_sym(symtab_section
,
1232 bss_section
->data_offset
, 0,
1233 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1234 bss_section
->sh_num
, "_end");
1235 /* horrible new standard ldscript defines */
1236 add_init_array_defines(s1
, ".preinit_array");
1237 add_init_array_defines(s1
, ".init_array");
1238 add_init_array_defines(s1
, ".fini_array");
1240 /* add start and stop symbols for sections whose name can be
1242 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1243 s
= s1
->sections
[i
];
1244 if (s
->sh_type
== SHT_PROGBITS
&&
1245 (s
->sh_flags
& SHF_ALLOC
)) {
1249 /* check if section name can be expressed in C */
1255 if (!isid(ch
) && !isnum(ch
))
1259 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1260 add_elf_sym(symtab_section
,
1262 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1264 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1265 add_elf_sym(symtab_section
,
1267 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1274 /* name of ELF interpreter */
1276 static char elf_interp
[] = "/usr/libexec/ld-elf.so.1";
1279 static char elf_interp
[] = "/lib/ld-linux.so.3";
1280 #elif defined(TCC_TARGET_X86_64)
1281 static char elf_interp
[] = "/lib/ld-linux-x86-64.so.2";
1283 static char elf_interp
[] = "/lib/ld-linux.so.2";
1287 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1288 const int *section_order
)
1291 int i
, offset
, size
;
1294 for(i
=1;i
<s1
->nb_sections
;i
++) {
1295 s
= s1
->sections
[section_order
[i
]];
1296 if (s
->sh_type
!= SHT_NOBITS
&&
1297 (s
->sh_flags
& SHF_ALLOC
)) {
1298 while (offset
< s
->sh_offset
) {
1303 fwrite(s
->data
, 1, size
, f
);
1309 /* output an ELF file */
1310 /* XXX: suppress unneeded sections */
1311 int elf_output_file(TCCState
*s1
, const char *filename
)
1317 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1319 Section
*strsec
, *s
;
1320 ElfW(Shdr
) shdr
, *sh
;
1321 ElfW(Phdr
) *phdr
, *ph
;
1322 Section
*interp
, *dynamic
, *dynstr
;
1323 unsigned long saved_dynamic_data_offset
;
1325 int type
, file_type
;
1326 unsigned long rel_addr
, rel_size
;
1328 file_type
= s1
->output_type
;
1331 if (file_type
!= TCC_OUTPUT_OBJ
) {
1332 tcc_add_runtime(s1
);
1336 section_order
= NULL
;
1339 dynstr
= NULL
; /* avoid warning */
1340 saved_dynamic_data_offset
= 0; /* avoid warning */
1342 if (file_type
!= TCC_OUTPUT_OBJ
) {
1343 relocate_common_syms();
1345 tcc_add_linker_symbols(s1
);
1347 if (!s1
->static_link
) {
1349 int sym_index
, index
;
1350 ElfW(Sym
) *esym
, *sym_end
;
1352 if (file_type
== TCC_OUTPUT_EXE
) {
1354 /* add interpreter section only if executable */
1355 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1356 interp
->sh_addralign
= 1;
1357 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
1358 strcpy(ptr
, elf_interp
);
1361 /* add dynamic symbol table */
1362 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1364 ".hash", SHF_ALLOC
);
1365 dynstr
= s1
->dynsym
->link
;
1367 /* add dynamic section */
1368 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1369 SHF_ALLOC
| SHF_WRITE
);
1370 dynamic
->link
= dynstr
;
1371 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1374 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1375 SHF_ALLOC
| SHF_EXECINSTR
);
1376 s1
->plt
->sh_entsize
= 4;
1380 /* scan for undefined symbols and see if they are in the
1381 dynamic symbols. If a symbol STT_FUNC is found, then we
1382 add it in the PLT. If a symbol STT_OBJECT is found, we
1383 add it in the .bss section with a suitable relocation */
1384 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1385 symtab_section
->data_offset
);
1386 if (file_type
== TCC_OUTPUT_EXE
) {
1387 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1390 if (sym
->st_shndx
== SHN_UNDEF
) {
1391 name
= symtab_section
->link
->data
+ sym
->st_name
;
1392 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1394 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1395 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1396 if (type
== STT_FUNC
) {
1397 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1399 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1400 } else if (type
== STT_OBJECT
) {
1401 unsigned long offset
;
1402 offset
= bss_section
->data_offset
;
1403 /* XXX: which alignment ? */
1404 offset
= (offset
+ 16 - 1) & -16;
1405 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1407 bss_section
->sh_num
, name
);
1408 put_elf_reloc(s1
->dynsym
, bss_section
,
1409 offset
, R_COPY
, index
);
1410 offset
+= esym
->st_size
;
1411 bss_section
->data_offset
= offset
;
1414 /* STB_WEAK undefined symbols are accepted */
1415 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1417 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1418 !strcmp(name
, "_fp_hw")) {
1420 error_noabort("undefined symbol '%s'", name
);
1423 } else if (s1
->rdynamic
&&
1424 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1425 /* if -rdynamic option, then export all non
1427 name
= symtab_section
->link
->data
+ sym
->st_name
;
1428 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1430 sym
->st_shndx
, name
);
1437 /* now look at unresolved dynamic symbols and export
1438 corresponding symbol */
1439 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1440 s1
->dynsymtab_section
->data_offset
);
1441 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1444 if (esym
->st_shndx
== SHN_UNDEF
) {
1445 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1446 sym_index
= find_elf_sym(symtab_section
, name
);
1448 /* XXX: avoid adding a symbol if already
1449 present because of -rdynamic ? */
1450 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1451 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1453 sym
->st_shndx
, name
);
1455 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1456 /* weak symbols can stay undefined */
1458 warning("undefined dynamic symbol '%s'", name
);
1465 /* shared library case : we simply export all the global symbols */
1466 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1467 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1468 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1471 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1472 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1473 if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
&&
1474 sym
->st_shndx
== SHN_UNDEF
) {
1475 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1477 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1479 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1480 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1482 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1487 name
= symtab_section
->link
->data
+ sym
->st_name
;
1488 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1490 sym
->st_shndx
, name
);
1491 s1
->symtab_to_dynsym
[sym
-
1492 (ElfW(Sym
) *)symtab_section
->data
] =
1499 build_got_entries(s1
);
1501 /* add a list of needed dlls */
1502 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1503 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1504 if (dllref
->level
== 0)
1505 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1507 /* XXX: currently, since we do not handle PIC code, we
1508 must relocate the readonly segments */
1509 if (file_type
== TCC_OUTPUT_DLL
) {
1511 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1512 put_dt(dynamic
, DT_TEXTREL
, 0);
1515 /* add necessary space for other entries */
1516 saved_dynamic_data_offset
= dynamic
->data_offset
;
1517 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * 9;
1519 /* still need to build got entries in case of static link */
1520 build_got_entries(s1
);
1524 memset(&ehdr
, 0, sizeof(ehdr
));
1526 /* we add a section for symbols */
1527 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1528 put_elf_str(strsec
, "");
1530 /* compute number of sections */
1531 shnum
= s1
->nb_sections
;
1533 /* this array is used to reorder sections in the output file */
1534 section_order
= tcc_malloc(sizeof(int) * shnum
);
1535 section_order
[0] = 0;
1538 /* compute number of program headers */
1541 case TCC_OUTPUT_OBJ
:
1544 case TCC_OUTPUT_EXE
:
1545 if (!s1
->static_link
)
1550 case TCC_OUTPUT_DLL
:
1555 /* allocate strings for section names and decide if an unallocated
1556 section should be output */
1557 /* NOTE: the strsec section comes last, so its size is also
1559 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1560 s
= s1
->sections
[i
];
1561 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1563 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1568 s
->reloc
? s
->reloc
->name
: "n"
1571 /* when generating a DLL, we include relocations but we may
1573 if (file_type
== TCC_OUTPUT_DLL
&&
1574 s
->sh_type
== SHT_RELX
&&
1575 !(s
->sh_flags
& SHF_ALLOC
)) {
1576 /* //gr: avoid bogus relocs for empty (debug) sections */
1577 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1578 prepare_dynamic_rel(s1
, s
);
1579 else if (s1
->do_debug
)
1580 s
->sh_size
= s
->data_offset
;
1581 } else if (s1
->do_debug
||
1582 file_type
== TCC_OUTPUT_OBJ
||
1583 (s
->sh_flags
& SHF_ALLOC
) ||
1584 i
== (s1
->nb_sections
- 1)) {
1585 /* we output all sections if debug or object file */
1586 s
->sh_size
= s
->data_offset
;
1590 /* allocate program segment headers */
1591 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1593 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1594 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1599 /* compute section to program header mapping */
1600 if (s1
->has_text_addr
) {
1601 int a_offset
, p_offset
;
1602 addr
= s1
->text_addr
;
1603 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1605 a_offset
= addr
& (ELF_PAGE_SIZE
- 1);
1606 p_offset
= file_offset
& (ELF_PAGE_SIZE
- 1);
1607 if (a_offset
< p_offset
)
1608 a_offset
+= ELF_PAGE_SIZE
;
1609 file_offset
+= (a_offset
- p_offset
);
1611 if (file_type
== TCC_OUTPUT_DLL
)
1614 addr
= ELF_START_ADDR
;
1615 /* compute address after headers */
1616 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1619 /* dynamic relocation table information, for .dynamic section */
1623 /* leave one program header for the program interpreter */
1628 for(j
= 0; j
< 2; j
++) {
1629 ph
->p_type
= PT_LOAD
;
1631 ph
->p_flags
= PF_R
| PF_X
;
1633 ph
->p_flags
= PF_R
| PF_W
;
1634 ph
->p_align
= ELF_PAGE_SIZE
;
1636 /* we do the following ordering: interp, symbol tables,
1637 relocations, progbits, nobits */
1638 /* XXX: do faster and simpler sorting */
1639 for(k
= 0; k
< 5; k
++) {
1640 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1641 s
= s1
->sections
[i
];
1642 /* compute if section should be included */
1644 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1648 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1649 (SHF_ALLOC
| SHF_WRITE
))
1655 } else if (s
->sh_type
== SHT_DYNSYM
||
1656 s
->sh_type
== SHT_STRTAB
||
1657 s
->sh_type
== SHT_HASH
) {
1660 } else if (s
->sh_type
== SHT_RELX
) {
1663 } else if (s
->sh_type
== SHT_NOBITS
) {
1670 section_order
[sh_order_index
++] = i
;
1672 /* section matches: we align it and add its size */
1674 addr
= (addr
+ s
->sh_addralign
- 1) &
1675 ~(s
->sh_addralign
- 1);
1676 file_offset
+= addr
- tmp
;
1677 s
->sh_offset
= file_offset
;
1680 /* update program header infos */
1681 if (ph
->p_offset
== 0) {
1682 ph
->p_offset
= file_offset
;
1684 ph
->p_paddr
= ph
->p_vaddr
;
1686 /* update dynamic relocation infos */
1687 if (s
->sh_type
== SHT_RELX
) {
1690 rel_size
+= s
->sh_size
;
1693 if (s
->sh_type
!= SHT_NOBITS
)
1694 file_offset
+= s
->sh_size
;
1697 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1698 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1701 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1702 /* if in the middle of a page, we duplicate the page in
1703 memory so that one copy is RX and the other is RW */
1704 if ((addr
& (ELF_PAGE_SIZE
- 1)) != 0)
1705 addr
+= ELF_PAGE_SIZE
;
1707 addr
= (addr
+ ELF_PAGE_SIZE
- 1) & ~(ELF_PAGE_SIZE
- 1);
1708 file_offset
= (file_offset
+ ELF_PAGE_SIZE
- 1) &
1709 ~(ELF_PAGE_SIZE
- 1);
1714 /* if interpreter, then add corresponing program header */
1718 ph
->p_type
= PT_INTERP
;
1719 ph
->p_offset
= interp
->sh_offset
;
1720 ph
->p_vaddr
= interp
->sh_addr
;
1721 ph
->p_paddr
= ph
->p_vaddr
;
1722 ph
->p_filesz
= interp
->sh_size
;
1723 ph
->p_memsz
= interp
->sh_size
;
1725 ph
->p_align
= interp
->sh_addralign
;
1728 /* if dynamic section, then add corresponing program header */
1732 ph
= &phdr
[phnum
- 1];
1734 ph
->p_type
= PT_DYNAMIC
;
1735 ph
->p_offset
= dynamic
->sh_offset
;
1736 ph
->p_vaddr
= dynamic
->sh_addr
;
1737 ph
->p_paddr
= ph
->p_vaddr
;
1738 ph
->p_filesz
= dynamic
->sh_size
;
1739 ph
->p_memsz
= dynamic
->sh_size
;
1740 ph
->p_flags
= PF_R
| PF_W
;
1741 ph
->p_align
= dynamic
->sh_addralign
;
1743 /* put GOT dynamic section address */
1744 put32(s1
->got
->data
, dynamic
->sh_addr
);
1746 /* relocate the PLT */
1747 if (file_type
== TCC_OUTPUT_EXE
1748 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1749 || file_type
== TCC_OUTPUT_DLL
1755 p_end
= p
+ s1
->plt
->data_offset
;
1757 #if defined(TCC_TARGET_I386)
1758 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1759 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1762 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1765 #elif defined(TCC_TARGET_X86_64)
1766 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1767 put32(p
+ 2, get32(p
+ 2) + x
);
1768 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1771 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1774 #elif defined(TCC_TARGET_ARM)
1776 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1779 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1782 #elif defined(TCC_TARGET_C67)
1785 #error unsupported CPU
1790 /* relocate symbols in .dynsym */
1791 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1792 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1795 if (sym
->st_shndx
== SHN_UNDEF
) {
1796 /* relocate to the PLT if the symbol corresponds
1799 sym
->st_value
+= s1
->plt
->sh_addr
;
1800 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1801 /* do symbol relocation */
1802 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1806 /* put dynamic section entries */
1807 dynamic
->data_offset
= saved_dynamic_data_offset
;
1808 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1809 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1810 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1811 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1812 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1813 #ifdef TCC_TARGET_X86_64
1814 put_dt(dynamic
, DT_RELA
, rel_addr
);
1815 put_dt(dynamic
, DT_RELASZ
, rel_size
);
1816 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1818 put_dt(dynamic
, DT_REL
, rel_addr
);
1819 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1820 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1823 put_dt(dynamic
, DT_DEBUG
, 0);
1824 put_dt(dynamic
, DT_NULL
, 0);
1827 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1828 ehdr
.e_phnum
= phnum
;
1829 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1832 /* all other sections come after */
1833 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1834 s
= s1
->sections
[i
];
1835 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1837 section_order
[sh_order_index
++] = i
;
1839 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1840 ~(s
->sh_addralign
- 1);
1841 s
->sh_offset
= file_offset
;
1842 if (s
->sh_type
!= SHT_NOBITS
)
1843 file_offset
+= s
->sh_size
;
1846 /* if building executable or DLL, then relocate each section
1847 except the GOT which is already relocated */
1848 if (file_type
!= TCC_OUTPUT_OBJ
) {
1849 relocate_syms(s1
, 0);
1851 if (s1
->nb_errors
!= 0) {
1857 /* relocate sections */
1858 /* XXX: ignore sections with allocated relocations ? */
1859 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1860 s
= s1
->sections
[i
];
1861 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1862 relocate_section(s1
, s
);
1865 /* relocate relocation entries if the relocation tables are
1866 allocated in the executable */
1867 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1868 s
= s1
->sections
[i
];
1869 if ((s
->sh_flags
& SHF_ALLOC
) &&
1870 s
->sh_type
== SHT_RELX
) {
1871 relocate_rel(s1
, s
);
1875 /* get entry point address */
1876 if (file_type
== TCC_OUTPUT_EXE
)
1877 ehdr
.e_entry
= (unsigned long)tcc_get_symbol_err(s1
, "_start");
1879 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1882 /* write elf file */
1883 if (file_type
== TCC_OUTPUT_OBJ
)
1887 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1889 error_noabort("could not write '%s'", filename
);
1892 f
= fdopen(fd
, "wb");
1894 printf("<- %s\n", filename
);
1896 #ifdef TCC_TARGET_COFF
1897 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1898 tcc_output_coff(s1
, f
);
1901 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1902 sort_syms(s1
, symtab_section
);
1905 file_offset
= (file_offset
+ 3) & -4;
1908 ehdr
.e_ident
[0] = ELFMAG0
;
1909 ehdr
.e_ident
[1] = ELFMAG1
;
1910 ehdr
.e_ident
[2] = ELFMAG2
;
1911 ehdr
.e_ident
[3] = ELFMAG3
;
1912 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
1913 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1914 ehdr
.e_ident
[6] = EV_CURRENT
;
1916 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1918 #ifdef TCC_TARGET_ARM
1920 ehdr
.e_ident
[EI_OSABI
] = 0;
1921 ehdr
.e_flags
= 4 << 24;
1923 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
1928 case TCC_OUTPUT_EXE
:
1929 ehdr
.e_type
= ET_EXEC
;
1931 case TCC_OUTPUT_DLL
:
1932 ehdr
.e_type
= ET_DYN
;
1934 case TCC_OUTPUT_OBJ
:
1935 ehdr
.e_type
= ET_REL
;
1938 ehdr
.e_machine
= EM_TCC_TARGET
;
1939 ehdr
.e_version
= EV_CURRENT
;
1940 ehdr
.e_shoff
= file_offset
;
1941 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
1942 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
1943 ehdr
.e_shnum
= shnum
;
1944 ehdr
.e_shstrndx
= shnum
- 1;
1946 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
1947 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
1948 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1950 for(i
=1;i
<s1
->nb_sections
;i
++) {
1951 s
= s1
->sections
[section_order
[i
]];
1952 if (s
->sh_type
!= SHT_NOBITS
) {
1953 while (offset
< s
->sh_offset
) {
1958 fwrite(s
->data
, 1, size
, f
);
1963 /* output section headers */
1964 while (offset
< ehdr
.e_shoff
) {
1969 for(i
=0;i
<s1
->nb_sections
;i
++) {
1971 memset(sh
, 0, sizeof(ElfW(Shdr
)));
1972 s
= s1
->sections
[i
];
1974 sh
->sh_name
= s
->sh_name
;
1975 sh
->sh_type
= s
->sh_type
;
1976 sh
->sh_flags
= s
->sh_flags
;
1977 sh
->sh_entsize
= s
->sh_entsize
;
1978 sh
->sh_info
= s
->sh_info
;
1980 sh
->sh_link
= s
->link
->sh_num
;
1981 sh
->sh_addralign
= s
->sh_addralign
;
1982 sh
->sh_addr
= s
->sh_addr
;
1983 sh
->sh_offset
= s
->sh_offset
;
1984 sh
->sh_size
= s
->sh_size
;
1986 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
1989 tcc_output_binary(s1
, f
, section_order
);
1995 tcc_free(s1
->symtab_to_dynsym
);
1996 tcc_free(section_order
);
1998 tcc_free(s1
->got_offsets
);
2002 int tcc_output_file(TCCState
*s
, const char *filename
)
2005 #ifdef TCC_TARGET_PE
2006 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2007 ret
= pe_output_file(s
, filename
);
2011 ret
= elf_output_file(s
, filename
);
2016 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2020 data
= tcc_malloc(size
);
2021 lseek(fd
, file_offset
, SEEK_SET
);
2022 read(fd
, data
, size
);
2026 typedef struct SectionMergeInfo
{
2027 Section
*s
; /* corresponding existing section */
2028 unsigned long offset
; /* offset of the new section in the existing section */
2029 uint8_t new_section
; /* true if section 's' was added */
2030 uint8_t link_once
; /* true if link once section */
2033 /* load an object file and merge it with current files */
2034 /* XXX: handle correctly stab (debug) info */
2035 static int tcc_load_object_file(TCCState
*s1
,
2036 int fd
, unsigned long file_offset
)
2039 ElfW(Shdr
) *shdr
, *sh
;
2040 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2041 unsigned char *strsec
, *strtab
;
2042 int *old_to_new_syms
;
2043 char *sh_name
, *name
;
2044 SectionMergeInfo
*sm_table
, *sm
;
2045 ElfW(Sym
) *sym
, *symtab
;
2046 ElfW_Rel
*rel
, *rel_end
;
2052 stab_index
= stabstr_index
= 0;
2054 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2056 if (ehdr
.e_ident
[0] != ELFMAG0
||
2057 ehdr
.e_ident
[1] != ELFMAG1
||
2058 ehdr
.e_ident
[2] != ELFMAG2
||
2059 ehdr
.e_ident
[3] != ELFMAG3
)
2061 /* test if object file */
2062 if (ehdr
.e_type
!= ET_REL
)
2064 /* test CPU specific stuff */
2065 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2066 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2068 error_noabort("invalid object file");
2072 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2073 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2074 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2076 /* load section names */
2077 sh
= &shdr
[ehdr
.e_shstrndx
];
2078 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2080 /* load symtab and strtab */
2081 old_to_new_syms
= NULL
;
2085 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2087 if (sh
->sh_type
== SHT_SYMTAB
) {
2089 error_noabort("object must contain only one symtab");
2094 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2095 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2096 sm_table
[i
].s
= symtab_section
;
2098 /* now load strtab */
2099 sh
= &shdr
[sh
->sh_link
];
2100 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2104 /* now examine each section and try to merge its content with the
2106 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2107 /* no need to examine section name strtab */
2108 if (i
== ehdr
.e_shstrndx
)
2111 sh_name
= strsec
+ sh
->sh_name
;
2112 /* ignore sections types we do not handle */
2113 if (sh
->sh_type
!= SHT_PROGBITS
&&
2114 sh
->sh_type
!= SHT_RELX
&&
2116 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2118 sh
->sh_type
!= SHT_NOBITS
&&
2119 strcmp(sh_name
, ".stabstr")
2122 if (sh
->sh_addralign
< 1)
2123 sh
->sh_addralign
= 1;
2124 /* find corresponding section, if any */
2125 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2126 s
= s1
->sections
[j
];
2127 if (!strcmp(s
->name
, sh_name
)) {
2128 if (!strncmp(sh_name
, ".gnu.linkonce",
2129 sizeof(".gnu.linkonce") - 1)) {
2130 /* if a 'linkonce' section is already present, we
2131 do not add it again. It is a little tricky as
2132 symbols can still be defined in
2134 sm_table
[i
].link_once
= 1;
2141 /* not found: create new section */
2142 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2143 /* take as much info as possible from the section. sh_link and
2144 sh_info will be updated later */
2145 s
->sh_addralign
= sh
->sh_addralign
;
2146 s
->sh_entsize
= sh
->sh_entsize
;
2147 sm_table
[i
].new_section
= 1;
2149 if (sh
->sh_type
!= s
->sh_type
) {
2150 error_noabort("invalid section type");
2154 /* align start of section */
2155 offset
= s
->data_offset
;
2157 if (0 == strcmp(sh_name
, ".stab")) {
2161 if (0 == strcmp(sh_name
, ".stabstr")) {
2166 size
= sh
->sh_addralign
- 1;
2167 offset
= (offset
+ size
) & ~size
;
2168 if (sh
->sh_addralign
> s
->sh_addralign
)
2169 s
->sh_addralign
= sh
->sh_addralign
;
2170 s
->data_offset
= offset
;
2172 sm_table
[i
].offset
= offset
;
2174 /* concatenate sections */
2176 if (sh
->sh_type
!= SHT_NOBITS
) {
2178 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2179 ptr
= section_ptr_add(s
, size
);
2180 read(fd
, ptr
, size
);
2182 s
->data_offset
+= size
;
2187 /* //gr relocate stab strings */
2188 if (stab_index
&& stabstr_index
) {
2191 s
= sm_table
[stab_index
].s
;
2192 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2193 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2194 o
= sm_table
[stabstr_index
].offset
;
2196 a
->n_strx
+= o
, a
++;
2199 /* second short pass to update sh_link and sh_info fields of new
2201 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2203 if (!s
|| !sm_table
[i
].new_section
)
2206 if (sh
->sh_link
> 0)
2207 s
->link
= sm_table
[sh
->sh_link
].s
;
2208 if (sh
->sh_type
== SHT_RELX
) {
2209 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2210 /* update backward link */
2211 s1
->sections
[s
->sh_info
]->reloc
= s
;
2216 /* resolve symbols */
2217 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2220 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2221 if (sym
->st_shndx
!= SHN_UNDEF
&&
2222 sym
->st_shndx
< SHN_LORESERVE
) {
2223 sm
= &sm_table
[sym
->st_shndx
];
2224 if (sm
->link_once
) {
2225 /* if a symbol is in a link once section, we use the
2226 already defined symbol. It is very important to get
2227 correct relocations */
2228 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2229 name
= strtab
+ sym
->st_name
;
2230 sym_index
= find_elf_sym(symtab_section
, name
);
2232 old_to_new_syms
[i
] = sym_index
;
2236 /* if no corresponding section added, no need to add symbol */
2239 /* convert section number */
2240 sym
->st_shndx
= sm
->s
->sh_num
;
2242 sym
->st_value
+= sm
->offset
;
2245 name
= strtab
+ sym
->st_name
;
2246 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2247 sym
->st_info
, sym
->st_other
,
2248 sym
->st_shndx
, name
);
2249 old_to_new_syms
[i
] = sym_index
;
2252 /* third pass to patch relocation entries */
2253 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2258 offset
= sm_table
[i
].offset
;
2259 switch(s
->sh_type
) {
2261 /* take relocation offset information */
2262 offseti
= sm_table
[sh
->sh_info
].offset
;
2263 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2264 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2269 /* convert symbol index */
2270 type
= ELFW(R_TYPE
)(rel
->r_info
);
2271 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2272 /* NOTE: only one symtab assumed */
2273 if (sym_index
>= nb_syms
)
2275 sym_index
= old_to_new_syms
[sym_index
];
2276 /* ignore link_once in rel section. */
2277 if (!sym_index
&& !sm
->link_once
) {
2279 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2280 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2283 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2284 /* offset the relocation offset */
2285 rel
->r_offset
+= offseti
;
2297 tcc_free(old_to_new_syms
);
2304 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2306 typedef struct ArchiveHeader
{
2307 char ar_name
[16]; /* name of this member */
2308 char ar_date
[12]; /* file mtime */
2309 char ar_uid
[6]; /* owner uid; printed as decimal */
2310 char ar_gid
[6]; /* owner gid; printed as decimal */
2311 char ar_mode
[8]; /* file mode, printed as octal */
2312 char ar_size
[10]; /* file size, printed as decimal */
2313 char ar_fmag
[2]; /* should contain ARFMAG */
2316 static int get_be32(const uint8_t *b
)
2318 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2321 /* load only the objects which resolve undefined symbols */
2322 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2324 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2326 const char *ar_names
, *p
;
2327 const uint8_t *ar_index
;
2330 data
= tcc_malloc(size
);
2331 if (read(fd
, data
, size
) != size
)
2333 nsyms
= get_be32(data
);
2334 ar_index
= data
+ 4;
2335 ar_names
= ar_index
+ nsyms
* 4;
2339 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2340 sym_index
= find_elf_sym(symtab_section
, p
);
2342 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2343 if(sym
->st_shndx
== SHN_UNDEF
) {
2344 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2346 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2349 lseek(fd
, off
, SEEK_SET
);
2350 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2365 /* load a '.a' file */
2366 static int tcc_load_archive(TCCState
*s1
, int fd
)
2373 unsigned long file_offset
;
2375 /* skip magic which was already checked */
2376 read(fd
, magic
, sizeof(magic
));
2379 len
= read(fd
, &hdr
, sizeof(hdr
));
2382 if (len
!= sizeof(hdr
)) {
2383 error_noabort("invalid archive");
2386 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2387 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2388 size
= strtol(ar_size
, NULL
, 0);
2389 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2390 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2391 if (ar_name
[i
] != ' ')
2394 ar_name
[i
+ 1] = '\0';
2395 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2396 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2398 size
= (size
+ 1) & ~1;
2399 if (!strcmp(ar_name
, "/")) {
2400 /* coff symbol table : we handle it */
2401 if(s1
->alacarte_link
)
2402 return tcc_load_alacarte(s1
, fd
, size
);
2403 } else if (!strcmp(ar_name
, "//") ||
2404 !strcmp(ar_name
, "__.SYMDEF") ||
2405 !strcmp(ar_name
, "__.SYMDEF/") ||
2406 !strcmp(ar_name
, "ARFILENAMES/")) {
2407 /* skip symbol table or archive names */
2409 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2412 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2417 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2418 is referenced by the user (so it should be added as DT_NEEDED in
2419 the generated ELF file) */
2420 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2423 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2424 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2425 ElfW(Sym
) *sym
, *dynsym
;
2426 ElfW(Dyn
) *dt
, *dynamic
;
2427 unsigned char *dynstr
;
2428 const char *name
, *soname
;
2429 DLLReference
*dllref
;
2431 read(fd
, &ehdr
, sizeof(ehdr
));
2433 /* test CPU specific stuff */
2434 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2435 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2436 error_noabort("bad architecture");
2441 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2443 /* load dynamic section and dynamic symbols */
2447 dynsym
= NULL
; /* avoid warning */
2448 dynstr
= NULL
; /* avoid warning */
2449 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2450 switch(sh
->sh_type
) {
2452 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2453 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2456 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2457 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2458 sh1
= &shdr
[sh
->sh_link
];
2459 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2466 /* compute the real library name */
2467 soname
= tcc_basename(filename
);
2469 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2470 if (dt
->d_tag
== DT_SONAME
) {
2471 soname
= dynstr
+ dt
->d_un
.d_val
;
2475 /* if the dll is already loaded, do not load it */
2476 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2477 dllref
= s1
->loaded_dlls
[i
];
2478 if (!strcmp(soname
, dllref
->name
)) {
2479 /* but update level if needed */
2480 if (level
< dllref
->level
)
2481 dllref
->level
= level
;
2487 // printf("loading dll '%s'\n", soname);
2489 /* add the dll and its level */
2490 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2491 dllref
->level
= level
;
2492 strcpy(dllref
->name
, soname
);
2493 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2495 /* add dynamic symbols in dynsym_section */
2496 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2497 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2498 if (sym_bind
== STB_LOCAL
)
2500 name
= dynstr
+ sym
->st_name
;
2501 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2502 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2505 /* load all referenced DLLs */
2506 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2509 name
= dynstr
+ dt
->d_un
.d_val
;
2510 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2511 dllref
= s1
->loaded_dlls
[j
];
2512 if (!strcmp(name
, dllref
->name
))
2513 goto already_loaded
;
2515 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2516 error_noabort("referenced dll '%s' not found", name
);
2533 #define LD_TOK_NAME 256
2534 #define LD_TOK_EOF (-1)
2536 /* return next ld script token */
2537 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2555 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2556 ch
= file
->buf_ptr
[0];
2564 /* case 'a' ... 'z': */
2591 /* case 'A' ... 'z': */
2626 if (!((ch
>= 'a' && ch
<= 'z') ||
2627 (ch
>= 'A' && ch
<= 'Z') ||
2628 (ch
>= '0' && ch
<= '9') ||
2629 strchr("/.-_+=$:\\,~", ch
)))
2631 if ((q
- name
) < name_size
- 1) {
2648 printf("tok=%c %d\n", c
, c
);
2649 if (c
== LD_TOK_NAME
)
2650 printf(" name=%s\n", name
);
2655 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2657 char filename
[1024];
2660 t
= ld_next(s1
, filename
, sizeof(filename
));
2663 t
= ld_next(s1
, filename
, sizeof(filename
));
2665 if (t
== LD_TOK_EOF
) {
2666 error_noabort("unexpected end of file");
2668 } else if (t
== ')') {
2670 } else if (t
!= LD_TOK_NAME
) {
2671 error_noabort("filename expected");
2674 if (!strcmp(filename
, "AS_NEEDED")) {
2675 ret
= ld_add_file_list(s1
, 1);
2679 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2681 tcc_add_file(s1
, filename
);
2683 t
= ld_next(s1
, filename
, sizeof(filename
));
2685 t
= ld_next(s1
, filename
, sizeof(filename
));
2691 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2693 static int tcc_load_ldscript(TCCState
*s1
)
2696 char filename
[1024];
2699 ch
= file
->buf_ptr
[0];
2702 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2703 if (t
== LD_TOK_EOF
)
2705 else if (t
!= LD_TOK_NAME
)
2707 if (!strcmp(cmd
, "INPUT") ||
2708 !strcmp(cmd
, "GROUP")) {
2709 ret
= ld_add_file_list(s1
, 0);
2712 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2713 !strcmp(cmd
, "TARGET")) {
2714 /* ignore some commands */
2715 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2719 t
= ld_next(s1
, filename
, sizeof(filename
));
2720 if (t
== LD_TOK_EOF
) {
2721 error_noabort("unexpected end of file");
2723 } else if (t
== ')') {