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%s", 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 * sizeof(int));
728 /* keep space for _DYNAMIC pointer, if present */
730 /* two dummy got entries */
735 /* put a got entry corresponding to a symbol in symtab_section. 'size'
736 and 'info' can be modifed if more precise info comes from the DLL */
737 static void put_got_entry(TCCState
*s1
,
738 int reloc_type
, unsigned long size
, int info
,
744 unsigned long offset
;
750 /* if a got entry already exists for that symbol, no need to add one */
751 if (sym_index
< s1
->nb_got_offsets
&&
752 s1
->got_offsets
[sym_index
] != 0)
755 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
758 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
759 name
= symtab_section
->link
->data
+ sym
->st_name
;
760 offset
= sym
->st_value
;
761 #ifdef TCC_TARGET_I386
762 if (reloc_type
== R_386_JMP_SLOT
) {
767 /* if we build a DLL, we add a %ebx offset */
768 if (s1
->output_type
== TCC_OUTPUT_DLL
)
773 /* add a PLT entry */
775 if (plt
->data_offset
== 0) {
776 /* first plt entry */
777 p
= section_ptr_add(plt
, 16);
778 p
[0] = 0xff; /* pushl got + 4 */
781 p
[6] = 0xff; /* jmp *(got + 8) */
786 p
= section_ptr_add(plt
, 16);
787 p
[0] = 0xff; /* jmp *(got + x) */
789 put32(p
+ 2, s1
->got
->data_offset
);
790 p
[6] = 0x68; /* push $xxx */
791 put32(p
+ 7, (plt
->data_offset
- 32) >> 1);
792 p
[11] = 0xe9; /* jmp plt_start */
793 put32(p
+ 12, -(plt
->data_offset
));
795 /* the symbol is modified so that it will be relocated to
797 if (s1
->output_type
== TCC_OUTPUT_EXE
)
798 offset
= plt
->data_offset
- 16;
800 #elif defined(TCC_TARGET_ARM)
801 if (reloc_type
== R_ARM_JUMP_SLOT
) {
805 /* if we build a DLL, we add a %ebx offset */
806 if (s1
->output_type
== TCC_OUTPUT_DLL
)
807 error("DLLs unimplemented!");
809 /* add a PLT entry */
811 if (plt
->data_offset
== 0) {
812 /* first plt entry */
813 p
= section_ptr_add(plt
, 16);
814 put32(p
, 0xe52de004);
815 put32(p
+ 4, 0xe59fe010);
816 put32(p
+ 8, 0xe08fe00e);
817 put32(p
+ 12, 0xe5bef008);
820 p
= section_ptr_add(plt
, 16);
821 put32(p
, 0xe59fc004);
822 put32(p
+4, 0xe08fc00c);
823 put32(p
+8, 0xe59cf000);
824 put32(p
+12, s1
->got
->data_offset
);
826 /* the symbol is modified so that it will be relocated to
828 if (s1
->output_type
== TCC_OUTPUT_EXE
)
829 offset
= plt
->data_offset
- 16;
831 #elif defined(TCC_TARGET_C67)
832 error("C67 got not implemented");
834 #error unsupported CPU
836 index
= put_elf_sym(s1
->dynsym
, offset
,
837 size
, info
, 0, sym
->st_shndx
, name
);
838 /* put a got entry */
839 put_elf_reloc(s1
->dynsym
, s1
->got
,
840 s1
->got
->data_offset
,
843 ptr
= section_ptr_add(s1
->got
, sizeof(int));
847 /* build GOT and PLT entries */
848 static void build_got_entries(TCCState
*s1
)
851 ElfW_Rel
*rel
, *rel_end
;
853 int i
, type
, reloc_type
, sym_index
;
855 for(i
= 1; i
< s1
->nb_sections
; i
++) {
857 if (s
->sh_type
!= SHT_RELX
)
859 /* no need to handle got relocations */
860 if (s
->link
!= symtab_section
)
863 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
864 for(rel
= (ElfW_Rel
*)s
->data
;
867 type
= ELFW(R_TYPE
)(rel
->r_info
);
869 #if defined(TCC_TARGET_I386)
876 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
877 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
878 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
879 /* look at the symbol got offset. If none, then add one */
880 if (type
== R_386_GOT32
)
881 reloc_type
= R_386_GLOB_DAT
;
883 reloc_type
= R_386_JMP_SLOT
;
884 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
888 #elif defined(TCC_TARGET_ARM)
891 case R_ARM_BASE_PREL
:
895 if (type
== R_ARM_GOT_BREL
|| type
== R_ARM_PLT32
) {
896 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
897 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
898 /* look at the symbol got offset. If none, then add one */
899 if (type
== R_ARM_GOT_BREL
)
900 reloc_type
= R_ARM_GLOB_DAT
;
902 reloc_type
= R_ARM_JUMP_SLOT
;
903 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
907 #elif defined(TCC_TARGET_C67)
914 if (type
== R_C60_GOT32
|| type
== R_C60_PLT32
) {
915 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
916 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
917 /* look at the symbol got offset. If none, then add one */
918 if (type
== R_C60_GOT32
)
919 reloc_type
= R_C60_GLOB_DAT
;
921 reloc_type
= R_C60_JMP_SLOT
;
922 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
927 #error unsupported CPU
936 static Section
*new_symtab(TCCState
*s1
,
937 const char *symtab_name
, int sh_type
, int sh_flags
,
938 const char *strtab_name
,
939 const char *hash_name
, int hash_sh_flags
)
941 Section
*symtab
, *strtab
, *hash
;
942 int *ptr
, nb_buckets
;
944 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
945 symtab
->sh_entsize
= sizeof(ElfW(Sym
));
946 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
947 put_elf_str(strtab
, "");
948 symtab
->link
= strtab
;
949 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
953 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
954 hash
->sh_entsize
= sizeof(int);
958 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
961 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
965 /* put dynamic tag */
966 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
969 dyn
= section_ptr_add(dynamic
, sizeof(ElfW(Dyn
)));
971 dyn
->d_un
.d_val
= val
;
974 static void add_init_array_defines(TCCState
*s1
, const char *section_name
)
978 char sym_start
[1024];
981 snprintf(sym_start
, sizeof(sym_start
), "__%s_start", section_name
+ 1);
982 snprintf(sym_end
, sizeof(sym_end
), "__%s_end", section_name
+ 1);
984 s
= find_section(s1
, section_name
);
989 end_offset
= s
->data_offset
;
992 add_elf_sym(symtab_section
,
994 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
995 s
->sh_num
, sym_start
);
996 add_elf_sym(symtab_section
,
998 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1002 /* add tcc runtime libraries */
1003 static void tcc_add_runtime(TCCState
*s1
)
1005 #if defined(CONFIG_TCC_BCHECK) || !defined(CONFIG_USE_LIBGCC)
1009 #ifdef CONFIG_TCC_BCHECK
1010 if (do_bounds_check
) {
1012 Section
*init_section
;
1013 unsigned char *pinit
;
1016 /* XXX: add an object file to do that */
1017 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
1019 add_elf_sym(symtab_section
, 0, 0,
1020 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1021 bounds_section
->sh_num
, "__bounds_start");
1022 /* add bound check code */
1023 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "bcheck.o");
1024 tcc_add_file(s1
, buf
);
1025 #ifdef TCC_TARGET_I386
1026 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
1027 /* add 'call __bound_init()' in .init section */
1028 init_section
= find_section(s1
, ".init");
1029 pinit
= section_ptr_add(init_section
, 5);
1031 put32(pinit
+ 1, -4);
1032 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
1033 put_elf_reloc(symtab_section
, init_section
,
1034 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
1040 if (!s1
->nostdlib
) {
1041 tcc_add_library(s1
, "c");
1043 #ifdef CONFIG_USE_LIBGCC
1044 tcc_add_file(s1
, CONFIG_SYSROOT
"/lib/libgcc_s.so.1");
1046 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "libtcc1.a");
1047 tcc_add_file(s1
, buf
);
1050 /* add crt end if not memory output */
1051 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
&& !s1
->nostdlib
) {
1052 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
1056 /* add various standard linker symbols (must be done after the
1057 sections are filled (for example after allocating common
1059 static void tcc_add_linker_symbols(TCCState
*s1
)
1065 add_elf_sym(symtab_section
,
1066 text_section
->data_offset
, 0,
1067 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1068 text_section
->sh_num
, "_etext");
1069 add_elf_sym(symtab_section
,
1070 data_section
->data_offset
, 0,
1071 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1072 data_section
->sh_num
, "_edata");
1073 add_elf_sym(symtab_section
,
1074 bss_section
->data_offset
, 0,
1075 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1076 bss_section
->sh_num
, "_end");
1077 /* horrible new standard ldscript defines */
1078 add_init_array_defines(s1
, ".preinit_array");
1079 add_init_array_defines(s1
, ".init_array");
1080 add_init_array_defines(s1
, ".fini_array");
1082 /* add start and stop symbols for sections whose name can be
1084 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1085 s
= s1
->sections
[i
];
1086 if (s
->sh_type
== SHT_PROGBITS
&&
1087 (s
->sh_flags
& SHF_ALLOC
)) {
1091 /* check if section name can be expressed in C */
1097 if (!isid(ch
) && !isnum(ch
))
1101 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
1102 add_elf_sym(symtab_section
,
1104 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1106 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
1107 add_elf_sym(symtab_section
,
1109 ELFW(ST_INFO
)(STB_GLOBAL
, STT_NOTYPE
), 0,
1116 /* name of ELF interpreter */
1118 static char elf_interp
[] = "/usr/libexec/ld-elf.so.1";
1121 static char elf_interp
[] = "/lib/ld-linux.so.3";
1123 static char elf_interp
[] = "/lib/ld-linux.so.2";
1127 static void tcc_output_binary(TCCState
*s1
, FILE *f
,
1128 const int *section_order
)
1131 int i
, offset
, size
;
1134 for(i
=1;i
<s1
->nb_sections
;i
++) {
1135 s
= s1
->sections
[section_order
[i
]];
1136 if (s
->sh_type
!= SHT_NOBITS
&&
1137 (s
->sh_flags
& SHF_ALLOC
)) {
1138 while (offset
< s
->sh_offset
) {
1143 fwrite(s
->data
, 1, size
, f
);
1149 /* output an ELF file */
1150 /* XXX: suppress unneeded sections */
1151 int elf_output_file(TCCState
*s1
, const char *filename
)
1157 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
1159 Section
*strsec
, *s
;
1160 ElfW(Shdr
) shdr
, *sh
;
1161 ElfW(Phdr
) *phdr
, *ph
;
1162 Section
*interp
, *dynamic
, *dynstr
;
1163 unsigned long saved_dynamic_data_offset
;
1165 int type
, file_type
;
1166 unsigned long rel_addr
, rel_size
;
1168 file_type
= s1
->output_type
;
1171 if (file_type
!= TCC_OUTPUT_OBJ
) {
1172 tcc_add_runtime(s1
);
1176 section_order
= NULL
;
1179 dynstr
= NULL
; /* avoid warning */
1180 saved_dynamic_data_offset
= 0; /* avoid warning */
1182 if (file_type
!= TCC_OUTPUT_OBJ
) {
1183 relocate_common_syms();
1185 tcc_add_linker_symbols(s1
);
1187 if (!s1
->static_link
) {
1189 int sym_index
, index
;
1190 ElfW(Sym
) *esym
, *sym_end
;
1192 if (file_type
== TCC_OUTPUT_EXE
) {
1194 /* add interpreter section only if executable */
1195 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
1196 interp
->sh_addralign
= 1;
1197 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
1198 strcpy(ptr
, elf_interp
);
1201 /* add dynamic symbol table */
1202 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
1204 ".hash", SHF_ALLOC
);
1205 dynstr
= s1
->dynsym
->link
;
1207 /* add dynamic section */
1208 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
1209 SHF_ALLOC
| SHF_WRITE
);
1210 dynamic
->link
= dynstr
;
1211 dynamic
->sh_entsize
= sizeof(ElfW(Dyn
));
1214 s1
->plt
= new_section(s1
, ".plt", SHT_PROGBITS
,
1215 SHF_ALLOC
| SHF_EXECINSTR
);
1216 s1
->plt
->sh_entsize
= 4;
1220 /* scan for undefined symbols and see if they are in the
1221 dynamic symbols. If a symbol STT_FUNC is found, then we
1222 add it in the PLT. If a symbol STT_OBJECT is found, we
1223 add it in the .bss section with a suitable relocation */
1224 sym_end
= (ElfW(Sym
) *)(symtab_section
->data
+
1225 symtab_section
->data_offset
);
1226 if (file_type
== TCC_OUTPUT_EXE
) {
1227 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1230 if (sym
->st_shndx
== SHN_UNDEF
) {
1231 name
= symtab_section
->link
->data
+ sym
->st_name
;
1232 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
1234 esym
= &((ElfW(Sym
) *)s1
->dynsymtab_section
->data
)[sym_index
];
1235 type
= ELFW(ST_TYPE
)(esym
->st_info
);
1236 if (type
== STT_FUNC
) {
1237 put_got_entry(s1
, R_JMP_SLOT
, esym
->st_size
,
1239 sym
- (ElfW(Sym
) *)symtab_section
->data
);
1240 } else if (type
== STT_OBJECT
) {
1241 unsigned long offset
;
1242 offset
= bss_section
->data_offset
;
1243 /* XXX: which alignment ? */
1244 offset
= (offset
+ 16 - 1) & -16;
1245 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
1247 bss_section
->sh_num
, name
);
1248 put_elf_reloc(s1
->dynsym
, bss_section
,
1249 offset
, R_COPY
, index
);
1250 offset
+= esym
->st_size
;
1251 bss_section
->data_offset
= offset
;
1254 /* STB_WEAK undefined symbols are accepted */
1255 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
1257 if (ELFW(ST_BIND
)(sym
->st_info
) == STB_WEAK
||
1258 !strcmp(name
, "_fp_hw")) {
1260 error_noabort("undefined symbol '%s'", name
);
1263 } else if (s1
->rdynamic
&&
1264 ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1265 /* if -rdynamic option, then export all non
1267 name
= symtab_section
->link
->data
+ sym
->st_name
;
1268 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1270 sym
->st_shndx
, name
);
1277 /* now look at unresolved dynamic symbols and export
1278 corresponding symbol */
1279 sym_end
= (ElfW(Sym
) *)(s1
->dynsymtab_section
->data
+
1280 s1
->dynsymtab_section
->data_offset
);
1281 for(esym
= (ElfW(Sym
) *)s1
->dynsymtab_section
->data
+ 1;
1284 if (esym
->st_shndx
== SHN_UNDEF
) {
1285 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
1286 sym_index
= find_elf_sym(symtab_section
, name
);
1288 /* XXX: avoid adding a symbol if already
1289 present because of -rdynamic ? */
1290 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
1291 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1293 sym
->st_shndx
, name
);
1295 if (ELFW(ST_BIND
)(esym
->st_info
) == STB_WEAK
) {
1296 /* weak symbols can stay undefined */
1298 warning("undefined dynamic symbol '%s'", name
);
1305 /* shared library case : we simply export all the global symbols */
1306 nb_syms
= symtab_section
->data_offset
/ sizeof(ElfW(Sym
));
1307 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
1308 for(sym
= (ElfW(Sym
) *)symtab_section
->data
+ 1;
1311 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
1312 name
= symtab_section
->link
->data
+ sym
->st_name
;
1313 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
1315 sym
->st_shndx
, name
);
1316 s1
->symtab_to_dynsym
[sym
-
1317 (ElfW(Sym
) *)symtab_section
->data
] =
1323 build_got_entries(s1
);
1325 /* add a list of needed dlls */
1326 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1327 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1328 if (dllref
->level
== 0)
1329 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1331 /* XXX: currently, since we do not handle PIC code, we
1332 must relocate the readonly segments */
1333 if (file_type
== TCC_OUTPUT_DLL
) {
1335 put_dt(dynamic
, DT_SONAME
, put_elf_str(dynstr
, s1
->soname
));
1336 put_dt(dynamic
, DT_TEXTREL
, 0);
1339 /* add necessary space for other entries */
1340 saved_dynamic_data_offset
= dynamic
->data_offset
;
1341 dynamic
->data_offset
+= 8 * 9;
1343 /* still need to build got entries in case of static link */
1344 build_got_entries(s1
);
1348 memset(&ehdr
, 0, sizeof(ehdr
));
1350 /* we add a section for symbols */
1351 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1352 put_elf_str(strsec
, "");
1354 /* compute number of sections */
1355 shnum
= s1
->nb_sections
;
1357 /* this array is used to reorder sections in the output file */
1358 section_order
= tcc_malloc(sizeof(int) * shnum
);
1359 section_order
[0] = 0;
1362 /* compute number of program headers */
1365 case TCC_OUTPUT_OBJ
:
1368 case TCC_OUTPUT_EXE
:
1369 if (!s1
->static_link
)
1374 case TCC_OUTPUT_DLL
:
1379 /* allocate strings for section names and decide if an unallocated
1380 section should be output */
1381 /* NOTE: the strsec section comes last, so its size is also
1383 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1384 s
= s1
->sections
[i
];
1385 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1387 printf("section: f=%08x t=%08x i=%08x %s %s\n",
1392 s
->reloc
? s
->reloc
->name
: "n"
1395 /* when generating a DLL, we include relocations but we may
1397 if (file_type
== TCC_OUTPUT_DLL
&&
1398 s
->sh_type
== SHT_RELX
&&
1399 !(s
->sh_flags
& SHF_ALLOC
)) {
1400 /* //gr: avoid bogus relocs for empty (debug) sections */
1401 if (s1
->sections
[s
->sh_info
]->sh_flags
& SHF_ALLOC
)
1402 prepare_dynamic_rel(s1
, s
);
1404 s
->sh_size
= s
->data_offset
;
1405 } else if (do_debug
||
1406 file_type
== TCC_OUTPUT_OBJ
||
1407 (s
->sh_flags
& SHF_ALLOC
) ||
1408 i
== (s1
->nb_sections
- 1)) {
1409 /* we output all sections if debug or object file */
1410 s
->sh_size
= s
->data_offset
;
1414 /* allocate program segment headers */
1415 phdr
= tcc_mallocz(phnum
* sizeof(ElfW(Phdr
)));
1417 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1418 file_offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1423 /* compute section to program header mapping */
1424 if (s1
->has_text_addr
) {
1425 int a_offset
, p_offset
;
1426 addr
= s1
->text_addr
;
1427 /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
1429 a_offset
= addr
& (ELF_PAGE_SIZE
- 1);
1430 p_offset
= file_offset
& (ELF_PAGE_SIZE
- 1);
1431 if (a_offset
< p_offset
)
1432 a_offset
+= ELF_PAGE_SIZE
;
1433 file_offset
+= (a_offset
- p_offset
);
1435 if (file_type
== TCC_OUTPUT_DLL
)
1438 addr
= ELF_START_ADDR
;
1439 /* compute address after headers */
1440 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1443 /* dynamic relocation table information, for .dynamic section */
1447 /* leave one program header for the program interpreter */
1452 for(j
= 0; j
< 2; j
++) {
1453 ph
->p_type
= PT_LOAD
;
1455 ph
->p_flags
= PF_R
| PF_X
;
1457 ph
->p_flags
= PF_R
| PF_W
;
1458 ph
->p_align
= ELF_PAGE_SIZE
;
1460 /* we do the following ordering: interp, symbol tables,
1461 relocations, progbits, nobits */
1462 /* XXX: do faster and simpler sorting */
1463 for(k
= 0; k
< 5; k
++) {
1464 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1465 s
= s1
->sections
[i
];
1466 /* compute if section should be included */
1468 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1472 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1473 (SHF_ALLOC
| SHF_WRITE
))
1479 } else if (s
->sh_type
== SHT_DYNSYM
||
1480 s
->sh_type
== SHT_STRTAB
||
1481 s
->sh_type
== SHT_HASH
) {
1484 } else if (s
->sh_type
== SHT_RELX
) {
1487 } else if (s
->sh_type
== SHT_NOBITS
) {
1494 section_order
[sh_order_index
++] = i
;
1496 /* section matches: we align it and add its size */
1498 addr
= (addr
+ s
->sh_addralign
- 1) &
1499 ~(s
->sh_addralign
- 1);
1500 file_offset
+= addr
- tmp
;
1501 s
->sh_offset
= file_offset
;
1504 /* update program header infos */
1505 if (ph
->p_offset
== 0) {
1506 ph
->p_offset
= file_offset
;
1508 ph
->p_paddr
= ph
->p_vaddr
;
1510 /* update dynamic relocation infos */
1511 if (s
->sh_type
== SHT_RELX
) {
1514 rel_size
+= s
->sh_size
;
1517 if (s
->sh_type
!= SHT_NOBITS
)
1518 file_offset
+= s
->sh_size
;
1521 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1522 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1525 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1526 /* if in the middle of a page, we duplicate the page in
1527 memory so that one copy is RX and the other is RW */
1528 if ((addr
& (ELF_PAGE_SIZE
- 1)) != 0)
1529 addr
+= ELF_PAGE_SIZE
;
1531 addr
= (addr
+ ELF_PAGE_SIZE
- 1) & ~(ELF_PAGE_SIZE
- 1);
1532 file_offset
= (file_offset
+ ELF_PAGE_SIZE
- 1) &
1533 ~(ELF_PAGE_SIZE
- 1);
1538 /* if interpreter, then add corresponing program header */
1542 ph
->p_type
= PT_INTERP
;
1543 ph
->p_offset
= interp
->sh_offset
;
1544 ph
->p_vaddr
= interp
->sh_addr
;
1545 ph
->p_paddr
= ph
->p_vaddr
;
1546 ph
->p_filesz
= interp
->sh_size
;
1547 ph
->p_memsz
= interp
->sh_size
;
1549 ph
->p_align
= interp
->sh_addralign
;
1552 /* if dynamic section, then add corresponing program header */
1556 ph
= &phdr
[phnum
- 1];
1558 ph
->p_type
= PT_DYNAMIC
;
1559 ph
->p_offset
= dynamic
->sh_offset
;
1560 ph
->p_vaddr
= dynamic
->sh_addr
;
1561 ph
->p_paddr
= ph
->p_vaddr
;
1562 ph
->p_filesz
= dynamic
->sh_size
;
1563 ph
->p_memsz
= dynamic
->sh_size
;
1564 ph
->p_flags
= PF_R
| PF_W
;
1565 ph
->p_align
= dynamic
->sh_addralign
;
1567 /* put GOT dynamic section address */
1568 put32(s1
->got
->data
, dynamic
->sh_addr
);
1570 /* relocate the PLT */
1571 if (file_type
== TCC_OUTPUT_EXE
) {
1575 p_end
= p
+ s1
->plt
->data_offset
;
1577 #if defined(TCC_TARGET_I386)
1578 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1579 put32(p
+ 8, get32(p
+ 8) + s1
->got
->sh_addr
);
1582 put32(p
+ 2, get32(p
+ 2) + s1
->got
->sh_addr
);
1585 #elif defined(TCC_TARGET_ARM)
1587 x
=s1
->got
->sh_addr
- s1
->plt
->sh_addr
- 12;
1590 put32(p
+ 12, x
+ get32(p
+ 12) + s1
->plt
->data
- p
);
1593 #elif defined(TCC_TARGET_C67)
1596 #error unsupported CPU
1601 /* relocate symbols in .dynsym */
1602 sym_end
= (ElfW(Sym
) *)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1603 for(sym
= (ElfW(Sym
) *)s1
->dynsym
->data
+ 1;
1606 if (sym
->st_shndx
== SHN_UNDEF
) {
1607 /* relocate to the PLT if the symbol corresponds
1610 sym
->st_value
+= s1
->plt
->sh_addr
;
1611 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1612 /* do symbol relocation */
1613 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1617 /* put dynamic section entries */
1618 dynamic
->data_offset
= saved_dynamic_data_offset
;
1619 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1620 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1621 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1622 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1623 put_dt(dynamic
, DT_SYMENT
, sizeof(ElfW(Sym
)));
1624 put_dt(dynamic
, DT_REL
, rel_addr
);
1625 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1626 put_dt(dynamic
, DT_RELENT
, sizeof(ElfW_Rel
));
1628 put_dt(dynamic
, DT_DEBUG
, 0);
1629 put_dt(dynamic
, DT_NULL
, 0);
1632 ehdr
.e_phentsize
= sizeof(ElfW(Phdr
));
1633 ehdr
.e_phnum
= phnum
;
1634 ehdr
.e_phoff
= sizeof(ElfW(Ehdr
));
1637 /* all other sections come after */
1638 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1639 s
= s1
->sections
[i
];
1640 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1642 section_order
[sh_order_index
++] = i
;
1644 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1645 ~(s
->sh_addralign
- 1);
1646 s
->sh_offset
= file_offset
;
1647 if (s
->sh_type
!= SHT_NOBITS
)
1648 file_offset
+= s
->sh_size
;
1651 /* if building executable or DLL, then relocate each section
1652 except the GOT which is already relocated */
1653 if (file_type
!= TCC_OUTPUT_OBJ
) {
1654 relocate_syms(s1
, 0);
1656 if (s1
->nb_errors
!= 0) {
1662 /* relocate sections */
1663 /* XXX: ignore sections with allocated relocations ? */
1664 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1665 s
= s1
->sections
[i
];
1666 if (s
->reloc
&& s
!= s1
->got
&& (s
->sh_flags
& SHF_ALLOC
)) //gr
1667 relocate_section(s1
, s
);
1670 /* relocate relocation entries if the relocation tables are
1671 allocated in the executable */
1672 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1673 s
= s1
->sections
[i
];
1674 if ((s
->sh_flags
& SHF_ALLOC
) &&
1675 s
->sh_type
== SHT_RELX
) {
1676 relocate_rel(s1
, s
);
1680 /* get entry point address */
1681 if (file_type
== TCC_OUTPUT_EXE
)
1682 ehdr
.e_entry
= (unsigned long)tcc_get_symbol_err(s1
, "_start");
1684 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1687 /* write elf file */
1688 if (file_type
== TCC_OUTPUT_OBJ
)
1692 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
1694 error_noabort("could not write '%s'", filename
);
1697 f
= fdopen(fd
, "wb");
1699 printf("<- %s\n", filename
);
1701 #ifdef TCC_TARGET_COFF
1702 if (s1
->output_format
== TCC_OUTPUT_FORMAT_COFF
) {
1703 tcc_output_coff(s1
, f
);
1706 if (s1
->output_format
== TCC_OUTPUT_FORMAT_ELF
) {
1707 sort_syms(s1
, symtab_section
);
1710 file_offset
= (file_offset
+ 3) & -4;
1713 ehdr
.e_ident
[0] = ELFMAG0
;
1714 ehdr
.e_ident
[1] = ELFMAG1
;
1715 ehdr
.e_ident
[2] = ELFMAG2
;
1716 ehdr
.e_ident
[3] = ELFMAG3
;
1717 ehdr
.e_ident
[4] = ELFCLASS32
;
1718 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1719 ehdr
.e_ident
[6] = EV_CURRENT
;
1721 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1723 #ifdef TCC_TARGET_ARM
1725 ehdr
.e_ident
[EI_OSABI
] = 0;
1726 ehdr
.e_flags
= 4 << 24;
1728 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_ARM
;
1733 case TCC_OUTPUT_EXE
:
1734 ehdr
.e_type
= ET_EXEC
;
1736 case TCC_OUTPUT_DLL
:
1737 ehdr
.e_type
= ET_DYN
;
1739 case TCC_OUTPUT_OBJ
:
1740 ehdr
.e_type
= ET_REL
;
1743 ehdr
.e_machine
= EM_TCC_TARGET
;
1744 ehdr
.e_version
= EV_CURRENT
;
1745 ehdr
.e_shoff
= file_offset
;
1746 ehdr
.e_ehsize
= sizeof(ElfW(Ehdr
));
1747 ehdr
.e_shentsize
= sizeof(ElfW(Shdr
));
1748 ehdr
.e_shnum
= shnum
;
1749 ehdr
.e_shstrndx
= shnum
- 1;
1751 fwrite(&ehdr
, 1, sizeof(ElfW(Ehdr
)), f
);
1752 fwrite(phdr
, 1, phnum
* sizeof(ElfW(Phdr
)), f
);
1753 offset
= sizeof(ElfW(Ehdr
)) + phnum
* sizeof(ElfW(Phdr
));
1755 for(i
=1;i
<s1
->nb_sections
;i
++) {
1756 s
= s1
->sections
[section_order
[i
]];
1757 if (s
->sh_type
!= SHT_NOBITS
) {
1758 while (offset
< s
->sh_offset
) {
1763 fwrite(s
->data
, 1, size
, f
);
1768 /* output section headers */
1769 while (offset
< ehdr
.e_shoff
) {
1774 for(i
=0;i
<s1
->nb_sections
;i
++) {
1776 memset(sh
, 0, sizeof(ElfW(Shdr
)));
1777 s
= s1
->sections
[i
];
1779 sh
->sh_name
= s
->sh_name
;
1780 sh
->sh_type
= s
->sh_type
;
1781 sh
->sh_flags
= s
->sh_flags
;
1782 sh
->sh_entsize
= s
->sh_entsize
;
1783 sh
->sh_info
= s
->sh_info
;
1785 sh
->sh_link
= s
->link
->sh_num
;
1786 sh
->sh_addralign
= s
->sh_addralign
;
1787 sh
->sh_addr
= s
->sh_addr
;
1788 sh
->sh_offset
= s
->sh_offset
;
1789 sh
->sh_size
= s
->sh_size
;
1791 fwrite(sh
, 1, sizeof(ElfW(Shdr
)), f
);
1794 tcc_output_binary(s1
, f
, section_order
);
1800 tcc_free(s1
->symtab_to_dynsym
);
1801 tcc_free(section_order
);
1803 tcc_free(s1
->got_offsets
);
1807 int tcc_output_file(TCCState
*s
, const char *filename
)
1810 #ifdef TCC_TARGET_PE
1811 if (s
->output_type
!= TCC_OUTPUT_OBJ
) {
1812 ret
= pe_output_file(s
, filename
);
1816 ret
= elf_output_file(s
, filename
);
1821 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
1825 data
= tcc_malloc(size
);
1826 lseek(fd
, file_offset
, SEEK_SET
);
1827 read(fd
, data
, size
);
1831 typedef struct SectionMergeInfo
{
1832 Section
*s
; /* corresponding existing section */
1833 unsigned long offset
; /* offset of the new section in the existing section */
1834 uint8_t new_section
; /* true if section 's' was added */
1835 uint8_t link_once
; /* true if link once section */
1838 /* load an object file and merge it with current files */
1839 /* XXX: handle correctly stab (debug) info */
1840 static int tcc_load_object_file(TCCState
*s1
,
1841 int fd
, unsigned long file_offset
)
1844 ElfW(Shdr
) *shdr
, *sh
;
1845 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
1846 unsigned char *strsec
, *strtab
;
1847 int *old_to_new_syms
;
1848 char *sh_name
, *name
;
1849 SectionMergeInfo
*sm_table
, *sm
;
1850 ElfW(Sym
) *sym
, *symtab
;
1851 ElfW_Rel
*rel
, *rel_end
;
1857 stab_index
= stabstr_index
= 0;
1859 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
1861 if (ehdr
.e_ident
[0] != ELFMAG0
||
1862 ehdr
.e_ident
[1] != ELFMAG1
||
1863 ehdr
.e_ident
[2] != ELFMAG2
||
1864 ehdr
.e_ident
[3] != ELFMAG3
)
1866 /* test if object file */
1867 if (ehdr
.e_type
!= ET_REL
)
1869 /* test CPU specific stuff */
1870 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
1871 ehdr
.e_machine
!= EM_TCC_TARGET
) {
1873 error_noabort("invalid object file");
1877 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
1878 sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
1879 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
1881 /* load section names */
1882 sh
= &shdr
[ehdr
.e_shstrndx
];
1883 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1885 /* load symtab and strtab */
1886 old_to_new_syms
= NULL
;
1890 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1892 if (sh
->sh_type
== SHT_SYMTAB
) {
1894 error_noabort("object must contain only one symtab");
1899 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
1900 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1901 sm_table
[i
].s
= symtab_section
;
1903 /* now load strtab */
1904 sh
= &shdr
[sh
->sh_link
];
1905 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1909 /* now examine each section and try to merge its content with the
1911 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1912 /* no need to examine section name strtab */
1913 if (i
== ehdr
.e_shstrndx
)
1916 sh_name
= strsec
+ sh
->sh_name
;
1917 /* ignore sections types we do not handle */
1918 if (sh
->sh_type
!= SHT_PROGBITS
&&
1919 sh
->sh_type
!= SHT_RELX
&&
1921 sh
->sh_type
!= SHT_ARM_EXIDX
&&
1923 sh
->sh_type
!= SHT_NOBITS
&&
1924 strcmp(sh_name
, ".stabstr")
1927 if (sh
->sh_addralign
< 1)
1928 sh
->sh_addralign
= 1;
1929 /* find corresponding section, if any */
1930 for(j
= 1; j
< s1
->nb_sections
;j
++) {
1931 s
= s1
->sections
[j
];
1932 if (!strcmp(s
->name
, sh_name
)) {
1933 if (!strncmp(sh_name
, ".gnu.linkonce",
1934 sizeof(".gnu.linkonce") - 1)) {
1935 /* if a 'linkonce' section is already present, we
1936 do not add it again. It is a little tricky as
1937 symbols can still be defined in
1939 sm_table
[i
].link_once
= 1;
1946 /* not found: create new section */
1947 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
1948 /* take as much info as possible from the section. sh_link and
1949 sh_info will be updated later */
1950 s
->sh_addralign
= sh
->sh_addralign
;
1951 s
->sh_entsize
= sh
->sh_entsize
;
1952 sm_table
[i
].new_section
= 1;
1954 if (sh
->sh_type
!= s
->sh_type
) {
1955 error_noabort("invalid section type");
1959 /* align start of section */
1960 offset
= s
->data_offset
;
1962 if (0 == strcmp(sh_name
, ".stab")) {
1966 if (0 == strcmp(sh_name
, ".stabstr")) {
1971 size
= sh
->sh_addralign
- 1;
1972 offset
= (offset
+ size
) & ~size
;
1973 if (sh
->sh_addralign
> s
->sh_addralign
)
1974 s
->sh_addralign
= sh
->sh_addralign
;
1975 s
->data_offset
= offset
;
1977 sm_table
[i
].offset
= offset
;
1979 /* concatenate sections */
1981 if (sh
->sh_type
!= SHT_NOBITS
) {
1983 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
1984 ptr
= section_ptr_add(s
, size
);
1985 read(fd
, ptr
, size
);
1987 s
->data_offset
+= size
;
1992 /* //gr relocate stab strings */
1993 if (stab_index
&& stabstr_index
) {
1996 s
= sm_table
[stab_index
].s
;
1997 a
= (Stab_Sym
*)(s
->data
+ sm_table
[stab_index
].offset
);
1998 b
= (Stab_Sym
*)(s
->data
+ s
->data_offset
);
1999 o
= sm_table
[stabstr_index
].offset
;
2001 a
->n_strx
+= o
, a
++;
2004 /* second short pass to update sh_link and sh_info fields of new
2006 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2008 if (!s
|| !sm_table
[i
].new_section
)
2011 if (sh
->sh_link
> 0)
2012 s
->link
= sm_table
[sh
->sh_link
].s
;
2013 if (sh
->sh_type
== SHT_RELX
) {
2014 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
2015 /* update backward link */
2016 s1
->sections
[s
->sh_info
]->reloc
= s
;
2021 /* resolve symbols */
2022 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
2025 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
2026 if (sym
->st_shndx
!= SHN_UNDEF
&&
2027 sym
->st_shndx
< SHN_LORESERVE
) {
2028 sm
= &sm_table
[sym
->st_shndx
];
2029 if (sm
->link_once
) {
2030 /* if a symbol is in a link once section, we use the
2031 already defined symbol. It is very important to get
2032 correct relocations */
2033 if (ELFW(ST_BIND
)(sym
->st_info
) != STB_LOCAL
) {
2034 name
= strtab
+ sym
->st_name
;
2035 sym_index
= find_elf_sym(symtab_section
, name
);
2037 old_to_new_syms
[i
] = sym_index
;
2041 /* if no corresponding section added, no need to add symbol */
2044 /* convert section number */
2045 sym
->st_shndx
= sm
->s
->sh_num
;
2047 sym
->st_value
+= sm
->offset
;
2050 name
= strtab
+ sym
->st_name
;
2051 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
2052 sym
->st_info
, sym
->st_other
,
2053 sym
->st_shndx
, name
);
2054 old_to_new_syms
[i
] = sym_index
;
2057 /* third pass to patch relocation entries */
2058 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
2063 offset
= sm_table
[i
].offset
;
2064 switch(s
->sh_type
) {
2066 /* take relocation offset information */
2067 offseti
= sm_table
[sh
->sh_info
].offset
;
2068 rel_end
= (ElfW_Rel
*)(s
->data
+ s
->data_offset
);
2069 for(rel
= (ElfW_Rel
*)(s
->data
+ offset
);
2074 /* convert symbol index */
2075 type
= ELFW(R_TYPE
)(rel
->r_info
);
2076 sym_index
= ELFW(R_SYM
)(rel
->r_info
);
2077 /* NOTE: only one symtab assumed */
2078 if (sym_index
>= nb_syms
)
2080 sym_index
= old_to_new_syms
[sym_index
];
2081 /* ignore link_once in rel section. */
2082 if (!sym_index
&& !sm
->link_once
) {
2084 error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
2085 i
, strsec
+ sh
->sh_name
, rel
->r_offset
);
2088 rel
->r_info
= ELFW(R_INFO
)(sym_index
, type
);
2089 /* offset the relocation offset */
2090 rel
->r_offset
+= offseti
;
2102 tcc_free(old_to_new_syms
);
2109 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
2111 typedef struct ArchiveHeader
{
2112 char ar_name
[16]; /* name of this member */
2113 char ar_date
[12]; /* file mtime */
2114 char ar_uid
[6]; /* owner uid; printed as decimal */
2115 char ar_gid
[6]; /* owner gid; printed as decimal */
2116 char ar_mode
[8]; /* file mode, printed as octal */
2117 char ar_size
[10]; /* file size, printed as decimal */
2118 char ar_fmag
[2]; /* should contain ARFMAG */
2121 static int get_be32(const uint8_t *b
)
2123 return b
[3] | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
2126 /* load only the objects which resolve undefined symbols */
2127 static int tcc_load_alacarte(TCCState
*s1
, int fd
, int size
)
2129 int i
, bound
, nsyms
, sym_index
, off
, ret
;
2131 const char *ar_names
, *p
;
2132 const uint8_t *ar_index
;
2135 data
= tcc_malloc(size
);
2136 if (read(fd
, data
, size
) != size
)
2138 nsyms
= get_be32(data
);
2139 ar_index
= data
+ 4;
2140 ar_names
= ar_index
+ nsyms
* 4;
2144 for(p
= ar_names
, i
= 0; i
< nsyms
; i
++, p
+= strlen(p
)+1) {
2145 sym_index
= find_elf_sym(symtab_section
, p
);
2147 sym
= &((ElfW(Sym
) *)symtab_section
->data
)[sym_index
];
2148 if(sym
->st_shndx
== SHN_UNDEF
) {
2149 off
= get_be32(ar_index
+ i
* 4) + sizeof(ArchiveHeader
);
2151 printf("%5d\t%s\t%08x\n", i
, p
, sym
->st_shndx
);
2154 lseek(fd
, off
, SEEK_SET
);
2155 if(tcc_load_object_file(s1
, fd
, off
) < 0) {
2170 /* load a '.a' file */
2171 static int tcc_load_archive(TCCState
*s1
, int fd
)
2178 unsigned long file_offset
;
2180 /* skip magic which was already checked */
2181 read(fd
, magic
, sizeof(magic
));
2184 len
= read(fd
, &hdr
, sizeof(hdr
));
2187 if (len
!= sizeof(hdr
)) {
2188 error_noabort("invalid archive");
2191 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
2192 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
2193 size
= strtol(ar_size
, NULL
, 0);
2194 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
2195 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
2196 if (ar_name
[i
] != ' ')
2199 ar_name
[i
+ 1] = '\0';
2200 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
2201 file_offset
= lseek(fd
, 0, SEEK_CUR
);
2203 size
= (size
+ 1) & ~1;
2204 if (!strcmp(ar_name
, "/")) {
2205 /* coff symbol table : we handle it */
2206 if(s1
->alacarte_link
)
2207 return tcc_load_alacarte(s1
, fd
, size
);
2208 } else if (!strcmp(ar_name
, "//") ||
2209 !strcmp(ar_name
, "__.SYMDEF") ||
2210 !strcmp(ar_name
, "__.SYMDEF/") ||
2211 !strcmp(ar_name
, "ARFILENAMES/")) {
2212 /* skip symbol table or archive names */
2214 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
2217 lseek(fd
, file_offset
+ size
, SEEK_SET
);
2222 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
2223 is referenced by the user (so it should be added as DT_NEEDED in
2224 the generated ELF file) */
2225 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
2228 ElfW(Shdr
) *shdr
, *sh
, *sh1
;
2229 int i
, j
, nb_syms
, nb_dts
, sym_bind
, ret
;
2230 ElfW(Sym
) *sym
, *dynsym
;
2231 ElfW(Dyn
) *dt
, *dynamic
;
2232 unsigned char *dynstr
;
2233 const char *name
, *soname
;
2234 DLLReference
*dllref
;
2236 read(fd
, &ehdr
, sizeof(ehdr
));
2238 /* test CPU specific stuff */
2239 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
2240 ehdr
.e_machine
!= EM_TCC_TARGET
) {
2241 error_noabort("bad architecture");
2246 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(ElfW(Shdr
)) * ehdr
.e_shnum
);
2248 /* load dynamic section and dynamic symbols */
2252 dynsym
= NULL
; /* avoid warning */
2253 dynstr
= NULL
; /* avoid warning */
2254 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
2255 switch(sh
->sh_type
) {
2257 nb_dts
= sh
->sh_size
/ sizeof(ElfW(Dyn
));
2258 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2261 nb_syms
= sh
->sh_size
/ sizeof(ElfW(Sym
));
2262 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
2263 sh1
= &shdr
[sh
->sh_link
];
2264 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
2271 /* compute the real library name */
2272 soname
= tcc_basename(filename
);
2274 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2275 if (dt
->d_tag
== DT_SONAME
) {
2276 soname
= dynstr
+ dt
->d_un
.d_val
;
2280 /* if the dll is already loaded, do not load it */
2281 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
2282 dllref
= s1
->loaded_dlls
[i
];
2283 if (!strcmp(soname
, dllref
->name
)) {
2284 /* but update level if needed */
2285 if (level
< dllref
->level
)
2286 dllref
->level
= level
;
2292 // printf("loading dll '%s'\n", soname);
2294 /* add the dll and its level */
2295 dllref
= tcc_mallocz(sizeof(DLLReference
) + strlen(soname
));
2296 dllref
->level
= level
;
2297 strcpy(dllref
->name
, soname
);
2298 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
2300 /* add dynamic symbols in dynsym_section */
2301 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
2302 sym_bind
= ELFW(ST_BIND
)(sym
->st_info
);
2303 if (sym_bind
== STB_LOCAL
)
2305 name
= dynstr
+ sym
->st_name
;
2306 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
2307 sym
->st_info
, sym
->st_other
, sym
->st_shndx
, name
);
2310 /* load all referenced DLLs */
2311 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
2314 name
= dynstr
+ dt
->d_un
.d_val
;
2315 for(j
= 0; j
< s1
->nb_loaded_dlls
; j
++) {
2316 dllref
= s1
->loaded_dlls
[j
];
2317 if (!strcmp(name
, dllref
->name
))
2318 goto already_loaded
;
2320 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
2321 error_noabort("referenced dll '%s' not found", name
);
2338 #define LD_TOK_NAME 256
2339 #define LD_TOK_EOF (-1)
2341 /* return next ld script token */
2342 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
2360 file
->buf_ptr
= parse_comment(file
->buf_ptr
);
2361 ch
= file
->buf_ptr
[0];
2369 /* case 'a' ... 'z': */
2396 /* case 'A' ... 'z': */
2431 if (!((ch
>= 'a' && ch
<= 'z') ||
2432 (ch
>= 'A' && ch
<= 'Z') ||
2433 (ch
>= '0' && ch
<= '9') ||
2434 strchr("/.-_+=$:\\,~", ch
)))
2436 if ((q
- name
) < name_size
- 1) {
2453 printf("tok=%c %d\n", c
, c
);
2454 if (c
== LD_TOK_NAME
)
2455 printf(" name=%s\n", name
);
2460 static int ld_add_file_list(TCCState
*s1
, int as_needed
)
2462 char filename
[1024];
2465 t
= ld_next(s1
, filename
, sizeof(filename
));
2468 t
= ld_next(s1
, filename
, sizeof(filename
));
2470 if (t
== LD_TOK_EOF
) {
2471 error_noabort("unexpected end of file");
2473 } else if (t
== ')') {
2475 } else if (t
!= LD_TOK_NAME
) {
2476 error_noabort("filename expected");
2479 if (!strcmp(filename
, "AS_NEEDED")) {
2480 ret
= ld_add_file_list(s1
, 1);
2484 /* TODO: Implement AS_NEEDED support. Ignore it for now */
2486 tcc_add_file(s1
, filename
);
2488 t
= ld_next(s1
, filename
, sizeof(filename
));
2490 t
= ld_next(s1
, filename
, sizeof(filename
));
2496 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
2498 static int tcc_load_ldscript(TCCState
*s1
)
2501 char filename
[1024];
2504 ch
= file
->buf_ptr
[0];
2507 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2508 if (t
== LD_TOK_EOF
)
2510 else if (t
!= LD_TOK_NAME
)
2512 if (!strcmp(cmd
, "INPUT") ||
2513 !strcmp(cmd
, "GROUP")) {
2514 ret
= ld_add_file_list(s1
, 0);
2517 } else if (!strcmp(cmd
, "OUTPUT_FORMAT") ||
2518 !strcmp(cmd
, "TARGET")) {
2519 /* ignore some commands */
2520 t
= ld_next(s1
, cmd
, sizeof(cmd
));
2524 t
= ld_next(s1
, filename
, sizeof(filename
));
2525 if (t
== LD_TOK_EOF
) {
2526 error_noabort("unexpected end of file");
2528 } else if (t
== ')') {