2 * ELF file handling for TCC
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #ifdef TCC_TARGET_X86_64
22 #define ElfW_Rel ElfW(Rela)
23 #define SHT_RELX SHT_RELA
24 #define REL_SECTION_FMT ".rela%s"
25 /* x86-64 requires PLT for DLLs */
26 #define TCC_OUTPUT_DLL_WITH_PLT
28 #define ElfW_Rel ElfW(Rel)
29 #define SHT_RELX SHT_REL
30 #define REL_SECTION_FMT ".rel%s"
33 /* XXX: DLL with PLT would only work with x86-64 for now */
34 //#define TCC_OUTPUT_DLL_WITH_PLT
36 static int put_elf_str(Section
*s
, const char *sym
)
41 len
= strlen(sym
) + 1;
42 offset
= s
->data_offset
;
43 ptr
= section_ptr_add(s
, len
);
44 memcpy(ptr
, sym
, len
);
48 /* elf symbol hashing function */
49 static unsigned long elf_hash(const unsigned char *name
)
51 unsigned long h
= 0, g
;
54 h
= (h
<< 4) + *name
++;
63 /* rebuild hash table of section s */
64 /* NOTE: we do factorize the hash table code to go faster */
65 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
68 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
71 strtab
= s
->link
->data
;
72 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
74 s
->hash
->data_offset
= 0;
75 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
80 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
81 ptr
+= nb_buckets
+ 1;
83 sym
= (ElfW(Sym
) *)s
->data
+ 1;
84 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
85 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
86 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
97 /* return the symbol number */
98 static int put_elf_sym(Section
*s
,
99 unsigned long value
, unsigned long size
,
100 int info
, int other
, int shndx
, const char *name
)
102 int name_offset
, sym_index
;
107 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
109 name_offset
= put_elf_str(s
->link
, name
);
112 /* XXX: endianness */
113 sym
->st_name
= name_offset
;
114 sym
->st_value
= value
;
117 sym
->st_other
= other
;
118 sym
->st_shndx
= shndx
;
119 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
123 ptr
= section_ptr_add(hs
, sizeof(int));
124 base
= (int *)hs
->data
;
125 /* only add global or weak symbols */
126 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
127 /* add another hashing entry */
129 h
= elf_hash(name
) % nbuckets
;
131 base
[2 + h
] = sym_index
;
133 /* we resize the hash table */
134 hs
->nb_hashed_syms
++;
135 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
136 rebuild_hash(s
, 2 * nbuckets
);
146 /* find global ELF symbol 'name' and return its index. Return 0 if not
148 static int find_elf_sym(Section
*s
, const char *name
)
152 int nbuckets
, sym_index
, h
;
158 nbuckets
= ((int *)hs
->data
)[0];
159 h
= elf_hash(name
) % nbuckets
;
160 sym_index
= ((int *)hs
->data
)[2 + h
];
161 while (sym_index
!= 0) {
162 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
163 name1
= s
->link
->data
+ sym
->st_name
;
164 if (!strcmp(name
, name1
))
166 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
171 /* return elf symbol value or error */
172 int tcc_get_symbol(TCCState
*s
, unsigned long *pval
, const char *name
)
177 sym_index
= find_elf_sym(symtab_section
, name
);
180 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
181 *pval
= sym
->st_value
;
185 void *tcc_get_symbol_err(TCCState
*s
, const char *name
)
188 if (tcc_get_symbol(s
, &val
, name
) < 0)
189 error("%s not defined", name
);
193 /* add an elf symbol : check if it is already defined and patch
194 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
195 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
196 int info
, int other
, int sh_num
, const char *name
)
199 int sym_bind
, sym_index
, sym_type
, esym_bind
;
200 unsigned char sym_vis
, esym_vis
, new_vis
;
202 sym_bind
= ELFW(ST_BIND
)(info
);
203 sym_type
= ELFW(ST_TYPE
)(info
);
204 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
206 if (sym_bind
!= STB_LOCAL
) {
207 /* we search global or weak symbols */
208 sym_index
= find_elf_sym(s
, name
);
211 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
212 if (esym
->st_shndx
!= SHN_UNDEF
) {
213 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
214 /* propagate the most constraining visibility */
215 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
216 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
217 if (esym_vis
== STV_DEFAULT
) {
219 } else if (sym_vis
== STV_DEFAULT
) {
222 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
224 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
226 other
= esym
->st_other
; /* in case we have to patch esym */
227 if (sh_num
== SHN_UNDEF
) {
228 /* ignore adding of undefined symbol if the
229 corresponding symbol is already defined */
230 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
231 /* global overrides weak, so patch */
233 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
234 /* weak is ignored if already global */
235 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
236 /* ignore hidden symbols after */
237 } else if (esym
->st_shndx
== SHN_COMMON
&& sh_num
< SHN_LORESERVE
) {
238 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
239 No idea if this is the correct solution ... */
241 } else if (s
== tcc_state
->dynsymtab_section
) {
242 /* we accept that two DLL define the same symbol */
245 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
246 sym_bind
, sh_num
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
248 error_noabort("'%s' defined twice", name
);
252 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
253 esym
->st_shndx
= sh_num
;
254 esym
->st_value
= value
;
255 esym
->st_size
= size
;
256 esym
->st_other
= other
;
260 sym_index
= put_elf_sym(s
, value
, size
,
261 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
268 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
269 int type
, int symbol
)
277 /* if no relocation section, create it */
278 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
279 /* if the symtab is allocated, then we consider the relocation
281 sr
= new_section(tcc_state
, buf
, SHT_RELX
, symtab
->sh_flags
);
282 sr
->sh_entsize
= sizeof(ElfW_Rel
);
284 sr
->sh_info
= s
->sh_num
;
287 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
288 rel
->r_offset
= offset
;
289 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
290 #ifdef TCC_TARGET_X86_64
295 /* put stab debug information */
298 unsigned int n_strx
; /* index into string table of name */
299 unsigned char n_type
; /* type of symbol */
300 unsigned char n_other
; /* misc info (usually empty) */
301 unsigned short n_desc
; /* description field */
302 unsigned int n_value
; /* value of symbol */
305 static void put_stabs(const char *str
, int type
, int other
, int desc
,
310 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
312 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
317 sym
->n_other
= other
;
319 sym
->n_value
= value
;
322 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
323 unsigned long value
, Section
*sec
, int sym_index
)
325 put_stabs(str
, type
, other
, desc
, value
);
326 put_elf_reloc(symtab_section
, stab_section
,
327 stab_section
->data_offset
- sizeof(unsigned int),
328 R_DATA_32
, sym_index
);
331 static void put_stabn(int type
, int other
, int desc
, int value
)
333 put_stabs(NULL
, type
, other
, desc
, value
);
336 static void put_stabd(int type
, int other
, int desc
)
338 put_stabs(NULL
, type
, other
, desc
, 0);
341 /* In an ELF file symbol table, the local symbols must appear below
342 the global and weak ones. Since TCC cannot sort it while generating
343 the code, we must do it after. All the relocation tables are also
344 modified to take into account the symbol table sorting */
345 static void sort_syms(TCCState
*s1
, Section
*s
)
347 int *old_to_new_syms
;
351 ElfW_Rel
*rel
, *rel_end
;
355 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
356 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
357 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
359 /* first pass for local symbols */
360 p
= (ElfW(Sym
) *)s
->data
;
362 for(i
= 0; i
< nb_syms
; i
++) {
363 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
364 old_to_new_syms
[i
] = q
- new_syms
;
369 /* save the number of local symbols in section header */
370 s
->sh_info
= q
- new_syms
;
372 /* then second pass for non local symbols */
373 p
= (ElfW(Sym
) *)s
->data
;
374 for(i
= 0; i
< nb_syms
; i
++) {
375 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
376 old_to_new_syms
[i
] = q
- new_syms
;
382 /* we copy the new symbols to the old */
383 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
386 /* now we modify all the relocations */
387 for(i
= 1; i
< s1
->nb_sections
; i
++) {
388 sr
= s1
->sections
[i
];
389 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
390 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
391 for(rel
= (ElfW_Rel
*)sr
->data
;
394 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
395 type
= ELFW(R_TYPE
)(rel
->r_info
);
396 sym_index
= old_to_new_syms
[sym_index
];
397 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
402 tcc_free(old_to_new_syms
);
405 /* relocate common symbols in the .bss section */
406 static void relocate_common_syms(void)
408 ElfW(Sym
) *sym
, *sym_end
;
409 unsigned long offset
, align
;
411 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
412 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
415 if (sym
->st_shndx
== SHN_COMMON
) {
417 align
= sym
->st_value
;
418 offset
= bss_section
->data_offset
;
419 offset
= (offset
+ align
- 1) & -align
;
420 sym
->st_value
= offset
;
421 sym
->st_shndx
= bss_section
->sh_num
;
422 offset
+= sym
->st_size
;
423 bss_section
->data_offset
= offset
;
428 /* relocate symbol table, resolve undefined symbols if do_resolve is
429 true and output error if undefined symbol. */
430 static void relocate_syms(TCCState
*s1
, int do_resolve
)
432 ElfW(Sym
) *sym
, *esym
, *sym_end
;
433 int sym_bind
, sh_num
, sym_index
;
437 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
438 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
441 sh_num
= sym
->st_shndx
;
442 if (sh_num
== SHN_UNDEF
) {
443 name
= strtab_section
->data
+ sym
->st_name
;
445 name
= symtab_section
->link
->data
+ sym
->st_name
;
446 addr
= (unsigned long)resolve_sym(s1
, name
, ELFW(ST_TYPE
)(sym
->st_info
));
448 sym
->st_value
= addr
;
451 } else if (s1
->dynsym
) {
452 /* if dynamic symbol exist, then use it */
453 sym_index
= find_elf_sym(s1
->dynsym
, name
);
455 esym
= &((ElfW(Sym
) *)s1
->dynsym
->data
)[sym_index
];
456 sym
->st_value
= esym
->st_value
;
460 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
462 if (!strcmp(name
, "_fp_hw"))
464 /* only weak symbols are accepted to be undefined. Their
466 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
467 if (sym_bind
== STB_WEAK
) {
470 error_noabort("undefined symbol '%s'", name
);
472 } else if (sh_num
< SHN_LORESERVE
) {
473 /* add section base */
474 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
480 #ifdef TCC_TARGET_X86_64
481 #define JMP_TABLE_ENTRY_SIZE 14
482 #define JMP_TABLE_ENTRY_MAX_NUM 4096
483 static unsigned long add_jmp_table(TCCState
*s1
, unsigned long val
)
486 if (!s1
->jmp_table
) {
487 int size
= JMP_TABLE_ENTRY_SIZE
* JMP_TABLE_ENTRY_MAX_NUM
;
488 s1
->jmp_table_num
= 0;
489 s1
->jmp_table
= (char *)tcc_malloc(size
);
490 set_pages_executable(s1
->jmp_table
, size
);
492 if (s1
->jmp_table_num
== JMP_TABLE_ENTRY_MAX_NUM
) {
493 error("relocating >%d symbols are not supported",
494 JMP_TABLE_ENTRY_MAX_NUM
);
496 p
= s1
->jmp_table
+ s1
->jmp_table_num
* JMP_TABLE_ENTRY_SIZE
;
502 *(unsigned long *)(p
+ 6) = val
;
503 return (unsigned long)p
;
507 /* relocate a given section (CPU dependent) */
508 static void relocate_section(TCCState
*s1
, Section
*s
)
511 ElfW_Rel
*rel
, *rel_end
, *qrel
;
515 unsigned long val
, addr
;
519 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
520 qrel
= (ElfW_Rel
*)sr
->data
;
524 ptr
= s
->data
+ rel
->r_offset
;
526 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
527 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
529 #ifdef TCC_TARGET_X86_64
530 /* XXX: not tested */
531 val
+= rel
->r_addend
;
533 type
= ELFW(R_TYPE
)(rel
->r_info
);
534 addr
= s
->sh_addr
+ rel
->r_offset
;
538 #if defined(TCC_TARGET_I386)
540 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
541 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
542 qrel
->r_offset
= rel
->r_offset
;
544 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_32
);
548 qrel
->r_info
= ELFW(R_INFO
)(0, R_386_RELATIVE
);
555 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
557 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
559 qrel
->r_offset
= rel
->r_offset
;
560 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_PC32
);
565 *(int *)ptr
+= val
- addr
;
568 *(int *)ptr
+= val
- addr
;
575 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
578 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
581 /* we load the got offset */
582 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
584 #elif defined(TCC_TARGET_ARM)
591 x
= (*(int *)ptr
)&0xffffff;
592 (*(int *)ptr
) &= 0xff000000;
597 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
598 error("can't relocate value at %x",addr
);
607 x
= (*(int *)ptr
) & 0x7fffffff;
608 (*(int *)ptr
) &= 0x80000000;
611 if((x
^(x
>>1))&0x40000000)
612 error("can't relocate value at %x",addr
);
613 (*(int *)ptr
) |= x
& 0x7fffffff;
618 case R_ARM_BASE_PREL
:
619 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
622 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
625 /* we load the got offset */
626 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
631 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
632 type
,addr
,(unsigned int )ptr
,val
);
634 #elif defined(TCC_TARGET_C67)
642 /* put the low 16 bits of the absolute address */
643 // add to what is already there
645 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
646 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
648 //patch both at once - assumes always in pairs Low - High
650 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
651 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
657 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
658 type
,addr
,(unsigned int )ptr
,val
);
660 #elif defined(TCC_TARGET_X86_64)
662 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
663 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
664 qrel
->r_addend
= *(long long *)ptr
+ val
;
667 *(long long *)ptr
+= val
;
671 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
672 /* XXX: this logic may depend on TCC's codegen
673 now TCC uses R_X86_64_32 even for a 64bit pointer */
674 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
675 qrel
->r_addend
= *(int *)ptr
+ val
;
680 case R_X86_64_PC32
: {
681 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
683 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
685 qrel
->r_offset
= rel
->r_offset
;
686 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_X86_64_PC32
);
687 qrel
->r_addend
= *(int *)ptr
;
692 long diff
= val
- addr
;
693 if (diff
< -2147483648 || diff
> 2147483647) {
694 /* XXX: naive support for over 32bit jump */
695 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
696 val
= add_jmp_table(s1
, val
);
699 if (diff
<= -2147483647 || diff
> 2147483647) {
701 /* output memory map to debug easily */
706 printf("%ld - %ld = %ld\n", val
, addr
, diff
);
707 dladdr((void *)addr
, &di
);
708 printf("addr = %lx = %lx+%lx(%s) ptr=%p\n",
709 addr
, s
->sh_addr
, rel
->r_offset
, di
.dli_sname
,
711 fp
= fopen("/proc/self/maps", "r");
712 size
= fread(buf
, 1, 4095, fp
);
716 error("internal error: relocation failed");
723 *(int *)ptr
+= val
- addr
;
725 case R_X86_64_GLOB_DAT
:
726 case R_X86_64_JUMP_SLOT
:
729 case R_X86_64_GOTPCREL
:
730 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
732 case R_X86_64_GOTTPOFF
:
733 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
736 /* we load the got offset */
737 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
740 #error unsupported processor
744 /* if the relocation is allocated, we change its symbol table */
745 if (sr
->sh_flags
& SHF_ALLOC
)
746 sr
->link
= s1
->dynsym
;
749 /* relocate relocation table in 'sr' */
750 static void relocate_rel(TCCState
*s1
, Section
*sr
)
753 ElfW_Rel
*rel
, *rel_end
;
755 s
= s1
->sections
[sr
->sh_info
];
756 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
757 for(rel
= (ElfW_Rel
*)sr
->data
;
760 rel
->r_offset
+= s
->sh_addr
;
764 /* count the number of dynamic relocations so that we can reserve
766 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
768 ElfW_Rel
*rel
, *rel_end
;
769 int sym_index
, esym_index
, type
, count
;
772 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
773 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
774 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
775 type
= ELFW(R_TYPE
)(rel
->r_info
);
777 #if defined(TCC_TARGET_I386)
779 #elif defined(TCC_TARGET_X86_64)
785 #if defined(TCC_TARGET_I386)
787 #elif defined(TCC_TARGET_X86_64)
790 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
799 /* allocate the section */
800 sr
->sh_flags
|= SHF_ALLOC
;
801 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
806 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
811 if (index
>= s1
->nb_got_offsets
) {
812 /* find immediately bigger power of 2 and reallocate array */
816 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
818 error("memory full");
819 s1
->got_offsets
= tab
;
820 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
821 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
822 s1
->nb_got_offsets
= n
;
824 s1
->got_offsets
[index
] = val
;
827 /* XXX: suppress that */
828 static void put32(unsigned char *p
, uint32_t val
)
836 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
837 defined(TCC_TARGET_X86_64)
838 static uint32_t get32(unsigned char *p
)
840 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
844 static void build_got(TCCState
*s1
)
848 /* if no got, then create it */
849 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
850 s1
->got
->sh_entsize
= 4;
851 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
852 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
853 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
855 /* keep space for _DYNAMIC pointer, if present */
857 /* two dummy got entries */
861 /* keep space for _DYNAMIC pointer, if present */
864 /* two dummy got entries */
872 /* put a got entry corresponding to a symbol in symtab_section. 'size'
873 and 'info' can be modifed if more precise info comes from the DLL */
874 static void put_got_entry(TCCState
*s1
,
875 int reloc_type
, unsigned long size
, int info
,
881 unsigned long offset
;
887 /* if a got entry already exists for that symbol, no need to add one */
888 if (sym_index
< s1
->nb_got_offsets
&&
889 s1
->got_offsets
[sym_index
] != 0)
892 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
895 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
896 name
= symtab_section
->link
->data
+ sym
->st_name
;
897 offset
= sym
->st_value
;
898 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
900 #ifdef TCC_TARGET_X86_64
910 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
913 /* if we build a DLL, we add a %ebx offset */
914 if (s1
->output_type
== TCC_OUTPUT_DLL
)
920 /* add a PLT entry */
922 if (plt
->data_offset
== 0) {
923 /* first plt entry */
924 p
= section_ptr_add(plt
, 16);
925 p
[0] = 0xff; /* pushl got + PTR_SIZE */
927 put32(p
+ 2, PTR_SIZE
);
928 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
930 put32(p
+ 8, PTR_SIZE
* 2);
933 p
= section_ptr_add(plt
, 16);
934 p
[0] = 0xff; /* jmp *(got + x) */
936 put32(p
+ 2, s1
->got
->data_offset
);
937 p
[6] = 0x68; /* push $xxx */
938 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
939 p
[11] = 0xe9; /* jmp plt_start */
940 put32(p
+ 12, -(plt
->data_offset
));
942 /* the symbol is modified so that it will be relocated to
944 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
945 if (s1
->output_type
== TCC_OUTPUT_EXE
)
947 offset
= plt
->data_offset
- 16;
949 #elif defined(TCC_TARGET_ARM)
950 if (reloc_type
== R_ARM_JUMP_SLOT
) {
954 /* if we build a DLL, we add a %ebx offset */
955 if (s1
->output_type
== TCC_OUTPUT_DLL
)
956 error("DLLs unimplemented!");
958 /* add a PLT entry */
960 if (plt
->data_offset
== 0) {
961 /* first plt entry */
962 p
= section_ptr_add(plt
, 16);
963 put32(p
, 0xe52de004);
964 put32(p
+ 4, 0xe59fe010);
965 put32(p
+ 8, 0xe08fe00e);
966 put32(p
+ 12, 0xe5bef008);
969 p
= section_ptr_add(plt
, 16);
970 put32(p
, 0xe59fc004);
971 put32(p
+4, 0xe08fc00c);
972 put32(p
+8, 0xe59cf000);
973 put32(p
+12, s1
->got
->data_offset
);
975 /* the symbol is modified so that it will be relocated to
977 if (s1
->output_type
== TCC_OUTPUT_EXE
)
978 offset
= plt
->data_offset
- 16;
980 #elif defined(TCC_TARGET_C67)
981 error("C67 got not implemented");
983 #error unsupported CPU
985 index
= put_elf_sym(s1
->dynsym
, offset
,
986 size
, info
, 0, sym
->st_shndx
, name
);
987 /* put a got entry */
988 put_elf_reloc(s1
->dynsym
, s1
->got
,
989 s1
->got
->data_offset
,
992 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
996 /* build GOT and PLT entries */
997 static void build_got_entries(TCCState
*s1
)
1000 ElfW_Rel
*rel
, *rel_end
;
1002 int i
, type
, reloc_type
, sym_index
;
1004 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1005 s
= s1
->sections
[i
];
1006 if (s
->sh_type
!= SHT_RELX
)
1008 /* no need to handle got relocations */
1009 if (s
->link
!= symtab_section
)
1012 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
1013 for(rel
= (ElfW_Rel
*)s
->data
;
1016 type
= ELFW(R_TYPE
)(rel
->r_info
);
1018 #if defined(TCC_TARGET_I386)
1025 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1026 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1027 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1028 /* look at the symbol got offset. If none, then add one */
1029 if (type
== R_386_GOT32
)
1030 reloc_type
= R_386_GLOB_DAT
;
1032 reloc_type
= R_386_JMP_SLOT
;
1033 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1037 #elif defined(TCC_TARGET_ARM)
1038 case R_ARM_GOT_BREL
:
1039 case R_ARM_GOTOFF32
:
1040 case R_ARM_BASE_PREL
:
1044 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1045 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1046 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1047 /* look at the symbol got offset. If none, then add one */
1048 if (type
== R_ARM_GOT_BREL
)
1049 reloc_type
= R_ARM_GLOB_DAT
;
1051 reloc_type
= R_ARM_JUMP_SLOT
;
1052 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1056 #elif defined(TCC_TARGET_C67)
1063 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1064 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1065 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1066 /* look at the symbol got offset. If none, then add one */
1067 if (type
== R_C60_GOT32
)
1068 reloc_type
= R_C60_GLOB_DAT
;
1070 reloc_type
= R_C60_JMP_SLOT
;
1071 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1075 #elif defined(TCC_TARGET_X86_64)
1076 case R_X86_64_GOT32
:
1077 case R_X86_64_GOTTPOFF
:
1078 case R_X86_64_GOTPCREL
:
1079 case R_X86_64_PLT32
:
1082 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_PLT32
) {
1083 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1084 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1085 /* look at the symbol got offset. If none, then add one */
1086 if (type
== R_X86_64_GOT32
)
1087 reloc_type
= R_X86_64_GLOB_DAT
;
1089 reloc_type
= R_X86_64_JUMP_SLOT
;
1090 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1095 #error unsupported CPU
1104 static Section
*new_symtab(TCCState
*s1
,
1105 const char *symtab_name
, int sh_type
, int sh_flags
,
1106 const char *strtab_name
,
1107 const char *hash_name
, int hash_sh_flags
)
1109 Section
*symtab
, *strtab
, *hash
;
1110 int *ptr
, nb_buckets
;
1112 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1113 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1114 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1115 put_elf_str(strtab
, "");
1116 symtab
->link
= strtab
;
1117 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1121 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1122 hash
->sh_entsize
= sizeof(int);
1123 symtab
->hash
= hash
;
1124 hash
->link
= symtab
;
1126 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1127 ptr
[0] = nb_buckets
;
1129 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1133 /* put dynamic tag */
1134 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1137 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1139 dyn
->d_un
.d_val
= val
;
1142 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1146 char sym_start
[1024];
1149 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1150 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1152 s
= find_section(s1
, section_name
);
1157 end_offset
= s
->data_offset
;
1160 add_elf_sym(symtab_section
,
1162 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1163 s
->sh_num
, sym_start
);
1164 add_elf_sym(symtab_section
,
1166 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1167 s
->sh_num
, sym_end
);
1170 /* add tcc runtime libraries */
1171 static void tcc_add_runtime(TCCState
*s1
)
1173 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1177 #ifdef CONFIG_TCC_BCHECK
1178 if (do_bounds_check
) {
1180 Section
*init_section
;
1181 unsigned char *pinit
;
1184 /* XXX: add an object file to do that */
1185 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1187 add_elf_sym(symtab_section
, 0, 0,
1188 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1189 bounds_section
->sh_num
, "__bounds_start");
1190 /* add bound check code */
1191 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "bcheck.o");
1192 tcc_add_file(s1
, buf
);
1193 #ifdef TCC_TARGET_I386
1194 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1195 /* add 'call __bound_init()' in .init section */
1196 init_section
= find_section(s1
, ".init");
1197 pinit
= section_ptr_add(init_section
, 5);
1199 put32(pinit
+ 1, -4);
1200 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1201 put_elf_reloc(symtab_section
, init_section
,
1202 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1208 if (!s1
->nostdlib
) {
1209 tcc_add_library(s1
, "c");
1211 #ifdef CONFIG_USE_LIBGCC
1212 tcc_add_file(s1
, CONFIG_SYSROOT
"/lib/libgcc_s.so.1");
1214 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "libtcc1.a");
1215 tcc_add_file(s1
, buf
);
1218 /* add crt end if not memory output */
1219 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1220 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1224 /* add various standard linker symbols (must be done after the
1225 sections are filled (for example after allocating common
1227 static void tcc_add_linker_symbols(TCCState
*s1
)
1233 add_elf_sym(symtab_section
,
1234 text_section
->data_offset
, 0,
1235 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1236 text_section
->sh_num
, "_etext");
1237 add_elf_sym(symtab_section
,
1238 data_section
->data_offset
, 0,
1239 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1240 data_section
->sh_num
, "_edata");
1241 add_elf_sym(symtab_section
,
1242 bss_section
->data_offset
, 0,
1243 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1244 bss_section
->sh_num
, "_end");
1245 /* horrible new standard ldscript defines */
1246 add_init_array_defines(s1
, ".preinit_array");
1247 add_init_array_defines(s1
, ".init_array");
1248 add_init_array_defines(s1
, ".fini_array");
1250 /* add start and stop symbols for sections whose name can be
1252 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1253 s
= s1
->sections
[i
];
1254 if (s
->sh_type
== SHT_PROGBITS
&&
1255 (s
->sh_flags
& SHF_ALLOC
)) {
1259 /* check if section name can be expressed in C */
1265 if (!isid(ch
) && !isnum(ch
))
1269 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1270 add_elf_sym(symtab_section
,
1272 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1274 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1275 add_elf_sym(symtab_section
,
1277 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1284 /* name of ELF interpreter */
1286 static char elf_interp
[] = "/usr/libexec/ld-elf.so.1";
1289 static char elf_interp
[] = "/lib/ld-linux.so.3";
1290 #elif defined(TCC_TARGET_X86_64)
1291 static char elf_interp
[] = "/lib/ld-linux-x86-64.so.2";
1293 static char elf_interp
[] = "/lib/ld-linux.so.2";
1297 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1298 const int *section_order
)
1301 int i
, offset
, size
;
1304 for(i
=1;i
<s1
->nb_sections
;i
++) {
1305 s
= s1
->sections
[section_order
[i
]];
1306 if (s
->sh_type
!= SHT_NOBITS
&&
1307 (s
->sh_flags
& SHF_ALLOC
)) {
1308 while (offset
< s
->sh_offset
) {
1313 fwrite(s
->data
, 1, size
, f
);
1319 /* output an ELF file */
1320 /* XXX: suppress unneeded sections */
1321 int elf_output_file(TCCState
*s1
, const char *filename
)
1327 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1329 Section
*strsec
, *s
;
1330 ElfW(Shdr
) shdr
, *sh
;
1331 ElfW(Phdr
) *phdr
, *ph
;
1332 Section
*interp
, *dynamic
, *dynstr
;
1333 unsigned long saved_dynamic_data_offset
;
1335 int type
, file_type
;
1336 unsigned long rel_addr
, rel_size
;
1338 file_type
= s1
->output_type
;
1341 if (file_type
!= TCC_OUTPUT_OBJ
) {
1342 tcc_add_runtime(s1
);
1346 section_order
= NULL
;
1349 dynstr
= NULL
; /* avoid warning */
1350 saved_dynamic_data_offset
= 0; /* avoid warning */
1352 if (file_type
!= TCC_OUTPUT_OBJ
) {
1353 relocate_common_syms();
1355 tcc_add_linker_symbols(s1
);
1357 if (!s1
->static_link
) {
1359 int sym_index
, index
;
1360 ElfW(Sym
) *esym
, *sym_end
;
1362 if (file_type
== TCC_OUTPUT_EXE
) {
1364 /* add interpreter section only if executable */
1365 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1366 interp
->sh_addralign
= 1;
1367 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
1368 strcpy(ptr
, elf_interp
);
1371 /* add dynamic symbol table */
1372 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1374 ".hash", SHF_ALLOC
);
1375 dynstr
= s1
->dynsym
->link
;
1377 /* add dynamic section */
1378 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1379 SHF_ALLOC
| SHF_WRITE
);
1380 dynamic
->link
= dynstr
;
1381 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1384 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1385 SHF_ALLOC
| SHF_EXECINSTR
);
1386 s1
->plt
->sh_entsize
= 4;
1390 /* scan for undefined symbols and see if they are in the
1391 dynamic symbols. If a symbol STT_FUNC is found, then we
1392 add it in the PLT. If a symbol STT_OBJECT is found, we
1393 add it in the .bss section with a suitable relocation */
1394 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1395 symtab_section
->data_offset
);
1396 if (file_type
== TCC_OUTPUT_EXE
) {
1397 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1400 if (sym
->st_shndx
== SHN_UNDEF
) {
1401 name
= symtab_section
->link
->data
+ sym
->st_name
;
1402 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1404 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1405 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1406 if (type
== STT_FUNC
) {
1407 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1409 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1410 } else if (type
== STT_OBJECT
) {
1411 unsigned long offset
;
1412 offset
= bss_section
->data_offset
;
1413 /* XXX: which alignment ? */
1414 offset
= (offset
+ 16 - 1) & -16;
1415 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1417 bss_section
->sh_num
, name
);
1418 put_elf_reloc(s1
->dynsym
, bss_section
,
1419 offset
, R_COPY
, index
);
1420 offset
+= esym
->st_size
;
1421 bss_section
->data_offset
= offset
;
1424 /* STB_WEAK undefined symbols are accepted */
1425 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1427 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1428 !strcmp(name
, "_fp_hw")) {
1430 error_noabort("undefined symbol '%s'", name
);
1433 } else if (s1
->rdynamic
&&
1434 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1435 /* if -rdynamic option, then export all non
1437 name
= symtab_section
->link
->data
+ sym
->st_name
;
1438 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1440 sym
->st_shndx
, name
);
1447 /* now look at unresolved dynamic symbols and export
1448 corresponding symbol */
1449 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1450 s1
->dynsymtab_section
->data_offset
);
1451 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1454 if (esym
->st_shndx
== SHN_UNDEF
) {
1455 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1456 sym_index
= find_elf_sym(symtab_section
, name
);
1458 /* XXX: avoid adding a symbol if already
1459 present because of -rdynamic ? */
1460 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1461 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1463 sym
->st_shndx
, name
);
1465 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1466 /* weak symbols can stay undefined */
1468 warning("undefined dynamic symbol '%s'", name
);
1475 /* shared library case : we simply export all the global symbols */
1476 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1477 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1478 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1481 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1482 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1483 if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
&&
1484 sym
->st_shndx
== SHN_UNDEF
) {
1485 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1487 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1489 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1490 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1492 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1497 name
= symtab_section
->link
->data
+ sym
->st_name
;
1498 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1500 sym
->st_shndx
, name
);
1501 s1
->symtab_to_dynsym
[sym
-
1502 (ElfW(Sym
) *)symtab_section
->data
] =
1509 build_got_entries(s1
);
1511 /* add a list of needed dlls */
1512 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1513 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1514 if (dllref
->level
== 0)
1515 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1517 /* XXX: currently, since we do not handle PIC code, we
1518 must relocate the readonly segments */
1519 if (file_type
== TCC_OUTPUT_DLL
) {
1521 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1522 put_dt(dynamic
, DT_TEXTREL
, 0);
1525 /* add necessary space for other entries */
1526 saved_dynamic_data_offset
= dynamic
->data_offset
;
1527 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * 9;
1529 /* still need to build got entries in case of static link */
1530 build_got_entries(s1
);
1534 memset(&ehdr
, 0, sizeof(ehdr
));
1536 /* we add a section for symbols */
1537 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1538 put_elf_str(strsec
, "");
1540 /* compute number of sections */
1541 shnum
= s1
->nb_sections
;
1543 /* this array is used to reorder sections in the output file */
1544 section_order
= tcc_malloc(sizeof(int) * shnum
);
1545 section_order
[0] = 0;
1548 /* compute number of program headers */
1551 case TCC_OUTPUT_OBJ
:
1554 case TCC_OUTPUT_EXE
:
1555 if (!s1
->static_link
)
1560 case TCC_OUTPUT_DLL
:
1565 /* allocate strings for section names and decide if an unallocated
1566 section should be output */
1567 /* NOTE: the strsec section comes last, so its size is also
1569 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1570 s
= s1
->sections
[i
];
1571 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1573 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1578 s
->reloc
? s
->reloc
->name
: "n"
1581 /* when generating a DLL, we include relocations but we may
1583 if (file_type
== TCC_OUTPUT_DLL
&&
1584 s
->sh_type
== SHT_RELX
&&
1585 !(s
->sh_flags
& SHF_ALLOC
)) {
1586 /* //gr: avoid bogus relocs for empty (debug) sections */
1587 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1588 prepare_dynamic_rel(s1
, s
);
1590 s
->sh_size
= s
->data_offset
;
1591 } else if (do_debug
||
1592 file_type
== TCC_OUTPUT_OBJ
||
1593 (s
->sh_flags
& SHF_ALLOC
) ||
1594 i
== (s1
->nb_sections
- 1)) {
1595 /* we output all sections if debug or object file */
1596 s
->sh_size
= s
->data_offset
;
1600 /* allocate program segment headers */
1601 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1603 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1604 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1609 /* compute section to program header mapping */
1610 if (s1
->has_text_addr
) {
1611 int a_offset
, p_offset
;
1612 addr
= s1
->text_addr
;
1613 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1615 a_offset
= addr
& (ELF_PAGE_SIZE
- 1);
1616 p_offset
= file_offset
& (ELF_PAGE_SIZE
- 1);
1617 if (a_offset
< p_offset
)
1618 a_offset
+= ELF_PAGE_SIZE
;
1619 file_offset
+= (a_offset
- p_offset
);
1621 if (file_type
== TCC_OUTPUT_DLL
)
1624 addr
= ELF_START_ADDR
;
1625 /* compute address after headers */
1626 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1629 /* dynamic relocation table information, for .dynamic section */
1633 /* leave one program header for the program interpreter */
1638 for(j
= 0; j
< 2; j
++) {
1639 ph
->p_type
= PT_LOAD
;
1641 ph
->p_flags
= PF_R
| PF_X
;
1643 ph
->p_flags
= PF_R
| PF_W
;
1644 ph
->p_align
= ELF_PAGE_SIZE
;
1646 /* we do the following ordering: interp, symbol tables,
1647 relocations, progbits, nobits */
1648 /* XXX: do faster and simpler sorting */
1649 for(k
= 0; k
< 5; k
++) {
1650 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1651 s
= s1
->sections
[i
];
1652 /* compute if section should be included */
1654 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1658 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1659 (SHF_ALLOC
| SHF_WRITE
))
1665 } else if (s
->sh_type
== SHT_DYNSYM
||
1666 s
->sh_type
== SHT_STRTAB
||
1667 s
->sh_type
== SHT_HASH
) {
1670 } else if (s
->sh_type
== SHT_RELX
) {
1673 } else if (s
->sh_type
== SHT_NOBITS
) {
1680 section_order
[sh_order_index
++] = i
;
1682 /* section matches: we align it and add its size */
1684 addr
= (addr
+ s
->sh_addralign
- 1) &
1685 ~(s
->sh_addralign
- 1);
1686 file_offset
+= addr
- tmp
;
1687 s
->sh_offset
= file_offset
;
1690 /* update program header infos */
1691 if (ph
->p_offset
== 0) {
1692 ph
->p_offset
= file_offset
;
1694 ph
->p_paddr
= ph
->p_vaddr
;
1696 /* update dynamic relocation infos */
1697 if (s
->sh_type
== SHT_RELX
) {
1700 rel_size
+= s
->sh_size
;
1703 if (s
->sh_type
!= SHT_NOBITS
)
1704 file_offset
+= s
->sh_size
;
1707 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1708 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1711 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1712 /* if in the middle of a page, we duplicate the page in
1713 memory so that one copy is RX and the other is RW */
1714 if ((addr
& (ELF_PAGE_SIZE
- 1)) != 0)
1715 addr
+= ELF_PAGE_SIZE
;
1717 addr
= (addr
+ ELF_PAGE_SIZE
- 1) & ~(ELF_PAGE_SIZE
- 1);
1718 file_offset
= (file_offset
+ ELF_PAGE_SIZE
- 1) &
1719 ~(ELF_PAGE_SIZE
- 1);
1724 /* if interpreter, then add corresponing program header */
1728 ph
->p_type
= PT_INTERP
;
1729 ph
->p_offset
= interp
->sh_offset
;
1730 ph
->p_vaddr
= interp
->sh_addr
;
1731 ph
->p_paddr
= ph
->p_vaddr
;
1732 ph
->p_filesz
= interp
->sh_size
;
1733 ph
->p_memsz
= interp
->sh_size
;
1735 ph
->p_align
= interp
->sh_addralign
;
1738 /* if dynamic section, then add corresponing program header */
1742 ph
= &phdr
[phnum
- 1];
1744 ph
->p_type
= PT_DYNAMIC
;
1745 ph
->p_offset
= dynamic
->sh_offset
;
1746 ph
->p_vaddr
= dynamic
->sh_addr
;
1747 ph
->p_paddr
= ph
->p_vaddr
;
1748 ph
->p_filesz
= dynamic
->sh_size
;
1749 ph
->p_memsz
= dynamic
->sh_size
;
1750 ph
->p_flags
= PF_R
| PF_W
;
1751 ph
->p_align
= dynamic
->sh_addralign
;
1753 /* put GOT dynamic section address */
1754 put32(s1
->got
->data
, dynamic
->sh_addr
);
1756 /* relocate the PLT */
1757 if (file_type
== TCC_OUTPUT_EXE
1758 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1759 || file_type
== TCC_OUTPUT_DLL
1765 p_end
= p
+ s1
->plt
->data_offset
;
1767 #if defined(TCC_TARGET_I386)
1768 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1769 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1772 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1775 #elif defined(TCC_TARGET_X86_64)
1776 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1777 put32(p
+ 2, get32(p
+ 2) + x
);
1778 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1781 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1784 #elif defined(TCC_TARGET_ARM)
1786 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1789 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1792 #elif defined(TCC_TARGET_C67)
1795 #error unsupported CPU
1800 /* relocate symbols in .dynsym */
1801 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1802 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1805 if (sym
->st_shndx
== SHN_UNDEF
) {
1806 /* relocate to the PLT if the symbol corresponds
1809 sym
->st_value
+= s1
->plt
->sh_addr
;
1810 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1811 /* do symbol relocation */
1812 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1816 /* put dynamic section entries */
1817 dynamic
->data_offset
= saved_dynamic_data_offset
;
1818 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1819 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1820 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1821 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1822 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1823 #ifdef TCC_TARGET_X86_64
1824 put_dt(dynamic
, DT_RELA
, rel_addr
);
1825 put_dt(dynamic
, DT_RELASZ
, rel_size
);
1826 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1828 put_dt(dynamic
, DT_REL
, rel_addr
);
1829 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1830 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1833 put_dt(dynamic
, DT_DEBUG
, 0);
1834 put_dt(dynamic
, DT_NULL
, 0);
1837 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1838 ehdr
.e_phnum
= phnum
;
1839 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1842 /* all other sections come after */
1843 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1844 s
= s1
->sections
[i
];
1845 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1847 section_order
[sh_order_index
++] = i
;
1849 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1850 ~(s
->sh_addralign
- 1);
1851 s
->sh_offset
= file_offset
;
1852 if (s
->sh_type
!= SHT_NOBITS
)
1853 file_offset
+= s
->sh_size
;
1856 /* if building executable or DLL, then relocate each section
1857 except the GOT which is already relocated */
1858 if (file_type
!= TCC_OUTPUT_OBJ
) {
1859 relocate_syms(s1
, 0);
1861 if (s1
->nb_errors
!= 0) {
1867 /* relocate sections */
1868 /* XXX: ignore sections with allocated relocations ? */
1869 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1870 s
= s1
->sections
[i
];
1871 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1872 relocate_section(s1
, s
);
1875 /* relocate relocation entries if the relocation tables are
1876 allocated in the executable */
1877 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1878 s
= s1
->sections
[i
];
1879 if ((s
->sh_flags
& SHF_ALLOC
) &&
1880 s
->sh_type
== SHT_RELX
) {
1881 relocate_rel(s1
, s
);
1885 /* get entry point address */
1886 if (file_type
== TCC_OUTPUT_EXE
)
1887 ehdr
.e_entry
= (unsigned long)tcc_get_symbol_err(s1
, "_start");
1889 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1892 /* write elf file */
1893 if (file_type
== TCC_OUTPUT_OBJ
)
1897 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1899 error_noabort("could not write '%s'", filename
);
1902 f
= fdopen(fd
, "wb");
1904 printf("<- %s\n", filename
);
1906 #ifdef TCC_TARGET_COFF
1907 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1908 tcc_output_coff(s1
, f
);
1911 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1912 sort_syms(s1
, symtab_section
);
1915 file_offset
= (file_offset
+ 3) & -4;
1918 ehdr
.e_ident
[0] = ELFMAG0
;
1919 ehdr
.e_ident
[1] = ELFMAG1
;
1920 ehdr
.e_ident
[2] = ELFMAG2
;
1921 ehdr
.e_ident
[3] = ELFMAG3
;
1922 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
1923 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1924 ehdr
.e_ident
[6] = EV_CURRENT
;
1926 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1928 #ifdef TCC_TARGET_ARM
1930 ehdr
.e_ident
[EI_OSABI
] = 0;
1931 ehdr
.e_flags
= 4 << 24;
1933 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
1938 case TCC_OUTPUT_EXE
:
1939 ehdr
.e_type
= ET_EXEC
;
1941 case TCC_OUTPUT_DLL
:
1942 ehdr
.e_type
= ET_DYN
;
1944 case TCC_OUTPUT_OBJ
:
1945 ehdr
.e_type
= ET_REL
;
1948 ehdr
.e_machine
= EM_TCC_TARGET
;
1949 ehdr
.e_version
= EV_CURRENT
;
1950 ehdr
.e_shoff
= file_offset
;
1951 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
1952 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
1953 ehdr
.e_shnum
= shnum
;
1954 ehdr
.e_shstrndx
= shnum
- 1;
1956 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
1957 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
1958 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1960 for(i
=1;i
<s1
->nb_sections
;i
++) {
1961 s
= s1
->sections
[section_order
[i
]];
1962 if (s
->sh_type
!= SHT_NOBITS
) {
1963 while (offset
< s
->sh_offset
) {
1968 fwrite(s
->data
, 1, size
, f
);
1973 /* output section headers */
1974 while (offset
< ehdr
.e_shoff
) {
1979 for(i
=0;i
<s1
->nb_sections
;i
++) {
1981 memset(sh
, 0, sizeof(ElfW(Shdr
)));
1982 s
= s1
->sections
[i
];
1984 sh
->sh_name
= s
->sh_name
;
1985 sh
->sh_type
= s
->sh_type
;
1986 sh
->sh_flags
= s
->sh_flags
;
1987 sh
->sh_entsize
= s
->sh_entsize
;
1988 sh
->sh_info
= s
->sh_info
;
1990 sh
->sh_link
= s
->link
->sh_num
;
1991 sh
->sh_addralign
= s
->sh_addralign
;
1992 sh
->sh_addr
= s
->sh_addr
;
1993 sh
->sh_offset
= s
->sh_offset
;
1994 sh
->sh_size
= s
->sh_size
;
1996 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
1999 tcc_output_binary(s1
, f
, section_order
);
2005 tcc_free(s1
->symtab_to_dynsym
);
2006 tcc_free(section_order
);
2008 tcc_free(s1
->got_offsets
);
2012 int tcc_output_file(TCCState
*s
, const char *filename
)
2015 #ifdef TCC_TARGET_PE
2016 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2017 ret
= pe_output_file(s
, filename
);
2021 ret
= elf_output_file(s
, filename
);
2026 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2030 data
= tcc_malloc(size
);
2031 lseek(fd
, file_offset
, SEEK_SET
);
2032 read(fd
, data
, size
);
2036 typedef struct SectionMergeInfo
{
2037 Section
*s
; /* corresponding existing section */
2038 unsigned long offset
; /* offset of the new section in the existing section */
2039 uint8_t new_section
; /* true if section 's' was added */
2040 uint8_t link_once
; /* true if link once section */
2043 /* load an object file and merge it with current files */
2044 /* XXX: handle correctly stab (debug) info */
2045 static int tcc_load_object_file(TCCState
*s1
,
2046 int fd
, unsigned long file_offset
)
2049 ElfW(Shdr
) *shdr
, *sh
;
2050 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2051 unsigned char *strsec
, *strtab
;
2052 int *old_to_new_syms
;
2053 char *sh_name
, *name
;
2054 SectionMergeInfo
*sm_table
, *sm
;
2055 ElfW(Sym
) *sym
, *symtab
;
2056 ElfW_Rel
*rel
, *rel_end
;
2062 stab_index
= stabstr_index
= 0;
2064 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2066 if (ehdr
.e_ident
[0] != ELFMAG0
||
2067 ehdr
.e_ident
[1] != ELFMAG1
||
2068 ehdr
.e_ident
[2] != ELFMAG2
||
2069 ehdr
.e_ident
[3] != ELFMAG3
)
2071 /* test if object file */
2072 if (ehdr
.e_type
!= ET_REL
)
2074 /* test CPU specific stuff */
2075 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2076 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2078 error_noabort("invalid object file");
2082 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2083 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2084 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2086 /* load section names */
2087 sh
= &shdr
[ehdr
.e_shstrndx
];
2088 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2090 /* load symtab and strtab */
2091 old_to_new_syms
= NULL
;
2095 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2097 if (sh
->sh_type
== SHT_SYMTAB
) {
2099 error_noabort("object must contain only one symtab");
2104 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2105 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2106 sm_table
[i
].s
= symtab_section
;
2108 /* now load strtab */
2109 sh
= &shdr
[sh
->sh_link
];
2110 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2114 /* now examine each section and try to merge its content with the
2116 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2117 /* no need to examine section name strtab */
2118 if (i
== ehdr
.e_shstrndx
)
2121 sh_name
= strsec
+ sh
->sh_name
;
2122 /* ignore sections types we do not handle */
2123 if (sh
->sh_type
!= SHT_PROGBITS
&&
2124 sh
->sh_type
!= SHT_RELX
&&
2126 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2128 sh
->sh_type
!= SHT_NOBITS
&&
2129 strcmp(sh_name
, ".stabstr")
2132 if (sh
->sh_addralign
< 1)
2133 sh
->sh_addralign
= 1;
2134 /* find corresponding section, if any */
2135 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2136 s
= s1
->sections
[j
];
2137 if (!strcmp(s
->name
, sh_name
)) {
2138 if (!strncmp(sh_name
, ".gnu.linkonce",
2139 sizeof(".gnu.linkonce") - 1)) {
2140 /* if a 'linkonce' section is already present, we
2141 do not add it again. It is a little tricky as
2142 symbols can still be defined in
2144 sm_table
[i
].link_once
= 1;
2151 /* not found: create new section */
2152 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2153 /* take as much info as possible from the section. sh_link and
2154 sh_info will be updated later */
2155 s
->sh_addralign
= sh
->sh_addralign
;
2156 s
->sh_entsize
= sh
->sh_entsize
;
2157 sm_table
[i
].new_section
= 1;
2159 if (sh
->sh_type
!= s
->sh_type
) {
2160 error_noabort("invalid section type");
2164 /* align start of section */
2165 offset
= s
->data_offset
;
2167 if (0 == strcmp(sh_name
, ".stab")) {
2171 if (0 == strcmp(sh_name
, ".stabstr")) {
2176 size
= sh
->sh_addralign
- 1;
2177 offset
= (offset
+ size
) & ~size
;
2178 if (sh
->sh_addralign
> s
->sh_addralign
)
2179 s
->sh_addralign
= sh
->sh_addralign
;
2180 s
->data_offset
= offset
;
2182 sm_table
[i
].offset
= offset
;
2184 /* concatenate sections */
2186 if (sh
->sh_type
!= SHT_NOBITS
) {
2188 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2189 ptr
= section_ptr_add(s
, size
);
2190 read(fd
, ptr
, size
);
2192 s
->data_offset
+= size
;
2197 /* //gr relocate stab strings */
2198 if (stab_index
&& stabstr_index
) {
2201 s
= sm_table
[stab_index
].s
;
2202 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2203 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2204 o
= sm_table
[stabstr_index
].offset
;
2206 a
->n_strx
+= o
, a
++;
2209 /* second short pass to update sh_link and sh_info fields of new
2211 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2213 if (!s
|| !sm_table
[i
].new_section
)
2216 if (sh
->sh_link
> 0)
2217 s
->link
= sm_table
[sh
->sh_link
].s
;
2218 if (sh
->sh_type
== SHT_RELX
) {
2219 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2220 /* update backward link */
2221 s1
->sections
[s
->sh_info
]->reloc
= s
;
2226 /* resolve symbols */
2227 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2230 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2231 if (sym
->st_shndx
!= SHN_UNDEF
&&
2232 sym
->st_shndx
< SHN_LORESERVE
) {
2233 sm
= &sm_table
[sym
->st_shndx
];
2234 if (sm
->link_once
) {
2235 /* if a symbol is in a link once section, we use the
2236 already defined symbol. It is very important to get
2237 correct relocations */
2238 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2239 name
= strtab
+ sym
->st_name
;
2240 sym_index
= find_elf_sym(symtab_section
, name
);
2242 old_to_new_syms
[i
] = sym_index
;
2246 /* if no corresponding section added, no need to add symbol */
2249 /* convert section number */
2250 sym
->st_shndx
= sm
->s
->sh_num
;
2252 sym
->st_value
+= sm
->offset
;
2255 name
= strtab
+ sym
->st_name
;
2256 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2257 sym
->st_info
, sym
->st_other
,
2258 sym
->st_shndx
, name
);
2259 old_to_new_syms
[i
] = sym_index
;
2262 /* third pass to patch relocation entries */
2263 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2268 offset
= sm_table
[i
].offset
;
2269 switch(s
->sh_type
) {
2271 /* take relocation offset information */
2272 offseti
= sm_table
[sh
->sh_info
].offset
;
2273 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2274 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2279 /* convert symbol index */
2280 type
= ELFW(R_TYPE
)(rel
->r_info
);
2281 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2282 /* NOTE: only one symtab assumed */
2283 if (sym_index
>= nb_syms
)
2285 sym_index
= old_to_new_syms
[sym_index
];
2286 /* ignore link_once in rel section. */
2287 if (!sym_index
&& !sm
->link_once
) {
2289 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2290 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2293 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2294 /* offset the relocation offset */
2295 rel
->r_offset
+= offseti
;
2307 tcc_free(old_to_new_syms
);
2314 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2316 typedef struct ArchiveHeader
{
2317 char ar_name
[16]; /* name of this member */
2318 char ar_date
[12]; /* file mtime */
2319 char ar_uid
[6]; /* owner uid; printed as decimal */
2320 char ar_gid
[6]; /* owner gid; printed as decimal */
2321 char ar_mode
[8]; /* file mode, printed as octal */
2322 char ar_size
[10]; /* file size, printed as decimal */
2323 char ar_fmag
[2]; /* should contain ARFMAG */
2326 static int get_be32(const uint8_t *b
)
2328 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2331 /* load only the objects which resolve undefined symbols */
2332 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2334 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2336 const char *ar_names
, *p
;
2337 const uint8_t *ar_index
;
2340 data
= tcc_malloc(size
);
2341 if (read(fd
, data
, size
) != size
)
2343 nsyms
= get_be32(data
);
2344 ar_index
= data
+ 4;
2345 ar_names
= ar_index
+ nsyms
* 4;
2349 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2350 sym_index
= find_elf_sym(symtab_section
, p
);
2352 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2353 if(sym
->st_shndx
== SHN_UNDEF
) {
2354 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2356 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2359 lseek(fd
, off
, SEEK_SET
);
2360 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2375 /* load a '.a' file */
2376 static int tcc_load_archive(TCCState
*s1
, int fd
)
2383 unsigned long file_offset
;
2385 /* skip magic which was already checked */
2386 read(fd
, magic
, sizeof(magic
));
2389 len
= read(fd
, &hdr
, sizeof(hdr
));
2392 if (len
!= sizeof(hdr
)) {
2393 error_noabort("invalid archive");
2396 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2397 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2398 size
= strtol(ar_size
, NULL
, 0);
2399 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2400 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2401 if (ar_name
[i
] != ' ')
2404 ar_name
[i
+ 1] = '\0';
2405 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2406 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2408 size
= (size
+ 1) & ~1;
2409 if (!strcmp(ar_name
, "/")) {
2410 /* coff symbol table : we handle it */
2411 if(s1
->alacarte_link
)
2412 return tcc_load_alacarte(s1
, fd
, size
);
2413 } else if (!strcmp(ar_name
, "//") ||
2414 !strcmp(ar_name
, "__.SYMDEF") ||
2415 !strcmp(ar_name
, "__.SYMDEF/") ||
2416 !strcmp(ar_name
, "ARFILENAMES/")) {
2417 /* skip symbol table or archive names */
2419 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2422 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2427 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2428 is referenced by the user (so it should be added as DT_NEEDED in
2429 the generated ELF file) */
2430 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2433 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2434 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2435 ElfW(Sym
) *sym
, *dynsym
;
2436 ElfW(Dyn
) *dt
, *dynamic
;
2437 unsigned char *dynstr
;
2438 const char *name
, *soname
;
2439 DLLReference
*dllref
;
2441 read(fd
, &ehdr
, sizeof(ehdr
));
2443 /* test CPU specific stuff */
2444 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2445 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2446 error_noabort("bad architecture");
2451 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2453 /* load dynamic section and dynamic symbols */
2457 dynsym
= NULL
; /* avoid warning */
2458 dynstr
= NULL
; /* avoid warning */
2459 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2460 switch(sh
->sh_type
) {
2462 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2463 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2466 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2467 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2468 sh1
= &shdr
[sh
->sh_link
];
2469 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2476 /* compute the real library name */
2477 soname
= tcc_basename(filename
);
2479 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2480 if (dt
->d_tag
== DT_SONAME
) {
2481 soname
= dynstr
+ dt
->d_un
.d_val
;
2485 /* if the dll is already loaded, do not load it */
2486 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2487 dllref
= s1
->loaded_dlls
[i
];
2488 if (!strcmp(soname
, dllref
->name
)) {
2489 /* but update level if needed */
2490 if (level
< dllref
->level
)
2491 dllref
->level
= level
;
2497 // printf("loading dll '%s'\n", soname);
2499 /* add the dll and its level */
2500 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2501 dllref
->level
= level
;
2502 strcpy(dllref
->name
, soname
);
2503 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2505 /* add dynamic symbols in dynsym_section */
2506 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2507 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2508 if (sym_bind
== STB_LOCAL
)
2510 name
= dynstr
+ sym
->st_name
;
2511 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2512 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2515 /* load all referenced DLLs */
2516 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2519 name
= dynstr
+ dt
->d_un
.d_val
;
2520 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2521 dllref
= s1
->loaded_dlls
[j
];
2522 if (!strcmp(name
, dllref
->name
))
2523 goto already_loaded
;
2525 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2526 error_noabort("referenced dll '%s' not found", name
);
2543 #define LD_TOK_NAME 256
2544 #define LD_TOK_EOF (-1)
2546 /* return next ld script token */
2547 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2565 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2566 ch
= file
->buf_ptr
[0];
2574 /* case 'a' ... 'z': */
2601 /* case 'A' ... 'z': */
2636 if (!((ch
>= 'a' && ch
<= 'z') ||
2637 (ch
>= 'A' && ch
<= 'Z') ||
2638 (ch
>= '0' && ch
<= '9') ||
2639 strchr("/.-_+=$:\\,~", ch
)))
2641 if ((q
- name
) < name_size
- 1) {
2658 printf("tok=%c %d\n", c
, c
);
2659 if (c
== LD_TOK_NAME
)
2660 printf(" name=%s\n", name
);
2665 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2667 char filename
[1024];
2670 t
= ld_next(s1
, filename
, sizeof(filename
));
2673 t
= ld_next(s1
, filename
, sizeof(filename
));
2675 if (t
== LD_TOK_EOF
) {
2676 error_noabort("unexpected end of file");
2678 } else if (t
== ')') {
2680 } else if (t
!= LD_TOK_NAME
) {
2681 error_noabort("filename expected");
2684 if (!strcmp(filename
, "AS_NEEDED")) {
2685 ret
= ld_add_file_list(s1
, 1);
2689 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2691 tcc_add_file(s1
, filename
);
2693 t
= ld_next(s1
, filename
, sizeof(filename
));
2695 t
= ld_next(s1
, filename
, sizeof(filename
));
2701 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2703 static int tcc_load_ldscript(TCCState
*s1
)
2706 char filename
[1024];
2709 ch
= file
->buf_ptr
[0];
2712 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2713 if (t
== LD_TOK_EOF
)
2715 else if (t
!= LD_TOK_NAME
)
2717 if (!strcmp(cmd
, "INPUT") ||
2718 !strcmp(cmd
, "GROUP")) {
2719 ret
= ld_add_file_list(s1
, 0);
2722 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2723 !strcmp(cmd
, "TARGET")) {
2724 /* ignore some commands */
2725 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2729 t
= ld_next(s1
, filename
, sizeof(filename
));
2730 if (t
== LD_TOK_EOF
) {
2731 error_noabort("unexpected end of file");
2733 } else if (t
== ')') {