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
!= dynsymtab_section
)
203 error("'%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(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(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
< nb_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(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
;
408 /* if dynamic symbol exist, then use it */
409 sym_index
= find_elf_sym(dynsym
, name
);
411 esym
= &((Elf32_Sym
*)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("undefined symbol '%s'", name
);
428 } else if (sh_num
< SHN_LORESERVE
) {
429 /* add section base */
430 sym
->st_value
+= 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
= 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
= 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
+= got
->sh_addr
- addr
;
501 *(int *)ptr
+= val
- got
->sh_addr
;
504 /* we load the got offset */
505 *(int *)ptr
+= got_offsets
[sym_index
];
509 /* if the relocation is allocated, we change its symbol table */
510 if (sr
->sh_flags
& SHF_ALLOC
)
514 /* relocate relocation table in 'sr' */
515 static void relocate_rel(Section
*sr
)
518 Elf32_Rel
*rel
, *rel_end
;
520 s
= 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(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
= 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(int index
, unsigned long val
)
567 if (index
>= nb_got_offsets
) {
568 /* find immediately bigger power of 2 and reallocate array */
572 tab
= tcc_realloc(got_offsets
, n
* sizeof(unsigned long));
574 error("memory full");
576 memset(got_offsets
+ nb_got_offsets
, 0,
577 (n
- nb_got_offsets
) * sizeof(unsigned long));
580 got_offsets
[index
] = val
;
583 /* XXX: suppress that */
584 static void put32(unsigned char *p
, unsigned int val
)
592 static void build_got(void)
596 /* if no got, then create it */
597 got
= new_section(".got", SHT_PROGBITS
, SHF_ALLOC
| SHF_WRITE
);
599 add_elf_sym(symtab_section
, 0, 4, ELF32_ST_INFO(STB_GLOBAL
, STT_OBJECT
),
600 got
->sh_num
, "_GLOBAL_OFFSET_TABLE_");
601 ptr
= section_ptr_add(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(int reloc_type
, unsigned long size
, int info
,
617 unsigned long offset
;
623 /* if a got entry already exists for that symbol, no need to add one */
624 if (sym_index
< nb_got_offsets
&&
625 got_offsets
[sym_index
] != 0)
628 put_got_offset(sym_index
, got
->data_offset
);
631 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
632 name
= symtab_section
->link
->data
+ sym
->st_name
;
633 offset
= sym
->st_value
;
634 /* NOTE: we put temporarily the got offset */
635 if (reloc_type
== R_386_JMP_SLOT
) {
637 offset
= got
->data_offset
;
639 index
= put_elf_sym(dynsym
, offset
,
640 size
, info
, 0, sym
->st_shndx
, name
);
641 /* put a got entry */
642 put_elf_reloc(dynsym
, got
,
646 ptr
= section_ptr_add(got
, sizeof(int));
650 /* build GOT and PLT entries */
651 static void build_got_entries(void)
654 Elf32_Rel
*rel
, *rel_end
;
656 int i
, type
, reloc_type
, sym_index
;
658 for(i
= 1; i
< nb_sections
; i
++) {
660 if (s
->sh_type
!= SHT_REL
)
662 /* no need to handle got relocations */
663 if (s
->link
!= symtab_section
)
666 rel_end
= (Elf32_Rel
*)(s
->data
+ s
->data_offset
);
667 for(rel
= (Elf32_Rel
*)s
->data
;
670 type
= ELF32_R_TYPE(rel
->r_info
);
678 if (type
== R_386_GOT32
|| type
== R_386_PLT32
) {
679 sym_index
= ELF32_R_SYM(rel
->r_info
);
680 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
681 /* look at the symbol got offset. If none, then add one */
682 if (type
== R_386_GOT32
)
683 reloc_type
= R_386_GLOB_DAT
;
685 reloc_type
= R_386_JMP_SLOT
;
686 put_got_entry(reloc_type
, sym
->st_size
, sym
->st_info
,
697 static Section
*new_symtab(const char *symtab_name
, int sh_type
, int sh_flags
,
698 const char *strtab_name
,
699 const char *hash_name
, int hash_sh_flags
)
701 Section
*symtab
, *strtab
, *hash
;
702 int *ptr
, nb_buckets
;
704 symtab
= new_section(symtab_name
, sh_type
, sh_flags
);
705 symtab
->sh_entsize
= sizeof(Elf32_Sym
);
706 strtab
= new_section(strtab_name
, SHT_STRTAB
, sh_flags
);
707 put_elf_str(strtab
, "");
708 symtab
->link
= strtab
;
709 put_elf_sym(symtab
, 0, 0, 0, 0, 0, NULL
);
713 hash
= new_section(hash_name
, SHT_HASH
, hash_sh_flags
);
714 hash
->sh_entsize
= sizeof(int);
718 ptr
= section_ptr_add(hash
, (2 + nb_buckets
+ 1) * sizeof(int));
721 memset(ptr
+ 2, 0, (nb_buckets
+ 1) * sizeof(int));
725 /* put dynamic tag */
726 static void put_dt(Section
*dynamic
, int dt
, unsigned long val
)
729 dyn
= section_ptr_add(dynamic
, sizeof(Elf32_Dyn
));
731 dyn
->d_un
.d_val
= val
;
734 /* add tcc runtime libraries */
735 static void tcc_add_runtime(TCCState
*s1
)
741 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "libtcc1.o");
742 tcc_add_file(s1
, buf
);
743 #ifdef CONFIG_TCC_BCHECK
744 if (do_bounds_check
) {
746 Section
*init_section
;
747 unsigned char *pinit
;
750 /* XXX: add an object file to do that */
751 ptr
= section_ptr_add(bounds_section
, sizeof(unsigned long));
753 add_elf_sym(symtab_section
, 0, 0,
754 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
755 bounds_section
->sh_num
, "__bounds_start");
756 /* add bound check code */
757 snprintf(buf
, sizeof(buf
), "%s/%s", tcc_lib_path
, "bcheck.o");
758 tcc_add_file(s1
, buf
);
759 #ifdef TCC_TARGET_I386
760 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
761 /* add 'call __bound_init()' in .init section */
762 init_section
= find_section(".init");
763 pinit
= section_ptr_add(init_section
, 5);
765 put32(pinit
+ 1, -4);
766 sym_index
= find_elf_sym(symtab_section
, "__bound_init");
767 put_elf_reloc(symtab_section
, init_section
,
768 init_section
->data_offset
- 4, R_386_PC32
, sym_index
);
773 /* add libc if not memory output */
774 if (s1
->output_type
!= TCC_OUTPUT_MEMORY
) {
775 tcc_add_library(s1
, "c");
776 tcc_add_file(s1
, CONFIG_TCC_CRT_PREFIX
"/crtn.o");
778 /* add various standard linker symbols */
779 add_elf_sym(symtab_section
,
780 text_section
->data_offset
, 0,
781 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
782 text_section
->sh_num
, "_etext");
783 add_elf_sym(symtab_section
,
784 data_section
->data_offset
, 0,
785 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
786 data_section
->sh_num
, "_edata");
787 add_elf_sym(symtab_section
,
788 bss_section
->data_offset
, 0,
789 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
790 bss_section
->sh_num
, "_end");
791 /* add start and stop symbols for sections whose name can be
793 for(i
= 1; i
< nb_sections
; i
++) {
795 if (s
->sh_type
== SHT_PROGBITS
&&
796 (s
->sh_flags
& SHF_ALLOC
)) {
800 /* check if section name can be expressed in C */
806 if (!isid(ch
) && !isnum(ch
))
810 snprintf(buf
, sizeof(buf
), "__start_%s", s
->name
);
811 add_elf_sym(symtab_section
,
813 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
815 snprintf(buf
, sizeof(buf
), "__stop_%s", s
->name
);
816 add_elf_sym(symtab_section
,
818 ELF32_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
825 /* name of ELF interpreter */
826 static char elf_interp
[] = "/lib/ld-linux.so.2";
828 #define ELF_START_ADDR 0x08048000
829 #define ELF_PAGE_SIZE 0x1000
831 /* output an ELF file */
832 /* XXX: suppress unneeded sections */
833 int tcc_output_file(TCCState
*s1
, const char *filename
)
839 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
842 Elf32_Shdr shdr
, *sh
;
843 Elf32_Phdr
*phdr
, *ph
;
844 Section
*interp
, *plt
, *dynamic
, *dynstr
;
845 unsigned long saved_dynamic_data_offset
;
848 unsigned long rel_addr
, rel_size
;
850 file_type
= s1
->output_type
;
852 if (file_type
!= TCC_OUTPUT_OBJ
)
860 plt
= NULL
; /* avoid warning */
861 dynstr
= NULL
; /* avoid warning */
862 saved_dynamic_data_offset
= 0; /* avoid warning */
864 if (file_type
!= TCC_OUTPUT_OBJ
) {
866 relocate_common_syms();
870 int sym_index
, index
;
871 Elf32_Sym
*esym
, *sym_end
;
873 if (file_type
== TCC_OUTPUT_EXE
) {
875 /* add interpreter section only if executable */
876 interp
= new_section(".interp", SHT_PROGBITS
, SHF_ALLOC
);
877 interp
->sh_addralign
= 1;
878 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
879 strcpy(ptr
, elf_interp
);
882 /* add dynamic symbol table */
883 dynsym
= new_symtab(".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
886 dynstr
= dynsym
->link
;
888 /* add dynamic section */
889 dynamic
= new_section(".dynamic", SHT_DYNAMIC
,
890 SHF_ALLOC
| SHF_WRITE
);
891 dynamic
->link
= dynstr
;
892 dynamic
->sh_entsize
= sizeof(Elf32_Dyn
);
895 plt
= new_section(".plt", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
900 /* scan for undefined symbols and see if they are in the
901 dynamic symbols. If a symbol STT_FUNC is found, then we
902 add it in the PLT. If a symbol STT_OBJECT is found, we
903 add it in the .bss section with a suitable relocation */
904 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+
905 symtab_section
->data_offset
);
906 if (file_type
== TCC_OUTPUT_EXE
) {
907 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
910 if (sym
->st_shndx
== SHN_UNDEF
) {
911 name
= symtab_section
->link
->data
+ sym
->st_name
;
912 sym_index
= find_elf_sym(dynsymtab_section
, name
);
914 esym
= &((Elf32_Sym
*)dynsymtab_section
->data
)[sym_index
];
915 type
= ELF32_ST_TYPE(esym
->st_info
);
916 if (type
== STT_FUNC
) {
917 put_got_entry(R_386_JMP_SLOT
, esym
->st_size
,
919 sym
- (Elf32_Sym
*)symtab_section
->data
);
920 } else if (type
== STT_OBJECT
) {
921 unsigned long offset
;
922 offset
= bss_section
->data_offset
;
923 /* XXX: which alignment ? */
924 offset
= (offset
+ 8 - 1) & -8;
925 index
= put_elf_sym(dynsym
, offset
, esym
->st_size
,
927 bss_section
->sh_num
, name
);
928 put_elf_reloc(dynsym
, bss_section
,
929 offset
, R_386_COPY
, index
);
930 offset
+= esym
->st_size
;
931 bss_section
->data_offset
= offset
;
934 /* STB_WEAK undefined symbols are accepted */
935 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
937 if (ELF32_ST_BIND(sym
->st_info
) == STB_WEAK
||
938 !strcmp(name
, "_fp_hw")) {
940 error("undefined symbol '%s'", name
);
946 /* now look at unresolved dynamic symbols and export
947 corresponding symbol */
948 sym_end
= (Elf32_Sym
*)(dynsymtab_section
->data
+
949 dynsymtab_section
->data_offset
);
950 for(esym
= (Elf32_Sym
*)dynsymtab_section
->data
+ 1;
953 if (esym
->st_shndx
== SHN_UNDEF
) {
954 name
= dynsymtab_section
->link
->data
+ esym
->st_name
;
955 sym_index
= find_elf_sym(symtab_section
, name
);
957 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
958 put_elf_sym(dynsym
, sym
->st_value
, sym
->st_size
,
960 sym
->st_shndx
, name
);
962 if (ELF32_ST_BIND(esym
->st_info
) == STB_WEAK
) {
963 /* weak symbols can stay undefined */
965 warning("undefined dynamic symbol '%s'", name
);
972 /* shared library case : we simply export all the global symbols */
973 nb_syms
= symtab_section
->data_offset
/ sizeof(Elf32_Sym
);
974 symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
975 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
978 if (ELF32_ST_BIND(sym
->st_info
) != STB_LOCAL
) {
979 name
= symtab_section
->link
->data
+ sym
->st_name
;
980 index
= put_elf_sym(dynsym
, sym
->st_value
, sym
->st_size
,
982 sym
->st_shndx
, name
);
983 symtab_to_dynsym
[sym
- (Elf32_Sym
*)symtab_section
->data
] =
991 /* update PLT/GOT sizes so that we can allocate their space */
992 plt
->data_offset
+= 16 * (nb_plt_entries
+ 1);
994 /* add a list of needed dlls */
995 for(i
= 0; i
< nb_loaded_dlls
; i
++) {
996 DLLReference
*dllref
= loaded_dlls
[i
];
997 if (dllref
->level
== 0)
998 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1000 /* XXX: currently, since we do not handle PIC code, we
1001 must relocate the readonly segments */
1002 if (file_type
== TCC_OUTPUT_DLL
)
1003 put_dt(dynamic
, DT_TEXTREL
, 0);
1005 /* add necessary space for other entries */
1006 saved_dynamic_data_offset
= dynamic
->data_offset
;
1007 dynamic
->data_offset
+= 8 * 9;
1009 /* still need to build got entries in case of static link */
1010 build_got_entries();
1014 memset(&ehdr
, 0, sizeof(ehdr
));
1016 /* we add a section for symbols */
1017 strsec
= new_section(".shstrtab", SHT_STRTAB
, 0);
1018 put_elf_str(strsec
, "");
1020 /* compute number of sections */
1021 shnum
= nb_sections
;
1023 /* this array is used to reorder sections in the output file */
1024 section_order
= tcc_malloc(sizeof(int) * shnum
);
1025 section_order
[0] = 0;
1028 /* compute number of program headers */
1031 case TCC_OUTPUT_OBJ
:
1034 case TCC_OUTPUT_EXE
:
1040 case TCC_OUTPUT_DLL
:
1045 /* allocate strings for section names and decide if an unallocated
1046 section should be output */
1047 /* NOTE: the strsec section comes last, so its size is also
1049 for(i
= 1; i
< nb_sections
; i
++) {
1051 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1052 /* when generating a DLL, we include relocations but we may
1054 if (file_type
== TCC_OUTPUT_DLL
&&
1055 s
->sh_type
== SHT_REL
&&
1056 !(s
->sh_flags
& SHF_ALLOC
)) {
1057 prepare_dynamic_rel(s
);
1058 } else if (do_debug
||
1059 file_type
== TCC_OUTPUT_OBJ
||
1060 (s
->sh_flags
& SHF_ALLOC
) ||
1061 i
== (nb_sections
- 1)) {
1062 /* we output all sections if debug or object file */
1063 s
->sh_size
= s
->data_offset
;
1067 /* allocate program segment headers */
1068 phdr
= tcc_mallocz(phnum
* sizeof(Elf32_Phdr
));
1070 file_offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
1072 /* compute section to program header mapping */
1073 if (file_type
== TCC_OUTPUT_DLL
)
1076 addr
= ELF_START_ADDR
;
1078 /* dynamic relocation table information, for .dynamic section */
1082 /* compute address after headers */
1083 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1085 /* leave one program header for the program interpreter */
1090 for(j
= 0; j
< 2; j
++) {
1091 ph
->p_type
= PT_LOAD
;
1093 ph
->p_flags
= PF_R
| PF_X
;
1095 ph
->p_flags
= PF_R
| PF_W
;
1096 ph
->p_align
= ELF_PAGE_SIZE
;
1098 /* we do the following ordering: interp, symbol tables,
1099 relocations, progbits, nobits */
1100 /* XXX: do faster and simpler sorting */
1101 for(k
= 0; k
< 5; k
++) {
1102 for(i
= 1; i
< nb_sections
; i
++) {
1104 /* compute if section should be included */
1106 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1110 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1111 (SHF_ALLOC
| SHF_WRITE
))
1117 } else if (s
->sh_type
== SHT_DYNSYM
||
1118 s
->sh_type
== SHT_STRTAB
||
1119 s
->sh_type
== SHT_HASH
) {
1122 } else if (s
->sh_type
== SHT_REL
) {
1125 } else if (s
->sh_type
== SHT_NOBITS
) {
1132 section_order
[sh_order_index
++] = i
;
1134 /* section matches: we align it and add its size */
1136 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1137 ~(s
->sh_addralign
- 1);
1138 s
->sh_offset
= file_offset
;
1139 addr
+= file_offset
- tmp
;
1142 /* update program header infos */
1143 if (ph
->p_offset
== 0) {
1144 ph
->p_offset
= file_offset
;
1146 ph
->p_paddr
= ph
->p_vaddr
;
1148 /* update dynamic relocation infos */
1149 if (s
->sh_type
== SHT_REL
) {
1152 rel_size
+= s
->sh_size
;
1155 if (s
->sh_type
!= SHT_NOBITS
)
1156 file_offset
+= s
->sh_size
;
1159 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1160 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1164 /* if interpreter, then add corresponing program header */
1168 ph
->p_type
= PT_INTERP
;
1169 ph
->p_offset
= interp
->sh_offset
;
1170 ph
->p_vaddr
= interp
->sh_addr
;
1171 ph
->p_paddr
= ph
->p_vaddr
;
1172 ph
->p_filesz
= interp
->sh_size
;
1173 ph
->p_memsz
= interp
->sh_size
;
1175 ph
->p_align
= interp
->sh_addralign
;
1178 /* if dynamic section, then add corresponing program header */
1184 ph
= &phdr
[phnum
- 1];
1186 ph
->p_type
= PT_DYNAMIC
;
1187 ph
->p_offset
= dynamic
->sh_offset
;
1188 ph
->p_vaddr
= dynamic
->sh_addr
;
1189 ph
->p_paddr
= ph
->p_vaddr
;
1190 ph
->p_filesz
= dynamic
->sh_size
;
1191 ph
->p_memsz
= dynamic
->sh_size
;
1192 ph
->p_flags
= PF_R
| PF_W
;
1193 ph
->p_align
= dynamic
->sh_addralign
;
1195 /* put GOT dynamic section address */
1196 put32(got
->data
, dynamic
->sh_addr
);
1198 /* compute the PLT */
1199 plt
->data_offset
= 0;
1201 /* first plt entry */
1202 p
= section_ptr_add(plt
, 16);
1203 p
[0] = 0xff; /* pushl got + 4 */
1205 put32(p
+ 2, got
->sh_addr
+ 4);
1206 p
[6] = 0xff; /* jmp *(got + 8) */
1208 put32(p
+ 8, got
->sh_addr
+ 8);
1210 /* relocation symbols in .dynsym and build PLT. */
1212 sym_end
= (Elf32_Sym
*)(dynsym
->data
+ dynsym
->data_offset
);
1213 for(sym
= (Elf32_Sym
*)dynsym
->data
+ 1;
1216 type
= ELF32_ST_TYPE(sym
->st_info
);
1217 if (sym
->st_shndx
== SHN_UNDEF
) {
1218 if (type
== STT_FUNC
) {
1219 /* one more entry in PLT */
1220 p
= section_ptr_add(plt
, 16);
1221 p
[0] = 0xff; /* jmp *(got + x) */
1223 put32(p
+ 2, got
->sh_addr
+ sym
->st_value
);
1224 p
[6] = 0x68; /* push $xxx */
1225 put32(p
+ 7, plt_offset
);
1226 p
[11] = 0xe9; /* jmp plt_start */
1227 put32(p
+ 12, -(plt
->data_offset
));
1229 /* patch symbol value to point to plt */
1230 sym
->st_value
= plt
->sh_addr
+ p
- plt
->data
;
1234 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1235 /* do symbol relocation */
1236 sym
->st_value
+= sections
[sym
->st_shndx
]->sh_addr
;
1239 /* put dynamic section entries */
1241 dynamic
->data_offset
= saved_dynamic_data_offset
;
1242 put_dt(dynamic
, DT_HASH
, dynsym
->hash
->sh_addr
);
1243 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1244 put_dt(dynamic
, DT_SYMTAB
, dynsym
->sh_addr
);
1245 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1246 put_dt(dynamic
, DT_SYMENT
, sizeof(Elf32_Sym
));
1247 put_dt(dynamic
, DT_REL
, rel_addr
);
1248 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1249 put_dt(dynamic
, DT_RELENT
, sizeof(Elf32_Rel
));
1250 put_dt(dynamic
, DT_NULL
, 0);
1253 ehdr
.e_phentsize
= sizeof(Elf32_Phdr
);
1254 ehdr
.e_phnum
= phnum
;
1255 ehdr
.e_phoff
= sizeof(Elf32_Ehdr
);
1258 /* all other sections come after */
1259 for(i
= 1; i
< nb_sections
; i
++) {
1261 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1263 section_order
[sh_order_index
++] = i
;
1265 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1266 ~(s
->sh_addralign
- 1);
1267 s
->sh_offset
= file_offset
;
1268 if (s
->sh_type
!= SHT_NOBITS
)
1269 file_offset
+= s
->sh_size
;
1272 /* if building executable or DLL, then relocate each section
1273 except the GOT which is already relocated */
1274 if (file_type
!= TCC_OUTPUT_OBJ
) {
1277 /* relocate sections */
1278 /* XXX: ignore sections with allocated relocations ? */
1279 for(i
= 1; i
< nb_sections
; i
++) {
1281 if (s
->reloc
&& s
!= got
)
1282 relocate_section(s1
, s
);
1285 /* relocate relocation entries if the relocation tables are
1286 allocated in the executable */
1287 for(i
= 1; i
< nb_sections
; i
++) {
1289 if ((s
->sh_flags
& SHF_ALLOC
) &&
1290 s
->sh_type
== SHT_REL
) {
1295 /* get entry point address */
1296 if (file_type
== TCC_OUTPUT_EXE
)
1297 ehdr
.e_entry
= (unsigned long)tcc_get_symbol(s1
, "_start");
1299 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1302 sort_syms(symtab_section
);
1305 file_offset
= (file_offset
+ 3) & -4;
1308 ehdr
.e_ident
[0] = ELFMAG0
;
1309 ehdr
.e_ident
[1] = ELFMAG1
;
1310 ehdr
.e_ident
[2] = ELFMAG2
;
1311 ehdr
.e_ident
[3] = ELFMAG3
;
1312 ehdr
.e_ident
[4] = ELFCLASS32
;
1313 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1314 ehdr
.e_ident
[6] = EV_CURRENT
;
1317 case TCC_OUTPUT_EXE
:
1318 ehdr
.e_type
= ET_EXEC
;
1320 case TCC_OUTPUT_DLL
:
1321 ehdr
.e_type
= ET_DYN
;
1323 case TCC_OUTPUT_OBJ
:
1324 ehdr
.e_type
= ET_REL
;
1327 ehdr
.e_machine
= EM_386
;
1328 ehdr
.e_version
= EV_CURRENT
;
1329 ehdr
.e_shoff
= file_offset
;
1330 ehdr
.e_ehsize
= sizeof(Elf32_Ehdr
);
1331 ehdr
.e_shentsize
= sizeof(Elf32_Shdr
);
1332 ehdr
.e_shnum
= shnum
;
1333 ehdr
.e_shstrndx
= shnum
- 1;
1335 /* write elf file */
1336 if (file_type
== TCC_OUTPUT_OBJ
)
1340 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
, mode
);
1342 error("could not write '%s'", filename
);
1344 f
= fdopen(fd
, "w");
1345 fwrite(&ehdr
, 1, sizeof(Elf32_Ehdr
), f
);
1346 fwrite(phdr
, 1, phnum
* sizeof(Elf32_Phdr
), f
);
1347 offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
1348 for(i
=1;i
<nb_sections
;i
++) {
1349 s
= sections
[section_order
[i
]];
1350 if (s
->sh_type
!= SHT_NOBITS
) {
1351 while (offset
< s
->sh_offset
) {
1356 fwrite(s
->data
, 1, size
, f
);
1360 while (offset
< ehdr
.e_shoff
) {
1365 /* output section headers */
1366 for(i
=0;i
<nb_sections
;i
++) {
1368 memset(sh
, 0, sizeof(Elf32_Shdr
));
1371 sh
->sh_name
= s
->sh_name
;
1372 sh
->sh_type
= s
->sh_type
;
1373 sh
->sh_flags
= s
->sh_flags
;
1374 sh
->sh_entsize
= s
->sh_entsize
;
1375 sh
->sh_info
= s
->sh_info
;
1377 sh
->sh_link
= s
->link
->sh_num
;
1378 sh
->sh_addralign
= s
->sh_addralign
;
1379 sh
->sh_addr
= s
->sh_addr
;
1380 sh
->sh_offset
= s
->sh_offset
;
1381 sh
->sh_size
= s
->sh_size
;
1383 fwrite(sh
, 1, sizeof(Elf32_Shdr
), f
);
1387 tcc_free(section_order
);
1392 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
1396 data
= tcc_malloc(size
);
1397 lseek(fd
, file_offset
, SEEK_SET
);
1398 read(fd
, data
, size
);
1402 typedef struct SectionMergeInfo
{
1403 Section
*s
; /* corresponding existing section */
1404 unsigned long offset
; /* offset of the new section in the existing section */
1405 int new_section
; /* true if section 's' was added */
1408 /* load an object file and merge it with current files */
1409 /* XXX: handle correctly stab (debug) info */
1410 static int tcc_load_object_file(TCCState
*s1
,
1411 int fd
, unsigned long file_offset
)
1414 Elf32_Shdr
*shdr
, *sh
;
1415 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
;
1416 unsigned char *strsec
, *strtab
;
1417 int *old_to_new_syms
;
1418 char *sh_name
, *name
;
1419 SectionMergeInfo
*sm_table
, *sm
;
1420 Elf32_Sym
*sym
, *symtab
;
1421 Elf32_Rel
*rel
, *rel_end
;
1424 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
1426 if (ehdr
.e_ident
[0] != ELFMAG0
||
1427 ehdr
.e_ident
[1] != ELFMAG1
||
1428 ehdr
.e_ident
[2] != ELFMAG2
||
1429 ehdr
.e_ident
[3] != ELFMAG3
)
1431 /* test if object file */
1432 if (ehdr
.e_type
!= ET_REL
)
1434 /* test CPU specific stuff */
1435 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
1436 ehdr
.e_machine
!= EM_386
) {
1438 error("invalid object file");
1441 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
1442 sizeof(Elf32_Shdr
) * ehdr
.e_shnum
);
1443 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
1445 /* load section names */
1446 sh
= &shdr
[ehdr
.e_shstrndx
];
1447 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1449 /* load symtab and strtab */
1453 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1455 if (sh
->sh_type
== SHT_SYMTAB
) {
1457 error("object must contain only one symtab");
1458 nb_syms
= sh
->sh_size
/ sizeof(Elf32_Sym
);
1459 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1460 sm_table
[i
].s
= symtab_section
;
1462 /* now load strtab */
1463 sh
= &shdr
[sh
->sh_link
];
1464 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1468 /* now examine each section and try to merge its content with the
1470 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1471 /* no need to examine section name strtab */
1472 if (i
== ehdr
.e_shstrndx
)
1475 sh_name
= strsec
+ sh
->sh_name
;
1476 /* ignore sections types we do not handle */
1477 if (sh
->sh_type
!= SHT_PROGBITS
&&
1478 sh
->sh_type
!= SHT_REL
&&
1479 sh
->sh_type
!= SHT_NOBITS
)
1481 if (sh
->sh_addralign
< 1)
1482 sh
->sh_addralign
= 1;
1483 /* find corresponding section, if any */
1484 for(j
= 1; j
< nb_sections
;j
++) {
1486 if (!strcmp(s
->name
, sh_name
))
1489 /* not found: create new section */
1490 s
= new_section(sh_name
, sh
->sh_type
, sh
->sh_flags
);
1491 /* take as much info as possible from the section. sh_link and
1492 sh_info will be updated later */
1493 s
->sh_addralign
= sh
->sh_addralign
;
1494 s
->sh_entsize
= sh
->sh_entsize
;
1495 sm_table
[i
].new_section
= 1;
1497 if (sh
->sh_type
!= s
->sh_type
)
1500 /* align start of section */
1501 offset
= s
->data_offset
;
1502 size
= sh
->sh_addralign
- 1;
1503 offset
= (offset
+ size
) & ~size
;
1504 if (sh
->sh_addralign
> s
->sh_addralign
)
1505 s
->sh_addralign
= sh
->sh_addralign
;
1506 s
->data_offset
= offset
;
1507 sm_table
[i
].offset
= offset
;
1509 /* concatenate sections */
1511 if (sh
->sh_type
!= SHT_NOBITS
) {
1513 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
1514 ptr
= section_ptr_add(s
, size
);
1515 read(fd
, ptr
, size
);
1517 s
->data_offset
+= size
;
1521 /* second short pass to update sh_link and sh_info fields of new
1524 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1526 if (!s
|| !sm_table
[i
].new_section
)
1529 if (sh
->sh_link
> 0)
1530 s
->link
= sm_table
[sh
->sh_link
].s
;
1531 if (sh
->sh_type
== SHT_REL
) {
1532 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
1533 /* update backward link */
1534 sections
[s
->sh_info
]->reloc
= s
;
1538 /* resolve symbols */
1539 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
1542 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
1543 if (sym
->st_shndx
!= SHN_UNDEF
&&
1544 sym
->st_shndx
< SHN_LORESERVE
) {
1545 sm
= &sm_table
[sym
->st_shndx
];
1546 /* if no corresponding section added, no need to add symbol */
1549 /* convert section number */
1550 sym
->st_shndx
= sm
->s
->sh_num
;
1552 sym
->st_value
+= sm
->offset
;
1555 name
= strtab
+ sym
->st_name
;
1556 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
1557 sym
->st_info
, sym
->st_shndx
, name
);
1558 old_to_new_syms
[i
] = sym_index
;
1561 /* third pass to patch relocation entries */
1562 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1567 offset
= sm_table
[i
].offset
;
1568 switch(s
->sh_type
) {
1570 /* take relocation offset information */
1571 offseti
= sm_table
[sh
->sh_info
].offset
;
1572 rel_end
= (Elf32_Rel
*)(s
->data
+ s
->data_offset
);
1573 for(rel
= (Elf32_Rel
*)(s
->data
+ offset
);
1578 /* convert symbol index */
1579 type
= ELF32_R_TYPE(rel
->r_info
);
1580 sym_index
= ELF32_R_SYM(rel
->r_info
);
1581 /* NOTE: only one symtab assumed */
1582 if (sym_index
>= nb_syms
)
1584 sym_index
= old_to_new_syms
[sym_index
];
1587 error("Invalid relocation entry");
1589 rel
->r_info
= ELF32_R_INFO(sym_index
, type
);
1590 /* offset the relocation offset */
1591 rel
->r_offset
+= offseti
;
1600 tcc_free(old_to_new_syms
);
1606 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1608 typedef struct ArchiveHeader
{
1609 char ar_name
[16]; /* name of this member */
1610 char ar_date
[12]; /* file mtime */
1611 char ar_uid
[6]; /* owner uid; printed as decimal */
1612 char ar_gid
[6]; /* owner gid; printed as decimal */
1613 char ar_mode
[8]; /* file mode, printed as octal */
1614 char ar_size
[10]; /* file size, printed as decimal */
1615 char ar_fmag
[2]; /* should contain ARFMAG */
1618 /* load a '.a' file */
1619 static int tcc_load_archive(TCCState
*s1
, int fd
)
1626 unsigned long file_offset
;
1628 /* skip magic which was already checked */
1629 read(fd
, magic
, sizeof(magic
));
1632 len
= read(fd
, &hdr
, sizeof(hdr
));
1635 if (len
!= sizeof(hdr
))
1636 error("invalid archive");
1637 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
1638 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
1639 size
= strtol(ar_size
, NULL
, 0);
1640 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
1641 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
1642 if (ar_name
[i
] != ' ')
1645 ar_name
[i
+ 1] = '\0';
1646 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
1647 file_offset
= lseek(fd
, 0, SEEK_CUR
);
1648 if (!strcmp(ar_name
, "/") ||
1649 !strcmp(ar_name
, "//") ||
1650 !strcmp(ar_name
, "__.SYMDEF") ||
1651 !strcmp(ar_name
, "__.SYMDEF/") ||
1652 !strcmp(ar_name
, "ARFILENAMES/")) {
1653 /* skip symbol table or archive names */
1655 tcc_load_object_file(s1
, fd
, file_offset
);
1658 size
= (size
+ 1) & ~1;
1659 lseek(fd
, file_offset
+ size
, SEEK_SET
);
1664 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
1665 is referenced by the user (so it should be added as DT_NEEDED in
1666 the generated ELF file) */
1667 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
1670 Elf32_Shdr
*shdr
, *sh
, *sh1
;
1671 int i
, nb_syms
, nb_dts
, sym_bind
;
1672 Elf32_Sym
*sym
, *dynsym
;
1673 Elf32_Dyn
*dt
, *dynamic
;
1674 unsigned char *dynstr
;
1675 const char *name
, *soname
, *p
;
1676 DLLReference
*dllref
;
1678 read(fd
, &ehdr
, sizeof(ehdr
));
1680 /* test CPU specific stuff */
1681 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
1682 ehdr
.e_machine
!= EM_386
)
1683 error("bad architecture");
1686 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(Elf32_Shdr
) * ehdr
.e_shnum
);
1688 /* load dynamic section and dynamic symbols */
1692 dynsym
= NULL
; /* avoid warning */
1693 dynstr
= NULL
; /* avoid warning */
1694 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
1695 switch(sh
->sh_type
) {
1697 nb_dts
= sh
->sh_size
/ sizeof(Elf32_Dyn
);
1698 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
1701 nb_syms
= sh
->sh_size
/ sizeof(Elf32_Sym
);
1702 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
1703 sh1
= &shdr
[sh
->sh_link
];
1704 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
1711 /* compute the real library name */
1713 p
= strrchr(soname
, '/');
1717 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
1718 if (dt
->d_tag
== DT_SONAME
) {
1719 soname
= dynstr
+ dt
->d_un
.d_val
;
1723 /* if the dll is already loaded, do not load it */
1724 for(i
= 0; i
< nb_loaded_dlls
; i
++) {
1725 dllref
= loaded_dlls
[i
];
1726 if (!strcmp(soname
, dllref
->name
)) {
1727 /* but update level if needed */
1728 if (level
< dllref
->level
)
1729 dllref
->level
= level
;
1734 // printf("loading dll '%s'\n", soname);
1736 /* add the dll and its level */
1737 dllref
= tcc_malloc(sizeof(DLLReference
) + strlen(soname
));
1738 dllref
->level
= level
;
1739 strcpy(dllref
->name
, soname
);
1740 dynarray_add((void ***)&loaded_dlls
, &nb_loaded_dlls
, dllref
);
1742 /* add dynamic symbols in dynsym_section */
1743 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
1744 sym_bind
= ELF32_ST_BIND(sym
->st_info
);
1745 if (sym_bind
== STB_LOCAL
)
1747 name
= dynstr
+ sym
->st_name
;
1748 add_elf_sym(dynsymtab_section
, sym
->st_value
, sym
->st_size
,
1749 sym
->st_info
, sym
->st_shndx
, name
);
1752 /* load all referenced DLLs */
1753 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
1756 name
= dynstr
+ dt
->d_un
.d_val
;
1757 for(i
= 0; i
< nb_loaded_dlls
; i
++) {
1758 dllref
= loaded_dlls
[i
];
1759 if (!strcmp(name
, dllref
->name
))
1760 goto already_loaded
;
1762 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0)
1763 error("referenced dll '%s' not found", name
);
1773 /* return -2 if error and CH_EOF if eof */
1774 static void ld_skipspaces(void)
1776 while (ch
== ' ' || ch
== '\t' || ch
== '\n')
1780 static int ld_get_cmd(char *cmd
, int cmd_size
)
1789 if (!((ch
>= 'a' && ch
<= 'z') ||
1790 (ch
>= 'A' && ch
<= 'Z') ||
1791 (ch
>= '0' && ch
<= '9') ||
1792 strchr("/.-_+=$:\\,~?*", ch
)))
1794 if ((q
- cmd
) >= (cmd_size
- 1))
1803 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
1805 static int tcc_load_ldscript(TCCState
*s1
)
1808 char filename
[1024];
1814 ret
= ld_get_cmd(cmd
, sizeof(cmd
));
1819 // printf("cmd='%s'\n", cmd);
1820 if (!strcmp(cmd
, "INPUT") ||
1821 !strcmp(cmd
, "GROUP")) {
1827 ld_get_cmd(filename
, sizeof(filename
));
1828 tcc_add_file(s1
, filename
);
1832 } else if (ch
== ')') {
1835 } else if (ch
== CH_EOF
) {
1836 error("unexpected end of file");