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"
26 #define ElfW_Rel ElfW(Rel)
27 #define SHT_RELX SHT_REL
28 #define REL_SECTION_FMT ".rel%s"
31 static int put_elf_str(Section
*s
, const char *sym
)
36 len
= strlen(sym
) + 1;
37 offset
= s
->data_offset
;
38 ptr
= section_ptr_add(s
, len
);
39 memcpy(ptr
, sym
, len
);
43 /* elf symbol hashing function */
44 static unsigned long elf_hash(const unsigned char *name
)
46 unsigned long h
= 0, g
;
49 h
= (h
<< 4) + *name
++;
58 /* rebuild hash table of section s */
59 /* NOTE: we do factorize the hash table code to go faster */
60 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
63 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
66 strtab
= s
->link
->data
;
67 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
69 s
->hash
->data_offset
= 0;
70 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
75 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
76 ptr
+= nb_buckets
+ 1;
78 sym
= (ElfW(Sym
) *)s
->data
+ 1;
79 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
80 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
81 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
92 /* return the symbol number */
93 static int put_elf_sym(Section
*s
,
94 unsigned long value
, unsigned long size
,
95 int info
, int other
, int shndx
, const char *name
)
97 int name_offset
, sym_index
;
102 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
104 name_offset
= put_elf_str(s
->link
, name
);
107 /* XXX: endianness */
108 sym
->st_name
= name_offset
;
109 sym
->st_value
= value
;
112 sym
->st_other
= other
;
113 sym
->st_shndx
= shndx
;
114 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
118 ptr
= section_ptr_add(hs
, sizeof(int));
119 base
= (int *)hs
->data
;
120 /* only add global or weak symbols */
121 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
122 /* add another hashing entry */
124 h
= elf_hash(name
) % nbuckets
;
126 base
[2 + h
] = sym_index
;
128 /* we resize the hash table */
129 hs
->nb_hashed_syms
++;
130 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
131 rebuild_hash(s
, 2 * nbuckets
);
141 /* find global ELF symbol 'name' and return its index. Return 0 if not
143 static int find_elf_sym(Section
*s
, const char *name
)
147 int nbuckets
, sym_index
, h
;
153 nbuckets
= ((int *)hs
->data
)[0];
154 h
= elf_hash(name
) % nbuckets
;
155 sym_index
= ((int *)hs
->data
)[2 + h
];
156 while (sym_index
!= 0) {
157 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
158 name1
= s
->link
->data
+ sym
->st_name
;
159 if (!strcmp(name
, name1
))
161 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
166 /* return elf symbol value or error */
167 int tcc_get_symbol(TCCState
*s
, unsigned long *pval
, const char *name
)
172 sym_index
= find_elf_sym(symtab_section
, name
);
175 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
176 *pval
= sym
->st_value
;
180 void *tcc_get_symbol_err(TCCState
*s
, const char *name
)
183 if (tcc_get_symbol(s
, &val
, name
) < 0)
184 error("%s not defined", name
);
188 /* add an elf symbol : check if it is already defined and patch
189 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
190 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
191 int info
, int other
, int sh_num
, const char *name
)
194 int sym_bind
, sym_index
, sym_type
, esym_bind
;
195 unsigned char sym_vis
, esym_vis
, new_vis
;
197 sym_bind
= ELFW(ST_BIND
)(info
);
198 sym_type
= ELFW(ST_TYPE
)(info
);
199 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
201 if (sym_bind
!= STB_LOCAL
) {
202 /* we search global or weak symbols */
203 sym_index
= find_elf_sym(s
, name
);
206 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
207 if (esym
->st_shndx
!= SHN_UNDEF
) {
208 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
209 /* propagate the most constraining visibility */
210 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
211 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
212 if (esym_vis
== STV_DEFAULT
) {
214 } else if (sym_vis
== STV_DEFAULT
) {
217 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
219 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
221 other
= esym
->st_other
; /* in case we have to patch esym */
222 if (sh_num
== SHN_UNDEF
) {
223 /* ignore adding of undefined symbol if the
224 corresponding symbol is already defined */
225 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
226 /* global overrides weak, so patch */
228 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
229 /* weak is ignored if already global */
230 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
231 /* ignore hidden symbols after */
232 } else if (esym
->st_shndx
== SHN_COMMON
&& sh_num
< SHN_LORESERVE
) {
233 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
234 No idea if this is the correct solution ... */
236 } else if (s
== tcc_state
->dynsymtab_section
) {
237 /* we accept that two DLL define the same symbol */
240 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
241 sym_bind
, sh_num
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
243 error_noabort("'%s' defined twice", name
);
247 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
248 esym
->st_shndx
= sh_num
;
249 esym
->st_value
= value
;
250 esym
->st_size
= size
;
251 esym
->st_other
= other
;
255 sym_index
= put_elf_sym(s
, value
, size
,
256 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
263 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
264 int type
, int symbol
)
272 /* if no relocation section, create it */
273 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
274 /* if the symtab is allocated, then we consider the relocation
276 sr
= new_section(tcc_state
, buf
, SHT_RELX
, symtab
->sh_flags
);
277 sr
->sh_entsize
= sizeof(ElfW_Rel
);
279 sr
->sh_info
= s
->sh_num
;
282 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
283 rel
->r_offset
= offset
;
284 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
285 #ifdef TCC_TARGET_X86_64
290 /* put stab debug information */
293 unsigned long n_strx
; /* index into string table of name */
294 unsigned char n_type
; /* type of symbol */
295 unsigned char n_other
; /* misc info (usually empty) */
296 unsigned short n_desc
; /* description field */
297 unsigned long n_value
; /* value of symbol */
300 static void put_stabs(const char *str
, int type
, int other
, int desc
,
305 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
307 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
312 sym
->n_other
= other
;
314 sym
->n_value
= value
;
317 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
318 unsigned long value
, Section
*sec
, int sym_index
)
320 put_stabs(str
, type
, other
, desc
, value
);
321 put_elf_reloc(symtab_section
, stab_section
,
322 stab_section
->data_offset
- sizeof(unsigned long),
323 R_DATA_32
, sym_index
);
326 static void put_stabn(int type
, int other
, int desc
, int value
)
328 put_stabs(NULL
, type
, other
, desc
, value
);
331 static void put_stabd(int type
, int other
, int desc
)
333 put_stabs(NULL
, type
, other
, desc
, 0);
336 /* In an ELF file symbol table, the local symbols must appear below
337 the global and weak ones. Since TCC cannot sort it while generating
338 the code, we must do it after. All the relocation tables are also
339 modified to take into account the symbol table sorting */
340 static void sort_syms(TCCState
*s1
, Section
*s
)
342 int *old_to_new_syms
;
346 ElfW_Rel
*rel
, *rel_end
;
350 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
351 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
352 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
354 /* first pass for local symbols */
355 p
= (ElfW(Sym
) *)s
->data
;
357 for(i
= 0; i
< nb_syms
; i
++) {
358 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
359 old_to_new_syms
[i
] = q
- new_syms
;
364 /* save the number of local symbols in section header */
365 s
->sh_info
= q
- new_syms
;
367 /* then second pass for non local symbols */
368 p
= (ElfW(Sym
) *)s
->data
;
369 for(i
= 0; i
< nb_syms
; i
++) {
370 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
371 old_to_new_syms
[i
] = q
- new_syms
;
377 /* we copy the new symbols to the old */
378 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
381 /* now we modify all the relocations */
382 for(i
= 1; i
< s1
->nb_sections
; i
++) {
383 sr
= s1
->sections
[i
];
384 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
385 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
386 for(rel
= (ElfW_Rel
*)sr
->data
;
389 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
390 type
= ELFW(R_TYPE
)(rel
->r_info
);
391 sym_index
= old_to_new_syms
[sym_index
];
392 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
397 tcc_free(old_to_new_syms
);
400 /* relocate common symbols in the .bss section */
401 static void relocate_common_syms(void)
403 ElfW(Sym
) *sym
, *sym_end
;
404 unsigned long offset
, align
;
406 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
407 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
410 if (sym
->st_shndx
== SHN_COMMON
) {
412 align
= sym
->st_value
;
413 offset
= bss_section
->data_offset
;
414 offset
= (offset
+ align
- 1) & -align
;
415 sym
->st_value
= offset
;
416 sym
->st_shndx
= bss_section
->sh_num
;
417 offset
+= sym
->st_size
;
418 bss_section
->data_offset
= offset
;
423 /* relocate symbol table, resolve undefined symbols if do_resolve is
424 true and output error if undefined symbol. */
425 static void relocate_syms(TCCState
*s1
, int do_resolve
)
427 ElfW(Sym
) *sym
, *esym
, *sym_end
;
428 int sym_bind
, sh_num
, sym_index
;
432 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
433 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
436 sh_num
= sym
->st_shndx
;
437 if (sh_num
== SHN_UNDEF
) {
438 name
= strtab_section
->data
+ sym
->st_name
;
440 name
= symtab_section
->link
->data
+ sym
->st_name
;
441 addr
= (unsigned long)resolve_sym(s1
, name
, ELFW(ST_TYPE
)(sym
->st_info
));
443 sym
->st_value
= addr
;
446 } else if (s1
->dynsym
) {
447 /* if dynamic symbol exist, then use it */
448 sym_index
= find_elf_sym(s1
->dynsym
, name
);
450 esym
= &((ElfW(Sym
) *)s1
->dynsym
->data
)[sym_index
];
451 sym
->st_value
= esym
->st_value
;
455 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
457 if (!strcmp(name
, "_fp_hw"))
459 /* only weak symbols are accepted to be undefined. Their
461 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
462 if (sym_bind
== STB_WEAK
) {
465 error_noabort("undefined symbol '%s'", name
);
467 } else if (sh_num
< SHN_LORESERVE
) {
468 /* add section base */
469 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
475 #ifdef TCC_TARGET_X86_64
476 #define JMP_TABLE_ENTRY_SIZE 14
477 #define JMP_TABLE_ENTRY_MAX_NUM 4096
478 static unsigned long add_jmp_table(TCCState
*s1
, unsigned long val
)
481 if (!s1
->jmp_table
) {
482 int size
= JMP_TABLE_ENTRY_SIZE
* JMP_TABLE_ENTRY_MAX_NUM
;
483 s1
->jmp_table_num
= 0;
484 s1
->jmp_table
= (char *)tcc_malloc(size
);
485 set_pages_executable(s1
->jmp_table
, size
);
487 if (s1
->jmp_table_num
== JMP_TABLE_ENTRY_MAX_NUM
) {
488 error("relocating >%d symbols are not supported",
489 JMP_TABLE_ENTRY_MAX_NUM
);
491 p
= s1
->jmp_table
+ s1
->jmp_table_num
* JMP_TABLE_ENTRY_SIZE
;
497 *(unsigned long *)(p
+ 6) = val
;
498 return (unsigned long)p
;
502 /* relocate a given section (CPU dependent) */
503 static void relocate_section(TCCState
*s1
, Section
*s
)
506 ElfW_Rel
*rel
, *rel_end
, *qrel
;
510 unsigned long val
, addr
;
514 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
515 qrel
= (ElfW_Rel
*)sr
->data
;
519 ptr
= s
->data
+ rel
->r_offset
;
521 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
522 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
524 #ifdef TCC_TARGET_X86_64
525 /* XXX: not tested */
526 val
+= rel
->r_addend
;
528 type
= ELFW(R_TYPE
)(rel
->r_info
);
529 addr
= s
->sh_addr
+ rel
->r_offset
;
533 #if defined(TCC_TARGET_I386)
535 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
536 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
537 qrel
->r_offset
= rel
->r_offset
;
539 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_32
);
543 qrel
->r_info
= ELFW(R_INFO
)(0, R_386_RELATIVE
);
550 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
552 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
554 qrel
->r_offset
= rel
->r_offset
;
555 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_PC32
);
560 *(int *)ptr
+= val
- addr
;
563 *(int *)ptr
+= val
- addr
;
570 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
573 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
576 /* we load the got offset */
577 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
579 #elif defined(TCC_TARGET_ARM)
586 x
= (*(int *)ptr
)&0xffffff;
587 (*(int *)ptr
) &= 0xff000000;
592 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
593 error("can't relocate value at %x",addr
);
602 x
= (*(int *)ptr
) & 0x7fffffff;
603 (*(int *)ptr
) &= 0x80000000;
606 if((x
^(x
>>1))&0x40000000)
607 error("can't relocate value at %x",addr
);
608 (*(int *)ptr
) |= x
& 0x7fffffff;
613 case R_ARM_BASE_PREL
:
614 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
617 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
620 /* we load the got offset */
621 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
626 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
627 type
,addr
,(unsigned int )ptr
,val
);
629 #elif defined(TCC_TARGET_C67)
637 /* put the low 16 bits of the absolute address */
638 // add to what is already there
640 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
641 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
643 //patch both at once - assumes always in pairs Low - High
645 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
646 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
652 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
653 type
,addr
,(unsigned int )ptr
,val
);
655 #elif defined(TCC_TARGET_X86_64)
657 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
658 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
659 qrel
->r_addend
= *(long long *)ptr
+ val
;
662 *(long long *)ptr
+= val
;
666 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
667 /* XXX: this logic may depend on TCC's codegen
668 now TCC uses R_X86_64_32 even for a 64bit pointer */
669 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
670 qrel
->r_addend
= *(int *)ptr
+ val
;
675 case R_X86_64_PC32
: {
676 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
678 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
680 qrel
->r_offset
= rel
->r_offset
;
681 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_X86_64_PC32
);
682 qrel
->r_addend
= *(int *)ptr
;
687 long diff
= val
- addr
;
688 if (diff
< -2147483648 || diff
> 2147483647) {
689 /* XXX: naive support for over 32bit jump */
690 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
691 val
= add_jmp_table(s1
, val
);
694 if (diff
<= -2147483647 || diff
> 2147483647) {
696 /* output memory map to debug easily */
701 printf("%ld - %ld = %ld\n", val
, addr
, diff
);
702 dladdr((void *)addr
, &di
);
703 printf("addr = %lx = %lx+%lx(%s) ptr=%p\n",
704 addr
, s
->sh_addr
, rel
->r_offset
, di
.dli_sname
,
706 fp
= fopen("/proc/self/maps", "r");
707 size
= fread(buf
, 1, 4095, fp
);
711 error("internal error: relocation failed");
718 *(int *)ptr
+= val
- addr
;
720 case R_X86_64_GLOB_DAT
:
721 case R_X86_64_JUMP_SLOT
:
724 case R_X86_64_GOTPCREL
:
725 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
727 case R_X86_64_GOTTPOFF
:
728 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
731 /* we load the got offset */
732 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
735 #error unsupported processor
739 /* if the relocation is allocated, we change its symbol table */
740 if (sr
->sh_flags
& SHF_ALLOC
)
741 sr
->link
= s1
->dynsym
;
744 /* relocate relocation table in 'sr' */
745 static void relocate_rel(TCCState
*s1
, Section
*sr
)
748 ElfW_Rel
*rel
, *rel_end
;
750 s
= s1
->sections
[sr
->sh_info
];
751 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
752 for(rel
= (ElfW_Rel
*)sr
->data
;
755 rel
->r_offset
+= s
->sh_addr
;
759 /* count the number of dynamic relocations so that we can reserve
761 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
763 ElfW_Rel
*rel
, *rel_end
;
764 int sym_index
, esym_index
, type
, count
;
767 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
768 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
769 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
770 type
= ELFW(R_TYPE
)(rel
->r_info
);
772 #if defined(TCC_TARGET_I386)
774 #elif defined(TCC_TARGET_X86_64)
780 #if defined(TCC_TARGET_I386)
782 #elif defined(TCC_TARGET_X86_64)
785 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
794 /* allocate the section */
795 sr
->sh_flags
|= SHF_ALLOC
;
796 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
801 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
806 if (index
>= s1
->nb_got_offsets
) {
807 /* find immediately bigger power of 2 and reallocate array */
811 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
813 error("memory full");
814 s1
->got_offsets
= tab
;
815 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
816 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
817 s1
->nb_got_offsets
= n
;
819 s1
->got_offsets
[index
] = val
;
822 /* XXX: suppress that */
823 static void put32(unsigned char *p
, uint32_t val
)
831 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
832 defined(TCC_TARGET_X86_64)
833 static uint32_t get32(unsigned char *p
)
835 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
839 static void build_got(TCCState
*s1
)
843 /* if no got, then create it */
844 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
845 s1
->got
->sh_entsize
= 4;
846 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
847 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
848 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
850 /* keep space for _DYNAMIC pointer, if present */
852 /* two dummy got entries */
856 /* keep space for _DYNAMIC pointer, if present */
859 /* two dummy got entries */
867 /* put a got entry corresponding to a symbol in symtab_section. 'size'
868 and 'info' can be modifed if more precise info comes from the DLL */
869 static void put_got_entry(TCCState
*s1
,
870 int reloc_type
, unsigned long size
, int info
,
876 unsigned long offset
;
882 /* if a got entry already exists for that symbol, no need to add one */
883 if (sym_index
< s1
->nb_got_offsets
&&
884 s1
->got_offsets
[sym_index
] != 0)
887 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
890 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
891 name
= symtab_section
->link
->data
+ sym
->st_name
;
892 offset
= sym
->st_value
;
893 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
895 #ifdef TCC_TARGET_X86_64
905 /* if we build a DLL, we add a %ebx offset */
906 if (s1
->output_type
== TCC_OUTPUT_DLL
)
911 /* add a PLT entry */
913 if (plt
->data_offset
== 0) {
914 /* first plt entry */
915 p
= section_ptr_add(plt
, 16);
916 p
[0] = 0xff; /* pushl got + PTR_SIZE */
918 put32(p
+ 2, PTR_SIZE
);
919 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
921 put32(p
+ 8, PTR_SIZE
* 2);
924 p
= section_ptr_add(plt
, 16);
925 p
[0] = 0xff; /* jmp *(got + x) */
927 put32(p
+ 2, s1
->got
->data_offset
);
928 p
[6] = 0x68; /* push $xxx */
929 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
930 p
[11] = 0xe9; /* jmp plt_start */
931 put32(p
+ 12, -(plt
->data_offset
));
933 /* the symbol is modified so that it will be relocated to
935 if (s1
->output_type
== TCC_OUTPUT_EXE
)
936 offset
= plt
->data_offset
- 16;
938 #elif defined(TCC_TARGET_ARM)
939 if (reloc_type
== R_ARM_JUMP_SLOT
) {
943 /* if we build a DLL, we add a %ebx offset */
944 if (s1
->output_type
== TCC_OUTPUT_DLL
)
945 error("DLLs unimplemented!");
947 /* add a PLT entry */
949 if (plt
->data_offset
== 0) {
950 /* first plt entry */
951 p
= section_ptr_add(plt
, 16);
952 put32(p
, 0xe52de004);
953 put32(p
+ 4, 0xe59fe010);
954 put32(p
+ 8, 0xe08fe00e);
955 put32(p
+ 12, 0xe5bef008);
958 p
= section_ptr_add(plt
, 16);
959 put32(p
, 0xe59fc004);
960 put32(p
+4, 0xe08fc00c);
961 put32(p
+8, 0xe59cf000);
962 put32(p
+12, s1
->got
->data_offset
);
964 /* the symbol is modified so that it will be relocated to
966 if (s1
->output_type
== TCC_OUTPUT_EXE
)
967 offset
= plt
->data_offset
- 16;
969 #elif defined(TCC_TARGET_C67)
970 error("C67 got not implemented");
972 #error unsupported CPU
974 index
= put_elf_sym(s1
->dynsym
, offset
,
975 size
, info
, 0, sym
->st_shndx
, name
);
976 /* put a got entry */
977 put_elf_reloc(s1
->dynsym
, s1
->got
,
978 s1
->got
->data_offset
,
981 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
985 /* build GOT and PLT entries */
986 static void build_got_entries(TCCState
*s1
)
989 ElfW_Rel
*rel
, *rel_end
;
991 int i
, type
, reloc_type
, sym_index
;
993 for(i
= 1; i
< s1
->nb_sections
; i
++) {
995 if (s
->sh_type
!= SHT_RELX
)
997 /* no need to handle got relocations */
998 if (s
->link
!= symtab_section
)
1001 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
1002 for(rel
= (ElfW_Rel
*)s
->data
;
1005 type
= ELFW(R_TYPE
)(rel
->r_info
);
1007 #if defined(TCC_TARGET_I386)
1014 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1015 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1016 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1017 /* look at the symbol got offset. If none, then add one */
1018 if (type
== R_386_GOT32
)
1019 reloc_type
= R_386_GLOB_DAT
;
1021 reloc_type
= R_386_JMP_SLOT
;
1022 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1026 #elif defined(TCC_TARGET_ARM)
1027 case R_ARM_GOT_BREL
:
1028 case R_ARM_GOTOFF32
:
1029 case R_ARM_BASE_PREL
:
1033 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1034 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1035 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1036 /* look at the symbol got offset. If none, then add one */
1037 if (type
== R_ARM_GOT_BREL
)
1038 reloc_type
= R_ARM_GLOB_DAT
;
1040 reloc_type
= R_ARM_JUMP_SLOT
;
1041 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1045 #elif defined(TCC_TARGET_C67)
1052 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1053 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1054 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1055 /* look at the symbol got offset. If none, then add one */
1056 if (type
== R_C60_GOT32
)
1057 reloc_type
= R_C60_GLOB_DAT
;
1059 reloc_type
= R_C60_JMP_SLOT
;
1060 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1064 #elif defined(TCC_TARGET_X86_64)
1065 case R_X86_64_GOT32
:
1066 case R_X86_64_GOTTPOFF
:
1067 case R_X86_64_GOTPCREL
:
1068 case R_X86_64_PLT32
:
1071 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_PLT32
) {
1072 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1073 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1074 /* look at the symbol got offset. If none, then add one */
1075 if (type
== R_X86_64_GOT32
)
1076 reloc_type
= R_X86_64_GLOB_DAT
;
1078 reloc_type
= R_X86_64_JUMP_SLOT
;
1079 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1084 #error unsupported CPU
1093 static Section
*new_symtab(TCCState
*s1
,
1094 const char *symtab_name
, int sh_type
, int sh_flags
,
1095 const char *strtab_name
,
1096 const char *hash_name
, int hash_sh_flags
)
1098 Section
*symtab
, *strtab
, *hash
;
1099 int *ptr
, nb_buckets
;
1101 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1102 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1103 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1104 put_elf_str(strtab
, "");
1105 symtab
->link
= strtab
;
1106 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1110 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1111 hash
->sh_entsize
= sizeof(int);
1112 symtab
->hash
= hash
;
1113 hash
->link
= symtab
;
1115 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1116 ptr
[0] = nb_buckets
;
1118 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1122 /* put dynamic tag */
1123 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1126 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1128 dyn
->d_un
.d_val
= val
;
1131 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1135 char sym_start
[1024];
1138 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1139 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1141 s
= find_section(s1
, section_name
);
1146 end_offset
= s
->data_offset
;
1149 add_elf_sym(symtab_section
,
1151 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1152 s
->sh_num
, sym_start
);
1153 add_elf_sym(symtab_section
,
1155 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1156 s
->sh_num
, sym_end
);
1159 /* add tcc runtime libraries */
1160 static void tcc_add_runtime(TCCState
*s1
)
1162 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1166 #ifdef CONFIG_TCC_BCHECK
1167 if (do_bounds_check
) {
1169 Section
*init_section
;
1170 unsigned char *pinit
;
1173 /* XXX: add an object file to do that */
1174 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1176 add_elf_sym(symtab_section
, 0, 0,
1177 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1178 bounds_section
->sh_num
, "__bounds_start");
1179 /* add bound check code */
1180 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "bcheck.o");
1181 tcc_add_file(s1
, buf
);
1182 #ifdef TCC_TARGET_I386
1183 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1184 /* add 'call __bound_init()' in .init section */
1185 init_section
= find_section(s1
, ".init");
1186 pinit
= section_ptr_add(init_section
, 5);
1188 put32(pinit
+ 1, -4);
1189 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1190 put_elf_reloc(symtab_section
, init_section
,
1191 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1197 if (!s1
->nostdlib
) {
1198 tcc_add_library(s1
, "c");
1200 #ifdef CONFIG_USE_LIBGCC
1201 tcc_add_file(s1
, CONFIG_SYSROOT
"/lib/libgcc_s.so.1");
1203 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "libtcc1.a");
1204 tcc_add_file(s1
, buf
);
1207 /* add crt end if not memory output */
1208 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1209 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1213 /* add various standard linker symbols (must be done after the
1214 sections are filled (for example after allocating common
1216 static void tcc_add_linker_symbols(TCCState
*s1
)
1222 add_elf_sym(symtab_section
,
1223 text_section
->data_offset
, 0,
1224 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1225 text_section
->sh_num
, "_etext");
1226 add_elf_sym(symtab_section
,
1227 data_section
->data_offset
, 0,
1228 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1229 data_section
->sh_num
, "_edata");
1230 add_elf_sym(symtab_section
,
1231 bss_section
->data_offset
, 0,
1232 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1233 bss_section
->sh_num
, "_end");
1234 /* horrible new standard ldscript defines */
1235 add_init_array_defines(s1
, ".preinit_array");
1236 add_init_array_defines(s1
, ".init_array");
1237 add_init_array_defines(s1
, ".fini_array");
1239 /* add start and stop symbols for sections whose name can be
1241 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1242 s
= s1
->sections
[i
];
1243 if (s
->sh_type
== SHT_PROGBITS
&&
1244 (s
->sh_flags
& SHF_ALLOC
)) {
1248 /* check if section name can be expressed in C */
1254 if (!isid(ch
) && !isnum(ch
))
1258 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1259 add_elf_sym(symtab_section
,
1261 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1263 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1264 add_elf_sym(symtab_section
,
1266 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1273 /* name of ELF interpreter */
1275 static char elf_interp
[] = "/usr/libexec/ld-elf.so.1";
1278 static char elf_interp
[] = "/lib/ld-linux.so.3";
1279 #elif defined(TCC_TARGET_X86_64)
1280 static char elf_interp
[] = "/lib/ld-linux-x86-64.so.2";
1282 static char elf_interp
[] = "/lib/ld-linux.so.2";
1286 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1287 const int *section_order
)
1290 int i
, offset
, size
;
1293 for(i
=1;i
<s1
->nb_sections
;i
++) {
1294 s
= s1
->sections
[section_order
[i
]];
1295 if (s
->sh_type
!= SHT_NOBITS
&&
1296 (s
->sh_flags
& SHF_ALLOC
)) {
1297 while (offset
< s
->sh_offset
) {
1302 fwrite(s
->data
, 1, size
, f
);
1308 /* output an ELF file */
1309 /* XXX: suppress unneeded sections */
1310 int elf_output_file(TCCState
*s1
, const char *filename
)
1316 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1318 Section
*strsec
, *s
;
1319 ElfW(Shdr
) shdr
, *sh
;
1320 ElfW(Phdr
) *phdr
, *ph
;
1321 Section
*interp
, *dynamic
, *dynstr
;
1322 unsigned long saved_dynamic_data_offset
;
1324 int type
, file_type
;
1325 unsigned long rel_addr
, rel_size
;
1327 file_type
= s1
->output_type
;
1330 if (file_type
!= TCC_OUTPUT_OBJ
) {
1331 tcc_add_runtime(s1
);
1335 section_order
= NULL
;
1338 dynstr
= NULL
; /* avoid warning */
1339 saved_dynamic_data_offset
= 0; /* avoid warning */
1341 if (file_type
!= TCC_OUTPUT_OBJ
) {
1342 relocate_common_syms();
1344 tcc_add_linker_symbols(s1
);
1346 if (!s1
->static_link
) {
1348 int sym_index
, index
;
1349 ElfW(Sym
) *esym
, *sym_end
;
1351 if (file_type
== TCC_OUTPUT_EXE
) {
1353 /* add interpreter section only if executable */
1354 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1355 interp
->sh_addralign
= 1;
1356 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
1357 strcpy(ptr
, elf_interp
);
1360 /* add dynamic symbol table */
1361 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1363 ".hash", SHF_ALLOC
);
1364 dynstr
= s1
->dynsym
->link
;
1366 /* add dynamic section */
1367 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1368 SHF_ALLOC
| SHF_WRITE
);
1369 dynamic
->link
= dynstr
;
1370 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1373 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1374 SHF_ALLOC
| SHF_EXECINSTR
);
1375 s1
->plt
->sh_entsize
= 4;
1379 /* scan for undefined symbols and see if they are in the
1380 dynamic symbols. If a symbol STT_FUNC is found, then we
1381 add it in the PLT. If a symbol STT_OBJECT is found, we
1382 add it in the .bss section with a suitable relocation */
1383 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1384 symtab_section
->data_offset
);
1385 if (file_type
== TCC_OUTPUT_EXE
) {
1386 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1389 if (sym
->st_shndx
== SHN_UNDEF
) {
1390 name
= symtab_section
->link
->data
+ sym
->st_name
;
1391 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1393 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1394 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1395 if (type
== STT_FUNC
) {
1396 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1398 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1399 } else if (type
== STT_OBJECT
) {
1400 unsigned long offset
;
1401 offset
= bss_section
->data_offset
;
1402 /* XXX: which alignment ? */
1403 offset
= (offset
+ 16 - 1) & -16;
1404 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1406 bss_section
->sh_num
, name
);
1407 put_elf_reloc(s1
->dynsym
, bss_section
,
1408 offset
, R_COPY
, index
);
1409 offset
+= esym
->st_size
;
1410 bss_section
->data_offset
= offset
;
1413 /* STB_WEAK undefined symbols are accepted */
1414 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1416 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1417 !strcmp(name
, "_fp_hw")) {
1419 error_noabort("undefined symbol '%s'", name
);
1422 } else if (s1
->rdynamic
&&
1423 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1424 /* if -rdynamic option, then export all non
1426 name
= symtab_section
->link
->data
+ sym
->st_name
;
1427 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1429 sym
->st_shndx
, name
);
1436 /* now look at unresolved dynamic symbols and export
1437 corresponding symbol */
1438 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1439 s1
->dynsymtab_section
->data_offset
);
1440 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1443 if (esym
->st_shndx
== SHN_UNDEF
) {
1444 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1445 sym_index
= find_elf_sym(symtab_section
, name
);
1447 /* XXX: avoid adding a symbol if already
1448 present because of -rdynamic ? */
1449 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1450 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1452 sym
->st_shndx
, name
);
1454 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1455 /* weak symbols can stay undefined */
1457 warning("undefined dynamic symbol '%s'", name
);
1464 /* shared library case : we simply export all the global symbols */
1465 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1466 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1467 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1470 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1471 name
= symtab_section
->link
->data
+ sym
->st_name
;
1472 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1474 sym
->st_shndx
, name
);
1475 s1
->symtab_to_dynsym
[sym
-
1476 (ElfW(Sym
) *)symtab_section
->data
] =
1482 build_got_entries(s1
);
1484 /* add a list of needed dlls */
1485 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1486 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1487 if (dllref
->level
== 0)
1488 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1490 /* XXX: currently, since we do not handle PIC code, we
1491 must relocate the readonly segments */
1492 if (file_type
== TCC_OUTPUT_DLL
) {
1494 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1495 put_dt(dynamic
, DT_TEXTREL
, 0);
1498 /* add necessary space for other entries */
1499 saved_dynamic_data_offset
= dynamic
->data_offset
;
1500 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * 9;
1502 /* still need to build got entries in case of static link */
1503 build_got_entries(s1
);
1507 memset(&ehdr
, 0, sizeof(ehdr
));
1509 /* we add a section for symbols */
1510 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1511 put_elf_str(strsec
, "");
1513 /* compute number of sections */
1514 shnum
= s1
->nb_sections
;
1516 /* this array is used to reorder sections in the output file */
1517 section_order
= tcc_malloc(sizeof(int) * shnum
);
1518 section_order
[0] = 0;
1521 /* compute number of program headers */
1524 case TCC_OUTPUT_OBJ
:
1527 case TCC_OUTPUT_EXE
:
1528 if (!s1
->static_link
)
1533 case TCC_OUTPUT_DLL
:
1538 /* allocate strings for section names and decide if an unallocated
1539 section should be output */
1540 /* NOTE: the strsec section comes last, so its size is also
1542 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1543 s
= s1
->sections
[i
];
1544 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1546 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1551 s
->reloc
? s
->reloc
->name
: "n"
1554 /* when generating a DLL, we include relocations but we may
1556 if (file_type
== TCC_OUTPUT_DLL
&&
1557 s
->sh_type
== SHT_RELX
&&
1558 !(s
->sh_flags
& SHF_ALLOC
)) {
1559 /* //gr: avoid bogus relocs for empty (debug) sections */
1560 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1561 prepare_dynamic_rel(s1
, s
);
1563 s
->sh_size
= s
->data_offset
;
1564 } else if (do_debug
||
1565 file_type
== TCC_OUTPUT_OBJ
||
1566 (s
->sh_flags
& SHF_ALLOC
) ||
1567 i
== (s1
->nb_sections
- 1)) {
1568 /* we output all sections if debug or object file */
1569 s
->sh_size
= s
->data_offset
;
1573 /* allocate program segment headers */
1574 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1576 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1577 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1582 /* compute section to program header mapping */
1583 if (s1
->has_text_addr
) {
1584 int a_offset
, p_offset
;
1585 addr
= s1
->text_addr
;
1586 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1588 a_offset
= addr
& (ELF_PAGE_SIZE
- 1);
1589 p_offset
= file_offset
& (ELF_PAGE_SIZE
- 1);
1590 if (a_offset
< p_offset
)
1591 a_offset
+= ELF_PAGE_SIZE
;
1592 file_offset
+= (a_offset
- p_offset
);
1594 if (file_type
== TCC_OUTPUT_DLL
)
1597 addr
= ELF_START_ADDR
;
1598 /* compute address after headers */
1599 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1602 /* dynamic relocation table information, for .dynamic section */
1606 /* leave one program header for the program interpreter */
1611 for(j
= 0; j
< 2; j
++) {
1612 ph
->p_type
= PT_LOAD
;
1614 ph
->p_flags
= PF_R
| PF_X
;
1616 ph
->p_flags
= PF_R
| PF_W
;
1617 ph
->p_align
= ELF_PAGE_SIZE
;
1619 /* we do the following ordering: interp, symbol tables,
1620 relocations, progbits, nobits */
1621 /* XXX: do faster and simpler sorting */
1622 for(k
= 0; k
< 5; k
++) {
1623 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1624 s
= s1
->sections
[i
];
1625 /* compute if section should be included */
1627 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1631 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1632 (SHF_ALLOC
| SHF_WRITE
))
1638 } else if (s
->sh_type
== SHT_DYNSYM
||
1639 s
->sh_type
== SHT_STRTAB
||
1640 s
->sh_type
== SHT_HASH
) {
1643 } else if (s
->sh_type
== SHT_RELX
) {
1646 } else if (s
->sh_type
== SHT_NOBITS
) {
1653 section_order
[sh_order_index
++] = i
;
1655 /* section matches: we align it and add its size */
1657 addr
= (addr
+ s
->sh_addralign
- 1) &
1658 ~(s
->sh_addralign
- 1);
1659 file_offset
+= addr
- tmp
;
1660 s
->sh_offset
= file_offset
;
1663 /* update program header infos */
1664 if (ph
->p_offset
== 0) {
1665 ph
->p_offset
= file_offset
;
1667 ph
->p_paddr
= ph
->p_vaddr
;
1669 /* update dynamic relocation infos */
1670 if (s
->sh_type
== SHT_RELX
) {
1673 rel_size
+= s
->sh_size
;
1676 if (s
->sh_type
!= SHT_NOBITS
)
1677 file_offset
+= s
->sh_size
;
1680 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1681 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1684 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1685 /* if in the middle of a page, we duplicate the page in
1686 memory so that one copy is RX and the other is RW */
1687 if ((addr
& (ELF_PAGE_SIZE
- 1)) != 0)
1688 addr
+= ELF_PAGE_SIZE
;
1690 addr
= (addr
+ ELF_PAGE_SIZE
- 1) & ~(ELF_PAGE_SIZE
- 1);
1691 file_offset
= (file_offset
+ ELF_PAGE_SIZE
- 1) &
1692 ~(ELF_PAGE_SIZE
- 1);
1697 /* if interpreter, then add corresponing program header */
1701 ph
->p_type
= PT_INTERP
;
1702 ph
->p_offset
= interp
->sh_offset
;
1703 ph
->p_vaddr
= interp
->sh_addr
;
1704 ph
->p_paddr
= ph
->p_vaddr
;
1705 ph
->p_filesz
= interp
->sh_size
;
1706 ph
->p_memsz
= interp
->sh_size
;
1708 ph
->p_align
= interp
->sh_addralign
;
1711 /* if dynamic section, then add corresponing program header */
1715 ph
= &phdr
[phnum
- 1];
1717 ph
->p_type
= PT_DYNAMIC
;
1718 ph
->p_offset
= dynamic
->sh_offset
;
1719 ph
->p_vaddr
= dynamic
->sh_addr
;
1720 ph
->p_paddr
= ph
->p_vaddr
;
1721 ph
->p_filesz
= dynamic
->sh_size
;
1722 ph
->p_memsz
= dynamic
->sh_size
;
1723 ph
->p_flags
= PF_R
| PF_W
;
1724 ph
->p_align
= dynamic
->sh_addralign
;
1726 /* put GOT dynamic section address */
1727 put32(s1
->got
->data
, dynamic
->sh_addr
);
1729 /* relocate the PLT */
1730 if (file_type
== TCC_OUTPUT_EXE
) {
1734 p_end
= p
+ s1
->plt
->data_offset
;
1736 #if defined(TCC_TARGET_I386)
1737 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1738 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1741 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1744 #elif defined(TCC_TARGET_X86_64)
1745 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1746 put32(p
+ 2, get32(p
+ 2) + x
);
1747 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1750 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1753 #elif defined(TCC_TARGET_ARM)
1755 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1758 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1761 #elif defined(TCC_TARGET_C67)
1764 #error unsupported CPU
1769 /* relocate symbols in .dynsym */
1770 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1771 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1774 if (sym
->st_shndx
== SHN_UNDEF
) {
1775 /* relocate to the PLT if the symbol corresponds
1778 sym
->st_value
+= s1
->plt
->sh_addr
;
1779 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1780 /* do symbol relocation */
1781 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1785 /* put dynamic section entries */
1786 dynamic
->data_offset
= saved_dynamic_data_offset
;
1787 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1788 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1789 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1790 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1791 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1792 #ifdef TCC_TARGET_X86_64
1793 put_dt(dynamic
, DT_RELA
, rel_addr
);
1794 put_dt(dynamic
, DT_RELASZ
, rel_size
);
1795 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1797 put_dt(dynamic
, DT_REL
, rel_addr
);
1798 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1799 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1802 put_dt(dynamic
, DT_DEBUG
, 0);
1803 put_dt(dynamic
, DT_NULL
, 0);
1806 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1807 ehdr
.e_phnum
= phnum
;
1808 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1811 /* all other sections come after */
1812 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1813 s
= s1
->sections
[i
];
1814 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1816 section_order
[sh_order_index
++] = i
;
1818 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1819 ~(s
->sh_addralign
- 1);
1820 s
->sh_offset
= file_offset
;
1821 if (s
->sh_type
!= SHT_NOBITS
)
1822 file_offset
+= s
->sh_size
;
1825 /* if building executable or DLL, then relocate each section
1826 except the GOT which is already relocated */
1827 if (file_type
!= TCC_OUTPUT_OBJ
) {
1828 relocate_syms(s1
, 0);
1830 if (s1
->nb_errors
!= 0) {
1836 /* relocate sections */
1837 /* XXX: ignore sections with allocated relocations ? */
1838 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1839 s
= s1
->sections
[i
];
1840 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1841 relocate_section(s1
, s
);
1844 /* relocate relocation entries if the relocation tables are
1845 allocated in the executable */
1846 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1847 s
= s1
->sections
[i
];
1848 if ((s
->sh_flags
& SHF_ALLOC
) &&
1849 s
->sh_type
== SHT_RELX
) {
1850 relocate_rel(s1
, s
);
1854 /* get entry point address */
1855 if (file_type
== TCC_OUTPUT_EXE
)
1856 ehdr
.e_entry
= (unsigned long)tcc_get_symbol_err(s1
, "_start");
1858 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1861 /* write elf file */
1862 if (file_type
== TCC_OUTPUT_OBJ
)
1866 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1868 error_noabort("could not write '%s'", filename
);
1871 f
= fdopen(fd
, "wb");
1873 printf("<- %s\n", filename
);
1875 #ifdef TCC_TARGET_COFF
1876 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1877 tcc_output_coff(s1
, f
);
1880 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1881 sort_syms(s1
, symtab_section
);
1884 file_offset
= (file_offset
+ 3) & -4;
1887 ehdr
.e_ident
[0] = ELFMAG0
;
1888 ehdr
.e_ident
[1] = ELFMAG1
;
1889 ehdr
.e_ident
[2] = ELFMAG2
;
1890 ehdr
.e_ident
[3] = ELFMAG3
;
1891 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
1892 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1893 ehdr
.e_ident
[6] = EV_CURRENT
;
1895 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1897 #ifdef TCC_TARGET_ARM
1899 ehdr
.e_ident
[EI_OSABI
] = 0;
1900 ehdr
.e_flags
= 4 << 24;
1902 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
1907 case TCC_OUTPUT_EXE
:
1908 ehdr
.e_type
= ET_EXEC
;
1910 case TCC_OUTPUT_DLL
:
1911 ehdr
.e_type
= ET_DYN
;
1913 case TCC_OUTPUT_OBJ
:
1914 ehdr
.e_type
= ET_REL
;
1917 ehdr
.e_machine
= EM_TCC_TARGET
;
1918 ehdr
.e_version
= EV_CURRENT
;
1919 ehdr
.e_shoff
= file_offset
;
1920 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
1921 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
1922 ehdr
.e_shnum
= shnum
;
1923 ehdr
.e_shstrndx
= shnum
- 1;
1925 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
1926 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
1927 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1929 for(i
=1;i
<s1
->nb_sections
;i
++) {
1930 s
= s1
->sections
[section_order
[i
]];
1931 if (s
->sh_type
!= SHT_NOBITS
) {
1932 while (offset
< s
->sh_offset
) {
1937 fwrite(s
->data
, 1, size
, f
);
1942 /* output section headers */
1943 while (offset
< ehdr
.e_shoff
) {
1948 for(i
=0;i
<s1
->nb_sections
;i
++) {
1950 memset(sh
, 0, sizeof(ElfW(Shdr
)));
1951 s
= s1
->sections
[i
];
1953 sh
->sh_name
= s
->sh_name
;
1954 sh
->sh_type
= s
->sh_type
;
1955 sh
->sh_flags
= s
->sh_flags
;
1956 sh
->sh_entsize
= s
->sh_entsize
;
1957 sh
->sh_info
= s
->sh_info
;
1959 sh
->sh_link
= s
->link
->sh_num
;
1960 sh
->sh_addralign
= s
->sh_addralign
;
1961 sh
->sh_addr
= s
->sh_addr
;
1962 sh
->sh_offset
= s
->sh_offset
;
1963 sh
->sh_size
= s
->sh_size
;
1965 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
1968 tcc_output_binary(s1
, f
, section_order
);
1974 tcc_free(s1
->symtab_to_dynsym
);
1975 tcc_free(section_order
);
1977 tcc_free(s1
->got_offsets
);
1981 int tcc_output_file(TCCState
*s
, const char *filename
)
1984 #ifdef TCC_TARGET_PE
1985 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
1986 ret
= pe_output_file(s
, filename
);
1990 ret
= elf_output_file(s
, filename
);
1995 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
1999 data
= tcc_malloc(size
);
2000 lseek(fd
, file_offset
, SEEK_SET
);
2001 read(fd
, data
, size
);
2005 typedef struct SectionMergeInfo
{
2006 Section
*s
; /* corresponding existing section */
2007 unsigned long offset
; /* offset of the new section in the existing section */
2008 uint8_t new_section
; /* true if section 's' was added */
2009 uint8_t link_once
; /* true if link once section */
2012 /* load an object file and merge it with current files */
2013 /* XXX: handle correctly stab (debug) info */
2014 static int tcc_load_object_file(TCCState
*s1
,
2015 int fd
, unsigned long file_offset
)
2018 ElfW(Shdr
) *shdr
, *sh
;
2019 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2020 unsigned char *strsec
, *strtab
;
2021 int *old_to_new_syms
;
2022 char *sh_name
, *name
;
2023 SectionMergeInfo
*sm_table
, *sm
;
2024 ElfW(Sym
) *sym
, *symtab
;
2025 ElfW_Rel
*rel
, *rel_end
;
2031 stab_index
= stabstr_index
= 0;
2033 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2035 if (ehdr
.e_ident
[0] != ELFMAG0
||
2036 ehdr
.e_ident
[1] != ELFMAG1
||
2037 ehdr
.e_ident
[2] != ELFMAG2
||
2038 ehdr
.e_ident
[3] != ELFMAG3
)
2040 /* test if object file */
2041 if (ehdr
.e_type
!= ET_REL
)
2043 /* test CPU specific stuff */
2044 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2045 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2047 error_noabort("invalid object file");
2051 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2052 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2053 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2055 /* load section names */
2056 sh
= &shdr
[ehdr
.e_shstrndx
];
2057 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2059 /* load symtab and strtab */
2060 old_to_new_syms
= NULL
;
2064 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2066 if (sh
->sh_type
== SHT_SYMTAB
) {
2068 error_noabort("object must contain only one symtab");
2073 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2074 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2075 sm_table
[i
].s
= symtab_section
;
2077 /* now load strtab */
2078 sh
= &shdr
[sh
->sh_link
];
2079 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2083 /* now examine each section and try to merge its content with the
2085 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2086 /* no need to examine section name strtab */
2087 if (i
== ehdr
.e_shstrndx
)
2090 sh_name
= strsec
+ sh
->sh_name
;
2091 /* ignore sections types we do not handle */
2092 if (sh
->sh_type
!= SHT_PROGBITS
&&
2093 sh
->sh_type
!= SHT_RELX
&&
2095 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2097 sh
->sh_type
!= SHT_NOBITS
&&
2098 strcmp(sh_name
, ".stabstr")
2101 if (sh
->sh_addralign
< 1)
2102 sh
->sh_addralign
= 1;
2103 /* find corresponding section, if any */
2104 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2105 s
= s1
->sections
[j
];
2106 if (!strcmp(s
->name
, sh_name
)) {
2107 if (!strncmp(sh_name
, ".gnu.linkonce",
2108 sizeof(".gnu.linkonce") - 1)) {
2109 /* if a 'linkonce' section is already present, we
2110 do not add it again. It is a little tricky as
2111 symbols can still be defined in
2113 sm_table
[i
].link_once
= 1;
2120 /* not found: create new section */
2121 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2122 /* take as much info as possible from the section. sh_link and
2123 sh_info will be updated later */
2124 s
->sh_addralign
= sh
->sh_addralign
;
2125 s
->sh_entsize
= sh
->sh_entsize
;
2126 sm_table
[i
].new_section
= 1;
2128 if (sh
->sh_type
!= s
->sh_type
) {
2129 error_noabort("invalid section type");
2133 /* align start of section */
2134 offset
= s
->data_offset
;
2136 if (0 == strcmp(sh_name
, ".stab")) {
2140 if (0 == strcmp(sh_name
, ".stabstr")) {
2145 size
= sh
->sh_addralign
- 1;
2146 offset
= (offset
+ size
) & ~size
;
2147 if (sh
->sh_addralign
> s
->sh_addralign
)
2148 s
->sh_addralign
= sh
->sh_addralign
;
2149 s
->data_offset
= offset
;
2151 sm_table
[i
].offset
= offset
;
2153 /* concatenate sections */
2155 if (sh
->sh_type
!= SHT_NOBITS
) {
2157 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2158 ptr
= section_ptr_add(s
, size
);
2159 read(fd
, ptr
, size
);
2161 s
->data_offset
+= size
;
2166 /* //gr relocate stab strings */
2167 if (stab_index
&& stabstr_index
) {
2170 s
= sm_table
[stab_index
].s
;
2171 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2172 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2173 o
= sm_table
[stabstr_index
].offset
;
2175 a
->n_strx
+= o
, a
++;
2178 /* second short pass to update sh_link and sh_info fields of new
2180 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2182 if (!s
|| !sm_table
[i
].new_section
)
2185 if (sh
->sh_link
> 0)
2186 s
->link
= sm_table
[sh
->sh_link
].s
;
2187 if (sh
->sh_type
== SHT_RELX
) {
2188 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2189 /* update backward link */
2190 s1
->sections
[s
->sh_info
]->reloc
= s
;
2195 /* resolve symbols */
2196 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2199 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2200 if (sym
->st_shndx
!= SHN_UNDEF
&&
2201 sym
->st_shndx
< SHN_LORESERVE
) {
2202 sm
= &sm_table
[sym
->st_shndx
];
2203 if (sm
->link_once
) {
2204 /* if a symbol is in a link once section, we use the
2205 already defined symbol. It is very important to get
2206 correct relocations */
2207 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2208 name
= strtab
+ sym
->st_name
;
2209 sym_index
= find_elf_sym(symtab_section
, name
);
2211 old_to_new_syms
[i
] = sym_index
;
2215 /* if no corresponding section added, no need to add symbol */
2218 /* convert section number */
2219 sym
->st_shndx
= sm
->s
->sh_num
;
2221 sym
->st_value
+= sm
->offset
;
2224 name
= strtab
+ sym
->st_name
;
2225 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2226 sym
->st_info
, sym
->st_other
,
2227 sym
->st_shndx
, name
);
2228 old_to_new_syms
[i
] = sym_index
;
2231 /* third pass to patch relocation entries */
2232 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2237 offset
= sm_table
[i
].offset
;
2238 switch(s
->sh_type
) {
2240 /* take relocation offset information */
2241 offseti
= sm_table
[sh
->sh_info
].offset
;
2242 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2243 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2248 /* convert symbol index */
2249 type
= ELFW(R_TYPE
)(rel
->r_info
);
2250 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2251 /* NOTE: only one symtab assumed */
2252 if (sym_index
>= nb_syms
)
2254 sym_index
= old_to_new_syms
[sym_index
];
2255 /* ignore link_once in rel section. */
2256 if (!sym_index
&& !sm
->link_once
) {
2258 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2259 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2262 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2263 /* offset the relocation offset */
2264 rel
->r_offset
+= offseti
;
2276 tcc_free(old_to_new_syms
);
2283 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2285 typedef struct ArchiveHeader
{
2286 char ar_name
[16]; /* name of this member */
2287 char ar_date
[12]; /* file mtime */
2288 char ar_uid
[6]; /* owner uid; printed as decimal */
2289 char ar_gid
[6]; /* owner gid; printed as decimal */
2290 char ar_mode
[8]; /* file mode, printed as octal */
2291 char ar_size
[10]; /* file size, printed as decimal */
2292 char ar_fmag
[2]; /* should contain ARFMAG */
2295 static int get_be32(const uint8_t *b
)
2297 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2300 /* load only the objects which resolve undefined symbols */
2301 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2303 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2305 const char *ar_names
, *p
;
2306 const uint8_t *ar_index
;
2309 data
= tcc_malloc(size
);
2310 if (read(fd
, data
, size
) != size
)
2312 nsyms
= get_be32(data
);
2313 ar_index
= data
+ 4;
2314 ar_names
= ar_index
+ nsyms
* 4;
2318 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2319 sym_index
= find_elf_sym(symtab_section
, p
);
2321 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2322 if(sym
->st_shndx
== SHN_UNDEF
) {
2323 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2325 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2328 lseek(fd
, off
, SEEK_SET
);
2329 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2344 /* load a '.a' file */
2345 static int tcc_load_archive(TCCState
*s1
, int fd
)
2352 unsigned long file_offset
;
2354 /* skip magic which was already checked */
2355 read(fd
, magic
, sizeof(magic
));
2358 len
= read(fd
, &hdr
, sizeof(hdr
));
2361 if (len
!= sizeof(hdr
)) {
2362 error_noabort("invalid archive");
2365 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2366 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2367 size
= strtol(ar_size
, NULL
, 0);
2368 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2369 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2370 if (ar_name
[i
] != ' ')
2373 ar_name
[i
+ 1] = '\0';
2374 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2375 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2377 size
= (size
+ 1) & ~1;
2378 if (!strcmp(ar_name
, "/")) {
2379 /* coff symbol table : we handle it */
2380 if(s1
->alacarte_link
)
2381 return tcc_load_alacarte(s1
, fd
, size
);
2382 } else if (!strcmp(ar_name
, "//") ||
2383 !strcmp(ar_name
, "__.SYMDEF") ||
2384 !strcmp(ar_name
, "__.SYMDEF/") ||
2385 !strcmp(ar_name
, "ARFILENAMES/")) {
2386 /* skip symbol table or archive names */
2388 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2391 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2396 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2397 is referenced by the user (so it should be added as DT_NEEDED in
2398 the generated ELF file) */
2399 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2402 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2403 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2404 ElfW(Sym
) *sym
, *dynsym
;
2405 ElfW(Dyn
) *dt
, *dynamic
;
2406 unsigned char *dynstr
;
2407 const char *name
, *soname
;
2408 DLLReference
*dllref
;
2410 read(fd
, &ehdr
, sizeof(ehdr
));
2412 /* test CPU specific stuff */
2413 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2414 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2415 error_noabort("bad architecture");
2420 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2422 /* load dynamic section and dynamic symbols */
2426 dynsym
= NULL
; /* avoid warning */
2427 dynstr
= NULL
; /* avoid warning */
2428 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2429 switch(sh
->sh_type
) {
2431 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2432 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2435 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2436 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2437 sh1
= &shdr
[sh
->sh_link
];
2438 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2445 /* compute the real library name */
2446 soname
= tcc_basename(filename
);
2448 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2449 if (dt
->d_tag
== DT_SONAME
) {
2450 soname
= dynstr
+ dt
->d_un
.d_val
;
2454 /* if the dll is already loaded, do not load it */
2455 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2456 dllref
= s1
->loaded_dlls
[i
];
2457 if (!strcmp(soname
, dllref
->name
)) {
2458 /* but update level if needed */
2459 if (level
< dllref
->level
)
2460 dllref
->level
= level
;
2466 // printf("loading dll '%s'\n", soname);
2468 /* add the dll and its level */
2469 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2470 dllref
->level
= level
;
2471 strcpy(dllref
->name
, soname
);
2472 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2474 /* add dynamic symbols in dynsym_section */
2475 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2476 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2477 if (sym_bind
== STB_LOCAL
)
2479 name
= dynstr
+ sym
->st_name
;
2480 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2481 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2484 /* load all referenced DLLs */
2485 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2488 name
= dynstr
+ dt
->d_un
.d_val
;
2489 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2490 dllref
= s1
->loaded_dlls
[j
];
2491 if (!strcmp(name
, dllref
->name
))
2492 goto already_loaded
;
2494 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2495 error_noabort("referenced dll '%s' not found", name
);
2512 #define LD_TOK_NAME 256
2513 #define LD_TOK_EOF (-1)
2515 /* return next ld script token */
2516 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2534 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2535 ch
= file
->buf_ptr
[0];
2543 /* case 'a' ... 'z': */
2570 /* case 'A' ... 'z': */
2605 if (!((ch
>= 'a' && ch
<= 'z') ||
2606 (ch
>= 'A' && ch
<= 'Z') ||
2607 (ch
>= '0' && ch
<= '9') ||
2608 strchr("/.-_+=$:\\,~", ch
)))
2610 if ((q
- name
) < name_size
- 1) {
2627 printf("tok=%c %d\n", c
, c
);
2628 if (c
== LD_TOK_NAME
)
2629 printf(" name=%s\n", name
);
2634 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2636 char filename
[1024];
2639 t
= ld_next(s1
, filename
, sizeof(filename
));
2642 t
= ld_next(s1
, filename
, sizeof(filename
));
2644 if (t
== LD_TOK_EOF
) {
2645 error_noabort("unexpected end of file");
2647 } else if (t
== ')') {
2649 } else if (t
!= LD_TOK_NAME
) {
2650 error_noabort("filename expected");
2653 if (!strcmp(filename
, "AS_NEEDED")) {
2654 ret
= ld_add_file_list(s1
, 1);
2658 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2660 tcc_add_file(s1
, filename
);
2662 t
= ld_next(s1
, filename
, sizeof(filename
));
2664 t
= ld_next(s1
, filename
, sizeof(filename
));
2670 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2672 static int tcc_load_ldscript(TCCState
*s1
)
2675 char filename
[1024];
2678 ch
= file
->buf_ptr
[0];
2681 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2682 if (t
== LD_TOK_EOF
)
2684 else if (t
!= LD_TOK_NAME
)
2686 if (!strcmp(cmd
, "INPUT") ||
2687 !strcmp(cmd
, "GROUP")) {
2688 ret
= ld_add_file_list(s1
, 0);
2691 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2692 !strcmp(cmd
, "TARGET")) {
2693 /* ignore some commands */
2694 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2698 t
= ld_next(s1
, filename
, sizeof(filename
));
2699 if (t
== LD_TOK_EOF
) {
2700 error_noabort("unexpected end of file");
2702 } else if (t
== ')') {