2 * ELF file handling for TCC
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #ifdef TCC_TARGET_X86_64
22 #define ElfW_Rel ElfW(Rela)
23 #define SHT_RELX SHT_RELA
24 #define REL_SECTION_FMT ".rela%s"
25 /* x86-64 requires PLT for DLLs */
26 #define TCC_OUTPUT_DLL_WITH_PLT
28 #define ElfW_Rel ElfW(Rel)
29 #define SHT_RELX SHT_REL
30 #define REL_SECTION_FMT ".rel%s"
33 /* XXX: DLL with PLT would only work with x86-64 for now */
34 //#define TCC_OUTPUT_DLL_WITH_PLT
36 static int put_elf_str(Section
*s
, const char *sym
)
41 len
= strlen(sym
) + 1;
42 offset
= s
->data_offset
;
43 ptr
= section_ptr_add(s
, len
);
44 memcpy(ptr
, sym
, len
);
48 /* elf symbol hashing function */
49 static unsigned long elf_hash(const unsigned char *name
)
51 unsigned long h
= 0, g
;
54 h
= (h
<< 4) + *name
++;
63 /* rebuild hash table of section s */
64 /* NOTE: we do factorize the hash table code to go faster */
65 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
68 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
71 strtab
= s
->link
->data
;
72 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
74 s
->hash
->data_offset
= 0;
75 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
80 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
81 ptr
+= nb_buckets
+ 1;
83 sym
= (ElfW(Sym
) *)s
->data
+ 1;
84 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
85 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
86 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
97 /* return the symbol number */
98 static int put_elf_sym(Section
*s
,
99 unsigned long value
, unsigned long size
,
100 int info
, int other
, int shndx
, const char *name
)
102 int name_offset
, sym_index
;
107 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
109 name_offset
= put_elf_str(s
->link
, name
);
112 /* XXX: endianness */
113 sym
->st_name
= name_offset
;
114 sym
->st_value
= value
;
117 sym
->st_other
= other
;
118 sym
->st_shndx
= shndx
;
119 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
123 ptr
= section_ptr_add(hs
, sizeof(int));
124 base
= (int *)hs
->data
;
125 /* only add global or weak symbols */
126 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
127 /* add another hashing entry */
129 h
= elf_hash(name
) % nbuckets
;
131 base
[2 + h
] = sym_index
;
133 /* we resize the hash table */
134 hs
->nb_hashed_syms
++;
135 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
136 rebuild_hash(s
, 2 * nbuckets
);
146 /* find global ELF symbol 'name' and return its index. Return 0 if not
148 static int find_elf_sym(Section
*s
, const char *name
)
152 int nbuckets
, sym_index
, h
;
158 nbuckets
= ((int *)hs
->data
)[0];
159 h
= elf_hash(name
) % nbuckets
;
160 sym_index
= ((int *)hs
->data
)[2 + h
];
161 while (sym_index
!= 0) {
162 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
163 name1
= s
->link
->data
+ sym
->st_name
;
164 if (!strcmp(name
, name1
))
166 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
171 /* return elf symbol value, signal error if 'err' is nonzero */
172 static void *get_elf_sym_addr(TCCState
*s
, const char *name
, int err
)
177 sym_index
= find_elf_sym(symtab_section
, name
);
178 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
179 if (!sym_index
|| sym
->st_shndx
== SHN_UNDEF
) {
181 error("%s not defined", name
);
184 return (void*)(uplong
)sym
->st_value
;
187 /* return elf symbol value */
188 void *tcc_get_symbol(TCCState
*s
, const char *name
)
190 return get_elf_sym_addr(s
, name
, 0);
193 /* return elf symbol value or error */
194 void *tcc_get_symbol_err(TCCState
*s
, const char *name
)
196 return get_elf_sym_addr(s
, name
, 1);
199 /* add an elf symbol : check if it is already defined and patch
200 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
201 static int add_elf_sym(Section
*s
, uplong value
, unsigned long size
,
202 int info
, int other
, int sh_num
, const char *name
)
205 int sym_bind
, sym_index
, sym_type
, esym_bind
;
206 unsigned char sym_vis
, esym_vis
, new_vis
;
208 sym_bind
= ELFW(ST_BIND
)(info
);
209 sym_type
= ELFW(ST_TYPE
)(info
);
210 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
212 if (sym_bind
!= STB_LOCAL
) {
213 /* we search global or weak symbols */
214 sym_index
= find_elf_sym(s
, name
);
217 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
218 if (esym
->st_shndx
!= SHN_UNDEF
) {
219 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
220 /* propagate the most constraining visibility */
221 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
222 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
223 if (esym_vis
== STV_DEFAULT
) {
225 } else if (sym_vis
== STV_DEFAULT
) {
228 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
230 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
232 other
= esym
->st_other
; /* in case we have to patch esym */
233 if (sh_num
== SHN_UNDEF
) {
234 /* ignore adding of undefined symbol if the
235 corresponding symbol is already defined */
236 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
237 /* global overrides weak, so patch */
239 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
240 /* weak is ignored if already global */
241 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
242 /* ignore hidden symbols after */
243 } else if (esym
->st_shndx
== SHN_COMMON
244 && (sh_num
< SHN_LORESERVE
|| sh_num
== SHN_COMMON
)) {
245 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
246 No idea if this is the correct solution ... */
248 } else if (s
== tcc_state
->dynsymtab_section
) {
249 /* we accept that two DLL define the same symbol */
252 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
253 sym_bind
, sh_num
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
255 error_noabort("'%s' defined twice", name
);
259 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
260 esym
->st_shndx
= sh_num
;
261 esym
->st_value
= value
;
262 esym
->st_size
= size
;
263 esym
->st_other
= other
;
267 sym_index
= put_elf_sym(s
, value
, size
,
268 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
275 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
276 int type
, int symbol
)
284 /* if no relocation section, create it */
285 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
286 /* if the symtab is allocated, then we consider the relocation
288 sr
= new_section(tcc_state
, buf
, SHT_RELX
, symtab
->sh_flags
);
289 sr
->sh_entsize
= sizeof(ElfW_Rel
);
291 sr
->sh_info
= s
->sh_num
;
294 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
295 rel
->r_offset
= offset
;
296 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
297 #ifdef TCC_TARGET_X86_64
302 /* put stab debug information */
305 unsigned int n_strx
; /* index into string table of name */
306 unsigned char n_type
; /* type of symbol */
307 unsigned char n_other
; /* misc info (usually empty) */
308 unsigned short n_desc
; /* description field */
309 unsigned int n_value
; /* value of symbol */
312 static void put_stabs(const char *str
, int type
, int other
, int desc
,
317 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
319 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
324 sym
->n_other
= other
;
326 sym
->n_value
= value
;
329 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
330 unsigned long value
, Section
*sec
, int sym_index
)
332 put_stabs(str
, type
, other
, desc
, value
);
333 put_elf_reloc(symtab_section
, stab_section
,
334 stab_section
->data_offset
- sizeof(unsigned int),
335 R_DATA_32
, sym_index
);
338 static void put_stabn(int type
, int other
, int desc
, int value
)
340 put_stabs(NULL
, type
, other
, desc
, value
);
343 static void put_stabd(int type
, int other
, int desc
)
345 put_stabs(NULL
, type
, other
, desc
, 0);
348 /* In an ELF file symbol table, the local symbols must appear below
349 the global and weak ones. Since TCC cannot sort it while generating
350 the code, we must do it after. All the relocation tables are also
351 modified to take into account the symbol table sorting */
352 static void sort_syms(TCCState
*s1
, Section
*s
)
354 int *old_to_new_syms
;
358 ElfW_Rel
*rel
, *rel_end
;
362 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
363 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
364 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
366 /* first pass for local symbols */
367 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
;
376 /* save the number of local symbols in section header */
377 s
->sh_info
= q
- new_syms
;
379 /* then second pass for non local symbols */
380 p
= (ElfW(Sym
) *)s
->data
;
381 for(i
= 0; i
< nb_syms
; i
++) {
382 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
383 old_to_new_syms
[i
] = q
- new_syms
;
389 /* we copy the new symbols to the old */
390 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
393 /* now we modify all the relocations */
394 for(i
= 1; i
< s1
->nb_sections
; i
++) {
395 sr
= s1
->sections
[i
];
396 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
397 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
398 for(rel
= (ElfW_Rel
*)sr
->data
;
401 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
402 type
= ELFW(R_TYPE
)(rel
->r_info
);
403 sym_index
= old_to_new_syms
[sym_index
];
404 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
409 tcc_free(old_to_new_syms
);
412 /* relocate common symbols in the .bss section */
413 static void relocate_common_syms(void)
415 ElfW(Sym
) *sym
, *sym_end
;
416 unsigned long offset
, align
;
418 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
419 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
422 if (sym
->st_shndx
== SHN_COMMON
) {
424 align
= sym
->st_value
;
425 offset
= bss_section
->data_offset
;
426 offset
= (offset
+ align
- 1) & -align
;
427 sym
->st_value
= offset
;
428 sym
->st_shndx
= bss_section
->sh_num
;
429 offset
+= sym
->st_size
;
430 bss_section
->data_offset
= offset
;
435 /* relocate symbol table, resolve undefined symbols if do_resolve is
436 true and output error if undefined symbol. */
437 static void relocate_syms(TCCState
*s1
, int do_resolve
)
439 ElfW(Sym
) *sym
, *esym
, *sym_end
;
440 int sym_bind
, sh_num
, sym_index
;
443 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
444 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
447 sh_num
= sym
->st_shndx
;
448 if (sh_num
== SHN_UNDEF
) {
449 name
= strtab_section
->data
+ sym
->st_name
;
453 name
= symtab_section
->link
->data
+ sym
->st_name
;
454 addr
= resolve_sym(s1
, name
);
456 sym
->st_value
= (uplong
)addr
;
460 } else if (s1
->dynsym
) {
461 /* if dynamic symbol exist, then use it */
462 sym_index
= find_elf_sym(s1
->dynsym
, name
);
464 esym
= &((ElfW(Sym
) *)s1
->dynsym
->data
)[sym_index
];
465 sym
->st_value
= esym
->st_value
;
469 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
471 if (!strcmp(name
, "_fp_hw"))
473 /* only weak symbols are accepted to be undefined. Their
475 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
476 if (sym_bind
== STB_WEAK
) {
479 error_noabort("undefined symbol '%s'", name
);
481 } else if (sh_num
< SHN_LORESERVE
) {
482 /* add section base */
483 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
489 #ifndef TCC_TARGET_PE
490 #ifdef TCC_TARGET_X86_64
491 #define JMP_TABLE_ENTRY_SIZE 14
492 static unsigned long add_jmp_table(TCCState
*s1
, unsigned long val
)
494 char *p
= s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
;
495 s1
->runtime_plt_and_got_offset
+= JMP_TABLE_ENTRY_SIZE
;
500 *(unsigned long *)(p
+ 6) = val
;
501 return (unsigned long)p
;
504 static unsigned long add_got_table(TCCState
*s1
, unsigned long val
)
506 unsigned long *p
=(unsigned long *)(s1
->runtime_plt_and_got
+
507 s1
->runtime_plt_and_got_offset
);
508 s1
->runtime_plt_and_got_offset
+= sizeof(void *);
510 return (unsigned long)p
;
515 /* relocate a given section (CPU dependent) */
516 static void relocate_section(TCCState
*s1
, Section
*s
)
519 ElfW_Rel
*rel
, *rel_end
, *qrel
;
523 unsigned long val
, addr
;
524 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
529 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
530 qrel
= (ElfW_Rel
*)sr
->data
;
534 ptr
= s
->data
+ rel
->r_offset
;
536 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
537 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
539 #ifdef TCC_TARGET_X86_64
540 /* XXX: not tested */
541 val
+= rel
->r_addend
;
543 type
= ELFW(R_TYPE
)(rel
->r_info
);
544 addr
= s
->sh_addr
+ rel
->r_offset
;
548 #if defined(TCC_TARGET_I386)
550 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
551 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
552 qrel
->r_offset
= rel
->r_offset
;
554 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_32
);
558 qrel
->r_info
= ELFW(R_INFO
)(0, R_386_RELATIVE
);
565 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
567 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
569 qrel
->r_offset
= rel
->r_offset
;
570 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_PC32
);
575 *(int *)ptr
+= val
- addr
;
578 *(int *)ptr
+= val
- addr
;
585 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
588 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
591 /* we load the got offset */
592 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
594 #elif defined(TCC_TARGET_ARM)
601 x
= (*(int *)ptr
)&0xffffff;
602 (*(int *)ptr
) &= 0xff000000;
607 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
608 error("can't relocate value at %x",addr
);
617 x
= (*(int *)ptr
) & 0x7fffffff;
618 (*(int *)ptr
) &= 0x80000000;
621 if((x
^(x
>>1))&0x40000000)
622 error("can't relocate value at %x",addr
);
623 (*(int *)ptr
) |= x
& 0x7fffffff;
628 case R_ARM_BASE_PREL
:
629 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
632 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
635 /* we load the got offset */
636 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
641 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
642 type
,addr
,(unsigned int)(long)ptr
,val
);
644 #elif defined(TCC_TARGET_C67)
652 /* put the low 16 bits of the absolute address */
653 // add to what is already there
655 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
656 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
658 //patch both at once - assumes always in pairs Low - High
660 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
661 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
667 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
668 type
,addr
,(unsigned int)(long)ptr
, val
);
670 #elif defined(TCC_TARGET_X86_64)
672 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
673 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
674 qrel
->r_addend
= *(long long *)ptr
+ val
;
677 *(long long *)ptr
+= val
;
681 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
682 /* XXX: this logic may depend on TCC's codegen
683 now TCC uses R_X86_64_32 even for a 64bit pointer */
684 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
685 qrel
->r_addend
= *(int *)ptr
+ val
;
690 case R_X86_64_PC32
: {
692 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
694 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
696 qrel
->r_offset
= rel
->r_offset
;
697 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_X86_64_PC32
);
698 qrel
->r_addend
= *(int *)ptr
;
703 diff
= (long long)val
- addr
;
704 if (diff
<= -2147483647 || diff
> 2147483647) {
705 #ifndef TCC_TARGET_PE
706 /* XXX: naive support for over 32bit jump */
707 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
708 val
= add_jmp_table(s1
, val
);
712 if (diff
<= -2147483647 || diff
> 2147483647) {
713 error("internal error: relocation failed");
720 *(int *)ptr
+= val
- addr
;
722 case R_X86_64_GLOB_DAT
:
723 case R_X86_64_JUMP_SLOT
:
726 case R_X86_64_GOTPCREL
:
727 #ifndef TCC_TARGET_PE
728 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
729 val
= add_got_table(s1
, val
- rel
->r_addend
) + rel
->r_addend
;
730 *(int *)ptr
+= val
- addr
;
734 *(int *)ptr
+= (s1
->got
->sh_addr
- addr
+
735 s1
->got_offsets
[sym_index
] - 4);
737 case R_X86_64_GOTTPOFF
:
738 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
741 /* we load the got offset */
742 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
745 #error unsupported processor
749 /* if the relocation is allocated, we change its symbol table */
750 if (sr
->sh_flags
& SHF_ALLOC
)
751 sr
->link
= s1
->dynsym
;
754 /* relocate relocation table in 'sr' */
755 static void relocate_rel(TCCState
*s1
, Section
*sr
)
758 ElfW_Rel
*rel
, *rel_end
;
760 s
= s1
->sections
[sr
->sh_info
];
761 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
762 for(rel
= (ElfW_Rel
*)sr
->data
;
765 rel
->r_offset
+= s
->sh_addr
;
769 /* count the number of dynamic relocations so that we can reserve
771 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
773 ElfW_Rel
*rel
, *rel_end
;
774 int sym_index
, esym_index
, type
, count
;
777 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
778 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
779 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
780 type
= ELFW(R_TYPE
)(rel
->r_info
);
782 #if defined(TCC_TARGET_I386)
784 #elif defined(TCC_TARGET_X86_64)
791 #if defined(TCC_TARGET_I386)
793 #elif defined(TCC_TARGET_X86_64)
796 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
805 /* allocate the section */
806 sr
->sh_flags
|= SHF_ALLOC
;
807 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
812 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
817 if (index
>= s1
->nb_got_offsets
) {
818 /* find immediately bigger power of 2 and reallocate array */
822 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
824 error("memory full");
825 s1
->got_offsets
= tab
;
826 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
827 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
828 s1
->nb_got_offsets
= n
;
830 s1
->got_offsets
[index
] = val
;
833 /* XXX: suppress that */
834 static void put32(unsigned char *p
, uint32_t val
)
842 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
843 defined(TCC_TARGET_X86_64)
844 static uint32_t get32(unsigned char *p
)
846 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
850 static void build_got(TCCState
*s1
)
854 /* if no got, then create it */
855 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
856 s1
->got
->sh_entsize
= 4;
857 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
858 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
859 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
861 /* keep space for _DYNAMIC pointer, if present */
863 /* two dummy got entries */
867 /* keep space for _DYNAMIC pointer, if present */
870 /* two dummy got entries */
878 /* put a got entry corresponding to a symbol in symtab_section. 'size'
879 and 'info' can be modifed if more precise info comes from the DLL */
880 static void put_got_entry(TCCState
*s1
,
881 int reloc_type
, unsigned long size
, int info
,
887 unsigned long offset
;
893 /* if a got entry already exists for that symbol, no need to add one */
894 if (sym_index
< s1
->nb_got_offsets
&&
895 s1
->got_offsets
[sym_index
] != 0)
898 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
901 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
902 name
= symtab_section
->link
->data
+ sym
->st_name
;
903 offset
= sym
->st_value
;
904 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
906 #ifdef TCC_TARGET_X86_64
916 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
919 /* if we build a DLL, we add a %ebx offset */
920 if (s1
->output_type
== TCC_OUTPUT_DLL
)
926 /* add a PLT entry */
928 if (plt
->data_offset
== 0) {
929 /* first plt entry */
930 p
= section_ptr_add(plt
, 16);
931 p
[0] = 0xff; /* pushl got + PTR_SIZE */
933 put32(p
+ 2, PTR_SIZE
);
934 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
936 put32(p
+ 8, PTR_SIZE
* 2);
939 p
= section_ptr_add(plt
, 16);
940 p
[0] = 0xff; /* jmp *(got + x) */
942 put32(p
+ 2, s1
->got
->data_offset
);
943 p
[6] = 0x68; /* push $xxx */
944 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
945 p
[11] = 0xe9; /* jmp plt_start */
946 put32(p
+ 12, -(plt
->data_offset
));
948 /* the symbol is modified so that it will be relocated to
950 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
951 if (s1
->output_type
== TCC_OUTPUT_EXE
)
953 offset
= plt
->data_offset
- 16;
955 #elif defined(TCC_TARGET_ARM)
956 if (reloc_type
== R_ARM_JUMP_SLOT
) {
960 /* if we build a DLL, we add a %ebx offset */
961 if (s1
->output_type
== TCC_OUTPUT_DLL
)
962 error("DLLs unimplemented!");
964 /* add a PLT entry */
966 if (plt
->data_offset
== 0) {
967 /* first plt entry */
968 p
= section_ptr_add(plt
, 16);
969 put32(p
, 0xe52de004);
970 put32(p
+ 4, 0xe59fe010);
971 put32(p
+ 8, 0xe08fe00e);
972 put32(p
+ 12, 0xe5bef008);
975 p
= section_ptr_add(plt
, 16);
976 put32(p
, 0xe59fc004);
977 put32(p
+4, 0xe08fc00c);
978 put32(p
+8, 0xe59cf000);
979 put32(p
+12, s1
->got
->data_offset
);
981 /* the symbol is modified so that it will be relocated to
983 if (s1
->output_type
== TCC_OUTPUT_EXE
)
984 offset
= plt
->data_offset
- 16;
986 #elif defined(TCC_TARGET_C67)
987 error("C67 got not implemented");
989 #error unsupported CPU
991 index
= put_elf_sym(s1
->dynsym
, offset
,
992 size
, info
, 0, sym
->st_shndx
, name
);
993 /* put a got entry */
994 put_elf_reloc(s1
->dynsym
, s1
->got
,
995 s1
->got
->data_offset
,
998 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
1002 /* build GOT and PLT entries */
1003 static void build_got_entries(TCCState
*s1
)
1005 Section
*s
, *symtab
;
1006 ElfW_Rel
*rel
, *rel_end
;
1008 int i
, type
, reloc_type
, sym_index
;
1010 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1011 s
= s1
->sections
[i
];
1012 if (s
->sh_type
!= SHT_RELX
)
1014 /* no need to handle got relocations */
1015 if (s
->link
!= symtab_section
)
1018 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
1019 for(rel
= (ElfW_Rel
*)s
->data
;
1022 type
= ELFW(R_TYPE
)(rel
->r_info
);
1024 #if defined(TCC_TARGET_I386)
1031 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1032 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1033 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1034 /* look at the symbol got offset. If none, then add one */
1035 if (type
== R_386_GOT32
)
1036 reloc_type
= R_386_GLOB_DAT
;
1038 reloc_type
= R_386_JMP_SLOT
;
1039 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1043 #elif defined(TCC_TARGET_ARM)
1044 case R_ARM_GOT_BREL
:
1045 case R_ARM_GOTOFF32
:
1046 case R_ARM_BASE_PREL
:
1050 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1051 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1052 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1053 /* look at the symbol got offset. If none, then add one */
1054 if (type
== R_ARM_GOT_BREL
)
1055 reloc_type
= R_ARM_GLOB_DAT
;
1057 reloc_type
= R_ARM_JUMP_SLOT
;
1058 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1062 #elif defined(TCC_TARGET_C67)
1069 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1070 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1071 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1072 /* look at the symbol got offset. If none, then add one */
1073 if (type
== R_C60_GOT32
)
1074 reloc_type
= R_C60_GLOB_DAT
;
1076 reloc_type
= R_C60_JMP_SLOT
;
1077 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1081 #elif defined(TCC_TARGET_X86_64)
1082 case R_X86_64_GOT32
:
1083 case R_X86_64_GOTTPOFF
:
1084 case R_X86_64_GOTPCREL
:
1085 case R_X86_64_PLT32
:
1088 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
||
1089 type
== R_X86_64_PLT32
) {
1090 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1091 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1092 /* look at the symbol got offset. If none, then add one */
1093 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
)
1094 reloc_type
= R_X86_64_GLOB_DAT
;
1096 reloc_type
= R_X86_64_JUMP_SLOT
;
1097 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1102 #error unsupported CPU
1111 static Section
*new_symtab(TCCState
*s1
,
1112 const char *symtab_name
, int sh_type
, int sh_flags
,
1113 const char *strtab_name
,
1114 const char *hash_name
, int hash_sh_flags
)
1116 Section
*symtab
, *strtab
, *hash
;
1117 int *ptr
, nb_buckets
;
1119 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1120 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1121 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1122 put_elf_str(strtab
, "");
1123 symtab
->link
= strtab
;
1124 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1128 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1129 hash
->sh_entsize
= sizeof(int);
1130 symtab
->hash
= hash
;
1131 hash
->link
= symtab
;
1133 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1134 ptr
[0] = nb_buckets
;
1136 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1140 /* put dynamic tag */
1141 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1144 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1146 dyn
->d_un
.d_val
= val
;
1149 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1153 char sym_start
[1024];
1156 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1157 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1159 s
= find_section(s1
, section_name
);
1164 end_offset
= s
->data_offset
;
1167 add_elf_sym(symtab_section
,
1169 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1170 s
->sh_num
, sym_start
);
1171 add_elf_sym(symtab_section
,
1173 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1174 s
->sh_num
, sym_end
);
1177 /* add tcc runtime libraries */
1178 static void tcc_add_runtime(TCCState
*s1
)
1180 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1184 #ifdef CONFIG_TCC_BCHECK
1185 if (s1
->do_bounds_check
) {
1187 Section
*init_section
;
1188 unsigned char *pinit
;
1191 /* XXX: add an object file to do that */
1192 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1194 add_elf_sym(symtab_section
, 0, 0,
1195 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1196 bounds_section
->sh_num
, "__bounds_start");
1197 /* add bound check code */
1198 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "bcheck.o");
1199 tcc_add_file(s1
, buf
);
1200 #ifdef TCC_TARGET_I386
1201 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1202 /* add 'call __bound_init()' in .init section */
1203 init_section
= find_section(s1
, ".init");
1204 pinit
= section_ptr_add(init_section
, 5);
1206 put32(pinit
+ 1, -4);
1207 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1208 put_elf_reloc(symtab_section
, init_section
,
1209 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1215 if (!s1
->nostdlib
) {
1216 tcc_add_library(s1
, "c");
1218 #ifdef CONFIG_USE_LIBGCC
1219 tcc_add_file(s1
, CONFIG_SYSROOT
"/lib/libgcc_s.so.1");
1221 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "libtcc1.a");
1222 tcc_add_file(s1
, buf
);
1225 /* add crt end if not memory output */
1226 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1227 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1231 /* add various standard linker symbols (must be done after the
1232 sections are filled (for example after allocating common
1234 static void tcc_add_linker_symbols(TCCState
*s1
)
1240 add_elf_sym(symtab_section
,
1241 text_section
->data_offset
, 0,
1242 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1243 text_section
->sh_num
, "_etext");
1244 add_elf_sym(symtab_section
,
1245 data_section
->data_offset
, 0,
1246 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1247 data_section
->sh_num
, "_edata");
1248 add_elf_sym(symtab_section
,
1249 bss_section
->data_offset
, 0,
1250 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1251 bss_section
->sh_num
, "_end");
1252 /* horrible new standard ldscript defines */
1253 add_init_array_defines(s1
, ".preinit_array");
1254 add_init_array_defines(s1
, ".init_array");
1255 add_init_array_defines(s1
, ".fini_array");
1257 /* add start and stop symbols for sections whose name can be
1259 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1260 s
= s1
->sections
[i
];
1261 if (s
->sh_type
== SHT_PROGBITS
&&
1262 (s
->sh_flags
& SHF_ALLOC
)) {
1266 /* check if section name can be expressed in C */
1272 if (!isid(ch
) && !isnum(ch
))
1276 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1277 add_elf_sym(symtab_section
,
1279 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1281 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1282 add_elf_sym(symtab_section
,
1284 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1291 /* name of ELF interpreter */
1292 #if defined __FreeBSD__
1293 static const char elf_interp
[] = "/usr/libexec/ld-elf.so.1";
1294 #elif defined TCC_ARM_EABI
1295 static const char elf_interp
[] = "/lib/ld-linux.so.3";
1296 #elif defined(TCC_TARGET_X86_64)
1297 static const char elf_interp
[] = "/lib/ld-linux-x86-64.so.2";
1298 #elif defined(TCC_UCLIBC)
1299 static const char elf_interp
[] = "/lib/ld-uClibc.so.0";
1301 static const char elf_interp
[] = "/lib/ld-linux.so.2";
1304 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1305 const int *section_order
)
1308 int i
, offset
, size
;
1311 for(i
=1;i
<s1
->nb_sections
;i
++) {
1312 s
= s1
->sections
[section_order
[i
]];
1313 if (s
->sh_type
!= SHT_NOBITS
&&
1314 (s
->sh_flags
& SHF_ALLOC
)) {
1315 while (offset
< s
->sh_offset
) {
1320 fwrite(s
->data
, 1, size
, f
);
1326 /* output an ELF file */
1327 /* XXX: suppress unneeded sections */
1328 int elf_output_file(TCCState
*s1
, const char *filename
)
1334 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1336 Section
*strsec
, *s
;
1337 ElfW(Shdr
) shdr
, *sh
;
1338 ElfW(Phdr
) *phdr
, *ph
;
1339 Section
*interp
, *dynamic
, *dynstr
;
1340 unsigned long saved_dynamic_data_offset
;
1342 int type
, file_type
;
1343 unsigned long rel_addr
, rel_size
;
1345 file_type
= s1
->output_type
;
1348 if (file_type
!= TCC_OUTPUT_OBJ
) {
1349 tcc_add_runtime(s1
);
1353 section_order
= NULL
;
1356 dynstr
= NULL
; /* avoid warning */
1357 saved_dynamic_data_offset
= 0; /* avoid warning */
1359 if (file_type
!= TCC_OUTPUT_OBJ
) {
1360 relocate_common_syms();
1362 tcc_add_linker_symbols(s1
);
1364 if (!s1
->static_link
) {
1366 int sym_index
, index
;
1367 ElfW(Sym
) *esym
, *sym_end
;
1369 if (file_type
== TCC_OUTPUT_EXE
) {
1371 /* add interpreter section only if executable */
1372 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1373 interp
->sh_addralign
= 1;
1374 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
1375 strcpy(ptr
, elf_interp
);
1378 /* add dynamic symbol table */
1379 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1381 ".hash", SHF_ALLOC
);
1382 dynstr
= s1
->dynsym
->link
;
1384 /* add dynamic section */
1385 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1386 SHF_ALLOC
| SHF_WRITE
);
1387 dynamic
->link
= dynstr
;
1388 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1391 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1392 SHF_ALLOC
| SHF_EXECINSTR
);
1393 s1
->plt
->sh_entsize
= 4;
1397 /* scan for undefined symbols and see if they are in the
1398 dynamic symbols. If a symbol STT_FUNC is found, then we
1399 add it in the PLT. If a symbol STT_OBJECT is found, we
1400 add it in the .bss section with a suitable relocation */
1401 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1402 symtab_section
->data_offset
);
1403 if (file_type
== TCC_OUTPUT_EXE
) {
1404 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1407 if (sym
->st_shndx
== SHN_UNDEF
) {
1408 name
= symtab_section
->link
->data
+ sym
->st_name
;
1409 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1411 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1412 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1413 if (type
== STT_FUNC
) {
1414 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1416 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1417 } else if (type
== STT_OBJECT
) {
1418 unsigned long offset
;
1419 offset
= bss_section
->data_offset
;
1420 /* XXX: which alignment ? */
1421 offset
= (offset
+ 16 - 1) & -16;
1422 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1424 bss_section
->sh_num
, name
);
1425 put_elf_reloc(s1
->dynsym
, bss_section
,
1426 offset
, R_COPY
, index
);
1427 offset
+= esym
->st_size
;
1428 bss_section
->data_offset
= offset
;
1431 /* STB_WEAK undefined symbols are accepted */
1432 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1434 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1435 !strcmp(name
, "_fp_hw")) {
1437 error_noabort("undefined symbol '%s'", name
);
1440 } else if (s1
->rdynamic
&&
1441 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1442 /* if -rdynamic option, then export all non
1444 name
= symtab_section
->link
->data
+ sym
->st_name
;
1445 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1447 sym
->st_shndx
, name
);
1454 /* now look at unresolved dynamic symbols and export
1455 corresponding symbol */
1456 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1457 s1
->dynsymtab_section
->data_offset
);
1458 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1461 if (esym
->st_shndx
== SHN_UNDEF
) {
1462 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1463 sym_index
= find_elf_sym(symtab_section
, name
);
1465 /* XXX: avoid adding a symbol if already
1466 present because of -rdynamic ? */
1467 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1468 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1470 sym
->st_shndx
, name
);
1472 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1473 /* weak symbols can stay undefined */
1475 warning("undefined dynamic symbol '%s'", name
);
1482 /* shared library case : we simply export all the global symbols */
1483 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1484 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1485 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1488 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1489 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1490 if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
&&
1491 sym
->st_shndx
== SHN_UNDEF
) {
1492 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1494 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1496 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1497 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1499 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1504 name
= symtab_section
->link
->data
+ sym
->st_name
;
1505 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1507 sym
->st_shndx
, name
);
1508 s1
->symtab_to_dynsym
[sym
-
1509 (ElfW(Sym
) *)symtab_section
->data
] =
1516 build_got_entries(s1
);
1518 /* add a list of needed dlls */
1519 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1520 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1521 if (dllref
->level
== 0)
1522 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1524 /* XXX: currently, since we do not handle PIC code, we
1525 must relocate the readonly segments */
1526 if (file_type
== TCC_OUTPUT_DLL
) {
1528 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1529 put_dt(dynamic
, DT_TEXTREL
, 0);
1532 /* add necessary space for other entries */
1533 saved_dynamic_data_offset
= dynamic
->data_offset
;
1534 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * 9;
1536 /* still need to build got entries in case of static link */
1537 build_got_entries(s1
);
1541 memset(&ehdr
, 0, sizeof(ehdr
));
1543 /* we add a section for symbols */
1544 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1545 put_elf_str(strsec
, "");
1547 /* compute number of sections */
1548 shnum
= s1
->nb_sections
;
1550 /* this array is used to reorder sections in the output file */
1551 section_order
= tcc_malloc(sizeof(int) * shnum
);
1552 section_order
[0] = 0;
1555 /* compute number of program headers */
1558 case TCC_OUTPUT_OBJ
:
1561 case TCC_OUTPUT_EXE
:
1562 if (!s1
->static_link
)
1567 case TCC_OUTPUT_DLL
:
1572 /* allocate strings for section names and decide if an unallocated
1573 section should be output */
1574 /* NOTE: the strsec section comes last, so its size is also
1576 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1577 s
= s1
->sections
[i
];
1578 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1580 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1585 s
->reloc
? s
->reloc
->name
: "n"
1588 /* when generating a DLL, we include relocations but we may
1590 if (file_type
== TCC_OUTPUT_DLL
&&
1591 s
->sh_type
== SHT_RELX
&&
1592 !(s
->sh_flags
& SHF_ALLOC
)) {
1593 /* //gr: avoid bogus relocs for empty (debug) sections */
1594 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1595 prepare_dynamic_rel(s1
, s
);
1596 else if (s1
->do_debug
)
1597 s
->sh_size
= s
->data_offset
;
1598 } else if (s1
->do_debug
||
1599 file_type
== TCC_OUTPUT_OBJ
||
1600 (s
->sh_flags
& SHF_ALLOC
) ||
1601 i
== (s1
->nb_sections
- 1)) {
1602 /* we output all sections if debug or object file */
1603 s
->sh_size
= s
->data_offset
;
1607 /* allocate program segment headers */
1608 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1610 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1611 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1616 /* compute section to program header mapping */
1617 if (s1
->has_text_addr
) {
1618 int a_offset
, p_offset
;
1619 addr
= s1
->text_addr
;
1620 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1622 a_offset
= addr
& (ELF_PAGE_SIZE
- 1);
1623 p_offset
= file_offset
& (ELF_PAGE_SIZE
- 1);
1624 if (a_offset
< p_offset
)
1625 a_offset
+= ELF_PAGE_SIZE
;
1626 file_offset
+= (a_offset
- p_offset
);
1628 if (file_type
== TCC_OUTPUT_DLL
)
1631 addr
= ELF_START_ADDR
;
1632 /* compute address after headers */
1633 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1636 /* dynamic relocation table information, for .dynamic section */
1640 /* leave one program header for the program interpreter */
1645 for(j
= 0; j
< 2; j
++) {
1646 ph
->p_type
= PT_LOAD
;
1648 ph
->p_flags
= PF_R
| PF_X
;
1650 ph
->p_flags
= PF_R
| PF_W
;
1651 ph
->p_align
= ELF_PAGE_SIZE
;
1653 /* we do the following ordering: interp, symbol tables,
1654 relocations, progbits, nobits */
1655 /* XXX: do faster and simpler sorting */
1656 for(k
= 0; k
< 5; k
++) {
1657 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1658 s
= s1
->sections
[i
];
1659 /* compute if section should be included */
1661 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1665 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1666 (SHF_ALLOC
| SHF_WRITE
))
1672 } else if (s
->sh_type
== SHT_DYNSYM
||
1673 s
->sh_type
== SHT_STRTAB
||
1674 s
->sh_type
== SHT_HASH
) {
1677 } else if (s
->sh_type
== SHT_RELX
) {
1680 } else if (s
->sh_type
== SHT_NOBITS
) {
1687 section_order
[sh_order_index
++] = i
;
1689 /* section matches: we align it and add its size */
1691 addr
= (addr
+ s
->sh_addralign
- 1) &
1692 ~(s
->sh_addralign
- 1);
1693 file_offset
+= addr
- tmp
;
1694 s
->sh_offset
= file_offset
;
1697 /* update program header infos */
1698 if (ph
->p_offset
== 0) {
1699 ph
->p_offset
= file_offset
;
1701 ph
->p_paddr
= ph
->p_vaddr
;
1703 /* update dynamic relocation infos */
1704 if (s
->sh_type
== SHT_RELX
) {
1707 rel_size
+= s
->sh_size
;
1710 if (s
->sh_type
!= SHT_NOBITS
)
1711 file_offset
+= s
->sh_size
;
1714 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1715 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1718 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1719 /* if in the middle of a page, we duplicate the page in
1720 memory so that one copy is RX and the other is RW */
1721 if ((addr
& (ELF_PAGE_SIZE
- 1)) != 0)
1722 addr
+= ELF_PAGE_SIZE
;
1724 addr
= (addr
+ ELF_PAGE_SIZE
- 1) & ~(ELF_PAGE_SIZE
- 1);
1725 file_offset
= (file_offset
+ ELF_PAGE_SIZE
- 1) &
1726 ~(ELF_PAGE_SIZE
- 1);
1731 /* if interpreter, then add corresponing program header */
1735 ph
->p_type
= PT_INTERP
;
1736 ph
->p_offset
= interp
->sh_offset
;
1737 ph
->p_vaddr
= interp
->sh_addr
;
1738 ph
->p_paddr
= ph
->p_vaddr
;
1739 ph
->p_filesz
= interp
->sh_size
;
1740 ph
->p_memsz
= interp
->sh_size
;
1742 ph
->p_align
= interp
->sh_addralign
;
1745 /* if dynamic section, then add corresponing program header */
1749 ph
= &phdr
[phnum
- 1];
1751 ph
->p_type
= PT_DYNAMIC
;
1752 ph
->p_offset
= dynamic
->sh_offset
;
1753 ph
->p_vaddr
= dynamic
->sh_addr
;
1754 ph
->p_paddr
= ph
->p_vaddr
;
1755 ph
->p_filesz
= dynamic
->sh_size
;
1756 ph
->p_memsz
= dynamic
->sh_size
;
1757 ph
->p_flags
= PF_R
| PF_W
;
1758 ph
->p_align
= dynamic
->sh_addralign
;
1760 /* put GOT dynamic section address */
1761 put32(s1
->got
->data
, dynamic
->sh_addr
);
1763 /* relocate the PLT */
1764 if (file_type
== TCC_OUTPUT_EXE
1765 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1766 || file_type
== TCC_OUTPUT_DLL
1772 p_end
= p
+ s1
->plt
->data_offset
;
1774 #if defined(TCC_TARGET_I386)
1775 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1776 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1779 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1782 #elif defined(TCC_TARGET_X86_64)
1783 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1784 put32(p
+ 2, get32(p
+ 2) + x
);
1785 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1788 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1791 #elif defined(TCC_TARGET_ARM)
1793 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1796 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1799 #elif defined(TCC_TARGET_C67)
1802 #error unsupported CPU
1807 /* relocate symbols in .dynsym */
1808 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1809 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1812 if (sym
->st_shndx
== SHN_UNDEF
) {
1813 /* relocate to the PLT if the symbol corresponds
1816 sym
->st_value
+= s1
->plt
->sh_addr
;
1817 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1818 /* do symbol relocation */
1819 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1823 /* put dynamic section entries */
1824 dynamic
->data_offset
= saved_dynamic_data_offset
;
1825 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1826 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1827 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1828 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1829 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1830 #ifdef TCC_TARGET_X86_64
1831 put_dt(dynamic
, DT_RELA
, rel_addr
);
1832 put_dt(dynamic
, DT_RELASZ
, rel_size
);
1833 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1835 put_dt(dynamic
, DT_REL
, rel_addr
);
1836 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1837 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1840 put_dt(dynamic
, DT_DEBUG
, 0);
1841 put_dt(dynamic
, DT_NULL
, 0);
1844 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1845 ehdr
.e_phnum
= phnum
;
1846 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1849 /* all other sections come after */
1850 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1851 s
= s1
->sections
[i
];
1852 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1854 section_order
[sh_order_index
++] = i
;
1856 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1857 ~(s
->sh_addralign
- 1);
1858 s
->sh_offset
= file_offset
;
1859 if (s
->sh_type
!= SHT_NOBITS
)
1860 file_offset
+= s
->sh_size
;
1863 /* if building executable or DLL, then relocate each section
1864 except the GOT which is already relocated */
1865 if (file_type
!= TCC_OUTPUT_OBJ
) {
1866 relocate_syms(s1
, 0);
1868 if (s1
->nb_errors
!= 0) {
1874 /* relocate sections */
1875 /* XXX: ignore sections with allocated relocations ? */
1876 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1877 s
= s1
->sections
[i
];
1878 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1879 relocate_section(s1
, s
);
1882 /* relocate relocation entries if the relocation tables are
1883 allocated in the executable */
1884 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1885 s
= s1
->sections
[i
];
1886 if ((s
->sh_flags
& SHF_ALLOC
) &&
1887 s
->sh_type
== SHT_RELX
) {
1888 relocate_rel(s1
, s
);
1892 /* get entry point address */
1893 if (file_type
== TCC_OUTPUT_EXE
)
1894 ehdr
.e_entry
= (uplong
)tcc_get_symbol_err(s1
, "_start");
1896 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1899 /* write elf file */
1900 if (file_type
== TCC_OUTPUT_OBJ
)
1904 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1906 error_noabort("could not write '%s'", filename
);
1909 f
= fdopen(fd
, "wb");
1911 printf("<- %s\n", filename
);
1913 #ifdef TCC_TARGET_COFF
1914 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1915 tcc_output_coff(s1
, f
);
1918 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1919 sort_syms(s1
, symtab_section
);
1922 file_offset
= (file_offset
+ 3) & -4;
1925 ehdr
.e_ident
[0] = ELFMAG0
;
1926 ehdr
.e_ident
[1] = ELFMAG1
;
1927 ehdr
.e_ident
[2] = ELFMAG2
;
1928 ehdr
.e_ident
[3] = ELFMAG3
;
1929 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
1930 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1931 ehdr
.e_ident
[6] = EV_CURRENT
;
1933 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1935 #ifdef TCC_TARGET_ARM
1937 ehdr
.e_ident
[EI_OSABI
] = 0;
1938 ehdr
.e_flags
= 4 << 24;
1940 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
1945 case TCC_OUTPUT_EXE
:
1946 ehdr
.e_type
= ET_EXEC
;
1948 case TCC_OUTPUT_DLL
:
1949 ehdr
.e_type
= ET_DYN
;
1951 case TCC_OUTPUT_OBJ
:
1952 ehdr
.e_type
= ET_REL
;
1955 ehdr
.e_machine
= EM_TCC_TARGET
;
1956 ehdr
.e_version
= EV_CURRENT
;
1957 ehdr
.e_shoff
= file_offset
;
1958 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
1959 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
1960 ehdr
.e_shnum
= shnum
;
1961 ehdr
.e_shstrndx
= shnum
- 1;
1963 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
1964 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
1965 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1967 for(i
=1;i
<s1
->nb_sections
;i
++) {
1968 s
= s1
->sections
[section_order
[i
]];
1969 if (s
->sh_type
!= SHT_NOBITS
) {
1970 while (offset
< s
->sh_offset
) {
1975 fwrite(s
->data
, 1, size
, f
);
1980 /* output section headers */
1981 while (offset
< ehdr
.e_shoff
) {
1986 for(i
=0;i
<s1
->nb_sections
;i
++) {
1988 memset(sh
, 0, sizeof(ElfW(Shdr
)));
1989 s
= s1
->sections
[i
];
1991 sh
->sh_name
= s
->sh_name
;
1992 sh
->sh_type
= s
->sh_type
;
1993 sh
->sh_flags
= s
->sh_flags
;
1994 sh
->sh_entsize
= s
->sh_entsize
;
1995 sh
->sh_info
= s
->sh_info
;
1997 sh
->sh_link
= s
->link
->sh_num
;
1998 sh
->sh_addralign
= s
->sh_addralign
;
1999 sh
->sh_addr
= s
->sh_addr
;
2000 sh
->sh_offset
= s
->sh_offset
;
2001 sh
->sh_size
= s
->sh_size
;
2003 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2006 tcc_output_binary(s1
, f
, section_order
);
2012 tcc_free(s1
->symtab_to_dynsym
);
2013 tcc_free(section_order
);
2015 tcc_free(s1
->got_offsets
);
2019 int tcc_output_file(TCCState
*s
, const char *filename
)
2022 #ifdef TCC_TARGET_PE
2023 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2024 ret
= pe_output_file(s
, filename
);
2028 ret
= elf_output_file(s
, filename
);
2033 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2037 data
= tcc_malloc(size
);
2038 lseek(fd
, file_offset
, SEEK_SET
);
2039 read(fd
, data
, size
);
2043 typedef struct SectionMergeInfo
{
2044 Section
*s
; /* corresponding existing section */
2045 unsigned long offset
; /* offset of the new section in the existing section */
2046 uint8_t new_section
; /* true if section 's' was added */
2047 uint8_t link_once
; /* true if link once section */
2050 /* load an object file and merge it with current files */
2051 /* XXX: handle correctly stab (debug) info */
2052 static int tcc_load_object_file(TCCState
*s1
,
2053 int fd
, unsigned long file_offset
)
2056 ElfW(Shdr
) *shdr
, *sh
;
2057 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2058 unsigned char *strsec
, *strtab
;
2059 int *old_to_new_syms
;
2060 char *sh_name
, *name
;
2061 SectionMergeInfo
*sm_table
, *sm
;
2062 ElfW(Sym
) *sym
, *symtab
;
2063 ElfW_Rel
*rel
, *rel_end
;
2069 stab_index
= stabstr_index
= 0;
2071 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2073 if (ehdr
.e_ident
[0] != ELFMAG0
||
2074 ehdr
.e_ident
[1] != ELFMAG1
||
2075 ehdr
.e_ident
[2] != ELFMAG2
||
2076 ehdr
.e_ident
[3] != ELFMAG3
)
2078 /* test if object file */
2079 if (ehdr
.e_type
!= ET_REL
)
2081 /* test CPU specific stuff */
2082 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2083 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2085 error_noabort("invalid object file");
2089 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2090 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2091 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2093 /* load section names */
2094 sh
= &shdr
[ehdr
.e_shstrndx
];
2095 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2097 /* load symtab and strtab */
2098 old_to_new_syms
= NULL
;
2102 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2104 if (sh
->sh_type
== SHT_SYMTAB
) {
2106 error_noabort("object must contain only one symtab");
2111 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2112 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2113 sm_table
[i
].s
= symtab_section
;
2115 /* now load strtab */
2116 sh
= &shdr
[sh
->sh_link
];
2117 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2121 /* now examine each section and try to merge its content with the
2123 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2124 /* no need to examine section name strtab */
2125 if (i
== ehdr
.e_shstrndx
)
2128 sh_name
= strsec
+ sh
->sh_name
;
2129 /* ignore sections types we do not handle */
2130 if (sh
->sh_type
!= SHT_PROGBITS
&&
2131 sh
->sh_type
!= SHT_RELX
&&
2133 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2135 sh
->sh_type
!= SHT_NOBITS
&&
2136 strcmp(sh_name
, ".stabstr")
2139 if (sh
->sh_addralign
< 1)
2140 sh
->sh_addralign
= 1;
2141 /* find corresponding section, if any */
2142 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2143 s
= s1
->sections
[j
];
2144 if (!strcmp(s
->name
, sh_name
)) {
2145 if (!strncmp(sh_name
, ".gnu.linkonce",
2146 sizeof(".gnu.linkonce") - 1)) {
2147 /* if a 'linkonce' section is already present, we
2148 do not add it again. It is a little tricky as
2149 symbols can still be defined in
2151 sm_table
[i
].link_once
= 1;
2158 /* not found: create new section */
2159 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2160 /* take as much info as possible from the section. sh_link and
2161 sh_info will be updated later */
2162 s
->sh_addralign
= sh
->sh_addralign
;
2163 s
->sh_entsize
= sh
->sh_entsize
;
2164 sm_table
[i
].new_section
= 1;
2166 if (sh
->sh_type
!= s
->sh_type
) {
2167 error_noabort("invalid section type");
2171 /* align start of section */
2172 offset
= s
->data_offset
;
2174 if (0 == strcmp(sh_name
, ".stab")) {
2178 if (0 == strcmp(sh_name
, ".stabstr")) {
2183 size
= sh
->sh_addralign
- 1;
2184 offset
= (offset
+ size
) & ~size
;
2185 if (sh
->sh_addralign
> s
->sh_addralign
)
2186 s
->sh_addralign
= sh
->sh_addralign
;
2187 s
->data_offset
= offset
;
2189 sm_table
[i
].offset
= offset
;
2191 /* concatenate sections */
2193 if (sh
->sh_type
!= SHT_NOBITS
) {
2195 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2196 ptr
= section_ptr_add(s
, size
);
2197 read(fd
, ptr
, size
);
2199 s
->data_offset
+= size
;
2204 /* //gr relocate stab strings */
2205 if (stab_index
&& stabstr_index
) {
2208 s
= sm_table
[stab_index
].s
;
2209 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2210 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2211 o
= sm_table
[stabstr_index
].offset
;
2213 a
->n_strx
+= o
, a
++;
2216 /* second short pass to update sh_link and sh_info fields of new
2218 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2220 if (!s
|| !sm_table
[i
].new_section
)
2223 if (sh
->sh_link
> 0)
2224 s
->link
= sm_table
[sh
->sh_link
].s
;
2225 if (sh
->sh_type
== SHT_RELX
) {
2226 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2227 /* update backward link */
2228 s1
->sections
[s
->sh_info
]->reloc
= s
;
2233 /* resolve symbols */
2234 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2237 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2238 if (sym
->st_shndx
!= SHN_UNDEF
&&
2239 sym
->st_shndx
< SHN_LORESERVE
) {
2240 sm
= &sm_table
[sym
->st_shndx
];
2241 if (sm
->link_once
) {
2242 /* if a symbol is in a link once section, we use the
2243 already defined symbol. It is very important to get
2244 correct relocations */
2245 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2246 name
= strtab
+ sym
->st_name
;
2247 sym_index
= find_elf_sym(symtab_section
, name
);
2249 old_to_new_syms
[i
] = sym_index
;
2253 /* if no corresponding section added, no need to add symbol */
2256 /* convert section number */
2257 sym
->st_shndx
= sm
->s
->sh_num
;
2259 sym
->st_value
+= sm
->offset
;
2262 name
= strtab
+ sym
->st_name
;
2263 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2264 sym
->st_info
, sym
->st_other
,
2265 sym
->st_shndx
, name
);
2266 old_to_new_syms
[i
] = sym_index
;
2269 /* third pass to patch relocation entries */
2270 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2275 offset
= sm_table
[i
].offset
;
2276 switch(s
->sh_type
) {
2278 /* take relocation offset information */
2279 offseti
= sm_table
[sh
->sh_info
].offset
;
2280 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2281 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2286 /* convert symbol index */
2287 type
= ELFW(R_TYPE
)(rel
->r_info
);
2288 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2289 /* NOTE: only one symtab assumed */
2290 if (sym_index
>= nb_syms
)
2292 sym_index
= old_to_new_syms
[sym_index
];
2293 /* ignore link_once in rel section. */
2294 if (!sym_index
&& !sm
->link_once
) {
2296 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2297 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2300 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2301 /* offset the relocation offset */
2302 rel
->r_offset
+= offseti
;
2314 tcc_free(old_to_new_syms
);
2321 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2323 typedef struct ArchiveHeader
{
2324 char ar_name
[16]; /* name of this member */
2325 char ar_date
[12]; /* file mtime */
2326 char ar_uid
[6]; /* owner uid; printed as decimal */
2327 char ar_gid
[6]; /* owner gid; printed as decimal */
2328 char ar_mode
[8]; /* file mode, printed as octal */
2329 char ar_size
[10]; /* file size, printed as decimal */
2330 char ar_fmag
[2]; /* should contain ARFMAG */
2333 static int get_be32(const uint8_t *b
)
2335 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2338 /* load only the objects which resolve undefined symbols */
2339 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2341 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2343 const char *ar_names
, *p
;
2344 const uint8_t *ar_index
;
2347 data
= tcc_malloc(size
);
2348 if (read(fd
, data
, size
) != size
)
2350 nsyms
= get_be32(data
);
2351 ar_index
= data
+ 4;
2352 ar_names
= ar_index
+ nsyms
* 4;
2356 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2357 sym_index
= find_elf_sym(symtab_section
, p
);
2359 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2360 if(sym
->st_shndx
== SHN_UNDEF
) {
2361 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2363 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2366 lseek(fd
, off
, SEEK_SET
);
2367 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2382 /* load a '.a' file */
2383 static int tcc_load_archive(TCCState
*s1
, int fd
)
2390 unsigned long file_offset
;
2392 /* skip magic which was already checked */
2393 read(fd
, magic
, sizeof(magic
));
2396 len
= read(fd
, &hdr
, sizeof(hdr
));
2399 if (len
!= sizeof(hdr
)) {
2400 error_noabort("invalid archive");
2403 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2404 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2405 size
= strtol(ar_size
, NULL
, 0);
2406 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2407 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2408 if (ar_name
[i
] != ' ')
2411 ar_name
[i
+ 1] = '\0';
2412 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2413 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2415 size
= (size
+ 1) & ~1;
2416 if (!strcmp(ar_name
, "/")) {
2417 /* coff symbol table : we handle it */
2418 if(s1
->alacarte_link
)
2419 return tcc_load_alacarte(s1
, fd
, size
);
2420 } else if (!strcmp(ar_name
, "//") ||
2421 !strcmp(ar_name
, "__.SYMDEF") ||
2422 !strcmp(ar_name
, "__.SYMDEF/") ||
2423 !strcmp(ar_name
, "ARFILENAMES/")) {
2424 /* skip symbol table or archive names */
2426 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2429 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2434 #ifndef TCC_TARGET_PE
2435 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2436 is referenced by the user (so it should be added as DT_NEEDED in
2437 the generated ELF file) */
2438 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2441 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2442 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2443 ElfW(Sym
) *sym
, *dynsym
;
2444 ElfW(Dyn
) *dt
, *dynamic
;
2445 unsigned char *dynstr
;
2446 const char *name
, *soname
;
2447 DLLReference
*dllref
;
2449 read(fd
, &ehdr
, sizeof(ehdr
));
2451 /* test CPU specific stuff */
2452 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2453 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2454 error_noabort("bad architecture");
2459 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2461 /* load dynamic section and dynamic symbols */
2465 dynsym
= NULL
; /* avoid warning */
2466 dynstr
= NULL
; /* avoid warning */
2467 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2468 switch(sh
->sh_type
) {
2470 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2471 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2474 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2475 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2476 sh1
= &shdr
[sh
->sh_link
];
2477 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2484 /* compute the real library name */
2485 soname
= tcc_basename(filename
);
2487 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2488 if (dt
->d_tag
== DT_SONAME
) {
2489 soname
= dynstr
+ dt
->d_un
.d_val
;
2493 /* if the dll is already loaded, do not load it */
2494 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2495 dllref
= s1
->loaded_dlls
[i
];
2496 if (!strcmp(soname
, dllref
->name
)) {
2497 /* but update level if needed */
2498 if (level
< dllref
->level
)
2499 dllref
->level
= level
;
2505 // printf("loading dll '%s'\n", soname);
2507 /* add the dll and its level */
2508 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2509 dllref
->level
= level
;
2510 strcpy(dllref
->name
, soname
);
2511 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2513 /* add dynamic symbols in dynsym_section */
2514 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2515 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2516 if (sym_bind
== STB_LOCAL
)
2518 name
= dynstr
+ sym
->st_name
;
2519 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2520 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2523 /* load all referenced DLLs */
2524 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2527 name
= dynstr
+ dt
->d_un
.d_val
;
2528 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2529 dllref
= s1
->loaded_dlls
[j
];
2530 if (!strcmp(name
, dllref
->name
))
2531 goto already_loaded
;
2533 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2534 error_noabort("referenced dll '%s' not found", name
);
2551 #define LD_TOK_NAME 256
2552 #define LD_TOK_EOF (-1)
2554 /* return next ld script token */
2555 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2573 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2574 ch
= file
->buf_ptr
[0];
2582 /* case 'a' ... 'z': */
2609 /* case 'A' ... 'z': */
2644 if (!((ch
>= 'a' && ch
<= 'z') ||
2645 (ch
>= 'A' && ch
<= 'Z') ||
2646 (ch
>= '0' && ch
<= '9') ||
2647 strchr("/.-_+=$:\\,~", ch
)))
2649 if ((q
- name
) < name_size
- 1) {
2666 printf("tok=%c %d\n", c
, c
);
2667 if (c
== LD_TOK_NAME
)
2668 printf(" name=%s\n", name
);
2673 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2675 char filename
[1024];
2678 t
= ld_next(s1
, filename
, sizeof(filename
));
2681 t
= ld_next(s1
, filename
, sizeof(filename
));
2683 if (t
== LD_TOK_EOF
) {
2684 error_noabort("unexpected end of file");
2686 } else if (t
== ')') {
2688 } else if (t
!= LD_TOK_NAME
) {
2689 error_noabort("filename expected");
2692 if (!strcmp(filename
, "AS_NEEDED")) {
2693 ret
= ld_add_file_list(s1
, 1);
2697 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2699 tcc_add_file(s1
, filename
);
2701 t
= ld_next(s1
, filename
, sizeof(filename
));
2703 t
= ld_next(s1
, filename
, sizeof(filename
));
2709 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2711 static int tcc_load_ldscript(TCCState
*s1
)
2714 char filename
[1024];
2717 ch
= file
->buf_ptr
[0];
2720 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2721 if (t
== LD_TOK_EOF
)
2723 else if (t
!= LD_TOK_NAME
)
2725 if (!strcmp(cmd
, "INPUT") ||
2726 !strcmp(cmd
, "GROUP")) {
2727 ret
= ld_add_file_list(s1
, 0);
2730 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2731 !strcmp(cmd
, "TARGET")) {
2732 /* ignore some commands */
2733 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2737 t
= ld_next(s1
, filename
, sizeof(filename
));
2738 if (t
== LD_TOK_EOF
) {
2739 error_noabort("unexpected end of file");
2741 } else if (t
== ')') {