2 * ELF file handling for TCC
4 * Copyright (c) 2001, 2002 Fabrice Bellard
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program 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
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 static int put_elf_str(Section
*s
, const char *sym
)
26 len
= strlen(sym
) + 1;
27 offset
= s
->data_offset
;
28 ptr
= section_ptr_add(s
, len
);
29 memcpy(ptr
, sym
, len
);
33 /* elf symbol hashing function */
34 static unsigned long elf_hash(const unsigned char *name
)
36 unsigned long h
= 0, g
;
39 h
= (h
<< 4) + *name
++;
48 /* rebuild hash table of section s */
49 /* NOTE: we do factorize the hash table code to go faster */
50 static void rebuild_hash(Section
*s
, unsigned int nb_buckets
)
53 int *ptr
, *hash
, nb_syms
, sym_index
, h
;
56 strtab
= s
->link
->data
;
57 nb_syms
= s
->data_offset
/ sizeof(Elf32_Sym
);
59 s
->hash
->data_offset
= 0;
60 ptr
= section_ptr_add(s
->hash
, (2 + nb_buckets
+ nb_syms
) * sizeof(int));
65 memset(hash
, 0, (nb_buckets
+ 1) * sizeof(int));
66 ptr
+= nb_buckets
+ 1;
68 sym
= (Elf32_Sym
*)s
->data
+ 1;
69 for(sym_index
= 1; sym_index
< nb_syms
; sym_index
++) {
70 if (ELF32_ST_BIND(sym
->st_info
) != STB_LOCAL
) {
71 h
= elf_hash(strtab
+ sym
->st_name
) % nb_buckets
;
82 /* return the symbol number */
83 static int put_elf_sym(Section
*s
,
84 unsigned long value
, unsigned long size
,
85 int info
, int other
, int shndx
, const char *name
)
87 int name_offset
, sym_index
;
92 sym
= section_ptr_add(s
, sizeof(Elf32_Sym
));
94 name_offset
= put_elf_str(s
->link
, name
);
98 sym
->st_name
= name_offset
;
99 sym
->st_value
= value
;
102 sym
->st_other
= other
;
103 sym
->st_shndx
= shndx
;
104 sym_index
= sym
- (Elf32_Sym
*)s
->data
;
108 ptr
= section_ptr_add(hs
, sizeof(int));
109 base
= (int *)hs
->data
;
110 /* only add global or weak symbols */
111 if (ELF32_ST_BIND(info
) != STB_LOCAL
) {
112 /* add another hashing entry */
114 h
= elf_hash(name
) % nbuckets
;
116 base
[2 + h
] = sym_index
;
118 /* we resize the hash table */
119 hs
->nb_hashed_syms
++;
120 if (hs
->nb_hashed_syms
> 2 * nbuckets
) {
121 rebuild_hash(s
, 2 * nbuckets
);
131 /* find global ELF symbol 'name' and return its index. Return 0 if not
133 static int find_elf_sym(Section
*s
, const char *name
)
137 int nbuckets
, sym_index
, h
;
143 nbuckets
= ((int *)hs
->data
)[0];
144 h
= elf_hash(name
) % nbuckets
;
145 sym_index
= ((int *)hs
->data
)[2 + h
];
146 while (sym_index
!= 0) {
147 sym
= &((Elf32_Sym
*)s
->data
)[sym_index
];
148 name1
= s
->link
->data
+ sym
->st_name
;
149 if (!strcmp(name
, name1
))
151 sym_index
= ((int *)hs
->data
)[2 + nbuckets
+ sym_index
];
156 /* return elf symbol value or error */
157 void *tcc_get_symbol(TCCState
*s
, const char *name
)
162 sym_index
= find_elf_sym(symtab_section
, name
);
164 error("%s not defined", name
);
165 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
166 return (void *)sym
->st_value
;
169 /* add an elf symbol : check if it is already defined and patch
170 it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
171 static int add_elf_sym(Section
*s
, unsigned long value
, unsigned long size
,
172 int info
, int sh_num
, const char *name
)
175 int sym_bind
, sym_index
, sym_type
, esym_bind
;
177 sym_bind
= ELF32_ST_BIND(info
);
178 sym_type
= ELF32_ST_TYPE(info
);
180 if (sym_bind
!= STB_LOCAL
) {
181 /* we search global or weak symbols */
182 sym_index
= find_elf_sym(s
, name
);
185 esym
= &((Elf32_Sym
*)s
->data
)[sym_index
];
186 if (esym
->st_shndx
!= SHN_UNDEF
) {
187 esym_bind
= ELF32_ST_BIND(esym
->st_info
);
188 if (sh_num
== SHN_UNDEF
) {
189 /* ignore adding of undefined symbol if the
190 corresponding symbol is already defined */
191 } else if (sym_bind
== STB_GLOBAL
&& esym_bind
== STB_WEAK
) {
192 /* global overrides weak, so patch */
194 } else if (sym_bind
== STB_WEAK
&& esym_bind
== STB_GLOBAL
) {
195 /* weak is ignored if already global */
198 printf("new_bind=%d new_shndx=%d last_bind=%d old_shndx=%d\n",
199 sym_bind
, sh_num
, esym_bind
, esym
->st_shndx
);
201 /* NOTE: we accept that two DLL define the same symbol */
202 if (s
!= tcc_state
->dynsymtab_section
)
203 error_noabort("'%s' defined twice", name
);
207 esym
->st_info
= ELF32_ST_INFO(sym_bind
, sym_type
);
208 esym
->st_shndx
= sh_num
;
209 esym
->st_value
= value
;
210 esym
->st_size
= size
;
214 sym_index
= put_elf_sym(s
, value
, size
,
215 ELF32_ST_INFO(sym_bind
, sym_type
), 0,
222 static void put_elf_reloc(Section
*symtab
, Section
*s
, unsigned long offset
,
223 int type
, int symbol
)
231 /* if no relocation section, create it */
232 snprintf(buf
, sizeof(buf
), ".rel%s", s
->name
);
233 /* if the symtab is allocated, then we consider the relocation
235 sr
= new_section(tcc_state
, buf
, SHT_REL
, symtab
->sh_flags
);
236 sr
->sh_entsize
= sizeof(Elf32_Rel
);
238 sr
->sh_info
= s
->sh_num
;
241 rel
= section_ptr_add(sr
, sizeof(Elf32_Rel
));
242 rel
->r_offset
= offset
;
243 rel
->r_info
= ELF32_R_INFO(symbol
, type
);
246 /* put stab debug information */
249 unsigned long n_strx
; /* index into string table of name */
250 unsigned char n_type
; /* type of symbol */
251 unsigned char n_other
; /* misc info (usually empty) */
252 unsigned short n_desc
; /* description field */
253 unsigned long n_value
; /* value of symbol */
256 static void put_stabs(const char *str
, int type
, int other
, int desc
,
261 sym
= section_ptr_add(stab_section
, sizeof(Stab_Sym
));
263 sym
->n_strx
= put_elf_str(stabstr_section
, str
);
268 sym
->n_other
= other
;
270 sym
->n_value
= value
;
273 static void put_stabs_r(const char *str
, int type
, int other
, int desc
,
274 unsigned long value
, Section
*sec
, int sym_index
)
276 put_stabs(str
, type
, other
, desc
, value
);
277 put_elf_reloc(symtab_section
, stab_section
,
278 stab_section
->data_offset
- sizeof(unsigned long),
279 R_DATA_32
, sym_index
);
282 static void put_stabn(int type
, int other
, int desc
, int value
)
284 put_stabs(NULL
, type
, other
, desc
, value
);
287 static void put_stabd(int type
, int other
, int desc
)
289 put_stabs(NULL
, type
, other
, desc
, 0);
292 /* In an ELF file symbol table, the local symbols must appear below
293 the global and weak ones. Since TCC cannot sort it while generating
294 the code, we must do it after. All the relocation tables are also
295 modified to take into account the symbol table sorting */
296 static void sort_syms(TCCState
*s1
, Section
*s
)
298 int *old_to_new_syms
;
302 Elf32_Rel
*rel
, *rel_end
;
306 nb_syms
= s
->data_offset
/ sizeof(Elf32_Sym
);
307 new_syms
= tcc_malloc(nb_syms
* sizeof(Elf32_Sym
));
308 old_to_new_syms
= tcc_malloc(nb_syms
* sizeof(int));
310 /* first pass for local symbols */
311 p
= (Elf32_Sym
*)s
->data
;
313 for(i
= 0; i
< nb_syms
; i
++) {
314 if (ELF32_ST_BIND(p
->st_info
) == STB_LOCAL
) {
315 old_to_new_syms
[i
] = q
- new_syms
;
320 /* save the number of local symbols in section header */
321 s
->sh_info
= q
- new_syms
;
323 /* then second pass for non local symbols */
324 p
= (Elf32_Sym
*)s
->data
;
325 for(i
= 0; i
< nb_syms
; i
++) {
326 if (ELF32_ST_BIND(p
->st_info
) != STB_LOCAL
) {
327 old_to_new_syms
[i
] = q
- new_syms
;
333 /* we copy the new symbols to the old */
334 memcpy(s
->data
, new_syms
, nb_syms
* sizeof(Elf32_Sym
));
337 /* now we modify all the relocations */
338 for(i
= 1; i
< s1
->nb_sections
; i
++) {
339 sr
= s1
->sections
[i
];
340 if (sr
->sh_type
== SHT_REL
&& sr
->link
== s
) {
341 rel_end
= (Elf32_Rel
*)(sr
->data
+ sr
->data_offset
);
342 for(rel
= (Elf32_Rel
*)sr
->data
;
345 sym_index
= ELF32_R_SYM(rel
->r_info
);
346 type
= ELF32_R_TYPE(rel
->r_info
);
347 sym_index
= old_to_new_syms
[sym_index
];
348 rel
->r_info
= ELF32_R_INFO(sym_index
, type
);
353 tcc_free(old_to_new_syms
);
356 /* relocate common symbols in the .bss section */
357 static void relocate_common_syms(void)
359 Elf32_Sym
*sym
, *sym_end
;
360 unsigned long offset
, align
;
362 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
363 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
366 if (sym
->st_shndx
== SHN_COMMON
) {
368 align
= sym
->st_value
;
369 offset
= bss_section
->data_offset
;
370 offset
= (offset
+ align
- 1) & -align
;
371 sym
->st_value
= offset
;
372 sym
->st_shndx
= bss_section
->sh_num
;
373 offset
+= sym
->st_size
;
374 bss_section
->data_offset
= offset
;
379 static void *resolve_sym(const char *sym
)
381 return dlsym(NULL
, sym
);
384 /* relocate symbol table, resolve undefined symbols if do_resolve is
385 true and output error if undefined symbol. */
386 static void relocate_syms(TCCState
*s1
, int do_resolve
)
388 Elf32_Sym
*sym
, *esym
, *sym_end
;
389 int sym_bind
, sh_num
, sym_index
;
393 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+ symtab_section
->data_offset
);
394 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
397 sh_num
= sym
->st_shndx
;
398 if (sh_num
== SHN_UNDEF
) {
399 name
= strtab_section
->data
+ sym
->st_name
;
401 name
= symtab_section
->link
->data
+ sym
->st_name
;
402 addr
= (unsigned long)resolve_sym(name
);
404 sym
->st_value
= addr
;
407 } else if (s1
->dynsym
) {
408 /* if dynamic symbol exist, then use it */
409 sym_index
= find_elf_sym(s1
->dynsym
, name
);
411 esym
= &((Elf32_Sym
*)s1
->dynsym
->data
)[sym_index
];
412 sym
->st_value
= esym
->st_value
;
416 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
418 if (!strcmp(name
, "_fp_hw"))
420 /* only weak symbols are accepted to be undefined. Their
422 sym_bind
= ELF32_ST_BIND(sym
->st_info
);
423 if (sym_bind
== STB_WEAK
) {
426 error_noabort("undefined symbol '%s'", name
);
428 } else if (sh_num
< SHN_LORESERVE
) {
429 /* add section base */
430 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
436 /* relocate a given section (CPU dependant) */
437 static void relocate_section(TCCState
*s1
, Section
*s
)
440 Elf32_Rel
*rel
, *rel_end
, *qrel
;
442 int type
, sym_index
, esym_index
;
444 unsigned long val
, addr
;
447 rel_end
= (Elf32_Rel
*)(sr
->data
+ sr
->data_offset
);
448 qrel
= (Elf32_Rel
*)sr
->data
;
452 ptr
= s
->data
+ rel
->r_offset
;
454 sym_index
= ELF32_R_SYM(rel
->r_info
);
455 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
457 type
= ELF32_R_TYPE(rel
->r_info
);
458 addr
= s
->sh_addr
+ rel
->r_offset
;
463 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
464 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
465 qrel
->r_offset
= rel
->r_offset
;
467 qrel
->r_info
= ELF32_R_INFO(esym_index
, R_386_32
);
471 qrel
->r_info
= ELF32_R_INFO(0, R_386_RELATIVE
);
478 if (s1
->output_type
== TCC_OUTPUT_DLL
) {
480 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
482 qrel
->r_offset
= rel
->r_offset
;
483 qrel
->r_info
= ELF32_R_INFO(esym_index
, R_386_PC32
);
488 *(int *)ptr
+= val
- addr
;
491 *(int *)ptr
+= val
- addr
;
498 *(int *)ptr
+= s1
->got
->sh_addr
- addr
;
501 *(int *)ptr
+= val
- s1
->got
->sh_addr
;
504 /* we load the got offset */
505 *(int *)ptr
+= s1
->got_offsets
[sym_index
];
509 /* if the relocation is allocated, we change its symbol table */
510 if (sr
->sh_flags
& SHF_ALLOC
)
511 sr
->link
= s1
->dynsym
;
514 /* relocate relocation table in 'sr' */
515 static void relocate_rel(TCCState
*s1
, Section
*sr
)
518 Elf32_Rel
*rel
, *rel_end
;
520 s
= s1
->sections
[sr
->sh_info
];
521 rel_end
= (Elf32_Rel
*)(sr
->data
+ sr
->data_offset
);
522 for(rel
= (Elf32_Rel
*)sr
->data
;
525 rel
->r_offset
+= s
->sh_addr
;
529 /* count the number of dynamic relocations so that we can reserve
531 static int prepare_dynamic_rel(TCCState
*s1
, Section
*sr
)
533 Elf32_Rel
*rel
, *rel_end
;
534 int sym_index
, esym_index
, type
, count
;
537 rel_end
= (Elf32_Rel
*)(sr
->data
+ sr
->data_offset
);
538 for(rel
= (Elf32_Rel
*)sr
->data
; rel
< rel_end
; rel
++) {
539 sym_index
= ELF32_R_SYM(rel
->r_info
);
540 type
= ELF32_R_TYPE(rel
->r_info
);
546 esym_index
= s1
->symtab_to_dynsym
[sym_index
];
555 /* allocate the section */
556 sr
->sh_flags
|= SHF_ALLOC
;
557 sr
->sh_size
= count
* sizeof(Elf32_Rel
);
562 static void put_got_offset(TCCState
*s1
, int index
, unsigned long val
)
567 if (index
>= s1
->nb_got_offsets
) {
568 /* find immediately bigger power of 2 and reallocate array */
572 tab
= tcc_realloc(s1
->got_offsets
, n
* sizeof(unsigned long));
574 error("memory full");
575 s1
->got_offsets
= tab
;
576 memset(s1
->got_offsets
+ s1
->nb_got_offsets
, 0,
577 (n
- s1
->nb_got_offsets
) * sizeof(unsigned long));
578 s1
->nb_got_offsets
= n
;
580 s1
->got_offsets
[index
] = val
;
583 /* XXX: suppress that */
584 static void put32(unsigned char *p
, unsigned int val
)
592 static void build_got(TCCState
*s1
)
596 /* if no got, then create it */
597 s1
->got
= new_section(s1
, ".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
598 s1
->got
->sh_entsize
= 4;
599 add_elf_sym(symtab_section
, 0, 4, ELF32_ST_INFO(STB_GLOBAL
, STT_OBJECT
),
600 s1
->got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
601 ptr
= section_ptr_add(s1
->got
, 3 * sizeof(int));
602 /* keep space for _DYNAMIC pointer, if present */
604 /* two dummy got entries */
609 /* put a got entry corresponding to a symbol in symtab_section. 'size'
610 and 'info' can be modifed if more precise info comes from the DLL */
611 static void put_got_entry(TCCState
*s1
,
612 int reloc_type
, unsigned long size
, int info
,
618 unsigned long offset
;
624 /* if a got entry already exists for that symbol, no need to add one */
625 if (sym_index
< s1
->nb_got_offsets
&&
626 s1
->got_offsets
[sym_index
] != 0)
629 put_got_offset(s1
, sym_index
, s1
->got
->data_offset
);
632 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
633 name
= symtab_section
->link
->data
+ sym
->st_name
;
634 offset
= sym
->st_value
;
635 /* NOTE: we put temporarily the got offset */
636 if (reloc_type
== R_386_JMP_SLOT
) {
637 s1
->nb_plt_entries
++;
638 offset
= s1
->got
->data_offset
;
640 index
= put_elf_sym(s1
->dynsym
, offset
,
641 size
, info
, 0, sym
->st_shndx
, name
);
642 /* put a got entry */
643 put_elf_reloc(s1
->dynsym
, s1
->got
,
644 s1
->got
->data_offset
,
647 ptr
= section_ptr_add(s1
->got
, sizeof(int));
651 /* build GOT and PLT entries */
652 static void build_got_entries(TCCState
*s1
)
655 Elf32_Rel
*rel
, *rel_end
;
657 int i
, type
, reloc_type
, sym_index
;
659 for(i
= 1; i
< s1
->nb_sections
; i
++) {
661 if (s
->sh_type
!= SHT_REL
)
663 /* no need to handle got relocations */
664 if (s
->link
!= symtab_section
)
667 rel_end
= (Elf32_Rel
*)(s
->data
+ s
->data_offset
);
668 for(rel
= (Elf32_Rel
*)s
->data
;
671 type
= ELF32_R_TYPE(rel
->r_info
);
679 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
680 sym_index
= ELF32_R_SYM(rel
->r_info
);
681 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
682 /* look at the symbol got offset. If none, then add one */
683 if (type
== R_386_GOT32
)
684 reloc_type
= R_386_GLOB_DAT
;
686 reloc_type
= R_386_JMP_SLOT
;
687 put_got_entry(s1
, reloc_type
, sym
->st_size
, sym
->st_info
,
698 static Section
*new_symtab(TCCState
*s1
,
699 const char *symtab_name
, int sh_type
, int sh_flags
,
700 const char *strtab_name
,
701 const char *hash_name
, int hash_sh_flags
)
703 Section
*symtab
, *strtab
, *hash
;
704 int *ptr
, nb_buckets
;
706 symtab
= new_section(s1
, symtab_name
, sh_type
, sh_flags
);
707 symtab
->sh_entsize
= sizeof(Elf32_Sym
);
708 strtab
= new_section(s1
, strtab_name
, SHT_STRTAB
, sh_flags
);
709 put_elf_str(strtab
, "");
710 symtab
->link
= strtab
;
711 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
715 hash
= new_section(s1
, hash_name
, SHT_HASH
, hash_sh_flags
);
716 hash
->sh_entsize
= sizeof(int);
720 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
723 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
727 /* put dynamic tag */
728 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
731 dyn
= section_ptr_add(dynamic
, sizeof(Elf32_Dyn
));
733 dyn
->d_un
.d_val
= val
;
736 /* add tcc runtime libraries */
737 static void tcc_add_runtime(TCCState
*s1
)
743 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "libtcc1.o");
744 tcc_add_file(s1
, buf
);
745 #ifdef CONFIG_TCC_BCHECK
746 if (do_bounds_check
) {
748 Section
*init_section
;
749 unsigned char *pinit
;
752 /* XXX: add an object file to do that */
753 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
755 add_elf_sym(symtab_section
, 0, 0,
756 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
757 bounds_section
->sh_num
, "__bounds_start");
758 /* add bound check code */
759 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "bcheck.o");
760 tcc_add_file(s1
, buf
);
761 #ifdef TCC_TARGET_I386
762 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
763 /* add 'call __bound_init()' in .init section */
764 init_section
= find_section(s1
, ".init");
765 pinit
= section_ptr_add(init_section
, 5);
767 put32(pinit
+ 1, -4);
768 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
769 put_elf_reloc(symtab_section
, init_section
,
770 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
775 /* add libc if not memory output */
776 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
777 tcc_add_library(s1
, "c");
778 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
780 /* add various standard linker symbols */
781 add_elf_sym(symtab_section
,
782 text_section
->data_offset
, 0,
783 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
784 text_section
->sh_num
, "_etext");
785 add_elf_sym(symtab_section
,
786 data_section
->data_offset
, 0,
787 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
788 data_section
->sh_num
, "_edata");
789 add_elf_sym(symtab_section
,
790 bss_section
->data_offset
, 0,
791 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
792 bss_section
->sh_num
, "_end");
793 /* add start and stop symbols for sections whose name can be
795 for(i
= 1; i
< s1
->nb_sections
; i
++) {
797 if (s
->sh_type
== SHT_PROGBITS
&&
798 (s
->sh_flags
& SHF_ALLOC
)) {
802 /* check if section name can be expressed in C */
808 if (!isid(ch
) && !isnum(ch
))
812 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
813 add_elf_sym(symtab_section
,
815 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
817 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
818 add_elf_sym(symtab_section
,
820 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
827 /* name of ELF interpreter */
828 static char elf_interp
[] = "/lib/ld-linux.so.2";
830 #define ELF_START_ADDR 0x08048000
831 #define ELF_PAGE_SIZE 0x1000
833 /* output an ELF file */
834 /* XXX: suppress unneeded sections */
835 int tcc_output_file(TCCState
*s1
, const char *filename
)
841 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
844 Elf32_Shdr shdr
, *sh
;
845 Elf32_Phdr
*phdr
, *ph
;
846 Section
*interp
, *plt
, *dynamic
, *dynstr
;
847 unsigned long saved_dynamic_data_offset
;
850 unsigned long rel_addr
, rel_size
;
852 file_type
= s1
->output_type
;
855 if (file_type
!= TCC_OUTPUT_OBJ
)
859 section_order
= NULL
;
862 plt
= NULL
; /* avoid warning */
863 dynstr
= NULL
; /* avoid warning */
864 saved_dynamic_data_offset
= 0; /* avoid warning */
866 if (file_type
!= TCC_OUTPUT_OBJ
) {
868 relocate_common_syms();
870 if (!s1
->static_link
) {
872 int sym_index
, index
;
873 Elf32_Sym
*esym
, *sym_end
;
875 if (file_type
== TCC_OUTPUT_EXE
) {
877 /* add interpreter section only if executable */
878 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
879 interp
->sh_addralign
= 1;
880 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
881 strcpy(ptr
, elf_interp
);
884 /* add dynamic symbol table */
885 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
888 dynstr
= s1
->dynsym
->link
;
890 /* add dynamic section */
891 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
892 SHF_ALLOC
| SHF_WRITE
);
893 dynamic
->link
= dynstr
;
894 dynamic
->sh_entsize
= sizeof(Elf32_Dyn
);
897 plt
= new_section(s1
, ".plt", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
902 /* scan for undefined symbols and see if they are in the
903 dynamic symbols. If a symbol STT_FUNC is found, then we
904 add it in the PLT. If a symbol STT_OBJECT is found, we
905 add it in the .bss section with a suitable relocation */
906 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+
907 symtab_section
->data_offset
);
908 if (file_type
== TCC_OUTPUT_EXE
) {
909 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
912 if (sym
->st_shndx
== SHN_UNDEF
) {
913 name
= symtab_section
->link
->data
+ sym
->st_name
;
914 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
916 esym
= &((Elf32_Sym
*)s1
->dynsymtab_section
->data
)[sym_index
];
917 type
= ELF32_ST_TYPE(esym
->st_info
);
918 if (type
== STT_FUNC
) {
919 put_got_entry(s1
, R_386_JMP_SLOT
, esym
->st_size
,
921 sym
- (Elf32_Sym
*)symtab_section
->data
);
922 } else if (type
== STT_OBJECT
) {
923 unsigned long offset
;
924 offset
= bss_section
->data_offset
;
925 /* XXX: which alignment ? */
926 offset
= (offset
+ 8 - 1) & -8;
927 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
929 bss_section
->sh_num
, name
);
930 put_elf_reloc(s1
->dynsym
, bss_section
,
931 offset
, R_386_COPY
, index
);
932 offset
+= esym
->st_size
;
933 bss_section
->data_offset
= offset
;
936 /* STB_WEAK undefined symbols are accepted */
937 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
939 if (ELF32_ST_BIND(sym
->st_info
) == STB_WEAK
||
940 !strcmp(name
, "_fp_hw")) {
942 error_noabort("undefined symbol '%s'", name
);
951 /* now look at unresolved dynamic symbols and export
952 corresponding symbol */
953 sym_end
= (Elf32_Sym
*)(s1
->dynsymtab_section
->data
+
954 s1
->dynsymtab_section
->data_offset
);
955 for(esym
= (Elf32_Sym
*)s1
->dynsymtab_section
->data
+ 1;
958 if (esym
->st_shndx
== SHN_UNDEF
) {
959 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
960 sym_index
= find_elf_sym(symtab_section
, name
);
962 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
963 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
965 sym
->st_shndx
, name
);
967 if (ELF32_ST_BIND(esym
->st_info
) == STB_WEAK
) {
968 /* weak symbols can stay undefined */
970 warning("undefined dynamic symbol '%s'", name
);
977 /* shared library case : we simply export all the global symbols */
978 nb_syms
= symtab_section
->data_offset
/ sizeof(Elf32_Sym
);
979 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
980 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
983 if (ELF32_ST_BIND(sym
->st_info
) != STB_LOCAL
) {
984 name
= symtab_section
->link
->data
+ sym
->st_name
;
985 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
987 sym
->st_shndx
, name
);
988 s1
->symtab_to_dynsym
[sym
-
989 (Elf32_Sym
*)symtab_section
->data
] =
995 build_got_entries(s1
);
997 /* update PLT/GOT sizes so that we can allocate their space */
998 plt
->data_offset
+= 16 * (s1
->nb_plt_entries
+ 1);
1000 /* add a list of needed dlls */
1001 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1002 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1003 if (dllref
->level
== 0)
1004 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1006 /* XXX: currently, since we do not handle PIC code, we
1007 must relocate the readonly segments */
1008 if (file_type
== TCC_OUTPUT_DLL
)
1009 put_dt(dynamic
, DT_TEXTREL
, 0);
1011 /* add necessary space for other entries */
1012 saved_dynamic_data_offset
= dynamic
->data_offset
;
1013 dynamic
->data_offset
+= 8 * 9;
1015 /* still need to build got entries in case of static link */
1016 build_got_entries(s1
);
1020 memset(&ehdr
, 0, sizeof(ehdr
));
1022 /* we add a section for symbols */
1023 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1024 put_elf_str(strsec
, "");
1026 /* compute number of sections */
1027 shnum
= s1
->nb_sections
;
1029 /* this array is used to reorder sections in the output file */
1030 section_order
= tcc_malloc(sizeof(int) * shnum
);
1031 section_order
[0] = 0;
1034 /* compute number of program headers */
1037 case TCC_OUTPUT_OBJ
:
1040 case TCC_OUTPUT_EXE
:
1041 if (!s1
->static_link
)
1046 case TCC_OUTPUT_DLL
:
1051 /* allocate strings for section names and decide if an unallocated
1052 section should be output */
1053 /* NOTE: the strsec section comes last, so its size is also
1055 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1056 s
= s1
->sections
[i
];
1057 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1058 /* when generating a DLL, we include relocations but we may
1060 if (file_type
== TCC_OUTPUT_DLL
&&
1061 s
->sh_type
== SHT_REL
&&
1062 !(s
->sh_flags
& SHF_ALLOC
)) {
1063 prepare_dynamic_rel(s1
, s
);
1064 } else if (do_debug
||
1065 file_type
== TCC_OUTPUT_OBJ
||
1066 (s
->sh_flags
& SHF_ALLOC
) ||
1067 i
== (s1
->nb_sections
- 1)) {
1068 /* we output all sections if debug or object file */
1069 s
->sh_size
= s
->data_offset
;
1073 /* allocate program segment headers */
1074 phdr
= tcc_mallocz(phnum
* sizeof(Elf32_Phdr
));
1076 file_offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
1078 /* compute section to program header mapping */
1079 if (file_type
== TCC_OUTPUT_DLL
)
1082 addr
= ELF_START_ADDR
;
1084 /* dynamic relocation table information, for .dynamic section */
1088 /* compute address after headers */
1089 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1091 /* leave one program header for the program interpreter */
1096 for(j
= 0; j
< 2; j
++) {
1097 ph
->p_type
= PT_LOAD
;
1099 ph
->p_flags
= PF_R
| PF_X
;
1101 ph
->p_flags
= PF_R
| PF_W
;
1102 ph
->p_align
= ELF_PAGE_SIZE
;
1104 /* we do the following ordering: interp, symbol tables,
1105 relocations, progbits, nobits */
1106 /* XXX: do faster and simpler sorting */
1107 for(k
= 0; k
< 5; k
++) {
1108 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1109 s
= s1
->sections
[i
];
1110 /* compute if section should be included */
1112 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1116 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1117 (SHF_ALLOC
| SHF_WRITE
))
1123 } else if (s
->sh_type
== SHT_DYNSYM
||
1124 s
->sh_type
== SHT_STRTAB
||
1125 s
->sh_type
== SHT_HASH
) {
1128 } else if (s
->sh_type
== SHT_REL
) {
1131 } else if (s
->sh_type
== SHT_NOBITS
) {
1138 section_order
[sh_order_index
++] = i
;
1140 /* section matches: we align it and add its size */
1142 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1143 ~(s
->sh_addralign
- 1);
1144 s
->sh_offset
= file_offset
;
1145 addr
+= file_offset
- tmp
;
1148 /* update program header infos */
1149 if (ph
->p_offset
== 0) {
1150 ph
->p_offset
= file_offset
;
1152 ph
->p_paddr
= ph
->p_vaddr
;
1154 /* update dynamic relocation infos */
1155 if (s
->sh_type
== SHT_REL
) {
1158 rel_size
+= s
->sh_size
;
1161 if (s
->sh_type
!= SHT_NOBITS
)
1162 file_offset
+= s
->sh_size
;
1165 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1166 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1170 /* if interpreter, then add corresponing program header */
1174 ph
->p_type
= PT_INTERP
;
1175 ph
->p_offset
= interp
->sh_offset
;
1176 ph
->p_vaddr
= interp
->sh_addr
;
1177 ph
->p_paddr
= ph
->p_vaddr
;
1178 ph
->p_filesz
= interp
->sh_size
;
1179 ph
->p_memsz
= interp
->sh_size
;
1181 ph
->p_align
= interp
->sh_addralign
;
1184 /* if dynamic section, then add corresponing program header */
1190 ph
= &phdr
[phnum
- 1];
1192 ph
->p_type
= PT_DYNAMIC
;
1193 ph
->p_offset
= dynamic
->sh_offset
;
1194 ph
->p_vaddr
= dynamic
->sh_addr
;
1195 ph
->p_paddr
= ph
->p_vaddr
;
1196 ph
->p_filesz
= dynamic
->sh_size
;
1197 ph
->p_memsz
= dynamic
->sh_size
;
1198 ph
->p_flags
= PF_R
| PF_W
;
1199 ph
->p_align
= dynamic
->sh_addralign
;
1201 /* put GOT dynamic section address */
1202 put32(s1
->got
->data
, dynamic
->sh_addr
);
1204 /* compute the PLT */
1205 plt
->data_offset
= 0;
1207 /* first plt entry */
1208 p
= section_ptr_add(plt
, 16);
1209 p
[0] = 0xff; /* pushl got + 4 */
1211 put32(p
+ 2, s1
->got
->sh_addr
+ 4);
1212 p
[6] = 0xff; /* jmp *(got + 8) */
1214 put32(p
+ 8, s1
->got
->sh_addr
+ 8);
1216 /* relocation symbols in .dynsym and build PLT. */
1218 sym_end
= (Elf32_Sym
*)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1219 for(sym
= (Elf32_Sym
*)s1
->dynsym
->data
+ 1;
1222 type
= ELF32_ST_TYPE(sym
->st_info
);
1223 if (sym
->st_shndx
== SHN_UNDEF
) {
1224 if (type
== STT_FUNC
) {
1225 /* one more entry in PLT */
1226 p
= section_ptr_add(plt
, 16);
1227 p
[0] = 0xff; /* jmp *(got + x) */
1229 put32(p
+ 2, s1
->got
->sh_addr
+ sym
->st_value
);
1230 p
[6] = 0x68; /* push $xxx */
1231 put32(p
+ 7, plt_offset
);
1232 p
[11] = 0xe9; /* jmp plt_start */
1233 put32(p
+ 12, -(plt
->data_offset
));
1235 /* patch symbol value to point to plt */
1236 sym
->st_value
= plt
->sh_addr
+ p
- plt
->data
;
1240 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1241 /* do symbol relocation */
1242 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1245 /* put dynamic section entries */
1247 dynamic
->data_offset
= saved_dynamic_data_offset
;
1248 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1249 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1250 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1251 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1252 put_dt(dynamic
, DT_SYMENT
, sizeof(Elf32_Sym
));
1253 put_dt(dynamic
, DT_REL
, rel_addr
);
1254 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1255 put_dt(dynamic
, DT_RELENT
, sizeof(Elf32_Rel
));
1256 put_dt(dynamic
, DT_NULL
, 0);
1259 ehdr
.e_phentsize
= sizeof(Elf32_Phdr
);
1260 ehdr
.e_phnum
= phnum
;
1261 ehdr
.e_phoff
= sizeof(Elf32_Ehdr
);
1264 /* all other sections come after */
1265 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1266 s
= s1
->sections
[i
];
1267 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1269 section_order
[sh_order_index
++] = i
;
1271 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1272 ~(s
->sh_addralign
- 1);
1273 s
->sh_offset
= file_offset
;
1274 if (s
->sh_type
!= SHT_NOBITS
)
1275 file_offset
+= s
->sh_size
;
1278 /* if building executable or DLL, then relocate each section
1279 except the GOT which is already relocated */
1280 if (file_type
!= TCC_OUTPUT_OBJ
) {
1281 relocate_syms(s1
, 0);
1283 if (s1
->nb_errors
!= 0) {
1289 /* relocate sections */
1290 /* XXX: ignore sections with allocated relocations ? */
1291 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1292 s
= s1
->sections
[i
];
1293 if (s
->reloc
&& s
!= s1
->got
)
1294 relocate_section(s1
, s
);
1297 /* relocate relocation entries if the relocation tables are
1298 allocated in the executable */
1299 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1300 s
= s1
->sections
[i
];
1301 if ((s
->sh_flags
& SHF_ALLOC
) &&
1302 s
->sh_type
== SHT_REL
) {
1303 relocate_rel(s1
, s
);
1307 /* get entry point address */
1308 if (file_type
== TCC_OUTPUT_EXE
)
1309 ehdr
.e_entry
= (unsigned long)tcc_get_symbol(s1
, "_start");
1311 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1314 sort_syms(s1
, symtab_section
);
1317 file_offset
= (file_offset
+ 3) & -4;
1320 ehdr
.e_ident
[0] = ELFMAG0
;
1321 ehdr
.e_ident
[1] = ELFMAG1
;
1322 ehdr
.e_ident
[2] = ELFMAG2
;
1323 ehdr
.e_ident
[3] = ELFMAG3
;
1324 ehdr
.e_ident
[4] = ELFCLASS32
;
1325 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1326 ehdr
.e_ident
[6] = EV_CURRENT
;
1329 case TCC_OUTPUT_EXE
:
1330 ehdr
.e_type
= ET_EXEC
;
1332 case TCC_OUTPUT_DLL
:
1333 ehdr
.e_type
= ET_DYN
;
1335 case TCC_OUTPUT_OBJ
:
1336 ehdr
.e_type
= ET_REL
;
1339 ehdr
.e_machine
= EM_386
;
1340 ehdr
.e_version
= EV_CURRENT
;
1341 ehdr
.e_shoff
= file_offset
;
1342 ehdr
.e_ehsize
= sizeof(Elf32_Ehdr
);
1343 ehdr
.e_shentsize
= sizeof(Elf32_Shdr
);
1344 ehdr
.e_shnum
= shnum
;
1345 ehdr
.e_shstrndx
= shnum
- 1;
1347 /* write elf file */
1348 if (file_type
== TCC_OUTPUT_OBJ
)
1352 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
, mode
);
1354 error_noabort("could not write '%s'", filename
);
1357 f
= fdopen(fd
, "w");
1358 fwrite(&ehdr
, 1, sizeof(Elf32_Ehdr
), f
);
1359 fwrite(phdr
, 1, phnum
* sizeof(Elf32_Phdr
), f
);
1360 offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
1361 for(i
=1;i
<s1
->nb_sections
;i
++) {
1362 s
= s1
->sections
[section_order
[i
]];
1363 if (s
->sh_type
!= SHT_NOBITS
) {
1364 while (offset
< s
->sh_offset
) {
1369 fwrite(s
->data
, 1, size
, f
);
1373 while (offset
< ehdr
.e_shoff
) {
1378 /* output section headers */
1379 for(i
=0;i
<s1
->nb_sections
;i
++) {
1381 memset(sh
, 0, sizeof(Elf32_Shdr
));
1382 s
= s1
->sections
[i
];
1384 sh
->sh_name
= s
->sh_name
;
1385 sh
->sh_type
= s
->sh_type
;
1386 sh
->sh_flags
= s
->sh_flags
;
1387 sh
->sh_entsize
= s
->sh_entsize
;
1388 sh
->sh_info
= s
->sh_info
;
1390 sh
->sh_link
= s
->link
->sh_num
;
1391 sh
->sh_addralign
= s
->sh_addralign
;
1392 sh
->sh_addr
= s
->sh_addr
;
1393 sh
->sh_offset
= s
->sh_offset
;
1394 sh
->sh_size
= s
->sh_size
;
1396 fwrite(sh
, 1, sizeof(Elf32_Shdr
), f
);
1402 tcc_free(s1
->symtab_to_dynsym
);
1403 tcc_free(section_order
);
1405 tcc_free(s1
->got_offsets
);
1409 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
1413 data
= tcc_malloc(size
);
1414 lseek(fd
, file_offset
, SEEK_SET
);
1415 read(fd
, data
, size
);
1419 typedef struct SectionMergeInfo
{
1420 Section
*s
; /* corresponding existing section */
1421 unsigned long offset
; /* offset of the new section in the existing section */
1422 int new_section
; /* true if section 's' was added */
1425 /* load an object file and merge it with current files */
1426 /* XXX: handle correctly stab (debug) info */
1427 static int tcc_load_object_file(TCCState
*s1
,
1428 int fd
, unsigned long file_offset
)
1431 Elf32_Shdr
*shdr
, *sh
;
1432 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
1433 unsigned char *strsec
, *strtab
;
1434 int *old_to_new_syms
;
1435 char *sh_name
, *name
;
1436 SectionMergeInfo
*sm_table
, *sm
;
1437 Elf32_Sym
*sym
, *symtab
;
1438 Elf32_Rel
*rel
, *rel_end
;
1441 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
1443 if (ehdr
.e_ident
[0] != ELFMAG0
||
1444 ehdr
.e_ident
[1] != ELFMAG1
||
1445 ehdr
.e_ident
[2] != ELFMAG2
||
1446 ehdr
.e_ident
[3] != ELFMAG3
)
1448 /* test if object file */
1449 if (ehdr
.e_type
!= ET_REL
)
1451 /* test CPU specific stuff */
1452 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
1453 ehdr
.e_machine
!= EM_386
) {
1455 error_noabort("invalid object file");
1459 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
1460 sizeof(Elf32_Shdr
) * ehdr
.e_shnum
);
1461 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
1463 /* load section names */
1464 sh
= &shdr
[ehdr
.e_shstrndx
];
1465 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1467 /* load symtab and strtab */
1468 old_to_new_syms
= NULL
;
1472 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1474 if (sh
->sh_type
== SHT_SYMTAB
) {
1476 error_noabort("object must contain only one symtab");
1481 nb_syms
= sh
->sh_size
/ sizeof(Elf32_Sym
);
1482 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1483 sm_table
[i
].s
= symtab_section
;
1485 /* now load strtab */
1486 sh
= &shdr
[sh
->sh_link
];
1487 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1491 /* now examine each section and try to merge its content with the
1493 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1494 /* no need to examine section name strtab */
1495 if (i
== ehdr
.e_shstrndx
)
1498 sh_name
= strsec
+ sh
->sh_name
;
1499 /* ignore sections types we do not handle */
1500 if (sh
->sh_type
!= SHT_PROGBITS
&&
1501 sh
->sh_type
!= SHT_REL
&&
1502 sh
->sh_type
!= SHT_NOBITS
)
1504 if (sh
->sh_addralign
< 1)
1505 sh
->sh_addralign
= 1;
1506 /* find corresponding section, if any */
1507 for(j
= 1; j
< s1
->nb_sections
;j
++) {
1508 s
= s1
->sections
[j
];
1509 if (!strcmp(s
->name
, sh_name
))
1512 /* not found: create new section */
1513 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
1514 /* take as much info as possible from the section. sh_link and
1515 sh_info will be updated later */
1516 s
->sh_addralign
= sh
->sh_addralign
;
1517 s
->sh_entsize
= sh
->sh_entsize
;
1518 sm_table
[i
].new_section
= 1;
1520 if (sh
->sh_type
!= s
->sh_type
) {
1521 error_noabort("invalid section type");
1525 /* align start of section */
1526 offset
= s
->data_offset
;
1527 size
= sh
->sh_addralign
- 1;
1528 offset
= (offset
+ size
) & ~size
;
1529 if (sh
->sh_addralign
> s
->sh_addralign
)
1530 s
->sh_addralign
= sh
->sh_addralign
;
1531 s
->data_offset
= offset
;
1532 sm_table
[i
].offset
= offset
;
1534 /* concatenate sections */
1536 if (sh
->sh_type
!= SHT_NOBITS
) {
1538 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
1539 ptr
= section_ptr_add(s
, size
);
1540 read(fd
, ptr
, size
);
1542 s
->data_offset
+= size
;
1546 /* second short pass to update sh_link and sh_info fields of new
1549 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1551 if (!s
|| !sm_table
[i
].new_section
)
1554 if (sh
->sh_link
> 0)
1555 s
->link
= sm_table
[sh
->sh_link
].s
;
1556 if (sh
->sh_type
== SHT_REL
) {
1557 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
1558 /* update backward link */
1559 s1
->sections
[s
->sh_info
]->reloc
= s
;
1563 /* resolve symbols */
1564 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
1567 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
1568 if (sym
->st_shndx
!= SHN_UNDEF
&&
1569 sym
->st_shndx
< SHN_LORESERVE
) {
1570 sm
= &sm_table
[sym
->st_shndx
];
1571 /* if no corresponding section added, no need to add symbol */
1574 /* convert section number */
1575 sym
->st_shndx
= sm
->s
->sh_num
;
1577 sym
->st_value
+= sm
->offset
;
1580 name
= strtab
+ sym
->st_name
;
1581 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
1582 sym
->st_info
, sym
->st_shndx
, name
);
1583 old_to_new_syms
[i
] = sym_index
;
1586 /* third pass to patch relocation entries */
1587 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1592 offset
= sm_table
[i
].offset
;
1593 switch(s
->sh_type
) {
1595 /* take relocation offset information */
1596 offseti
= sm_table
[sh
->sh_info
].offset
;
1597 rel_end
= (Elf32_Rel
*)(s
->data
+ s
->data_offset
);
1598 for(rel
= (Elf32_Rel
*)(s
->data
+ offset
);
1603 /* convert symbol index */
1604 type
= ELF32_R_TYPE(rel
->r_info
);
1605 sym_index
= ELF32_R_SYM(rel
->r_info
);
1606 /* NOTE: only one symtab assumed */
1607 if (sym_index
>= nb_syms
)
1609 sym_index
= old_to_new_syms
[sym_index
];
1612 error_noabort("Invalid relocation entry");
1615 rel
->r_info
= ELF32_R_INFO(sym_index
, type
);
1616 /* offset the relocation offset */
1617 rel
->r_offset
+= offseti
;
1629 tcc_free(old_to_new_syms
);
1636 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1638 typedef struct ArchiveHeader
{
1639 char ar_name
[16]; /* name of this member */
1640 char ar_date
[12]; /* file mtime */
1641 char ar_uid
[6]; /* owner uid; printed as decimal */
1642 char ar_gid
[6]; /* owner gid; printed as decimal */
1643 char ar_mode
[8]; /* file mode, printed as octal */
1644 char ar_size
[10]; /* file size, printed as decimal */
1645 char ar_fmag
[2]; /* should contain ARFMAG */
1648 /* load a '.a' file */
1649 static int tcc_load_archive(TCCState
*s1
, int fd
)
1656 unsigned long file_offset
;
1658 /* skip magic which was already checked */
1659 read(fd
, magic
, sizeof(magic
));
1662 len
= read(fd
, &hdr
, sizeof(hdr
));
1665 if (len
!= sizeof(hdr
)) {
1666 error_noabort("invalid archive");
1669 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
1670 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
1671 size
= strtol(ar_size
, NULL
, 0);
1672 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
1673 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
1674 if (ar_name
[i
] != ' ')
1677 ar_name
[i
+ 1] = '\0';
1678 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
1679 file_offset
= lseek(fd
, 0, SEEK_CUR
);
1680 if (!strcmp(ar_name
, "/") ||
1681 !strcmp(ar_name
, "//") ||
1682 !strcmp(ar_name
, "__.SYMDEF") ||
1683 !strcmp(ar_name
, "__.SYMDEF/") ||
1684 !strcmp(ar_name
, "ARFILENAMES/")) {
1685 /* skip symbol table or archive names */
1687 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
1691 size
= (size
+ 1) & ~1;
1692 lseek(fd
, file_offset
+ size
, SEEK_SET
);
1697 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
1698 is referenced by the user (so it should be added as DT_NEEDED in
1699 the generated ELF file) */
1700 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
1703 Elf32_Shdr
*shdr
, *sh
, *sh1
;
1704 int i
, nb_syms
, nb_dts
, sym_bind
, ret
;
1705 Elf32_Sym
*sym
, *dynsym
;
1706 Elf32_Dyn
*dt
, *dynamic
;
1707 unsigned char *dynstr
;
1708 const char *name
, *soname
, *p
;
1709 DLLReference
*dllref
;
1711 read(fd
, &ehdr
, sizeof(ehdr
));
1713 /* test CPU specific stuff */
1714 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
1715 ehdr
.e_machine
!= EM_386
) {
1716 error_noabort("bad architecture");
1721 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(Elf32_Shdr
) * ehdr
.e_shnum
);
1723 /* load dynamic section and dynamic symbols */
1727 dynsym
= NULL
; /* avoid warning */
1728 dynstr
= NULL
; /* avoid warning */
1729 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
1730 switch(sh
->sh_type
) {
1732 nb_dts
= sh
->sh_size
/ sizeof(Elf32_Dyn
);
1733 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
1736 nb_syms
= sh
->sh_size
/ sizeof(Elf32_Sym
);
1737 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
1738 sh1
= &shdr
[sh
->sh_link
];
1739 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
1746 /* compute the real library name */
1748 p
= strrchr(soname
, '/');
1752 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
1753 if (dt
->d_tag
== DT_SONAME
) {
1754 soname
= dynstr
+ dt
->d_un
.d_val
;
1758 /* if the dll is already loaded, do not load it */
1759 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1760 dllref
= s1
->loaded_dlls
[i
];
1761 if (!strcmp(soname
, dllref
->name
)) {
1762 /* but update level if needed */
1763 if (level
< dllref
->level
)
1764 dllref
->level
= level
;
1770 // printf("loading dll '%s'\n", soname);
1772 /* add the dll and its level */
1773 dllref
= tcc_malloc(sizeof(DLLReference
) + strlen(soname
));
1774 dllref
->level
= level
;
1775 strcpy(dllref
->name
, soname
);
1776 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
1778 /* add dynamic symbols in dynsym_section */
1779 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
1780 sym_bind
= ELF32_ST_BIND(sym
->st_info
);
1781 if (sym_bind
== STB_LOCAL
)
1783 name
= dynstr
+ sym
->st_name
;
1784 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
1785 sym
->st_info
, sym
->st_shndx
, name
);
1788 /* load all referenced DLLs */
1789 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
1792 name
= dynstr
+ dt
->d_un
.d_val
;
1793 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1794 dllref
= s1
->loaded_dlls
[i
];
1795 if (!strcmp(name
, dllref
->name
))
1796 goto already_loaded
;
1798 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
1799 error_noabort("referenced dll '%s' not found", name
);
1816 /* return -2 if error and CH_EOF if eof */
1817 static void ld_skipspaces(void)
1819 while (ch
== ' ' || ch
== '\t' || ch
== '\n')
1823 static int ld_get_cmd(char *cmd
, int cmd_size
)
1832 if (!((ch
>= 'a' && ch
<= 'z') ||
1833 (ch
>= 'A' && ch
<= 'Z') ||
1834 (ch
>= '0' && ch
<= '9') ||
1835 strchr("/.-_+=$:\\,~?*", ch
)))
1837 if ((q
- cmd
) >= (cmd_size
- 1))
1846 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
1848 static int tcc_load_ldscript(TCCState
*s1
)
1851 char filename
[1024];
1857 ret
= ld_get_cmd(cmd
, sizeof(cmd
));
1862 // printf("cmd='%s'\n", cmd);
1863 if (!strcmp(cmd
, "INPUT") ||
1864 !strcmp(cmd
, "GROUP")) {
1870 ld_get_cmd(filename
, sizeof(filename
));
1871 tcc_add_file(s1
, filename
);
1875 } else if (ch
== ')') {
1878 } else if (ch
== CH_EOF
) {
1879 error_noabort("unexpected end of file");