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(RTLD_DEFAULT
, 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 */
829 static char elf_interp
[] = "/usr/libexec/ld-elf.so.1";
831 static char elf_interp
[] = "/lib/ld-linux.so.2";
834 #define ELF_START_ADDR 0x08048000
835 #define ELF_PAGE_SIZE 0x1000
837 /* output an ELF file */
838 /* XXX: suppress unneeded sections */
839 int tcc_output_file(TCCState
*s1
, const char *filename
)
845 int shnum
, i
, phnum
, file_offset
, offset
, size
, j
, tmp
, sh_order_index
, k
;
848 Elf32_Shdr shdr
, *sh
;
849 Elf32_Phdr
*phdr
, *ph
;
850 Section
*interp
, *plt
, *dynamic
, *dynstr
;
851 unsigned long saved_dynamic_data_offset
;
854 unsigned long rel_addr
, rel_size
;
856 file_type
= s1
->output_type
;
859 if (file_type
!= TCC_OUTPUT_OBJ
)
863 section_order
= NULL
;
866 plt
= NULL
; /* avoid warning */
867 dynstr
= NULL
; /* avoid warning */
868 saved_dynamic_data_offset
= 0; /* avoid warning */
870 if (file_type
!= TCC_OUTPUT_OBJ
) {
872 relocate_common_syms();
874 if (!s1
->static_link
) {
876 int sym_index
, index
;
877 Elf32_Sym
*esym
, *sym_end
;
879 if (file_type
== TCC_OUTPUT_EXE
) {
881 /* add interpreter section only if executable */
882 interp
= new_section(s1
, ".interp", SHT_PROGBITS
, SHF_ALLOC
);
883 interp
->sh_addralign
= 1;
884 ptr
= section_ptr_add(interp
, sizeof(elf_interp
));
885 strcpy(ptr
, elf_interp
);
888 /* add dynamic symbol table */
889 s1
->dynsym
= new_symtab(s1
, ".dynsym", SHT_DYNSYM
, SHF_ALLOC
,
892 dynstr
= s1
->dynsym
->link
;
894 /* add dynamic section */
895 dynamic
= new_section(s1
, ".dynamic", SHT_DYNAMIC
,
896 SHF_ALLOC
| SHF_WRITE
);
897 dynamic
->link
= dynstr
;
898 dynamic
->sh_entsize
= sizeof(Elf32_Dyn
);
901 plt
= new_section(s1
, ".plt", SHT_PROGBITS
, SHF_ALLOC
| SHF_EXECINSTR
);
906 /* scan for undefined symbols and see if they are in the
907 dynamic symbols. If a symbol STT_FUNC is found, then we
908 add it in the PLT. If a symbol STT_OBJECT is found, we
909 add it in the .bss section with a suitable relocation */
910 sym_end
= (Elf32_Sym
*)(symtab_section
->data
+
911 symtab_section
->data_offset
);
912 if (file_type
== TCC_OUTPUT_EXE
) {
913 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
916 if (sym
->st_shndx
== SHN_UNDEF
) {
917 name
= symtab_section
->link
->data
+ sym
->st_name
;
918 sym_index
= find_elf_sym(s1
->dynsymtab_section
, name
);
920 esym
= &((Elf32_Sym
*)s1
->dynsymtab_section
->data
)[sym_index
];
921 type
= ELF32_ST_TYPE(esym
->st_info
);
922 if (type
== STT_FUNC
) {
923 put_got_entry(s1
, R_386_JMP_SLOT
, esym
->st_size
,
925 sym
- (Elf32_Sym
*)symtab_section
->data
);
926 } else if (type
== STT_OBJECT
) {
927 unsigned long offset
;
928 offset
= bss_section
->data_offset
;
929 /* XXX: which alignment ? */
930 offset
= (offset
+ 8 - 1) & -8;
931 index
= put_elf_sym(s1
->dynsym
, offset
, esym
->st_size
,
933 bss_section
->sh_num
, name
);
934 put_elf_reloc(s1
->dynsym
, bss_section
,
935 offset
, R_386_COPY
, index
);
936 offset
+= esym
->st_size
;
937 bss_section
->data_offset
= offset
;
940 /* STB_WEAK undefined symbols are accepted */
941 /* XXX: _fp_hw seems to be part of the ABI, so we ignore
943 if (ELF32_ST_BIND(sym
->st_info
) == STB_WEAK
||
944 !strcmp(name
, "_fp_hw")) {
946 error_noabort("undefined symbol '%s'", name
);
955 /* now look at unresolved dynamic symbols and export
956 corresponding symbol */
957 sym_end
= (Elf32_Sym
*)(s1
->dynsymtab_section
->data
+
958 s1
->dynsymtab_section
->data_offset
);
959 for(esym
= (Elf32_Sym
*)s1
->dynsymtab_section
->data
+ 1;
962 if (esym
->st_shndx
== SHN_UNDEF
) {
963 name
= s1
->dynsymtab_section
->link
->data
+ esym
->st_name
;
964 sym_index
= find_elf_sym(symtab_section
, name
);
966 sym
= &((Elf32_Sym
*)symtab_section
->data
)[sym_index
];
967 put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
969 sym
->st_shndx
, name
);
971 if (ELF32_ST_BIND(esym
->st_info
) == STB_WEAK
) {
972 /* weak symbols can stay undefined */
974 warning("undefined dynamic symbol '%s'", name
);
981 /* shared library case : we simply export all the global symbols */
982 nb_syms
= symtab_section
->data_offset
/ sizeof(Elf32_Sym
);
983 s1
->symtab_to_dynsym
= tcc_mallocz(sizeof(int) * nb_syms
);
984 for(sym
= (Elf32_Sym
*)symtab_section
->data
+ 1;
987 if (ELF32_ST_BIND(sym
->st_info
) != STB_LOCAL
) {
988 name
= symtab_section
->link
->data
+ sym
->st_name
;
989 index
= put_elf_sym(s1
->dynsym
, sym
->st_value
, sym
->st_size
,
991 sym
->st_shndx
, name
);
992 s1
->symtab_to_dynsym
[sym
-
993 (Elf32_Sym
*)symtab_section
->data
] =
999 build_got_entries(s1
);
1001 /* update PLT/GOT sizes so that we can allocate their space */
1002 plt
->data_offset
+= 16 * (s1
->nb_plt_entries
+ 1);
1004 /* add a list of needed dlls */
1005 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1006 DLLReference
*dllref
= s1
->loaded_dlls
[i
];
1007 if (dllref
->level
== 0)
1008 put_dt(dynamic
, DT_NEEDED
, put_elf_str(dynstr
, dllref
->name
));
1010 /* XXX: currently, since we do not handle PIC code, we
1011 must relocate the readonly segments */
1012 if (file_type
== TCC_OUTPUT_DLL
)
1013 put_dt(dynamic
, DT_TEXTREL
, 0);
1015 /* add necessary space for other entries */
1016 saved_dynamic_data_offset
= dynamic
->data_offset
;
1017 dynamic
->data_offset
+= 8 * 9;
1019 /* still need to build got entries in case of static link */
1020 build_got_entries(s1
);
1024 memset(&ehdr
, 0, sizeof(ehdr
));
1026 /* we add a section for symbols */
1027 strsec
= new_section(s1
, ".shstrtab", SHT_STRTAB
, 0);
1028 put_elf_str(strsec
, "");
1030 /* compute number of sections */
1031 shnum
= s1
->nb_sections
;
1033 /* this array is used to reorder sections in the output file */
1034 section_order
= tcc_malloc(sizeof(int) * shnum
);
1035 section_order
[0] = 0;
1038 /* compute number of program headers */
1041 case TCC_OUTPUT_OBJ
:
1044 case TCC_OUTPUT_EXE
:
1045 if (!s1
->static_link
)
1050 case TCC_OUTPUT_DLL
:
1055 /* allocate strings for section names and decide if an unallocated
1056 section should be output */
1057 /* NOTE: the strsec section comes last, so its size is also
1059 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1060 s
= s1
->sections
[i
];
1061 s
->sh_name
= put_elf_str(strsec
, s
->name
);
1062 /* when generating a DLL, we include relocations but we may
1064 if (file_type
== TCC_OUTPUT_DLL
&&
1065 s
->sh_type
== SHT_REL
&&
1066 !(s
->sh_flags
& SHF_ALLOC
)) {
1067 prepare_dynamic_rel(s1
, s
);
1068 } else if (do_debug
||
1069 file_type
== TCC_OUTPUT_OBJ
||
1070 (s
->sh_flags
& SHF_ALLOC
) ||
1071 i
== (s1
->nb_sections
- 1)) {
1072 /* we output all sections if debug or object file */
1073 s
->sh_size
= s
->data_offset
;
1077 /* allocate program segment headers */
1078 phdr
= tcc_mallocz(phnum
* sizeof(Elf32_Phdr
));
1080 file_offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
1082 /* compute section to program header mapping */
1083 if (file_type
== TCC_OUTPUT_DLL
)
1086 addr
= ELF_START_ADDR
;
1088 /* dynamic relocation table information, for .dynamic section */
1092 /* compute address after headers */
1093 addr
+= (file_offset
& (ELF_PAGE_SIZE
- 1));
1095 /* leave one program header for the program interpreter */
1100 for(j
= 0; j
< 2; j
++) {
1101 ph
->p_type
= PT_LOAD
;
1103 ph
->p_flags
= PF_R
| PF_X
;
1105 ph
->p_flags
= PF_R
| PF_W
;
1106 ph
->p_align
= ELF_PAGE_SIZE
;
1108 /* we do the following ordering: interp, symbol tables,
1109 relocations, progbits, nobits */
1110 /* XXX: do faster and simpler sorting */
1111 for(k
= 0; k
< 5; k
++) {
1112 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1113 s
= s1
->sections
[i
];
1114 /* compute if section should be included */
1116 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1120 if ((s
->sh_flags
& (SHF_ALLOC
| SHF_WRITE
)) !=
1121 (SHF_ALLOC
| SHF_WRITE
))
1127 } else if (s
->sh_type
== SHT_DYNSYM
||
1128 s
->sh_type
== SHT_STRTAB
||
1129 s
->sh_type
== SHT_HASH
) {
1132 } else if (s
->sh_type
== SHT_REL
) {
1135 } else if (s
->sh_type
== SHT_NOBITS
) {
1142 section_order
[sh_order_index
++] = i
;
1144 /* section matches: we align it and add its size */
1146 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1147 ~(s
->sh_addralign
- 1);
1148 s
->sh_offset
= file_offset
;
1149 addr
+= file_offset
- tmp
;
1152 /* update program header infos */
1153 if (ph
->p_offset
== 0) {
1154 ph
->p_offset
= file_offset
;
1156 ph
->p_paddr
= ph
->p_vaddr
;
1158 /* update dynamic relocation infos */
1159 if (s
->sh_type
== SHT_REL
) {
1162 rel_size
+= s
->sh_size
;
1165 if (s
->sh_type
!= SHT_NOBITS
)
1166 file_offset
+= s
->sh_size
;
1169 ph
->p_filesz
= file_offset
- ph
->p_offset
;
1170 ph
->p_memsz
= addr
- ph
->p_vaddr
;
1172 /* if in the middle of a page, we duplicate the page in
1173 memory so that one copy is RX and the other is RW */
1174 if ((addr
& (ELF_PAGE_SIZE
- 1)) != 0)
1175 addr
+= ELF_PAGE_SIZE
;
1178 /* if interpreter, then add corresponing program header */
1182 ph
->p_type
= PT_INTERP
;
1183 ph
->p_offset
= interp
->sh_offset
;
1184 ph
->p_vaddr
= interp
->sh_addr
;
1185 ph
->p_paddr
= ph
->p_vaddr
;
1186 ph
->p_filesz
= interp
->sh_size
;
1187 ph
->p_memsz
= interp
->sh_size
;
1189 ph
->p_align
= interp
->sh_addralign
;
1192 /* if dynamic section, then add corresponing program header */
1198 ph
= &phdr
[phnum
- 1];
1200 ph
->p_type
= PT_DYNAMIC
;
1201 ph
->p_offset
= dynamic
->sh_offset
;
1202 ph
->p_vaddr
= dynamic
->sh_addr
;
1203 ph
->p_paddr
= ph
->p_vaddr
;
1204 ph
->p_filesz
= dynamic
->sh_size
;
1205 ph
->p_memsz
= dynamic
->sh_size
;
1206 ph
->p_flags
= PF_R
| PF_W
;
1207 ph
->p_align
= dynamic
->sh_addralign
;
1209 /* put GOT dynamic section address */
1210 put32(s1
->got
->data
, dynamic
->sh_addr
);
1212 /* compute the PLT */
1213 plt
->data_offset
= 0;
1215 /* first plt entry */
1216 p
= section_ptr_add(plt
, 16);
1217 p
[0] = 0xff; /* pushl got + 4 */
1219 put32(p
+ 2, s1
->got
->sh_addr
+ 4);
1220 p
[6] = 0xff; /* jmp *(got + 8) */
1222 put32(p
+ 8, s1
->got
->sh_addr
+ 8);
1224 /* relocation symbols in .dynsym and build PLT. */
1226 sym_end
= (Elf32_Sym
*)(s1
->dynsym
->data
+ s1
->dynsym
->data_offset
);
1227 for(sym
= (Elf32_Sym
*)s1
->dynsym
->data
+ 1;
1230 type
= ELF32_ST_TYPE(sym
->st_info
);
1231 if (sym
->st_shndx
== SHN_UNDEF
) {
1232 if (type
== STT_FUNC
) {
1233 /* one more entry in PLT */
1234 p
= section_ptr_add(plt
, 16);
1235 p
[0] = 0xff; /* jmp *(got + x) */
1237 put32(p
+ 2, s1
->got
->sh_addr
+ sym
->st_value
);
1238 p
[6] = 0x68; /* push $xxx */
1239 put32(p
+ 7, plt_offset
);
1240 p
[11] = 0xe9; /* jmp plt_start */
1241 put32(p
+ 12, -(plt
->data_offset
));
1243 /* patch symbol value to point to plt */
1244 sym
->st_value
= plt
->sh_addr
+ p
- plt
->data
;
1248 } else if (sym
->st_shndx
< SHN_LORESERVE
) {
1249 /* do symbol relocation */
1250 sym
->st_value
+= s1
->sections
[sym
->st_shndx
]->sh_addr
;
1253 /* put dynamic section entries */
1255 dynamic
->data_offset
= saved_dynamic_data_offset
;
1256 put_dt(dynamic
, DT_HASH
, s1
->dynsym
->hash
->sh_addr
);
1257 put_dt(dynamic
, DT_STRTAB
, dynstr
->sh_addr
);
1258 put_dt(dynamic
, DT_SYMTAB
, s1
->dynsym
->sh_addr
);
1259 put_dt(dynamic
, DT_STRSZ
, dynstr
->data_offset
);
1260 put_dt(dynamic
, DT_SYMENT
, sizeof(Elf32_Sym
));
1261 put_dt(dynamic
, DT_REL
, rel_addr
);
1262 put_dt(dynamic
, DT_RELSZ
, rel_size
);
1263 put_dt(dynamic
, DT_RELENT
, sizeof(Elf32_Rel
));
1264 put_dt(dynamic
, DT_NULL
, 0);
1267 ehdr
.e_phentsize
= sizeof(Elf32_Phdr
);
1268 ehdr
.e_phnum
= phnum
;
1269 ehdr
.e_phoff
= sizeof(Elf32_Ehdr
);
1272 /* all other sections come after */
1273 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1274 s
= s1
->sections
[i
];
1275 if (phnum
> 0 && (s
->sh_flags
& SHF_ALLOC
))
1277 section_order
[sh_order_index
++] = i
;
1279 file_offset
= (file_offset
+ s
->sh_addralign
- 1) &
1280 ~(s
->sh_addralign
- 1);
1281 s
->sh_offset
= file_offset
;
1282 if (s
->sh_type
!= SHT_NOBITS
)
1283 file_offset
+= s
->sh_size
;
1286 /* if building executable or DLL, then relocate each section
1287 except the GOT which is already relocated */
1288 if (file_type
!= TCC_OUTPUT_OBJ
) {
1289 relocate_syms(s1
, 0);
1291 if (s1
->nb_errors
!= 0) {
1297 /* relocate sections */
1298 /* XXX: ignore sections with allocated relocations ? */
1299 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1300 s
= s1
->sections
[i
];
1301 if (s
->reloc
&& s
!= s1
->got
)
1302 relocate_section(s1
, s
);
1305 /* relocate relocation entries if the relocation tables are
1306 allocated in the executable */
1307 for(i
= 1; i
< s1
->nb_sections
; i
++) {
1308 s
= s1
->sections
[i
];
1309 if ((s
->sh_flags
& SHF_ALLOC
) &&
1310 s
->sh_type
== SHT_REL
) {
1311 relocate_rel(s1
, s
);
1315 /* get entry point address */
1316 if (file_type
== TCC_OUTPUT_EXE
)
1317 ehdr
.e_entry
= (unsigned long)tcc_get_symbol(s1
, "_start");
1319 ehdr
.e_entry
= text_section
->sh_addr
; /* XXX: is it correct ? */
1322 sort_syms(s1
, symtab_section
);
1325 file_offset
= (file_offset
+ 3) & -4;
1328 ehdr
.e_ident
[0] = ELFMAG0
;
1329 ehdr
.e_ident
[1] = ELFMAG1
;
1330 ehdr
.e_ident
[2] = ELFMAG2
;
1331 ehdr
.e_ident
[3] = ELFMAG3
;
1332 ehdr
.e_ident
[4] = ELFCLASS32
;
1333 ehdr
.e_ident
[5] = ELFDATA2LSB
;
1334 ehdr
.e_ident
[6] = EV_CURRENT
;
1336 ehdr
.e_ident
[EI_OSABI
] = ELFOSABI_FREEBSD
;
1340 case TCC_OUTPUT_EXE
:
1341 ehdr
.e_type
= ET_EXEC
;
1343 case TCC_OUTPUT_DLL
:
1344 ehdr
.e_type
= ET_DYN
;
1346 case TCC_OUTPUT_OBJ
:
1347 ehdr
.e_type
= ET_REL
;
1350 ehdr
.e_machine
= EM_386
;
1351 ehdr
.e_version
= EV_CURRENT
;
1352 ehdr
.e_shoff
= file_offset
;
1353 ehdr
.e_ehsize
= sizeof(Elf32_Ehdr
);
1354 ehdr
.e_shentsize
= sizeof(Elf32_Shdr
);
1355 ehdr
.e_shnum
= shnum
;
1356 ehdr
.e_shstrndx
= shnum
- 1;
1358 /* write elf file */
1359 if (file_type
== TCC_OUTPUT_OBJ
)
1363 fd
= open(filename
, O_WRONLY
| O_CREAT
| O_TRUNC
, mode
);
1365 error_noabort("could not write '%s'", filename
);
1368 f
= fdopen(fd
, "w");
1369 fwrite(&ehdr
, 1, sizeof(Elf32_Ehdr
), f
);
1370 fwrite(phdr
, 1, phnum
* sizeof(Elf32_Phdr
), f
);
1371 offset
= sizeof(Elf32_Ehdr
) + phnum
* sizeof(Elf32_Phdr
);
1372 for(i
=1;i
<s1
->nb_sections
;i
++) {
1373 s
= s1
->sections
[section_order
[i
]];
1374 if (s
->sh_type
!= SHT_NOBITS
) {
1375 while (offset
< s
->sh_offset
) {
1380 fwrite(s
->data
, 1, size
, f
);
1384 while (offset
< ehdr
.e_shoff
) {
1389 /* output section headers */
1390 for(i
=0;i
<s1
->nb_sections
;i
++) {
1392 memset(sh
, 0, sizeof(Elf32_Shdr
));
1393 s
= s1
->sections
[i
];
1395 sh
->sh_name
= s
->sh_name
;
1396 sh
->sh_type
= s
->sh_type
;
1397 sh
->sh_flags
= s
->sh_flags
;
1398 sh
->sh_entsize
= s
->sh_entsize
;
1399 sh
->sh_info
= s
->sh_info
;
1401 sh
->sh_link
= s
->link
->sh_num
;
1402 sh
->sh_addralign
= s
->sh_addralign
;
1403 sh
->sh_addr
= s
->sh_addr
;
1404 sh
->sh_offset
= s
->sh_offset
;
1405 sh
->sh_size
= s
->sh_size
;
1407 fwrite(sh
, 1, sizeof(Elf32_Shdr
), f
);
1413 tcc_free(s1
->symtab_to_dynsym
);
1414 tcc_free(section_order
);
1416 tcc_free(s1
->got_offsets
);
1420 static void *load_data(int fd
, unsigned long file_offset
, unsigned long size
)
1424 data
= tcc_malloc(size
);
1425 lseek(fd
, file_offset
, SEEK_SET
);
1426 read(fd
, data
, size
);
1430 typedef struct SectionMergeInfo
{
1431 Section
*s
; /* corresponding existing section */
1432 unsigned long offset
; /* offset of the new section in the existing section */
1433 int new_section
; /* true if section 's' was added */
1436 /* load an object file and merge it with current files */
1437 /* XXX: handle correctly stab (debug) info */
1438 static int tcc_load_object_file(TCCState
*s1
,
1439 int fd
, unsigned long file_offset
)
1442 Elf32_Shdr
*shdr
, *sh
;
1443 int size
, i
, j
, offset
, offseti
, nb_syms
, sym_index
, ret
;
1444 unsigned char *strsec
, *strtab
;
1445 int *old_to_new_syms
;
1446 char *sh_name
, *name
;
1447 SectionMergeInfo
*sm_table
, *sm
;
1448 Elf32_Sym
*sym
, *symtab
;
1449 Elf32_Rel
*rel
, *rel_end
;
1452 if (read(fd
, &ehdr
, sizeof(ehdr
)) != sizeof(ehdr
))
1454 if (ehdr
.e_ident
[0] != ELFMAG0
||
1455 ehdr
.e_ident
[1] != ELFMAG1
||
1456 ehdr
.e_ident
[2] != ELFMAG2
||
1457 ehdr
.e_ident
[3] != ELFMAG3
)
1459 /* test if object file */
1460 if (ehdr
.e_type
!= ET_REL
)
1462 /* test CPU specific stuff */
1463 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
1464 ehdr
.e_machine
!= EM_386
) {
1466 error_noabort("invalid object file");
1470 shdr
= load_data(fd
, file_offset
+ ehdr
.e_shoff
,
1471 sizeof(Elf32_Shdr
) * ehdr
.e_shnum
);
1472 sm_table
= tcc_mallocz(sizeof(SectionMergeInfo
) * ehdr
.e_shnum
);
1474 /* load section names */
1475 sh
= &shdr
[ehdr
.e_shstrndx
];
1476 strsec
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1478 /* load symtab and strtab */
1479 old_to_new_syms
= NULL
;
1483 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1485 if (sh
->sh_type
== SHT_SYMTAB
) {
1487 error_noabort("object must contain only one symtab");
1492 nb_syms
= sh
->sh_size
/ sizeof(Elf32_Sym
);
1493 symtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1494 sm_table
[i
].s
= symtab_section
;
1496 /* now load strtab */
1497 sh
= &shdr
[sh
->sh_link
];
1498 strtab
= load_data(fd
, file_offset
+ sh
->sh_offset
, sh
->sh_size
);
1502 /* now examine each section and try to merge its content with the
1504 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1505 /* no need to examine section name strtab */
1506 if (i
== ehdr
.e_shstrndx
)
1509 sh_name
= strsec
+ sh
->sh_name
;
1510 /* ignore sections types we do not handle */
1511 if (sh
->sh_type
!= SHT_PROGBITS
&&
1512 sh
->sh_type
!= SHT_REL
&&
1513 sh
->sh_type
!= SHT_NOBITS
)
1515 if (sh
->sh_addralign
< 1)
1516 sh
->sh_addralign
= 1;
1517 /* find corresponding section, if any */
1518 for(j
= 1; j
< s1
->nb_sections
;j
++) {
1519 s
= s1
->sections
[j
];
1520 if (!strcmp(s
->name
, sh_name
))
1523 /* not found: create new section */
1524 s
= new_section(s1
, sh_name
, sh
->sh_type
, sh
->sh_flags
);
1525 /* take as much info as possible from the section. sh_link and
1526 sh_info will be updated later */
1527 s
->sh_addralign
= sh
->sh_addralign
;
1528 s
->sh_entsize
= sh
->sh_entsize
;
1529 sm_table
[i
].new_section
= 1;
1531 if (sh
->sh_type
!= s
->sh_type
) {
1532 error_noabort("invalid section type");
1536 /* align start of section */
1537 offset
= s
->data_offset
;
1538 size
= sh
->sh_addralign
- 1;
1539 offset
= (offset
+ size
) & ~size
;
1540 if (sh
->sh_addralign
> s
->sh_addralign
)
1541 s
->sh_addralign
= sh
->sh_addralign
;
1542 s
->data_offset
= offset
;
1543 sm_table
[i
].offset
= offset
;
1545 /* concatenate sections */
1547 if (sh
->sh_type
!= SHT_NOBITS
) {
1549 lseek(fd
, file_offset
+ sh
->sh_offset
, SEEK_SET
);
1550 ptr
= section_ptr_add(s
, size
);
1551 read(fd
, ptr
, size
);
1553 s
->data_offset
+= size
;
1557 /* second short pass to update sh_link and sh_info fields of new
1560 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1562 if (!s
|| !sm_table
[i
].new_section
)
1565 if (sh
->sh_link
> 0)
1566 s
->link
= sm_table
[sh
->sh_link
].s
;
1567 if (sh
->sh_type
== SHT_REL
) {
1568 s
->sh_info
= sm_table
[sh
->sh_info
].s
->sh_num
;
1569 /* update backward link */
1570 s1
->sections
[s
->sh_info
]->reloc
= s
;
1574 /* resolve symbols */
1575 old_to_new_syms
= tcc_mallocz(nb_syms
* sizeof(int));
1578 for(i
= 1; i
< nb_syms
; i
++, sym
++) {
1579 if (sym
->st_shndx
!= SHN_UNDEF
&&
1580 sym
->st_shndx
< SHN_LORESERVE
) {
1581 sm
= &sm_table
[sym
->st_shndx
];
1582 /* if no corresponding section added, no need to add symbol */
1585 /* convert section number */
1586 sym
->st_shndx
= sm
->s
->sh_num
;
1588 sym
->st_value
+= sm
->offset
;
1591 name
= strtab
+ sym
->st_name
;
1592 sym_index
= add_elf_sym(symtab_section
, sym
->st_value
, sym
->st_size
,
1593 sym
->st_info
, sym
->st_shndx
, name
);
1594 old_to_new_syms
[i
] = sym_index
;
1597 /* third pass to patch relocation entries */
1598 for(i
= 1; i
< ehdr
.e_shnum
; i
++) {
1603 offset
= sm_table
[i
].offset
;
1604 switch(s
->sh_type
) {
1606 /* take relocation offset information */
1607 offseti
= sm_table
[sh
->sh_info
].offset
;
1608 rel_end
= (Elf32_Rel
*)(s
->data
+ s
->data_offset
);
1609 for(rel
= (Elf32_Rel
*)(s
->data
+ offset
);
1614 /* convert symbol index */
1615 type
= ELF32_R_TYPE(rel
->r_info
);
1616 sym_index
= ELF32_R_SYM(rel
->r_info
);
1617 /* NOTE: only one symtab assumed */
1618 if (sym_index
>= nb_syms
)
1620 sym_index
= old_to_new_syms
[sym_index
];
1623 error_noabort("Invalid relocation entry");
1626 rel
->r_info
= ELF32_R_INFO(sym_index
, type
);
1627 /* offset the relocation offset */
1628 rel
->r_offset
+= offseti
;
1640 tcc_free(old_to_new_syms
);
1647 #define ARMAG "!<arch>\012" /* For COFF and a.out archives */
1649 typedef struct ArchiveHeader
{
1650 char ar_name
[16]; /* name of this member */
1651 char ar_date
[12]; /* file mtime */
1652 char ar_uid
[6]; /* owner uid; printed as decimal */
1653 char ar_gid
[6]; /* owner gid; printed as decimal */
1654 char ar_mode
[8]; /* file mode, printed as octal */
1655 char ar_size
[10]; /* file size, printed as decimal */
1656 char ar_fmag
[2]; /* should contain ARFMAG */
1659 /* load a '.a' file */
1660 static int tcc_load_archive(TCCState
*s1
, int fd
)
1667 unsigned long file_offset
;
1669 /* skip magic which was already checked */
1670 read(fd
, magic
, sizeof(magic
));
1673 len
= read(fd
, &hdr
, sizeof(hdr
));
1676 if (len
!= sizeof(hdr
)) {
1677 error_noabort("invalid archive");
1680 memcpy(ar_size
, hdr
.ar_size
, sizeof(hdr
.ar_size
));
1681 ar_size
[sizeof(hdr
.ar_size
)] = '\0';
1682 size
= strtol(ar_size
, NULL
, 0);
1683 memcpy(ar_name
, hdr
.ar_name
, sizeof(hdr
.ar_name
));
1684 for(i
= sizeof(hdr
.ar_name
) - 1; i
>= 0; i
--) {
1685 if (ar_name
[i
] != ' ')
1688 ar_name
[i
+ 1] = '\0';
1689 // printf("name='%s' size=%d %s\n", ar_name, size, ar_size);
1690 file_offset
= lseek(fd
, 0, SEEK_CUR
);
1691 if (!strcmp(ar_name
, "/") ||
1692 !strcmp(ar_name
, "//") ||
1693 !strcmp(ar_name
, "__.SYMDEF") ||
1694 !strcmp(ar_name
, "__.SYMDEF/") ||
1695 !strcmp(ar_name
, "ARFILENAMES/")) {
1696 /* skip symbol table or archive names */
1698 if (tcc_load_object_file(s1
, fd
, file_offset
) < 0)
1702 size
= (size
+ 1) & ~1;
1703 lseek(fd
, file_offset
+ size
, SEEK_SET
);
1708 /* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
1709 is referenced by the user (so it should be added as DT_NEEDED in
1710 the generated ELF file) */
1711 static int tcc_load_dll(TCCState
*s1
, int fd
, const char *filename
, int level
)
1714 Elf32_Shdr
*shdr
, *sh
, *sh1
;
1715 int i
, nb_syms
, nb_dts
, sym_bind
, ret
;
1716 Elf32_Sym
*sym
, *dynsym
;
1717 Elf32_Dyn
*dt
, *dynamic
;
1718 unsigned char *dynstr
;
1719 const char *name
, *soname
, *p
;
1720 DLLReference
*dllref
;
1722 read(fd
, &ehdr
, sizeof(ehdr
));
1724 /* test CPU specific stuff */
1725 if (ehdr
.e_ident
[5] != ELFDATA2LSB
||
1726 ehdr
.e_machine
!= EM_386
) {
1727 error_noabort("bad architecture");
1732 shdr
= load_data(fd
, ehdr
.e_shoff
, sizeof(Elf32_Shdr
) * ehdr
.e_shnum
);
1734 /* load dynamic section and dynamic symbols */
1738 dynsym
= NULL
; /* avoid warning */
1739 dynstr
= NULL
; /* avoid warning */
1740 for(i
= 0, sh
= shdr
; i
< ehdr
.e_shnum
; i
++, sh
++) {
1741 switch(sh
->sh_type
) {
1743 nb_dts
= sh
->sh_size
/ sizeof(Elf32_Dyn
);
1744 dynamic
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
1747 nb_syms
= sh
->sh_size
/ sizeof(Elf32_Sym
);
1748 dynsym
= load_data(fd
, sh
->sh_offset
, sh
->sh_size
);
1749 sh1
= &shdr
[sh
->sh_link
];
1750 dynstr
= load_data(fd
, sh1
->sh_offset
, sh1
->sh_size
);
1757 /* compute the real library name */
1759 p
= strrchr(soname
, '/');
1763 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
1764 if (dt
->d_tag
== DT_SONAME
) {
1765 soname
= dynstr
+ dt
->d_un
.d_val
;
1769 /* if the dll is already loaded, do not load it */
1770 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1771 dllref
= s1
->loaded_dlls
[i
];
1772 if (!strcmp(soname
, dllref
->name
)) {
1773 /* but update level if needed */
1774 if (level
< dllref
->level
)
1775 dllref
->level
= level
;
1781 // printf("loading dll '%s'\n", soname);
1783 /* add the dll and its level */
1784 dllref
= tcc_malloc(sizeof(DLLReference
) + strlen(soname
));
1785 dllref
->level
= level
;
1786 strcpy(dllref
->name
, soname
);
1787 dynarray_add((void ***)&s1
->loaded_dlls
, &s1
->nb_loaded_dlls
, dllref
);
1789 /* add dynamic symbols in dynsym_section */
1790 for(i
= 1, sym
= dynsym
+ 1; i
< nb_syms
; i
++, sym
++) {
1791 sym_bind
= ELF32_ST_BIND(sym
->st_info
);
1792 if (sym_bind
== STB_LOCAL
)
1794 name
= dynstr
+ sym
->st_name
;
1795 add_elf_sym(s1
->dynsymtab_section
, sym
->st_value
, sym
->st_size
,
1796 sym
->st_info
, sym
->st_shndx
, name
);
1799 /* load all referenced DLLs */
1800 for(i
= 0, dt
= dynamic
; i
< nb_dts
; i
++, dt
++) {
1803 name
= dynstr
+ dt
->d_un
.d_val
;
1804 for(i
= 0; i
< s1
->nb_loaded_dlls
; i
++) {
1805 dllref
= s1
->loaded_dlls
[i
];
1806 if (!strcmp(name
, dllref
->name
))
1807 goto already_loaded
;
1809 if (tcc_add_dll(s1
, name
, AFF_REFERENCED_DLL
) < 0) {
1810 error_noabort("referenced dll '%s' not found", name
);
1827 #define LD_TOK_NAME 256
1828 #define LD_TOK_EOF (-1)
1830 /* return next ld script token */
1831 static int ld_next(TCCState
*s1
, char *name
, int name_size
)
1867 if (!((ch
>= 'a' && ch
<= 'z') ||
1868 (ch
>= 'A' && ch
<= 'Z') ||
1869 (ch
>= '0' && ch
<= '9') ||
1870 strchr("/.-_+=$:\\,~", ch
)))
1872 if ((q
- name
) < name_size
- 1) {
1889 printf("tok=%c %d\n", c
, c
);
1890 if (c
== LD_TOK_NAME
)
1891 printf(" name=%s\n", name
);
1896 /* interpret a subset of GNU ldscripts to handle the dummy libc.so
1898 static int tcc_load_ldscript(TCCState
*s1
)
1901 char filename
[1024];
1904 ch
= file
->buf_ptr
[0];
1907 t
= ld_next(s1
, cmd
, sizeof(cmd
));
1908 if (t
== LD_TOK_EOF
)
1910 else if (t
!= LD_TOK_NAME
)
1912 if (!strcmp(cmd
, "INPUT") ||
1913 !strcmp(cmd
, "GROUP")) {
1914 t
= ld_next(s1
, cmd
, sizeof(cmd
));
1917 t
= ld_next(s1
, filename
, sizeof(filename
));
1919 if (t
== LD_TOK_EOF
) {
1920 error_noabort("unexpected end of file");
1922 } else if (t
== ')') {
1924 } else if (t
!= LD_TOK_NAME
) {
1925 error_noabort("filename expected");
1928 tcc_add_file(s1
, filename
);
1929 t
= ld_next(s1
, filename
, sizeof(filename
));
1931 t
= ld_next(s1
, filename
, sizeof(filename
));