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
22 #ifdef TCC_TARGET_X86_64
23 #define ElfW_Rel ElfW(Rela)
24 #define SHT_RELX SHT_RELA
25 #define REL_SECTION_FMT ".rela%s"
26 /* x86-64 requires PLT for DLLs */
27 #define TCC_OUTPUT_DLL_WITH_PLT
29 #define ElfW_Rel ElfW(Rel)
30 #define SHT_RELX SHT_REL
31 #define REL_SECTION_FMT ".rel%s"
34 void put_extern_sym(Sym
*sym
, Section
*section
,
35 unsigned long value
, unsigned long size
)
37 put_extern_sym2(sym
, section
, value
, size
, 1);
41 /* XXX: DLL with PLT would only work with x86-64 for now */
42 //#define TCC_OUTPUT_DLL_WITH_PLT
44 int put_elf_str(Section
*s
, const char *sym
)
49 len
= strlen(sym
) + 1;
50 offset
= s
->data_offset
;
51 ptr
= section_ptr_add(s
, len
);
52 memcpy(ptr
, sym
, len
);
57 Section
*new_section(TCCState
*s1
, const char *name
, int sh_type
, int sh_flags
)
61 sec
= tcc_mallocz(sizeof(Section
) + strlen(name
));
62 strcpy(sec
->name
, name
);
63 sec
->sh_type
= sh_type
;
64 sec
->sh_flags
= sh_flags
;
72 sec
->sh_addralign
= 4;
75 sec
->sh_addralign
= 1;
78 sec
->sh_addralign
= 32; /* default conservative alignment */
82 if (sh_flags
& SHF_PRIVATE
) {
83 dynarray_add((void ***)&s1
->priv_sections
, &s1
->nb_priv_sections
, sec
);
85 sec
->sh_num
= s1
->nb_sections
;
86 dynarray_add((void ***)&s1
->sections
, &s1
->nb_sections
, sec
);
92 void free_section(Section
*s
)
97 /* realloc section and set its content to zero */
98 void section_realloc(Section
*sec
, unsigned long new_size
)
103 size
= sec
->data_allocated
;
106 while (size
< new_size
)
108 data
= tcc_realloc(sec
->data
, size
);
110 error("memory full");
111 memset(data
+ sec
->data_allocated
, 0, size
- sec
->data_allocated
);
113 sec
->data_allocated
= size
;
116 /* reserve at least 'size' bytes in section 'sec' from
118 void *section_ptr_add(Section
*sec
, unsigned long size
)
120 unsigned long offset
, offset1
;
122 offset
= sec
->data_offset
;
123 offset1
= offset
+ size
;
124 if (offset1
> sec
->data_allocated
)
125 section_realloc(sec
, offset1
);
126 sec
->data_offset
= offset1
;
127 return sec
->data
+ offset
;
130 /* return a reference to a section, and create it if it does not
132 Section
*find_section(TCCState
*s1
, const char *name
)
136 for(i
= 1; i
< s1
->nb_sections
; i
++) {
137 sec
= s1
->sections
[i
];
138 if (!strcmp(name
, sec
->name
))
141 /* sections are created as PROGBITS */
142 return new_section(s1
, name
, SHT_PROGBITS
, SHF_ALLOC
);
145 /* update sym->c so that it points to an external symbol in section
146 'section' with value 'value' */
147 void put_extern_sym2(Sym
*sym
, Section
*section
,
148 unsigned long value
, unsigned long size
,
149 int can_add_underscore
)
151 int sym_type
, sym_bind
, sh_num
, info
, other
, attr
;
158 else if (section
== SECTION_ABS
)
161 sh_num
= section
->sh_num
;
165 if ((sym
->type
.t
& VT_BTYPE
) == VT_FUNC
) {
169 attr
= sym
->type
.ref
->r
;
170 if (FUNC_EXPORT(attr
))
172 if (FUNC_CALL(attr
) == FUNC_STDCALL
)
176 sym_type
= STT_OBJECT
;
179 if (sym
->type
.t
& VT_STATIC
)
180 sym_bind
= STB_LOCAL
;
182 sym_bind
= STB_GLOBAL
;
185 name
= get_tok_str(sym
->v
, NULL
);
186 #ifdef CONFIG_TCC_BCHECK
187 if (tcc_state
->do_bounds_check
) {
190 /* XXX: avoid doing that for statics ? */
191 /* if bound checking is activated, we change some function
192 names by adding the "__bound" prefix */
195 /* XXX: we rely only on malloc hooks */
208 strcpy(buf
, "__bound_");
217 if ((other
& 2) && can_add_underscore
) {
218 sprintf(buf1
, "_%s@%d", name
, FUNC_ARGS(attr
));
222 if (tcc_state
->leading_underscore
&& can_add_underscore
) {
224 pstrcpy(buf1
+ 1, sizeof(buf1
) - 1, name
);
227 info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
228 sym
->c
= add_elf_sym(symtab_section
, value
, size
, info
, other
, sh_num
, name
);
230 esym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym
->c
];
231 esym
->st_value
= value
;
232 esym
->st_size
= size
;
233 esym
->st_shndx
= sh_num
;
234 esym
->st_other
|= other
;
238 /* add a new relocation entry to symbol 'sym' in section 's' */
239 void greloc(Section
*s
, Sym
*sym
, unsigned long offset
, int type
)
242 put_extern_sym(sym
, NULL
, 0, 0);
243 /* now we can add ELF relocation info */
244 put_elf_reloc(symtab_section
, s
, offset
, type
, sym
->c
);
248 /* elf symbol hashing function */
249 static unsigned long elf_hash(const unsigned char *name
)
251 unsigned long h
= 0, g
;
254 h
= (h
<< 4) + *name
++;
263 /* rebuild hash table of section s */
264 /* NOTE: we do factorize the hash table code to go faster */
265 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
268 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
271 strtab
= s
->link
->data
;
272 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
274 s
->hash
->data_offset
= 0;
275 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
280 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
281 ptr
+= nb_buckets
+ 1;
283 sym
= (ElfW(Sym
) *)s
->data
+ 1;
284 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
285 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
286 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
297 /* return the symbol number */
298 int put_elf_sym(Section
*s
,
299 unsigned long value
, unsigned long size
,
300 int info
, int other
, int shndx
, const char *name
)
302 int name_offset
, sym_index
;
307 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
309 name_offset
= put_elf_str(s
->link
, name
);
312 /* XXX: endianness */
313 sym
->st_name
= name_offset
;
314 sym
->st_value
= value
;
317 sym
->st_other
= other
;
318 sym
->st_shndx
= shndx
;
319 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
323 ptr
= section_ptr_add(hs
, sizeof(int));
324 base
= (int *)hs
->data
;
325 /* only add global or weak symbols */
326 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
327 /* add another hashing entry */
329 h
= elf_hash(name
) % nbuckets
;
331 base
[2 + h
] = sym_index
;
333 /* we resize the hash table */
334 hs
->nb_hashed_syms
++;
335 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
336 rebuild_hash(s
, 2 * nbuckets
);
346 /* find global ELF symbol 'name' and return its index. Return 0 if not
348 static int find_elf_sym(Section
*s
, const char *name
)
352 int nbuckets
, sym_index
, h
;
358 nbuckets
= ((int *)hs
->data
)[0];
359 h
= elf_hash(name
) % nbuckets
;
360 sym_index
= ((int *)hs
->data
)[2 + h
];
361 while (sym_index
!= 0) {
362 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
363 name1
= s
->link
->data
+ sym
->st_name
;
364 if (!strcmp(name
, name1
))
366 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
371 /* return elf symbol value, signal error if 'err' is nonzero */
372 static void *get_elf_sym_addr(TCCState
*s
, const char *name
, int err
)
377 sym_index
= find_elf_sym(symtab_section
, name
);
378 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
379 if (!sym_index
|| sym
->st_shndx
== SHN_UNDEF
) {
381 error("%s not defined", name
);
384 return (void*)(uplong
)sym
->st_value
;
387 /* return elf symbol value */
388 void *tcc_get_symbol(TCCState
*s
, const char *name
)
390 return get_elf_sym_addr(s
, name
, 0);
393 /* return elf symbol value or error */
394 void *tcc_get_symbol_err(TCCState
*s
, const char *name
)
396 return get_elf_sym_addr(s
, name
, 1);
399 /* add an elf symbol : check if it is already defined and patch
400 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
401 int add_elf_sym(Section
*s
, uplong value
, unsigned long size
,
402 int info
, int other
, int sh_num
, const char *name
)
405 int sym_bind
, sym_index
, sym_type
, esym_bind
;
406 unsigned char sym_vis
, esym_vis
, new_vis
;
408 sym_bind
= ELFW(ST_BIND
)(info
);
409 sym_type
= ELFW(ST_TYPE
)(info
);
410 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
412 if (sym_bind
!= STB_LOCAL
) {
413 /* we search global or weak symbols */
414 sym_index
= find_elf_sym(s
, name
);
417 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
418 if (esym
->st_shndx
!= SHN_UNDEF
) {
419 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
420 /* propagate the most constraining visibility */
421 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
422 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
423 if (esym_vis
== STV_DEFAULT
) {
425 } else if (sym_vis
== STV_DEFAULT
) {
428 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
430 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
432 other
= esym
->st_other
; /* in case we have to patch esym */
433 if (sh_num
== SHN_UNDEF
) {
434 /* ignore adding of undefined symbol if the
435 corresponding symbol is already defined */
436 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
437 /* global overrides weak, so patch */
439 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
440 /* weak is ignored if already global */
441 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
442 /* ignore hidden symbols after */
443 } else if (esym
->st_shndx
== SHN_COMMON
444 && (sh_num
< SHN_LORESERVE
|| sh_num
== SHN_COMMON
)) {
445 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
446 No idea if this is the correct solution ... */
448 } else if (s
== tcc_state
->dynsymtab_section
) {
449 /* we accept that two DLL define the same symbol */
452 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
453 sym_bind
, sh_num
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
455 error_noabort("'%s' defined twice", name
);
459 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
460 esym
->st_shndx
= sh_num
;
461 esym
->st_value
= value
;
462 esym
->st_size
= size
;
463 esym
->st_other
= other
;
467 sym_index
= put_elf_sym(s
, value
, size
,
468 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
475 void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
476 int type
, int symbol
)
484 /* if no relocation section, create it */
485 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
486 /* if the symtab is allocated, then we consider the relocation
488 sr
= new_section(tcc_state
, buf
, SHT_RELX
, symtab
->sh_flags
);
489 sr
->sh_entsize
= sizeof(ElfW_Rel
);
491 sr
->sh_info
= s
->sh_num
;
494 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
495 rel
->r_offset
= offset
;
496 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
497 #ifdef TCC_TARGET_X86_64
502 /* put stab debug information */
504 void put_stabs(const char *str
, int type
, int other
, int desc
,
509 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
511 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
516 sym
->n_other
= other
;
518 sym
->n_value
= value
;
521 void put_stabs_r(const char *str
, int type
, int other
, int desc
,
522 unsigned long value
, Section
*sec
, int sym_index
)
524 put_stabs(str
, type
, other
, desc
, value
);
525 put_elf_reloc(symtab_section
, stab_section
,
526 stab_section
->data_offset
- sizeof(unsigned int),
527 R_DATA_32
, sym_index
);
530 void put_stabn(int type
, int other
, int desc
, int value
)
532 put_stabs(NULL
, type
, other
, desc
, value
);
535 void put_stabd(int type
, int other
, int desc
)
537 put_stabs(NULL
, type
, other
, desc
, 0);
540 /* In an ELF file symbol table, the local symbols must appear below
541 the global and weak ones. Since TCC cannot sort it while generating
542 the code, we must do it after. All the relocation tables are also
543 modified to take into account the symbol table sorting */
544 static void sort_syms(TCCState
*s1
, Section
*s
)
546 int *old_to_new_syms
;
550 ElfW_Rel
*rel
, *rel_end
;
554 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
555 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
556 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
558 /* first pass for local symbols */
559 p
= (ElfW(Sym
) *)s
->data
;
561 for(i
= 0; i
< nb_syms
; i
++) {
562 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
563 old_to_new_syms
[i
] = q
- new_syms
;
568 /* save the number of local symbols in section header */
569 s
->sh_info
= q
- new_syms
;
571 /* then second pass for non local symbols */
572 p
= (ElfW(Sym
) *)s
->data
;
573 for(i
= 0; i
< nb_syms
; i
++) {
574 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
575 old_to_new_syms
[i
] = q
- new_syms
;
581 /* we copy the new symbols to the old */
582 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
585 /* now we modify all the relocations */
586 for(i
= 1; i
< s1
->nb_sections
; i
++) {
587 sr
= s1
->sections
[i
];
588 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
589 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
590 for(rel
= (ElfW_Rel
*)sr
->data
;
593 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
594 type
= ELFW(R_TYPE
)(rel
->r_info
);
595 sym_index
= old_to_new_syms
[sym_index
];
596 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
601 tcc_free(old_to_new_syms
);
604 /* relocate common symbols in the .bss section */
605 void relocate_common_syms(void)
607 ElfW(Sym
) *sym
, *sym_end
;
608 unsigned long offset
, align
;
610 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
611 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
614 if (sym
->st_shndx
== SHN_COMMON
) {
616 align
= sym
->st_value
;
617 offset
= bss_section
->data_offset
;
618 offset
= (offset
+ align
- 1) & -align
;
619 sym
->st_value
= offset
;
620 sym
->st_shndx
= bss_section
->sh_num
;
621 offset
+= sym
->st_size
;
622 bss_section
->data_offset
= offset
;
627 /* relocate symbol table, resolve undefined symbols if do_resolve is
628 true and output error if undefined symbol. */
629 void relocate_syms(TCCState
*s1
, int do_resolve
)
631 ElfW(Sym
) *sym
, *esym
, *sym_end
;
632 int sym_bind
, sh_num
, sym_index
;
635 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
636 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
639 sh_num
= sym
->st_shndx
;
640 if (sh_num
== SHN_UNDEF
) {
641 name
= strtab_section
->data
+ sym
->st_name
;
645 name
= symtab_section
->link
->data
+ sym
->st_name
;
646 addr
= resolve_sym(s1
, name
);
648 sym
->st_value
= (uplong
)addr
;
652 } else if (s1
->dynsym
) {
653 /* if dynamic symbol exist, then use it */
654 sym_index
= find_elf_sym(s1
->dynsym
, name
);
656 esym
= &((ElfW(Sym
) *)s1
->dynsym
->data
)[sym_index
];
657 sym
->st_value
= esym
->st_value
;
661 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
663 if (!strcmp(name
, "_fp_hw"))
665 /* only weak symbols are accepted to be undefined. Their
667 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
668 if (sym_bind
== STB_WEAK
) {
671 error_noabort("undefined symbol '%s'", name
);
673 } else if (sh_num
< SHN_LORESERVE
) {
674 /* add section base */
675 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
681 #ifndef TCC_TARGET_PE
682 #ifdef TCC_TARGET_X86_64
683 #define JMP_TABLE_ENTRY_SIZE 14
684 static unsigned long add_jmp_table(TCCState
*s1
, unsigned long val
)
686 char *p
= s1
->runtime_plt_and_got
+ s1
->runtime_plt_and_got_offset
;
687 s1
->runtime_plt_and_got_offset
+= JMP_TABLE_ENTRY_SIZE
;
692 *(unsigned long *)(p
+ 6) = val
;
693 return (unsigned long)p
;
696 static unsigned long add_got_table(TCCState
*s1
, unsigned long val
)
698 unsigned long *p
=(unsigned long *)(s1
->runtime_plt_and_got
+
699 s1
->runtime_plt_and_got_offset
);
700 s1
->runtime_plt_and_got_offset
+= sizeof(void *);
702 return (unsigned long)p
;
707 /* relocate a given section (CPU dependent) */
708 void relocate_section(TCCState
*s1
, Section
*s
)
711 ElfW_Rel
*rel
, *rel_end
, *qrel
;
715 unsigned long val
, addr
;
716 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
721 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
722 qrel
= (ElfW_Rel
*)sr
->data
;
726 ptr
= s
->data
+ rel
->r_offset
;
728 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
729 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
731 #ifdef TCC_TARGET_X86_64
732 /* XXX: not tested */
733 val
+= rel
->r_addend
;
735 type
= ELFW(R_TYPE
)(rel
->r_info
);
736 addr
= s
->sh_addr
+ rel
->r_offset
;
740 #if defined(TCC_TARGET_I386)
742 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
743 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
744 qrel
->r_offset
= rel
->r_offset
;
746 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_32
);
750 qrel
->r_info
= ELFW(R_INFO
)(0, R_386_RELATIVE
);
757 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
759 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
761 qrel
->r_offset
= rel
->r_offset
;
762 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_PC32
);
767 *(int *)ptr
+= val
- addr
;
770 *(int *)ptr
+= val
- addr
;
777 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
780 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
783 /* we load the got offset */
784 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
787 if (s1
->output_format
!= TCC_OUTPUT_FORMAT_BINARY
) {
789 error("can only produce 16-bit binary files");
791 *(short *)ptr
+= val
;
794 if (s1
->output_format
!= TCC_OUTPUT_FORMAT_BINARY
)
796 *(short *)ptr
+= val
- addr
;
798 #elif defined(TCC_TARGET_ARM)
805 x
= (*(int *)ptr
)&0xffffff;
806 (*(int *)ptr
) &= 0xff000000;
811 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
812 error("can't relocate value at %x",addr
);
821 x
= (*(int *)ptr
) & 0x7fffffff;
822 (*(int *)ptr
) &= 0x80000000;
825 if((x
^(x
>>1))&0x40000000)
826 error("can't relocate value at %x",addr
);
827 (*(int *)ptr
) |= x
& 0x7fffffff;
832 case R_ARM_BASE_PREL
:
833 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
836 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
839 /* we load the got offset */
840 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
845 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
846 type
,addr
,(unsigned int)(long)ptr
,val
);
848 #elif defined(TCC_TARGET_C67)
856 /* put the low 16 bits of the absolute address */
857 // add to what is already there
859 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
860 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
862 //patch both at once - assumes always in pairs Low - High
864 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
865 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
871 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
872 type
,addr
,(unsigned int)(long)ptr
, val
);
874 #elif defined(TCC_TARGET_X86_64)
876 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
877 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
878 qrel
->r_addend
= *(long long *)ptr
+ val
;
881 *(long long *)ptr
+= val
;
885 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
886 /* XXX: this logic may depend on TCC's codegen
887 now TCC uses R_X86_64_32 even for a 64bit pointer */
888 qrel
->r_info
= ELFW(R_INFO
)(0, R_X86_64_RELATIVE
);
889 qrel
->r_addend
= *(int *)ptr
+ val
;
894 case R_X86_64_PC32
: {
896 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
898 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
900 qrel
->r_offset
= rel
->r_offset
;
901 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_X86_64_PC32
);
902 qrel
->r_addend
= *(int *)ptr
;
907 diff
= (long long)val
- addr
;
908 if (diff
<= -2147483647 || diff
> 2147483647) {
909 #ifndef TCC_TARGET_PE
910 /* XXX: naive support for over 32bit jump */
911 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
912 val
= add_jmp_table(s1
, val
);
916 if (diff
<= -2147483647 || diff
> 2147483647) {
917 error("internal error: relocation failed");
924 *(int *)ptr
+= val
- addr
;
926 case R_X86_64_GLOB_DAT
:
927 case R_X86_64_JUMP_SLOT
:
930 case R_X86_64_GOTPCREL
:
931 #ifndef TCC_TARGET_PE
932 if (s1
->output_type
== TCC_OUTPUT_MEMORY
) {
933 val
= add_got_table(s1
, val
- rel
->r_addend
) + rel
->r_addend
;
934 *(int *)ptr
+= val
- addr
;
938 *(int *)ptr
+= (s1
->got
->sh_addr
- addr
+
939 s1
->got_offsets
[sym_index
] - 4);
941 case R_X86_64_GOTTPOFF
:
942 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
945 /* we load the got offset */
946 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
949 #error unsupported processor
953 /* if the relocation is allocated, we change its symbol table */
954 if (sr
->sh_flags
& SHF_ALLOC
)
955 sr
->link
= s1
->dynsym
;
958 /* relocate relocation table in 'sr' */
959 static void relocate_rel(TCCState
*s1
, Section
*sr
)
962 ElfW_Rel
*rel
, *rel_end
;
964 s
= s1
->sections
[sr
->sh_info
];
965 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
966 for(rel
= (ElfW_Rel
*)sr
->data
;
969 rel
->r_offset
+= s
->sh_addr
;
973 /* count the number of dynamic relocations so that we can reserve
975 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
977 ElfW_Rel
*rel
, *rel_end
;
978 int sym_index
, esym_index
, type
, count
;
981 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
982 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
983 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
984 type
= ELFW(R_TYPE
)(rel
->r_info
);
986 #if defined(TCC_TARGET_I386)
988 #elif defined(TCC_TARGET_X86_64)
995 #if defined(TCC_TARGET_I386)
997 #elif defined(TCC_TARGET_X86_64)
1000 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
1009 /* allocate the section */
1010 sr
->sh_flags
|= SHF_ALLOC
;
1011 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
1016 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
1021 if (index
>= s1
->nb_got_offsets
) {
1022 /* find immediately bigger power of 2 and reallocate array */
1026 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
1028 error("memory full");
1029 s1
->got_offsets
= tab
;
1030 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
1031 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
1032 s1
->nb_got_offsets
= n
;
1034 s1
->got_offsets
[index
] = val
;
1037 /* XXX: suppress that */
1038 static void put32(unsigned char *p
, uint32_t val
)
1046 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM) || \
1047 defined(TCC_TARGET_X86_64)
1048 static uint32_t get32(unsigned char *p
)
1050 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
1054 static void build_got(TCCState
*s1
)
1058 /* if no got, then create it */
1059 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
1060 s1
->got
->sh_entsize
= 4;
1061 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
1062 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
1063 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
1065 /* keep space for _DYNAMIC pointer, if present */
1067 /* two dummy got entries */
1071 /* keep space for _DYNAMIC pointer, if present */
1074 /* two dummy got entries */
1082 /* put a got entry corresponding to a symbol in symtab_section. 'size'
1083 and 'info' can be modifed if more precise info comes from the DLL */
1084 static void put_got_entry(TCCState
*s1
,
1085 int reloc_type
, unsigned long size
, int info
,
1091 unsigned long offset
;
1097 /* if a got entry already exists for that symbol, no need to add one */
1098 if (sym_index
< s1
->nb_got_offsets
&&
1099 s1
->got_offsets
[sym_index
] != 0)
1102 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
1105 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1106 name
= symtab_section
->link
->data
+ sym
->st_name
;
1107 offset
= sym
->st_value
;
1108 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1110 #ifdef TCC_TARGET_X86_64
1120 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1123 /* if we build a DLL, we add a %ebx offset */
1124 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1130 /* add a PLT entry */
1132 if (plt
->data_offset
== 0) {
1133 /* first plt entry */
1134 p
= section_ptr_add(plt
, 16);
1135 p
[0] = 0xff; /* pushl got + PTR_SIZE */
1136 p
[1] = modrm
+ 0x10;
1137 put32(p
+ 2, PTR_SIZE
);
1138 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
1140 put32(p
+ 8, PTR_SIZE
* 2);
1143 p
= section_ptr_add(plt
, 16);
1144 p
[0] = 0xff; /* jmp *(got + x) */
1146 put32(p
+ 2, s1
->got
->data_offset
);
1147 p
[6] = 0x68; /* push $xxx */
1148 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
1149 p
[11] = 0xe9; /* jmp plt_start */
1150 put32(p
+ 12, -(plt
->data_offset
));
1152 /* the symbol is modified so that it will be relocated to
1154 #if !defined(TCC_OUTPUT_DLL_WITH_PLT)
1155 if (s1
->output_type
== TCC_OUTPUT_EXE
)
1157 offset
= plt
->data_offset
- 16;
1159 #elif defined(TCC_TARGET_ARM)
1160 if (reloc_type
== R_ARM_JUMP_SLOT
) {
1164 /* if we build a DLL, we add a %ebx offset */
1165 if (s1
->output_type
== TCC_OUTPUT_DLL
)
1166 error("DLLs unimplemented!");
1168 /* add a PLT entry */
1170 if (plt
->data_offset
== 0) {
1171 /* first plt entry */
1172 p
= section_ptr_add(plt
, 16);
1173 put32(p
, 0xe52de004);
1174 put32(p
+ 4, 0xe59fe010);
1175 put32(p
+ 8, 0xe08fe00e);
1176 put32(p
+ 12, 0xe5bef008);
1179 p
= section_ptr_add(plt
, 16);
1180 put32(p
, 0xe59fc004);
1181 put32(p
+4, 0xe08fc00c);
1182 put32(p
+8, 0xe59cf000);
1183 put32(p
+12, s1
->got
->data_offset
);
1185 /* the symbol is modified so that it will be relocated to
1187 if (s1
->output_type
== TCC_OUTPUT_EXE
)
1188 offset
= plt
->data_offset
- 16;
1190 #elif defined(TCC_TARGET_C67)
1191 error("C67 got not implemented");
1193 #error unsupported CPU
1195 index
= put_elf_sym(s1
->dynsym
, offset
,
1196 size
, info
, 0, sym
->st_shndx
, name
);
1197 /* put a got entry */
1198 put_elf_reloc(s1
->dynsym
, s1
->got
,
1199 s1
->got
->data_offset
,
1202 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
1206 /* build GOT and PLT entries */
1207 void build_got_entries(TCCState
*s1
)
1209 Section
*s
, *symtab
;
1210 ElfW_Rel
*rel
, *rel_end
;
1212 int i
, type
, reloc_type
, sym_index
;
1214 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1215 s
= s1
->sections
[i
];
1216 if (s
->sh_type
!= SHT_RELX
)
1218 /* no need to handle got relocations */
1219 if (s
->link
!= symtab_section
)
1222 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
1223 for(rel
= (ElfW_Rel
*)s
->data
;
1226 type
= ELFW(R_TYPE
)(rel
->r_info
);
1228 #if defined(TCC_TARGET_I386)
1235 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
1236 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1237 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1238 /* look at the symbol got offset. If none, then add one */
1239 if (type
== R_386_GOT32
)
1240 reloc_type
= R_386_GLOB_DAT
;
1242 reloc_type
= R_386_JMP_SLOT
;
1243 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1247 #elif defined(TCC_TARGET_ARM)
1248 case R_ARM_GOT_BREL
:
1249 case R_ARM_GOTOFF32
:
1250 case R_ARM_BASE_PREL
:
1254 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
1255 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1256 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1257 /* look at the symbol got offset. If none, then add one */
1258 if (type
== R_ARM_GOT_BREL
)
1259 reloc_type
= R_ARM_GLOB_DAT
;
1261 reloc_type
= R_ARM_JUMP_SLOT
;
1262 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1266 #elif defined(TCC_TARGET_C67)
1273 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
1274 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1275 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1276 /* look at the symbol got offset. If none, then add one */
1277 if (type
== R_C60_GOT32
)
1278 reloc_type
= R_C60_GLOB_DAT
;
1280 reloc_type
= R_C60_JMP_SLOT
;
1281 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1285 #elif defined(TCC_TARGET_X86_64)
1286 case R_X86_64_GOT32
:
1287 case R_X86_64_GOTTPOFF
:
1288 case R_X86_64_GOTPCREL
:
1289 case R_X86_64_PLT32
:
1292 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
||
1293 type
== R_X86_64_PLT32
) {
1294 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
1295 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1296 /* look at the symbol got offset. If none, then add one */
1297 if (type
== R_X86_64_GOT32
|| type
== R_X86_64_GOTPCREL
)
1298 reloc_type
= R_X86_64_GLOB_DAT
;
1300 reloc_type
= R_X86_64_JUMP_SLOT
;
1301 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
1306 #error unsupported CPU
1315 Section
*new_symtab(TCCState
*s1
,
1316 const char *symtab_name
, int sh_type
, int sh_flags
,
1317 const char *strtab_name
,
1318 const char *hash_name
, int hash_sh_flags
)
1320 Section
*symtab
, *strtab
, *hash
;
1321 int *ptr
, nb_buckets
;
1323 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
1324 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
1325 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
1326 put_elf_str(strtab
, "");
1327 symtab
->link
= strtab
;
1328 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
1332 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
1333 hash
->sh_entsize
= sizeof(int);
1334 symtab
->hash
= hash
;
1335 hash
->link
= symtab
;
1337 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
1338 ptr
[0] = nb_buckets
;
1340 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
1344 /* put dynamic tag */
1345 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
1348 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
1350 dyn
->d_un
.d_val
= val
;
1353 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
1357 char sym_start
[1024];
1360 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
1361 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
1363 s
= find_section(s1
, section_name
);
1368 end_offset
= s
->data_offset
;
1371 add_elf_sym(symtab_section
,
1373 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1374 s
->sh_num
, sym_start
);
1375 add_elf_sym(symtab_section
,
1377 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1378 s
->sh_num
, sym_end
);
1381 /* add tcc runtime libraries */
1382 void tcc_add_runtime(TCCState
*s1
)
1384 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1388 #ifdef CONFIG_TCC_BCHECK
1389 if (s1
->do_bounds_check
) {
1391 Section
*init_section
;
1392 unsigned char *pinit
;
1395 /* XXX: add an object file to do that */
1396 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1398 add_elf_sym(symtab_section
, 0, 0,
1399 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1400 bounds_section
->sh_num
, "__bounds_start");
1401 /* add bound check code */
1402 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "bcheck.o");
1403 tcc_add_file(s1
, buf
);
1404 #ifdef TCC_TARGET_I386
1405 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1406 /* add 'call __bound_init()' in .init section */
1407 init_section
= find_section(s1
, ".init");
1408 pinit
= section_ptr_add(init_section
, 5);
1410 put32(pinit
+ 1, -4);
1411 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1412 put_elf_reloc(symtab_section
, init_section
,
1413 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1419 if (!s1
->nostdlib
) {
1420 tcc_add_library(s1
, "c");
1422 #ifdef CONFIG_USE_LIBGCC
1423 tcc_add_file(s1
, CONFIG_SYSROOT
"/lib/libgcc_s.so.1");
1425 snprintf(buf
, sizeof(buf
), "%s/%s", s1
->tcc_lib_path
, "libtcc1.a");
1426 tcc_add_file(s1
, buf
);
1429 /* add crt end if not memory output */
1430 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1431 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1435 /* add various standard linker symbols (must be done after the
1436 sections are filled (for example after allocating common
1438 void tcc_add_linker_symbols(TCCState
*s1
)
1444 add_elf_sym(symtab_section
,
1445 text_section
->data_offset
, 0,
1446 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1447 text_section
->sh_num
, "_etext");
1448 add_elf_sym(symtab_section
,
1449 data_section
->data_offset
, 0,
1450 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1451 data_section
->sh_num
, "_edata");
1452 add_elf_sym(symtab_section
,
1453 bss_section
->data_offset
, 0,
1454 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1455 bss_section
->sh_num
, "_end");
1456 /* horrible new standard ldscript defines */
1457 add_init_array_defines(s1
, ".preinit_array");
1458 add_init_array_defines(s1
, ".init_array");
1459 add_init_array_defines(s1
, ".fini_array");
1461 /* add start and stop symbols for sections whose name can be
1463 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1464 s
= s1
->sections
[i
];
1465 if (s
->sh_type
== SHT_PROGBITS
&&
1466 (s
->sh_flags
& SHF_ALLOC
)) {
1470 /* check if section name can be expressed in C */
1476 if (!isid(ch
) && !isnum(ch
))
1480 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1481 add_elf_sym(symtab_section
,
1483 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1485 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1486 add_elf_sym(symtab_section
,
1488 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1495 /* name of ELF interpreter */
1496 #if defined __FreeBSD__
1497 static const char elf_interp
[] = "/libexec/ld-elf.so.1";
1498 #elif defined TCC_ARM_EABI
1499 static const char elf_interp
[] = "/lib/ld-linux.so.3";
1500 #elif defined(TCC_TARGET_X86_64)
1501 static const char elf_interp
[] = "/lib/ld-linux-x86-64.so.2";
1502 #elif defined(TCC_UCLIBC)
1503 static const char elf_interp
[] = "/lib/ld-uClibc.so.0";
1505 static const char elf_interp
[] = "/lib/ld-linux.so.2";
1508 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1509 const int *section_order
)
1512 int i
, offset
, size
;
1515 for(i
=1;i
<s1
->nb_sections
;i
++) {
1516 s
= s1
->sections
[section_order
[i
]];
1517 if (s
->sh_type
!= SHT_NOBITS
&&
1518 (s
->sh_flags
& SHF_ALLOC
)) {
1519 while (offset
< s
->sh_offset
) {
1524 fwrite(s
->data
, 1, size
, f
);
1530 #if defined(__FreeBSD__)
1532 #define EXTRA_RELITEMS 14
1534 /* move the relocation value from .dynsym to .got */
1535 void patch_dynsym_undef(TCCState
*s1
, Section
*s
)
1537 uint32_t *gotd
= (void *)s1
->got
->data
;
1538 ElfW(Sym
) *sym
, *sym_end
;
1540 gotd
+= 3; // dummy entries in .got
1541 /* relocate symbols in .dynsym */
1542 sym_end
= (ElfW(Sym
) *)(s
->data
+ s
->data_offset
);
1543 for (sym
= (ElfW(Sym
) *)s
->data
+ 1; sym
< sym_end
; sym
++) {
1544 if (sym
->st_shndx
== SHN_UNDEF
) {
1545 *gotd
++ = sym
->st_value
+ 6; // XXX 6 is magic ?
1552 #define EXTRA_RELITEMS 9
1555 /* output an ELF file */
1556 /* XXX: suppress unneeded sections */
1557 int elf_output_file(TCCState
*s1
, const char *filename
)
1563 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1565 Section
*strsec
, *s
;
1566 ElfW(Shdr
) shdr
, *sh
;
1567 ElfW(Phdr
) *phdr
, *ph
;
1568 Section
*interp
, *dynamic
, *dynstr
;
1569 unsigned long saved_dynamic_data_offset
;
1571 int type
, file_type
;
1572 unsigned long rel_addr
, rel_size
;
1573 unsigned long bss_addr
, bss_size
;
1575 file_type
= s1
->output_type
;
1578 if (file_type
!= TCC_OUTPUT_OBJ
) {
1579 tcc_add_runtime(s1
);
1583 section_order
= NULL
;
1586 dynstr
= NULL
; /* avoid warning */
1587 saved_dynamic_data_offset
= 0; /* avoid warning */
1589 if (file_type
!= TCC_OUTPUT_OBJ
) {
1590 relocate_common_syms();
1592 tcc_add_linker_symbols(s1
);
1594 if (!s1
->static_link
) {
1596 int sym_index
, index
;
1597 ElfW(Sym
) *esym
, *sym_end
;
1599 if (file_type
== TCC_OUTPUT_EXE
) {
1601 /* allow override the dynamic loader */
1602 const char *elfint
= getenv("LD_SO");
1604 elfint
= elf_interp
;
1605 /* add interpreter section only if executable */
1606 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1607 interp
->sh_addralign
= 1;
1608 ptr
= section_ptr_add(interp
, 1+strlen(elfint
));
1609 strcpy(ptr
, elfint
);
1612 /* add dynamic symbol table */
1613 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1615 ".hash", SHF_ALLOC
);
1616 dynstr
= s1
->dynsym
->link
;
1618 /* add dynamic section */
1619 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1620 SHF_ALLOC
| SHF_WRITE
);
1621 dynamic
->link
= dynstr
;
1622 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1625 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1626 SHF_ALLOC
| SHF_EXECINSTR
);
1627 s1
->plt
->sh_entsize
= 4;
1631 /* scan for undefined symbols and see if they are in the
1632 dynamic symbols. If a symbol STT_FUNC is found, then we
1633 add it in the PLT. If a symbol STT_OBJECT is found, we
1634 add it in the .bss section with a suitable relocation */
1635 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1636 symtab_section
->data_offset
);
1637 if (file_type
== TCC_OUTPUT_EXE
) {
1638 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1641 if (sym
->st_shndx
== SHN_UNDEF
) {
1642 name
= symtab_section
->link
->data
+ sym
->st_name
;
1643 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1645 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1646 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1647 if (type
== STT_FUNC
) {
1648 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1650 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1651 } else if (type
== STT_OBJECT
) {
1652 unsigned long offset
;
1653 offset
= bss_section
->data_offset
;
1654 /* XXX: which alignment ? */
1655 offset
= (offset
+ 16 - 1) & -16;
1656 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1658 bss_section
->sh_num
, name
);
1659 put_elf_reloc(s1
->dynsym
, bss_section
,
1660 offset
, R_COPY
, index
);
1661 offset
+= esym
->st_size
;
1662 bss_section
->data_offset
= offset
;
1665 /* STB_WEAK undefined symbols are accepted */
1666 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1668 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1669 !strcmp(name
, "_fp_hw")) {
1671 error_noabort("undefined symbol '%s'", name
);
1674 } else if (s1
->rdynamic
&&
1675 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1676 /* if -rdynamic option, then export all non
1678 name
= symtab_section
->link
->data
+ sym
->st_name
;
1679 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1681 sym
->st_shndx
, name
);
1688 /* now look at unresolved dynamic symbols and export
1689 corresponding symbol */
1690 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1691 s1
->dynsymtab_section
->data_offset
);
1692 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1695 if (esym
->st_shndx
== SHN_UNDEF
) {
1696 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1697 sym_index
= find_elf_sym(symtab_section
, name
);
1699 /* XXX: avoid adding a symbol if already
1700 present because of -rdynamic ? */
1701 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1702 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1704 sym
->st_shndx
, name
);
1706 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1707 /* weak symbols can stay undefined */
1709 warning("undefined dynamic symbol '%s'", name
);
1716 /* shared library case : we simply export all the global symbols */
1717 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1718 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1719 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1722 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1723 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
1724 if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_FUNC
&&
1725 sym
->st_shndx
== SHN_UNDEF
) {
1726 put_got_entry(s1
, R_JMP_SLOT
, sym
->st_size
,
1728 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1730 else if (ELFW(ST_TYPE
)(sym
->st_info
) == STT_OBJECT
) {
1731 put_got_entry(s1
, R_X86_64_GLOB_DAT
, sym
->st_size
,
1733 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1738 name
= symtab_section
->link
->data
+ sym
->st_name
;
1739 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1741 sym
->st_shndx
, name
);
1742 s1
->symtab_to_dynsym
[sym
-
1743 (ElfW(Sym
) *)symtab_section
->data
] =
1750 build_got_entries(s1
);
1752 /* add a list of needed dlls */
1753 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1754 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1755 if (dllref
->level
== 0)
1756 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1758 /* XXX: currently, since we do not handle PIC code, we
1759 must relocate the readonly segments */
1760 if (file_type
== TCC_OUTPUT_DLL
) {
1762 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1763 put_dt(dynamic
, DT_TEXTREL
, 0);
1766 /* add necessary space for other entries */
1767 saved_dynamic_data_offset
= dynamic
->data_offset
;
1768 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * EXTRA_RELITEMS
;
1770 /* still need to build got entries in case of static link */
1771 build_got_entries(s1
);
1775 memset(&ehdr
, 0, sizeof(ehdr
));
1777 /* we add a section for symbols */
1778 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1779 put_elf_str(strsec
, "");
1781 /* compute number of sections */
1782 shnum
= s1
->nb_sections
;
1784 /* this array is used to reorder sections in the output file */
1785 section_order
= tcc_malloc(sizeof(int) * shnum
);
1786 section_order
[0] = 0;
1789 /* compute number of program headers */
1792 case TCC_OUTPUT_OBJ
:
1795 case TCC_OUTPUT_EXE
:
1796 if (!s1
->static_link
)
1797 phnum
= 4 + HAVE_PHDR
;
1801 case TCC_OUTPUT_DLL
:
1806 /* allocate strings for section names and decide if an unallocated
1807 section should be output */
1808 /* NOTE: the strsec section comes last, so its size is also
1810 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1811 s
= s1
->sections
[i
];
1812 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1814 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1819 s
->reloc
? s
->reloc
->name
: "n"
1822 /* when generating a DLL, we include relocations but we may
1824 if (file_type
== TCC_OUTPUT_DLL
&&
1825 s
->sh_type
== SHT_RELX
&&
1826 !(s
->sh_flags
& SHF_ALLOC
)) {
1827 /* //gr: avoid bogus relocs for empty (debug) sections */
1828 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1829 prepare_dynamic_rel(s1
, s
);
1830 else if (s1
->do_debug
)
1831 s
->sh_size
= s
->data_offset
;
1832 } else if (s1
->do_debug
||
1833 file_type
== TCC_OUTPUT_OBJ
||
1834 (s
->sh_flags
& SHF_ALLOC
) ||
1835 i
== (s1
->nb_sections
- 1)) {
1836 /* we output all sections if debug or object file */
1837 s
->sh_size
= s
->data_offset
;
1841 /* allocate program segment headers */
1842 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1844 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1845 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1850 /* compute section to program header mapping */
1851 if (s1
->has_text_addr
) {
1852 int a_offset
, p_offset
;
1853 addr
= s1
->text_addr
;
1854 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1856 a_offset
= addr
& (s1
->section_align
- 1);
1857 p_offset
= file_offset
& (s1
->section_align
- 1);
1858 if (a_offset
< p_offset
)
1859 a_offset
+= s1
->section_align
;
1860 file_offset
+= (a_offset
- p_offset
);
1862 if (file_type
== TCC_OUTPUT_DLL
)
1865 addr
= ELF_START_ADDR
;
1866 /* compute address after headers */
1867 addr
+= (file_offset
& (s1
->section_align
- 1));
1870 /* dynamic relocation table information, for .dynamic section */
1874 bss_addr
= bss_size
= 0;
1875 /* leave one program header for the program interpreter */
1878 ph
+= 1 + HAVE_PHDR
;
1880 for(j
= 0; j
< 2; j
++) {
1881 ph
->p_type
= PT_LOAD
;
1883 ph
->p_flags
= PF_R
| PF_X
;
1885 ph
->p_flags
= PF_R
| PF_W
;
1886 ph
->p_align
= s1
->section_align
;
1888 /* we do the following ordering: interp, symbol tables,
1889 relocations, progbits, nobits */
1890 /* XXX: do faster and simpler sorting */
1891 for(k
= 0; k
< 5; k
++) {
1892 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1893 s
= s1
->sections
[i
];
1894 /* compute if section should be included */
1896 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1900 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1901 (SHF_ALLOC
| SHF_WRITE
))
1907 } else if (s
->sh_type
== SHT_DYNSYM
||
1908 s
->sh_type
== SHT_STRTAB
||
1909 s
->sh_type
== SHT_HASH
) {
1912 } else if (s
->sh_type
== SHT_RELX
) {
1915 } else if (s
->sh_type
== SHT_NOBITS
) {
1922 section_order
[sh_order_index
++] = i
;
1924 /* section matches: we align it and add its size */
1926 addr
= (addr
+ s
->sh_addralign
- 1) &
1927 ~(s
->sh_addralign
- 1);
1928 file_offset
+= addr
- tmp
;
1929 s
->sh_offset
= file_offset
;
1932 /* update program header infos */
1933 if (ph
->p_offset
== 0) {
1934 ph
->p_offset
= file_offset
;
1936 ph
->p_paddr
= ph
->p_vaddr
;
1938 /* update dynamic relocation infos */
1939 if (s
->sh_type
== SHT_RELX
) {
1940 #if defined(__FreeBSD__)
1941 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.got")) { // rel_size == 0) {
1943 rel_size
+= s
->sh_size
; // XXX only first rel.
1945 if (!strcmp(strsec
->data
+ s
->sh_name
, ".rel.bss")) { // rel_size == 0) {
1947 bss_size
= s
->sh_size
; // XXX only first rel.
1952 rel_size
+= s
->sh_size
;
1956 if (s
->sh_type
!= SHT_NOBITS
)
1957 file_offset
+= s
->sh_size
;
1960 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1961 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1964 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1965 /* if in the middle of a page, we duplicate the page in
1966 memory so that one copy is RX and the other is RW */
1967 if ((addr
& (s1
->section_align
- 1)) != 0)
1968 addr
+= s1
->section_align
;
1970 addr
= (addr
+ s1
->section_align
- 1) & ~(s1
->section_align
- 1);
1971 file_offset
= (file_offset
+ s1
->section_align
- 1) &
1972 ~(s1
->section_align
- 1);
1977 /* if interpreter, then add corresponing program header */
1981 #if defined(__FreeBSD__)
1983 int len
= phnum
* sizeof(ElfW(Phdr
));
1985 ph
->p_type
= PT_PHDR
;
1986 ph
->p_offset
= sizeof(ElfW(Ehdr
));
1987 ph
->p_vaddr
= interp
->sh_addr
- len
;
1988 ph
->p_paddr
= ph
->p_vaddr
;
1989 ph
->p_filesz
= ph
->p_memsz
= len
;
1990 ph
->p_flags
= PF_R
| PF_X
;
1991 ph
->p_align
= 4; // interp->sh_addralign;
1996 ph
->p_type
= PT_INTERP
;
1997 ph
->p_offset
= interp
->sh_offset
;
1998 ph
->p_vaddr
= interp
->sh_addr
;
1999 ph
->p_paddr
= ph
->p_vaddr
;
2000 ph
->p_filesz
= interp
->sh_size
;
2001 ph
->p_memsz
= interp
->sh_size
;
2003 ph
->p_align
= interp
->sh_addralign
;
2006 /* if dynamic section, then add corresponing program header */
2010 ph
= &phdr
[phnum
- 1];
2012 ph
->p_type
= PT_DYNAMIC
;
2013 ph
->p_offset
= dynamic
->sh_offset
;
2014 ph
->p_vaddr
= dynamic
->sh_addr
;
2015 ph
->p_paddr
= ph
->p_vaddr
;
2016 ph
->p_filesz
= dynamic
->sh_size
;
2017 ph
->p_memsz
= dynamic
->sh_size
;
2018 ph
->p_flags
= PF_R
| PF_W
;
2019 ph
->p_align
= dynamic
->sh_addralign
;
2021 /* put GOT dynamic section address */
2022 put32(s1
->got
->data
, dynamic
->sh_addr
);
2024 /* relocate the PLT */
2025 if (file_type
== TCC_OUTPUT_EXE
2026 #if defined(TCC_OUTPUT_DLL_WITH_PLT)
2027 || file_type
== TCC_OUTPUT_DLL
2033 p_end
= p
+ s1
->plt
->data_offset
;
2035 #if defined(TCC_TARGET_I386)
2036 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
2037 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
2040 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
2043 #elif defined(TCC_TARGET_X86_64)
2044 int x
= s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 6;
2045 put32(p
+ 2, get32(p
+ 2) + x
);
2046 put32(p
+ 8, get32(p
+ 8) + x
- 6);
2049 put32(p
+ 2, get32(p
+ 2) + x
+ s1
->plt
->data
- p
);
2052 #elif defined(TCC_TARGET_ARM)
2054 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
2057 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
2060 #elif defined(TCC_TARGET_C67)
2063 #error unsupported CPU
2068 /* relocate symbols in .dynsym */
2069 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
2070 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
2073 if (sym
->st_shndx
== SHN_UNDEF
) {
2074 /* relocate to the PLT if the symbol corresponds
2077 sym
->st_value
+= s1
->plt
->sh_addr
;
2078 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
2079 /* do symbol relocation */
2080 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
2084 /* put dynamic section entries */
2085 dynamic
->data_offset
= saved_dynamic_data_offset
;
2086 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
2087 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
2088 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
2089 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
2090 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
2091 #ifdef TCC_TARGET_X86_64
2092 put_dt(dynamic
, DT_RELA
, rel_addr
);
2093 put_dt(dynamic
, DT_RELASZ
, rel_size
);
2094 put_dt(dynamic
, DT_RELAENT
, sizeof(ElfW_Rel
));
2096 #if defined(__FreeBSD__)
2097 put_dt(dynamic
, DT_PLTGOT
, s1
->got
->sh_addr
);
2098 put_dt(dynamic
, DT_PLTRELSZ
, rel_size
);
2099 put_dt(dynamic
, DT_JMPREL
, rel_addr
);
2100 put_dt(dynamic
, DT_PLTREL
, DT_REL
);
2101 put_dt(dynamic
, DT_REL
, bss_addr
);
2102 put_dt(dynamic
, DT_RELSZ
, bss_size
);
2104 put_dt(dynamic
, DT_REL
, rel_addr
);
2105 put_dt(dynamic
, DT_RELSZ
, rel_size
);
2106 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
2110 put_dt(dynamic
, DT_DEBUG
, 0);
2111 put_dt(dynamic
, DT_NULL
, 0);
2114 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
2115 ehdr
.e_phnum
= phnum
;
2116 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
2119 /* all other sections come after */
2120 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2121 s
= s1
->sections
[i
];
2122 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
2124 section_order
[sh_order_index
++] = i
;
2126 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
2127 ~(s
->sh_addralign
- 1);
2128 s
->sh_offset
= file_offset
;
2129 if (s
->sh_type
!= SHT_NOBITS
)
2130 file_offset
+= s
->sh_size
;
2133 /* if building executable or DLL, then relocate each section
2134 except the GOT which is already relocated */
2135 if (file_type
!= TCC_OUTPUT_OBJ
) {
2136 relocate_syms(s1
, 0);
2138 if (s1
->nb_errors
!= 0) {
2144 /* relocate sections */
2145 /* XXX: ignore sections with allocated relocations ? */
2146 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2147 s
= s1
->sections
[i
];
2148 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
2149 relocate_section(s1
, s
);
2152 /* relocate relocation entries if the relocation tables are
2153 allocated in the executable */
2154 for(i
= 1; i
< s1
->nb_sections
; i
++) {
2155 s
= s1
->sections
[i
];
2156 if ((s
->sh_flags
& SHF_ALLOC
) &&
2157 s
->sh_type
== SHT_RELX
) {
2158 relocate_rel(s1
, s
);
2162 /* get entry point address */
2163 if (file_type
== TCC_OUTPUT_EXE
)
2164 ehdr
.e_entry
= (uplong
)tcc_get_symbol_err(s1
, "_start");
2166 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
2169 /* write elf file */
2170 if (file_type
== TCC_OUTPUT_OBJ
)
2174 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
2176 error_noabort("could not write '%s'", filename
);
2179 f
= fdopen(fd
, "wb");
2181 printf("<- %s\n", filename
);
2183 #ifdef TCC_TARGET_COFF
2184 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
2185 tcc_output_coff(s1
, f
);
2188 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
2189 sort_syms(s1
, symtab_section
);
2192 file_offset
= (file_offset
+ 3) & -4;
2195 ehdr
.e_ident
[0] = ELFMAG0
;
2196 ehdr
.e_ident
[1] = ELFMAG1
;
2197 ehdr
.e_ident
[2] = ELFMAG2
;
2198 ehdr
.e_ident
[3] = ELFMAG3
;
2199 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
2200 ehdr
.e_ident
[5] = ELFDATA2LSB
;
2201 ehdr
.e_ident
[6] = EV_CURRENT
;
2203 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
2205 #ifdef TCC_TARGET_ARM
2207 ehdr
.e_ident
[EI_OSABI
] = 0;
2208 ehdr
.e_flags
= 4 << 24;
2210 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
2215 case TCC_OUTPUT_EXE
:
2216 ehdr
.e_type
= ET_EXEC
;
2218 case TCC_OUTPUT_DLL
:
2219 ehdr
.e_type
= ET_DYN
;
2221 case TCC_OUTPUT_OBJ
:
2222 ehdr
.e_type
= ET_REL
;
2225 ehdr
.e_machine
= EM_TCC_TARGET
;
2226 ehdr
.e_version
= EV_CURRENT
;
2227 ehdr
.e_shoff
= file_offset
;
2228 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
2229 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
2230 ehdr
.e_shnum
= shnum
;
2231 ehdr
.e_shstrndx
= shnum
- 1;
2233 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
2234 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
2235 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
2237 for(i
=1;i
<s1
->nb_sections
;i
++) {
2238 s
= s1
->sections
[section_order
[i
]];
2239 if (s
->sh_type
!= SHT_NOBITS
) {
2240 #if defined(__FreeBSD__)
2241 if (s
->sh_type
== SHT_DYNSYM
)
2242 patch_dynsym_undef(s1
, s
);
2244 while (offset
< s
->sh_offset
) {
2249 fwrite(s
->data
, 1, size
, f
);
2254 /* output section headers */
2255 while (offset
< ehdr
.e_shoff
) {
2260 for(i
=0;i
<s1
->nb_sections
;i
++) {
2262 memset(sh
, 0, sizeof(ElfW(Shdr
)));
2263 s
= s1
->sections
[i
];
2265 sh
->sh_name
= s
->sh_name
;
2266 sh
->sh_type
= s
->sh_type
;
2267 sh
->sh_flags
= s
->sh_flags
;
2268 sh
->sh_entsize
= s
->sh_entsize
;
2269 sh
->sh_info
= s
->sh_info
;
2271 sh
->sh_link
= s
->link
->sh_num
;
2272 sh
->sh_addralign
= s
->sh_addralign
;
2273 sh
->sh_addr
= s
->sh_addr
;
2274 sh
->sh_offset
= s
->sh_offset
;
2275 sh
->sh_size
= s
->sh_size
;
2277 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
2280 tcc_output_binary(s1
, f
, section_order
);
2286 tcc_free(s1
->symtab_to_dynsym
);
2287 tcc_free(section_order
);
2289 tcc_free(s1
->got_offsets
);
2293 int tcc_output_file(TCCState
*s
, const char *filename
)
2296 #ifdef TCC_TARGET_PE
2297 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
2298 ret
= pe_output_file(s
, filename
);
2302 ret
= elf_output_file(s
, filename
);
2307 void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
2311 data
= tcc_malloc(size
);
2312 lseek(fd
, file_offset
, SEEK_SET
);
2313 read(fd
, data
, size
);
2317 typedef struct SectionMergeInfo
{
2318 Section
*s
; /* corresponding existing section */
2319 unsigned long offset
; /* offset of the new section in the existing section */
2320 uint8_t new_section
; /* true if section 's' was added */
2321 uint8_t link_once
; /* true if link once section */
2324 /* load an object file and merge it with current files */
2325 /* XXX: handle correctly stab (debug) info */
2326 int tcc_load_object_file(TCCState
*s1
,
2327 int fd
, unsigned long file_offset
)
2330 ElfW(Shdr
) *shdr
, *sh
;
2331 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
2332 unsigned char *strsec
, *strtab
;
2333 int *old_to_new_syms
;
2334 char *sh_name
, *name
;
2335 SectionMergeInfo
*sm_table
, *sm
;
2336 ElfW(Sym
) *sym
, *symtab
;
2337 ElfW_Rel
*rel
, *rel_end
;
2343 stab_index
= stabstr_index
= 0;
2345 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
2347 if (ehdr
.e_ident
[0] != ELFMAG0
||
2348 ehdr
.e_ident
[1] != ELFMAG1
||
2349 ehdr
.e_ident
[2] != ELFMAG2
||
2350 ehdr
.e_ident
[3] != ELFMAG3
)
2352 /* test if object file */
2353 if (ehdr
.e_type
!= ET_REL
)
2355 /* test CPU specific stuff */
2356 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2357 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2359 error_noabort("invalid object file");
2363 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
2364 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2365 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
2367 /* load section names */
2368 sh
= &shdr
[ehdr
.e_shstrndx
];
2369 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2371 /* load symtab and strtab */
2372 old_to_new_syms
= NULL
;
2376 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2378 if (sh
->sh_type
== SHT_SYMTAB
) {
2380 error_noabort("object must contain only one symtab");
2385 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2386 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2387 sm_table
[i
].s
= symtab_section
;
2389 /* now load strtab */
2390 sh
= &shdr
[sh
->sh_link
];
2391 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
2395 /* now examine each section and try to merge its content with the
2397 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2398 /* no need to examine section name strtab */
2399 if (i
== ehdr
.e_shstrndx
)
2402 sh_name
= strsec
+ sh
->sh_name
;
2403 /* ignore sections types we do not handle */
2404 if (sh
->sh_type
!= SHT_PROGBITS
&&
2405 sh
->sh_type
!= SHT_RELX
&&
2407 sh
->sh_type
!= SHT_ARM_EXIDX
&&
2409 sh
->sh_type
!= SHT_NOBITS
&&
2410 strcmp(sh_name
, ".stabstr")
2413 if (sh
->sh_addralign
< 1)
2414 sh
->sh_addralign
= 1;
2415 /* find corresponding section, if any */
2416 for(j
= 1; j
< s1
->nb_sections
;j
++) {
2417 s
= s1
->sections
[j
];
2418 if (!strcmp(s
->name
, sh_name
)) {
2419 if (!strncmp(sh_name
, ".gnu.linkonce",
2420 sizeof(".gnu.linkonce") - 1)) {
2421 /* if a 'linkonce' section is already present, we
2422 do not add it again. It is a little tricky as
2423 symbols can still be defined in
2425 sm_table
[i
].link_once
= 1;
2432 /* not found: create new section */
2433 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
2434 /* take as much info as possible from the section. sh_link and
2435 sh_info will be updated later */
2436 s
->sh_addralign
= sh
->sh_addralign
;
2437 s
->sh_entsize
= sh
->sh_entsize
;
2438 sm_table
[i
].new_section
= 1;
2440 if (sh
->sh_type
!= s
->sh_type
) {
2441 error_noabort("invalid section type");
2445 /* align start of section */
2446 offset
= s
->data_offset
;
2448 if (0 == strcmp(sh_name
, ".stab")) {
2452 if (0 == strcmp(sh_name
, ".stabstr")) {
2457 size
= sh
->sh_addralign
- 1;
2458 offset
= (offset
+ size
) & ~size
;
2459 if (sh
->sh_addralign
> s
->sh_addralign
)
2460 s
->sh_addralign
= sh
->sh_addralign
;
2461 s
->data_offset
= offset
;
2463 sm_table
[i
].offset
= offset
;
2465 /* concatenate sections */
2467 if (sh
->sh_type
!= SHT_NOBITS
) {
2469 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
2470 ptr
= section_ptr_add(s
, size
);
2471 read(fd
, ptr
, size
);
2473 s
->data_offset
+= size
;
2478 /* //gr relocate stab strings */
2479 if (stab_index
&& stabstr_index
) {
2482 s
= sm_table
[stab_index
].s
;
2483 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2484 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2485 o
= sm_table
[stabstr_index
].offset
;
2487 a
->n_strx
+= o
, a
++;
2490 /* second short pass to update sh_link and sh_info fields of new
2492 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2494 if (!s
|| !sm_table
[i
].new_section
)
2497 if (sh
->sh_link
> 0)
2498 s
->link
= sm_table
[sh
->sh_link
].s
;
2499 if (sh
->sh_type
== SHT_RELX
) {
2500 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2501 /* update backward link */
2502 s1
->sections
[s
->sh_info
]->reloc
= s
;
2507 /* resolve symbols */
2508 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2511 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2512 if (sym
->st_shndx
!= SHN_UNDEF
&&
2513 sym
->st_shndx
< SHN_LORESERVE
) {
2514 sm
= &sm_table
[sym
->st_shndx
];
2515 if (sm
->link_once
) {
2516 /* if a symbol is in a link once section, we use the
2517 already defined symbol. It is very important to get
2518 correct relocations */
2519 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2520 name
= strtab
+ sym
->st_name
;
2521 sym_index
= find_elf_sym(symtab_section
, name
);
2523 old_to_new_syms
[i
] = sym_index
;
2527 /* if no corresponding section added, no need to add symbol */
2530 /* convert section number */
2531 sym
->st_shndx
= sm
->s
->sh_num
;
2533 sym
->st_value
+= sm
->offset
;
2536 name
= strtab
+ sym
->st_name
;
2537 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2538 sym
->st_info
, sym
->st_other
,
2539 sym
->st_shndx
, name
);
2540 old_to_new_syms
[i
] = sym_index
;
2543 /* third pass to patch relocation entries */
2544 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2549 offset
= sm_table
[i
].offset
;
2550 switch(s
->sh_type
) {
2552 /* take relocation offset information */
2553 offseti
= sm_table
[sh
->sh_info
].offset
;
2554 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2555 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2560 /* convert symbol index */
2561 type
= ELFW(R_TYPE
)(rel
->r_info
);
2562 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2563 /* NOTE: only one symtab assumed */
2564 if (sym_index
>= nb_syms
)
2566 sym_index
= old_to_new_syms
[sym_index
];
2567 /* ignore link_once in rel section. */
2568 if (!sym_index
&& !sm
->link_once
) {
2570 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2571 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2574 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2575 /* offset the relocation offset */
2576 rel
->r_offset
+= offseti
;
2588 tcc_free(old_to_new_syms
);
2595 typedef struct ArchiveHeader
{
2596 char ar_name
[16]; /* name of this member */
2597 char ar_date
[12]; /* file mtime */
2598 char ar_uid
[6]; /* owner uid; printed as decimal */
2599 char ar_gid
[6]; /* owner gid; printed as decimal */
2600 char ar_mode
[8]; /* file mode, printed as octal */
2601 char ar_size
[10]; /* file size, printed as decimal */
2602 char ar_fmag
[2]; /* should contain ARFMAG */
2605 static int get_be32(const uint8_t *b
)
2607 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2610 /* load only the objects which resolve undefined symbols */
2611 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2613 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2615 const char *ar_names
, *p
;
2616 const uint8_t *ar_index
;
2619 data
= tcc_malloc(size
);
2620 if (read(fd
, data
, size
) != size
)
2622 nsyms
= get_be32(data
);
2623 ar_index
= data
+ 4;
2624 ar_names
= ar_index
+ nsyms
* 4;
2628 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2629 sym_index
= find_elf_sym(symtab_section
, p
);
2631 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2632 if(sym
->st_shndx
== SHN_UNDEF
) {
2633 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2635 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2638 lseek(fd
, off
, SEEK_SET
);
2639 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2654 /* load a '.a' file */
2655 int tcc_load_archive(TCCState
*s1
, int fd
)
2662 unsigned long file_offset
;
2664 /* skip magic which was already checked */
2665 read(fd
, magic
, sizeof(magic
));
2668 len
= read(fd
, &hdr
, sizeof(hdr
));
2671 if (len
!= sizeof(hdr
)) {
2672 error_noabort("invalid archive");
2675 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2676 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2677 size
= strtol(ar_size
, NULL
, 0);
2678 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2679 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2680 if (ar_name
[i
] != ' ')
2683 ar_name
[i
+ 1] = '\0';
2684 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2685 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2687 size
= (size
+ 1) & ~1;
2688 if (!strcmp(ar_name
, "/")) {
2689 /* coff symbol table : we handle it */
2690 if(s1
->alacarte_link
)
2691 return tcc_load_alacarte(s1
, fd
, size
);
2692 } else if (!strcmp(ar_name
, "//") ||
2693 !strcmp(ar_name
, "__.SYMDEF") ||
2694 !strcmp(ar_name
, "__.SYMDEF/") ||
2695 !strcmp(ar_name
, "ARFILENAMES/")) {
2696 /* skip symbol table or archive names */
2698 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2701 lseek(fd
, file_offset
+ size
, SEEK_SET
);