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
;
506 #define GOT_TABLE_ENTRY_MAX_NUM 4096
507 static unsigned long add_got_table(TCCState
*s1
, unsigned long val
)
510 if (!s1
->got_table
) {
511 int size
= sizeof(void *) * GOT_TABLE_ENTRY_MAX_NUM
;
512 s1
->got_table_num
= 0;
513 s1
->got_table
= (char *)tcc_malloc(size
);
515 if (s1
->got_table_num
== GOT_TABLE_ENTRY_MAX_NUM
) {
516 error("relocating >%d symbols are not supported",
517 GOT_TABLE_ENTRY_MAX_NUM
);
519 p
= s1
->got_table
+ s1
->got_table_num
;
522 return (unsigned long)p
;
526 /* relocate a given section (CPU dependent) */
527 static void relocate_section(TCCState
*s1
, Section
*s
)
530 ElfW_Rel
*rel
, *rel_end
, *qrel
;
534 unsigned long val
, addr
;
538 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
539 qrel
= (ElfW_Rel
*)sr
->data
;
543 ptr
= s
->data
+ rel
->r_offset
;
545 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
546 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
548 #ifdef TCC_TARGET_X86_64
549 /* XXX: not tested */
550 val
+= rel
->r_addend
;
552 type
= ELFW(R_TYPE
)(rel
->r_info
);
553 addr
= s
->sh_addr
+ rel
->r_offset
;
557 #if defined(TCC_TARGET_I386)
559 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
560 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
561 qrel
->r_offset
= rel
->r_offset
;
563 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_32
);
567 qrel
->r_info
= ELFW(R_INFO
)(0, R_386_RELATIVE
);
574 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
576 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
578 qrel
->r_offset
= rel
->r_offset
;
579 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_PC32
);
584 *(int *)ptr
+= val
- addr
;
587 *(int *)ptr
+= val
- addr
;
594 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
597 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
600 /* we load the got offset */
601 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
603 #elif defined(TCC_TARGET_ARM)
610 x
= (*(int *)ptr
)&0xffffff;
611 (*(int *)ptr
) &= 0xff000000;
616 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
617 error("can't relocate value at %x",addr
);
626 x
= (*(int *)ptr
) & 0x7fffffff;
627 (*(int *)ptr
) &= 0x80000000;
630 if((x
^(x
>>1))&0x40000000)
631 error("can't relocate value at %x",addr
);
632 (*(int *)ptr
) |= x
& 0x7fffffff;
637 case R_ARM_BASE_PREL
:
638 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
641 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
644 /* we load the got offset */
645 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
650 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
651 type
,addr
,(unsigned int )ptr
,val
);
653 #elif defined(TCC_TARGET_C67)
661 /* put the low 16 bits of the absolute address */
662 // add to what is already there
664 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
665 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
667 //patch both at once - assumes always in pairs Low - High
669 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
670 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
676 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
677 type
,addr
,(unsigned int )ptr
,val
);
679 #elif defined(TCC_TARGET_X86_64)
681 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
682 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
683 qrel
->r_addend
= *(long long *)ptr
+ val
;
686 *(long long *)ptr
+= val
;
690 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
691 /* XXX: this logic may depend on TCC's codegen
692 now TCC uses R_X86_64_32 even for a 64bit pointer */
693 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
694 qrel
->r_addend
= *(int *)ptr
+ val
;
699 case R_X86_64_PC32
: {
700 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
702 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
704 qrel
->r_offset
= rel
->r_offset
;
705 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_X86_64_PC32
);
706 qrel
->r_addend
= *(int *)ptr
;
711 long diff
= val
- addr
;
712 if (diff
< -2147483648 || diff
> 2147483647) {
713 /* XXX: naive support for over 32bit jump */
714 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
715 val
= add_jmp_table(s1
, val
);
718 if (diff
<= -2147483647 || diff
> 2147483647) {
720 /* output memory map to debug easily */
725 printf("%ld - %ld = %ld\n", val
, addr
, diff
);
726 dladdr((void *)addr
, &di
);
727 printf("addr = %lx = %lx+%lx(%s) ptr=%p\n",
728 addr
, s
->sh_addr
, rel
->r_offset
, di
.dli_sname
,
730 fp
= fopen("/proc/self/maps", "r");
731 size
= fread(buf
, 1, 4095, fp
);
735 error("internal error: relocation failed");
742 *(int *)ptr
+= val
- addr
;
744 case R_X86_64_GLOB_DAT
:
745 case R_X86_64_JUMP_SLOT
:
748 case R_X86_64_GOTPCREL
:
749 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
750 val
= add_got_table(s1
, val
- rel
->r_addend
) + rel
->r_addend
;
751 *(int *)ptr
+= val
- addr
;
754 *(int *)ptr
+= (s1
->got
->sh_addr
- addr
+
755 s1
->got_offsets
[sym_index
] - 4);
757 case R_X86_64_GOTTPOFF
:
758 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
761 /* we load the got offset */
762 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
765 #error unsupported processor
769 /* if the relocation is allocated, we change its symbol table */
770 if (sr
->sh_flags
& SHF_ALLOC
)
771 sr
->link
= s1
->dynsym
;
774 /* relocate relocation table in 'sr' */
775 static void relocate_rel(TCCState
*s1
, Section
*sr
)
778 ElfW_Rel
*rel
, *rel_end
;
780 s
= s1
->sections
[sr
->sh_info
];
781 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
782 for(rel
= (ElfW_Rel
*)sr
->data
;
785 rel
->r_offset
+= s
->sh_addr
;
789 /* count the number of dynamic relocations so that we can reserve
791 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
793 ElfW_Rel
*rel
, *rel_end
;
794 int sym_index
, esym_index
, type
, count
;
797 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
798 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
799 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
800 type
= ELFW(R_TYPE
)(rel
->r_info
);
802 #if defined(TCC_TARGET_I386)
804 #elif defined(TCC_TARGET_X86_64)
811 #if defined(TCC_TARGET_I386)
813 #elif defined(TCC_TARGET_X86_64)
816 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
825 /* allocate the section */
826 sr
->sh_flags
|= SHF_ALLOC
;
827 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
832 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
837 if (index
>= s1
->nb_got_offsets
) {
838 /* find immediately bigger power of 2 and reallocate array */
842 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
844 error("memory full");
845 s1
->got_offsets
= tab
;
846 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
847 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
848 s1
->nb_got_offsets
= n
;
850 s1
->got_offsets
[index
] = val
;
853 /* XXX: suppress that */
854 static void put32(unsigned char *p
, uint32_t val
)
862 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
863 defined(TCC_TARGET_X86_64)
864 static uint32_t get32(unsigned char *p
)
866 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
870 static void build_got(TCCState
*s1
)
874 /* if no got, then create it */
875 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
876 s1
->got
->sh_entsize
= 4;
877 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
878 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
879 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
881 /* keep space for _DYNAMIC pointer, if present */
883 /* two dummy got entries */
887 /* keep space for _DYNAMIC pointer, if present */
890 /* two dummy got entries */
898 /* put a got entry corresponding to a symbol in symtab_section. 'size'
899 and 'info' can be modifed if more precise info comes from the DLL */
900 static void put_got_entry(TCCState
*s1
,
901 int reloc_type
, unsigned long size
, int info
,
907 unsigned long offset
;
913 /* if a got entry already exists for that symbol, no need to add one */
914 if (sym_index
< s1
->nb_got_offsets
&&
915 s1
->got_offsets
[sym_index
] != 0)
918 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
921 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
922 name
= symtab_section
->link
->data
+ sym
->st_name
;
923 offset
= sym
->st_value
;
924 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
926 #ifdef TCC_TARGET_X86_64
936 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
939 /* if we build a DLL, we add a %ebx offset */
940 if (s1
->output_type
== TCC_OUTPUT_DLL
)
946 /* add a PLT entry */
948 if (plt
->data_offset
== 0) {
949 /* first plt entry */
950 p
= section_ptr_add(plt
, 16);
951 p
[0] = 0xff; /* pushl got + PTR_SIZE */
953 put32(p
+ 2, PTR_SIZE
);
954 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
956 put32(p
+ 8, PTR_SIZE
* 2);
959 p
= section_ptr_add(plt
, 16);
960 p
[0] = 0xff; /* jmp *(got + x) */
962 put32(p
+ 2, s1
->got
->data_offset
);
963 p
[6] = 0x68; /* push $xxx */
964 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
965 p
[11] = 0xe9; /* jmp plt_start */
966 put32(p
+ 12, -(plt
->data_offset
));
968 /* the symbol is modified so that it will be relocated to
970 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
971 if (s1
->output_type
== TCC_OUTPUT_EXE
)
973 offset
= plt
->data_offset
- 16;
975 #elif defined(TCC_TARGET_ARM)
976 if (reloc_type
== R_ARM_JUMP_SLOT
) {
980 /* if we build a DLL, we add a %ebx offset */
981 if (s1
->output_type
== TCC_OUTPUT_DLL
)
982 error("DLLs unimplemented!");
984 /* add a PLT entry */
986 if (plt
->data_offset
== 0) {
987 /* first plt entry */
988 p
= section_ptr_add(plt
, 16);
989 put32(p
, 0xe52de004);
990 put32(p
+ 4, 0xe59fe010);
991 put32(p
+ 8, 0xe08fe00e);
992 put32(p
+ 12, 0xe5bef008);
995 p
= section_ptr_add(plt
, 16);
996 put32(p
, 0xe59fc004);
997 put32(p
+4, 0xe08fc00c);
998 put32(p
+8, 0xe59cf000);
999 put32(p
+12, s1
->got
->data_offset
);
1001 /* the symbol is modified so that it will be relocated to
1003 if (s1
->output_type
== TCC_OUTPUT_EXE
)
1004 offset
= plt
->data_offset
- 16;
1006 #elif defined(TCC_TARGET_C67)
1007 error("C67 got not implemented");
1009 #error unsupported CPU
1011 index
= put_elf_sym(s1
->dynsym
, offset
,
1012 size
, info
, 0, sym
->st_shndx
, name
);
1013 /* put a got entry */
1014 put_elf_reloc(s1
->dynsym
, s1
->got
,
1015 s1
->got
->data_offset
,
1018 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
1022 /* build GOT and PLT entries */
1023 static void build_got_entries(TCCState
*s1
)
1025 Section
*s
, *symtab
;
1026 ElfW_Rel
*rel
, *rel_end
;
1028 int i
, type
, reloc_type
, sym_index
;
1030 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1031 s
= s1
->sections
[i
];
1032 if (s
->sh_type
!= SHT_RELX
)
1034 /* no need to handle got relocations */
1035 if (s
->link
!= symtab_section
)
1038 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
1039 for(rel
= (ElfW_Rel
*)s
->data
;
1042 type
= ELFW(R_TYPE
)(rel
->r_info
);
1044 #if defined(TCC_TARGET_I386)
1051 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1052 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1053 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1054 /* look at the symbol got offset. If none, then add one */
1055 if (type
== R_386_GOT32
)
1056 reloc_type
= R_386_GLOB_DAT
;
1058 reloc_type
= R_386_JMP_SLOT
;
1059 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1063 #elif defined(TCC_TARGET_ARM)
1064 case R_ARM_GOT_BREL
:
1065 case R_ARM_GOTOFF32
:
1066 case R_ARM_BASE_PREL
:
1070 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1071 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1072 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1073 /* look at the symbol got offset. If none, then add one */
1074 if (type
== R_ARM_GOT_BREL
)
1075 reloc_type
= R_ARM_GLOB_DAT
;
1077 reloc_type
= R_ARM_JUMP_SLOT
;
1078 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1082 #elif defined(TCC_TARGET_C67)
1089 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1090 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1091 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1092 /* look at the symbol got offset. If none, then add one */
1093 if (type
== R_C60_GOT32
)
1094 reloc_type
= R_C60_GLOB_DAT
;
1096 reloc_type
= R_C60_JMP_SLOT
;
1097 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1101 #elif defined(TCC_TARGET_X86_64)
1102 case R_X86_64_GOT32
:
1103 case R_X86_64_GOTTPOFF
:
1104 case R_X86_64_GOTPCREL
:
1105 case R_X86_64_PLT32
:
1108 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
||
1109 type
== R_X86_64_PLT32
) {
1110 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1111 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1112 /* look at the symbol got offset. If none, then add one */
1113 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
)
1114 reloc_type
= R_X86_64_GLOB_DAT
;
1116 reloc_type
= R_X86_64_JUMP_SLOT
;
1117 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1122 #error unsupported CPU
1131 static Section
*new_symtab(TCCState
*s1
,
1132 const char *symtab_name
, int sh_type
, int sh_flags
,
1133 const char *strtab_name
,
1134 const char *hash_name
, int hash_sh_flags
)
1136 Section
*symtab
, *strtab
, *hash
;
1137 int *ptr
, nb_buckets
;
1139 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1140 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1141 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1142 put_elf_str(strtab
, "");
1143 symtab
->link
= strtab
;
1144 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1148 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1149 hash
->sh_entsize
= sizeof(int);
1150 symtab
->hash
= hash
;
1151 hash
->link
= symtab
;
1153 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1154 ptr
[0] = nb_buckets
;
1156 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1160 /* put dynamic tag */
1161 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1164 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1166 dyn
->d_un
.d_val
= val
;
1169 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1173 char sym_start
[1024];
1176 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1177 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1179 s
= find_section(s1
, section_name
);
1184 end_offset
= s
->data_offset
;
1187 add_elf_sym(symtab_section
,
1189 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1190 s
->sh_num
, sym_start
);
1191 add_elf_sym(symtab_section
,
1193 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1194 s
->sh_num
, sym_end
);
1197 /* add tcc runtime libraries */
1198 static void tcc_add_runtime(TCCState
*s1
)
1200 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1204 #ifdef CONFIG_TCC_BCHECK
1205 if (do_bounds_check
) {
1207 Section
*init_section
;
1208 unsigned char *pinit
;
1211 /* XXX: add an object file to do that */
1212 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1214 add_elf_sym(symtab_section
, 0, 0,
1215 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1216 bounds_section
->sh_num
, "__bounds_start");
1217 /* add bound check code */
1218 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "bcheck.o");
1219 tcc_add_file(s1
, buf
);
1220 #ifdef TCC_TARGET_I386
1221 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1222 /* add 'call __bound_init()' in .init section */
1223 init_section
= find_section(s1
, ".init");
1224 pinit
= section_ptr_add(init_section
, 5);
1226 put32(pinit
+ 1, -4);
1227 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1228 put_elf_reloc(symtab_section
, init_section
,
1229 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1235 if (!s1
->nostdlib
) {
1236 tcc_add_library(s1
, "c");
1238 #ifdef CONFIG_USE_LIBGCC
1239 tcc_add_file(s1
, CONFIG_SYSROOT
"/lib/libgcc_s.so.1");
1241 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "libtcc1.a");
1242 tcc_add_file(s1
, buf
);
1245 /* add crt end if not memory output */
1246 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1247 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1251 /* add various standard linker symbols (must be done after the
1252 sections are filled (for example after allocating common
1254 static void tcc_add_linker_symbols(TCCState
*s1
)
1260 add_elf_sym(symtab_section
,
1261 text_section
->data_offset
, 0,
1262 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1263 text_section
->sh_num
, "_etext");
1264 add_elf_sym(symtab_section
,
1265 data_section
->data_offset
, 0,
1266 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1267 data_section
->sh_num
, "_edata");
1268 add_elf_sym(symtab_section
,
1269 bss_section
->data_offset
, 0,
1270 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1271 bss_section
->sh_num
, "_end");
1272 /* horrible new standard ldscript defines */
1273 add_init_array_defines(s1
, ".preinit_array");
1274 add_init_array_defines(s1
, ".init_array");
1275 add_init_array_defines(s1
, ".fini_array");
1277 /* add start and stop symbols for sections whose name can be
1279 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1280 s
= s1
->sections
[i
];
1281 if (s
->sh_type
== SHT_PROGBITS
&&
1282 (s
->sh_flags
& SHF_ALLOC
)) {
1286 /* check if section name can be expressed in C */
1292 if (!isid(ch
) && !isnum(ch
))
1296 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1297 add_elf_sym(symtab_section
,
1299 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1301 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1302 add_elf_sym(symtab_section
,
1304 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1311 /* name of ELF interpreter */
1313 static char elf_interp
[] = "/usr/libexec/ld-elf.so.1";
1316 static char elf_interp
[] = "/lib/ld-linux.so.3";
1317 #elif defined(TCC_TARGET_X86_64)
1318 static char elf_interp
[] = "/lib/ld-linux-x86-64.so.2";
1320 static char elf_interp
[] = "/lib/ld-linux.so.2";
1324 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1325 const int *section_order
)
1328 int i
, offset
, size
;
1331 for(i
=1;i
<s1
->nb_sections
;i
++) {
1332 s
= s1
->sections
[section_order
[i
]];
1333 if (s
->sh_type
!= SHT_NOBITS
&&
1334 (s
->sh_flags
& SHF_ALLOC
)) {
1335 while (offset
< s
->sh_offset
) {
1340 fwrite(s
->data
, 1, size
, f
);
1346 /* output an ELF file */
1347 /* XXX: suppress unneeded sections */
1348 int elf_output_file(TCCState
*s1
, const char *filename
)
1354 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1356 Section
*strsec
, *s
;
1357 ElfW(Shdr
) shdr
, *sh
;
1358 ElfW(Phdr
) *phdr
, *ph
;
1359 Section
*interp
, *dynamic
, *dynstr
;
1360 unsigned long saved_dynamic_data_offset
;
1362 int type
, file_type
;
1363 unsigned long rel_addr
, rel_size
;
1365 file_type
= s1
->output_type
;
1368 if (file_type
!= TCC_OUTPUT_OBJ
) {
1369 tcc_add_runtime(s1
);
1373 section_order
= NULL
;
1376 dynstr
= NULL
; /* avoid warning */
1377 saved_dynamic_data_offset
= 0; /* avoid warning */
1379 if (file_type
!= TCC_OUTPUT_OBJ
) {
1380 relocate_common_syms();
1382 tcc_add_linker_symbols(s1
);
1384 if (!s1
->static_link
) {
1386 int sym_index
, index
;
1387 ElfW(Sym
) *esym
, *sym_end
;
1389 if (file_type
== TCC_OUTPUT_EXE
) {
1391 /* add interpreter section only if executable */
1392 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1393 interp
->sh_addralign
= 1;
1394 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
1395 strcpy(ptr
, elf_interp
);
1398 /* add dynamic symbol table */
1399 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1401 ".hash", SHF_ALLOC
);
1402 dynstr
= s1
->dynsym
->link
;
1404 /* add dynamic section */
1405 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1406 SHF_ALLOC
| SHF_WRITE
);
1407 dynamic
->link
= dynstr
;
1408 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1411 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1412 SHF_ALLOC
| SHF_EXECINSTR
);
1413 s1
->plt
->sh_entsize
= 4;
1417 /* scan for undefined symbols and see if they are in the
1418 dynamic symbols. If a symbol STT_FUNC is found, then we
1419 add it in the PLT. If a symbol STT_OBJECT is found, we
1420 add it in the .bss section with a suitable relocation */
1421 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1422 symtab_section
->data_offset
);
1423 if (file_type
== TCC_OUTPUT_EXE
) {
1424 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1427 if (sym
->st_shndx
== SHN_UNDEF
) {
1428 name
= symtab_section
->link
->data
+ sym
->st_name
;
1429 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1431 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1432 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1433 if (type
== STT_FUNC
) {
1434 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1436 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1437 } else if (type
== STT_OBJECT
) {
1438 unsigned long offset
;
1439 offset
= bss_section
->data_offset
;
1440 /* XXX: which alignment ? */
1441 offset
= (offset
+ 16 - 1) & -16;
1442 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1444 bss_section
->sh_num
, name
);
1445 put_elf_reloc(s1
->dynsym
, bss_section
,
1446 offset
, R_COPY
, index
);
1447 offset
+= esym
->st_size
;
1448 bss_section
->data_offset
= offset
;
1451 /* STB_WEAK undefined symbols are accepted */
1452 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1454 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1455 !strcmp(name
, "_fp_hw")) {
1457 error_noabort("undefined symbol '%s'", name
);
1460 } else if (s1
->rdynamic
&&
1461 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1462 /* if -rdynamic option, then export all non
1464 name
= symtab_section
->link
->data
+ sym
->st_name
;
1465 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1467 sym
->st_shndx
, name
);
1474 /* now look at unresolved dynamic symbols and export
1475 corresponding symbol */
1476 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1477 s1
->dynsymtab_section
->data_offset
);
1478 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1481 if (esym
->st_shndx
== SHN_UNDEF
) {
1482 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1483 sym_index
= find_elf_sym(symtab_section
, name
);
1485 /* XXX: avoid adding a symbol if already
1486 present because of -rdynamic ? */
1487 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1488 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1490 sym
->st_shndx
, name
);
1492 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1493 /* weak symbols can stay undefined */
1495 warning("undefined dynamic symbol '%s'", name
);
1502 /* shared library case : we simply export all the global symbols */
1503 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1504 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1505 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1508 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1509 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1510 if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
&&
1511 sym
->st_shndx
== SHN_UNDEF
) {
1512 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1514 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1516 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1517 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1519 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1524 name
= symtab_section
->link
->data
+ sym
->st_name
;
1525 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1527 sym
->st_shndx
, name
);
1528 s1
->symtab_to_dynsym
[sym
-
1529 (ElfW(Sym
) *)symtab_section
->data
] =
1536 build_got_entries(s1
);
1538 /* add a list of needed dlls */
1539 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1540 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1541 if (dllref
->level
== 0)
1542 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1544 /* XXX: currently, since we do not handle PIC code, we
1545 must relocate the readonly segments */
1546 if (file_type
== TCC_OUTPUT_DLL
) {
1548 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1549 put_dt(dynamic
, DT_TEXTREL
, 0);
1552 /* add necessary space for other entries */
1553 saved_dynamic_data_offset
= dynamic
->data_offset
;
1554 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * 9;
1556 /* still need to build got entries in case of static link */
1557 build_got_entries(s1
);
1561 memset(&ehdr
, 0, sizeof(ehdr
));
1563 /* we add a section for symbols */
1564 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1565 put_elf_str(strsec
, "");
1567 /* compute number of sections */
1568 shnum
= s1
->nb_sections
;
1570 /* this array is used to reorder sections in the output file */
1571 section_order
= tcc_malloc(sizeof(int) * shnum
);
1572 section_order
[0] = 0;
1575 /* compute number of program headers */
1578 case TCC_OUTPUT_OBJ
:
1581 case TCC_OUTPUT_EXE
:
1582 if (!s1
->static_link
)
1587 case TCC_OUTPUT_DLL
:
1592 /* allocate strings for section names and decide if an unallocated
1593 section should be output */
1594 /* NOTE: the strsec section comes last, so its size is also
1596 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1597 s
= s1
->sections
[i
];
1598 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1600 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1605 s
->reloc
? s
->reloc
->name
: "n"
1608 /* when generating a DLL, we include relocations but we may
1610 if (file_type
== TCC_OUTPUT_DLL
&&
1611 s
->sh_type
== SHT_RELX
&&
1612 !(s
->sh_flags
& SHF_ALLOC
)) {
1613 /* //gr: avoid bogus relocs for empty (debug) sections */
1614 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1615 prepare_dynamic_rel(s1
, s
);
1617 s
->sh_size
= s
->data_offset
;
1618 } else if (do_debug
||
1619 file_type
== TCC_OUTPUT_OBJ
||
1620 (s
->sh_flags
& SHF_ALLOC
) ||
1621 i
== (s1
->nb_sections
- 1)) {
1622 /* we output all sections if debug or object file */
1623 s
->sh_size
= s
->data_offset
;
1627 /* allocate program segment headers */
1628 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1630 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1631 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1636 /* compute section to program header mapping */
1637 if (s1
->has_text_addr
) {
1638 int a_offset
, p_offset
;
1639 addr
= s1
->text_addr
;
1640 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1642 a_offset
= addr
& (ELF_PAGE_SIZE
- 1);
1643 p_offset
= file_offset
& (ELF_PAGE_SIZE
- 1);
1644 if (a_offset
< p_offset
)
1645 a_offset
+= ELF_PAGE_SIZE
;
1646 file_offset
+= (a_offset
- p_offset
);
1648 if (file_type
== TCC_OUTPUT_DLL
)
1651 addr
= ELF_START_ADDR
;
1652 /* compute address after headers */
1653 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1656 /* dynamic relocation table information, for .dynamic section */
1660 /* leave one program header for the program interpreter */
1665 for(j
= 0; j
< 2; j
++) {
1666 ph
->p_type
= PT_LOAD
;
1668 ph
->p_flags
= PF_R
| PF_X
;
1670 ph
->p_flags
= PF_R
| PF_W
;
1671 ph
->p_align
= ELF_PAGE_SIZE
;
1673 /* we do the following ordering: interp, symbol tables,
1674 relocations, progbits, nobits */
1675 /* XXX: do faster and simpler sorting */
1676 for(k
= 0; k
< 5; k
++) {
1677 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1678 s
= s1
->sections
[i
];
1679 /* compute if section should be included */
1681 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1685 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1686 (SHF_ALLOC
| SHF_WRITE
))
1692 } else if (s
->sh_type
== SHT_DYNSYM
||
1693 s
->sh_type
== SHT_STRTAB
||
1694 s
->sh_type
== SHT_HASH
) {
1697 } else if (s
->sh_type
== SHT_RELX
) {
1700 } else if (s
->sh_type
== SHT_NOBITS
) {
1707 section_order
[sh_order_index
++] = i
;
1709 /* section matches: we align it and add its size */
1711 addr
= (addr
+ s
->sh_addralign
- 1) &
1712 ~(s
->sh_addralign
- 1);
1713 file_offset
+= addr
- tmp
;
1714 s
->sh_offset
= file_offset
;
1717 /* update program header infos */
1718 if (ph
->p_offset
== 0) {
1719 ph
->p_offset
= file_offset
;
1721 ph
->p_paddr
= ph
->p_vaddr
;
1723 /* update dynamic relocation infos */
1724 if (s
->sh_type
== SHT_RELX
) {
1727 rel_size
+= s
->sh_size
;
1730 if (s
->sh_type
!= SHT_NOBITS
)
1731 file_offset
+= s
->sh_size
;
1734 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1735 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1738 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1739 /* if in the middle of a page, we duplicate the page in
1740 memory so that one copy is RX and the other is RW */
1741 if ((addr
& (ELF_PAGE_SIZE
- 1)) != 0)
1742 addr
+= ELF_PAGE_SIZE
;
1744 addr
= (addr
+ ELF_PAGE_SIZE
- 1) & ~(ELF_PAGE_SIZE
- 1);
1745 file_offset
= (file_offset
+ ELF_PAGE_SIZE
- 1) &
1746 ~(ELF_PAGE_SIZE
- 1);
1751 /* if interpreter, then add corresponing program header */
1755 ph
->p_type
= PT_INTERP
;
1756 ph
->p_offset
= interp
->sh_offset
;
1757 ph
->p_vaddr
= interp
->sh_addr
;
1758 ph
->p_paddr
= ph
->p_vaddr
;
1759 ph
->p_filesz
= interp
->sh_size
;
1760 ph
->p_memsz
= interp
->sh_size
;
1762 ph
->p_align
= interp
->sh_addralign
;
1765 /* if dynamic section, then add corresponing program header */
1769 ph
= &phdr
[phnum
- 1];
1771 ph
->p_type
= PT_DYNAMIC
;
1772 ph
->p_offset
= dynamic
->sh_offset
;
1773 ph
->p_vaddr
= dynamic
->sh_addr
;
1774 ph
->p_paddr
= ph
->p_vaddr
;
1775 ph
->p_filesz
= dynamic
->sh_size
;
1776 ph
->p_memsz
= dynamic
->sh_size
;
1777 ph
->p_flags
= PF_R
| PF_W
;
1778 ph
->p_align
= dynamic
->sh_addralign
;
1780 /* put GOT dynamic section address */
1781 put32(s1
->got
->data
, dynamic
->sh_addr
);
1783 /* relocate the PLT */
1784 if (file_type
== TCC_OUTPUT_EXE
1785 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1786 || file_type
== TCC_OUTPUT_DLL
1792 p_end
= p
+ s1
->plt
->data_offset
;
1794 #if defined(TCC_TARGET_I386)
1795 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1796 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1799 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1802 #elif defined(TCC_TARGET_X86_64)
1803 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1804 put32(p
+ 2, get32(p
+ 2) + x
);
1805 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1808 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1811 #elif defined(TCC_TARGET_ARM)
1813 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1816 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1819 #elif defined(TCC_TARGET_C67)
1822 #error unsupported CPU
1827 /* relocate symbols in .dynsym */
1828 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1829 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1832 if (sym
->st_shndx
== SHN_UNDEF
) {
1833 /* relocate to the PLT if the symbol corresponds
1836 sym
->st_value
+= s1
->plt
->sh_addr
;
1837 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1838 /* do symbol relocation */
1839 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1843 /* put dynamic section entries */
1844 dynamic
->data_offset
= saved_dynamic_data_offset
;
1845 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1846 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1847 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1848 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1849 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1850 #ifdef TCC_TARGET_X86_64
1851 put_dt(dynamic
, DT_RELA
, rel_addr
);
1852 put_dt(dynamic
, DT_RELASZ
, rel_size
);
1853 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1855 put_dt(dynamic
, DT_REL
, rel_addr
);
1856 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1857 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1860 put_dt(dynamic
, DT_DEBUG
, 0);
1861 put_dt(dynamic
, DT_NULL
, 0);
1864 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1865 ehdr
.e_phnum
= phnum
;
1866 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1869 /* all other sections come after */
1870 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1871 s
= s1
->sections
[i
];
1872 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1874 section_order
[sh_order_index
++] = i
;
1876 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1877 ~(s
->sh_addralign
- 1);
1878 s
->sh_offset
= file_offset
;
1879 if (s
->sh_type
!= SHT_NOBITS
)
1880 file_offset
+= s
->sh_size
;
1883 /* if building executable or DLL, then relocate each section
1884 except the GOT which is already relocated */
1885 if (file_type
!= TCC_OUTPUT_OBJ
) {
1886 relocate_syms(s1
, 0);
1888 if (s1
->nb_errors
!= 0) {
1894 /* relocate sections */
1895 /* XXX: ignore sections with allocated relocations ? */
1896 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1897 s
= s1
->sections
[i
];
1898 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1899 relocate_section(s1
, s
);
1902 /* relocate relocation entries if the relocation tables are
1903 allocated in the executable */
1904 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1905 s
= s1
->sections
[i
];
1906 if ((s
->sh_flags
& SHF_ALLOC
) &&
1907 s
->sh_type
== SHT_RELX
) {
1908 relocate_rel(s1
, s
);
1912 /* get entry point address */
1913 if (file_type
== TCC_OUTPUT_EXE
)
1914 ehdr
.e_entry
= (unsigned long)tcc_get_symbol_err(s1
, "_start");
1916 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1919 /* write elf file */
1920 if (file_type
== TCC_OUTPUT_OBJ
)
1924 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1926 error_noabort("could not write '%s'", filename
);
1929 f
= fdopen(fd
, "wb");
1931 printf("<- %s\n", filename
);
1933 #ifdef TCC_TARGET_COFF
1934 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1935 tcc_output_coff(s1
, f
);
1938 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1939 sort_syms(s1
, symtab_section
);
1942 file_offset
= (file_offset
+ 3) & -4;
1945 ehdr
.e_ident
[0] = ELFMAG0
;
1946 ehdr
.e_ident
[1] = ELFMAG1
;
1947 ehdr
.e_ident
[2] = ELFMAG2
;
1948 ehdr
.e_ident
[3] = ELFMAG3
;
1949 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
1950 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1951 ehdr
.e_ident
[6] = EV_CURRENT
;
1953 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1955 #ifdef TCC_TARGET_ARM
1957 ehdr
.e_ident
[EI_OSABI
] = 0;
1958 ehdr
.e_flags
= 4 << 24;
1960 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
1965 case TCC_OUTPUT_EXE
:
1966 ehdr
.e_type
= ET_EXEC
;
1968 case TCC_OUTPUT_DLL
:
1969 ehdr
.e_type
= ET_DYN
;
1971 case TCC_OUTPUT_OBJ
:
1972 ehdr
.e_type
= ET_REL
;
1975 ehdr
.e_machine
= EM_TCC_TARGET
;
1976 ehdr
.e_version
= EV_CURRENT
;
1977 ehdr
.e_shoff
= file_offset
;
1978 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
1979 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
1980 ehdr
.e_shnum
= shnum
;
1981 ehdr
.e_shstrndx
= shnum
- 1;
1983 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
1984 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
1985 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1987 for(i
=1;i
<s1
->nb_sections
;i
++) {
1988 s
= s1
->sections
[section_order
[i
]];
1989 if (s
->sh_type
!= SHT_NOBITS
) {
1990 while (offset
< s
->sh_offset
) {
1995 fwrite(s
->data
, 1, size
, f
);
2000 /* output section headers */
2001 while (offset
< ehdr
.e_shoff
) {
2006 for(i
=0;i
<s1
->nb_sections
;i
++) {
2008 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2009 s
= s1
->sections
[i
];
2011 sh
->sh_name
= s
->sh_name
;
2012 sh
->sh_type
= s
->sh_type
;
2013 sh
->sh_flags
= s
->sh_flags
;
2014 sh
->sh_entsize
= s
->sh_entsize
;
2015 sh
->sh_info
= s
->sh_info
;
2017 sh
->sh_link
= s
->link
->sh_num
;
2018 sh
->sh_addralign
= s
->sh_addralign
;
2019 sh
->sh_addr
= s
->sh_addr
;
2020 sh
->sh_offset
= s
->sh_offset
;
2021 sh
->sh_size
= s
->sh_size
;
2023 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2026 tcc_output_binary(s1
, f
, section_order
);
2032 tcc_free(s1
->symtab_to_dynsym
);
2033 tcc_free(section_order
);
2035 tcc_free(s1
->got_offsets
);
2039 int tcc_output_file(TCCState
*s
, const char *filename
)
2042 #ifdef TCC_TARGET_PE
2043 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2044 ret
= pe_output_file(s
, filename
);
2048 ret
= elf_output_file(s
, filename
);
2053 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2057 data
= tcc_malloc(size
);
2058 lseek(fd
, file_offset
, SEEK_SET
);
2059 read(fd
, data
, size
);
2063 typedef struct SectionMergeInfo
{
2064 Section
*s
; /* corresponding existing section */
2065 unsigned long offset
; /* offset of the new section in the existing section */
2066 uint8_t new_section
; /* true if section 's' was added */
2067 uint8_t link_once
; /* true if link once section */
2070 /* load an object file and merge it with current files */
2071 /* XXX: handle correctly stab (debug) info */
2072 static int tcc_load_object_file(TCCState
*s1
,
2073 int fd
, unsigned long file_offset
)
2076 ElfW(Shdr
) *shdr
, *sh
;
2077 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2078 unsigned char *strsec
, *strtab
;
2079 int *old_to_new_syms
;
2080 char *sh_name
, *name
;
2081 SectionMergeInfo
*sm_table
, *sm
;
2082 ElfW(Sym
) *sym
, *symtab
;
2083 ElfW_Rel
*rel
, *rel_end
;
2089 stab_index
= stabstr_index
= 0;
2091 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2093 if (ehdr
.e_ident
[0] != ELFMAG0
||
2094 ehdr
.e_ident
[1] != ELFMAG1
||
2095 ehdr
.e_ident
[2] != ELFMAG2
||
2096 ehdr
.e_ident
[3] != ELFMAG3
)
2098 /* test if object file */
2099 if (ehdr
.e_type
!= ET_REL
)
2101 /* test CPU specific stuff */
2102 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2103 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2105 error_noabort("invalid object file");
2109 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2110 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2111 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2113 /* load section names */
2114 sh
= &shdr
[ehdr
.e_shstrndx
];
2115 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2117 /* load symtab and strtab */
2118 old_to_new_syms
= NULL
;
2122 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2124 if (sh
->sh_type
== SHT_SYMTAB
) {
2126 error_noabort("object must contain only one symtab");
2131 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2132 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2133 sm_table
[i
].s
= symtab_section
;
2135 /* now load strtab */
2136 sh
= &shdr
[sh
->sh_link
];
2137 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2141 /* now examine each section and try to merge its content with the
2143 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2144 /* no need to examine section name strtab */
2145 if (i
== ehdr
.e_shstrndx
)
2148 sh_name
= strsec
+ sh
->sh_name
;
2149 /* ignore sections types we do not handle */
2150 if (sh
->sh_type
!= SHT_PROGBITS
&&
2151 sh
->sh_type
!= SHT_RELX
&&
2153 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2155 sh
->sh_type
!= SHT_NOBITS
&&
2156 strcmp(sh_name
, ".stabstr")
2159 if (sh
->sh_addralign
< 1)
2160 sh
->sh_addralign
= 1;
2161 /* find corresponding section, if any */
2162 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2163 s
= s1
->sections
[j
];
2164 if (!strcmp(s
->name
, sh_name
)) {
2165 if (!strncmp(sh_name
, ".gnu.linkonce",
2166 sizeof(".gnu.linkonce") - 1)) {
2167 /* if a 'linkonce' section is already present, we
2168 do not add it again. It is a little tricky as
2169 symbols can still be defined in
2171 sm_table
[i
].link_once
= 1;
2178 /* not found: create new section */
2179 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2180 /* take as much info as possible from the section. sh_link and
2181 sh_info will be updated later */
2182 s
->sh_addralign
= sh
->sh_addralign
;
2183 s
->sh_entsize
= sh
->sh_entsize
;
2184 sm_table
[i
].new_section
= 1;
2186 if (sh
->sh_type
!= s
->sh_type
) {
2187 error_noabort("invalid section type");
2191 /* align start of section */
2192 offset
= s
->data_offset
;
2194 if (0 == strcmp(sh_name
, ".stab")) {
2198 if (0 == strcmp(sh_name
, ".stabstr")) {
2203 size
= sh
->sh_addralign
- 1;
2204 offset
= (offset
+ size
) & ~size
;
2205 if (sh
->sh_addralign
> s
->sh_addralign
)
2206 s
->sh_addralign
= sh
->sh_addralign
;
2207 s
->data_offset
= offset
;
2209 sm_table
[i
].offset
= offset
;
2211 /* concatenate sections */
2213 if (sh
->sh_type
!= SHT_NOBITS
) {
2215 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2216 ptr
= section_ptr_add(s
, size
);
2217 read(fd
, ptr
, size
);
2219 s
->data_offset
+= size
;
2224 /* //gr relocate stab strings */
2225 if (stab_index
&& stabstr_index
) {
2228 s
= sm_table
[stab_index
].s
;
2229 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2230 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2231 o
= sm_table
[stabstr_index
].offset
;
2233 a
->n_strx
+= o
, a
++;
2236 /* second short pass to update sh_link and sh_info fields of new
2238 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2240 if (!s
|| !sm_table
[i
].new_section
)
2243 if (sh
->sh_link
> 0)
2244 s
->link
= sm_table
[sh
->sh_link
].s
;
2245 if (sh
->sh_type
== SHT_RELX
) {
2246 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2247 /* update backward link */
2248 s1
->sections
[s
->sh_info
]->reloc
= s
;
2253 /* resolve symbols */
2254 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2257 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2258 if (sym
->st_shndx
!= SHN_UNDEF
&&
2259 sym
->st_shndx
< SHN_LORESERVE
) {
2260 sm
= &sm_table
[sym
->st_shndx
];
2261 if (sm
->link_once
) {
2262 /* if a symbol is in a link once section, we use the
2263 already defined symbol. It is very important to get
2264 correct relocations */
2265 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2266 name
= strtab
+ sym
->st_name
;
2267 sym_index
= find_elf_sym(symtab_section
, name
);
2269 old_to_new_syms
[i
] = sym_index
;
2273 /* if no corresponding section added, no need to add symbol */
2276 /* convert section number */
2277 sym
->st_shndx
= sm
->s
->sh_num
;
2279 sym
->st_value
+= sm
->offset
;
2282 name
= strtab
+ sym
->st_name
;
2283 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2284 sym
->st_info
, sym
->st_other
,
2285 sym
->st_shndx
, name
);
2286 old_to_new_syms
[i
] = sym_index
;
2289 /* third pass to patch relocation entries */
2290 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2295 offset
= sm_table
[i
].offset
;
2296 switch(s
->sh_type
) {
2298 /* take relocation offset information */
2299 offseti
= sm_table
[sh
->sh_info
].offset
;
2300 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2301 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2306 /* convert symbol index */
2307 type
= ELFW(R_TYPE
)(rel
->r_info
);
2308 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2309 /* NOTE: only one symtab assumed */
2310 if (sym_index
>= nb_syms
)
2312 sym_index
= old_to_new_syms
[sym_index
];
2313 /* ignore link_once in rel section. */
2314 if (!sym_index
&& !sm
->link_once
) {
2316 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2317 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2320 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2321 /* offset the relocation offset */
2322 rel
->r_offset
+= offseti
;
2334 tcc_free(old_to_new_syms
);
2341 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2343 typedef struct ArchiveHeader
{
2344 char ar_name
[16]; /* name of this member */
2345 char ar_date
[12]; /* file mtime */
2346 char ar_uid
[6]; /* owner uid; printed as decimal */
2347 char ar_gid
[6]; /* owner gid; printed as decimal */
2348 char ar_mode
[8]; /* file mode, printed as octal */
2349 char ar_size
[10]; /* file size, printed as decimal */
2350 char ar_fmag
[2]; /* should contain ARFMAG */
2353 static int get_be32(const uint8_t *b
)
2355 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2358 /* load only the objects which resolve undefined symbols */
2359 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2361 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2363 const char *ar_names
, *p
;
2364 const uint8_t *ar_index
;
2367 data
= tcc_malloc(size
);
2368 if (read(fd
, data
, size
) != size
)
2370 nsyms
= get_be32(data
);
2371 ar_index
= data
+ 4;
2372 ar_names
= ar_index
+ nsyms
* 4;
2376 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2377 sym_index
= find_elf_sym(symtab_section
, p
);
2379 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2380 if(sym
->st_shndx
== SHN_UNDEF
) {
2381 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2383 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2386 lseek(fd
, off
, SEEK_SET
);
2387 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2402 /* load a '.a' file */
2403 static int tcc_load_archive(TCCState
*s1
, int fd
)
2410 unsigned long file_offset
;
2412 /* skip magic which was already checked */
2413 read(fd
, magic
, sizeof(magic
));
2416 len
= read(fd
, &hdr
, sizeof(hdr
));
2419 if (len
!= sizeof(hdr
)) {
2420 error_noabort("invalid archive");
2423 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2424 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2425 size
= strtol(ar_size
, NULL
, 0);
2426 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2427 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2428 if (ar_name
[i
] != ' ')
2431 ar_name
[i
+ 1] = '\0';
2432 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2433 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2435 size
= (size
+ 1) & ~1;
2436 if (!strcmp(ar_name
, "/")) {
2437 /* coff symbol table : we handle it */
2438 if(s1
->alacarte_link
)
2439 return tcc_load_alacarte(s1
, fd
, size
);
2440 } else if (!strcmp(ar_name
, "//") ||
2441 !strcmp(ar_name
, "__.SYMDEF") ||
2442 !strcmp(ar_name
, "__.SYMDEF/") ||
2443 !strcmp(ar_name
, "ARFILENAMES/")) {
2444 /* skip symbol table or archive names */
2446 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2449 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2454 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2455 is referenced by the user (so it should be added as DT_NEEDED in
2456 the generated ELF file) */
2457 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2460 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2461 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2462 ElfW(Sym
) *sym
, *dynsym
;
2463 ElfW(Dyn
) *dt
, *dynamic
;
2464 unsigned char *dynstr
;
2465 const char *name
, *soname
;
2466 DLLReference
*dllref
;
2468 read(fd
, &ehdr
, sizeof(ehdr
));
2470 /* test CPU specific stuff */
2471 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2472 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2473 error_noabort("bad architecture");
2478 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2480 /* load dynamic section and dynamic symbols */
2484 dynsym
= NULL
; /* avoid warning */
2485 dynstr
= NULL
; /* avoid warning */
2486 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2487 switch(sh
->sh_type
) {
2489 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2490 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2493 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2494 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2495 sh1
= &shdr
[sh
->sh_link
];
2496 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2503 /* compute the real library name */
2504 soname
= tcc_basename(filename
);
2506 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2507 if (dt
->d_tag
== DT_SONAME
) {
2508 soname
= dynstr
+ dt
->d_un
.d_val
;
2512 /* if the dll is already loaded, do not load it */
2513 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2514 dllref
= s1
->loaded_dlls
[i
];
2515 if (!strcmp(soname
, dllref
->name
)) {
2516 /* but update level if needed */
2517 if (level
< dllref
->level
)
2518 dllref
->level
= level
;
2524 // printf("loading dll '%s'\n", soname);
2526 /* add the dll and its level */
2527 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2528 dllref
->level
= level
;
2529 strcpy(dllref
->name
, soname
);
2530 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2532 /* add dynamic symbols in dynsym_section */
2533 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2534 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2535 if (sym_bind
== STB_LOCAL
)
2537 name
= dynstr
+ sym
->st_name
;
2538 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2539 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2542 /* load all referenced DLLs */
2543 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2546 name
= dynstr
+ dt
->d_un
.d_val
;
2547 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2548 dllref
= s1
->loaded_dlls
[j
];
2549 if (!strcmp(name
, dllref
->name
))
2550 goto already_loaded
;
2552 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2553 error_noabort("referenced dll '%s' not found", name
);
2570 #define LD_TOK_NAME 256
2571 #define LD_TOK_EOF (-1)
2573 /* return next ld script token */
2574 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2592 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2593 ch
= file
->buf_ptr
[0];
2601 /* case 'a' ... 'z': */
2628 /* case 'A' ... 'z': */
2663 if (!((ch
>= 'a' && ch
<= 'z') ||
2664 (ch
>= 'A' && ch
<= 'Z') ||
2665 (ch
>= '0' && ch
<= '9') ||
2666 strchr("/.-_+=$:\\,~", ch
)))
2668 if ((q
- name
) < name_size
- 1) {
2685 printf("tok=%c %d\n", c
, c
);
2686 if (c
== LD_TOK_NAME
)
2687 printf(" name=%s\n", name
);
2692 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2694 char filename
[1024];
2697 t
= ld_next(s1
, filename
, sizeof(filename
));
2700 t
= ld_next(s1
, filename
, sizeof(filename
));
2702 if (t
== LD_TOK_EOF
) {
2703 error_noabort("unexpected end of file");
2705 } else if (t
== ')') {
2707 } else if (t
!= LD_TOK_NAME
) {
2708 error_noabort("filename expected");
2711 if (!strcmp(filename
, "AS_NEEDED")) {
2712 ret
= ld_add_file_list(s1
, 1);
2716 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2718 tcc_add_file(s1
, filename
);
2720 t
= ld_next(s1
, filename
, sizeof(filename
));
2722 t
= ld_next(s1
, filename
, sizeof(filename
));
2728 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2730 static int tcc_load_ldscript(TCCState
*s1
)
2733 char filename
[1024];
2736 ch
= file
->buf_ptr
[0];
2739 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2740 if (t
== LD_TOK_EOF
)
2742 else if (t
!= LD_TOK_NAME
)
2744 if (!strcmp(cmd
, "INPUT") ||
2745 !strcmp(cmd
, "GROUP")) {
2746 ret
= ld_add_file_list(s1
, 0);
2749 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2750 !strcmp(cmd
, "TARGET")) {
2751 /* ignore some commands */
2752 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2756 t
= ld_next(s1
, filename
, sizeof(filename
));
2757 if (t
== LD_TOK_EOF
) {
2758 error_noabort("unexpected end of file");
2760 } else if (t
== ')') {