2 * ELF file handling for TCC
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #ifdef TCC_TARGET_X86_64
22 #define ElfW_Rel ElfW(Rela)
23 #define SHT_RELX SHT_RELA
24 #define REL_SECTION_FMT ".rela%s"
26 #define ElfW_Rel ElfW(Rel)
27 #define SHT_RELX SHT_REL
28 #define REL_SECTION_FMT ".rel%s"
31 static int put_elf_str(Section
*s
, const char *sym
)
36 len
= strlen(sym
) + 1;
37 offset
= s
->data_offset
;
38 ptr
= section_ptr_add(s
, len
);
39 memcpy(ptr
, sym
, len
);
43 /* elf symbol hashing function */
44 static unsigned long elf_hash(const unsigned char *name
)
46 unsigned long h
= 0, g
;
49 h
= (h
<< 4) + *name
++;
58 /* rebuild hash table of section s */
59 /* NOTE: we do factorize the hash table code to go faster */
60 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
63 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
66 strtab
= s
->link
->data
;
67 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
69 s
->hash
->data_offset
= 0;
70 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
75 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
76 ptr
+= nb_buckets
+ 1;
78 sym
= (ElfW(Sym
) *)s
->data
+ 1;
79 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
80 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
81 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
92 /* return the symbol number */
93 static int put_elf_sym(Section
*s
,
94 unsigned long value
, unsigned long size
,
95 int info
, int other
, int shndx
, const char *name
)
97 int name_offset
, sym_index
;
102 sym
= section_ptr_add(s
, sizeof(ElfW(Sym
)));
104 name_offset
= put_elf_str(s
->link
, name
);
107 /* XXX: endianness */
108 sym
->st_name
= name_offset
;
109 sym
->st_value
= value
;
112 sym
->st_other
= other
;
113 sym
->st_shndx
= shndx
;
114 sym_index
= sym
- (ElfW(Sym
) *)s
->data
;
118 ptr
= section_ptr_add(hs
, sizeof(int));
119 base
= (int *)hs
->data
;
120 /* only add global or weak symbols */
121 if (ELFW(ST_BIND
)(info
) != STB_LOCAL
) {
122 /* add another hashing entry */
124 h
= elf_hash(name
) % nbuckets
;
126 base
[2 + h
] = sym_index
;
128 /* we resize the hash table */
129 hs
->nb_hashed_syms
++;
130 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
131 rebuild_hash(s
, 2 * nbuckets
);
141 /* find global ELF symbol 'name' and return its index. Return 0 if not
143 static int find_elf_sym(Section
*s
, const char *name
)
147 int nbuckets
, sym_index
, h
;
153 nbuckets
= ((int *)hs
->data
)[0];
154 h
= elf_hash(name
) % nbuckets
;
155 sym_index
= ((int *)hs
->data
)[2 + h
];
156 while (sym_index
!= 0) {
157 sym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
158 name1
= s
->link
->data
+ sym
->st_name
;
159 if (!strcmp(name
, name1
))
161 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
166 /* return elf symbol value or error */
167 int tcc_get_symbol(TCCState
*s
, unsigned long *pval
, const char *name
)
172 sym_index
= find_elf_sym(symtab_section
, name
);
175 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
176 *pval
= sym
->st_value
;
180 void *tcc_get_symbol_err(TCCState
*s
, const char *name
)
183 if (tcc_get_symbol(s
, &val
, name
) < 0)
184 error("%s not defined", name
);
188 /* add an elf symbol : check if it is already defined and patch
189 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
190 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
191 int info
, int other
, int sh_num
, const char *name
)
194 int sym_bind
, sym_index
, sym_type
, esym_bind
;
195 unsigned char sym_vis
, esym_vis
, new_vis
;
197 sym_bind
= ELFW(ST_BIND
)(info
);
198 sym_type
= ELFW(ST_TYPE
)(info
);
199 sym_vis
= ELFW(ST_VISIBILITY
)(other
);
201 if (sym_bind
!= STB_LOCAL
) {
202 /* we search global or weak symbols */
203 sym_index
= find_elf_sym(s
, name
);
206 esym
= &((ElfW(Sym
) *)s
->data
)[sym_index
];
207 if (esym
->st_shndx
!= SHN_UNDEF
) {
208 esym_bind
= ELFW(ST_BIND
)(esym
->st_info
);
209 /* propagate the most constraining visibility */
210 /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
211 esym_vis
= ELFW(ST_VISIBILITY
)(esym
->st_other
);
212 if (esym_vis
== STV_DEFAULT
) {
214 } else if (sym_vis
== STV_DEFAULT
) {
217 new_vis
= (esym_vis
< sym_vis
) ? esym_vis
: sym_vis
;
219 esym
->st_other
= (esym
->st_other
& ~ELFW(ST_VISIBILITY
)(-1))
221 other
= esym
->st_other
; /* in case we have to patch esym */
222 if (sh_num
== SHN_UNDEF
) {
223 /* ignore adding of undefined symbol if the
224 corresponding symbol is already defined */
225 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
226 /* global overrides weak, so patch */
228 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
229 /* weak is ignored if already global */
230 } else if (sym_vis
== STV_HIDDEN
|| sym_vis
== STV_INTERNAL
) {
231 /* ignore hidden symbols after */
232 } else if (esym
->st_shndx
== SHN_COMMON
&& sh_num
< SHN_LORESERVE
) {
233 /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
234 No idea if this is the correct solution ... */
236 } else if (s
== tcc_state
->dynsymtab_section
) {
237 /* we accept that two DLL define the same symbol */
240 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
241 sym_bind
, sh_num
, new_vis
, esym_bind
, esym
->st_shndx
, esym_vis
);
243 error_noabort("'%s' defined twice", name
);
247 esym
->st_info
= ELFW(ST_INFO
)(sym_bind
, sym_type
);
248 esym
->st_shndx
= sh_num
;
249 esym
->st_value
= value
;
250 esym
->st_size
= size
;
251 esym
->st_other
= other
;
255 sym_index
= put_elf_sym(s
, value
, size
,
256 ELFW(ST_INFO
)(sym_bind
, sym_type
), other
,
263 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
264 int type
, int symbol
)
272 /* if no relocation section, create it */
273 snprintf(buf
, sizeof(buf
), REL_SECTION_FMT
, s
->name
);
274 /* if the symtab is allocated, then we consider the relocation
276 sr
= new_section(tcc_state
, buf
, SHT_RELX
, symtab
->sh_flags
);
277 sr
->sh_entsize
= sizeof(ElfW_Rel
);
279 sr
->sh_info
= s
->sh_num
;
282 rel
= section_ptr_add(sr
, sizeof(ElfW_Rel
));
283 rel
->r_offset
= offset
;
284 rel
->r_info
= ELFW(R_INFO
)(symbol
, type
);
287 /* put stab debug information */
290 unsigned long n_strx
; /* index into string table of name */
291 unsigned char n_type
; /* type of symbol */
292 unsigned char n_other
; /* misc info (usually empty) */
293 unsigned short n_desc
; /* description field */
294 unsigned long n_value
; /* value of symbol */
297 static void put_stabs(const char *str
, int type
, int other
, int desc
,
302 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
304 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
309 sym
->n_other
= other
;
311 sym
->n_value
= value
;
314 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
315 unsigned long value
, Section
*sec
, int sym_index
)
317 put_stabs(str
, type
, other
, desc
, value
);
318 put_elf_reloc(symtab_section
, stab_section
,
319 stab_section
->data_offset
- sizeof(unsigned long),
320 R_DATA_32
, sym_index
);
323 static void put_stabn(int type
, int other
, int desc
, int value
)
325 put_stabs(NULL
, type
, other
, desc
, value
);
328 static void put_stabd(int type
, int other
, int desc
)
330 put_stabs(NULL
, type
, other
, desc
, 0);
333 /* In an ELF file symbol table, the local symbols must appear below
334 the global and weak ones. Since TCC cannot sort it while generating
335 the code, we must do it after. All the relocation tables are also
336 modified to take into account the symbol table sorting */
337 static void sort_syms(TCCState
*s1
, Section
*s
)
339 int *old_to_new_syms
;
343 ElfW_Rel
*rel
, *rel_end
;
347 nb_syms
= s
->data_offset
/ sizeof(ElfW(Sym
));
348 new_syms
= tcc_malloc(nb_syms
* sizeof(ElfW(Sym
)));
349 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
351 /* first pass for local symbols */
352 p
= (ElfW(Sym
) *)s
->data
;
354 for(i
= 0; i
< nb_syms
; i
++) {
355 if (ELFW(ST_BIND
)(p
->st_info
) == STB_LOCAL
) {
356 old_to_new_syms
[i
] = q
- new_syms
;
361 /* save the number of local symbols in section header */
362 s
->sh_info
= q
- new_syms
;
364 /* then second pass for non local symbols */
365 p
= (ElfW(Sym
) *)s
->data
;
366 for(i
= 0; i
< nb_syms
; i
++) {
367 if (ELFW(ST_BIND
)(p
->st_info
) != STB_LOCAL
) {
368 old_to_new_syms
[i
] = q
- new_syms
;
374 /* we copy the new symbols to the old */
375 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(ElfW(Sym
)));
378 /* now we modify all the relocations */
379 for(i
= 1; i
< s1
->nb_sections
; i
++) {
380 sr
= s1
->sections
[i
];
381 if (sr
->sh_type
== SHT_RELX
&& sr
->link
== s
) {
382 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
383 for(rel
= (ElfW_Rel
*)sr
->data
;
386 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
387 type
= ELFW(R_TYPE
)(rel
->r_info
);
388 sym_index
= old_to_new_syms
[sym_index
];
389 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
394 tcc_free(old_to_new_syms
);
397 /* relocate common symbols in the .bss section */
398 static void relocate_common_syms(void)
400 ElfW(Sym
) *sym
, *sym_end
;
401 unsigned long offset
, align
;
403 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
404 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
407 if (sym
->st_shndx
== SHN_COMMON
) {
409 align
= sym
->st_value
;
410 offset
= bss_section
->data_offset
;
411 offset
= (offset
+ align
- 1) & -align
;
412 sym
->st_value
= offset
;
413 sym
->st_shndx
= bss_section
->sh_num
;
414 offset
+= sym
->st_size
;
415 bss_section
->data_offset
= offset
;
420 /* relocate symbol table, resolve undefined symbols if do_resolve is
421 true and output error if undefined symbol. */
422 static void relocate_syms(TCCState
*s1
, int do_resolve
)
424 ElfW(Sym
) *sym
, *esym
, *sym_end
;
425 int sym_bind
, sh_num
, sym_index
;
429 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+ symtab_section
->data_offset
);
430 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
433 sh_num
= sym
->st_shndx
;
434 if (sh_num
== SHN_UNDEF
) {
435 name
= strtab_section
->data
+ sym
->st_name
;
437 name
= symtab_section
->link
->data
+ sym
->st_name
;
438 addr
= (unsigned long)resolve_sym(s1
, name
, ELFW(ST_TYPE
)(sym
->st_info
));
440 sym
->st_value
= addr
;
443 } else if (s1
->dynsym
) {
444 /* if dynamic symbol exist, then use it */
445 sym_index
= find_elf_sym(s1
->dynsym
, name
);
447 esym
= &((ElfW(Sym
) *)s1
->dynsym
->data
)[sym_index
];
448 sym
->st_value
= esym
->st_value
;
452 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
454 if (!strcmp(name
, "_fp_hw"))
456 /* only weak symbols are accepted to be undefined. Their
458 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
459 if (sym_bind
== STB_WEAK
) {
462 error_noabort("undefined symbol '%s'", name
);
464 } else if (sh_num
< SHN_LORESERVE
) {
465 /* add section base */
466 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
472 /* relocate a given section (CPU dependent) */
473 static void relocate_section(TCCState
*s1
, Section
*s
)
476 ElfW_Rel
*rel
, *rel_end
, *qrel
;
480 unsigned long val
, addr
;
481 #if defined(TCC_TARGET_I386)
486 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
487 qrel
= (ElfW_Rel
*)sr
->data
;
491 ptr
= s
->data
+ rel
->r_offset
;
493 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
494 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
496 type
= ELFW(R_TYPE
)(rel
->r_info
);
497 addr
= s
->sh_addr
+ rel
->r_offset
;
501 #if defined(TCC_TARGET_I386)
503 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
504 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
505 qrel
->r_offset
= rel
->r_offset
;
507 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_32
);
511 qrel
->r_info
= ELFW(R_INFO
)(0, R_386_RELATIVE
);
518 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
520 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
522 qrel
->r_offset
= rel
->r_offset
;
523 qrel
->r_info
= ELFW(R_INFO
)(esym_index
, R_386_PC32
);
528 *(int *)ptr
+= val
- addr
;
531 *(int *)ptr
+= val
- addr
;
538 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
541 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
544 /* we load the got offset */
545 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
547 #elif defined(TCC_TARGET_ARM)
554 x
= (*(int *)ptr
)&0xffffff;
555 (*(int *)ptr
) &= 0xff000000;
560 if((x
& 3) != 0 || x
>= 0x4000000 || x
< -0x4000000)
561 error("can't relocate value at %x",addr
);
570 x
= (*(int *)ptr
) & 0x7fffffff;
571 (*(int *)ptr
) &= 0x80000000;
574 if((x
^(x
>>1))&0x40000000)
575 error("can't relocate value at %x",addr
);
576 (*(int *)ptr
) |= x
& 0x7fffffff;
581 case R_ARM_BASE_PREL
:
582 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
585 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
588 /* we load the got offset */
589 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
594 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
595 type
,addr
,(unsigned int )ptr
,val
);
597 #elif defined(TCC_TARGET_C67)
605 /* put the low 16 bits of the absolute address */
606 // add to what is already there
608 orig
= ((*(int *)(ptr
)) >> 7) & 0xffff;
609 orig
|= (((*(int *)(ptr
+4)) >> 7) & 0xffff) << 16;
611 //patch both at once - assumes always in pairs Low - High
613 *(int *) ptr
= (*(int *) ptr
& (~(0xffff << 7)) ) | (((val
+orig
) & 0xffff) << 7);
614 *(int *)(ptr
+4) = (*(int *)(ptr
+4) & (~(0xffff << 7)) ) | ((((val
+orig
)>>16) & 0xffff) << 7);
620 fprintf(stderr
,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
621 type
,addr
,(unsigned int )ptr
,val
);
624 #error unsupported processor
628 /* if the relocation is allocated, we change its symbol table */
629 if (sr
->sh_flags
& SHF_ALLOC
)
630 sr
->link
= s1
->dynsym
;
633 /* relocate relocation table in 'sr' */
634 static void relocate_rel(TCCState
*s1
, Section
*sr
)
637 ElfW_Rel
*rel
, *rel_end
;
639 s
= s1
->sections
[sr
->sh_info
];
640 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
641 for(rel
= (ElfW_Rel
*)sr
->data
;
644 rel
->r_offset
+= s
->sh_addr
;
648 /* count the number of dynamic relocations so that we can reserve
650 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
652 ElfW_Rel
*rel
, *rel_end
;
653 int sym_index
, esym_index
, type
, count
;
656 rel_end
= (ElfW_Rel
*)(sr
->data
+ sr
->data_offset
);
657 for(rel
= (ElfW_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
658 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
659 type
= ELFW(R_TYPE
)(rel
->r_info
);
665 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
674 /* allocate the section */
675 sr
->sh_flags
|= SHF_ALLOC
;
676 sr
->sh_size
= count
* sizeof(ElfW_Rel
);
681 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
686 if (index
>= s1
->nb_got_offsets
) {
687 /* find immediately bigger power of 2 and reallocate array */
691 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
693 error("memory full");
694 s1
->got_offsets
= tab
;
695 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
696 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
697 s1
->nb_got_offsets
= n
;
699 s1
->got_offsets
[index
] = val
;
702 /* XXX: suppress that */
703 static void put32(unsigned char *p
, uint32_t val
)
711 #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_ARM)
712 static uint32_t get32(unsigned char *p
)
714 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
718 static void build_got(TCCState
*s1
)
722 /* if no got, then create it */
723 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
724 s1
->got
->sh_entsize
= 4;
725 add_elf_sym(symtab_section
, 0, 4, ELFW(ST_INFO
)(STB_GLOBAL
, STT_OBJECT
),
726 0, s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
727 ptr
= section_ptr_add(s1
->got
, 3 * PTR_SIZE
);
729 /* keep space for _DYNAMIC pointer, if present */
731 /* two dummy got entries */
735 /* keep space for _DYNAMIC pointer, if present */
738 /* two dummy got entries */
746 /* put a got entry corresponding to a symbol in symtab_section. 'size'
747 and 'info' can be modifed if more precise info comes from the DLL */
748 static void put_got_entry(TCCState
*s1
,
749 int reloc_type
, unsigned long size
, int info
,
755 unsigned long offset
;
761 /* if a got entry already exists for that symbol, no need to add one */
762 if (sym_index
< s1
->nb_got_offsets
&&
763 s1
->got_offsets
[sym_index
] != 0)
766 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
769 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
770 name
= symtab_section
->link
->data
+ sym
->st_name
;
771 offset
= sym
->st_value
;
772 #ifdef TCC_TARGET_I386
773 if (reloc_type
== R_386_JMP_SLOT
) {
778 /* if we build a DLL, we add a %ebx offset */
779 if (s1
->output_type
== TCC_OUTPUT_DLL
)
784 /* add a PLT entry */
786 if (plt
->data_offset
== 0) {
787 /* first plt entry */
788 p
= section_ptr_add(plt
, 16);
789 p
[0] = 0xff; /* pushl got + PTR_SIZE */
791 put32(p
+ 2, PTR_SIZE
);
792 p
[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
794 put32(p
+ 8, PTR_SIZE
* 2);
797 p
= section_ptr_add(plt
, 16);
798 p
[0] = 0xff; /* jmp *(got + x) */
800 put32(p
+ 2, s1
->got
->data_offset
);
801 p
[6] = 0x68; /* push $xxx */
802 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
803 p
[11] = 0xe9; /* jmp plt_start */
804 put32(p
+ 12, -(plt
->data_offset
));
806 /* the symbol is modified so that it will be relocated to
808 if (s1
->output_type
== TCC_OUTPUT_EXE
)
809 offset
= plt
->data_offset
- 16;
811 #elif defined(TCC_TARGET_ARM)
812 if (reloc_type
== R_ARM_JUMP_SLOT
) {
816 /* if we build a DLL, we add a %ebx offset */
817 if (s1
->output_type
== TCC_OUTPUT_DLL
)
818 error("DLLs unimplemented!");
820 /* add a PLT entry */
822 if (plt
->data_offset
== 0) {
823 /* first plt entry */
824 p
= section_ptr_add(plt
, 16);
825 put32(p
, 0xe52de004);
826 put32(p
+ 4, 0xe59fe010);
827 put32(p
+ 8, 0xe08fe00e);
828 put32(p
+ 12, 0xe5bef008);
831 p
= section_ptr_add(plt
, 16);
832 put32(p
, 0xe59fc004);
833 put32(p
+4, 0xe08fc00c);
834 put32(p
+8, 0xe59cf000);
835 put32(p
+12, s1
->got
->data_offset
);
837 /* the symbol is modified so that it will be relocated to
839 if (s1
->output_type
== TCC_OUTPUT_EXE
)
840 offset
= plt
->data_offset
- 16;
842 #elif defined(TCC_TARGET_C67)
843 error("C67 got not implemented");
845 #error unsupported CPU
847 index
= put_elf_sym(s1
->dynsym
, offset
,
848 size
, info
, 0, sym
->st_shndx
, name
);
849 /* put a got entry */
850 put_elf_reloc(s1
->dynsym
, s1
->got
,
851 s1
->got
->data_offset
,
854 ptr
= section_ptr_add(s1
->got
, PTR_SIZE
);
858 /* build GOT and PLT entries */
859 static void build_got_entries(TCCState
*s1
)
862 ElfW_Rel
*rel
, *rel_end
;
864 int i
, type
, reloc_type
, sym_index
;
866 for(i
= 1; i
< s1
->nb_sections
; i
++) {
868 if (s
->sh_type
!= SHT_RELX
)
870 /* no need to handle got relocations */
871 if (s
->link
!= symtab_section
)
874 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
875 for(rel
= (ElfW_Rel
*)s
->data
;
878 type
= ELFW(R_TYPE
)(rel
->r_info
);
880 #if defined(TCC_TARGET_I386)
887 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
888 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
889 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
890 /* look at the symbol got offset. If none, then add one */
891 if (type
== R_386_GOT32
)
892 reloc_type
= R_386_GLOB_DAT
;
894 reloc_type
= R_386_JMP_SLOT
;
895 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
899 #elif defined(TCC_TARGET_ARM)
902 case R_ARM_BASE_PREL
:
906 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
907 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
908 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
909 /* look at the symbol got offset. If none, then add one */
910 if (type
== R_ARM_GOT_BREL
)
911 reloc_type
= R_ARM_GLOB_DAT
;
913 reloc_type
= R_ARM_JUMP_SLOT
;
914 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
918 #elif defined(TCC_TARGET_C67)
925 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
926 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
927 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
928 /* look at the symbol got offset. If none, then add one */
929 if (type
== R_C60_GOT32
)
930 reloc_type
= R_C60_GLOB_DAT
;
932 reloc_type
= R_C60_JMP_SLOT
;
933 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
938 #error unsupported CPU
947 static Section
*new_symtab(TCCState
*s1
,
948 const char *symtab_name
, int sh_type
, int sh_flags
,
949 const char *strtab_name
,
950 const char *hash_name
, int hash_sh_flags
)
952 Section
*symtab
, *strtab
, *hash
;
953 int *ptr
, nb_buckets
;
955 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
956 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
957 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
958 put_elf_str(strtab
, "");
959 symtab
->link
= strtab
;
960 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
964 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
965 hash
->sh_entsize
= sizeof(int);
969 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
972 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
976 /* put dynamic tag */
977 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
980 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
982 dyn
->d_un
.d_val
= val
;
985 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
989 char sym_start
[1024];
992 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
993 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
995 s
= find_section(s1
, section_name
);
1000 end_offset
= s
->data_offset
;
1003 add_elf_sym(symtab_section
,
1005 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1006 s
->sh_num
, sym_start
);
1007 add_elf_sym(symtab_section
,
1009 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1010 s
->sh_num
, sym_end
);
1013 /* add tcc runtime libraries */
1014 static void tcc_add_runtime(TCCState
*s1
)
1016 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1020 #ifdef CONFIG_TCC_BCHECK
1021 if (do_bounds_check
) {
1023 Section
*init_section
;
1024 unsigned char *pinit
;
1027 /* XXX: add an object file to do that */
1028 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1030 add_elf_sym(symtab_section
, 0, 0,
1031 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1032 bounds_section
->sh_num
, "__bounds_start");
1033 /* add bound check code */
1034 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "bcheck.o");
1035 tcc_add_file(s1
, buf
);
1036 #ifdef TCC_TARGET_I386
1037 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1038 /* add 'call __bound_init()' in .init section */
1039 init_section
= find_section(s1
, ".init");
1040 pinit
= section_ptr_add(init_section
, 5);
1042 put32(pinit
+ 1, -4);
1043 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1044 put_elf_reloc(symtab_section
, init_section
,
1045 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1051 if (!s1
->nostdlib
) {
1052 tcc_add_library(s1
, "c");
1054 #ifdef CONFIG_USE_LIBGCC
1055 tcc_add_file(s1
, CONFIG_SYSROOT
"/lib/libgcc_s.so.1");
1057 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "libtcc1.a");
1058 tcc_add_file(s1
, buf
);
1061 /* add crt end if not memory output */
1062 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1063 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1067 /* add various standard linker symbols (must be done after the
1068 sections are filled (for example after allocating common
1070 static void tcc_add_linker_symbols(TCCState
*s1
)
1076 add_elf_sym(symtab_section
,
1077 text_section
->data_offset
, 0,
1078 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1079 text_section
->sh_num
, "_etext");
1080 add_elf_sym(symtab_section
,
1081 data_section
->data_offset
, 0,
1082 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1083 data_section
->sh_num
, "_edata");
1084 add_elf_sym(symtab_section
,
1085 bss_section
->data_offset
, 0,
1086 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1087 bss_section
->sh_num
, "_end");
1088 /* horrible new standard ldscript defines */
1089 add_init_array_defines(s1
, ".preinit_array");
1090 add_init_array_defines(s1
, ".init_array");
1091 add_init_array_defines(s1
, ".fini_array");
1093 /* add start and stop symbols for sections whose name can be
1095 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1096 s
= s1
->sections
[i
];
1097 if (s
->sh_type
== SHT_PROGBITS
&&
1098 (s
->sh_flags
& SHF_ALLOC
)) {
1102 /* check if section name can be expressed in C */
1108 if (!isid(ch
) && !isnum(ch
))
1112 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1113 add_elf_sym(symtab_section
,
1115 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1117 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1118 add_elf_sym(symtab_section
,
1120 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1127 /* name of ELF interpreter */
1129 static char elf_interp
[] = "/usr/libexec/ld-elf.so.1";
1132 static char elf_interp
[] = "/lib/ld-linux.so.3";
1134 static char elf_interp
[] = "/lib/ld-linux.so.2";
1138 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1139 const int *section_order
)
1142 int i
, offset
, size
;
1145 for(i
=1;i
<s1
->nb_sections
;i
++) {
1146 s
= s1
->sections
[section_order
[i
]];
1147 if (s
->sh_type
!= SHT_NOBITS
&&
1148 (s
->sh_flags
& SHF_ALLOC
)) {
1149 while (offset
< s
->sh_offset
) {
1154 fwrite(s
->data
, 1, size
, f
);
1160 /* output an ELF file */
1161 /* XXX: suppress unneeded sections */
1162 int elf_output_file(TCCState
*s1
, const char *filename
)
1168 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1170 Section
*strsec
, *s
;
1171 ElfW(Shdr
) shdr
, *sh
;
1172 ElfW(Phdr
) *phdr
, *ph
;
1173 Section
*interp
, *dynamic
, *dynstr
;
1174 unsigned long saved_dynamic_data_offset
;
1176 int type
, file_type
;
1177 unsigned long rel_addr
, rel_size
;
1179 file_type
= s1
->output_type
;
1182 if (file_type
!= TCC_OUTPUT_OBJ
) {
1183 tcc_add_runtime(s1
);
1187 section_order
= NULL
;
1190 dynstr
= NULL
; /* avoid warning */
1191 saved_dynamic_data_offset
= 0; /* avoid warning */
1193 if (file_type
!= TCC_OUTPUT_OBJ
) {
1194 relocate_common_syms();
1196 tcc_add_linker_symbols(s1
);
1198 if (!s1
->static_link
) {
1200 int sym_index
, index
;
1201 ElfW(Sym
) *esym
, *sym_end
;
1203 if (file_type
== TCC_OUTPUT_EXE
) {
1205 /* add interpreter section only if executable */
1206 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1207 interp
->sh_addralign
= 1;
1208 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
1209 strcpy(ptr
, elf_interp
);
1212 /* add dynamic symbol table */
1213 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1215 ".hash", SHF_ALLOC
);
1216 dynstr
= s1
->dynsym
->link
;
1218 /* add dynamic section */
1219 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1220 SHF_ALLOC
| SHF_WRITE
);
1221 dynamic
->link
= dynstr
;
1222 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1225 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1226 SHF_ALLOC
| SHF_EXECINSTR
);
1227 s1
->plt
->sh_entsize
= 4;
1231 /* scan for undefined symbols and see if they are in the
1232 dynamic symbols. If a symbol STT_FUNC is found, then we
1233 add it in the PLT. If a symbol STT_OBJECT is found, we
1234 add it in the .bss section with a suitable relocation */
1235 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1236 symtab_section
->data_offset
);
1237 if (file_type
== TCC_OUTPUT_EXE
) {
1238 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1241 if (sym
->st_shndx
== SHN_UNDEF
) {
1242 name
= symtab_section
->link
->data
+ sym
->st_name
;
1243 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1245 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1246 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1247 if (type
== STT_FUNC
) {
1248 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1250 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1251 } else if (type
== STT_OBJECT
) {
1252 unsigned long offset
;
1253 offset
= bss_section
->data_offset
;
1254 /* XXX: which alignment ? */
1255 offset
= (offset
+ 16 - 1) & -16;
1256 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1258 bss_section
->sh_num
, name
);
1259 put_elf_reloc(s1
->dynsym
, bss_section
,
1260 offset
, R_COPY
, index
);
1261 offset
+= esym
->st_size
;
1262 bss_section
->data_offset
= offset
;
1265 /* STB_WEAK undefined symbols are accepted */
1266 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1268 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1269 !strcmp(name
, "_fp_hw")) {
1271 error_noabort("undefined symbol '%s'", name
);
1274 } else if (s1
->rdynamic
&&
1275 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1276 /* if -rdynamic option, then export all non
1278 name
= symtab_section
->link
->data
+ sym
->st_name
;
1279 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1281 sym
->st_shndx
, name
);
1288 /* now look at unresolved dynamic symbols and export
1289 corresponding symbol */
1290 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1291 s1
->dynsymtab_section
->data_offset
);
1292 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1295 if (esym
->st_shndx
== SHN_UNDEF
) {
1296 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1297 sym_index
= find_elf_sym(symtab_section
, name
);
1299 /* XXX: avoid adding a symbol if already
1300 present because of -rdynamic ? */
1301 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1302 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1304 sym
->st_shndx
, name
);
1306 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1307 /* weak symbols can stay undefined */
1309 warning("undefined dynamic symbol '%s'", name
);
1316 /* shared library case : we simply export all the global symbols */
1317 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1318 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1319 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1322 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1323 name
= symtab_section
->link
->data
+ sym
->st_name
;
1324 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1326 sym
->st_shndx
, name
);
1327 s1
->symtab_to_dynsym
[sym
-
1328 (ElfW(Sym
) *)symtab_section
->data
] =
1334 build_got_entries(s1
);
1336 /* add a list of needed dlls */
1337 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1338 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1339 if (dllref
->level
== 0)
1340 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1342 /* XXX: currently, since we do not handle PIC code, we
1343 must relocate the readonly segments */
1344 if (file_type
== TCC_OUTPUT_DLL
) {
1346 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1347 put_dt(dynamic
, DT_TEXTREL
, 0);
1350 /* add necessary space for other entries */
1351 saved_dynamic_data_offset
= dynamic
->data_offset
;
1352 dynamic
->data_offset
+= sizeof(ElfW(Dyn
)) * 9;
1354 /* still need to build got entries in case of static link */
1355 build_got_entries(s1
);
1359 memset(&ehdr
, 0, sizeof(ehdr
));
1361 /* we add a section for symbols */
1362 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1363 put_elf_str(strsec
, "");
1365 /* compute number of sections */
1366 shnum
= s1
->nb_sections
;
1368 /* this array is used to reorder sections in the output file */
1369 section_order
= tcc_malloc(sizeof(int) * shnum
);
1370 section_order
[0] = 0;
1373 /* compute number of program headers */
1376 case TCC_OUTPUT_OBJ
:
1379 case TCC_OUTPUT_EXE
:
1380 if (!s1
->static_link
)
1385 case TCC_OUTPUT_DLL
:
1390 /* allocate strings for section names and decide if an unallocated
1391 section should be output */
1392 /* NOTE: the strsec section comes last, so its size is also
1394 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1395 s
= s1
->sections
[i
];
1396 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1398 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1403 s
->reloc
? s
->reloc
->name
: "n"
1406 /* when generating a DLL, we include relocations but we may
1408 if (file_type
== TCC_OUTPUT_DLL
&&
1409 s
->sh_type
== SHT_RELX
&&
1410 !(s
->sh_flags
& SHF_ALLOC
)) {
1411 /* //gr: avoid bogus relocs for empty (debug) sections */
1412 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1413 prepare_dynamic_rel(s1
, s
);
1415 s
->sh_size
= s
->data_offset
;
1416 } else if (do_debug
||
1417 file_type
== TCC_OUTPUT_OBJ
||
1418 (s
->sh_flags
& SHF_ALLOC
) ||
1419 i
== (s1
->nb_sections
- 1)) {
1420 /* we output all sections if debug or object file */
1421 s
->sh_size
= s
->data_offset
;
1425 /* allocate program segment headers */
1426 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1428 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1429 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1434 /* compute section to program header mapping */
1435 if (s1
->has_text_addr
) {
1436 int a_offset
, p_offset
;
1437 addr
= s1
->text_addr
;
1438 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1440 a_offset
= addr
& (ELF_PAGE_SIZE
- 1);
1441 p_offset
= file_offset
& (ELF_PAGE_SIZE
- 1);
1442 if (a_offset
< p_offset
)
1443 a_offset
+= ELF_PAGE_SIZE
;
1444 file_offset
+= (a_offset
- p_offset
);
1446 if (file_type
== TCC_OUTPUT_DLL
)
1449 addr
= ELF_START_ADDR
;
1450 /* compute address after headers */
1451 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1454 /* dynamic relocation table information, for .dynamic section */
1458 /* leave one program header for the program interpreter */
1463 for(j
= 0; j
< 2; j
++) {
1464 ph
->p_type
= PT_LOAD
;
1466 ph
->p_flags
= PF_R
| PF_X
;
1468 ph
->p_flags
= PF_R
| PF_W
;
1469 ph
->p_align
= ELF_PAGE_SIZE
;
1471 /* we do the following ordering: interp, symbol tables,
1472 relocations, progbits, nobits */
1473 /* XXX: do faster and simpler sorting */
1474 for(k
= 0; k
< 5; k
++) {
1475 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1476 s
= s1
->sections
[i
];
1477 /* compute if section should be included */
1479 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1483 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1484 (SHF_ALLOC
| SHF_WRITE
))
1490 } else if (s
->sh_type
== SHT_DYNSYM
||
1491 s
->sh_type
== SHT_STRTAB
||
1492 s
->sh_type
== SHT_HASH
) {
1495 } else if (s
->sh_type
== SHT_RELX
) {
1498 } else if (s
->sh_type
== SHT_NOBITS
) {
1505 section_order
[sh_order_index
++] = i
;
1507 /* section matches: we align it and add its size */
1509 addr
= (addr
+ s
->sh_addralign
- 1) &
1510 ~(s
->sh_addralign
- 1);
1511 file_offset
+= addr
- tmp
;
1512 s
->sh_offset
= file_offset
;
1515 /* update program header infos */
1516 if (ph
->p_offset
== 0) {
1517 ph
->p_offset
= file_offset
;
1519 ph
->p_paddr
= ph
->p_vaddr
;
1521 /* update dynamic relocation infos */
1522 if (s
->sh_type
== SHT_RELX
) {
1525 rel_size
+= s
->sh_size
;
1528 if (s
->sh_type
!= SHT_NOBITS
)
1529 file_offset
+= s
->sh_size
;
1532 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1533 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1536 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1537 /* if in the middle of a page, we duplicate the page in
1538 memory so that one copy is RX and the other is RW */
1539 if ((addr
& (ELF_PAGE_SIZE
- 1)) != 0)
1540 addr
+= ELF_PAGE_SIZE
;
1542 addr
= (addr
+ ELF_PAGE_SIZE
- 1) & ~(ELF_PAGE_SIZE
- 1);
1543 file_offset
= (file_offset
+ ELF_PAGE_SIZE
- 1) &
1544 ~(ELF_PAGE_SIZE
- 1);
1549 /* if interpreter, then add corresponing program header */
1553 ph
->p_type
= PT_INTERP
;
1554 ph
->p_offset
= interp
->sh_offset
;
1555 ph
->p_vaddr
= interp
->sh_addr
;
1556 ph
->p_paddr
= ph
->p_vaddr
;
1557 ph
->p_filesz
= interp
->sh_size
;
1558 ph
->p_memsz
= interp
->sh_size
;
1560 ph
->p_align
= interp
->sh_addralign
;
1563 /* if dynamic section, then add corresponing program header */
1567 ph
= &phdr
[phnum
- 1];
1569 ph
->p_type
= PT_DYNAMIC
;
1570 ph
->p_offset
= dynamic
->sh_offset
;
1571 ph
->p_vaddr
= dynamic
->sh_addr
;
1572 ph
->p_paddr
= ph
->p_vaddr
;
1573 ph
->p_filesz
= dynamic
->sh_size
;
1574 ph
->p_memsz
= dynamic
->sh_size
;
1575 ph
->p_flags
= PF_R
| PF_W
;
1576 ph
->p_align
= dynamic
->sh_addralign
;
1578 /* put GOT dynamic section address */
1579 put32(s1
->got
->data
, dynamic
->sh_addr
);
1581 /* relocate the PLT */
1582 if (file_type
== TCC_OUTPUT_EXE
) {
1586 p_end
= p
+ s1
->plt
->data_offset
;
1588 #if defined(TCC_TARGET_I386)
1589 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1590 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1593 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1596 #elif defined(TCC_TARGET_ARM)
1598 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1601 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1604 #elif defined(TCC_TARGET_C67)
1607 #error unsupported CPU
1612 /* relocate symbols in .dynsym */
1613 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1614 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1617 if (sym
->st_shndx
== SHN_UNDEF
) {
1618 /* relocate to the PLT if the symbol corresponds
1621 sym
->st_value
+= s1
->plt
->sh_addr
;
1622 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1623 /* do symbol relocation */
1624 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1628 /* put dynamic section entries */
1629 dynamic
->data_offset
= saved_dynamic_data_offset
;
1630 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1631 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1632 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1633 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1634 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1635 put_dt(dynamic
, DT_REL
, rel_addr
);
1636 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1637 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1639 put_dt(dynamic
, DT_DEBUG
, 0);
1640 put_dt(dynamic
, DT_NULL
, 0);
1643 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1644 ehdr
.e_phnum
= phnum
;
1645 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1648 /* all other sections come after */
1649 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1650 s
= s1
->sections
[i
];
1651 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1653 section_order
[sh_order_index
++] = i
;
1655 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1656 ~(s
->sh_addralign
- 1);
1657 s
->sh_offset
= file_offset
;
1658 if (s
->sh_type
!= SHT_NOBITS
)
1659 file_offset
+= s
->sh_size
;
1662 /* if building executable or DLL, then relocate each section
1663 except the GOT which is already relocated */
1664 if (file_type
!= TCC_OUTPUT_OBJ
) {
1665 relocate_syms(s1
, 0);
1667 if (s1
->nb_errors
!= 0) {
1673 /* relocate sections */
1674 /* XXX: ignore sections with allocated relocations ? */
1675 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1676 s
= s1
->sections
[i
];
1677 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1678 relocate_section(s1
, s
);
1681 /* relocate relocation entries if the relocation tables are
1682 allocated in the executable */
1683 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1684 s
= s1
->sections
[i
];
1685 if ((s
->sh_flags
& SHF_ALLOC
) &&
1686 s
->sh_type
== SHT_RELX
) {
1687 relocate_rel(s1
, s
);
1691 /* get entry point address */
1692 if (file_type
== TCC_OUTPUT_EXE
)
1693 ehdr
.e_entry
= (unsigned long)tcc_get_symbol_err(s1
, "_start");
1695 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1698 /* write elf file */
1699 if (file_type
== TCC_OUTPUT_OBJ
)
1703 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1705 error_noabort("could not write '%s'", filename
);
1708 f
= fdopen(fd
, "wb");
1710 printf("<- %s\n", filename
);
1712 #ifdef TCC_TARGET_COFF
1713 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1714 tcc_output_coff(s1
, f
);
1717 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1718 sort_syms(s1
, symtab_section
);
1721 file_offset
= (file_offset
+ 3) & -4;
1724 ehdr
.e_ident
[0] = ELFMAG0
;
1725 ehdr
.e_ident
[1] = ELFMAG1
;
1726 ehdr
.e_ident
[2] = ELFMAG2
;
1727 ehdr
.e_ident
[3] = ELFMAG3
;
1728 ehdr
.e_ident
[4] = TCC_ELFCLASS
;
1729 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1730 ehdr
.e_ident
[6] = EV_CURRENT
;
1732 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1734 #ifdef TCC_TARGET_ARM
1736 ehdr
.e_ident
[EI_OSABI
] = 0;
1737 ehdr
.e_flags
= 4 << 24;
1739 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
1744 case TCC_OUTPUT_EXE
:
1745 ehdr
.e_type
= ET_EXEC
;
1747 case TCC_OUTPUT_DLL
:
1748 ehdr
.e_type
= ET_DYN
;
1750 case TCC_OUTPUT_OBJ
:
1751 ehdr
.e_type
= ET_REL
;
1754 ehdr
.e_machine
= EM_TCC_TARGET
;
1755 ehdr
.e_version
= EV_CURRENT
;
1756 ehdr
.e_shoff
= file_offset
;
1757 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
1758 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
1759 ehdr
.e_shnum
= shnum
;
1760 ehdr
.e_shstrndx
= shnum
- 1;
1762 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
1763 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
1764 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1766 for(i
=1;i
<s1
->nb_sections
;i
++) {
1767 s
= s1
->sections
[section_order
[i
]];
1768 if (s
->sh_type
!= SHT_NOBITS
) {
1769 while (offset
< s
->sh_offset
) {
1774 fwrite(s
->data
, 1, size
, f
);
1779 /* output section headers */
1780 while (offset
< ehdr
.e_shoff
) {
1785 for(i
=0;i
<s1
->nb_sections
;i
++) {
1787 memset(sh
, 0, sizeof(ElfW(Shdr
)));
1788 s
= s1
->sections
[i
];
1790 sh
->sh_name
= s
->sh_name
;
1791 sh
->sh_type
= s
->sh_type
;
1792 sh
->sh_flags
= s
->sh_flags
;
1793 sh
->sh_entsize
= s
->sh_entsize
;
1794 sh
->sh_info
= s
->sh_info
;
1796 sh
->sh_link
= s
->link
->sh_num
;
1797 sh
->sh_addralign
= s
->sh_addralign
;
1798 sh
->sh_addr
= s
->sh_addr
;
1799 sh
->sh_offset
= s
->sh_offset
;
1800 sh
->sh_size
= s
->sh_size
;
1802 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
1805 tcc_output_binary(s1
, f
, section_order
);
1811 tcc_free(s1
->symtab_to_dynsym
);
1812 tcc_free(section_order
);
1814 tcc_free(s1
->got_offsets
);
1818 int tcc_output_file(TCCState
*s
, const char *filename
)
1821 #ifdef TCC_TARGET_PE
1822 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
1823 ret
= pe_output_file(s
, filename
);
1827 ret
= elf_output_file(s
, filename
);
1832 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
1836 data
= tcc_malloc(size
);
1837 lseek(fd
, file_offset
, SEEK_SET
);
1838 read(fd
, data
, size
);
1842 typedef struct SectionMergeInfo
{
1843 Section
*s
; /* corresponding existing section */
1844 unsigned long offset
; /* offset of the new section in the existing section */
1845 uint8_t new_section
; /* true if section 's' was added */
1846 uint8_t link_once
; /* true if link once section */
1849 /* load an object file and merge it with current files */
1850 /* XXX: handle correctly stab (debug) info */
1851 static int tcc_load_object_file(TCCState
*s1
,
1852 int fd
, unsigned long file_offset
)
1855 ElfW(Shdr
) *shdr
, *sh
;
1856 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
1857 unsigned char *strsec
, *strtab
;
1858 int *old_to_new_syms
;
1859 char *sh_name
, *name
;
1860 SectionMergeInfo
*sm_table
, *sm
;
1861 ElfW(Sym
) *sym
, *symtab
;
1862 ElfW_Rel
*rel
, *rel_end
;
1868 stab_index
= stabstr_index
= 0;
1870 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
1872 if (ehdr
.e_ident
[0] != ELFMAG0
||
1873 ehdr
.e_ident
[1] != ELFMAG1
||
1874 ehdr
.e_ident
[2] != ELFMAG2
||
1875 ehdr
.e_ident
[3] != ELFMAG3
)
1877 /* test if object file */
1878 if (ehdr
.e_type
!= ET_REL
)
1880 /* test CPU specific stuff */
1881 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
1882 ehdr
.e_machine
!= EM_TCC_TARGET
) {
1884 error_noabort("invalid object file");
1888 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
1889 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
1890 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
1892 /* load section names */
1893 sh
= &shdr
[ehdr
.e_shstrndx
];
1894 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1896 /* load symtab and strtab */
1897 old_to_new_syms
= NULL
;
1901 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1903 if (sh
->sh_type
== SHT_SYMTAB
) {
1905 error_noabort("object must contain only one symtab");
1910 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
1911 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1912 sm_table
[i
].s
= symtab_section
;
1914 /* now load strtab */
1915 sh
= &shdr
[sh
->sh_link
];
1916 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1920 /* now examine each section and try to merge its content with the
1922 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1923 /* no need to examine section name strtab */
1924 if (i
== ehdr
.e_shstrndx
)
1927 sh_name
= strsec
+ sh
->sh_name
;
1928 /* ignore sections types we do not handle */
1929 if (sh
->sh_type
!= SHT_PROGBITS
&&
1930 sh
->sh_type
!= SHT_RELX
&&
1932 sh
->sh_type
!= SHT_ARM_EXIDX
&&
1934 sh
->sh_type
!= SHT_NOBITS
&&
1935 strcmp(sh_name
, ".stabstr")
1938 if (sh
->sh_addralign
< 1)
1939 sh
->sh_addralign
= 1;
1940 /* find corresponding section, if any */
1941 for(j
= 1; j
< s1
->nb_sections
;j
++) {
1942 s
= s1
->sections
[j
];
1943 if (!strcmp(s
->name
, sh_name
)) {
1944 if (!strncmp(sh_name
, ".gnu.linkonce",
1945 sizeof(".gnu.linkonce") - 1)) {
1946 /* if a 'linkonce' section is already present, we
1947 do not add it again. It is a little tricky as
1948 symbols can still be defined in
1950 sm_table
[i
].link_once
= 1;
1957 /* not found: create new section */
1958 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
1959 /* take as much info as possible from the section. sh_link and
1960 sh_info will be updated later */
1961 s
->sh_addralign
= sh
->sh_addralign
;
1962 s
->sh_entsize
= sh
->sh_entsize
;
1963 sm_table
[i
].new_section
= 1;
1965 if (sh
->sh_type
!= s
->sh_type
) {
1966 error_noabort("invalid section type");
1970 /* align start of section */
1971 offset
= s
->data_offset
;
1973 if (0 == strcmp(sh_name
, ".stab")) {
1977 if (0 == strcmp(sh_name
, ".stabstr")) {
1982 size
= sh
->sh_addralign
- 1;
1983 offset
= (offset
+ size
) & ~size
;
1984 if (sh
->sh_addralign
> s
->sh_addralign
)
1985 s
->sh_addralign
= sh
->sh_addralign
;
1986 s
->data_offset
= offset
;
1988 sm_table
[i
].offset
= offset
;
1990 /* concatenate sections */
1992 if (sh
->sh_type
!= SHT_NOBITS
) {
1994 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
1995 ptr
= section_ptr_add(s
, size
);
1996 read(fd
, ptr
, size
);
1998 s
->data_offset
+= size
;
2003 /* //gr relocate stab strings */
2004 if (stab_index
&& stabstr_index
) {
2007 s
= sm_table
[stab_index
].s
;
2008 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
2009 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
2010 o
= sm_table
[stabstr_index
].offset
;
2012 a
->n_strx
+= o
, a
++;
2015 /* second short pass to update sh_link and sh_info fields of new
2017 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2019 if (!s
|| !sm_table
[i
].new_section
)
2022 if (sh
->sh_link
> 0)
2023 s
->link
= sm_table
[sh
->sh_link
].s
;
2024 if (sh
->sh_type
== SHT_RELX
) {
2025 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2026 /* update backward link */
2027 s1
->sections
[s
->sh_info
]->reloc
= s
;
2032 /* resolve symbols */
2033 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2036 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2037 if (sym
->st_shndx
!= SHN_UNDEF
&&
2038 sym
->st_shndx
< SHN_LORESERVE
) {
2039 sm
= &sm_table
[sym
->st_shndx
];
2040 if (sm
->link_once
) {
2041 /* if a symbol is in a link once section, we use the
2042 already defined symbol. It is very important to get
2043 correct relocations */
2044 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2045 name
= strtab
+ sym
->st_name
;
2046 sym_index
= find_elf_sym(symtab_section
, name
);
2048 old_to_new_syms
[i
] = sym_index
;
2052 /* if no corresponding section added, no need to add symbol */
2055 /* convert section number */
2056 sym
->st_shndx
= sm
->s
->sh_num
;
2058 sym
->st_value
+= sm
->offset
;
2061 name
= strtab
+ sym
->st_name
;
2062 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2063 sym
->st_info
, sym
->st_other
,
2064 sym
->st_shndx
, name
);
2065 old_to_new_syms
[i
] = sym_index
;
2068 /* third pass to patch relocation entries */
2069 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2074 offset
= sm_table
[i
].offset
;
2075 switch(s
->sh_type
) {
2077 /* take relocation offset information */
2078 offseti
= sm_table
[sh
->sh_info
].offset
;
2079 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2080 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2085 /* convert symbol index */
2086 type
= ELFW(R_TYPE
)(rel
->r_info
);
2087 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2088 /* NOTE: only one symtab assumed */
2089 if (sym_index
>= nb_syms
)
2091 sym_index
= old_to_new_syms
[sym_index
];
2092 /* ignore link_once in rel section. */
2093 if (!sym_index
&& !sm
->link_once
) {
2095 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2096 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2099 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2100 /* offset the relocation offset */
2101 rel
->r_offset
+= offseti
;
2113 tcc_free(old_to_new_syms
);
2120 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2122 typedef struct ArchiveHeader
{
2123 char ar_name
[16]; /* name of this member */
2124 char ar_date
[12]; /* file mtime */
2125 char ar_uid
[6]; /* owner uid; printed as decimal */
2126 char ar_gid
[6]; /* owner gid; printed as decimal */
2127 char ar_mode
[8]; /* file mode, printed as octal */
2128 char ar_size
[10]; /* file size, printed as decimal */
2129 char ar_fmag
[2]; /* should contain ARFMAG */
2132 static int get_be32(const uint8_t *b
)
2134 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2137 /* load only the objects which resolve undefined symbols */
2138 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2140 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2142 const char *ar_names
, *p
;
2143 const uint8_t *ar_index
;
2146 data
= tcc_malloc(size
);
2147 if (read(fd
, data
, size
) != size
)
2149 nsyms
= get_be32(data
);
2150 ar_index
= data
+ 4;
2151 ar_names
= ar_index
+ nsyms
* 4;
2155 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2156 sym_index
= find_elf_sym(symtab_section
, p
);
2158 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2159 if(sym
->st_shndx
== SHN_UNDEF
) {
2160 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2162 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2165 lseek(fd
, off
, SEEK_SET
);
2166 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2181 /* load a '.a' file */
2182 static int tcc_load_archive(TCCState
*s1
, int fd
)
2189 unsigned long file_offset
;
2191 /* skip magic which was already checked */
2192 read(fd
, magic
, sizeof(magic
));
2195 len
= read(fd
, &hdr
, sizeof(hdr
));
2198 if (len
!= sizeof(hdr
)) {
2199 error_noabort("invalid archive");
2202 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2203 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2204 size
= strtol(ar_size
, NULL
, 0);
2205 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2206 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2207 if (ar_name
[i
] != ' ')
2210 ar_name
[i
+ 1] = '\0';
2211 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2212 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2214 size
= (size
+ 1) & ~1;
2215 if (!strcmp(ar_name
, "/")) {
2216 /* coff symbol table : we handle it */
2217 if(s1
->alacarte_link
)
2218 return tcc_load_alacarte(s1
, fd
, size
);
2219 } else if (!strcmp(ar_name
, "//") ||
2220 !strcmp(ar_name
, "__.SYMDEF") ||
2221 !strcmp(ar_name
, "__.SYMDEF/") ||
2222 !strcmp(ar_name
, "ARFILENAMES/")) {
2223 /* skip symbol table or archive names */
2225 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2228 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2233 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2234 is referenced by the user (so it should be added as DT_NEEDED in
2235 the generated ELF file) */
2236 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2239 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2240 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2241 ElfW(Sym
) *sym
, *dynsym
;
2242 ElfW(Dyn
) *dt
, *dynamic
;
2243 unsigned char *dynstr
;
2244 const char *name
, *soname
;
2245 DLLReference
*dllref
;
2247 read(fd
, &ehdr
, sizeof(ehdr
));
2249 /* test CPU specific stuff */
2250 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2251 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2252 error_noabort("bad architecture");
2257 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2259 /* load dynamic section and dynamic symbols */
2263 dynsym
= NULL
; /* avoid warning */
2264 dynstr
= NULL
; /* avoid warning */
2265 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2266 switch(sh
->sh_type
) {
2268 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2269 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2272 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2273 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2274 sh1
= &shdr
[sh
->sh_link
];
2275 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2282 /* compute the real library name */
2283 soname
= tcc_basename(filename
);
2285 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2286 if (dt
->d_tag
== DT_SONAME
) {
2287 soname
= dynstr
+ dt
->d_un
.d_val
;
2291 /* if the dll is already loaded, do not load it */
2292 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2293 dllref
= s1
->loaded_dlls
[i
];
2294 if (!strcmp(soname
, dllref
->name
)) {
2295 /* but update level if needed */
2296 if (level
< dllref
->level
)
2297 dllref
->level
= level
;
2303 // printf("loading dll '%s'\n", soname);
2305 /* add the dll and its level */
2306 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2307 dllref
->level
= level
;
2308 strcpy(dllref
->name
, soname
);
2309 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2311 /* add dynamic symbols in dynsym_section */
2312 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2313 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2314 if (sym_bind
== STB_LOCAL
)
2316 name
= dynstr
+ sym
->st_name
;
2317 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2318 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2321 /* load all referenced DLLs */
2322 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2325 name
= dynstr
+ dt
->d_un
.d_val
;
2326 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2327 dllref
= s1
->loaded_dlls
[j
];
2328 if (!strcmp(name
, dllref
->name
))
2329 goto already_loaded
;
2331 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2332 error_noabort("referenced dll '%s' not found", name
);
2349 #define LD_TOK_NAME 256
2350 #define LD_TOK_EOF (-1)
2352 /* return next ld script token */
2353 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2371 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2372 ch
= file
->buf_ptr
[0];
2380 /* case 'a' ... 'z': */
2407 /* case 'A' ... 'z': */
2442 if (!((ch
>= 'a' && ch
<= 'z') ||
2443 (ch
>= 'A' && ch
<= 'Z') ||
2444 (ch
>= '0' && ch
<= '9') ||
2445 strchr("/.-_+=$:\\,~", ch
)))
2447 if ((q
- name
) < name_size
- 1) {
2464 printf("tok=%c %d\n", c
, c
);
2465 if (c
== LD_TOK_NAME
)
2466 printf(" name=%s\n", name
);
2471 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2473 char filename
[1024];
2476 t
= ld_next(s1
, filename
, sizeof(filename
));
2479 t
= ld_next(s1
, filename
, sizeof(filename
));
2481 if (t
== LD_TOK_EOF
) {
2482 error_noabort("unexpected end of file");
2484 } else if (t
== ')') {
2486 } else if (t
!= LD_TOK_NAME
) {
2487 error_noabort("filename expected");
2490 if (!strcmp(filename
, "AS_NEEDED")) {
2491 ret
= ld_add_file_list(s1
, 1);
2495 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2497 tcc_add_file(s1
, filename
);
2499 t
= ld_next(s1
, filename
, sizeof(filename
));
2501 t
= ld_next(s1
, filename
, sizeof(filename
));
2507 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2509 static int tcc_load_ldscript(TCCState
*s1
)
2512 char filename
[1024];
2515 ch
= file
->buf_ptr
[0];
2518 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2519 if (t
== LD_TOK_EOF
)
2521 else if (t
!= LD_TOK_NAME
)
2523 if (!strcmp(cmd
, "INPUT") ||
2524 !strcmp(cmd
, "GROUP")) {
2525 ret
= ld_add_file_list(s1
, 0);
2528 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2529 !strcmp(cmd
, "TARGET")) {
2530 /* ignore some commands */
2531 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2535 t
= ld_next(s1
, filename
, sizeof(filename
));
2536 if (t
== LD_TOK_EOF
) {
2537 error_noabort("unexpected end of file");
2539 } else if (t
== ')') {