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
];
595 if (s1
->output_format
!= TCC_OUTPUT_FORMAT_BINARY
) {
597 error("can only produce 16-bit binary files");
599 *(short *)ptr
+= val
;
602 if (s1
->output_format
!= TCC_OUTPUT_FORMAT_BINARY
)
604 *(short *)ptr
+= val
- addr
;
606 #elif defined(TCC_TARGET_ARM)
613 x
= (*(int *)ptr
)&0xffffff;
614 (*(int *)ptr
) &= 0xff000000;
619 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
620 error("can't relocate value at %x",addr
);
629 x
= (*(int *)ptr
) & 0x7fffffff;
630 (*(int *)ptr
) &= 0x80000000;
633 if((x
^(x
>>1))&0x40000000)
634 error("can't relocate value at %x",addr
);
635 (*(int *)ptr
) |= x
& 0x7fffffff;
640 case R_ARM_BASE_PREL
:
641 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
644 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
647 /* we load the got offset */
648 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
653 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
654 type
,addr
,(unsigned int)(long)ptr
,val
);
656 #elif defined(TCC_TARGET_C67)
664 /* put the low 16 bits of the absolute address */
665 // add to what is already there
667 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
668 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
670 //patch both at once - assumes always in pairs Low - High
672 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
673 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
679 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
680 type
,addr
,(unsigned int)(long)ptr
, val
);
682 #elif defined(TCC_TARGET_X86_64)
684 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
685 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
686 qrel
->r_addend
= *(long long *)ptr
+ val
;
689 *(long long *)ptr
+= val
;
693 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
694 /* XXX: this logic may depend on TCC's codegen
695 now TCC uses R_X86_64_32 even for a 64bit pointer */
696 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
697 qrel
->r_addend
= *(int *)ptr
+ val
;
702 case R_X86_64_PC32
: {
704 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
706 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
708 qrel
->r_offset
= rel
->r_offset
;
709 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_X86_64_PC32
);
710 qrel
->r_addend
= *(int *)ptr
;
715 diff
= (long long)val
- addr
;
716 if (diff
<= -2147483647 || diff
> 2147483647) {
717 #ifndef TCC_TARGET_PE
718 /* XXX: naive support for over 32bit jump */
719 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
720 val
= add_jmp_table(s1
, val
);
724 if (diff
<= -2147483647 || diff
> 2147483647) {
725 error("internal error: relocation failed");
732 *(int *)ptr
+= val
- addr
;
734 case R_X86_64_GLOB_DAT
:
735 case R_X86_64_JUMP_SLOT
:
738 case R_X86_64_GOTPCREL
:
739 #ifndef TCC_TARGET_PE
740 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
741 val
= add_got_table(s1
, val
- rel
->r_addend
) + rel
->r_addend
;
742 *(int *)ptr
+= val
- addr
;
746 *(int *)ptr
+= (s1
->got
->sh_addr
- addr
+
747 s1
->got_offsets
[sym_index
] - 4);
749 case R_X86_64_GOTTPOFF
:
750 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
753 /* we load the got offset */
754 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
757 #error unsupported processor
761 /* if the relocation is allocated, we change its symbol table */
762 if (sr
->sh_flags
& SHF_ALLOC
)
763 sr
->link
= s1
->dynsym
;
766 /* relocate relocation table in 'sr' */
767 static void relocate_rel(TCCState
*s1
, Section
*sr
)
770 ElfW_Rel
*rel
, *rel_end
;
772 s
= s1
->sections
[sr
->sh_info
];
773 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
774 for(rel
= (ElfW_Rel
*)sr
->data
;
777 rel
->r_offset
+= s
->sh_addr
;
781 /* count the number of dynamic relocations so that we can reserve
783 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
785 ElfW_Rel
*rel
, *rel_end
;
786 int sym_index
, esym_index
, type
, count
;
789 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
790 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
791 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
792 type
= ELFW(R_TYPE
)(rel
->r_info
);
794 #if defined(TCC_TARGET_I386)
796 #elif defined(TCC_TARGET_X86_64)
803 #if defined(TCC_TARGET_I386)
805 #elif defined(TCC_TARGET_X86_64)
808 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
817 /* allocate the section */
818 sr
->sh_flags
|= SHF_ALLOC
;
819 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
824 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
829 if (index
>= s1
->nb_got_offsets
) {
830 /* find immediately bigger power of 2 and reallocate array */
834 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
836 error("memory full");
837 s1
->got_offsets
= tab
;
838 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
839 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
840 s1
->nb_got_offsets
= n
;
842 s1
->got_offsets
[index
] = val
;
845 /* XXX: suppress that */
846 static void put32(unsigned char *p
, uint32_t val
)
854 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
855 defined(TCC_TARGET_X86_64)
856 static uint32_t get32(unsigned char *p
)
858 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
862 static void build_got(TCCState
*s1
)
866 /* if no got, then create it */
867 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
868 s1
->got
->sh_entsize
= 4;
869 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
870 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
871 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
873 /* keep space for _DYNAMIC pointer, if present */
875 /* two dummy got entries */
879 /* keep space for _DYNAMIC pointer, if present */
882 /* two dummy got entries */
890 /* put a got entry corresponding to a symbol in symtab_section. 'size'
891 and 'info' can be modifed if more precise info comes from the DLL */
892 static void put_got_entry(TCCState
*s1
,
893 int reloc_type
, unsigned long size
, int info
,
899 unsigned long offset
;
905 /* if a got entry already exists for that symbol, no need to add one */
906 if (sym_index
< s1
->nb_got_offsets
&&
907 s1
->got_offsets
[sym_index
] != 0)
910 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
913 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
914 name
= symtab_section
->link
->data
+ sym
->st_name
;
915 offset
= sym
->st_value
;
916 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
918 #ifdef TCC_TARGET_X86_64
928 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
931 /* if we build a DLL, we add a %ebx offset */
932 if (s1
->output_type
== TCC_OUTPUT_DLL
)
938 /* add a PLT entry */
940 if (plt
->data_offset
== 0) {
941 /* first plt entry */
942 p
= section_ptr_add(plt
, 16);
943 p
[0] = 0xff; /* pushl got + PTR_SIZE */
945 put32(p
+ 2, PTR_SIZE
);
946 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
948 put32(p
+ 8, PTR_SIZE
* 2);
951 p
= section_ptr_add(plt
, 16);
952 p
[0] = 0xff; /* jmp *(got + x) */
954 put32(p
+ 2, s1
->got
->data_offset
);
955 p
[6] = 0x68; /* push $xxx */
956 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
957 p
[11] = 0xe9; /* jmp plt_start */
958 put32(p
+ 12, -(plt
->data_offset
));
960 /* the symbol is modified so that it will be relocated to
962 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
963 if (s1
->output_type
== TCC_OUTPUT_EXE
)
965 offset
= plt
->data_offset
- 16;
967 #elif defined(TCC_TARGET_ARM)
968 if (reloc_type
== R_ARM_JUMP_SLOT
) {
972 /* if we build a DLL, we add a %ebx offset */
973 if (s1
->output_type
== TCC_OUTPUT_DLL
)
974 error("DLLs unimplemented!");
976 /* add a PLT entry */
978 if (plt
->data_offset
== 0) {
979 /* first plt entry */
980 p
= section_ptr_add(plt
, 16);
981 put32(p
, 0xe52de004);
982 put32(p
+ 4, 0xe59fe010);
983 put32(p
+ 8, 0xe08fe00e);
984 put32(p
+ 12, 0xe5bef008);
987 p
= section_ptr_add(plt
, 16);
988 put32(p
, 0xe59fc004);
989 put32(p
+4, 0xe08fc00c);
990 put32(p
+8, 0xe59cf000);
991 put32(p
+12, s1
->got
->data_offset
);
993 /* the symbol is modified so that it will be relocated to
995 if (s1
->output_type
== TCC_OUTPUT_EXE
)
996 offset
= plt
->data_offset
- 16;
998 #elif defined(TCC_TARGET_C67)
999 error("C67 got not implemented");
1001 #error unsupported CPU
1003 index
= put_elf_sym(s1
->dynsym
, offset
,
1004 size
, info
, 0, sym
->st_shndx
, name
);
1005 /* put a got entry */
1006 put_elf_reloc(s1
->dynsym
, s1
->got
,
1007 s1
->got
->data_offset
,
1010 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
1014 /* build GOT and PLT entries */
1015 static void build_got_entries(TCCState
*s1
)
1017 Section
*s
, *symtab
;
1018 ElfW_Rel
*rel
, *rel_end
;
1020 int i
, type
, reloc_type
, sym_index
;
1022 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1023 s
= s1
->sections
[i
];
1024 if (s
->sh_type
!= SHT_RELX
)
1026 /* no need to handle got relocations */
1027 if (s
->link
!= symtab_section
)
1030 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
1031 for(rel
= (ElfW_Rel
*)s
->data
;
1034 type
= ELFW(R_TYPE
)(rel
->r_info
);
1036 #if defined(TCC_TARGET_I386)
1043 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1044 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1045 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1046 /* look at the symbol got offset. If none, then add one */
1047 if (type
== R_386_GOT32
)
1048 reloc_type
= R_386_GLOB_DAT
;
1050 reloc_type
= R_386_JMP_SLOT
;
1051 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1055 #elif defined(TCC_TARGET_ARM)
1056 case R_ARM_GOT_BREL
:
1057 case R_ARM_GOTOFF32
:
1058 case R_ARM_BASE_PREL
:
1062 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1063 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1064 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1065 /* look at the symbol got offset. If none, then add one */
1066 if (type
== R_ARM_GOT_BREL
)
1067 reloc_type
= R_ARM_GLOB_DAT
;
1069 reloc_type
= R_ARM_JUMP_SLOT
;
1070 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1074 #elif defined(TCC_TARGET_C67)
1081 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1082 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1083 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1084 /* look at the symbol got offset. If none, then add one */
1085 if (type
== R_C60_GOT32
)
1086 reloc_type
= R_C60_GLOB_DAT
;
1088 reloc_type
= R_C60_JMP_SLOT
;
1089 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1093 #elif defined(TCC_TARGET_X86_64)
1094 case R_X86_64_GOT32
:
1095 case R_X86_64_GOTTPOFF
:
1096 case R_X86_64_GOTPCREL
:
1097 case R_X86_64_PLT32
:
1100 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
||
1101 type
== R_X86_64_PLT32
) {
1102 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1103 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1104 /* look at the symbol got offset. If none, then add one */
1105 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
)
1106 reloc_type
= R_X86_64_GLOB_DAT
;
1108 reloc_type
= R_X86_64_JUMP_SLOT
;
1109 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1114 #error unsupported CPU
1123 static Section
*new_symtab(TCCState
*s1
,
1124 const char *symtab_name
, int sh_type
, int sh_flags
,
1125 const char *strtab_name
,
1126 const char *hash_name
, int hash_sh_flags
)
1128 Section
*symtab
, *strtab
, *hash
;
1129 int *ptr
, nb_buckets
;
1131 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1132 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1133 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1134 put_elf_str(strtab
, "");
1135 symtab
->link
= strtab
;
1136 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1140 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1141 hash
->sh_entsize
= sizeof(int);
1142 symtab
->hash
= hash
;
1143 hash
->link
= symtab
;
1145 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1146 ptr
[0] = nb_buckets
;
1148 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1152 /* put dynamic tag */
1153 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1156 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1158 dyn
->d_un
.d_val
= val
;
1161 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1165 char sym_start
[1024];
1168 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1169 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1171 s
= find_section(s1
, section_name
);
1176 end_offset
= s
->data_offset
;
1179 add_elf_sym(symtab_section
,
1181 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1182 s
->sh_num
, sym_start
);
1183 add_elf_sym(symtab_section
,
1185 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1186 s
->sh_num
, sym_end
);
1189 /* add tcc runtime libraries */
1190 static void tcc_add_runtime(TCCState
*s1
)
1192 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1196 #ifdef CONFIG_TCC_BCHECK
1197 if (s1
->do_bounds_check
) {
1199 Section
*init_section
;
1200 unsigned char *pinit
;
1203 /* XXX: add an object file to do that */
1204 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1206 add_elf_sym(symtab_section
, 0, 0,
1207 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1208 bounds_section
->sh_num
, "__bounds_start");
1209 /* add bound check code */
1210 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "bcheck.o");
1211 tcc_add_file(s1
, buf
);
1212 #ifdef TCC_TARGET_I386
1213 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1214 /* add 'call __bound_init()' in .init section */
1215 init_section
= find_section(s1
, ".init");
1216 pinit
= section_ptr_add(init_section
, 5);
1218 put32(pinit
+ 1, -4);
1219 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1220 put_elf_reloc(symtab_section
, init_section
,
1221 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1227 if (!s1
->nostdlib
) {
1228 tcc_add_library(s1
, "c");
1230 #ifdef CONFIG_USE_LIBGCC
1231 tcc_add_file(s1
, CONFIG_SYSROOT
"/lib/libgcc_s.so.1");
1233 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "libtcc1.a");
1234 tcc_add_file(s1
, buf
);
1237 /* add crt end if not memory output */
1238 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1239 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1243 /* add various standard linker symbols (must be done after the
1244 sections are filled (for example after allocating common
1246 static void tcc_add_linker_symbols(TCCState
*s1
)
1252 add_elf_sym(symtab_section
,
1253 text_section
->data_offset
, 0,
1254 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1255 text_section
->sh_num
, "_etext");
1256 add_elf_sym(symtab_section
,
1257 data_section
->data_offset
, 0,
1258 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1259 data_section
->sh_num
, "_edata");
1260 add_elf_sym(symtab_section
,
1261 bss_section
->data_offset
, 0,
1262 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1263 bss_section
->sh_num
, "_end");
1264 /* horrible new standard ldscript defines */
1265 add_init_array_defines(s1
, ".preinit_array");
1266 add_init_array_defines(s1
, ".init_array");
1267 add_init_array_defines(s1
, ".fini_array");
1269 /* add start and stop symbols for sections whose name can be
1271 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1272 s
= s1
->sections
[i
];
1273 if (s
->sh_type
== SHT_PROGBITS
&&
1274 (s
->sh_flags
& SHF_ALLOC
)) {
1278 /* check if section name can be expressed in C */
1284 if (!isid(ch
) && !isnum(ch
))
1288 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1289 add_elf_sym(symtab_section
,
1291 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1293 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1294 add_elf_sym(symtab_section
,
1296 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1303 /* name of ELF interpreter */
1304 #if defined __FreeBSD__
1305 static const char elf_interp
[] = "/usr/libexec/ld-elf.so.1";
1306 #elif defined TCC_ARM_EABI
1307 static const char elf_interp
[] = "/lib/ld-linux.so.3";
1308 #elif defined(TCC_TARGET_X86_64)
1309 static const char elf_interp
[] = "/lib/ld-linux-x86-64.so.2";
1310 #elif defined(TCC_UCLIBC)
1311 static const char elf_interp
[] = "/lib/ld-uClibc.so.0";
1313 static const char elf_interp
[] = "/lib/ld-linux.so.2";
1316 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1317 const int *section_order
)
1320 int i
, offset
, size
;
1323 for(i
=1;i
<s1
->nb_sections
;i
++) {
1324 s
= s1
->sections
[section_order
[i
]];
1325 if (s
->sh_type
!= SHT_NOBITS
&&
1326 (s
->sh_flags
& SHF_ALLOC
)) {
1327 while (offset
< s
->sh_offset
) {
1332 fwrite(s
->data
, 1, size
, f
);
1338 /* output an ELF file */
1339 /* XXX: suppress unneeded sections */
1340 int elf_output_file(TCCState
*s1
, const char *filename
)
1346 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1348 Section
*strsec
, *s
;
1349 ElfW(Shdr
) shdr
, *sh
;
1350 ElfW(Phdr
) *phdr
, *ph
;
1351 Section
*interp
, *dynamic
, *dynstr
;
1352 unsigned long saved_dynamic_data_offset
;
1354 int type
, file_type
;
1355 unsigned long rel_addr
, rel_size
;
1357 file_type
= s1
->output_type
;
1360 if ((file_type
!= TCC_OUTPUT_OBJ
) && (s1
->output_type
!= TCC_OUTPUT_FORMAT_BINARY
)) {
1361 tcc_add_runtime(s1
);
1365 section_order
= NULL
;
1368 dynstr
= NULL
; /* avoid warning */
1369 saved_dynamic_data_offset
= 0; /* avoid warning */
1371 if (file_type
!= TCC_OUTPUT_OBJ
) {
1372 relocate_common_syms();
1374 if (s1
->output_type
!= TCC_OUTPUT_FORMAT_BINARY
)
1375 tcc_add_linker_symbols(s1
);
1377 if ((!s1
->static_link
) && (s1
->output_type
!= TCC_OUTPUT_FORMAT_BINARY
)) {
1379 int sym_index
, index
;
1380 ElfW(Sym
) *esym
, *sym_end
;
1382 if ((file_type
== TCC_OUTPUT_EXE
) && (s1
->output_type
!= TCC_OUTPUT_FORMAT_BINARY
)) {
1384 /* add interpreter section only if executable */
1385 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1386 interp
->sh_addralign
= 1;
1387 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
1388 strcpy(ptr
, elf_interp
);
1391 /* add dynamic symbol table */
1392 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1394 ".hash", SHF_ALLOC
);
1395 dynstr
= s1
->dynsym
->link
;
1397 /* add dynamic section */
1398 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1399 SHF_ALLOC
| SHF_WRITE
);
1400 dynamic
->link
= dynstr
;
1401 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1404 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1405 SHF_ALLOC
| SHF_EXECINSTR
);
1406 s1
->plt
->sh_entsize
= 4;
1410 /* scan for undefined symbols and see if they are in the
1411 dynamic symbols. If a symbol STT_FUNC is found, then we
1412 add it in the PLT. If a symbol STT_OBJECT is found, we
1413 add it in the .bss section with a suitable relocation */
1414 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1415 symtab_section
->data_offset
);
1416 if (file_type
== TCC_OUTPUT_EXE
) {
1417 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1420 if (sym
->st_shndx
== SHN_UNDEF
) {
1421 name
= symtab_section
->link
->data
+ sym
->st_name
;
1422 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1424 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1425 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1426 if (type
== STT_FUNC
) {
1427 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1429 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1430 } else if (type
== STT_OBJECT
) {
1431 unsigned long offset
;
1432 offset
= bss_section
->data_offset
;
1433 /* XXX: which alignment ? */
1434 offset
= (offset
+ 16 - 1) & -16;
1435 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1437 bss_section
->sh_num
, name
);
1438 put_elf_reloc(s1
->dynsym
, bss_section
,
1439 offset
, R_COPY
, index
);
1440 offset
+= esym
->st_size
;
1441 bss_section
->data_offset
= offset
;
1444 /* STB_WEAK undefined symbols are accepted */
1445 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1447 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1448 !strcmp(name
, "_fp_hw")) {
1450 error_noabort("undefined symbol '%s'", name
);
1453 } else if (s1
->rdynamic
&&
1454 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1455 /* if -rdynamic option, then export all non
1457 name
= symtab_section
->link
->data
+ sym
->st_name
;
1458 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1460 sym
->st_shndx
, name
);
1467 /* now look at unresolved dynamic symbols and export
1468 corresponding symbol */
1469 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1470 s1
->dynsymtab_section
->data_offset
);
1471 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1474 if (esym
->st_shndx
== SHN_UNDEF
) {
1475 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1476 sym_index
= find_elf_sym(symtab_section
, name
);
1478 /* XXX: avoid adding a symbol if already
1479 present because of -rdynamic ? */
1480 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1481 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1483 sym
->st_shndx
, name
);
1485 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1486 /* weak symbols can stay undefined */
1488 warning("undefined dynamic symbol '%s'", name
);
1495 /* shared library case : we simply export all the global symbols */
1496 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1497 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1498 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1501 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1502 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1503 if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
&&
1504 sym
->st_shndx
== SHN_UNDEF
) {
1505 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1507 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1509 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1510 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1512 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1517 name
= symtab_section
->link
->data
+ sym
->st_name
;
1518 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1520 sym
->st_shndx
, name
);
1521 s1
->symtab_to_dynsym
[sym
-
1522 (ElfW(Sym
) *)symtab_section
->data
] =
1529 build_got_entries(s1
);
1531 /* add a list of needed dlls */
1532 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1533 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1534 if (dllref
->level
== 0)
1535 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1537 /* XXX: currently, since we do not handle PIC code, we
1538 must relocate the readonly segments */
1539 if (file_type
== TCC_OUTPUT_DLL
) {
1541 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1542 put_dt(dynamic
, DT_TEXTREL
, 0);
1545 /* add necessary space for other entries */
1546 saved_dynamic_data_offset
= dynamic
->data_offset
;
1547 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * 9;
1549 /* still need to build got entries in case of static link */
1550 build_got_entries(s1
);
1554 memset(&ehdr
, 0, sizeof(ehdr
));
1556 /* we add a section for symbols */
1557 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1558 put_elf_str(strsec
, "");
1560 /* compute number of sections */
1561 shnum
= s1
->nb_sections
;
1563 /* this array is used to reorder sections in the output file */
1564 section_order
= tcc_malloc(sizeof(int) * shnum
);
1565 section_order
[0] = 0;
1568 /* compute number of program headers */
1571 case TCC_OUTPUT_OBJ
:
1574 case TCC_OUTPUT_EXE
:
1575 if (!s1
->static_link
)
1580 case TCC_OUTPUT_DLL
:
1585 /* allocate strings for section names and decide if an unallocated
1586 section should be output */
1587 /* NOTE: the strsec section comes last, so its size is also
1589 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1590 s
= s1
->sections
[i
];
1591 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1593 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1598 s
->reloc
? s
->reloc
->name
: "n"
1601 /* when generating a DLL, we include relocations but we may
1603 if (file_type
== TCC_OUTPUT_DLL
&&
1604 s
->sh_type
== SHT_RELX
&&
1605 !(s
->sh_flags
& SHF_ALLOC
)) {
1606 /* //gr: avoid bogus relocs for empty (debug) sections */
1607 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1608 prepare_dynamic_rel(s1
, s
);
1609 else if (s1
->do_debug
)
1610 s
->sh_size
= s
->data_offset
;
1611 } else if (s1
->do_debug
||
1612 file_type
== TCC_OUTPUT_OBJ
||
1613 (s
->sh_flags
& SHF_ALLOC
) ||
1614 i
== (s1
->nb_sections
- 1)) {
1615 /* we output all sections if debug or object file */
1616 s
->sh_size
= s
->data_offset
;
1620 /* allocate program segment headers */
1621 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1623 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1624 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1629 /* compute section to program header mapping */
1630 if (s1
->has_text_addr
) {
1631 int a_offset
, p_offset
;
1632 addr
= s1
->text_addr
;
1633 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1635 a_offset
= addr
& (s1
->section_align
- 1);
1636 p_offset
= file_offset
& (s1
->section_align
- 1);
1637 if (a_offset
< p_offset
)
1638 a_offset
+= s1
->section_align
;
1639 file_offset
+= (a_offset
- p_offset
);
1641 if (file_type
== TCC_OUTPUT_DLL
)
1644 addr
= ELF_START_ADDR
;
1645 /* compute address after headers */
1646 addr
+= (file_offset
& (s1
->section_align
- 1));
1649 /* dynamic relocation table information, for .dynamic section */
1653 /* leave one program header for the program interpreter */
1658 for(j
= 0; j
< 2; j
++) {
1659 ph
->p_type
= PT_LOAD
;
1661 ph
->p_flags
= PF_R
| PF_X
;
1663 ph
->p_flags
= PF_R
| PF_W
;
1664 ph
->p_align
= s1
->section_align
;
1666 /* we do the following ordering: interp, symbol tables,
1667 relocations, progbits, nobits */
1668 /* XXX: do faster and simpler sorting */
1669 for(k
= 0; k
< 5; k
++) {
1670 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1671 s
= s1
->sections
[i
];
1672 /* compute if section should be included */
1674 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1678 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1679 (SHF_ALLOC
| SHF_WRITE
))
1685 } else if (s
->sh_type
== SHT_DYNSYM
||
1686 s
->sh_type
== SHT_STRTAB
||
1687 s
->sh_type
== SHT_HASH
) {
1690 } else if (s
->sh_type
== SHT_RELX
) {
1693 } else if (s
->sh_type
== SHT_NOBITS
) {
1700 section_order
[sh_order_index
++] = i
;
1702 /* section matches: we align it and add its size */
1704 addr
= (addr
+ s
->sh_addralign
- 1) &
1705 ~(s
->sh_addralign
- 1);
1706 file_offset
+= addr
- tmp
;
1707 s
->sh_offset
= file_offset
;
1710 /* update program header infos */
1711 if (ph
->p_offset
== 0) {
1712 ph
->p_offset
= file_offset
;
1714 ph
->p_paddr
= ph
->p_vaddr
;
1716 /* update dynamic relocation infos */
1717 if (s
->sh_type
== SHT_RELX
) {
1720 rel_size
+= s
->sh_size
;
1723 if (s
->sh_type
!= SHT_NOBITS
)
1724 file_offset
+= s
->sh_size
;
1727 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1728 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1731 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1732 /* if in the middle of a page, we duplicate the page in
1733 memory so that one copy is RX and the other is RW */
1734 if ((addr
& (s1
->section_align
- 1)) != 0)
1735 addr
+= s1
->section_align
;
1737 addr
= (addr
+ s1
->section_align
- 1) & ~(s1
->section_align
- 1);
1738 file_offset
= (file_offset
+ s1
->section_align
- 1) &
1739 ~(s1
->section_align
- 1);
1744 /* if interpreter, then add corresponing program header */
1748 ph
->p_type
= PT_INTERP
;
1749 ph
->p_offset
= interp
->sh_offset
;
1750 ph
->p_vaddr
= interp
->sh_addr
;
1751 ph
->p_paddr
= ph
->p_vaddr
;
1752 ph
->p_filesz
= interp
->sh_size
;
1753 ph
->p_memsz
= interp
->sh_size
;
1755 ph
->p_align
= interp
->sh_addralign
;
1758 /* if dynamic section, then add corresponing program header */
1762 ph
= &phdr
[phnum
- 1];
1764 ph
->p_type
= PT_DYNAMIC
;
1765 ph
->p_offset
= dynamic
->sh_offset
;
1766 ph
->p_vaddr
= dynamic
->sh_addr
;
1767 ph
->p_paddr
= ph
->p_vaddr
;
1768 ph
->p_filesz
= dynamic
->sh_size
;
1769 ph
->p_memsz
= dynamic
->sh_size
;
1770 ph
->p_flags
= PF_R
| PF_W
;
1771 ph
->p_align
= dynamic
->sh_addralign
;
1773 /* put GOT dynamic section address */
1774 put32(s1
->got
->data
, dynamic
->sh_addr
);
1776 /* relocate the PLT */
1777 if (file_type
== TCC_OUTPUT_EXE
1778 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1779 || file_type
== TCC_OUTPUT_DLL
1785 p_end
= p
+ s1
->plt
->data_offset
;
1787 #if defined(TCC_TARGET_I386)
1788 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1789 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1792 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1795 #elif defined(TCC_TARGET_X86_64)
1796 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
1797 put32(p
+ 2, get32(p
+ 2) + x
);
1798 put32(p
+ 8, get32(p
+ 8) + x
- 6);
1801 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
1804 #elif defined(TCC_TARGET_ARM)
1806 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1809 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1812 #elif defined(TCC_TARGET_C67)
1815 #error unsupported CPU
1820 /* relocate symbols in .dynsym */
1821 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1822 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1825 if (sym
->st_shndx
== SHN_UNDEF
) {
1826 /* relocate to the PLT if the symbol corresponds
1829 sym
->st_value
+= s1
->plt
->sh_addr
;
1830 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1831 /* do symbol relocation */
1832 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1836 /* put dynamic section entries */
1837 dynamic
->data_offset
= saved_dynamic_data_offset
;
1838 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1839 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1840 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1841 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1842 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1843 #ifdef TCC_TARGET_X86_64
1844 put_dt(dynamic
, DT_RELA
, rel_addr
);
1845 put_dt(dynamic
, DT_RELASZ
, rel_size
);
1846 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
1848 put_dt(dynamic
, DT_REL
, rel_addr
);
1849 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1850 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1853 put_dt(dynamic
, DT_DEBUG
, 0);
1854 put_dt(dynamic
, DT_NULL
, 0);
1857 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1858 ehdr
.e_phnum
= phnum
;
1859 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1862 /* all other sections come after */
1863 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1864 s
= s1
->sections
[i
];
1865 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1867 section_order
[sh_order_index
++] = i
;
1869 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1870 ~(s
->sh_addralign
- 1);
1871 s
->sh_offset
= file_offset
;
1872 if (s
->sh_type
!= SHT_NOBITS
)
1873 file_offset
+= s
->sh_size
;
1876 /* if building executable or DLL, then relocate each section
1877 except the GOT which is already relocated */
1878 if (file_type
!= TCC_OUTPUT_OBJ
) {
1879 relocate_syms(s1
, 0);
1881 if (s1
->nb_errors
!= 0) {
1887 /* relocate sections */
1888 /* XXX: ignore sections with allocated relocations ? */
1889 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1890 s
= s1
->sections
[i
];
1891 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1892 relocate_section(s1
, s
);
1895 /* relocate relocation entries if the relocation tables are
1896 allocated in the executable */
1897 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1898 s
= s1
->sections
[i
];
1899 if ((s
->sh_flags
& SHF_ALLOC
) &&
1900 s
->sh_type
== SHT_RELX
) {
1901 relocate_rel(s1
, s
);
1905 /* get entry point address */
1906 if (file_type
== TCC_OUTPUT_EXE
)
1907 ehdr
.e_entry
= (uplong
)tcc_get_symbol_err(s1
, "_start");
1909 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1912 /* write elf file */
1913 if (file_type
== TCC_OUTPUT_OBJ
)
1917 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1919 error_noabort("could not write '%s'", filename
);
1922 f
= fdopen(fd
, "wb");
1924 printf("<- %s\n", filename
);
1926 #ifdef TCC_TARGET_COFF
1927 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1928 tcc_output_coff(s1
, f
);
1931 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1932 sort_syms(s1
, symtab_section
);
1935 file_offset
= (file_offset
+ 3) & -4;
1938 ehdr
.e_ident
[0] = ELFMAG0
;
1939 ehdr
.e_ident
[1] = ELFMAG1
;
1940 ehdr
.e_ident
[2] = ELFMAG2
;
1941 ehdr
.e_ident
[3] = ELFMAG3
;
1942 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
1943 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1944 ehdr
.e_ident
[6] = EV_CURRENT
;
1946 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1948 #ifdef TCC_TARGET_ARM
1950 ehdr
.e_ident
[EI_OSABI
] = 0;
1951 ehdr
.e_flags
= 4 << 24;
1953 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
1958 case TCC_OUTPUT_EXE
:
1959 ehdr
.e_type
= ET_EXEC
;
1961 case TCC_OUTPUT_DLL
:
1962 ehdr
.e_type
= ET_DYN
;
1964 case TCC_OUTPUT_OBJ
:
1965 ehdr
.e_type
= ET_REL
;
1968 ehdr
.e_machine
= EM_TCC_TARGET
;
1969 ehdr
.e_version
= EV_CURRENT
;
1970 ehdr
.e_shoff
= file_offset
;
1971 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
1972 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
1973 ehdr
.e_shnum
= shnum
;
1974 ehdr
.e_shstrndx
= shnum
- 1;
1976 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
1977 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
1978 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1980 for(i
=1;i
<s1
->nb_sections
;i
++) {
1981 s
= s1
->sections
[section_order
[i
]];
1982 if (s
->sh_type
!= SHT_NOBITS
) {
1983 while (offset
< s
->sh_offset
) {
1988 fwrite(s
->data
, 1, size
, f
);
1993 /* output section headers */
1994 while (offset
< ehdr
.e_shoff
) {
1999 for(i
=0;i
<s1
->nb_sections
;i
++) {
2001 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2002 s
= s1
->sections
[i
];
2004 sh
->sh_name
= s
->sh_name
;
2005 sh
->sh_type
= s
->sh_type
;
2006 sh
->sh_flags
= s
->sh_flags
;
2007 sh
->sh_entsize
= s
->sh_entsize
;
2008 sh
->sh_info
= s
->sh_info
;
2010 sh
->sh_link
= s
->link
->sh_num
;
2011 sh
->sh_addralign
= s
->sh_addralign
;
2012 sh
->sh_addr
= s
->sh_addr
;
2013 sh
->sh_offset
= s
->sh_offset
;
2014 sh
->sh_size
= s
->sh_size
;
2016 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2019 tcc_output_binary(s1
, f
, section_order
);
2025 tcc_free(s1
->symtab_to_dynsym
);
2026 tcc_free(section_order
);
2028 tcc_free(s1
->got_offsets
);
2032 int tcc_output_file(TCCState
*s
, const char *filename
)
2035 #ifdef TCC_TARGET_PE
2036 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2037 ret
= pe_output_file(s
, filename
);
2041 ret
= elf_output_file(s
, filename
);
2046 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2050 data
= tcc_malloc(size
);
2051 lseek(fd
, file_offset
, SEEK_SET
);
2052 read(fd
, data
, size
);
2056 typedef struct SectionMergeInfo
{
2057 Section
*s
; /* corresponding existing section */
2058 unsigned long offset
; /* offset of the new section in the existing section */
2059 uint8_t new_section
; /* true if section 's' was added */
2060 uint8_t link_once
; /* true if link once section */
2063 /* load an object file and merge it with current files */
2064 /* XXX: handle correctly stab (debug) info */
2065 static int tcc_load_object_file(TCCState
*s1
,
2066 int fd
, unsigned long file_offset
)
2069 ElfW(Shdr
) *shdr
, *sh
;
2070 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2071 unsigned char *strsec
, *strtab
;
2072 int *old_to_new_syms
;
2073 char *sh_name
, *name
;
2074 SectionMergeInfo
*sm_table
, *sm
;
2075 ElfW(Sym
) *sym
, *symtab
;
2076 ElfW_Rel
*rel
, *rel_end
;
2082 stab_index
= stabstr_index
= 0;
2084 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2086 if (ehdr
.e_ident
[0] != ELFMAG0
||
2087 ehdr
.e_ident
[1] != ELFMAG1
||
2088 ehdr
.e_ident
[2] != ELFMAG2
||
2089 ehdr
.e_ident
[3] != ELFMAG3
)
2091 /* test if object file */
2092 if (ehdr
.e_type
!= ET_REL
)
2094 /* test CPU specific stuff */
2095 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2096 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2098 error_noabort("invalid object file");
2102 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2103 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2104 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2106 /* load section names */
2107 sh
= &shdr
[ehdr
.e_shstrndx
];
2108 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2110 /* load symtab and strtab */
2111 old_to_new_syms
= NULL
;
2115 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2117 if (sh
->sh_type
== SHT_SYMTAB
) {
2119 error_noabort("object must contain only one symtab");
2124 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2125 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2126 sm_table
[i
].s
= symtab_section
;
2128 /* now load strtab */
2129 sh
= &shdr
[sh
->sh_link
];
2130 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2134 /* now examine each section and try to merge its content with the
2136 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2137 /* no need to examine section name strtab */
2138 if (i
== ehdr
.e_shstrndx
)
2141 sh_name
= strsec
+ sh
->sh_name
;
2142 /* ignore sections types we do not handle */
2143 if (sh
->sh_type
!= SHT_PROGBITS
&&
2144 sh
->sh_type
!= SHT_RELX
&&
2146 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2148 sh
->sh_type
!= SHT_NOBITS
&&
2149 strcmp(sh_name
, ".stabstr")
2152 if (sh
->sh_addralign
< 1)
2153 sh
->sh_addralign
= 1;
2154 /* find corresponding section, if any */
2155 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2156 s
= s1
->sections
[j
];
2157 if (!strcmp(s
->name
, sh_name
)) {
2158 if (!strncmp(sh_name
, ".gnu.linkonce",
2159 sizeof(".gnu.linkonce") - 1)) {
2160 /* if a 'linkonce' section is already present, we
2161 do not add it again. It is a little tricky as
2162 symbols can still be defined in
2164 sm_table
[i
].link_once
= 1;
2171 /* not found: create new section */
2172 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2173 /* take as much info as possible from the section. sh_link and
2174 sh_info will be updated later */
2175 s
->sh_addralign
= sh
->sh_addralign
;
2176 s
->sh_entsize
= sh
->sh_entsize
;
2177 sm_table
[i
].new_section
= 1;
2179 if (sh
->sh_type
!= s
->sh_type
) {
2180 error_noabort("invalid section type");
2184 /* align start of section */
2185 offset
= s
->data_offset
;
2187 if (0 == strcmp(sh_name
, ".stab")) {
2191 if (0 == strcmp(sh_name
, ".stabstr")) {
2196 size
= sh
->sh_addralign
- 1;
2197 offset
= (offset
+ size
) & ~size
;
2198 if (sh
->sh_addralign
> s
->sh_addralign
)
2199 s
->sh_addralign
= sh
->sh_addralign
;
2200 s
->data_offset
= offset
;
2202 sm_table
[i
].offset
= offset
;
2204 /* concatenate sections */
2206 if (sh
->sh_type
!= SHT_NOBITS
) {
2208 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2209 ptr
= section_ptr_add(s
, size
);
2210 read(fd
, ptr
, size
);
2212 s
->data_offset
+= size
;
2217 /* //gr relocate stab strings */
2218 if (stab_index
&& stabstr_index
) {
2221 s
= sm_table
[stab_index
].s
;
2222 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2223 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2224 o
= sm_table
[stabstr_index
].offset
;
2226 a
->n_strx
+= o
, a
++;
2229 /* second short pass to update sh_link and sh_info fields of new
2231 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2233 if (!s
|| !sm_table
[i
].new_section
)
2236 if (sh
->sh_link
> 0)
2237 s
->link
= sm_table
[sh
->sh_link
].s
;
2238 if (sh
->sh_type
== SHT_RELX
) {
2239 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2240 /* update backward link */
2241 s1
->sections
[s
->sh_info
]->reloc
= s
;
2246 /* resolve symbols */
2247 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2250 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2251 if (sym
->st_shndx
!= SHN_UNDEF
&&
2252 sym
->st_shndx
< SHN_LORESERVE
) {
2253 sm
= &sm_table
[sym
->st_shndx
];
2254 if (sm
->link_once
) {
2255 /* if a symbol is in a link once section, we use the
2256 already defined symbol. It is very important to get
2257 correct relocations */
2258 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2259 name
= strtab
+ sym
->st_name
;
2260 sym_index
= find_elf_sym(symtab_section
, name
);
2262 old_to_new_syms
[i
] = sym_index
;
2266 /* if no corresponding section added, no need to add symbol */
2269 /* convert section number */
2270 sym
->st_shndx
= sm
->s
->sh_num
;
2272 sym
->st_value
+= sm
->offset
;
2275 name
= strtab
+ sym
->st_name
;
2276 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2277 sym
->st_info
, sym
->st_other
,
2278 sym
->st_shndx
, name
);
2279 old_to_new_syms
[i
] = sym_index
;
2282 /* third pass to patch relocation entries */
2283 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2288 offset
= sm_table
[i
].offset
;
2289 switch(s
->sh_type
) {
2291 /* take relocation offset information */
2292 offseti
= sm_table
[sh
->sh_info
].offset
;
2293 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2294 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2299 /* convert symbol index */
2300 type
= ELFW(R_TYPE
)(rel
->r_info
);
2301 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2302 /* NOTE: only one symtab assumed */
2303 if (sym_index
>= nb_syms
)
2305 sym_index
= old_to_new_syms
[sym_index
];
2306 /* ignore link_once in rel section. */
2307 if (!sym_index
&& !sm
->link_once
) {
2309 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2310 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2313 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2314 /* offset the relocation offset */
2315 rel
->r_offset
+= offseti
;
2327 tcc_free(old_to_new_syms
);
2334 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2336 typedef struct ArchiveHeader
{
2337 char ar_name
[16]; /* name of this member */
2338 char ar_date
[12]; /* file mtime */
2339 char ar_uid
[6]; /* owner uid; printed as decimal */
2340 char ar_gid
[6]; /* owner gid; printed as decimal */
2341 char ar_mode
[8]; /* file mode, printed as octal */
2342 char ar_size
[10]; /* file size, printed as decimal */
2343 char ar_fmag
[2]; /* should contain ARFMAG */
2346 static int get_be32(const uint8_t *b
)
2348 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2351 /* load only the objects which resolve undefined symbols */
2352 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2354 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2356 const char *ar_names
, *p
;
2357 const uint8_t *ar_index
;
2360 data
= tcc_malloc(size
);
2361 if (read(fd
, data
, size
) != size
)
2363 nsyms
= get_be32(data
);
2364 ar_index
= data
+ 4;
2365 ar_names
= ar_index
+ nsyms
* 4;
2369 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2370 sym_index
= find_elf_sym(symtab_section
, p
);
2372 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2373 if(sym
->st_shndx
== SHN_UNDEF
) {
2374 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2376 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2379 lseek(fd
, off
, SEEK_SET
);
2380 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2395 /* load a '.a' file */
2396 static int tcc_load_archive(TCCState
*s1
, int fd
)
2403 unsigned long file_offset
;
2405 /* skip magic which was already checked */
2406 read(fd
, magic
, sizeof(magic
));
2409 len
= read(fd
, &hdr
, sizeof(hdr
));
2412 if (len
!= sizeof(hdr
)) {
2413 error_noabort("invalid archive");
2416 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2417 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2418 size
= strtol(ar_size
, NULL
, 0);
2419 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2420 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2421 if (ar_name
[i
] != ' ')
2424 ar_name
[i
+ 1] = '\0';
2425 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2426 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2428 size
= (size
+ 1) & ~1;
2429 if (!strcmp(ar_name
, "/")) {
2430 /* coff symbol table : we handle it */
2431 if(s1
->alacarte_link
)
2432 return tcc_load_alacarte(s1
, fd
, size
);
2433 } else if (!strcmp(ar_name
, "//") ||
2434 !strcmp(ar_name
, "__.SYMDEF") ||
2435 !strcmp(ar_name
, "__.SYMDEF/") ||
2436 !strcmp(ar_name
, "ARFILENAMES/")) {
2437 /* skip symbol table or archive names */
2439 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2442 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2447 #ifndef TCC_TARGET_PE
2448 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2449 is referenced by the user (so it should be added as DT_NEEDED in
2450 the generated ELF file) */
2451 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2454 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2455 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2456 ElfW(Sym
) *sym
, *dynsym
;
2457 ElfW(Dyn
) *dt
, *dynamic
;
2458 unsigned char *dynstr
;
2459 const char *name
, *soname
;
2460 DLLReference
*dllref
;
2462 read(fd
, &ehdr
, sizeof(ehdr
));
2464 /* test CPU specific stuff */
2465 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2466 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2467 error_noabort("bad architecture");
2472 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2474 /* load dynamic section and dynamic symbols */
2478 dynsym
= NULL
; /* avoid warning */
2479 dynstr
= NULL
; /* avoid warning */
2480 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2481 switch(sh
->sh_type
) {
2483 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2484 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2487 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2488 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2489 sh1
= &shdr
[sh
->sh_link
];
2490 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2497 /* compute the real library name */
2498 soname
= tcc_basename(filename
);
2500 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2501 if (dt
->d_tag
== DT_SONAME
) {
2502 soname
= dynstr
+ dt
->d_un
.d_val
;
2506 /* if the dll is already loaded, do not load it */
2507 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2508 dllref
= s1
->loaded_dlls
[i
];
2509 if (!strcmp(soname
, dllref
->name
)) {
2510 /* but update level if needed */
2511 if (level
< dllref
->level
)
2512 dllref
->level
= level
;
2518 // printf("loading dll '%s'\n", soname);
2520 /* add the dll and its level */
2521 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2522 dllref
->level
= level
;
2523 strcpy(dllref
->name
, soname
);
2524 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2526 /* add dynamic symbols in dynsym_section */
2527 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2528 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2529 if (sym_bind
== STB_LOCAL
)
2531 name
= dynstr
+ sym
->st_name
;
2532 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2533 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2536 /* load all referenced DLLs */
2537 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2540 name
= dynstr
+ dt
->d_un
.d_val
;
2541 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2542 dllref
= s1
->loaded_dlls
[j
];
2543 if (!strcmp(name
, dllref
->name
))
2544 goto already_loaded
;
2546 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2547 error_noabort("referenced dll '%s' not found", name
);
2564 #define LD_TOK_NAME 256
2565 #define LD_TOK_EOF (-1)
2567 /* return next ld script token */
2568 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2586 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2587 ch
= file
->buf_ptr
[0];
2595 /* case 'a' ... 'z': */
2622 /* case 'A' ... 'z': */
2657 if (!((ch
>= 'a' && ch
<= 'z') ||
2658 (ch
>= 'A' && ch
<= 'Z') ||
2659 (ch
>= '0' && ch
<= '9') ||
2660 strchr("/.-_+=$:\\,~", ch
)))
2662 if ((q
- name
) < name_size
- 1) {
2679 printf("tok=%c %d\n", c
, c
);
2680 if (c
== LD_TOK_NAME
)
2681 printf(" name=%s\n", name
);
2686 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2688 char filename
[1024];
2691 t
= ld_next(s1
, filename
, sizeof(filename
));
2694 t
= ld_next(s1
, filename
, sizeof(filename
));
2696 if (t
== LD_TOK_EOF
) {
2697 error_noabort("unexpected end of file");
2699 } else if (t
== ')') {
2701 } else if (t
!= LD_TOK_NAME
) {
2702 error_noabort("filename expected");
2705 if (!strcmp(filename
, "AS_NEEDED")) {
2706 ret
= ld_add_file_list(s1
, 1);
2710 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2712 tcc_add_file(s1
, filename
);
2714 t
= ld_next(s1
, filename
, sizeof(filename
));
2716 t
= ld_next(s1
, filename
, sizeof(filename
));
2722 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2724 static int tcc_load_ldscript(TCCState
*s1
)
2727 char filename
[1024];
2730 ch
= file
->buf_ptr
[0];
2733 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2734 if (t
== LD_TOK_EOF
)
2736 else if (t
!= LD_TOK_NAME
)
2738 if (!strcmp(cmd
, "INPUT") ||
2739 !strcmp(cmd
, "GROUP")) {
2740 ret
= ld_add_file_list(s1
, 0);
2743 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2744 !strcmp(cmd
, "TARGET")) {
2745 /* ignore some commands */
2746 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2750 t
= ld_next(s1
, filename
, sizeof(filename
));
2751 if (t
== LD_TOK_EOF
) {
2752 error_noabort("unexpected end of file");
2754 } else if (t
== ')') {