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
;
511 #if defined(TCC_TARGET_I386)
516 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
517 qrel
= (ElfW_Rel
*)sr
->data
;
521 ptr
= s
->data
+ rel
->r_offset
;
523 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
524 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
526 #ifdef TCC_TARGET_X86_64
527 /* XXX: not tested */
528 val
+= rel
->r_addend
;
530 type
= ELFW(R_TYPE
)(rel
->r_info
);
531 addr
= s
->sh_addr
+ rel
->r_offset
;
535 #if defined(TCC_TARGET_I386)
537 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
538 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
539 qrel
->r_offset
= rel
->r_offset
;
541 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_32
);
545 qrel
->r_info
= ELFW(R_INFO
)(0, R_386_RELATIVE
);
552 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
554 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
556 qrel
->r_offset
= rel
->r_offset
;
557 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_PC32
);
562 *(int *)ptr
+= val
- addr
;
565 *(int *)ptr
+= val
- addr
;
572 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
575 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
578 /* we load the got offset */
579 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
581 #elif defined(TCC_TARGET_ARM)
588 x
= (*(int *)ptr
)&0xffffff;
589 (*(int *)ptr
) &= 0xff000000;
594 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
595 error("can't relocate value at %x",addr
);
604 x
= (*(int *)ptr
) & 0x7fffffff;
605 (*(int *)ptr
) &= 0x80000000;
608 if((x
^(x
>>1))&0x40000000)
609 error("can't relocate value at %x",addr
);
610 (*(int *)ptr
) |= x
& 0x7fffffff;
615 case R_ARM_BASE_PREL
:
616 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
619 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
622 /* we load the got offset */
623 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
628 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
629 type
,addr
,(unsigned int )ptr
,val
);
631 #elif defined(TCC_TARGET_C67)
639 /* put the low 16 bits of the absolute address */
640 // add to what is already there
642 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
643 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
645 //patch both at once - assumes always in pairs Low - High
647 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
648 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
654 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
655 type
,addr
,(unsigned int )ptr
,val
);
657 #elif defined(TCC_TARGET_X86_64)
659 *(long long *)ptr
+= val
;
665 case R_X86_64_PC32
: {
666 long diff
= val
- addr
;
667 if (diff
< -2147483648 || diff
> 2147483647) {
668 /* XXX: naive support for over 32bit jump */
669 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
670 val
= add_jmp_table(s1
, val
);
673 if (diff
<= -2147483647 || diff
> 2147483647) {
675 /* output memory map to debug easily */
680 printf("%ld - %ld = %ld\n", val
, addr
, diff
);
681 dladdr((void *)addr
, &di
);
682 printf("addr = %lx = %lx+%lx(%s) ptr=%p\n",
683 addr
, s
->sh_addr
, rel
->r_offset
, di
.dli_sname
,
685 fp
= fopen("/proc/self/maps", "r");
686 size
= fread(buf
, 1, 4095, fp
);
690 error("internal error: relocation failed");
693 *(int *)ptr
+= val
- addr
;
697 *(int *)ptr
+= val
- addr
;
699 case R_X86_64_GLOB_DAT
:
700 case R_X86_64_JUMP_SLOT
:
703 case R_X86_64_GOTPCREL
:
704 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
706 case R_X86_64_GOTTPOFF
:
707 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
710 /* we load the got offset */
711 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
714 #error unsupported processor
718 /* if the relocation is allocated, we change its symbol table */
719 if (sr
->sh_flags
& SHF_ALLOC
)
720 sr
->link
= s1
->dynsym
;
723 /* relocate relocation table in 'sr' */
724 static void relocate_rel(TCCState
*s1
, Section
*sr
)
727 ElfW_Rel
*rel
, *rel_end
;
729 s
= s1
->sections
[sr
->sh_info
];
730 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
731 for(rel
= (ElfW_Rel
*)sr
->data
;
734 rel
->r_offset
+= s
->sh_addr
;
738 /* count the number of dynamic relocations so that we can reserve
740 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
742 ElfW_Rel
*rel
, *rel_end
;
743 int sym_index
, esym_index
, type
, count
;
746 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
747 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
748 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
749 type
= ELFW(R_TYPE
)(rel
->r_info
);
755 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
764 /* allocate the section */
765 sr
->sh_flags
|= SHF_ALLOC
;
766 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
771 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
776 if (index
>= s1
->nb_got_offsets
) {
777 /* find immediately bigger power of 2 and reallocate array */
781 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
783 error("memory full");
784 s1
->got_offsets
= tab
;
785 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
786 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
787 s1
->nb_got_offsets
= n
;
789 s1
->got_offsets
[index
] = val
;
792 /* XXX: suppress that */
793 static void put32(unsigned char *p
, uint32_t val
)
801 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
802 defined(TCC_TARGET_X86_64)
803 static uint32_t get32(unsigned char *p
)
805 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
809 static void build_got(TCCState
*s1
)
813 /* if no got, then create it */
814 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
815 s1
->got
->sh_entsize
= 4;
816 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
817 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
818 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
820 /* keep space for _DYNAMIC pointer, if present */
822 /* two dummy got entries */
826 /* keep space for _DYNAMIC pointer, if present */
829 /* two dummy got entries */
837 /* put a got entry corresponding to a symbol in symtab_section. 'size'
838 and 'info' can be modifed if more precise info comes from the DLL */
839 static void put_got_entry(TCCState
*s1
,
840 int reloc_type
, unsigned long size
, int info
,
846 unsigned long offset
;
852 /* if a got entry already exists for that symbol, no need to add one */
853 if (sym_index
< s1
->nb_got_offsets
&&
854 s1
->got_offsets
[sym_index
] != 0)
857 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
860 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
861 name
= symtab_section
->link
->data
+ sym
->st_name
;
862 offset
= sym
->st_value
;
863 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
865 #ifdef TCC_TARGET_X86_64
875 /* if we build a DLL, we add a %ebx offset */
876 if (s1
->output_type
== TCC_OUTPUT_DLL
)
881 /* add a PLT entry */
883 if (plt
->data_offset
== 0) {
884 /* first plt entry */
885 p
= section_ptr_add(plt
, 16);
886 p
[0] = 0xff; /* pushl got + PTR_SIZE */
888 put32(p
+ 2, PTR_SIZE
);
889 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
891 put32(p
+ 8, PTR_SIZE
* 2);
894 p
= section_ptr_add(plt
, 16);
895 p
[0] = 0xff; /* jmp *(got + x) */
897 put32(p
+ 2, s1
->got
->data_offset
);
898 p
[6] = 0x68; /* push $xxx */
899 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
900 p
[11] = 0xe9; /* jmp plt_start */
901 put32(p
+ 12, -(plt
->data_offset
));
903 /* the symbol is modified so that it will be relocated to
905 if (s1
->output_type
== TCC_OUTPUT_EXE
)
906 offset
= plt
->data_offset
- 16;
908 #elif defined(TCC_TARGET_ARM)
909 if (reloc_type
== R_ARM_JUMP_SLOT
) {
913 /* if we build a DLL, we add a %ebx offset */
914 if (s1
->output_type
== TCC_OUTPUT_DLL
)
915 error("DLLs unimplemented!");
917 /* add a PLT entry */
919 if (plt
->data_offset
== 0) {
920 /* first plt entry */
921 p
= section_ptr_add(plt
, 16);
922 put32(p
, 0xe52de004);
923 put32(p
+ 4, 0xe59fe010);
924 put32(p
+ 8, 0xe08fe00e);
925 put32(p
+ 12, 0xe5bef008);
928 p
= section_ptr_add(plt
, 16);
929 put32(p
, 0xe59fc004);
930 put32(p
+4, 0xe08fc00c);
931 put32(p
+8, 0xe59cf000);
932 put32(p
+12, s1
->got
->data_offset
);
934 /* the symbol is modified so that it will be relocated to
936 if (s1
->output_type
== TCC_OUTPUT_EXE
)
937 offset
= plt
->data_offset
- 16;
939 #elif defined(TCC_TARGET_C67)
940 error("C67 got not implemented");
942 #error unsupported CPU
944 index
= put_elf_sym(s1
->dynsym
, offset
,
945 size
, info
, 0, sym
->st_shndx
, name
);
946 /* put a got entry */
947 put_elf_reloc(s1
->dynsym
, s1
->got
,
948 s1
->got
->data_offset
,
951 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
955 /* build GOT and PLT entries */
956 static void build_got_entries(TCCState
*s1
)
959 ElfW_Rel
*rel
, *rel_end
;
961 int i
, type
, reloc_type
, sym_index
;
963 for(i
= 1; i
< s1
->nb_sections
; i
++) {
965 if (s
->sh_type
!= SHT_RELX
)
967 /* no need to handle got relocations */
968 if (s
->link
!= symtab_section
)
971 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
972 for(rel
= (ElfW_Rel
*)s
->data
;
975 type
= ELFW(R_TYPE
)(rel
->r_info
);
977 #if defined(TCC_TARGET_I386)
984 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
985 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
986 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
987 /* look at the symbol got offset. If none, then add one */
988 if (type
== R_386_GOT32
)
989 reloc_type
= R_386_GLOB_DAT
;
991 reloc_type
= R_386_JMP_SLOT
;
992 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
996 #elif defined(TCC_TARGET_ARM)
999 case R_ARM_BASE_PREL
:
1003 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1004 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1005 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1006 /* look at the symbol got offset. If none, then add one */
1007 if (type
== R_ARM_GOT_BREL
)
1008 reloc_type
= R_ARM_GLOB_DAT
;
1010 reloc_type
= R_ARM_JUMP_SLOT
;
1011 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1015 #elif defined(TCC_TARGET_C67)
1022 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1023 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1024 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1025 /* look at the symbol got offset. If none, then add one */
1026 if (type
== R_C60_GOT32
)
1027 reloc_type
= R_C60_GLOB_DAT
;
1029 reloc_type
= R_C60_JMP_SLOT
;
1030 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1034 #elif defined(TCC_TARGET_X86_64)
1035 case R_X86_64_GOT32
:
1036 case R_X86_64_GOTTPOFF
:
1037 case R_X86_64_GOTPCREL
:
1038 case R_X86_64_PLT32
:
1041 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_PLT32
) {
1042 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1043 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1044 /* look at the symbol got offset. If none, then add one */
1045 if (type
== R_X86_64_GOT32
)
1046 reloc_type
= R_X86_64_GLOB_DAT
;
1048 reloc_type
= R_X86_64_JUMP_SLOT
;
1049 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1054 #error unsupported CPU
1063 static Section
*new_symtab(TCCState
*s1
,
1064 const char *symtab_name
, int sh_type
, int sh_flags
,
1065 const char *strtab_name
,
1066 const char *hash_name
, int hash_sh_flags
)
1068 Section
*symtab
, *strtab
, *hash
;
1069 int *ptr
, nb_buckets
;
1071 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1072 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1073 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1074 put_elf_str(strtab
, "");
1075 symtab
->link
= strtab
;
1076 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1080 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1081 hash
->sh_entsize
= sizeof(int);
1082 symtab
->hash
= hash
;
1083 hash
->link
= symtab
;
1085 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1086 ptr
[0] = nb_buckets
;
1088 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1092 /* put dynamic tag */
1093 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1096 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1098 dyn
->d_un
.d_val
= val
;
1101 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1105 char sym_start
[1024];
1108 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1109 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1111 s
= find_section(s1
, section_name
);
1116 end_offset
= s
->data_offset
;
1119 add_elf_sym(symtab_section
,
1121 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1122 s
->sh_num
, sym_start
);
1123 add_elf_sym(symtab_section
,
1125 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1126 s
->sh_num
, sym_end
);
1129 /* add tcc runtime libraries */
1130 static void tcc_add_runtime(TCCState
*s1
)
1132 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1136 #ifdef CONFIG_TCC_BCHECK
1137 if (do_bounds_check
) {
1139 Section
*init_section
;
1140 unsigned char *pinit
;
1143 /* XXX: add an object file to do that */
1144 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1146 add_elf_sym(symtab_section
, 0, 0,
1147 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1148 bounds_section
->sh_num
, "__bounds_start");
1149 /* add bound check code */
1150 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "bcheck.o");
1151 tcc_add_file(s1
, buf
);
1152 #ifdef TCC_TARGET_I386
1153 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1154 /* add 'call __bound_init()' in .init section */
1155 init_section
= find_section(s1
, ".init");
1156 pinit
= section_ptr_add(init_section
, 5);
1158 put32(pinit
+ 1, -4);
1159 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1160 put_elf_reloc(symtab_section
, init_section
,
1161 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1167 if (!s1
->nostdlib
) {
1168 tcc_add_library(s1
, "c");
1170 #ifdef CONFIG_USE_LIBGCC
1171 tcc_add_file(s1
, CONFIG_SYSROOT
"/lib/libgcc_s.so.1");
1173 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "libtcc1.a");
1174 tcc_add_file(s1
, buf
);
1177 /* add crt end if not memory output */
1178 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1179 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1183 /* add various standard linker symbols (must be done after the
1184 sections are filled (for example after allocating common
1186 static void tcc_add_linker_symbols(TCCState
*s1
)
1192 add_elf_sym(symtab_section
,
1193 text_section
->data_offset
, 0,
1194 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1195 text_section
->sh_num
, "_etext");
1196 add_elf_sym(symtab_section
,
1197 data_section
->data_offset
, 0,
1198 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1199 data_section
->sh_num
, "_edata");
1200 add_elf_sym(symtab_section
,
1201 bss_section
->data_offset
, 0,
1202 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1203 bss_section
->sh_num
, "_end");
1204 /* horrible new standard ldscript defines */
1205 add_init_array_defines(s1
, ".preinit_array");
1206 add_init_array_defines(s1
, ".init_array");
1207 add_init_array_defines(s1
, ".fini_array");
1209 /* add start and stop symbols for sections whose name can be
1211 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1212 s
= s1
->sections
[i
];
1213 if (s
->sh_type
== SHT_PROGBITS
&&
1214 (s
->sh_flags
& SHF_ALLOC
)) {
1218 /* check if section name can be expressed in C */
1224 if (!isid(ch
) && !isnum(ch
))
1228 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1229 add_elf_sym(symtab_section
,
1231 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1233 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1234 add_elf_sym(symtab_section
,
1236 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1243 /* name of ELF interpreter */
1245 static char elf_interp
[] = "/usr/libexec/ld-elf.so.1";
1248 static char elf_interp
[] = "/lib/ld-linux.so.3";
1249 #elif defined(TCC_TARGET_X86_64)
1250 static char elf_interp
[] = "/lib/ld-linux-x86-64.so.2";
1252 static char elf_interp
[] = "/lib/ld-linux.so.2";
1256 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1257 const int *section_order
)
1260 int i
, offset
, size
;
1263 for(i
=1;i
<s1
->nb_sections
;i
++) {
1264 s
= s1
->sections
[section_order
[i
]];
1265 if (s
->sh_type
!= SHT_NOBITS
&&
1266 (s
->sh_flags
& SHF_ALLOC
)) {
1267 while (offset
< s
->sh_offset
) {
1272 fwrite(s
->data
, 1, size
, f
);
1278 /* output an ELF file */
1279 /* XXX: suppress unneeded sections */
1280 int elf_output_file(TCCState
*s1
, const char *filename
)
1286 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1288 Section
*strsec
, *s
;
1289 ElfW(Shdr
) shdr
, *sh
;
1290 ElfW(Phdr
) *phdr
, *ph
;
1291 Section
*interp
, *dynamic
, *dynstr
;
1292 unsigned long saved_dynamic_data_offset
;
1294 int type
, file_type
;
1295 unsigned long rel_addr
, rel_size
;
1297 file_type
= s1
->output_type
;
1300 if (file_type
!= TCC_OUTPUT_OBJ
) {
1301 tcc_add_runtime(s1
);
1305 section_order
= NULL
;
1308 dynstr
= NULL
; /* avoid warning */
1309 saved_dynamic_data_offset
= 0; /* avoid warning */
1311 if (file_type
!= TCC_OUTPUT_OBJ
) {
1312 relocate_common_syms();
1314 tcc_add_linker_symbols(s1
);
1316 if (!s1
->static_link
) {
1318 int sym_index
, index
;
1319 ElfW(Sym
) *esym
, *sym_end
;
1321 if (file_type
== TCC_OUTPUT_EXE
) {
1323 /* add interpreter section only if executable */
1324 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1325 interp
->sh_addralign
= 1;
1326 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
1327 strcpy(ptr
, elf_interp
);
1330 /* add dynamic symbol table */
1331 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1333 ".hash", SHF_ALLOC
);
1334 dynstr
= s1
->dynsym
->link
;
1336 /* add dynamic section */
1337 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1338 SHF_ALLOC
| SHF_WRITE
);
1339 dynamic
->link
= dynstr
;
1340 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1343 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1344 SHF_ALLOC
| SHF_EXECINSTR
);
1345 s1
->plt
->sh_entsize
= 4;
1349 /* scan for undefined symbols and see if they are in the
1350 dynamic symbols. If a symbol STT_FUNC is found, then we
1351 add it in the PLT. If a symbol STT_OBJECT is found, we
1352 add it in the .bss section with a suitable relocation */
1353 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1354 symtab_section
->data_offset
);
1355 if (file_type
== TCC_OUTPUT_EXE
) {
1356 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1359 if (sym
->st_shndx
== SHN_UNDEF
) {
1360 name
= symtab_section
->link
->data
+ sym
->st_name
;
1361 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1363 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1364 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1365 if (type
== STT_FUNC
) {
1366 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1368 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1369 } else if (type
== STT_OBJECT
) {
1370 unsigned long offset
;
1371 offset
= bss_section
->data_offset
;
1372 /* XXX: which alignment ? */
1373 offset
= (offset
+ 16 - 1) & -16;
1374 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1376 bss_section
->sh_num
, name
);
1377 put_elf_reloc(s1
->dynsym
, bss_section
,
1378 offset
, R_COPY
, index
);
1379 offset
+= esym
->st_size
;
1380 bss_section
->data_offset
= offset
;
1383 /* STB_WEAK undefined symbols are accepted */
1384 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1386 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1387 !strcmp(name
, "_fp_hw")) {
1389 error_noabort("undefined symbol '%s'", name
);
1392 } else if (s1
->rdynamic
&&
1393 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1394 /* if -rdynamic option, then export all non
1396 name
= symtab_section
->link
->data
+ sym
->st_name
;
1397 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1399 sym
->st_shndx
, name
);
1406 /* now look at unresolved dynamic symbols and export
1407 corresponding symbol */
1408 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1409 s1
->dynsymtab_section
->data_offset
);
1410 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1413 if (esym
->st_shndx
== SHN_UNDEF
) {
1414 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1415 sym_index
= find_elf_sym(symtab_section
, name
);
1417 /* XXX: avoid adding a symbol if already
1418 present because of -rdynamic ? */
1419 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1420 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1422 sym
->st_shndx
, name
);
1424 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1425 /* weak symbols can stay undefined */
1427 warning("undefined dynamic symbol '%s'", name
);
1434 /* shared library case : we simply export all the global symbols */
1435 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1436 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1437 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1440 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1441 name
= symtab_section
->link
->data
+ sym
->st_name
;
1442 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1444 sym
->st_shndx
, name
);
1445 s1
->symtab_to_dynsym
[sym
-
1446 (ElfW(Sym
) *)symtab_section
->data
] =
1452 build_got_entries(s1
);
1454 /* add a list of needed dlls */
1455 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1456 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1457 if (dllref
->level
== 0)
1458 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1460 /* XXX: currently, since we do not handle PIC code, we
1461 must relocate the readonly segments */
1462 if (file_type
== TCC_OUTPUT_DLL
) {
1464 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1465 put_dt(dynamic
, DT_TEXTREL
, 0);
1468 /* add necessary space for other entries */
1469 saved_dynamic_data_offset
= dynamic
->data_offset
;
1470 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * 9;
1472 /* still need to build got entries in case of static link */
1473 build_got_entries(s1
);
1477 memset(&ehdr
, 0, sizeof(ehdr
));
1479 /* we add a section for symbols */
1480 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1481 put_elf_str(strsec
, "");
1483 /* compute number of sections */
1484 shnum
= s1
->nb_sections
;
1486 /* this array is used to reorder sections in the output file */
1487 section_order
= tcc_malloc(sizeof(int) * shnum
);
1488 section_order
[0] = 0;
1491 /* compute number of program headers */
1494 case TCC_OUTPUT_OBJ
:
1497 case TCC_OUTPUT_EXE
:
1498 if (!s1
->static_link
)
1503 case TCC_OUTPUT_DLL
:
1508 /* allocate strings for section names and decide if an unallocated
1509 section should be output */
1510 /* NOTE: the strsec section comes last, so its size is also
1512 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1513 s
= s1
->sections
[i
];
1514 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1516 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1521 s
->reloc
? s
->reloc
->name
: "n"
1524 /* when generating a DLL, we include relocations but we may
1526 if (file_type
== TCC_OUTPUT_DLL
&&
1527 s
->sh_type
== SHT_RELX
&&
1528 !(s
->sh_flags
& SHF_ALLOC
)) {
1529 /* //gr: avoid bogus relocs for empty (debug) sections */
1530 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1531 prepare_dynamic_rel(s1
, s
);
1533 s
->sh_size
= s
->data_offset
;
1534 } else if (do_debug
||
1535 file_type
== TCC_OUTPUT_OBJ
||
1536 (s
->sh_flags
& SHF_ALLOC
) ||
1537 i
== (s1
->nb_sections
- 1)) {
1538 /* we output all sections if debug or object file */
1539 s
->sh_size
= s
->data_offset
;
1543 /* allocate program segment headers */
1544 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1546 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1547 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1552 /* compute section to program header mapping */
1553 if (s1
->has_text_addr
) {
1554 int a_offset
, p_offset
;
1555 addr
= s1
->text_addr
;
1556 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1558 a_offset
= addr
& (ELF_PAGE_SIZE
- 1);
1559 p_offset
= file_offset
& (ELF_PAGE_SIZE
- 1);
1560 if (a_offset
< p_offset
)
1561 a_offset
+= ELF_PAGE_SIZE
;
1562 file_offset
+= (a_offset
- p_offset
);
1564 if (file_type
== TCC_OUTPUT_DLL
)
1567 addr
= ELF_START_ADDR
;
1568 /* compute address after headers */
1569 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1572 /* dynamic relocation table information, for .dynamic section */
1576 /* leave one program header for the program interpreter */
1581 for(j
= 0; j
< 2; j
++) {
1582 ph
->p_type
= PT_LOAD
;
1584 ph
->p_flags
= PF_R
| PF_X
;
1586 ph
->p_flags
= PF_R
| PF_W
;
1587 ph
->p_align
= ELF_PAGE_SIZE
;
1589 /* we do the following ordering: interp, symbol tables,
1590 relocations, progbits, nobits */
1591 /* XXX: do faster and simpler sorting */
1592 for(k
= 0; k
< 5; k
++) {
1593 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1594 s
= s1
->sections
[i
];
1595 /* compute if section should be included */
1597 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1601 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1602 (SHF_ALLOC
| SHF_WRITE
))
1608 } else if (s
->sh_type
== SHT_DYNSYM
||
1609 s
->sh_type
== SHT_STRTAB
||
1610 s
->sh_type
== SHT_HASH
) {
1613 } else if (s
->sh_type
== SHT_RELX
) {
1616 } else if (s
->sh_type
== SHT_NOBITS
) {
1623 section_order
[sh_order_index
++] = i
;
1625 /* section matches: we align it and add its size */
1627 addr
= (addr
+ s
->sh_addralign
- 1) &
1628 ~(s
->sh_addralign
- 1);
1629 file_offset
+= addr
- tmp
;
1630 s
->sh_offset
= file_offset
;
1633 /* update program header infos */
1634 if (ph
->p_offset
== 0) {
1635 ph
->p_offset
= file_offset
;
1637 ph
->p_paddr
= ph
->p_vaddr
;
1639 /* update dynamic relocation infos */
1640 if (s
->sh_type
== SHT_RELX
) {
1643 rel_size
+= s
->sh_size
;
1646 if (s
->sh_type
!= SHT_NOBITS
)
1647 file_offset
+= s
->sh_size
;
1650 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1651 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1654 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1655 /* if in the middle of a page, we duplicate the page in
1656 memory so that one copy is RX and the other is RW */
1657 if ((addr
& (ELF_PAGE_SIZE
- 1)) != 0)
1658 addr
+= ELF_PAGE_SIZE
;
1660 addr
= (addr
+ ELF_PAGE_SIZE
- 1) & ~(ELF_PAGE_SIZE
- 1);
1661 file_offset
= (file_offset
+ ELF_PAGE_SIZE
- 1) &
1662 ~(ELF_PAGE_SIZE
- 1);
1667 /* if interpreter, then add corresponing program header */
1671 ph
->p_type
= PT_INTERP
;
1672 ph
->p_offset
= interp
->sh_offset
;
1673 ph
->p_vaddr
= interp
->sh_addr
;
1674 ph
->p_paddr
= ph
->p_vaddr
;
1675 ph
->p_filesz
= interp
->sh_size
;
1676 ph
->p_memsz
= interp
->sh_size
;
1678 ph
->p_align
= interp
->sh_addralign
;
1681 /* if dynamic section, then add corresponing program header */
1685 ph
= &phdr
[phnum
- 1];
1687 ph
->p_type
= PT_DYNAMIC
;
1688 ph
->p_offset
= dynamic
->sh_offset
;
1689 ph
->p_vaddr
= dynamic
->sh_addr
;
1690 ph
->p_paddr
= ph
->p_vaddr
;
1691 ph
->p_filesz
= dynamic
->sh_size
;
1692 ph
->p_memsz
= dynamic
->sh_size
;
1693 ph
->p_flags
= PF_R
| PF_W
;
1694 ph
->p_align
= dynamic
->sh_addralign
;
1696 /* put GOT dynamic section address */
1697 put32(s1
->got
->data
, dynamic
->sh_addr
);
1699 /* relocate the PLT */
1700 if (file_type
== TCC_OUTPUT_EXE
) {
1704 p_end
= p
+ s1
->plt
->data_offset
;
1706 #if defined(TCC_TARGET_I386)
1707 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1708 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1711 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1714 #elif defined(TCC_TARGET_X86_64)
1715 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1716 put32(p
+ 2, get32(p
+ 2) + x
);
1717 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1720 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1723 #elif defined(TCC_TARGET_ARM)
1725 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1728 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1731 #elif defined(TCC_TARGET_C67)
1734 #error unsupported CPU
1739 /* relocate symbols in .dynsym */
1740 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1741 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1744 if (sym
->st_shndx
== SHN_UNDEF
) {
1745 /* relocate to the PLT if the symbol corresponds
1748 sym
->st_value
+= s1
->plt
->sh_addr
;
1749 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1750 /* do symbol relocation */
1751 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1755 /* put dynamic section entries */
1756 dynamic
->data_offset
= saved_dynamic_data_offset
;
1757 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1758 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1759 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1760 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1761 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1762 #ifdef TCC_TARGET_X86_64
1763 put_dt(dynamic
, DT_RELA
, rel_addr
);
1764 put_dt(dynamic
, DT_RELASZ
, rel_size
);
1765 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1767 put_dt(dynamic
, DT_REL
, rel_addr
);
1768 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1769 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1772 put_dt(dynamic
, DT_DEBUG
, 0);
1773 put_dt(dynamic
, DT_NULL
, 0);
1776 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1777 ehdr
.e_phnum
= phnum
;
1778 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1781 /* all other sections come after */
1782 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1783 s
= s1
->sections
[i
];
1784 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1786 section_order
[sh_order_index
++] = i
;
1788 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1789 ~(s
->sh_addralign
- 1);
1790 s
->sh_offset
= file_offset
;
1791 if (s
->sh_type
!= SHT_NOBITS
)
1792 file_offset
+= s
->sh_size
;
1795 /* if building executable or DLL, then relocate each section
1796 except the GOT which is already relocated */
1797 if (file_type
!= TCC_OUTPUT_OBJ
) {
1798 relocate_syms(s1
, 0);
1800 if (s1
->nb_errors
!= 0) {
1806 /* relocate sections */
1807 /* XXX: ignore sections with allocated relocations ? */
1808 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1809 s
= s1
->sections
[i
];
1810 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1811 relocate_section(s1
, s
);
1814 /* relocate relocation entries if the relocation tables are
1815 allocated in the executable */
1816 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1817 s
= s1
->sections
[i
];
1818 if ((s
->sh_flags
& SHF_ALLOC
) &&
1819 s
->sh_type
== SHT_RELX
) {
1820 relocate_rel(s1
, s
);
1824 /* get entry point address */
1825 if (file_type
== TCC_OUTPUT_EXE
)
1826 ehdr
.e_entry
= (unsigned long)tcc_get_symbol_err(s1
, "_start");
1828 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1831 /* write elf file */
1832 if (file_type
== TCC_OUTPUT_OBJ
)
1836 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1838 error_noabort("could not write '%s'", filename
);
1841 f
= fdopen(fd
, "wb");
1843 printf("<- %s\n", filename
);
1845 #ifdef TCC_TARGET_COFF
1846 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1847 tcc_output_coff(s1
, f
);
1850 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1851 sort_syms(s1
, symtab_section
);
1854 file_offset
= (file_offset
+ 3) & -4;
1857 ehdr
.e_ident
[0] = ELFMAG0
;
1858 ehdr
.e_ident
[1] = ELFMAG1
;
1859 ehdr
.e_ident
[2] = ELFMAG2
;
1860 ehdr
.e_ident
[3] = ELFMAG3
;
1861 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
1862 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1863 ehdr
.e_ident
[6] = EV_CURRENT
;
1865 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1867 #ifdef TCC_TARGET_ARM
1869 ehdr
.e_ident
[EI_OSABI
] = 0;
1870 ehdr
.e_flags
= 4 << 24;
1872 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
1877 case TCC_OUTPUT_EXE
:
1878 ehdr
.e_type
= ET_EXEC
;
1880 case TCC_OUTPUT_DLL
:
1881 ehdr
.e_type
= ET_DYN
;
1883 case TCC_OUTPUT_OBJ
:
1884 ehdr
.e_type
= ET_REL
;
1887 ehdr
.e_machine
= EM_TCC_TARGET
;
1888 ehdr
.e_version
= EV_CURRENT
;
1889 ehdr
.e_shoff
= file_offset
;
1890 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
1891 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
1892 ehdr
.e_shnum
= shnum
;
1893 ehdr
.e_shstrndx
= shnum
- 1;
1895 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
1896 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
1897 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1899 for(i
=1;i
<s1
->nb_sections
;i
++) {
1900 s
= s1
->sections
[section_order
[i
]];
1901 if (s
->sh_type
!= SHT_NOBITS
) {
1902 while (offset
< s
->sh_offset
) {
1907 fwrite(s
->data
, 1, size
, f
);
1912 /* output section headers */
1913 while (offset
< ehdr
.e_shoff
) {
1918 for(i
=0;i
<s1
->nb_sections
;i
++) {
1920 memset(sh
, 0, sizeof(ElfW(Shdr
)));
1921 s
= s1
->sections
[i
];
1923 sh
->sh_name
= s
->sh_name
;
1924 sh
->sh_type
= s
->sh_type
;
1925 sh
->sh_flags
= s
->sh_flags
;
1926 sh
->sh_entsize
= s
->sh_entsize
;
1927 sh
->sh_info
= s
->sh_info
;
1929 sh
->sh_link
= s
->link
->sh_num
;
1930 sh
->sh_addralign
= s
->sh_addralign
;
1931 sh
->sh_addr
= s
->sh_addr
;
1932 sh
->sh_offset
= s
->sh_offset
;
1933 sh
->sh_size
= s
->sh_size
;
1935 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
1938 tcc_output_binary(s1
, f
, section_order
);
1944 tcc_free(s1
->symtab_to_dynsym
);
1945 tcc_free(section_order
);
1947 tcc_free(s1
->got_offsets
);
1951 int tcc_output_file(TCCState
*s
, const char *filename
)
1954 #ifdef TCC_TARGET_PE
1955 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
1956 ret
= pe_output_file(s
, filename
);
1960 ret
= elf_output_file(s
, filename
);
1965 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
1969 data
= tcc_malloc(size
);
1970 lseek(fd
, file_offset
, SEEK_SET
);
1971 read(fd
, data
, size
);
1975 typedef struct SectionMergeInfo
{
1976 Section
*s
; /* corresponding existing section */
1977 unsigned long offset
; /* offset of the new section in the existing section */
1978 uint8_t new_section
; /* true if section 's' was added */
1979 uint8_t link_once
; /* true if link once section */
1982 /* load an object file and merge it with current files */
1983 /* XXX: handle correctly stab (debug) info */
1984 static int tcc_load_object_file(TCCState
*s1
,
1985 int fd
, unsigned long file_offset
)
1988 ElfW(Shdr
) *shdr
, *sh
;
1989 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
1990 unsigned char *strsec
, *strtab
;
1991 int *old_to_new_syms
;
1992 char *sh_name
, *name
;
1993 SectionMergeInfo
*sm_table
, *sm
;
1994 ElfW(Sym
) *sym
, *symtab
;
1995 ElfW_Rel
*rel
, *rel_end
;
2001 stab_index
= stabstr_index
= 0;
2003 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2005 if (ehdr
.e_ident
[0] != ELFMAG0
||
2006 ehdr
.e_ident
[1] != ELFMAG1
||
2007 ehdr
.e_ident
[2] != ELFMAG2
||
2008 ehdr
.e_ident
[3] != ELFMAG3
)
2010 /* test if object file */
2011 if (ehdr
.e_type
!= ET_REL
)
2013 /* test CPU specific stuff */
2014 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2015 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2017 error_noabort("invalid object file");
2021 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2022 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2023 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2025 /* load section names */
2026 sh
= &shdr
[ehdr
.e_shstrndx
];
2027 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2029 /* load symtab and strtab */
2030 old_to_new_syms
= NULL
;
2034 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2036 if (sh
->sh_type
== SHT_SYMTAB
) {
2038 error_noabort("object must contain only one symtab");
2043 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2044 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2045 sm_table
[i
].s
= symtab_section
;
2047 /* now load strtab */
2048 sh
= &shdr
[sh
->sh_link
];
2049 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2053 /* now examine each section and try to merge its content with the
2055 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2056 /* no need to examine section name strtab */
2057 if (i
== ehdr
.e_shstrndx
)
2060 sh_name
= strsec
+ sh
->sh_name
;
2061 /* ignore sections types we do not handle */
2062 if (sh
->sh_type
!= SHT_PROGBITS
&&
2063 sh
->sh_type
!= SHT_RELX
&&
2065 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2067 sh
->sh_type
!= SHT_NOBITS
&&
2068 strcmp(sh_name
, ".stabstr")
2071 if (sh
->sh_addralign
< 1)
2072 sh
->sh_addralign
= 1;
2073 /* find corresponding section, if any */
2074 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2075 s
= s1
->sections
[j
];
2076 if (!strcmp(s
->name
, sh_name
)) {
2077 if (!strncmp(sh_name
, ".gnu.linkonce",
2078 sizeof(".gnu.linkonce") - 1)) {
2079 /* if a 'linkonce' section is already present, we
2080 do not add it again. It is a little tricky as
2081 symbols can still be defined in
2083 sm_table
[i
].link_once
= 1;
2090 /* not found: create new section */
2091 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2092 /* take as much info as possible from the section. sh_link and
2093 sh_info will be updated later */
2094 s
->sh_addralign
= sh
->sh_addralign
;
2095 s
->sh_entsize
= sh
->sh_entsize
;
2096 sm_table
[i
].new_section
= 1;
2098 if (sh
->sh_type
!= s
->sh_type
) {
2099 error_noabort("invalid section type");
2103 /* align start of section */
2104 offset
= s
->data_offset
;
2106 if (0 == strcmp(sh_name
, ".stab")) {
2110 if (0 == strcmp(sh_name
, ".stabstr")) {
2115 size
= sh
->sh_addralign
- 1;
2116 offset
= (offset
+ size
) & ~size
;
2117 if (sh
->sh_addralign
> s
->sh_addralign
)
2118 s
->sh_addralign
= sh
->sh_addralign
;
2119 s
->data_offset
= offset
;
2121 sm_table
[i
].offset
= offset
;
2123 /* concatenate sections */
2125 if (sh
->sh_type
!= SHT_NOBITS
) {
2127 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2128 ptr
= section_ptr_add(s
, size
);
2129 read(fd
, ptr
, size
);
2131 s
->data_offset
+= size
;
2136 /* //gr relocate stab strings */
2137 if (stab_index
&& stabstr_index
) {
2140 s
= sm_table
[stab_index
].s
;
2141 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2142 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2143 o
= sm_table
[stabstr_index
].offset
;
2145 a
->n_strx
+= o
, a
++;
2148 /* second short pass to update sh_link and sh_info fields of new
2150 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2152 if (!s
|| !sm_table
[i
].new_section
)
2155 if (sh
->sh_link
> 0)
2156 s
->link
= sm_table
[sh
->sh_link
].s
;
2157 if (sh
->sh_type
== SHT_RELX
) {
2158 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2159 /* update backward link */
2160 s1
->sections
[s
->sh_info
]->reloc
= s
;
2165 /* resolve symbols */
2166 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2169 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2170 if (sym
->st_shndx
!= SHN_UNDEF
&&
2171 sym
->st_shndx
< SHN_LORESERVE
) {
2172 sm
= &sm_table
[sym
->st_shndx
];
2173 if (sm
->link_once
) {
2174 /* if a symbol is in a link once section, we use the
2175 already defined symbol. It is very important to get
2176 correct relocations */
2177 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2178 name
= strtab
+ sym
->st_name
;
2179 sym_index
= find_elf_sym(symtab_section
, name
);
2181 old_to_new_syms
[i
] = sym_index
;
2185 /* if no corresponding section added, no need to add symbol */
2188 /* convert section number */
2189 sym
->st_shndx
= sm
->s
->sh_num
;
2191 sym
->st_value
+= sm
->offset
;
2194 name
= strtab
+ sym
->st_name
;
2195 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2196 sym
->st_info
, sym
->st_other
,
2197 sym
->st_shndx
, name
);
2198 old_to_new_syms
[i
] = sym_index
;
2201 /* third pass to patch relocation entries */
2202 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2207 offset
= sm_table
[i
].offset
;
2208 switch(s
->sh_type
) {
2210 /* take relocation offset information */
2211 offseti
= sm_table
[sh
->sh_info
].offset
;
2212 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2213 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2218 /* convert symbol index */
2219 type
= ELFW(R_TYPE
)(rel
->r_info
);
2220 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2221 /* NOTE: only one symtab assumed */
2222 if (sym_index
>= nb_syms
)
2224 sym_index
= old_to_new_syms
[sym_index
];
2225 /* ignore link_once in rel section. */
2226 if (!sym_index
&& !sm
->link_once
) {
2228 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2229 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2232 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2233 /* offset the relocation offset */
2234 rel
->r_offset
+= offseti
;
2246 tcc_free(old_to_new_syms
);
2253 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2255 typedef struct ArchiveHeader
{
2256 char ar_name
[16]; /* name of this member */
2257 char ar_date
[12]; /* file mtime */
2258 char ar_uid
[6]; /* owner uid; printed as decimal */
2259 char ar_gid
[6]; /* owner gid; printed as decimal */
2260 char ar_mode
[8]; /* file mode, printed as octal */
2261 char ar_size
[10]; /* file size, printed as decimal */
2262 char ar_fmag
[2]; /* should contain ARFMAG */
2265 static int get_be32(const uint8_t *b
)
2267 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2270 /* load only the objects which resolve undefined symbols */
2271 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2273 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2275 const char *ar_names
, *p
;
2276 const uint8_t *ar_index
;
2279 data
= tcc_malloc(size
);
2280 if (read(fd
, data
, size
) != size
)
2282 nsyms
= get_be32(data
);
2283 ar_index
= data
+ 4;
2284 ar_names
= ar_index
+ nsyms
* 4;
2288 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2289 sym_index
= find_elf_sym(symtab_section
, p
);
2291 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2292 if(sym
->st_shndx
== SHN_UNDEF
) {
2293 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2295 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2298 lseek(fd
, off
, SEEK_SET
);
2299 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2314 /* load a '.a' file */
2315 static int tcc_load_archive(TCCState
*s1
, int fd
)
2322 unsigned long file_offset
;
2324 /* skip magic which was already checked */
2325 read(fd
, magic
, sizeof(magic
));
2328 len
= read(fd
, &hdr
, sizeof(hdr
));
2331 if (len
!= sizeof(hdr
)) {
2332 error_noabort("invalid archive");
2335 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2336 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2337 size
= strtol(ar_size
, NULL
, 0);
2338 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2339 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2340 if (ar_name
[i
] != ' ')
2343 ar_name
[i
+ 1] = '\0';
2344 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2345 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2347 size
= (size
+ 1) & ~1;
2348 if (!strcmp(ar_name
, "/")) {
2349 /* coff symbol table : we handle it */
2350 if(s1
->alacarte_link
)
2351 return tcc_load_alacarte(s1
, fd
, size
);
2352 } else if (!strcmp(ar_name
, "//") ||
2353 !strcmp(ar_name
, "__.SYMDEF") ||
2354 !strcmp(ar_name
, "__.SYMDEF/") ||
2355 !strcmp(ar_name
, "ARFILENAMES/")) {
2356 /* skip symbol table or archive names */
2358 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2361 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2366 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2367 is referenced by the user (so it should be added as DT_NEEDED in
2368 the generated ELF file) */
2369 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2372 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2373 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2374 ElfW(Sym
) *sym
, *dynsym
;
2375 ElfW(Dyn
) *dt
, *dynamic
;
2376 unsigned char *dynstr
;
2377 const char *name
, *soname
;
2378 DLLReference
*dllref
;
2380 read(fd
, &ehdr
, sizeof(ehdr
));
2382 /* test CPU specific stuff */
2383 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2384 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2385 error_noabort("bad architecture");
2390 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2392 /* load dynamic section and dynamic symbols */
2396 dynsym
= NULL
; /* avoid warning */
2397 dynstr
= NULL
; /* avoid warning */
2398 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2399 switch(sh
->sh_type
) {
2401 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2402 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2405 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2406 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2407 sh1
= &shdr
[sh
->sh_link
];
2408 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2415 /* compute the real library name */
2416 soname
= tcc_basename(filename
);
2418 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2419 if (dt
->d_tag
== DT_SONAME
) {
2420 soname
= dynstr
+ dt
->d_un
.d_val
;
2424 /* if the dll is already loaded, do not load it */
2425 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2426 dllref
= s1
->loaded_dlls
[i
];
2427 if (!strcmp(soname
, dllref
->name
)) {
2428 /* but update level if needed */
2429 if (level
< dllref
->level
)
2430 dllref
->level
= level
;
2436 // printf("loading dll '%s'\n", soname);
2438 /* add the dll and its level */
2439 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2440 dllref
->level
= level
;
2441 strcpy(dllref
->name
, soname
);
2442 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2444 /* add dynamic symbols in dynsym_section */
2445 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2446 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2447 if (sym_bind
== STB_LOCAL
)
2449 name
= dynstr
+ sym
->st_name
;
2450 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2451 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2454 /* load all referenced DLLs */
2455 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2458 name
= dynstr
+ dt
->d_un
.d_val
;
2459 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2460 dllref
= s1
->loaded_dlls
[j
];
2461 if (!strcmp(name
, dllref
->name
))
2462 goto already_loaded
;
2464 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2465 error_noabort("referenced dll '%s' not found", name
);
2482 #define LD_TOK_NAME 256
2483 #define LD_TOK_EOF (-1)
2485 /* return next ld script token */
2486 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2504 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2505 ch
= file
->buf_ptr
[0];
2513 /* case 'a' ... 'z': */
2540 /* case 'A' ... 'z': */
2575 if (!((ch
>= 'a' && ch
<= 'z') ||
2576 (ch
>= 'A' && ch
<= 'Z') ||
2577 (ch
>= '0' && ch
<= '9') ||
2578 strchr("/.-_+=$:\\,~", ch
)))
2580 if ((q
- name
) < name_size
- 1) {
2597 printf("tok=%c %d\n", c
, c
);
2598 if (c
== LD_TOK_NAME
)
2599 printf(" name=%s\n", name
);
2604 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2606 char filename
[1024];
2609 t
= ld_next(s1
, filename
, sizeof(filename
));
2612 t
= ld_next(s1
, filename
, sizeof(filename
));
2614 if (t
== LD_TOK_EOF
) {
2615 error_noabort("unexpected end of file");
2617 } else if (t
== ')') {
2619 } else if (t
!= LD_TOK_NAME
) {
2620 error_noabort("filename expected");
2623 if (!strcmp(filename
, "AS_NEEDED")) {
2624 ret
= ld_add_file_list(s1
, 1);
2628 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2630 tcc_add_file(s1
, filename
);
2632 t
= ld_next(s1
, filename
, sizeof(filename
));
2634 t
= ld_next(s1
, filename
, sizeof(filename
));
2640 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2642 static int tcc_load_ldscript(TCCState
*s1
)
2645 char filename
[1024];
2648 ch
= file
->buf_ptr
[0];
2651 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2652 if (t
== LD_TOK_EOF
)
2654 else if (t
!= LD_TOK_NAME
)
2656 if (!strcmp(cmd
, "INPUT") ||
2657 !strcmp(cmd
, "GROUP")) {
2658 ret
= ld_add_file_list(s1
, 0);
2661 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2662 !strcmp(cmd
, "TARGET")) {
2663 /* ignore some commands */
2664 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2668 t
= ld_next(s1
, filename
, sizeof(filename
));
2669 if (t
== LD_TOK_EOF
) {
2670 error_noabort("unexpected end of file");
2672 } else if (t
== ')') {