2 * ELF file handling for TCC
4 * Copyright (c) 2001, 2002 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 static int put_elf_str(Section
*s
, const char *sym
)
26 len
= strlen(sym
) + 1;
27 offset
= s
->data_offset
;
28 ptr
= section_ptr_add(s
, len
);
29 memcpy(ptr
, sym
, len
);
33 /* elf symbol hashing function */
34 static unsigned long elf_hash(const unsigned char *name
)
36 unsigned long h
= 0, g
;
39 h
= (h
<< 4) + *name
++;
48 /* rebuild hash table of section s */
49 /* NOTE: we do factorize the hash table code to go faster */
50 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
53 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
56 strtab
= s
->link
->data
;
57 nb_syms
= s
->data_offset
/ sizeof(Elf32_Sym
);
59 s
->hash
->data_offset
= 0;
60 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
65 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
66 ptr
+= nb_buckets
+ 1;
68 sym
= (Elf32_Sym
*)s
->data
+ 1;
69 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
70 if (ELF32_ST_BIND(sym
->st_info
) != STB_LOCAL
) {
71 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
82 /* return the symbol number */
83 static int put_elf_sym(Section
*s
,
84 unsigned long value
, unsigned long size
,
85 int info
, int other
, int shndx
, const char *name
)
87 int name_offset
, sym_index
;
92 sym
= section_ptr_add(s
, sizeof(Elf32_Sym
));
94 name_offset
= put_elf_str(s
->link
, name
);
98 sym
->st_name
= name_offset
;
99 sym
->st_value
= value
;
102 sym
->st_other
= other
;
103 sym
->st_shndx
= shndx
;
104 sym_index
= sym
- (Elf32_Sym
*)s
->data
;
108 ptr
= section_ptr_add(hs
, sizeof(int));
109 base
= (int *)hs
->data
;
110 /* only add global or weak symbols */
111 if (ELF32_ST_BIND(info
) != STB_LOCAL
) {
112 /* add another hashing entry */
114 h
= elf_hash(name
) % nbuckets
;
116 base
[2 + h
] = sym_index
;
118 /* we resize the hash table */
119 hs
->nb_hashed_syms
++;
120 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
121 rebuild_hash(s
, 2 * nbuckets
);
131 /* find global ELF symbol 'name' and return its index. Return 0 if not
133 static int find_elf_sym(Section
*s
, const char *name
)
137 int nbuckets
, sym_index
, h
;
143 nbuckets
= ((int *)hs
->data
)[0];
144 h
= elf_hash(name
) % nbuckets
;
145 sym_index
= ((int *)hs
->data
)[2 + h
];
146 while (sym_index
!= 0) {
147 sym
= &((Elf32_Sym
*)s
->data
)[sym_index
];
148 name1
= s
->link
->data
+ sym
->st_name
;
149 if (!strcmp(name
, name1
))
151 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
156 /* return elf symbol value or error */
157 int tcc_get_symbol(TCCState
*s
, unsigned long *pval
, const char *name
)
162 sym_index
= find_elf_sym(symtab_section
, name
);
165 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
166 *pval
= sym
->st_value
;
170 void *tcc_get_symbol_err(TCCState
*s
, const char *name
)
173 if (tcc_get_symbol(s
, &val
, name
) < 0)
174 error("%s not defined", name
);
178 /* add an elf symbol : check if it is already defined and patch
179 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
180 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
181 int info
, int sh_num
, const char *name
)
184 int sym_bind
, sym_index
, sym_type
, esym_bind
;
186 sym_bind
= ELF32_ST_BIND(info
);
187 sym_type
= ELF32_ST_TYPE(info
);
189 if (sym_bind
!= STB_LOCAL
) {
190 /* we search global or weak symbols */
191 sym_index
= find_elf_sym(s
, name
);
194 esym
= &((Elf32_Sym
*)s
->data
)[sym_index
];
195 if (esym
->st_shndx
!= SHN_UNDEF
) {
196 esym_bind
= ELF32_ST_BIND(esym
->st_info
);
197 if (sh_num
== SHN_UNDEF
) {
198 /* ignore adding of undefined symbol if the
199 corresponding symbol is already defined */
200 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
201 /* global overrides weak, so patch */
203 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
204 /* weak is ignored if already global */
207 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
208 sym_bind
, sh_num
, esym_bind
, esym
->st_shndx
);
210 /* NOTE: we accept that two DLL define the same symbol */
211 if (s
!= tcc_state
->dynsymtab_section
)
212 error_noabort("'%s' defined twice", name
);
216 esym
->st_info
= ELF32_ST_INFO(sym_bind
, sym_type
);
217 esym
->st_shndx
= sh_num
;
218 esym
->st_value
= value
;
219 esym
->st_size
= size
;
223 sym_index
= put_elf_sym(s
, value
, size
,
224 ELF32_ST_INFO(sym_bind
, sym_type
), 0,
231 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
232 int type
, int symbol
)
240 /* if no relocation section, create it */
241 snprintf(buf
, sizeof(buf
), ".rel%s", s
->name
);
242 /* if the symtab is allocated, then we consider the relocation
244 sr
= new_section(tcc_state
, buf
, SHT_REL
, symtab
->sh_flags
);
245 sr
->sh_entsize
= sizeof(Elf32_Rel
);
247 sr
->sh_info
= s
->sh_num
;
250 rel
= section_ptr_add(sr
, sizeof(Elf32_Rel
));
251 rel
->r_offset
= offset
;
252 rel
->r_info
= ELF32_R_INFO(symbol
, type
);
255 /* put stab debug information */
258 unsigned long n_strx
; /* index into string table of name */
259 unsigned char n_type
; /* type of symbol */
260 unsigned char n_other
; /* misc info (usually empty) */
261 unsigned short n_desc
; /* description field */
262 unsigned long n_value
; /* value of symbol */
265 static void put_stabs(const char *str
, int type
, int other
, int desc
,
270 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
272 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
277 sym
->n_other
= other
;
279 sym
->n_value
= value
;
282 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
283 unsigned long value
, Section
*sec
, int sym_index
)
285 put_stabs(str
, type
, other
, desc
, value
);
286 put_elf_reloc(symtab_section
, stab_section
,
287 stab_section
->data_offset
- sizeof(unsigned long),
288 R_DATA_32
, sym_index
);
291 static void put_stabn(int type
, int other
, int desc
, int value
)
293 put_stabs(NULL
, type
, other
, desc
, value
);
296 static void put_stabd(int type
, int other
, int desc
)
298 put_stabs(NULL
, type
, other
, desc
, 0);
301 /* In an ELF file symbol table, the local symbols must appear below
302 the global and weak ones. Since TCC cannot sort it while generating
303 the code, we must do it after. All the relocation tables are also
304 modified to take into account the symbol table sorting */
305 static void sort_syms(TCCState
*s1
, Section
*s
)
307 int *old_to_new_syms
;
311 Elf32_Rel
*rel
, *rel_end
;
315 nb_syms
= s
->data_offset
/ sizeof(Elf32_Sym
);
316 new_syms
= tcc_malloc(nb_syms
* sizeof(Elf32_Sym
));
317 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
319 /* first pass for local symbols */
320 p
= (Elf32_Sym
*)s
->data
;
322 for(i
= 0; i
< nb_syms
; i
++) {
323 if (ELF32_ST_BIND(p
->st_info
) == STB_LOCAL
) {
324 old_to_new_syms
[i
] = q
- new_syms
;
329 /* save the number of local symbols in section header */
330 s
->sh_info
= q
- new_syms
;
332 /* then second pass for non local symbols */
333 p
= (Elf32_Sym
*)s
->data
;
334 for(i
= 0; i
< nb_syms
; i
++) {
335 if (ELF32_ST_BIND(p
->st_info
) != STB_LOCAL
) {
336 old_to_new_syms
[i
] = q
- new_syms
;
342 /* we copy the new symbols to the old */
343 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(Elf32_Sym
));
346 /* now we modify all the relocations */
347 for(i
= 1; i
< s1
->nb_sections
; i
++) {
348 sr
= s1
->sections
[i
];
349 if (sr
->sh_type
== SHT_REL
&& sr
->link
== s
) {
350 rel_end
= (Elf32_Rel
*)(sr
->data
+ sr
->data_offset
);
351 for(rel
= (Elf32_Rel
*)sr
->data
;
354 sym_index
= ELF32_R_SYM(rel
->r_info
);
355 type
= ELF32_R_TYPE(rel
->r_info
);
356 sym_index
= old_to_new_syms
[sym_index
];
357 rel
->r_info
= ELF32_R_INFO(sym_index
, type
);
362 tcc_free(old_to_new_syms
);
365 /* relocate common symbols in the .bss section */
366 static void relocate_common_syms(void)
368 Elf32_Sym
*sym
, *sym_end
;
369 unsigned long offset
, align
;
371 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
372 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
375 if (sym
->st_shndx
== SHN_COMMON
) {
377 align
= sym
->st_value
;
378 offset
= bss_section
->data_offset
;
379 offset
= (offset
+ align
- 1) & -align
;
380 sym
->st_value
= offset
;
381 sym
->st_shndx
= bss_section
->sh_num
;
382 offset
+= sym
->st_size
;
383 bss_section
->data_offset
= offset
;
388 static void *resolve_sym(const char *sym
)
390 return dlsym(RTLD_DEFAULT
, sym
);
393 /* relocate symbol table, resolve undefined symbols if do_resolve is
394 true and output error if undefined symbol. */
395 static void relocate_syms(TCCState
*s1
, int do_resolve
)
397 Elf32_Sym
*sym
, *esym
, *sym_end
;
398 int sym_bind
, sh_num
, sym_index
;
402 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
403 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
406 sh_num
= sym
->st_shndx
;
407 if (sh_num
== SHN_UNDEF
) {
408 name
= strtab_section
->data
+ sym
->st_name
;
410 name
= symtab_section
->link
->data
+ sym
->st_name
;
411 addr
= (unsigned long)resolve_sym(name
);
413 sym
->st_value
= addr
;
416 } else if (s1
->dynsym
) {
417 /* if dynamic symbol exist, then use it */
418 sym_index
= find_elf_sym(s1
->dynsym
, name
);
420 esym
= &((Elf32_Sym
*)s1
->dynsym
->data
)[sym_index
];
421 sym
->st_value
= esym
->st_value
;
425 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
427 if (!strcmp(name
, "_fp_hw"))
429 /* only weak symbols are accepted to be undefined. Their
431 sym_bind
= ELF32_ST_BIND(sym
->st_info
);
432 if (sym_bind
== STB_WEAK
) {
435 error_noabort("undefined symbol '%s'", name
);
437 } else if (sh_num
< SHN_LORESERVE
) {
438 /* add section base */
439 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
445 /* relocate a given section (CPU dependent) */
446 static void relocate_section(TCCState
*s1
, Section
*s
)
449 Elf32_Rel
*rel
, *rel_end
, *qrel
;
451 int type
, sym_index
, esym_index
;
453 unsigned long val
, addr
;
456 rel_end
= (Elf32_Rel
*)(sr
->data
+ sr
->data_offset
);
457 qrel
= (Elf32_Rel
*)sr
->data
;
461 ptr
= s
->data
+ rel
->r_offset
;
463 sym_index
= ELF32_R_SYM(rel
->r_info
);
464 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
466 type
= ELF32_R_TYPE(rel
->r_info
);
467 addr
= s
->sh_addr
+ rel
->r_offset
;
471 #if defined(TCC_TARGET_I386)
473 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
474 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
475 qrel
->r_offset
= rel
->r_offset
;
477 qrel
->r_info
= ELF32_R_INFO(esym_index
, R_386_32
);
481 qrel
->r_info
= ELF32_R_INFO(0, R_386_RELATIVE
);
488 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
490 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
492 qrel
->r_offset
= rel
->r_offset
;
493 qrel
->r_info
= ELF32_R_INFO(esym_index
, R_386_PC32
);
498 *(int *)ptr
+= val
- addr
;
501 *(int *)ptr
+= val
- addr
;
508 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
511 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
514 /* we load the got offset */
515 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
517 #elif defined(TCC_TARGET_ARM)
522 x
= (*(int *)ptr
)&0xffffff;
523 (*(int *)ptr
) &= 0xff000000;
528 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
529 error("can't relocate value at %x",addr
);
539 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
542 /* we load the got offset */
543 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
548 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
549 type
,addr
,(unsigned int )ptr
,val
);
551 #elif defined(TCC_TARGET_C67)
559 /* put the low 16 bits of the absolute address */
560 // add to what is already there
562 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
563 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
565 //patch both at once - assumes always in pairs Low - High
567 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
568 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
574 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
575 type
,addr
,(unsigned int )ptr
,val
);
578 #error unsupported processor
582 /* if the relocation is allocated, we change its symbol table */
583 if (sr
->sh_flags
& SHF_ALLOC
)
584 sr
->link
= s1
->dynsym
;
587 /* relocate relocation table in 'sr' */
588 static void relocate_rel(TCCState
*s1
, Section
*sr
)
591 Elf32_Rel
*rel
, *rel_end
;
593 s
= s1
->sections
[sr
->sh_info
];
594 rel_end
= (Elf32_Rel
*)(sr
->data
+ sr
->data_offset
);
595 for(rel
= (Elf32_Rel
*)sr
->data
;
598 rel
->r_offset
+= s
->sh_addr
;
602 /* count the number of dynamic relocations so that we can reserve
604 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
606 Elf32_Rel
*rel
, *rel_end
;
607 int sym_index
, esym_index
, type
, count
;
610 rel_end
= (Elf32_Rel
*)(sr
->data
+ sr
->data_offset
);
611 for(rel
= (Elf32_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
612 sym_index
= ELF32_R_SYM(rel
->r_info
);
613 type
= ELF32_R_TYPE(rel
->r_info
);
619 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
628 /* allocate the section */
629 sr
->sh_flags
|= SHF_ALLOC
;
630 sr
->sh_size
= count
* sizeof(Elf32_Rel
);
635 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
640 if (index
>= s1
->nb_got_offsets
) {
641 /* find immediately bigger power of 2 and reallocate array */
645 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
647 error("memory full");
648 s1
->got_offsets
= tab
;
649 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
650 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
651 s1
->nb_got_offsets
= n
;
653 s1
->got_offsets
[index
] = val
;
656 /* XXX: suppress that */
657 static void put32(unsigned char *p
, uint32_t val
)
665 static uint32_t get32(unsigned char *p
)
667 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
670 static void build_got(TCCState
*s1
)
674 /* if no got, then create it */
675 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
676 s1
->got
->sh_entsize
= 4;
677 add_elf_sym(symtab_section
, 0, 4, ELF32_ST_INFO(STB_GLOBAL
, STT_OBJECT
),
678 s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
679 ptr
= section_ptr_add(s1
->got
, 3 * sizeof(int));
680 /* keep space for _DYNAMIC pointer, if present */
682 /* two dummy got entries */
687 /* put a got entry corresponding to a symbol in symtab_section. 'size'
688 and 'info' can be modifed if more precise info comes from the DLL */
689 static void put_got_entry(TCCState
*s1
,
690 int reloc_type
, unsigned long size
, int info
,
696 unsigned long offset
;
702 /* if a got entry already exists for that symbol, no need to add one */
703 if (sym_index
< s1
->nb_got_offsets
&&
704 s1
->got_offsets
[sym_index
] != 0)
707 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
710 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
711 name
= symtab_section
->link
->data
+ sym
->st_name
;
712 offset
= sym
->st_value
;
713 #ifdef TCC_TARGET_I386
714 if (reloc_type
== R_386_JMP_SLOT
) {
719 /* if we build a DLL, we add a %ebx offset */
720 if (s1
->output_type
== TCC_OUTPUT_DLL
)
725 /* add a PLT entry */
727 if (plt
->data_offset
== 0) {
728 /* first plt entry */
729 p
= section_ptr_add(plt
, 16);
730 p
[0] = 0xff; /* pushl got + 4 */
733 p
[6] = 0xff; /* jmp *(got + 8) */
738 p
= section_ptr_add(plt
, 16);
739 p
[0] = 0xff; /* jmp *(got + x) */
741 put32(p
+ 2, s1
->got
->data_offset
);
742 p
[6] = 0x68; /* push $xxx */
743 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
744 p
[11] = 0xe9; /* jmp plt_start */
745 put32(p
+ 12, -(plt
->data_offset
));
747 /* the symbol is modified so that it will be relocated to
749 if (s1
->output_type
== TCC_OUTPUT_EXE
)
750 offset
= plt
->data_offset
- 16;
752 #elif defined(TCC_TARGET_ARM)
753 if (reloc_type
== R_ARM_JUMP_SLOT
) {
757 /* if we build a DLL, we add a %ebx offset */
758 if (s1
->output_type
== TCC_OUTPUT_DLL
)
759 error("DLLs unimplemented!");
761 /* add a PLT entry */
763 if (plt
->data_offset
== 0) {
764 /* first plt entry */
765 p
= section_ptr_add(plt
, 16);
766 put32(p
, 0xe52de004);
767 put32(p
+ 4, 0xe59fe010);
768 put32(p
+ 8, 0xe08fe00e);
769 put32(p
+ 12, 0xe5bef008);
772 p
= section_ptr_add(plt
, 16);
773 put32(p
, 0xe59fc004);
774 put32(p
+4, 0xe08fc00c);
775 put32(p
+8, 0xe59cf000);
776 put32(p
+12, s1
->got
->data_offset
);
778 /* the symbol is modified so that it will be relocated to
780 if (s1
->output_type
== TCC_OUTPUT_EXE
)
781 offset
= plt
->data_offset
- 16;
783 #elif defined(TCC_TARGET_C67)
784 error("C67 got not implemented");
786 #error unsupported CPU
788 index
= put_elf_sym(s1
->dynsym
, offset
,
789 size
, info
, 0, sym
->st_shndx
, name
);
790 /* put a got entry */
791 put_elf_reloc(s1
->dynsym
, s1
->got
,
792 s1
->got
->data_offset
,
795 ptr
= section_ptr_add(s1
->got
, sizeof(int));
799 /* build GOT and PLT entries */
800 static void build_got_entries(TCCState
*s1
)
803 Elf32_Rel
*rel
, *rel_end
;
805 int i
, type
, reloc_type
, sym_index
;
807 for(i
= 1; i
< s1
->nb_sections
; i
++) {
809 if (s
->sh_type
!= SHT_REL
)
811 /* no need to handle got relocations */
812 if (s
->link
!= symtab_section
)
815 rel_end
= (Elf32_Rel
*)(s
->data
+ s
->data_offset
);
816 for(rel
= (Elf32_Rel
*)s
->data
;
819 type
= ELF32_R_TYPE(rel
->r_info
);
821 #if defined(TCC_TARGET_I386)
828 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
829 sym_index
= ELF32_R_SYM(rel
->r_info
);
830 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
831 /* look at the symbol got offset. If none, then add one */
832 if (type
== R_386_GOT32
)
833 reloc_type
= R_386_GLOB_DAT
;
835 reloc_type
= R_386_JMP_SLOT
;
836 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
840 #elif defined(TCC_TARGET_ARM)
847 if (type
== R_ARM_GOT32
|| type
== R_ARM_PLT32
) {
848 sym_index
= ELF32_R_SYM(rel
->r_info
);
849 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
850 /* look at the symbol got offset. If none, then add one */
851 if (type
== R_ARM_GOT32
)
852 reloc_type
= R_ARM_GLOB_DAT
;
854 reloc_type
= R_ARM_JUMP_SLOT
;
855 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
859 #elif defined(TCC_TARGET_C67)
866 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
867 sym_index
= ELF32_R_SYM(rel
->r_info
);
868 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
869 /* look at the symbol got offset. If none, then add one */
870 if (type
== R_C60_GOT32
)
871 reloc_type
= R_C60_GLOB_DAT
;
873 reloc_type
= R_C60_JMP_SLOT
;
874 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
879 #error unsupported CPU
888 static Section
*new_symtab(TCCState
*s1
,
889 const char *symtab_name
, int sh_type
, int sh_flags
,
890 const char *strtab_name
,
891 const char *hash_name
, int hash_sh_flags
)
893 Section
*symtab
, *strtab
, *hash
;
894 int *ptr
, nb_buckets
;
896 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
897 symtab
->sh_entsize
= sizeof(Elf32_Sym
);
898 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
899 put_elf_str(strtab
, "");
900 symtab
->link
= strtab
;
901 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
905 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
906 hash
->sh_entsize
= sizeof(int);
910 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
913 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
917 /* put dynamic tag */
918 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
921 dyn
= section_ptr_add(dynamic
, sizeof(Elf32_Dyn
));
923 dyn
->d_un
.d_val
= val
;
926 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
930 char sym_start
[1024];
933 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
934 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
936 s
= find_section(s1
, section_name
);
941 end_offset
= s
->data_offset
;
944 add_elf_sym(symtab_section
,
946 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
947 s
->sh_num
, sym_start
);
948 add_elf_sym(symtab_section
,
950 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
954 /* add tcc runtime libraries */
955 static void tcc_add_runtime(TCCState
*s1
)
962 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "libtcc1.a");
963 tcc_add_file(s1
, buf
);
965 #ifdef CONFIG_TCC_BCHECK
966 if (do_bounds_check
) {
968 Section
*init_section
;
969 unsigned char *pinit
;
972 /* XXX: add an object file to do that */
973 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
975 add_elf_sym(symtab_section
, 0, 0,
976 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
977 bounds_section
->sh_num
, "__bounds_start");
978 /* add bound check code */
979 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "bcheck.o");
980 tcc_add_file(s1
, buf
);
981 #ifdef TCC_TARGET_I386
982 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
983 /* add 'call __bound_init()' in .init section */
984 init_section
= find_section(s1
, ".init");
985 pinit
= section_ptr_add(init_section
, 5);
987 put32(pinit
+ 1, -4);
988 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
989 put_elf_reloc(symtab_section
, init_section
,
990 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
997 tcc_add_library(s1
, "c");
999 /* add crt end if not memory output */
1000 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1001 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1003 /* add various standard linker symbols */
1004 add_elf_sym(symtab_section
,
1005 text_section
->data_offset
, 0,
1006 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
1007 text_section
->sh_num
, "_etext");
1008 add_elf_sym(symtab_section
,
1009 data_section
->data_offset
, 0,
1010 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
1011 data_section
->sh_num
, "_edata");
1012 add_elf_sym(symtab_section
,
1013 bss_section
->data_offset
, 0,
1014 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
1015 bss_section
->sh_num
, "_end");
1016 /* horrible new standard ldscript defines */
1017 add_init_array_defines(s1
, ".preinit_array");
1018 add_init_array_defines(s1
, ".init_array");
1019 add_init_array_defines(s1
, ".fini_array");
1021 /* add start and stop symbols for sections whose name can be
1023 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1024 s
= s1
->sections
[i
];
1025 if (s
->sh_type
== SHT_PROGBITS
&&
1026 (s
->sh_flags
& SHF_ALLOC
)) {
1030 /* check if section name can be expressed in C */
1036 if (!isid(ch
) && !isnum(ch
))
1040 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1041 add_elf_sym(symtab_section
,
1043 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
1045 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1046 add_elf_sym(symtab_section
,
1048 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
1055 /* name of ELF interpreter */
1057 static char elf_interp
[] = "/usr/libexec/ld-elf.so.1";
1059 static char elf_interp
[] = "/lib/ld-linux.so.2";
1062 /* output an ELF file */
1063 /* XXX: suppress unneeded sections */
1064 int tcc_output_file(TCCState
*s1
, const char *filename
)
1070 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1072 Section
*strsec
, *s
;
1073 Elf32_Shdr shdr
, *sh
;
1074 Elf32_Phdr
*phdr
, *ph
;
1075 Section
*interp
, *dynamic
, *dynstr
;
1076 unsigned long saved_dynamic_data_offset
;
1078 int type
, file_type
;
1079 unsigned long rel_addr
, rel_size
;
1081 file_type
= s1
->output_type
;
1084 if (file_type
!= TCC_OUTPUT_OBJ
)
1085 tcc_add_runtime(s1
);
1088 section_order
= NULL
;
1091 dynstr
= NULL
; /* avoid warning */
1092 saved_dynamic_data_offset
= 0; /* avoid warning */
1094 if (file_type
!= TCC_OUTPUT_OBJ
) {
1096 relocate_common_syms();
1098 if (!s1
->static_link
) {
1100 int sym_index
, index
;
1101 Elf32_Sym
*esym
, *sym_end
;
1103 if (file_type
== TCC_OUTPUT_EXE
) {
1105 /* add interpreter section only if executable */
1106 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1107 interp
->sh_addralign
= 1;
1108 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
1109 strcpy(ptr
, elf_interp
);
1112 /* add dynamic symbol table */
1113 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1115 ".hash", SHF_ALLOC
);
1116 dynstr
= s1
->dynsym
->link
;
1118 /* add dynamic section */
1119 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1120 SHF_ALLOC
| SHF_WRITE
);
1121 dynamic
->link
= dynstr
;
1122 dynamic
->sh_entsize
= sizeof(Elf32_Dyn
);
1125 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1126 SHF_ALLOC
| SHF_EXECINSTR
);
1127 s1
->plt
->sh_entsize
= 4;
1131 /* scan for undefined symbols and see if they are in the
1132 dynamic symbols. If a symbol STT_FUNC is found, then we
1133 add it in the PLT. If a symbol STT_OBJECT is found, we
1134 add it in the .bss section with a suitable relocation */
1135 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+
1136 symtab_section
->data_offset
);
1137 if (file_type
== TCC_OUTPUT_EXE
) {
1138 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
1141 if (sym
->st_shndx
== SHN_UNDEF
) {
1142 name
= symtab_section
->link
->data
+ sym
->st_name
;
1143 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1145 esym
= &((Elf32_Sym
*)s1
->dynsymtab_section
->data
)[sym_index
];
1146 type
= ELF32_ST_TYPE(esym
->st_info
);
1147 if (type
== STT_FUNC
) {
1148 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1150 sym
- (Elf32_Sym
*)symtab_section
->data
);
1151 } else if (type
== STT_OBJECT
) {
1152 unsigned long offset
;
1153 offset
= bss_section
->data_offset
;
1154 /* XXX: which alignment ? */
1155 offset
= (offset
+ 16 - 1) & -16;
1156 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1158 bss_section
->sh_num
, name
);
1159 put_elf_reloc(s1
->dynsym
, bss_section
,
1160 offset
, R_COPY
, index
);
1161 offset
+= esym
->st_size
;
1162 bss_section
->data_offset
= offset
;
1165 /* STB_WEAK undefined symbols are accepted */
1166 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1168 if (ELF32_ST_BIND(sym
->st_info
) == STB_WEAK
||
1169 !strcmp(name
, "_fp_hw")) {
1171 error_noabort("undefined symbol '%s'", name
);
1174 } else if (s1
->rdynamic
&&
1175 ELF32_ST_BIND(sym
->st_info
) != STB_LOCAL
) {
1176 /* if -rdynamic option, then export all non
1178 name
= symtab_section
->link
->data
+ sym
->st_name
;
1179 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1181 sym
->st_shndx
, name
);
1188 /* now look at unresolved dynamic symbols and export
1189 corresponding symbol */
1190 sym_end
= (Elf32_Sym
*)(s1
->dynsymtab_section
->data
+
1191 s1
->dynsymtab_section
->data_offset
);
1192 for(esym
= (Elf32_Sym
*)s1
->dynsymtab_section
->data
+ 1;
1195 if (esym
->st_shndx
== SHN_UNDEF
) {
1196 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1197 sym_index
= find_elf_sym(symtab_section
, name
);
1199 /* XXX: avoid adding a symbol if already
1200 present because of -rdynamic ? */
1201 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
1202 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1204 sym
->st_shndx
, name
);
1206 if (ELF32_ST_BIND(esym
->st_info
) == STB_WEAK
) {
1207 /* weak symbols can stay undefined */
1209 warning("undefined dynamic symbol '%s'", name
);
1216 /* shared library case : we simply export all the global symbols */
1217 nb_syms
= symtab_section
->data_offset
/ sizeof(Elf32_Sym
);
1218 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1219 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
1222 if (ELF32_ST_BIND(sym
->st_info
) != STB_LOCAL
) {
1223 name
= symtab_section
->link
->data
+ sym
->st_name
;
1224 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1226 sym
->st_shndx
, name
);
1227 s1
->symtab_to_dynsym
[sym
-
1228 (Elf32_Sym
*)symtab_section
->data
] =
1234 build_got_entries(s1
);
1236 /* add a list of needed dlls */
1237 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1238 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1239 if (dllref
->level
== 0)
1240 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1242 /* XXX: currently, since we do not handle PIC code, we
1243 must relocate the readonly segments */
1244 if (file_type
== TCC_OUTPUT_DLL
)
1245 put_dt(dynamic
, DT_TEXTREL
, 0);
1247 /* add necessary space for other entries */
1248 saved_dynamic_data_offset
= dynamic
->data_offset
;
1249 dynamic
->data_offset
+= 8 * 9;
1251 /* still need to build got entries in case of static link */
1252 build_got_entries(s1
);
1256 memset(&ehdr
, 0, sizeof(ehdr
));
1258 /* we add a section for symbols */
1259 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1260 put_elf_str(strsec
, "");
1262 /* compute number of sections */
1263 shnum
= s1
->nb_sections
;
1265 /* this array is used to reorder sections in the output file */
1266 section_order
= tcc_malloc(sizeof(int) * shnum
);
1267 section_order
[0] = 0;
1270 /* compute number of program headers */
1273 case TCC_OUTPUT_OBJ
:
1276 case TCC_OUTPUT_EXE
:
1277 if (!s1
->static_link
)
1282 case TCC_OUTPUT_DLL
:
1287 /* allocate strings for section names and decide if an unallocated
1288 section should be output */
1289 /* NOTE: the strsec section comes last, so its size is also
1291 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1292 s
= s1
->sections
[i
];
1293 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1294 /* when generating a DLL, we include relocations but we may
1296 if (file_type
== TCC_OUTPUT_DLL
&&
1297 s
->sh_type
== SHT_REL
&&
1298 !(s
->sh_flags
& SHF_ALLOC
)) {
1299 prepare_dynamic_rel(s1
, s
);
1300 } else if (do_debug
||
1301 file_type
== TCC_OUTPUT_OBJ
||
1302 (s
->sh_flags
& SHF_ALLOC
) ||
1303 i
== (s1
->nb_sections
- 1)) {
1304 /* we output all sections if debug or object file */
1305 s
->sh_size
= s
->data_offset
;
1309 /* allocate program segment headers */
1310 phdr
= tcc_mallocz(phnum
* sizeof(Elf32_Phdr
));
1312 file_offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
1314 /* compute section to program header mapping */
1315 if (file_type
== TCC_OUTPUT_DLL
)
1318 addr
= ELF_START_ADDR
;
1320 /* dynamic relocation table information, for .dynamic section */
1324 /* compute address after headers */
1325 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1327 /* leave one program header for the program interpreter */
1332 for(j
= 0; j
< 2; j
++) {
1333 ph
->p_type
= PT_LOAD
;
1335 ph
->p_flags
= PF_R
| PF_X
;
1337 ph
->p_flags
= PF_R
| PF_W
;
1338 ph
->p_align
= ELF_PAGE_SIZE
;
1340 /* we do the following ordering: interp, symbol tables,
1341 relocations, progbits, nobits */
1342 /* XXX: do faster and simpler sorting */
1343 for(k
= 0; k
< 5; k
++) {
1344 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1345 s
= s1
->sections
[i
];
1346 /* compute if section should be included */
1348 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1352 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1353 (SHF_ALLOC
| SHF_WRITE
))
1359 } else if (s
->sh_type
== SHT_DYNSYM
||
1360 s
->sh_type
== SHT_STRTAB
||
1361 s
->sh_type
== SHT_HASH
) {
1364 } else if (s
->sh_type
== SHT_REL
) {
1367 } else if (s
->sh_type
== SHT_NOBITS
) {
1374 section_order
[sh_order_index
++] = i
;
1376 /* section matches: we align it and add its size */
1378 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1379 ~(s
->sh_addralign
- 1);
1380 s
->sh_offset
= file_offset
;
1381 addr
+= file_offset
- tmp
;
1384 /* update program header infos */
1385 if (ph
->p_offset
== 0) {
1386 ph
->p_offset
= file_offset
;
1388 ph
->p_paddr
= ph
->p_vaddr
;
1390 /* update dynamic relocation infos */
1391 if (s
->sh_type
== SHT_REL
) {
1394 rel_size
+= s
->sh_size
;
1397 if (s
->sh_type
!= SHT_NOBITS
)
1398 file_offset
+= s
->sh_size
;
1401 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1402 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1404 /* if in the middle of a page, we duplicate the page in
1405 memory so that one copy is RX and the other is RW */
1406 if ((addr
& (ELF_PAGE_SIZE
- 1)) != 0)
1407 addr
+= ELF_PAGE_SIZE
;
1410 /* if interpreter, then add corresponing program header */
1414 ph
->p_type
= PT_INTERP
;
1415 ph
->p_offset
= interp
->sh_offset
;
1416 ph
->p_vaddr
= interp
->sh_addr
;
1417 ph
->p_paddr
= ph
->p_vaddr
;
1418 ph
->p_filesz
= interp
->sh_size
;
1419 ph
->p_memsz
= interp
->sh_size
;
1421 ph
->p_align
= interp
->sh_addralign
;
1424 /* if dynamic section, then add corresponing program header */
1428 ph
= &phdr
[phnum
- 1];
1430 ph
->p_type
= PT_DYNAMIC
;
1431 ph
->p_offset
= dynamic
->sh_offset
;
1432 ph
->p_vaddr
= dynamic
->sh_addr
;
1433 ph
->p_paddr
= ph
->p_vaddr
;
1434 ph
->p_filesz
= dynamic
->sh_size
;
1435 ph
->p_memsz
= dynamic
->sh_size
;
1436 ph
->p_flags
= PF_R
| PF_W
;
1437 ph
->p_align
= dynamic
->sh_addralign
;
1439 /* put GOT dynamic section address */
1440 put32(s1
->got
->data
, dynamic
->sh_addr
);
1442 /* relocate the PLT */
1443 if (file_type
== TCC_OUTPUT_EXE
) {
1447 p_end
= p
+ s1
->plt
->data_offset
;
1449 #if defined(TCC_TARGET_I386)
1450 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1451 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1454 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1457 #elif defined(TCC_TARGET_ARM)
1459 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1462 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1465 #elif defined(TCC_TARGET_C67)
1468 #error unsupported CPU
1473 /* relocate symbols in .dynsym */
1474 sym_end
= (Elf32_Sym
*)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1475 for(sym
= (Elf32_Sym
*)s1
->dynsym
->data
+ 1;
1478 if (sym
->st_shndx
== SHN_UNDEF
) {
1479 /* relocate to the PLT if the symbol corresponds
1482 sym
->st_value
+= s1
->plt
->sh_addr
;
1483 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1484 /* do symbol relocation */
1485 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1489 /* put dynamic section entries */
1490 dynamic
->data_offset
= saved_dynamic_data_offset
;
1491 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1492 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1493 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1494 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1495 put_dt(dynamic
, DT_SYMENT
, sizeof(Elf32_Sym
));
1496 put_dt(dynamic
, DT_REL
, rel_addr
);
1497 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1498 put_dt(dynamic
, DT_RELENT
, sizeof(Elf32_Rel
));
1499 put_dt(dynamic
, DT_NULL
, 0);
1502 ehdr
.e_phentsize
= sizeof(Elf32_Phdr
);
1503 ehdr
.e_phnum
= phnum
;
1504 ehdr
.e_phoff
= sizeof(Elf32_Ehdr
);
1507 /* all other sections come after */
1508 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1509 s
= s1
->sections
[i
];
1510 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1512 section_order
[sh_order_index
++] = i
;
1514 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1515 ~(s
->sh_addralign
- 1);
1516 s
->sh_offset
= file_offset
;
1517 if (s
->sh_type
!= SHT_NOBITS
)
1518 file_offset
+= s
->sh_size
;
1521 /* if building executable or DLL, then relocate each section
1522 except the GOT which is already relocated */
1523 if (file_type
!= TCC_OUTPUT_OBJ
) {
1524 relocate_syms(s1
, 0);
1526 if (s1
->nb_errors
!= 0) {
1532 /* relocate sections */
1533 /* XXX: ignore sections with allocated relocations ? */
1534 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1535 s
= s1
->sections
[i
];
1536 if (s
->reloc
&& s
!= s1
->got
)
1537 relocate_section(s1
, s
);
1540 /* relocate relocation entries if the relocation tables are
1541 allocated in the executable */
1542 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1543 s
= s1
->sections
[i
];
1544 if ((s
->sh_flags
& SHF_ALLOC
) &&
1545 s
->sh_type
== SHT_REL
) {
1546 relocate_rel(s1
, s
);
1550 /* get entry point address */
1551 if (file_type
== TCC_OUTPUT_EXE
)
1552 ehdr
.e_entry
= (unsigned long)tcc_get_symbol_err(s1
, "_start");
1554 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1557 #ifdef TCC_TARGET_COFF
1558 ret
= tcc_output_coff(s1
, filename
);
1560 sort_syms(s1
, symtab_section
);
1563 file_offset
= (file_offset
+ 3) & -4;
1566 ehdr
.e_ident
[0] = ELFMAG0
;
1567 ehdr
.e_ident
[1] = ELFMAG1
;
1568 ehdr
.e_ident
[2] = ELFMAG2
;
1569 ehdr
.e_ident
[3] = ELFMAG3
;
1570 ehdr
.e_ident
[4] = ELFCLASS32
;
1571 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1572 ehdr
.e_ident
[6] = EV_CURRENT
;
1574 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1576 #ifdef TCC_TARGET_ARM
1577 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
1581 case TCC_OUTPUT_EXE
:
1582 ehdr
.e_type
= ET_EXEC
;
1584 case TCC_OUTPUT_DLL
:
1585 ehdr
.e_type
= ET_DYN
;
1587 case TCC_OUTPUT_OBJ
:
1588 ehdr
.e_type
= ET_REL
;
1591 ehdr
.e_machine
= EM_TCC_TARGET
;
1592 ehdr
.e_version
= EV_CURRENT
;
1593 ehdr
.e_shoff
= file_offset
;
1594 ehdr
.e_ehsize
= sizeof(Elf32_Ehdr
);
1595 ehdr
.e_shentsize
= sizeof(Elf32_Shdr
);
1596 ehdr
.e_shnum
= shnum
;
1597 ehdr
.e_shstrndx
= shnum
- 1;
1599 /* write elf file */
1600 if (file_type
== TCC_OUTPUT_OBJ
)
1604 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
, mode
);
1606 error_noabort("could not write '%s'", filename
);
1609 f
= fdopen(fd
, "w");
1610 fwrite(&ehdr
, 1, sizeof(Elf32_Ehdr
), f
);
1611 fwrite(phdr
, 1, phnum
* sizeof(Elf32_Phdr
), f
);
1612 offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
1613 for(i
=1;i
<s1
->nb_sections
;i
++) {
1614 s
= s1
->sections
[section_order
[i
]];
1615 if (s
->sh_type
!= SHT_NOBITS
) {
1616 while (offset
< s
->sh_offset
) {
1621 fwrite(s
->data
, 1, size
, f
);
1625 while (offset
< ehdr
.e_shoff
) {
1630 /* output section headers */
1631 for(i
=0;i
<s1
->nb_sections
;i
++) {
1633 memset(sh
, 0, sizeof(Elf32_Shdr
));
1634 s
= s1
->sections
[i
];
1636 sh
->sh_name
= s
->sh_name
;
1637 sh
->sh_type
= s
->sh_type
;
1638 sh
->sh_flags
= s
->sh_flags
;
1639 sh
->sh_entsize
= s
->sh_entsize
;
1640 sh
->sh_info
= s
->sh_info
;
1642 sh
->sh_link
= s
->link
->sh_num
;
1643 sh
->sh_addralign
= s
->sh_addralign
;
1644 sh
->sh_addr
= s
->sh_addr
;
1645 sh
->sh_offset
= s
->sh_offset
;
1646 sh
->sh_size
= s
->sh_size
;
1648 fwrite(sh
, 1, sizeof(Elf32_Shdr
), f
);
1655 tcc_free(s1
->symtab_to_dynsym
);
1656 tcc_free(section_order
);
1658 tcc_free(s1
->got_offsets
);
1662 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
1666 data
= tcc_malloc(size
);
1667 lseek(fd
, file_offset
, SEEK_SET
);
1668 read(fd
, data
, size
);
1672 typedef struct SectionMergeInfo
{
1673 Section
*s
; /* corresponding existing section */
1674 unsigned long offset
; /* offset of the new section in the existing section */
1675 uint8_t new_section
; /* true if section 's' was added */
1676 uint8_t link_once
; /* true if link once section */
1679 /* load an object file and merge it with current files */
1680 /* XXX: handle correctly stab (debug) info */
1681 static int tcc_load_object_file(TCCState
*s1
,
1682 int fd
, unsigned long file_offset
)
1685 Elf32_Shdr
*shdr
, *sh
;
1686 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
1687 unsigned char *strsec
, *strtab
;
1688 int *old_to_new_syms
;
1689 char *sh_name
, *name
;
1690 SectionMergeInfo
*sm_table
, *sm
;
1691 Elf32_Sym
*sym
, *symtab
;
1692 Elf32_Rel
*rel
, *rel_end
;
1695 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
1697 if (ehdr
.e_ident
[0] != ELFMAG0
||
1698 ehdr
.e_ident
[1] != ELFMAG1
||
1699 ehdr
.e_ident
[2] != ELFMAG2
||
1700 ehdr
.e_ident
[3] != ELFMAG3
)
1702 /* test if object file */
1703 if (ehdr
.e_type
!= ET_REL
)
1705 /* test CPU specific stuff */
1706 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
1707 ehdr
.e_machine
!= EM_TCC_TARGET
) {
1709 error_noabort("invalid object file");
1713 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
1714 sizeof(Elf32_Shdr
) * ehdr
.e_shnum
);
1715 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
1717 /* load section names */
1718 sh
= &shdr
[ehdr
.e_shstrndx
];
1719 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1721 /* load symtab and strtab */
1722 old_to_new_syms
= NULL
;
1726 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1728 if (sh
->sh_type
== SHT_SYMTAB
) {
1730 error_noabort("object must contain only one symtab");
1735 nb_syms
= sh
->sh_size
/ sizeof(Elf32_Sym
);
1736 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1737 sm_table
[i
].s
= symtab_section
;
1739 /* now load strtab */
1740 sh
= &shdr
[sh
->sh_link
];
1741 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1745 /* now examine each section and try to merge its content with the
1747 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1748 /* no need to examine section name strtab */
1749 if (i
== ehdr
.e_shstrndx
)
1752 sh_name
= strsec
+ sh
->sh_name
;
1753 /* ignore sections types we do not handle */
1754 if (sh
->sh_type
!= SHT_PROGBITS
&&
1755 sh
->sh_type
!= SHT_REL
&&
1756 sh
->sh_type
!= SHT_NOBITS
)
1758 if (sh
->sh_addralign
< 1)
1759 sh
->sh_addralign
= 1;
1760 /* find corresponding section, if any */
1761 for(j
= 1; j
< s1
->nb_sections
;j
++) {
1762 s
= s1
->sections
[j
];
1763 if (!strcmp(s
->name
, sh_name
)) {
1764 if (!strncmp(sh_name
, ".gnu.linkonce",
1765 sizeof(".gnu.linkonce") - 1)) {
1766 /* if a 'linkonce' section is already present, we
1767 do not add it again. It is a little tricky as
1768 symbols can still be defined in
1770 sm_table
[i
].link_once
= 1;
1777 /* not found: create new section */
1778 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
1779 /* take as much info as possible from the section. sh_link and
1780 sh_info will be updated later */
1781 s
->sh_addralign
= sh
->sh_addralign
;
1782 s
->sh_entsize
= sh
->sh_entsize
;
1783 sm_table
[i
].new_section
= 1;
1785 if (sh
->sh_type
!= s
->sh_type
) {
1786 error_noabort("invalid section type");
1790 /* align start of section */
1791 offset
= s
->data_offset
;
1792 size
= sh
->sh_addralign
- 1;
1793 offset
= (offset
+ size
) & ~size
;
1794 if (sh
->sh_addralign
> s
->sh_addralign
)
1795 s
->sh_addralign
= sh
->sh_addralign
;
1796 s
->data_offset
= offset
;
1797 sm_table
[i
].offset
= offset
;
1799 /* concatenate sections */
1801 if (sh
->sh_type
!= SHT_NOBITS
) {
1803 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
1804 ptr
= section_ptr_add(s
, size
);
1805 read(fd
, ptr
, size
);
1807 s
->data_offset
+= size
;
1812 /* second short pass to update sh_link and sh_info fields of new
1815 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1817 if (!s
|| !sm_table
[i
].new_section
)
1820 if (sh
->sh_link
> 0)
1821 s
->link
= sm_table
[sh
->sh_link
].s
;
1822 if (sh
->sh_type
== SHT_REL
) {
1823 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
1824 /* update backward link */
1825 s1
->sections
[s
->sh_info
]->reloc
= s
;
1829 /* resolve symbols */
1830 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
1833 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
1834 if (sym
->st_shndx
!= SHN_UNDEF
&&
1835 sym
->st_shndx
< SHN_LORESERVE
) {
1836 sm
= &sm_table
[sym
->st_shndx
];
1837 if (sm
->link_once
) {
1838 /* if a symbol is in a link once section, we use the
1839 already defined symbol. It is very important to get
1840 correct relocations */
1841 if (ELF32_ST_BIND(sym
->st_info
) != STB_LOCAL
) {
1842 name
= strtab
+ sym
->st_name
;
1843 sym_index
= find_elf_sym(symtab_section
, name
);
1845 old_to_new_syms
[i
] = sym_index
;
1849 /* if no corresponding section added, no need to add symbol */
1852 /* convert section number */
1853 sym
->st_shndx
= sm
->s
->sh_num
;
1855 sym
->st_value
+= sm
->offset
;
1858 name
= strtab
+ sym
->st_name
;
1859 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
1860 sym
->st_info
, sym
->st_shndx
, name
);
1861 old_to_new_syms
[i
] = sym_index
;
1864 /* third pass to patch relocation entries */
1865 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1870 offset
= sm_table
[i
].offset
;
1871 switch(s
->sh_type
) {
1873 /* take relocation offset information */
1874 offseti
= sm_table
[sh
->sh_info
].offset
;
1875 rel_end
= (Elf32_Rel
*)(s
->data
+ s
->data_offset
);
1876 for(rel
= (Elf32_Rel
*)(s
->data
+ offset
);
1881 /* convert symbol index */
1882 type
= ELF32_R_TYPE(rel
->r_info
);
1883 sym_index
= ELF32_R_SYM(rel
->r_info
);
1884 /* NOTE: only one symtab assumed */
1885 if (sym_index
>= nb_syms
)
1887 sym_index
= old_to_new_syms
[sym_index
];
1890 error_noabort("Invalid relocation entry");
1893 rel
->r_info
= ELF32_R_INFO(sym_index
, type
);
1894 /* offset the relocation offset */
1895 rel
->r_offset
+= offseti
;
1907 tcc_free(old_to_new_syms
);
1914 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1916 typedef struct ArchiveHeader
{
1917 char ar_name
[16]; /* name of this member */
1918 char ar_date
[12]; /* file mtime */
1919 char ar_uid
[6]; /* owner uid; printed as decimal */
1920 char ar_gid
[6]; /* owner gid; printed as decimal */
1921 char ar_mode
[8]; /* file mode, printed as octal */
1922 char ar_size
[10]; /* file size, printed as decimal */
1923 char ar_fmag
[2]; /* should contain ARFMAG */
1926 static int get_be32(const uint8_t *b
)
1928 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
1931 /* load only the objects which resolve undefined symbols */
1932 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
1934 int i
, bound
, nsyms
, sym_index
, off
, ret
;
1936 const char *ar_names
, *p
;
1937 const uint8_t *ar_index
;
1940 data
= tcc_malloc(size
);
1941 if (read(fd
, data
, size
) != size
)
1943 nsyms
= get_be32(data
);
1944 ar_index
= data
+ 4;
1945 ar_names
= ar_index
+ nsyms
* 4;
1949 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
1950 sym_index
= find_elf_sym(symtab_section
, p
);
1952 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
1953 if(sym
->st_shndx
== SHN_UNDEF
) {
1954 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
1956 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
1959 lseek(fd
, off
, SEEK_SET
);
1960 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
1975 /* load a '.a' file */
1976 static int tcc_load_archive(TCCState
*s1
, int fd
)
1983 unsigned long file_offset
;
1985 /* skip magic which was already checked */
1986 read(fd
, magic
, sizeof(magic
));
1989 len
= read(fd
, &hdr
, sizeof(hdr
));
1992 if (len
!= sizeof(hdr
)) {
1993 error_noabort("invalid archive");
1996 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
1997 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
1998 size
= strtol(ar_size
, NULL
, 0);
1999 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2000 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2001 if (ar_name
[i
] != ' ')
2004 ar_name
[i
+ 1] = '\0';
2005 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2006 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2008 size
= (size
+ 1) & ~1;
2009 if (!strcmp(ar_name
, "/")) {
2010 /* coff symbol table : we handle it */
2011 if(s1
->alacarte_link
)
2012 return tcc_load_alacarte(s1
, fd
, size
);
2013 } else if (!strcmp(ar_name
, "//") ||
2014 !strcmp(ar_name
, "__.SYMDEF") ||
2015 !strcmp(ar_name
, "__.SYMDEF/") ||
2016 !strcmp(ar_name
, "ARFILENAMES/")) {
2017 /* skip symbol table or archive names */
2019 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2022 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2027 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2028 is referenced by the user (so it should be added as DT_NEEDED in
2029 the generated ELF file) */
2030 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2033 Elf32_Shdr
*shdr
, *sh
, *sh1
;
2034 int i
, nb_syms
, nb_dts
, sym_bind
, ret
;
2035 Elf32_Sym
*sym
, *dynsym
;
2036 Elf32_Dyn
*dt
, *dynamic
;
2037 unsigned char *dynstr
;
2038 const char *name
, *soname
, *p
;
2039 DLLReference
*dllref
;
2041 read(fd
, &ehdr
, sizeof(ehdr
));
2043 /* test CPU specific stuff */
2044 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2045 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2046 error_noabort("bad architecture");
2051 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(Elf32_Shdr
) * ehdr
.e_shnum
);
2053 /* load dynamic section and dynamic symbols */
2057 dynsym
= NULL
; /* avoid warning */
2058 dynstr
= NULL
; /* avoid warning */
2059 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2060 switch(sh
->sh_type
) {
2062 nb_dts
= sh
->sh_size
/ sizeof(Elf32_Dyn
);
2063 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2066 nb_syms
= sh
->sh_size
/ sizeof(Elf32_Sym
);
2067 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2068 sh1
= &shdr
[sh
->sh_link
];
2069 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2076 /* compute the real library name */
2078 p
= strrchr(soname
, '/');
2082 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2083 if (dt
->d_tag
== DT_SONAME
) {
2084 soname
= dynstr
+ dt
->d_un
.d_val
;
2088 /* if the dll is already loaded, do not load it */
2089 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2090 dllref
= s1
->loaded_dlls
[i
];
2091 if (!strcmp(soname
, dllref
->name
)) {
2092 /* but update level if needed */
2093 if (level
< dllref
->level
)
2094 dllref
->level
= level
;
2100 // printf("loading dll '%s'\n", soname);
2102 /* add the dll and its level */
2103 dllref
= tcc_malloc(sizeof(DLLReference
) + strlen(soname
));
2104 dllref
->level
= level
;
2105 strcpy(dllref
->name
, soname
);
2106 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2108 /* add dynamic symbols in dynsym_section */
2109 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2110 sym_bind
= ELF32_ST_BIND(sym
->st_info
);
2111 if (sym_bind
== STB_LOCAL
)
2113 name
= dynstr
+ sym
->st_name
;
2114 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2115 sym
->st_info
, sym
->st_shndx
, name
);
2118 /* load all referenced DLLs */
2119 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2122 name
= dynstr
+ dt
->d_un
.d_val
;
2123 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2124 dllref
= s1
->loaded_dlls
[i
];
2125 if (!strcmp(name
, dllref
->name
))
2126 goto already_loaded
;
2128 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2129 error_noabort("referenced dll '%s' not found", name
);
2146 #define LD_TOK_NAME 256
2147 #define LD_TOK_EOF (-1)
2149 /* return next ld script token */
2150 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2168 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2169 ch
= file
->buf_ptr
[0];
2187 if (!((ch
>= 'a' && ch
<= 'z') ||
2188 (ch
>= 'A' && ch
<= 'Z') ||
2189 (ch
>= '0' && ch
<= '9') ||
2190 strchr("/.-_+=$:\\,~", ch
)))
2192 if ((q
- name
) < name_size
- 1) {
2209 printf("tok=%c %d\n", c
, c
);
2210 if (c
== LD_TOK_NAME
)
2211 printf(" name=%s\n", name
);
2216 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2218 static int tcc_load_ldscript(TCCState
*s1
)
2221 char filename
[1024];
2224 ch
= file
->buf_ptr
[0];
2227 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2228 if (t
== LD_TOK_EOF
)
2230 else if (t
!= LD_TOK_NAME
)
2232 if (!strcmp(cmd
, "INPUT") ||
2233 !strcmp(cmd
, "GROUP")) {
2234 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2237 t
= ld_next(s1
, filename
, sizeof(filename
));
2239 if (t
== LD_TOK_EOF
) {
2240 error_noabort("unexpected end of file");
2242 } else if (t
== ')') {
2244 } else if (t
!= LD_TOK_NAME
) {
2245 error_noabort("filename expected");
2248 tcc_add_file(s1
, filename
);
2249 t
= ld_next(s1
, filename
, sizeof(filename
));
2251 t
= ld_next(s1
, filename
, sizeof(filename
));
2254 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2255 !strcmp(cmd
, "TARGET")) {
2256 /* ignore some commands */
2257 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2261 t
= ld_next(s1
, filename
, sizeof(filename
));
2262 if (t
== LD_TOK_EOF
) {
2263 error_noabort("unexpected end of file");
2265 } else if (t
== ')') {