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
;
731 /* XXX: is this OK? */
732 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
733 *(int *)ptr
+= s1
->got_offsets
[sym_index
] - 4;
736 case R_X86_64_GOTTPOFF
:
737 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
740 /* we load the got offset */
741 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
744 #error unsupported processor
748 /* if the relocation is allocated, we change its symbol table */
749 if (sr
->sh_flags
& SHF_ALLOC
)
750 sr
->link
= s1
->dynsym
;
753 /* relocate relocation table in 'sr' */
754 static void relocate_rel(TCCState
*s1
, Section
*sr
)
757 ElfW_Rel
*rel
, *rel_end
;
759 s
= s1
->sections
[sr
->sh_info
];
760 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
761 for(rel
= (ElfW_Rel
*)sr
->data
;
764 rel
->r_offset
+= s
->sh_addr
;
768 /* count the number of dynamic relocations so that we can reserve
770 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
772 ElfW_Rel
*rel
, *rel_end
;
773 int sym_index
, esym_index
, type
, count
;
776 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
777 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
778 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
779 type
= ELFW(R_TYPE
)(rel
->r_info
);
781 #if defined(TCC_TARGET_I386)
783 #elif defined(TCC_TARGET_X86_64)
790 #if defined(TCC_TARGET_I386)
792 #elif defined(TCC_TARGET_X86_64)
795 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
804 /* allocate the section */
805 sr
->sh_flags
|= SHF_ALLOC
;
806 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
811 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
816 if (index
>= s1
->nb_got_offsets
) {
817 /* find immediately bigger power of 2 and reallocate array */
821 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
823 error("memory full");
824 s1
->got_offsets
= tab
;
825 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
826 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
827 s1
->nb_got_offsets
= n
;
829 s1
->got_offsets
[index
] = val
;
832 /* XXX: suppress that */
833 static void put32(unsigned char *p
, uint32_t val
)
841 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
842 defined(TCC_TARGET_X86_64)
843 static uint32_t get32(unsigned char *p
)
845 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
849 static void build_got(TCCState
*s1
)
853 /* if no got, then create it */
854 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
855 s1
->got
->sh_entsize
= 4;
856 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
857 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
858 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
860 /* keep space for _DYNAMIC pointer, if present */
862 /* two dummy got entries */
866 /* keep space for _DYNAMIC pointer, if present */
869 /* two dummy got entries */
877 /* put a got entry corresponding to a symbol in symtab_section. 'size'
878 and 'info' can be modifed if more precise info comes from the DLL */
879 static void put_got_entry(TCCState
*s1
,
880 int reloc_type
, unsigned long size
, int info
,
886 unsigned long offset
;
892 /* if a got entry already exists for that symbol, no need to add one */
893 if (sym_index
< s1
->nb_got_offsets
&&
894 s1
->got_offsets
[sym_index
] != 0)
897 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
900 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
901 name
= symtab_section
->link
->data
+ sym
->st_name
;
902 offset
= sym
->st_value
;
903 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
905 #ifdef TCC_TARGET_X86_64
915 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
918 /* if we build a DLL, we add a %ebx offset */
919 if (s1
->output_type
== TCC_OUTPUT_DLL
)
925 /* add a PLT entry */
927 if (plt
->data_offset
== 0) {
928 /* first plt entry */
929 p
= section_ptr_add(plt
, 16);
930 p
[0] = 0xff; /* pushl got + PTR_SIZE */
932 put32(p
+ 2, PTR_SIZE
);
933 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
935 put32(p
+ 8, PTR_SIZE
* 2);
938 p
= section_ptr_add(plt
, 16);
939 p
[0] = 0xff; /* jmp *(got + x) */
941 put32(p
+ 2, s1
->got
->data_offset
);
942 p
[6] = 0x68; /* push $xxx */
943 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
944 p
[11] = 0xe9; /* jmp plt_start */
945 put32(p
+ 12, -(plt
->data_offset
));
947 /* the symbol is modified so that it will be relocated to
949 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
950 if (s1
->output_type
== TCC_OUTPUT_EXE
)
952 offset
= plt
->data_offset
- 16;
954 #elif defined(TCC_TARGET_ARM)
955 if (reloc_type
== R_ARM_JUMP_SLOT
) {
959 /* if we build a DLL, we add a %ebx offset */
960 if (s1
->output_type
== TCC_OUTPUT_DLL
)
961 error("DLLs unimplemented!");
963 /* add a PLT entry */
965 if (plt
->data_offset
== 0) {
966 /* first plt entry */
967 p
= section_ptr_add(plt
, 16);
968 put32(p
, 0xe52de004);
969 put32(p
+ 4, 0xe59fe010);
970 put32(p
+ 8, 0xe08fe00e);
971 put32(p
+ 12, 0xe5bef008);
974 p
= section_ptr_add(plt
, 16);
975 put32(p
, 0xe59fc004);
976 put32(p
+4, 0xe08fc00c);
977 put32(p
+8, 0xe59cf000);
978 put32(p
+12, s1
->got
->data_offset
);
980 /* the symbol is modified so that it will be relocated to
982 if (s1
->output_type
== TCC_OUTPUT_EXE
)
983 offset
= plt
->data_offset
- 16;
985 #elif defined(TCC_TARGET_C67)
986 error("C67 got not implemented");
988 #error unsupported CPU
990 index
= put_elf_sym(s1
->dynsym
, offset
,
991 size
, info
, 0, sym
->st_shndx
, name
);
992 /* put a got entry */
993 put_elf_reloc(s1
->dynsym
, s1
->got
,
994 s1
->got
->data_offset
,
997 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
1001 /* build GOT and PLT entries */
1002 static void build_got_entries(TCCState
*s1
)
1004 Section
*s
, *symtab
;
1005 ElfW_Rel
*rel
, *rel_end
;
1007 int i
, type
, reloc_type
, sym_index
;
1009 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1010 s
= s1
->sections
[i
];
1011 if (s
->sh_type
!= SHT_RELX
)
1013 /* no need to handle got relocations */
1014 if (s
->link
!= symtab_section
)
1017 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
1018 for(rel
= (ElfW_Rel
*)s
->data
;
1021 type
= ELFW(R_TYPE
)(rel
->r_info
);
1023 #if defined(TCC_TARGET_I386)
1030 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1031 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1032 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1033 /* look at the symbol got offset. If none, then add one */
1034 if (type
== R_386_GOT32
)
1035 reloc_type
= R_386_GLOB_DAT
;
1037 reloc_type
= R_386_JMP_SLOT
;
1038 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1042 #elif defined(TCC_TARGET_ARM)
1043 case R_ARM_GOT_BREL
:
1044 case R_ARM_GOTOFF32
:
1045 case R_ARM_BASE_PREL
:
1049 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1050 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1051 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1052 /* look at the symbol got offset. If none, then add one */
1053 if (type
== R_ARM_GOT_BREL
)
1054 reloc_type
= R_ARM_GLOB_DAT
;
1056 reloc_type
= R_ARM_JUMP_SLOT
;
1057 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1061 #elif defined(TCC_TARGET_C67)
1068 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1069 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1070 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1071 /* look at the symbol got offset. If none, then add one */
1072 if (type
== R_C60_GOT32
)
1073 reloc_type
= R_C60_GLOB_DAT
;
1075 reloc_type
= R_C60_JMP_SLOT
;
1076 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1080 #elif defined(TCC_TARGET_X86_64)
1081 case R_X86_64_GOT32
:
1082 case R_X86_64_GOTTPOFF
:
1083 case R_X86_64_GOTPCREL
:
1084 case R_X86_64_PLT32
:
1087 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
||
1088 type
== R_X86_64_PLT32
) {
1089 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1090 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1091 /* look at the symbol got offset. If none, then add one */
1092 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
)
1093 reloc_type
= R_X86_64_GLOB_DAT
;
1095 reloc_type
= R_X86_64_JUMP_SLOT
;
1096 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1101 #error unsupported CPU
1110 static Section
*new_symtab(TCCState
*s1
,
1111 const char *symtab_name
, int sh_type
, int sh_flags
,
1112 const char *strtab_name
,
1113 const char *hash_name
, int hash_sh_flags
)
1115 Section
*symtab
, *strtab
, *hash
;
1116 int *ptr
, nb_buckets
;
1118 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1119 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1120 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1121 put_elf_str(strtab
, "");
1122 symtab
->link
= strtab
;
1123 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1127 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1128 hash
->sh_entsize
= sizeof(int);
1129 symtab
->hash
= hash
;
1130 hash
->link
= symtab
;
1132 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1133 ptr
[0] = nb_buckets
;
1135 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1139 /* put dynamic tag */
1140 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1143 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1145 dyn
->d_un
.d_val
= val
;
1148 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1152 char sym_start
[1024];
1155 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1156 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1158 s
= find_section(s1
, section_name
);
1163 end_offset
= s
->data_offset
;
1166 add_elf_sym(symtab_section
,
1168 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1169 s
->sh_num
, sym_start
);
1170 add_elf_sym(symtab_section
,
1172 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1173 s
->sh_num
, sym_end
);
1176 /* add tcc runtime libraries */
1177 static void tcc_add_runtime(TCCState
*s1
)
1179 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1183 #ifdef CONFIG_TCC_BCHECK
1184 if (do_bounds_check
) {
1186 Section
*init_section
;
1187 unsigned char *pinit
;
1190 /* XXX: add an object file to do that */
1191 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1193 add_elf_sym(symtab_section
, 0, 0,
1194 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1195 bounds_section
->sh_num
, "__bounds_start");
1196 /* add bound check code */
1197 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "bcheck.o");
1198 tcc_add_file(s1
, buf
);
1199 #ifdef TCC_TARGET_I386
1200 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1201 /* add 'call __bound_init()' in .init section */
1202 init_section
= find_section(s1
, ".init");
1203 pinit
= section_ptr_add(init_section
, 5);
1205 put32(pinit
+ 1, -4);
1206 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1207 put_elf_reloc(symtab_section
, init_section
,
1208 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1214 if (!s1
->nostdlib
) {
1215 tcc_add_library(s1
, "c");
1217 #ifdef CONFIG_USE_LIBGCC
1218 tcc_add_file(s1
, CONFIG_SYSROOT
"/lib/libgcc_s.so.1");
1220 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "libtcc1.a");
1221 tcc_add_file(s1
, buf
);
1224 /* add crt end if not memory output */
1225 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1226 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1230 /* add various standard linker symbols (must be done after the
1231 sections are filled (for example after allocating common
1233 static void tcc_add_linker_symbols(TCCState
*s1
)
1239 add_elf_sym(symtab_section
,
1240 text_section
->data_offset
, 0,
1241 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1242 text_section
->sh_num
, "_etext");
1243 add_elf_sym(symtab_section
,
1244 data_section
->data_offset
, 0,
1245 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1246 data_section
->sh_num
, "_edata");
1247 add_elf_sym(symtab_section
,
1248 bss_section
->data_offset
, 0,
1249 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1250 bss_section
->sh_num
, "_end");
1251 /* horrible new standard ldscript defines */
1252 add_init_array_defines(s1
, ".preinit_array");
1253 add_init_array_defines(s1
, ".init_array");
1254 add_init_array_defines(s1
, ".fini_array");
1256 /* add start and stop symbols for sections whose name can be
1258 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1259 s
= s1
->sections
[i
];
1260 if (s
->sh_type
== SHT_PROGBITS
&&
1261 (s
->sh_flags
& SHF_ALLOC
)) {
1265 /* check if section name can be expressed in C */
1271 if (!isid(ch
) && !isnum(ch
))
1275 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1276 add_elf_sym(symtab_section
,
1278 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1280 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1281 add_elf_sym(symtab_section
,
1283 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1290 /* name of ELF interpreter */
1292 static char elf_interp
[] = "/usr/libexec/ld-elf.so.1";
1295 static char elf_interp
[] = "/lib/ld-linux.so.3";
1296 #elif defined(TCC_TARGET_X86_64)
1297 static char elf_interp
[] = "/lib/ld-linux-x86-64.so.2";
1299 static char elf_interp
[] = "/lib/ld-linux.so.2";
1303 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1304 const int *section_order
)
1307 int i
, offset
, size
;
1310 for(i
=1;i
<s1
->nb_sections
;i
++) {
1311 s
= s1
->sections
[section_order
[i
]];
1312 if (s
->sh_type
!= SHT_NOBITS
&&
1313 (s
->sh_flags
& SHF_ALLOC
)) {
1314 while (offset
< s
->sh_offset
) {
1319 fwrite(s
->data
, 1, size
, f
);
1325 /* output an ELF file */
1326 /* XXX: suppress unneeded sections */
1327 int elf_output_file(TCCState
*s1
, const char *filename
)
1333 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1335 Section
*strsec
, *s
;
1336 ElfW(Shdr
) shdr
, *sh
;
1337 ElfW(Phdr
) *phdr
, *ph
;
1338 Section
*interp
, *dynamic
, *dynstr
;
1339 unsigned long saved_dynamic_data_offset
;
1341 int type
, file_type
;
1342 unsigned long rel_addr
, rel_size
;
1344 file_type
= s1
->output_type
;
1347 if (file_type
!= TCC_OUTPUT_OBJ
) {
1348 tcc_add_runtime(s1
);
1352 section_order
= NULL
;
1355 dynstr
= NULL
; /* avoid warning */
1356 saved_dynamic_data_offset
= 0; /* avoid warning */
1358 if (file_type
!= TCC_OUTPUT_OBJ
) {
1359 relocate_common_syms();
1361 tcc_add_linker_symbols(s1
);
1363 if (!s1
->static_link
) {
1365 int sym_index
, index
;
1366 ElfW(Sym
) *esym
, *sym_end
;
1368 if (file_type
== TCC_OUTPUT_EXE
) {
1370 /* add interpreter section only if executable */
1371 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1372 interp
->sh_addralign
= 1;
1373 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
1374 strcpy(ptr
, elf_interp
);
1377 /* add dynamic symbol table */
1378 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1380 ".hash", SHF_ALLOC
);
1381 dynstr
= s1
->dynsym
->link
;
1383 /* add dynamic section */
1384 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1385 SHF_ALLOC
| SHF_WRITE
);
1386 dynamic
->link
= dynstr
;
1387 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1390 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1391 SHF_ALLOC
| SHF_EXECINSTR
);
1392 s1
->plt
->sh_entsize
= 4;
1396 /* scan for undefined symbols and see if they are in the
1397 dynamic symbols. If a symbol STT_FUNC is found, then we
1398 add it in the PLT. If a symbol STT_OBJECT is found, we
1399 add it in the .bss section with a suitable relocation */
1400 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1401 symtab_section
->data_offset
);
1402 if (file_type
== TCC_OUTPUT_EXE
) {
1403 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1406 if (sym
->st_shndx
== SHN_UNDEF
) {
1407 name
= symtab_section
->link
->data
+ sym
->st_name
;
1408 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1410 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1411 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1412 if (type
== STT_FUNC
) {
1413 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1415 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1416 } else if (type
== STT_OBJECT
) {
1417 unsigned long offset
;
1418 offset
= bss_section
->data_offset
;
1419 /* XXX: which alignment ? */
1420 offset
= (offset
+ 16 - 1) & -16;
1421 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1423 bss_section
->sh_num
, name
);
1424 put_elf_reloc(s1
->dynsym
, bss_section
,
1425 offset
, R_COPY
, index
);
1426 offset
+= esym
->st_size
;
1427 bss_section
->data_offset
= offset
;
1430 /* STB_WEAK undefined symbols are accepted */
1431 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1433 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1434 !strcmp(name
, "_fp_hw")) {
1436 error_noabort("undefined symbol '%s'", name
);
1439 } else if (s1
->rdynamic
&&
1440 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1441 /* if -rdynamic option, then export all non
1443 name
= symtab_section
->link
->data
+ sym
->st_name
;
1444 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1446 sym
->st_shndx
, name
);
1453 /* now look at unresolved dynamic symbols and export
1454 corresponding symbol */
1455 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1456 s1
->dynsymtab_section
->data_offset
);
1457 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1460 if (esym
->st_shndx
== SHN_UNDEF
) {
1461 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1462 sym_index
= find_elf_sym(symtab_section
, name
);
1464 /* XXX: avoid adding a symbol if already
1465 present because of -rdynamic ? */
1466 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1467 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1469 sym
->st_shndx
, name
);
1471 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1472 /* weak symbols can stay undefined */
1474 warning("undefined dynamic symbol '%s'", name
);
1481 /* shared library case : we simply export all the global symbols */
1482 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1483 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1484 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1487 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1488 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1489 if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
&&
1490 sym
->st_shndx
== SHN_UNDEF
) {
1491 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1493 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1495 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1496 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1498 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1503 name
= symtab_section
->link
->data
+ sym
->st_name
;
1504 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1506 sym
->st_shndx
, name
);
1507 s1
->symtab_to_dynsym
[sym
-
1508 (ElfW(Sym
) *)symtab_section
->data
] =
1515 build_got_entries(s1
);
1517 /* add a list of needed dlls */
1518 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1519 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1520 if (dllref
->level
== 0)
1521 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1523 /* XXX: currently, since we do not handle PIC code, we
1524 must relocate the readonly segments */
1525 if (file_type
== TCC_OUTPUT_DLL
) {
1527 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1528 put_dt(dynamic
, DT_TEXTREL
, 0);
1531 /* add necessary space for other entries */
1532 saved_dynamic_data_offset
= dynamic
->data_offset
;
1533 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * 9;
1535 /* still need to build got entries in case of static link */
1536 build_got_entries(s1
);
1540 memset(&ehdr
, 0, sizeof(ehdr
));
1542 /* we add a section for symbols */
1543 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1544 put_elf_str(strsec
, "");
1546 /* compute number of sections */
1547 shnum
= s1
->nb_sections
;
1549 /* this array is used to reorder sections in the output file */
1550 section_order
= tcc_malloc(sizeof(int) * shnum
);
1551 section_order
[0] = 0;
1554 /* compute number of program headers */
1557 case TCC_OUTPUT_OBJ
:
1560 case TCC_OUTPUT_EXE
:
1561 if (!s1
->static_link
)
1566 case TCC_OUTPUT_DLL
:
1571 /* allocate strings for section names and decide if an unallocated
1572 section should be output */
1573 /* NOTE: the strsec section comes last, so its size is also
1575 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1576 s
= s1
->sections
[i
];
1577 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1579 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1584 s
->reloc
? s
->reloc
->name
: "n"
1587 /* when generating a DLL, we include relocations but we may
1589 if (file_type
== TCC_OUTPUT_DLL
&&
1590 s
->sh_type
== SHT_RELX
&&
1591 !(s
->sh_flags
& SHF_ALLOC
)) {
1592 /* //gr: avoid bogus relocs for empty (debug) sections */
1593 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1594 prepare_dynamic_rel(s1
, s
);
1596 s
->sh_size
= s
->data_offset
;
1597 } else if (do_debug
||
1598 file_type
== TCC_OUTPUT_OBJ
||
1599 (s
->sh_flags
& SHF_ALLOC
) ||
1600 i
== (s1
->nb_sections
- 1)) {
1601 /* we output all sections if debug or object file */
1602 s
->sh_size
= s
->data_offset
;
1606 /* allocate program segment headers */
1607 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1609 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1610 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1615 /* compute section to program header mapping */
1616 if (s1
->has_text_addr
) {
1617 int a_offset
, p_offset
;
1618 addr
= s1
->text_addr
;
1619 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1621 a_offset
= addr
& (ELF_PAGE_SIZE
- 1);
1622 p_offset
= file_offset
& (ELF_PAGE_SIZE
- 1);
1623 if (a_offset
< p_offset
)
1624 a_offset
+= ELF_PAGE_SIZE
;
1625 file_offset
+= (a_offset
- p_offset
);
1627 if (file_type
== TCC_OUTPUT_DLL
)
1630 addr
= ELF_START_ADDR
;
1631 /* compute address after headers */
1632 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1635 /* dynamic relocation table information, for .dynamic section */
1639 /* leave one program header for the program interpreter */
1644 for(j
= 0; j
< 2; j
++) {
1645 ph
->p_type
= PT_LOAD
;
1647 ph
->p_flags
= PF_R
| PF_X
;
1649 ph
->p_flags
= PF_R
| PF_W
;
1650 ph
->p_align
= ELF_PAGE_SIZE
;
1652 /* we do the following ordering: interp, symbol tables,
1653 relocations, progbits, nobits */
1654 /* XXX: do faster and simpler sorting */
1655 for(k
= 0; k
< 5; k
++) {
1656 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1657 s
= s1
->sections
[i
];
1658 /* compute if section should be included */
1660 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1664 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1665 (SHF_ALLOC
| SHF_WRITE
))
1671 } else if (s
->sh_type
== SHT_DYNSYM
||
1672 s
->sh_type
== SHT_STRTAB
||
1673 s
->sh_type
== SHT_HASH
) {
1676 } else if (s
->sh_type
== SHT_RELX
) {
1679 } else if (s
->sh_type
== SHT_NOBITS
) {
1686 section_order
[sh_order_index
++] = i
;
1688 /* section matches: we align it and add its size */
1690 addr
= (addr
+ s
->sh_addralign
- 1) &
1691 ~(s
->sh_addralign
- 1);
1692 file_offset
+= addr
- tmp
;
1693 s
->sh_offset
= file_offset
;
1696 /* update program header infos */
1697 if (ph
->p_offset
== 0) {
1698 ph
->p_offset
= file_offset
;
1700 ph
->p_paddr
= ph
->p_vaddr
;
1702 /* update dynamic relocation infos */
1703 if (s
->sh_type
== SHT_RELX
) {
1706 rel_size
+= s
->sh_size
;
1709 if (s
->sh_type
!= SHT_NOBITS
)
1710 file_offset
+= s
->sh_size
;
1713 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1714 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1717 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1718 /* if in the middle of a page, we duplicate the page in
1719 memory so that one copy is RX and the other is RW */
1720 if ((addr
& (ELF_PAGE_SIZE
- 1)) != 0)
1721 addr
+= ELF_PAGE_SIZE
;
1723 addr
= (addr
+ ELF_PAGE_SIZE
- 1) & ~(ELF_PAGE_SIZE
- 1);
1724 file_offset
= (file_offset
+ ELF_PAGE_SIZE
- 1) &
1725 ~(ELF_PAGE_SIZE
- 1);
1730 /* if interpreter, then add corresponing program header */
1734 ph
->p_type
= PT_INTERP
;
1735 ph
->p_offset
= interp
->sh_offset
;
1736 ph
->p_vaddr
= interp
->sh_addr
;
1737 ph
->p_paddr
= ph
->p_vaddr
;
1738 ph
->p_filesz
= interp
->sh_size
;
1739 ph
->p_memsz
= interp
->sh_size
;
1741 ph
->p_align
= interp
->sh_addralign
;
1744 /* if dynamic section, then add corresponing program header */
1748 ph
= &phdr
[phnum
- 1];
1750 ph
->p_type
= PT_DYNAMIC
;
1751 ph
->p_offset
= dynamic
->sh_offset
;
1752 ph
->p_vaddr
= dynamic
->sh_addr
;
1753 ph
->p_paddr
= ph
->p_vaddr
;
1754 ph
->p_filesz
= dynamic
->sh_size
;
1755 ph
->p_memsz
= dynamic
->sh_size
;
1756 ph
->p_flags
= PF_R
| PF_W
;
1757 ph
->p_align
= dynamic
->sh_addralign
;
1759 /* put GOT dynamic section address */
1760 put32(s1
->got
->data
, dynamic
->sh_addr
);
1762 /* relocate the PLT */
1763 if (file_type
== TCC_OUTPUT_EXE
1764 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1765 || file_type
== TCC_OUTPUT_DLL
1771 p_end
= p
+ s1
->plt
->data_offset
;
1773 #if defined(TCC_TARGET_I386)
1774 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1775 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1778 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1781 #elif defined(TCC_TARGET_X86_64)
1782 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1783 put32(p
+ 2, get32(p
+ 2) + x
);
1784 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1787 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1790 #elif defined(TCC_TARGET_ARM)
1792 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1795 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1798 #elif defined(TCC_TARGET_C67)
1801 #error unsupported CPU
1806 /* relocate symbols in .dynsym */
1807 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1808 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1811 if (sym
->st_shndx
== SHN_UNDEF
) {
1812 /* relocate to the PLT if the symbol corresponds
1815 sym
->st_value
+= s1
->plt
->sh_addr
;
1816 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1817 /* do symbol relocation */
1818 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1822 /* put dynamic section entries */
1823 dynamic
->data_offset
= saved_dynamic_data_offset
;
1824 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1825 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1826 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1827 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1828 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1829 #ifdef TCC_TARGET_X86_64
1830 put_dt(dynamic
, DT_RELA
, rel_addr
);
1831 put_dt(dynamic
, DT_RELASZ
, rel_size
);
1832 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1834 put_dt(dynamic
, DT_REL
, rel_addr
);
1835 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1836 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1839 put_dt(dynamic
, DT_DEBUG
, 0);
1840 put_dt(dynamic
, DT_NULL
, 0);
1843 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1844 ehdr
.e_phnum
= phnum
;
1845 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1848 /* all other sections come after */
1849 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1850 s
= s1
->sections
[i
];
1851 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1853 section_order
[sh_order_index
++] = i
;
1855 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1856 ~(s
->sh_addralign
- 1);
1857 s
->sh_offset
= file_offset
;
1858 if (s
->sh_type
!= SHT_NOBITS
)
1859 file_offset
+= s
->sh_size
;
1862 /* if building executable or DLL, then relocate each section
1863 except the GOT which is already relocated */
1864 if (file_type
!= TCC_OUTPUT_OBJ
) {
1865 relocate_syms(s1
, 0);
1867 if (s1
->nb_errors
!= 0) {
1873 /* relocate sections */
1874 /* XXX: ignore sections with allocated relocations ? */
1875 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1876 s
= s1
->sections
[i
];
1877 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1878 relocate_section(s1
, s
);
1881 /* relocate relocation entries if the relocation tables are
1882 allocated in the executable */
1883 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1884 s
= s1
->sections
[i
];
1885 if ((s
->sh_flags
& SHF_ALLOC
) &&
1886 s
->sh_type
== SHT_RELX
) {
1887 relocate_rel(s1
, s
);
1891 /* get entry point address */
1892 if (file_type
== TCC_OUTPUT_EXE
)
1893 ehdr
.e_entry
= (unsigned long)tcc_get_symbol_err(s1
, "_start");
1895 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1898 /* write elf file */
1899 if (file_type
== TCC_OUTPUT_OBJ
)
1903 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1905 error_noabort("could not write '%s'", filename
);
1908 f
= fdopen(fd
, "wb");
1910 printf("<- %s\n", filename
);
1912 #ifdef TCC_TARGET_COFF
1913 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1914 tcc_output_coff(s1
, f
);
1917 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1918 sort_syms(s1
, symtab_section
);
1921 file_offset
= (file_offset
+ 3) & -4;
1924 ehdr
.e_ident
[0] = ELFMAG0
;
1925 ehdr
.e_ident
[1] = ELFMAG1
;
1926 ehdr
.e_ident
[2] = ELFMAG2
;
1927 ehdr
.e_ident
[3] = ELFMAG3
;
1928 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
1929 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1930 ehdr
.e_ident
[6] = EV_CURRENT
;
1932 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1934 #ifdef TCC_TARGET_ARM
1936 ehdr
.e_ident
[EI_OSABI
] = 0;
1937 ehdr
.e_flags
= 4 << 24;
1939 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
1944 case TCC_OUTPUT_EXE
:
1945 ehdr
.e_type
= ET_EXEC
;
1947 case TCC_OUTPUT_DLL
:
1948 ehdr
.e_type
= ET_DYN
;
1950 case TCC_OUTPUT_OBJ
:
1951 ehdr
.e_type
= ET_REL
;
1954 ehdr
.e_machine
= EM_TCC_TARGET
;
1955 ehdr
.e_version
= EV_CURRENT
;
1956 ehdr
.e_shoff
= file_offset
;
1957 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
1958 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
1959 ehdr
.e_shnum
= shnum
;
1960 ehdr
.e_shstrndx
= shnum
- 1;
1962 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
1963 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
1964 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1966 for(i
=1;i
<s1
->nb_sections
;i
++) {
1967 s
= s1
->sections
[section_order
[i
]];
1968 if (s
->sh_type
!= SHT_NOBITS
) {
1969 while (offset
< s
->sh_offset
) {
1974 fwrite(s
->data
, 1, size
, f
);
1979 /* output section headers */
1980 while (offset
< ehdr
.e_shoff
) {
1985 for(i
=0;i
<s1
->nb_sections
;i
++) {
1987 memset(sh
, 0, sizeof(ElfW(Shdr
)));
1988 s
= s1
->sections
[i
];
1990 sh
->sh_name
= s
->sh_name
;
1991 sh
->sh_type
= s
->sh_type
;
1992 sh
->sh_flags
= s
->sh_flags
;
1993 sh
->sh_entsize
= s
->sh_entsize
;
1994 sh
->sh_info
= s
->sh_info
;
1996 sh
->sh_link
= s
->link
->sh_num
;
1997 sh
->sh_addralign
= s
->sh_addralign
;
1998 sh
->sh_addr
= s
->sh_addr
;
1999 sh
->sh_offset
= s
->sh_offset
;
2000 sh
->sh_size
= s
->sh_size
;
2002 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2005 tcc_output_binary(s1
, f
, section_order
);
2011 tcc_free(s1
->symtab_to_dynsym
);
2012 tcc_free(section_order
);
2014 tcc_free(s1
->got_offsets
);
2018 int tcc_output_file(TCCState
*s
, const char *filename
)
2021 #ifdef TCC_TARGET_PE
2022 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2023 ret
= pe_output_file(s
, filename
);
2027 ret
= elf_output_file(s
, filename
);
2032 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2036 data
= tcc_malloc(size
);
2037 lseek(fd
, file_offset
, SEEK_SET
);
2038 read(fd
, data
, size
);
2042 typedef struct SectionMergeInfo
{
2043 Section
*s
; /* corresponding existing section */
2044 unsigned long offset
; /* offset of the new section in the existing section */
2045 uint8_t new_section
; /* true if section 's' was added */
2046 uint8_t link_once
; /* true if link once section */
2049 /* load an object file and merge it with current files */
2050 /* XXX: handle correctly stab (debug) info */
2051 static int tcc_load_object_file(TCCState
*s1
,
2052 int fd
, unsigned long file_offset
)
2055 ElfW(Shdr
) *shdr
, *sh
;
2056 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2057 unsigned char *strsec
, *strtab
;
2058 int *old_to_new_syms
;
2059 char *sh_name
, *name
;
2060 SectionMergeInfo
*sm_table
, *sm
;
2061 ElfW(Sym
) *sym
, *symtab
;
2062 ElfW_Rel
*rel
, *rel_end
;
2068 stab_index
= stabstr_index
= 0;
2070 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2072 if (ehdr
.e_ident
[0] != ELFMAG0
||
2073 ehdr
.e_ident
[1] != ELFMAG1
||
2074 ehdr
.e_ident
[2] != ELFMAG2
||
2075 ehdr
.e_ident
[3] != ELFMAG3
)
2077 /* test if object file */
2078 if (ehdr
.e_type
!= ET_REL
)
2080 /* test CPU specific stuff */
2081 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2082 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2084 error_noabort("invalid object file");
2088 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2089 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2090 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2092 /* load section names */
2093 sh
= &shdr
[ehdr
.e_shstrndx
];
2094 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2096 /* load symtab and strtab */
2097 old_to_new_syms
= NULL
;
2101 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2103 if (sh
->sh_type
== SHT_SYMTAB
) {
2105 error_noabort("object must contain only one symtab");
2110 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2111 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2112 sm_table
[i
].s
= symtab_section
;
2114 /* now load strtab */
2115 sh
= &shdr
[sh
->sh_link
];
2116 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2120 /* now examine each section and try to merge its content with the
2122 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2123 /* no need to examine section name strtab */
2124 if (i
== ehdr
.e_shstrndx
)
2127 sh_name
= strsec
+ sh
->sh_name
;
2128 /* ignore sections types we do not handle */
2129 if (sh
->sh_type
!= SHT_PROGBITS
&&
2130 sh
->sh_type
!= SHT_RELX
&&
2132 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2134 sh
->sh_type
!= SHT_NOBITS
&&
2135 strcmp(sh_name
, ".stabstr")
2138 if (sh
->sh_addralign
< 1)
2139 sh
->sh_addralign
= 1;
2140 /* find corresponding section, if any */
2141 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2142 s
= s1
->sections
[j
];
2143 if (!strcmp(s
->name
, sh_name
)) {
2144 if (!strncmp(sh_name
, ".gnu.linkonce",
2145 sizeof(".gnu.linkonce") - 1)) {
2146 /* if a 'linkonce' section is already present, we
2147 do not add it again. It is a little tricky as
2148 symbols can still be defined in
2150 sm_table
[i
].link_once
= 1;
2157 /* not found: create new section */
2158 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2159 /* take as much info as possible from the section. sh_link and
2160 sh_info will be updated later */
2161 s
->sh_addralign
= sh
->sh_addralign
;
2162 s
->sh_entsize
= sh
->sh_entsize
;
2163 sm_table
[i
].new_section
= 1;
2165 if (sh
->sh_type
!= s
->sh_type
) {
2166 error_noabort("invalid section type");
2170 /* align start of section */
2171 offset
= s
->data_offset
;
2173 if (0 == strcmp(sh_name
, ".stab")) {
2177 if (0 == strcmp(sh_name
, ".stabstr")) {
2182 size
= sh
->sh_addralign
- 1;
2183 offset
= (offset
+ size
) & ~size
;
2184 if (sh
->sh_addralign
> s
->sh_addralign
)
2185 s
->sh_addralign
= sh
->sh_addralign
;
2186 s
->data_offset
= offset
;
2188 sm_table
[i
].offset
= offset
;
2190 /* concatenate sections */
2192 if (sh
->sh_type
!= SHT_NOBITS
) {
2194 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2195 ptr
= section_ptr_add(s
, size
);
2196 read(fd
, ptr
, size
);
2198 s
->data_offset
+= size
;
2203 /* //gr relocate stab strings */
2204 if (stab_index
&& stabstr_index
) {
2207 s
= sm_table
[stab_index
].s
;
2208 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2209 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2210 o
= sm_table
[stabstr_index
].offset
;
2212 a
->n_strx
+= o
, a
++;
2215 /* second short pass to update sh_link and sh_info fields of new
2217 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2219 if (!s
|| !sm_table
[i
].new_section
)
2222 if (sh
->sh_link
> 0)
2223 s
->link
= sm_table
[sh
->sh_link
].s
;
2224 if (sh
->sh_type
== SHT_RELX
) {
2225 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2226 /* update backward link */
2227 s1
->sections
[s
->sh_info
]->reloc
= s
;
2232 /* resolve symbols */
2233 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2236 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2237 if (sym
->st_shndx
!= SHN_UNDEF
&&
2238 sym
->st_shndx
< SHN_LORESERVE
) {
2239 sm
= &sm_table
[sym
->st_shndx
];
2240 if (sm
->link_once
) {
2241 /* if a symbol is in a link once section, we use the
2242 already defined symbol. It is very important to get
2243 correct relocations */
2244 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2245 name
= strtab
+ sym
->st_name
;
2246 sym_index
= find_elf_sym(symtab_section
, name
);
2248 old_to_new_syms
[i
] = sym_index
;
2252 /* if no corresponding section added, no need to add symbol */
2255 /* convert section number */
2256 sym
->st_shndx
= sm
->s
->sh_num
;
2258 sym
->st_value
+= sm
->offset
;
2261 name
= strtab
+ sym
->st_name
;
2262 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2263 sym
->st_info
, sym
->st_other
,
2264 sym
->st_shndx
, name
);
2265 old_to_new_syms
[i
] = sym_index
;
2268 /* third pass to patch relocation entries */
2269 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2274 offset
= sm_table
[i
].offset
;
2275 switch(s
->sh_type
) {
2277 /* take relocation offset information */
2278 offseti
= sm_table
[sh
->sh_info
].offset
;
2279 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2280 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2285 /* convert symbol index */
2286 type
= ELFW(R_TYPE
)(rel
->r_info
);
2287 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2288 /* NOTE: only one symtab assumed */
2289 if (sym_index
>= nb_syms
)
2291 sym_index
= old_to_new_syms
[sym_index
];
2292 /* ignore link_once in rel section. */
2293 if (!sym_index
&& !sm
->link_once
) {
2295 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2296 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2299 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2300 /* offset the relocation offset */
2301 rel
->r_offset
+= offseti
;
2313 tcc_free(old_to_new_syms
);
2320 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2322 typedef struct ArchiveHeader
{
2323 char ar_name
[16]; /* name of this member */
2324 char ar_date
[12]; /* file mtime */
2325 char ar_uid
[6]; /* owner uid; printed as decimal */
2326 char ar_gid
[6]; /* owner gid; printed as decimal */
2327 char ar_mode
[8]; /* file mode, printed as octal */
2328 char ar_size
[10]; /* file size, printed as decimal */
2329 char ar_fmag
[2]; /* should contain ARFMAG */
2332 static int get_be32(const uint8_t *b
)
2334 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2337 /* load only the objects which resolve undefined symbols */
2338 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2340 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2342 const char *ar_names
, *p
;
2343 const uint8_t *ar_index
;
2346 data
= tcc_malloc(size
);
2347 if (read(fd
, data
, size
) != size
)
2349 nsyms
= get_be32(data
);
2350 ar_index
= data
+ 4;
2351 ar_names
= ar_index
+ nsyms
* 4;
2355 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2356 sym_index
= find_elf_sym(symtab_section
, p
);
2358 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2359 if(sym
->st_shndx
== SHN_UNDEF
) {
2360 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2362 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2365 lseek(fd
, off
, SEEK_SET
);
2366 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2381 /* load a '.a' file */
2382 static int tcc_load_archive(TCCState
*s1
, int fd
)
2389 unsigned long file_offset
;
2391 /* skip magic which was already checked */
2392 read(fd
, magic
, sizeof(magic
));
2395 len
= read(fd
, &hdr
, sizeof(hdr
));
2398 if (len
!= sizeof(hdr
)) {
2399 error_noabort("invalid archive");
2402 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2403 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2404 size
= strtol(ar_size
, NULL
, 0);
2405 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2406 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2407 if (ar_name
[i
] != ' ')
2410 ar_name
[i
+ 1] = '\0';
2411 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2412 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2414 size
= (size
+ 1) & ~1;
2415 if (!strcmp(ar_name
, "/")) {
2416 /* coff symbol table : we handle it */
2417 if(s1
->alacarte_link
)
2418 return tcc_load_alacarte(s1
, fd
, size
);
2419 } else if (!strcmp(ar_name
, "//") ||
2420 !strcmp(ar_name
, "__.SYMDEF") ||
2421 !strcmp(ar_name
, "__.SYMDEF/") ||
2422 !strcmp(ar_name
, "ARFILENAMES/")) {
2423 /* skip symbol table or archive names */
2425 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2428 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2433 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2434 is referenced by the user (so it should be added as DT_NEEDED in
2435 the generated ELF file) */
2436 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2439 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2440 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2441 ElfW(Sym
) *sym
, *dynsym
;
2442 ElfW(Dyn
) *dt
, *dynamic
;
2443 unsigned char *dynstr
;
2444 const char *name
, *soname
;
2445 DLLReference
*dllref
;
2447 read(fd
, &ehdr
, sizeof(ehdr
));
2449 /* test CPU specific stuff */
2450 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2451 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2452 error_noabort("bad architecture");
2457 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2459 /* load dynamic section and dynamic symbols */
2463 dynsym
= NULL
; /* avoid warning */
2464 dynstr
= NULL
; /* avoid warning */
2465 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2466 switch(sh
->sh_type
) {
2468 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2469 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2472 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2473 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2474 sh1
= &shdr
[sh
->sh_link
];
2475 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2482 /* compute the real library name */
2483 soname
= tcc_basename(filename
);
2485 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2486 if (dt
->d_tag
== DT_SONAME
) {
2487 soname
= dynstr
+ dt
->d_un
.d_val
;
2491 /* if the dll is already loaded, do not load it */
2492 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2493 dllref
= s1
->loaded_dlls
[i
];
2494 if (!strcmp(soname
, dllref
->name
)) {
2495 /* but update level if needed */
2496 if (level
< dllref
->level
)
2497 dllref
->level
= level
;
2503 // printf("loading dll '%s'\n", soname);
2505 /* add the dll and its level */
2506 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2507 dllref
->level
= level
;
2508 strcpy(dllref
->name
, soname
);
2509 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2511 /* add dynamic symbols in dynsym_section */
2512 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2513 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2514 if (sym_bind
== STB_LOCAL
)
2516 name
= dynstr
+ sym
->st_name
;
2517 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2518 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2521 /* load all referenced DLLs */
2522 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2525 name
= dynstr
+ dt
->d_un
.d_val
;
2526 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2527 dllref
= s1
->loaded_dlls
[j
];
2528 if (!strcmp(name
, dllref
->name
))
2529 goto already_loaded
;
2531 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2532 error_noabort("referenced dll '%s' not found", name
);
2549 #define LD_TOK_NAME 256
2550 #define LD_TOK_EOF (-1)
2552 /* return next ld script token */
2553 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2571 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2572 ch
= file
->buf_ptr
[0];
2580 /* case 'a' ... 'z': */
2607 /* case 'A' ... 'z': */
2642 if (!((ch
>= 'a' && ch
<= 'z') ||
2643 (ch
>= 'A' && ch
<= 'Z') ||
2644 (ch
>= '0' && ch
<= '9') ||
2645 strchr("/.-_+=$:\\,~", ch
)))
2647 if ((q
- name
) < name_size
- 1) {
2664 printf("tok=%c %d\n", c
, c
);
2665 if (c
== LD_TOK_NAME
)
2666 printf(" name=%s\n", name
);
2671 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2673 char filename
[1024];
2676 t
= ld_next(s1
, filename
, sizeof(filename
));
2679 t
= ld_next(s1
, filename
, sizeof(filename
));
2681 if (t
== LD_TOK_EOF
) {
2682 error_noabort("unexpected end of file");
2684 } else if (t
== ')') {
2686 } else if (t
!= LD_TOK_NAME
) {
2687 error_noabort("filename expected");
2690 if (!strcmp(filename
, "AS_NEEDED")) {
2691 ret
= ld_add_file_list(s1
, 1);
2695 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2697 tcc_add_file(s1
, filename
);
2699 t
= ld_next(s1
, filename
, sizeof(filename
));
2701 t
= ld_next(s1
, filename
, sizeof(filename
));
2707 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2709 static int tcc_load_ldscript(TCCState
*s1
)
2712 char filename
[1024];
2715 ch
= file
->buf_ptr
[0];
2718 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2719 if (t
== LD_TOK_EOF
)
2721 else if (t
!= LD_TOK_NAME
)
2723 if (!strcmp(cmd
, "INPUT") ||
2724 !strcmp(cmd
, "GROUP")) {
2725 ret
= ld_add_file_list(s1
, 0);
2728 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2729 !strcmp(cmd
, "TARGET")) {
2730 /* ignore some commands */
2731 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2735 t
= ld_next(s1
, filename
, sizeof(filename
));
2736 if (t
== LD_TOK_EOF
) {
2737 error_noabort("unexpected end of file");
2739 } else if (t
== ')') {