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
) && (s1
->output_type
!= TCC_OUTPUT_FORMAT_BINARY
)) {
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 if (s1
->output_type
!= TCC_OUTPUT_FORMAT_BINARY
)
1363 tcc_add_linker_symbols(s1
);
1365 if ((!s1
->static_link
) && (s1
->output_type
!= TCC_OUTPUT_FORMAT_BINARY
)) {
1367 int sym_index
, index
;
1368 ElfW(Sym
) *esym
, *sym_end
;
1370 if ((file_type
== TCC_OUTPUT_EXE
) && (s1
->output_type
!= TCC_OUTPUT_FORMAT_BINARY
)) {
1372 /* add interpreter section only if executable */
1373 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1374 interp
->sh_addralign
= 1;
1375 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
1376 strcpy(ptr
, elf_interp
);
1379 /* add dynamic symbol table */
1380 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1382 ".hash", SHF_ALLOC
);
1383 dynstr
= s1
->dynsym
->link
;
1385 /* add dynamic section */
1386 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1387 SHF_ALLOC
| SHF_WRITE
);
1388 dynamic
->link
= dynstr
;
1389 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1392 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1393 SHF_ALLOC
| SHF_EXECINSTR
);
1394 s1
->plt
->sh_entsize
= 4;
1398 /* scan for undefined symbols and see if they are in the
1399 dynamic symbols. If a symbol STT_FUNC is found, then we
1400 add it in the PLT. If a symbol STT_OBJECT is found, we
1401 add it in the .bss section with a suitable relocation */
1402 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1403 symtab_section
->data_offset
);
1404 if (file_type
== TCC_OUTPUT_EXE
) {
1405 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1408 if (sym
->st_shndx
== SHN_UNDEF
) {
1409 name
= symtab_section
->link
->data
+ sym
->st_name
;
1410 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1412 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1413 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1414 if (type
== STT_FUNC
) {
1415 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1417 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1418 } else if (type
== STT_OBJECT
) {
1419 unsigned long offset
;
1420 offset
= bss_section
->data_offset
;
1421 /* XXX: which alignment ? */
1422 offset
= (offset
+ 16 - 1) & -16;
1423 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1425 bss_section
->sh_num
, name
);
1426 put_elf_reloc(s1
->dynsym
, bss_section
,
1427 offset
, R_COPY
, index
);
1428 offset
+= esym
->st_size
;
1429 bss_section
->data_offset
= offset
;
1432 /* STB_WEAK undefined symbols are accepted */
1433 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1435 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1436 !strcmp(name
, "_fp_hw")) {
1438 error_noabort("undefined symbol '%s'", name
);
1441 } else if (s1
->rdynamic
&&
1442 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1443 /* if -rdynamic option, then export all non
1445 name
= symtab_section
->link
->data
+ sym
->st_name
;
1446 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1448 sym
->st_shndx
, name
);
1455 /* now look at unresolved dynamic symbols and export
1456 corresponding symbol */
1457 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1458 s1
->dynsymtab_section
->data_offset
);
1459 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1462 if (esym
->st_shndx
== SHN_UNDEF
) {
1463 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1464 sym_index
= find_elf_sym(symtab_section
, name
);
1466 /* XXX: avoid adding a symbol if already
1467 present because of -rdynamic ? */
1468 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1469 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1471 sym
->st_shndx
, name
);
1473 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1474 /* weak symbols can stay undefined */
1476 warning("undefined dynamic symbol '%s'", name
);
1483 /* shared library case : we simply export all the global symbols */
1484 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1485 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1486 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1489 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1490 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1491 if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
&&
1492 sym
->st_shndx
== SHN_UNDEF
) {
1493 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1495 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1497 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1498 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1500 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1505 name
= symtab_section
->link
->data
+ sym
->st_name
;
1506 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1508 sym
->st_shndx
, name
);
1509 s1
->symtab_to_dynsym
[sym
-
1510 (ElfW(Sym
) *)symtab_section
->data
] =
1517 build_got_entries(s1
);
1519 /* add a list of needed dlls */
1520 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1521 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1522 if (dllref
->level
== 0)
1523 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1525 /* XXX: currently, since we do not handle PIC code, we
1526 must relocate the readonly segments */
1527 if (file_type
== TCC_OUTPUT_DLL
) {
1529 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1530 put_dt(dynamic
, DT_TEXTREL
, 0);
1533 /* add necessary space for other entries */
1534 saved_dynamic_data_offset
= dynamic
->data_offset
;
1535 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * 9;
1537 /* still need to build got entries in case of static link */
1538 build_got_entries(s1
);
1542 memset(&ehdr
, 0, sizeof(ehdr
));
1544 /* we add a section for symbols */
1545 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1546 put_elf_str(strsec
, "");
1548 /* compute number of sections */
1549 shnum
= s1
->nb_sections
;
1551 /* this array is used to reorder sections in the output file */
1552 section_order
= tcc_malloc(sizeof(int) * shnum
);
1553 section_order
[0] = 0;
1556 /* compute number of program headers */
1559 case TCC_OUTPUT_OBJ
:
1562 case TCC_OUTPUT_EXE
:
1563 if (!s1
->static_link
)
1568 case TCC_OUTPUT_DLL
:
1573 /* allocate strings for section names and decide if an unallocated
1574 section should be output */
1575 /* NOTE: the strsec section comes last, so its size is also
1577 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1578 s
= s1
->sections
[i
];
1579 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1581 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1586 s
->reloc
? s
->reloc
->name
: "n"
1589 /* when generating a DLL, we include relocations but we may
1591 if (file_type
== TCC_OUTPUT_DLL
&&
1592 s
->sh_type
== SHT_RELX
&&
1593 !(s
->sh_flags
& SHF_ALLOC
)) {
1594 /* //gr: avoid bogus relocs for empty (debug) sections */
1595 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1596 prepare_dynamic_rel(s1
, s
);
1597 else if (s1
->do_debug
)
1598 s
->sh_size
= s
->data_offset
;
1599 } else if (s1
->do_debug
||
1600 file_type
== TCC_OUTPUT_OBJ
||
1601 (s
->sh_flags
& SHF_ALLOC
) ||
1602 i
== (s1
->nb_sections
- 1)) {
1603 /* we output all sections if debug or object file */
1604 s
->sh_size
= s
->data_offset
;
1608 /* allocate program segment headers */
1609 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1611 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1612 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1617 /* compute section to program header mapping */
1618 if (s1
->has_text_addr
) {
1619 int a_offset
, p_offset
;
1620 addr
= s1
->text_addr
;
1621 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1623 a_offset
= addr
& (ELF_PAGE_SIZE
- 1);
1624 p_offset
= file_offset
& (ELF_PAGE_SIZE
- 1);
1625 if (a_offset
< p_offset
)
1626 a_offset
+= ELF_PAGE_SIZE
;
1627 file_offset
+= (a_offset
- p_offset
);
1629 if (file_type
== TCC_OUTPUT_DLL
)
1632 addr
= ELF_START_ADDR
;
1633 /* compute address after headers */
1634 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1637 /* dynamic relocation table information, for .dynamic section */
1641 /* leave one program header for the program interpreter */
1646 for(j
= 0; j
< 2; j
++) {
1647 ph
->p_type
= PT_LOAD
;
1649 ph
->p_flags
= PF_R
| PF_X
;
1651 ph
->p_flags
= PF_R
| PF_W
;
1652 ph
->p_align
= ELF_PAGE_SIZE
;
1654 /* we do the following ordering: interp, symbol tables,
1655 relocations, progbits, nobits */
1656 /* XXX: do faster and simpler sorting */
1657 for(k
= 0; k
< 5; k
++) {
1658 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1659 s
= s1
->sections
[i
];
1660 /* compute if section should be included */
1662 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1666 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1667 (SHF_ALLOC
| SHF_WRITE
))
1673 } else if (s
->sh_type
== SHT_DYNSYM
||
1674 s
->sh_type
== SHT_STRTAB
||
1675 s
->sh_type
== SHT_HASH
) {
1678 } else if (s
->sh_type
== SHT_RELX
) {
1681 } else if (s
->sh_type
== SHT_NOBITS
) {
1688 section_order
[sh_order_index
++] = i
;
1690 /* section matches: we align it and add its size */
1692 addr
= (addr
+ s
->sh_addralign
- 1) &
1693 ~(s
->sh_addralign
- 1);
1694 file_offset
+= addr
- tmp
;
1695 s
->sh_offset
= file_offset
;
1698 /* update program header infos */
1699 if (ph
->p_offset
== 0) {
1700 ph
->p_offset
= file_offset
;
1702 ph
->p_paddr
= ph
->p_vaddr
;
1704 /* update dynamic relocation infos */
1705 if (s
->sh_type
== SHT_RELX
) {
1708 rel_size
+= s
->sh_size
;
1711 if (s
->sh_type
!= SHT_NOBITS
)
1712 file_offset
+= s
->sh_size
;
1715 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1716 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1719 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1720 /* if in the middle of a page, we duplicate the page in
1721 memory so that one copy is RX and the other is RW */
1722 if ((addr
& (ELF_PAGE_SIZE
- 1)) != 0)
1723 addr
+= ELF_PAGE_SIZE
;
1725 addr
= (addr
+ ELF_PAGE_SIZE
- 1) & ~(ELF_PAGE_SIZE
- 1);
1726 file_offset
= (file_offset
+ ELF_PAGE_SIZE
- 1) &
1727 ~(ELF_PAGE_SIZE
- 1);
1732 /* if interpreter, then add corresponing program header */
1736 ph
->p_type
= PT_INTERP
;
1737 ph
->p_offset
= interp
->sh_offset
;
1738 ph
->p_vaddr
= interp
->sh_addr
;
1739 ph
->p_paddr
= ph
->p_vaddr
;
1740 ph
->p_filesz
= interp
->sh_size
;
1741 ph
->p_memsz
= interp
->sh_size
;
1743 ph
->p_align
= interp
->sh_addralign
;
1746 /* if dynamic section, then add corresponing program header */
1750 ph
= &phdr
[phnum
- 1];
1752 ph
->p_type
= PT_DYNAMIC
;
1753 ph
->p_offset
= dynamic
->sh_offset
;
1754 ph
->p_vaddr
= dynamic
->sh_addr
;
1755 ph
->p_paddr
= ph
->p_vaddr
;
1756 ph
->p_filesz
= dynamic
->sh_size
;
1757 ph
->p_memsz
= dynamic
->sh_size
;
1758 ph
->p_flags
= PF_R
| PF_W
;
1759 ph
->p_align
= dynamic
->sh_addralign
;
1761 /* put GOT dynamic section address */
1762 put32(s1
->got
->data
, dynamic
->sh_addr
);
1764 /* relocate the PLT */
1765 if (file_type
== TCC_OUTPUT_EXE
1766 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1767 || file_type
== TCC_OUTPUT_DLL
1773 p_end
= p
+ s1
->plt
->data_offset
;
1775 #if defined(TCC_TARGET_I386)
1776 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1777 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1780 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1783 #elif defined(TCC_TARGET_X86_64)
1784 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1785 put32(p
+ 2, get32(p
+ 2) + x
);
1786 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1789 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1792 #elif defined(TCC_TARGET_ARM)
1794 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1797 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1800 #elif defined(TCC_TARGET_C67)
1803 #error unsupported CPU
1808 /* relocate symbols in .dynsym */
1809 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1810 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1813 if (sym
->st_shndx
== SHN_UNDEF
) {
1814 /* relocate to the PLT if the symbol corresponds
1817 sym
->st_value
+= s1
->plt
->sh_addr
;
1818 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1819 /* do symbol relocation */
1820 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1824 /* put dynamic section entries */
1825 dynamic
->data_offset
= saved_dynamic_data_offset
;
1826 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1827 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1828 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1829 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1830 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1831 #ifdef TCC_TARGET_X86_64
1832 put_dt(dynamic
, DT_RELA
, rel_addr
);
1833 put_dt(dynamic
, DT_RELASZ
, rel_size
);
1834 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1836 put_dt(dynamic
, DT_REL
, rel_addr
);
1837 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1838 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1841 put_dt(dynamic
, DT_DEBUG
, 0);
1842 put_dt(dynamic
, DT_NULL
, 0);
1845 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1846 ehdr
.e_phnum
= phnum
;
1847 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1850 /* all other sections come after */
1851 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1852 s
= s1
->sections
[i
];
1853 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1855 section_order
[sh_order_index
++] = i
;
1857 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1858 ~(s
->sh_addralign
- 1);
1859 s
->sh_offset
= file_offset
;
1860 if (s
->sh_type
!= SHT_NOBITS
)
1861 file_offset
+= s
->sh_size
;
1864 /* if building executable or DLL, then relocate each section
1865 except the GOT which is already relocated */
1866 if (file_type
!= TCC_OUTPUT_OBJ
) {
1867 relocate_syms(s1
, 0);
1869 if (s1
->nb_errors
!= 0) {
1875 /* relocate sections */
1876 /* XXX: ignore sections with allocated relocations ? */
1877 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1878 s
= s1
->sections
[i
];
1879 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1880 relocate_section(s1
, s
);
1883 /* relocate relocation entries if the relocation tables are
1884 allocated in the executable */
1885 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1886 s
= s1
->sections
[i
];
1887 if ((s
->sh_flags
& SHF_ALLOC
) &&
1888 s
->sh_type
== SHT_RELX
) {
1889 relocate_rel(s1
, s
);
1893 /* get entry point address */
1894 if (file_type
== TCC_OUTPUT_EXE
)
1895 ehdr
.e_entry
= (uplong
)tcc_get_symbol_err(s1
, "_start");
1897 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1900 /* write elf file */
1901 if (file_type
== TCC_OUTPUT_OBJ
)
1905 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1907 error_noabort("could not write '%s'", filename
);
1910 f
= fdopen(fd
, "wb");
1912 printf("<- %s\n", filename
);
1914 #ifdef TCC_TARGET_COFF
1915 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1916 tcc_output_coff(s1
, f
);
1919 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1920 sort_syms(s1
, symtab_section
);
1923 file_offset
= (file_offset
+ 3) & -4;
1926 ehdr
.e_ident
[0] = ELFMAG0
;
1927 ehdr
.e_ident
[1] = ELFMAG1
;
1928 ehdr
.e_ident
[2] = ELFMAG2
;
1929 ehdr
.e_ident
[3] = ELFMAG3
;
1930 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
1931 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1932 ehdr
.e_ident
[6] = EV_CURRENT
;
1934 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1936 #ifdef TCC_TARGET_ARM
1938 ehdr
.e_ident
[EI_OSABI
] = 0;
1939 ehdr
.e_flags
= 4 << 24;
1941 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
1946 case TCC_OUTPUT_EXE
:
1947 ehdr
.e_type
= ET_EXEC
;
1949 case TCC_OUTPUT_DLL
:
1950 ehdr
.e_type
= ET_DYN
;
1952 case TCC_OUTPUT_OBJ
:
1953 ehdr
.e_type
= ET_REL
;
1956 ehdr
.e_machine
= EM_TCC_TARGET
;
1957 ehdr
.e_version
= EV_CURRENT
;
1958 ehdr
.e_shoff
= file_offset
;
1959 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
1960 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
1961 ehdr
.e_shnum
= shnum
;
1962 ehdr
.e_shstrndx
= shnum
- 1;
1964 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
1965 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
1966 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1968 for(i
=1;i
<s1
->nb_sections
;i
++) {
1969 s
= s1
->sections
[section_order
[i
]];
1970 if (s
->sh_type
!= SHT_NOBITS
) {
1971 while (offset
< s
->sh_offset
) {
1976 fwrite(s
->data
, 1, size
, f
);
1981 /* output section headers */
1982 while (offset
< ehdr
.e_shoff
) {
1987 for(i
=0;i
<s1
->nb_sections
;i
++) {
1989 memset(sh
, 0, sizeof(ElfW(Shdr
)));
1990 s
= s1
->sections
[i
];
1992 sh
->sh_name
= s
->sh_name
;
1993 sh
->sh_type
= s
->sh_type
;
1994 sh
->sh_flags
= s
->sh_flags
;
1995 sh
->sh_entsize
= s
->sh_entsize
;
1996 sh
->sh_info
= s
->sh_info
;
1998 sh
->sh_link
= s
->link
->sh_num
;
1999 sh
->sh_addralign
= s
->sh_addralign
;
2000 sh
->sh_addr
= s
->sh_addr
;
2001 sh
->sh_offset
= s
->sh_offset
;
2002 sh
->sh_size
= s
->sh_size
;
2004 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2007 tcc_output_binary(s1
, f
, section_order
);
2013 tcc_free(s1
->symtab_to_dynsym
);
2014 tcc_free(section_order
);
2016 tcc_free(s1
->got_offsets
);
2020 int tcc_output_file(TCCState
*s
, const char *filename
)
2023 #ifdef TCC_TARGET_PE
2024 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2025 ret
= pe_output_file(s
, filename
);
2029 ret
= elf_output_file(s
, filename
);
2034 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2038 data
= tcc_malloc(size
);
2039 lseek(fd
, file_offset
, SEEK_SET
);
2040 read(fd
, data
, size
);
2044 typedef struct SectionMergeInfo
{
2045 Section
*s
; /* corresponding existing section */
2046 unsigned long offset
; /* offset of the new section in the existing section */
2047 uint8_t new_section
; /* true if section 's' was added */
2048 uint8_t link_once
; /* true if link once section */
2051 /* load an object file and merge it with current files */
2052 /* XXX: handle correctly stab (debug) info */
2053 static int tcc_load_object_file(TCCState
*s1
,
2054 int fd
, unsigned long file_offset
)
2057 ElfW(Shdr
) *shdr
, *sh
;
2058 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2059 unsigned char *strsec
, *strtab
;
2060 int *old_to_new_syms
;
2061 char *sh_name
, *name
;
2062 SectionMergeInfo
*sm_table
, *sm
;
2063 ElfW(Sym
) *sym
, *symtab
;
2064 ElfW_Rel
*rel
, *rel_end
;
2070 stab_index
= stabstr_index
= 0;
2072 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2074 if (ehdr
.e_ident
[0] != ELFMAG0
||
2075 ehdr
.e_ident
[1] != ELFMAG1
||
2076 ehdr
.e_ident
[2] != ELFMAG2
||
2077 ehdr
.e_ident
[3] != ELFMAG3
)
2079 /* test if object file */
2080 if (ehdr
.e_type
!= ET_REL
)
2082 /* test CPU specific stuff */
2083 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2084 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2086 error_noabort("invalid object file");
2090 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2091 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2092 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2094 /* load section names */
2095 sh
= &shdr
[ehdr
.e_shstrndx
];
2096 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2098 /* load symtab and strtab */
2099 old_to_new_syms
= NULL
;
2103 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2105 if (sh
->sh_type
== SHT_SYMTAB
) {
2107 error_noabort("object must contain only one symtab");
2112 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2113 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2114 sm_table
[i
].s
= symtab_section
;
2116 /* now load strtab */
2117 sh
= &shdr
[sh
->sh_link
];
2118 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2122 /* now examine each section and try to merge its content with the
2124 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2125 /* no need to examine section name strtab */
2126 if (i
== ehdr
.e_shstrndx
)
2129 sh_name
= strsec
+ sh
->sh_name
;
2130 /* ignore sections types we do not handle */
2131 if (sh
->sh_type
!= SHT_PROGBITS
&&
2132 sh
->sh_type
!= SHT_RELX
&&
2134 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2136 sh
->sh_type
!= SHT_NOBITS
&&
2137 strcmp(sh_name
, ".stabstr")
2140 if (sh
->sh_addralign
< 1)
2141 sh
->sh_addralign
= 1;
2142 /* find corresponding section, if any */
2143 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2144 s
= s1
->sections
[j
];
2145 if (!strcmp(s
->name
, sh_name
)) {
2146 if (!strncmp(sh_name
, ".gnu.linkonce",
2147 sizeof(".gnu.linkonce") - 1)) {
2148 /* if a 'linkonce' section is already present, we
2149 do not add it again. It is a little tricky as
2150 symbols can still be defined in
2152 sm_table
[i
].link_once
= 1;
2159 /* not found: create new section */
2160 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2161 /* take as much info as possible from the section. sh_link and
2162 sh_info will be updated later */
2163 s
->sh_addralign
= sh
->sh_addralign
;
2164 s
->sh_entsize
= sh
->sh_entsize
;
2165 sm_table
[i
].new_section
= 1;
2167 if (sh
->sh_type
!= s
->sh_type
) {
2168 error_noabort("invalid section type");
2172 /* align start of section */
2173 offset
= s
->data_offset
;
2175 if (0 == strcmp(sh_name
, ".stab")) {
2179 if (0 == strcmp(sh_name
, ".stabstr")) {
2184 size
= sh
->sh_addralign
- 1;
2185 offset
= (offset
+ size
) & ~size
;
2186 if (sh
->sh_addralign
> s
->sh_addralign
)
2187 s
->sh_addralign
= sh
->sh_addralign
;
2188 s
->data_offset
= offset
;
2190 sm_table
[i
].offset
= offset
;
2192 /* concatenate sections */
2194 if (sh
->sh_type
!= SHT_NOBITS
) {
2196 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2197 ptr
= section_ptr_add(s
, size
);
2198 read(fd
, ptr
, size
);
2200 s
->data_offset
+= size
;
2205 /* //gr relocate stab strings */
2206 if (stab_index
&& stabstr_index
) {
2209 s
= sm_table
[stab_index
].s
;
2210 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2211 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2212 o
= sm_table
[stabstr_index
].offset
;
2214 a
->n_strx
+= o
, a
++;
2217 /* second short pass to update sh_link and sh_info fields of new
2219 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2221 if (!s
|| !sm_table
[i
].new_section
)
2224 if (sh
->sh_link
> 0)
2225 s
->link
= sm_table
[sh
->sh_link
].s
;
2226 if (sh
->sh_type
== SHT_RELX
) {
2227 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2228 /* update backward link */
2229 s1
->sections
[s
->sh_info
]->reloc
= s
;
2234 /* resolve symbols */
2235 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2238 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2239 if (sym
->st_shndx
!= SHN_UNDEF
&&
2240 sym
->st_shndx
< SHN_LORESERVE
) {
2241 sm
= &sm_table
[sym
->st_shndx
];
2242 if (sm
->link_once
) {
2243 /* if a symbol is in a link once section, we use the
2244 already defined symbol. It is very important to get
2245 correct relocations */
2246 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2247 name
= strtab
+ sym
->st_name
;
2248 sym_index
= find_elf_sym(symtab_section
, name
);
2250 old_to_new_syms
[i
] = sym_index
;
2254 /* if no corresponding section added, no need to add symbol */
2257 /* convert section number */
2258 sym
->st_shndx
= sm
->s
->sh_num
;
2260 sym
->st_value
+= sm
->offset
;
2263 name
= strtab
+ sym
->st_name
;
2264 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2265 sym
->st_info
, sym
->st_other
,
2266 sym
->st_shndx
, name
);
2267 old_to_new_syms
[i
] = sym_index
;
2270 /* third pass to patch relocation entries */
2271 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2276 offset
= sm_table
[i
].offset
;
2277 switch(s
->sh_type
) {
2279 /* take relocation offset information */
2280 offseti
= sm_table
[sh
->sh_info
].offset
;
2281 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2282 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2287 /* convert symbol index */
2288 type
= ELFW(R_TYPE
)(rel
->r_info
);
2289 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2290 /* NOTE: only one symtab assumed */
2291 if (sym_index
>= nb_syms
)
2293 sym_index
= old_to_new_syms
[sym_index
];
2294 /* ignore link_once in rel section. */
2295 if (!sym_index
&& !sm
->link_once
) {
2297 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2298 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2301 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2302 /* offset the relocation offset */
2303 rel
->r_offset
+= offseti
;
2315 tcc_free(old_to_new_syms
);
2322 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2324 typedef struct ArchiveHeader
{
2325 char ar_name
[16]; /* name of this member */
2326 char ar_date
[12]; /* file mtime */
2327 char ar_uid
[6]; /* owner uid; printed as decimal */
2328 char ar_gid
[6]; /* owner gid; printed as decimal */
2329 char ar_mode
[8]; /* file mode, printed as octal */
2330 char ar_size
[10]; /* file size, printed as decimal */
2331 char ar_fmag
[2]; /* should contain ARFMAG */
2334 static int get_be32(const uint8_t *b
)
2336 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2339 /* load only the objects which resolve undefined symbols */
2340 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2342 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2344 const char *ar_names
, *p
;
2345 const uint8_t *ar_index
;
2348 data
= tcc_malloc(size
);
2349 if (read(fd
, data
, size
) != size
)
2351 nsyms
= get_be32(data
);
2352 ar_index
= data
+ 4;
2353 ar_names
= ar_index
+ nsyms
* 4;
2357 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2358 sym_index
= find_elf_sym(symtab_section
, p
);
2360 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2361 if(sym
->st_shndx
== SHN_UNDEF
) {
2362 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2364 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2367 lseek(fd
, off
, SEEK_SET
);
2368 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2383 /* load a '.a' file */
2384 static int tcc_load_archive(TCCState
*s1
, int fd
)
2391 unsigned long file_offset
;
2393 /* skip magic which was already checked */
2394 read(fd
, magic
, sizeof(magic
));
2397 len
= read(fd
, &hdr
, sizeof(hdr
));
2400 if (len
!= sizeof(hdr
)) {
2401 error_noabort("invalid archive");
2404 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2405 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2406 size
= strtol(ar_size
, NULL
, 0);
2407 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2408 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2409 if (ar_name
[i
] != ' ')
2412 ar_name
[i
+ 1] = '\0';
2413 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2414 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2416 size
= (size
+ 1) & ~1;
2417 if (!strcmp(ar_name
, "/")) {
2418 /* coff symbol table : we handle it */
2419 if(s1
->alacarte_link
)
2420 return tcc_load_alacarte(s1
, fd
, size
);
2421 } else if (!strcmp(ar_name
, "//") ||
2422 !strcmp(ar_name
, "__.SYMDEF") ||
2423 !strcmp(ar_name
, "__.SYMDEF/") ||
2424 !strcmp(ar_name
, "ARFILENAMES/")) {
2425 /* skip symbol table or archive names */
2427 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2430 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2435 #ifndef TCC_TARGET_PE
2436 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2437 is referenced by the user (so it should be added as DT_NEEDED in
2438 the generated ELF file) */
2439 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2442 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2443 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2444 ElfW(Sym
) *sym
, *dynsym
;
2445 ElfW(Dyn
) *dt
, *dynamic
;
2446 unsigned char *dynstr
;
2447 const char *name
, *soname
;
2448 DLLReference
*dllref
;
2450 read(fd
, &ehdr
, sizeof(ehdr
));
2452 /* test CPU specific stuff */
2453 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2454 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2455 error_noabort("bad architecture");
2460 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2462 /* load dynamic section and dynamic symbols */
2466 dynsym
= NULL
; /* avoid warning */
2467 dynstr
= NULL
; /* avoid warning */
2468 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2469 switch(sh
->sh_type
) {
2471 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2472 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2475 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2476 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2477 sh1
= &shdr
[sh
->sh_link
];
2478 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2485 /* compute the real library name */
2486 soname
= tcc_basename(filename
);
2488 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2489 if (dt
->d_tag
== DT_SONAME
) {
2490 soname
= dynstr
+ dt
->d_un
.d_val
;
2494 /* if the dll is already loaded, do not load it */
2495 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2496 dllref
= s1
->loaded_dlls
[i
];
2497 if (!strcmp(soname
, dllref
->name
)) {
2498 /* but update level if needed */
2499 if (level
< dllref
->level
)
2500 dllref
->level
= level
;
2506 // printf("loading dll '%s'\n", soname);
2508 /* add the dll and its level */
2509 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2510 dllref
->level
= level
;
2511 strcpy(dllref
->name
, soname
);
2512 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2514 /* add dynamic symbols in dynsym_section */
2515 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2516 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2517 if (sym_bind
== STB_LOCAL
)
2519 name
= dynstr
+ sym
->st_name
;
2520 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2521 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2524 /* load all referenced DLLs */
2525 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2528 name
= dynstr
+ dt
->d_un
.d_val
;
2529 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2530 dllref
= s1
->loaded_dlls
[j
];
2531 if (!strcmp(name
, dllref
->name
))
2532 goto already_loaded
;
2534 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2535 error_noabort("referenced dll '%s' not found", name
);
2552 #define LD_TOK_NAME 256
2553 #define LD_TOK_EOF (-1)
2555 /* return next ld script token */
2556 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2574 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2575 ch
= file
->buf_ptr
[0];
2583 /* case 'a' ... 'z': */
2610 /* case 'A' ... 'z': */
2645 if (!((ch
>= 'a' && ch
<= 'z') ||
2646 (ch
>= 'A' && ch
<= 'Z') ||
2647 (ch
>= '0' && ch
<= '9') ||
2648 strchr("/.-_+=$:\\,~", ch
)))
2650 if ((q
- name
) < name_size
- 1) {
2667 printf("tok=%c %d\n", c
, c
);
2668 if (c
== LD_TOK_NAME
)
2669 printf(" name=%s\n", name
);
2674 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2676 char filename
[1024];
2679 t
= ld_next(s1
, filename
, sizeof(filename
));
2682 t
= ld_next(s1
, filename
, sizeof(filename
));
2684 if (t
== LD_TOK_EOF
) {
2685 error_noabort("unexpected end of file");
2687 } else if (t
== ')') {
2689 } else if (t
!= LD_TOK_NAME
) {
2690 error_noabort("filename expected");
2693 if (!strcmp(filename
, "AS_NEEDED")) {
2694 ret
= ld_add_file_list(s1
, 1);
2698 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2700 tcc_add_file(s1
, filename
);
2702 t
= ld_next(s1
, filename
, sizeof(filename
));
2704 t
= ld_next(s1
, filename
, sizeof(filename
));
2710 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2712 static int tcc_load_ldscript(TCCState
*s1
)
2715 char filename
[1024];
2718 ch
= file
->buf_ptr
[0];
2721 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2722 if (t
== LD_TOK_EOF
)
2724 else if (t
!= LD_TOK_NAME
)
2726 if (!strcmp(cmd
, "INPUT") ||
2727 !strcmp(cmd
, "GROUP")) {
2728 ret
= ld_add_file_list(s1
, 0);
2731 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2732 !strcmp(cmd
, "TARGET")) {
2733 /* ignore some commands */
2734 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2738 t
= ld_next(s1
, filename
, sizeof(filename
));
2739 if (t
== LD_TOK_EOF
) {
2740 error_noabort("unexpected end of file");
2742 } else if (t
== ')') {