elfcode.h revision 38889
133965Sjdp/* ELF executable support for BFD. 238889Sjdp Copyright 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. 333965Sjdp 433965Sjdp Written by Fred Fish @ Cygnus Support, from information published 533965Sjdp in "UNIX System V Release 4, Programmers Guide: ANSI C and 633965Sjdp Programming Support Tools". Sufficient support for gdb. 733965Sjdp 833965Sjdp Rewritten by Mark Eichin @ Cygnus Support, from information 933965Sjdp published in "System V Application Binary Interface", chapters 4 1033965Sjdp and 5, as well as the various "Processor Supplement" documents 1133965Sjdp derived from it. Added support for assembler and other object file 1233965Sjdp utilities. Further work done by Ken Raeburn (Cygnus Support), Michael 1333965Sjdp Meissner (Open Software Foundation), and Peter Hoogenboom (University 1433965Sjdp of Utah) to finish and extend this. 1533965Sjdp 1633965SjdpThis file is part of BFD, the Binary File Descriptor library. 1733965Sjdp 1833965SjdpThis program is free software; you can redistribute it and/or modify 1933965Sjdpit under the terms of the GNU General Public License as published by 2033965Sjdpthe Free Software Foundation; either version 2 of the License, or 2133965Sjdp(at your option) any later version. 2233965Sjdp 2333965SjdpThis program is distributed in the hope that it will be useful, 2433965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 2533965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2633965SjdpGNU General Public License for more details. 2733965Sjdp 2833965SjdpYou should have received a copy of the GNU General Public License 2933965Sjdpalong with this program; if not, write to the Free Software 3033965SjdpFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 3133965Sjdp 3233965Sjdp/* Problems and other issues to resolve. 3333965Sjdp 3433965Sjdp (1) BFD expects there to be some fixed number of "sections" in 3533965Sjdp the object file. I.E. there is a "section_count" variable in the 3633965Sjdp bfd structure which contains the number of sections. However, ELF 3733965Sjdp supports multiple "views" of a file. In particular, with current 3833965Sjdp implementations, executable files typically have two tables, a 3933965Sjdp program header table and a section header table, both of which 4033965Sjdp partition the executable. 4133965Sjdp 4233965Sjdp In ELF-speak, the "linking view" of the file uses the section header 4333965Sjdp table to access "sections" within the file, and the "execution view" 4433965Sjdp uses the program header table to access "segments" within the file. 4533965Sjdp "Segments" typically may contain all the data from one or more 4633965Sjdp "sections". 4733965Sjdp 4833965Sjdp Note that the section header table is optional in ELF executables, 4933965Sjdp but it is this information that is most useful to gdb. If the 5033965Sjdp section header table is missing, then gdb should probably try 5133965Sjdp to make do with the program header table. (FIXME) 5233965Sjdp 5333965Sjdp (2) The code in this file is compiled twice, once in 32-bit mode and 5433965Sjdp once in 64-bit mode. More of it should be made size-independent 5533965Sjdp and moved into elf.c. 5633965Sjdp 5733965Sjdp (3) ELF section symbols are handled rather sloppily now. This should 5833965Sjdp be cleaned up, and ELF section symbols reconciled with BFD section 5933965Sjdp symbols. 6033965Sjdp 6133965Sjdp (4) We need a published spec for 64-bit ELF. We've got some stuff here 6233965Sjdp that we're using for SPARC V9 64-bit chips, but don't assume that 6333965Sjdp it's cast in stone. 6433965Sjdp */ 6533965Sjdp 6633965Sjdp#include "bfd.h" 6733965Sjdp#include "sysdep.h" 6833965Sjdp#include "bfdlink.h" 6933965Sjdp#include "libbfd.h" 7033965Sjdp#include "elf-bfd.h" 7133965Sjdp#include "fnmatch.h" 7233965Sjdp 7333965Sjdp/* Renaming structures, typedefs, macros and functions to be size-specific. */ 7433965Sjdp#define Elf_External_Ehdr NAME(Elf,External_Ehdr) 7533965Sjdp#define Elf_External_Sym NAME(Elf,External_Sym) 7633965Sjdp#define Elf_External_Shdr NAME(Elf,External_Shdr) 7733965Sjdp#define Elf_External_Phdr NAME(Elf,External_Phdr) 7833965Sjdp#define Elf_External_Rel NAME(Elf,External_Rel) 7933965Sjdp#define Elf_External_Rela NAME(Elf,External_Rela) 8033965Sjdp#define Elf_External_Dyn NAME(Elf,External_Dyn) 8133965Sjdp 8233965Sjdp#define elf_core_file_failing_command NAME(bfd_elf,core_file_failing_command) 8333965Sjdp#define elf_core_file_failing_signal NAME(bfd_elf,core_file_failing_signal) 8433965Sjdp#define elf_core_file_matches_executable_p \ 8533965Sjdp NAME(bfd_elf,core_file_matches_executable_p) 8633965Sjdp#define elf_object_p NAME(bfd_elf,object_p) 8733965Sjdp#define elf_core_file_p NAME(bfd_elf,core_file_p) 8833965Sjdp#define elf_get_symtab_upper_bound NAME(bfd_elf,get_symtab_upper_bound) 8933965Sjdp#define elf_get_dynamic_symtab_upper_bound \ 9033965Sjdp NAME(bfd_elf,get_dynamic_symtab_upper_bound) 9133965Sjdp#define elf_swap_reloc_in NAME(bfd_elf,swap_reloc_in) 9233965Sjdp#define elf_swap_reloca_in NAME(bfd_elf,swap_reloca_in) 9333965Sjdp#define elf_swap_reloc_out NAME(bfd_elf,swap_reloc_out) 9433965Sjdp#define elf_swap_reloca_out NAME(bfd_elf,swap_reloca_out) 9533965Sjdp#define elf_swap_symbol_in NAME(bfd_elf,swap_symbol_in) 9633965Sjdp#define elf_swap_symbol_out NAME(bfd_elf,swap_symbol_out) 9733965Sjdp#define elf_swap_phdr_in NAME(bfd_elf,swap_phdr_in) 9833965Sjdp#define elf_swap_phdr_out NAME(bfd_elf,swap_phdr_out) 9933965Sjdp#define elf_swap_dyn_in NAME(bfd_elf,swap_dyn_in) 10033965Sjdp#define elf_swap_dyn_out NAME(bfd_elf,swap_dyn_out) 10133965Sjdp#define elf_get_reloc_upper_bound NAME(bfd_elf,get_reloc_upper_bound) 10233965Sjdp#define elf_canonicalize_reloc NAME(bfd_elf,canonicalize_reloc) 10333965Sjdp#define elf_slurp_symbol_table NAME(bfd_elf,slurp_symbol_table) 10433965Sjdp#define elf_get_symtab NAME(bfd_elf,get_symtab) 10533965Sjdp#define elf_canonicalize_dynamic_symtab \ 10633965Sjdp NAME(bfd_elf,canonicalize_dynamic_symtab) 10733965Sjdp#define elf_make_empty_symbol NAME(bfd_elf,make_empty_symbol) 10833965Sjdp#define elf_get_symbol_info NAME(bfd_elf,get_symbol_info) 10933965Sjdp#define elf_get_lineno NAME(bfd_elf,get_lineno) 11033965Sjdp#define elf_set_arch_mach NAME(bfd_elf,set_arch_mach) 11133965Sjdp#define elf_find_nearest_line NAME(bfd_elf,find_nearest_line) 11233965Sjdp#define elf_sizeof_headers NAME(bfd_elf,sizeof_headers) 11333965Sjdp#define elf_set_section_contents NAME(bfd_elf,set_section_contents) 11433965Sjdp#define elf_no_info_to_howto NAME(bfd_elf,no_info_to_howto) 11533965Sjdp#define elf_no_info_to_howto_rel NAME(bfd_elf,no_info_to_howto_rel) 11633965Sjdp#define elf_find_section NAME(bfd_elf,find_section) 11733965Sjdp#define elf_bfd_link_add_symbols NAME(bfd_elf,bfd_link_add_symbols) 11833965Sjdp#define elf_add_dynamic_entry NAME(bfd_elf,add_dynamic_entry) 11933965Sjdp#define elf_write_shdrs_and_ehdr NAME(bfd_elf,write_shdrs_and_ehdr) 12033965Sjdp#define elf_write_out_phdrs NAME(bfd_elf,write_out_phdrs) 12133965Sjdp#define elf_link_create_dynamic_sections \ 12233965Sjdp NAME(bfd_elf,link_create_dynamic_sections) 12333965Sjdp#define elf_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol 12433965Sjdp#define elf_bfd_final_link NAME(bfd_elf,bfd_final_link) 12533965Sjdp#define elf_create_pointer_linker_section NAME(bfd_elf,create_pointer_linker_section) 12633965Sjdp#define elf_finish_pointer_linker_section NAME(bfd_elf,finish_pointer_linker_section) 12733965Sjdp 12833965Sjdp#if ARCH_SIZE == 64 12933965Sjdp#define ELF_R_INFO(X,Y) ELF64_R_INFO(X,Y) 13033965Sjdp#define ELF_R_SYM(X) ELF64_R_SYM(X) 13133965Sjdp#define ELF_R_TYPE(X) ELF64_R_TYPE(X) 13233965Sjdp#define ELFCLASS ELFCLASS64 13333965Sjdp#define FILE_ALIGN 8 13433965Sjdp#define LOG_FILE_ALIGN 3 13533965Sjdp#endif 13633965Sjdp#if ARCH_SIZE == 32 13733965Sjdp#define ELF_R_INFO(X,Y) ELF32_R_INFO(X,Y) 13833965Sjdp#define ELF_R_SYM(X) ELF32_R_SYM(X) 13933965Sjdp#define ELF_R_TYPE(X) ELF32_R_TYPE(X) 14033965Sjdp#define ELFCLASS ELFCLASS32 14133965Sjdp#define FILE_ALIGN 4 14233965Sjdp#define LOG_FILE_ALIGN 2 14333965Sjdp#endif 14433965Sjdp 14533965Sjdp/* Static functions */ 14633965Sjdp 14733965Sjdpstatic void elf_swap_ehdr_in 14833965Sjdp PARAMS ((bfd *, const Elf_External_Ehdr *, Elf_Internal_Ehdr *)); 14933965Sjdpstatic void elf_swap_ehdr_out 15033965Sjdp PARAMS ((bfd *, const Elf_Internal_Ehdr *, Elf_External_Ehdr *)); 15133965Sjdpstatic void elf_swap_shdr_in 15233965Sjdp PARAMS ((bfd *, const Elf_External_Shdr *, Elf_Internal_Shdr *)); 15333965Sjdpstatic void elf_swap_shdr_out 15433965Sjdp PARAMS ((bfd *, const Elf_Internal_Shdr *, Elf_External_Shdr *)); 15533965Sjdp 15633965Sjdp#define elf_stringtab_init _bfd_elf_stringtab_init 15733965Sjdp 15833965Sjdp#define section_from_elf_index bfd_section_from_elf_index 15933965Sjdp 16033965Sjdpstatic boolean elf_slurp_reloc_table 16133965Sjdp PARAMS ((bfd *, asection *, asymbol **, boolean)); 16233965Sjdp 16333965Sjdpstatic void write_relocs PARAMS ((bfd *, asection *, PTR)); 16433965Sjdp 16533965Sjdpstatic boolean elf_file_p PARAMS ((Elf_External_Ehdr *)); 16633965Sjdp 16733965Sjdp#ifdef DEBUG 16833965Sjdpstatic void elf_debug_section PARAMS ((int, Elf_Internal_Shdr *)); 16933965Sjdpstatic void elf_debug_file PARAMS ((Elf_Internal_Ehdr *)); 17033965Sjdpstatic char *elf_symbol_flags PARAMS ((flagword)); 17133965Sjdp#endif 17233965Sjdp 17333965Sjdp/* Structure swapping routines */ 17433965Sjdp 17533965Sjdp/* Should perhaps use put_offset, put_word, etc. For now, the two versions 17633965Sjdp can be handled by explicitly specifying 32 bits or "the long type". */ 17733965Sjdp#if ARCH_SIZE == 64 17833965Sjdp#define put_word bfd_h_put_64 17938889Sjdp#define put_signed_word bfd_h_put_signed_64 18033965Sjdp#define get_word bfd_h_get_64 18138889Sjdp#define get_signed_word bfd_h_get_signed_64 18233965Sjdp#endif 18333965Sjdp#if ARCH_SIZE == 32 18433965Sjdp#define put_word bfd_h_put_32 18538889Sjdp#define put_signed_word bfd_h_put_signed_32 18633965Sjdp#define get_word bfd_h_get_32 18738889Sjdp#define get_signed_word bfd_h_get_signed_32 18833965Sjdp#endif 18933965Sjdp 19033965Sjdp/* Translate an ELF symbol in external format into an ELF symbol in internal 19133965Sjdp format. */ 19233965Sjdp 19333965Sjdpvoid 19433965Sjdpelf_swap_symbol_in (abfd, src, dst) 19533965Sjdp bfd *abfd; 19633965Sjdp const Elf_External_Sym *src; 19733965Sjdp Elf_Internal_Sym *dst; 19833965Sjdp{ 19933965Sjdp dst->st_name = bfd_h_get_32 (abfd, (bfd_byte *) src->st_name); 20033965Sjdp dst->st_value = get_word (abfd, (bfd_byte *) src->st_value); 20133965Sjdp dst->st_size = get_word (abfd, (bfd_byte *) src->st_size); 20233965Sjdp dst->st_info = bfd_h_get_8 (abfd, (bfd_byte *) src->st_info); 20333965Sjdp dst->st_other = bfd_h_get_8 (abfd, (bfd_byte *) src->st_other); 20433965Sjdp dst->st_shndx = bfd_h_get_16 (abfd, (bfd_byte *) src->st_shndx); 20533965Sjdp} 20633965Sjdp 20733965Sjdp/* Translate an ELF symbol in internal format into an ELF symbol in external 20833965Sjdp format. */ 20933965Sjdp 21033965Sjdpvoid 21133965Sjdpelf_swap_symbol_out (abfd, src, cdst) 21233965Sjdp bfd *abfd; 21333965Sjdp const Elf_Internal_Sym *src; 21433965Sjdp PTR cdst; 21533965Sjdp{ 21633965Sjdp Elf_External_Sym *dst = (Elf_External_Sym *) cdst; 21733965Sjdp bfd_h_put_32 (abfd, src->st_name, dst->st_name); 21833965Sjdp put_word (abfd, src->st_value, dst->st_value); 21933965Sjdp put_word (abfd, src->st_size, dst->st_size); 22033965Sjdp bfd_h_put_8 (abfd, src->st_info, dst->st_info); 22133965Sjdp bfd_h_put_8 (abfd, src->st_other, dst->st_other); 22233965Sjdp bfd_h_put_16 (abfd, src->st_shndx, dst->st_shndx); 22333965Sjdp} 22433965Sjdp 22533965Sjdp 22633965Sjdp/* Translate an ELF file header in external format into an ELF file header in 22733965Sjdp internal format. */ 22833965Sjdp 22933965Sjdpstatic void 23033965Sjdpelf_swap_ehdr_in (abfd, src, dst) 23133965Sjdp bfd *abfd; 23233965Sjdp const Elf_External_Ehdr *src; 23333965Sjdp Elf_Internal_Ehdr *dst; 23433965Sjdp{ 23533965Sjdp memcpy (dst->e_ident, src->e_ident, EI_NIDENT); 23633965Sjdp dst->e_type = bfd_h_get_16 (abfd, (bfd_byte *) src->e_type); 23733965Sjdp dst->e_machine = bfd_h_get_16 (abfd, (bfd_byte *) src->e_machine); 23833965Sjdp dst->e_version = bfd_h_get_32 (abfd, (bfd_byte *) src->e_version); 23933965Sjdp dst->e_entry = get_word (abfd, (bfd_byte *) src->e_entry); 24033965Sjdp dst->e_phoff = get_word (abfd, (bfd_byte *) src->e_phoff); 24133965Sjdp dst->e_shoff = get_word (abfd, (bfd_byte *) src->e_shoff); 24233965Sjdp dst->e_flags = bfd_h_get_32 (abfd, (bfd_byte *) src->e_flags); 24333965Sjdp dst->e_ehsize = bfd_h_get_16 (abfd, (bfd_byte *) src->e_ehsize); 24433965Sjdp dst->e_phentsize = bfd_h_get_16 (abfd, (bfd_byte *) src->e_phentsize); 24533965Sjdp dst->e_phnum = bfd_h_get_16 (abfd, (bfd_byte *) src->e_phnum); 24633965Sjdp dst->e_shentsize = bfd_h_get_16 (abfd, (bfd_byte *) src->e_shentsize); 24733965Sjdp dst->e_shnum = bfd_h_get_16 (abfd, (bfd_byte *) src->e_shnum); 24833965Sjdp dst->e_shstrndx = bfd_h_get_16 (abfd, (bfd_byte *) src->e_shstrndx); 24933965Sjdp} 25033965Sjdp 25133965Sjdp/* Translate an ELF file header in internal format into an ELF file header in 25233965Sjdp external format. */ 25333965Sjdp 25433965Sjdpstatic void 25533965Sjdpelf_swap_ehdr_out (abfd, src, dst) 25633965Sjdp bfd *abfd; 25733965Sjdp const Elf_Internal_Ehdr *src; 25833965Sjdp Elf_External_Ehdr *dst; 25933965Sjdp{ 26033965Sjdp memcpy (dst->e_ident, src->e_ident, EI_NIDENT); 26133965Sjdp /* note that all elements of dst are *arrays of unsigned char* already... */ 26233965Sjdp bfd_h_put_16 (abfd, src->e_type, dst->e_type); 26333965Sjdp bfd_h_put_16 (abfd, src->e_machine, dst->e_machine); 26433965Sjdp bfd_h_put_32 (abfd, src->e_version, dst->e_version); 26533965Sjdp put_word (abfd, src->e_entry, dst->e_entry); 26633965Sjdp put_word (abfd, src->e_phoff, dst->e_phoff); 26733965Sjdp put_word (abfd, src->e_shoff, dst->e_shoff); 26833965Sjdp bfd_h_put_32 (abfd, src->e_flags, dst->e_flags); 26933965Sjdp bfd_h_put_16 (abfd, src->e_ehsize, dst->e_ehsize); 27033965Sjdp bfd_h_put_16 (abfd, src->e_phentsize, dst->e_phentsize); 27133965Sjdp bfd_h_put_16 (abfd, src->e_phnum, dst->e_phnum); 27233965Sjdp bfd_h_put_16 (abfd, src->e_shentsize, dst->e_shentsize); 27333965Sjdp bfd_h_put_16 (abfd, src->e_shnum, dst->e_shnum); 27433965Sjdp bfd_h_put_16 (abfd, src->e_shstrndx, dst->e_shstrndx); 27533965Sjdp} 27633965Sjdp 27733965Sjdp 27833965Sjdp/* Translate an ELF section header table entry in external format into an 27933965Sjdp ELF section header table entry in internal format. */ 28033965Sjdp 28133965Sjdpstatic void 28233965Sjdpelf_swap_shdr_in (abfd, src, dst) 28333965Sjdp bfd *abfd; 28433965Sjdp const Elf_External_Shdr *src; 28533965Sjdp Elf_Internal_Shdr *dst; 28633965Sjdp{ 28733965Sjdp dst->sh_name = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_name); 28833965Sjdp dst->sh_type = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_type); 28933965Sjdp dst->sh_flags = get_word (abfd, (bfd_byte *) src->sh_flags); 29033965Sjdp dst->sh_addr = get_word (abfd, (bfd_byte *) src->sh_addr); 29133965Sjdp dst->sh_offset = get_word (abfd, (bfd_byte *) src->sh_offset); 29233965Sjdp dst->sh_size = get_word (abfd, (bfd_byte *) src->sh_size); 29333965Sjdp dst->sh_link = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_link); 29433965Sjdp dst->sh_info = bfd_h_get_32 (abfd, (bfd_byte *) src->sh_info); 29533965Sjdp dst->sh_addralign = get_word (abfd, (bfd_byte *) src->sh_addralign); 29633965Sjdp dst->sh_entsize = get_word (abfd, (bfd_byte *) src->sh_entsize); 29733965Sjdp dst->bfd_section = NULL; 29833965Sjdp dst->contents = NULL; 29933965Sjdp} 30033965Sjdp 30133965Sjdp/* Translate an ELF section header table entry in internal format into an 30233965Sjdp ELF section header table entry in external format. */ 30333965Sjdp 30433965Sjdpstatic void 30533965Sjdpelf_swap_shdr_out (abfd, src, dst) 30633965Sjdp bfd *abfd; 30733965Sjdp const Elf_Internal_Shdr *src; 30833965Sjdp Elf_External_Shdr *dst; 30933965Sjdp{ 31033965Sjdp /* note that all elements of dst are *arrays of unsigned char* already... */ 31133965Sjdp bfd_h_put_32 (abfd, src->sh_name, dst->sh_name); 31233965Sjdp bfd_h_put_32 (abfd, src->sh_type, dst->sh_type); 31333965Sjdp put_word (abfd, src->sh_flags, dst->sh_flags); 31433965Sjdp put_word (abfd, src->sh_addr, dst->sh_addr); 31533965Sjdp put_word (abfd, src->sh_offset, dst->sh_offset); 31633965Sjdp put_word (abfd, src->sh_size, dst->sh_size); 31733965Sjdp bfd_h_put_32 (abfd, src->sh_link, dst->sh_link); 31833965Sjdp bfd_h_put_32 (abfd, src->sh_info, dst->sh_info); 31933965Sjdp put_word (abfd, src->sh_addralign, dst->sh_addralign); 32033965Sjdp put_word (abfd, src->sh_entsize, dst->sh_entsize); 32133965Sjdp} 32233965Sjdp 32333965Sjdp 32433965Sjdp/* Translate an ELF program header table entry in external format into an 32533965Sjdp ELF program header table entry in internal format. */ 32633965Sjdp 32733965Sjdpvoid 32833965Sjdpelf_swap_phdr_in (abfd, src, dst) 32933965Sjdp bfd *abfd; 33033965Sjdp const Elf_External_Phdr *src; 33133965Sjdp Elf_Internal_Phdr *dst; 33233965Sjdp{ 33333965Sjdp dst->p_type = bfd_h_get_32 (abfd, (bfd_byte *) src->p_type); 33433965Sjdp dst->p_flags = bfd_h_get_32 (abfd, (bfd_byte *) src->p_flags); 33533965Sjdp dst->p_offset = get_word (abfd, (bfd_byte *) src->p_offset); 33633965Sjdp dst->p_vaddr = get_word (abfd, (bfd_byte *) src->p_vaddr); 33733965Sjdp dst->p_paddr = get_word (abfd, (bfd_byte *) src->p_paddr); 33833965Sjdp dst->p_filesz = get_word (abfd, (bfd_byte *) src->p_filesz); 33933965Sjdp dst->p_memsz = get_word (abfd, (bfd_byte *) src->p_memsz); 34033965Sjdp dst->p_align = get_word (abfd, (bfd_byte *) src->p_align); 34133965Sjdp} 34233965Sjdp 34333965Sjdpvoid 34433965Sjdpelf_swap_phdr_out (abfd, src, dst) 34533965Sjdp bfd *abfd; 34633965Sjdp const Elf_Internal_Phdr *src; 34733965Sjdp Elf_External_Phdr *dst; 34833965Sjdp{ 34933965Sjdp /* note that all elements of dst are *arrays of unsigned char* already... */ 35033965Sjdp bfd_h_put_32 (abfd, src->p_type, dst->p_type); 35133965Sjdp put_word (abfd, src->p_offset, dst->p_offset); 35233965Sjdp put_word (abfd, src->p_vaddr, dst->p_vaddr); 35333965Sjdp put_word (abfd, src->p_paddr, dst->p_paddr); 35433965Sjdp put_word (abfd, src->p_filesz, dst->p_filesz); 35533965Sjdp put_word (abfd, src->p_memsz, dst->p_memsz); 35633965Sjdp bfd_h_put_32 (abfd, src->p_flags, dst->p_flags); 35733965Sjdp put_word (abfd, src->p_align, dst->p_align); 35833965Sjdp} 35933965Sjdp 36033965Sjdp/* Translate an ELF reloc from external format to internal format. */ 36133965SjdpINLINE void 36233965Sjdpelf_swap_reloc_in (abfd, src, dst) 36333965Sjdp bfd *abfd; 36433965Sjdp const Elf_External_Rel *src; 36533965Sjdp Elf_Internal_Rel *dst; 36633965Sjdp{ 36733965Sjdp dst->r_offset = get_word (abfd, (bfd_byte *) src->r_offset); 36833965Sjdp dst->r_info = get_word (abfd, (bfd_byte *) src->r_info); 36933965Sjdp} 37033965Sjdp 37133965SjdpINLINE void 37233965Sjdpelf_swap_reloca_in (abfd, src, dst) 37333965Sjdp bfd *abfd; 37433965Sjdp const Elf_External_Rela *src; 37533965Sjdp Elf_Internal_Rela *dst; 37633965Sjdp{ 37733965Sjdp dst->r_offset = get_word (abfd, (bfd_byte *) src->r_offset); 37833965Sjdp dst->r_info = get_word (abfd, (bfd_byte *) src->r_info); 37938889Sjdp dst->r_addend = get_signed_word (abfd, (bfd_byte *) src->r_addend); 38033965Sjdp} 38133965Sjdp 38233965Sjdp/* Translate an ELF reloc from internal format to external format. */ 38333965SjdpINLINE void 38433965Sjdpelf_swap_reloc_out (abfd, src, dst) 38533965Sjdp bfd *abfd; 38633965Sjdp const Elf_Internal_Rel *src; 38733965Sjdp Elf_External_Rel *dst; 38833965Sjdp{ 38933965Sjdp put_word (abfd, src->r_offset, dst->r_offset); 39033965Sjdp put_word (abfd, src->r_info, dst->r_info); 39133965Sjdp} 39233965Sjdp 39333965SjdpINLINE void 39433965Sjdpelf_swap_reloca_out (abfd, src, dst) 39533965Sjdp bfd *abfd; 39633965Sjdp const Elf_Internal_Rela *src; 39733965Sjdp Elf_External_Rela *dst; 39833965Sjdp{ 39933965Sjdp put_word (abfd, src->r_offset, dst->r_offset); 40033965Sjdp put_word (abfd, src->r_info, dst->r_info); 40138889Sjdp put_signed_word (abfd, src->r_addend, dst->r_addend); 40233965Sjdp} 40333965Sjdp 40433965SjdpINLINE void 40533965Sjdpelf_swap_dyn_in (abfd, p, dst) 40633965Sjdp bfd *abfd; 40733965Sjdp const PTR p; 40833965Sjdp Elf_Internal_Dyn *dst; 40933965Sjdp{ 41033965Sjdp const Elf_External_Dyn *src = (const Elf_External_Dyn *) p; 41133965Sjdp 41233965Sjdp dst->d_tag = get_word (abfd, src->d_tag); 41333965Sjdp dst->d_un.d_val = get_word (abfd, src->d_un.d_val); 41433965Sjdp} 41533965Sjdp 41633965SjdpINLINE void 41733965Sjdpelf_swap_dyn_out (abfd, src, dst) 41833965Sjdp bfd *abfd; 41933965Sjdp const Elf_Internal_Dyn *src; 42033965Sjdp Elf_External_Dyn *dst; 42133965Sjdp{ 42233965Sjdp put_word (abfd, src->d_tag, dst->d_tag); 42333965Sjdp put_word (abfd, src->d_un.d_val, dst->d_un.d_val); 42433965Sjdp} 42533965Sjdp 42633965Sjdp/* ELF .o/exec file reading */ 42733965Sjdp 42833965Sjdp 42933965Sjdp/* Begin processing a given object. 43033965Sjdp 43133965Sjdp First we validate the file by reading in the ELF header and checking 43233965Sjdp the magic number. */ 43333965Sjdp 43433965Sjdpstatic INLINE boolean 43533965Sjdpelf_file_p (x_ehdrp) 43633965Sjdp Elf_External_Ehdr *x_ehdrp; 43733965Sjdp{ 43833965Sjdp return ((x_ehdrp->e_ident[EI_MAG0] == ELFMAG0) 43933965Sjdp && (x_ehdrp->e_ident[EI_MAG1] == ELFMAG1) 44033965Sjdp && (x_ehdrp->e_ident[EI_MAG2] == ELFMAG2) 44133965Sjdp && (x_ehdrp->e_ident[EI_MAG3] == ELFMAG3)); 44233965Sjdp} 44333965Sjdp 44433965Sjdp/* Check to see if the file associated with ABFD matches the target vector 44533965Sjdp that ABFD points to. 44633965Sjdp 44733965Sjdp Note that we may be called several times with the same ABFD, but different 44833965Sjdp target vectors, most of which will not match. We have to avoid leaving 44933965Sjdp any side effects in ABFD, or any data it points to (like tdata), if the 45033965Sjdp file does not match the target vector. */ 45133965Sjdp 45233965Sjdpconst bfd_target * 45333965Sjdpelf_object_p (abfd) 45433965Sjdp bfd *abfd; 45533965Sjdp{ 45633965Sjdp Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ 45733965Sjdp Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ 45833965Sjdp Elf_External_Shdr x_shdr; /* Section header table entry, external form */ 45933965Sjdp Elf_Internal_Shdr *i_shdrp = NULL; /* Section header table, internal form */ 46033965Sjdp unsigned int shindex; 46133965Sjdp char *shstrtab; /* Internal copy of section header stringtab */ 46233965Sjdp struct elf_backend_data *ebd; 46333965Sjdp struct elf_obj_tdata *preserved_tdata = elf_tdata (abfd); 46433965Sjdp struct elf_obj_tdata *new_tdata = NULL; 46533965Sjdp asection *s; 46633965Sjdp 46733965Sjdp /* Read in the ELF header in external format. */ 46833965Sjdp 46933965Sjdp if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr)) 47033965Sjdp { 47133965Sjdp if (bfd_get_error () != bfd_error_system_call) 47233965Sjdp goto got_wrong_format_error; 47333965Sjdp else 47433965Sjdp goto got_no_match; 47533965Sjdp } 47633965Sjdp 47733965Sjdp /* Now check to see if we have a valid ELF file, and one that BFD can 47833965Sjdp make use of. The magic number must match, the address size ('class') 47933965Sjdp and byte-swapping must match our XVEC entry, and it must have a 48033965Sjdp section header table (FIXME: See comments re sections at top of this 48133965Sjdp file). */ 48233965Sjdp 48333965Sjdp if ((elf_file_p (&x_ehdr) == false) || 48433965Sjdp (x_ehdr.e_ident[EI_VERSION] != EV_CURRENT) || 48533965Sjdp (x_ehdr.e_ident[EI_CLASS] != ELFCLASS)) 48633965Sjdp goto got_wrong_format_error; 48733965Sjdp 48833965Sjdp /* Check that file's byte order matches xvec's */ 48933965Sjdp switch (x_ehdr.e_ident[EI_DATA]) 49033965Sjdp { 49133965Sjdp case ELFDATA2MSB: /* Big-endian */ 49233965Sjdp if (! bfd_header_big_endian (abfd)) 49333965Sjdp goto got_wrong_format_error; 49433965Sjdp break; 49533965Sjdp case ELFDATA2LSB: /* Little-endian */ 49633965Sjdp if (! bfd_header_little_endian (abfd)) 49733965Sjdp goto got_wrong_format_error; 49833965Sjdp break; 49933965Sjdp case ELFDATANONE: /* No data encoding specified */ 50033965Sjdp default: /* Unknown data encoding specified */ 50133965Sjdp goto got_wrong_format_error; 50233965Sjdp } 50333965Sjdp 50433965Sjdp /* Allocate an instance of the elf_obj_tdata structure and hook it up to 50533965Sjdp the tdata pointer in the bfd. */ 50633965Sjdp 50733965Sjdp new_tdata = ((struct elf_obj_tdata *) 50833965Sjdp bfd_zalloc (abfd, sizeof (struct elf_obj_tdata))); 50933965Sjdp if (new_tdata == NULL) 51033965Sjdp goto got_no_match; 51133965Sjdp elf_tdata (abfd) = new_tdata; 51233965Sjdp 51333965Sjdp /* Now that we know the byte order, swap in the rest of the header */ 51433965Sjdp i_ehdrp = elf_elfheader (abfd); 51533965Sjdp elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp); 51633965Sjdp#if DEBUG & 1 51733965Sjdp elf_debug_file (i_ehdrp); 51833965Sjdp#endif 51933965Sjdp 52033965Sjdp /* If there is no section header table, we're hosed. */ 52133965Sjdp if (i_ehdrp->e_shoff == 0) 52233965Sjdp goto got_wrong_format_error; 52333965Sjdp 52433965Sjdp /* As a simple sanity check, verify that the what BFD thinks is the 52533965Sjdp size of each section header table entry actually matches the size 52633965Sjdp recorded in the file. */ 52733965Sjdp if (i_ehdrp->e_shentsize != sizeof (x_shdr)) 52833965Sjdp goto got_wrong_format_error; 52933965Sjdp 53033965Sjdp ebd = get_elf_backend_data (abfd); 53133965Sjdp 53233965Sjdp /* Check that the ELF e_machine field matches what this particular 53333965Sjdp BFD format expects. */ 53433965Sjdp if (ebd->elf_machine_code != i_ehdrp->e_machine 53533965Sjdp && (ebd->elf_machine_alt1 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt1) 53633965Sjdp && (ebd->elf_machine_alt2 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt2)) 53733965Sjdp { 53833965Sjdp const bfd_target * const *target_ptr; 53933965Sjdp 54033965Sjdp if (ebd->elf_machine_code != EM_NONE) 54133965Sjdp goto got_wrong_format_error; 54233965Sjdp 54333965Sjdp /* This is the generic ELF target. Let it match any ELF target 54433965Sjdp for which we do not have a specific backend. */ 54533965Sjdp for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++) 54633965Sjdp { 54733965Sjdp struct elf_backend_data *back; 54833965Sjdp 54933965Sjdp if ((*target_ptr)->flavour != bfd_target_elf_flavour) 55033965Sjdp continue; 55133965Sjdp back = (struct elf_backend_data *) (*target_ptr)->backend_data; 55233965Sjdp if (back->elf_machine_code == i_ehdrp->e_machine 55333965Sjdp || (back->elf_machine_alt1 != 0 55433965Sjdp && back->elf_machine_alt1 == i_ehdrp->e_machine) 55533965Sjdp || (back->elf_machine_alt2 != 0 55633965Sjdp && back->elf_machine_alt2 == i_ehdrp->e_machine)) 55733965Sjdp { 55833965Sjdp /* target_ptr is an ELF backend which matches this 55933965Sjdp object file, so reject the generic ELF target. */ 56033965Sjdp goto got_wrong_format_error; 56133965Sjdp } 56233965Sjdp } 56333965Sjdp } 56433965Sjdp 56533965Sjdp if (i_ehdrp->e_type == ET_EXEC) 56633965Sjdp abfd->flags |= EXEC_P; 56733965Sjdp else if (i_ehdrp->e_type == ET_DYN) 56833965Sjdp abfd->flags |= DYNAMIC; 56933965Sjdp 57033965Sjdp if (i_ehdrp->e_phnum > 0) 57133965Sjdp abfd->flags |= D_PAGED; 57233965Sjdp 57333965Sjdp if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0)) 57433965Sjdp goto got_no_match; 57533965Sjdp 57633965Sjdp /* Remember the entry point specified in the ELF file header. */ 57733965Sjdp bfd_get_start_address (abfd) = i_ehdrp->e_entry; 57833965Sjdp 57933965Sjdp /* Allocate space for a copy of the section header table in 58033965Sjdp internal form, seek to the section header table in the file, 58133965Sjdp read it in, and convert it to internal form. */ 58233965Sjdp i_shdrp = ((Elf_Internal_Shdr *) 58333965Sjdp bfd_alloc (abfd, sizeof (*i_shdrp) * i_ehdrp->e_shnum)); 58433965Sjdp elf_elfsections (abfd) = ((Elf_Internal_Shdr **) 58533965Sjdp bfd_alloc (abfd, 58633965Sjdp sizeof (i_shdrp) * i_ehdrp->e_shnum)); 58733965Sjdp if (!i_shdrp || !elf_elfsections (abfd)) 58833965Sjdp goto got_no_match; 58933965Sjdp if (bfd_seek (abfd, i_ehdrp->e_shoff, SEEK_SET) != 0) 59033965Sjdp goto got_no_match; 59133965Sjdp for (shindex = 0; shindex < i_ehdrp->e_shnum; shindex++) 59233965Sjdp { 59333965Sjdp if (bfd_read ((PTR) & x_shdr, sizeof x_shdr, 1, abfd) != sizeof (x_shdr)) 59433965Sjdp goto got_no_match; 59533965Sjdp elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex); 59633965Sjdp elf_elfsections (abfd)[shindex] = i_shdrp + shindex; 59733965Sjdp 59833965Sjdp /* If the section is loaded, but not page aligned, clear 59933965Sjdp D_PAGED. */ 60033965Sjdp if ((i_shdrp[shindex].sh_flags & SHF_ALLOC) != 0 60133965Sjdp && i_shdrp[shindex].sh_type != SHT_NOBITS 60233965Sjdp && (((i_shdrp[shindex].sh_addr - i_shdrp[shindex].sh_offset) 60333965Sjdp % ebd->maxpagesize) 60433965Sjdp != 0)) 60533965Sjdp abfd->flags &= ~D_PAGED; 60633965Sjdp } 60733965Sjdp if (i_ehdrp->e_shstrndx) 60833965Sjdp { 60933965Sjdp if (! bfd_section_from_shdr (abfd, i_ehdrp->e_shstrndx)) 61033965Sjdp goto got_no_match; 61133965Sjdp } 61233965Sjdp 61333965Sjdp /* Read in the program headers. */ 61433965Sjdp if (i_ehdrp->e_phnum == 0) 61533965Sjdp elf_tdata (abfd)->phdr = NULL; 61633965Sjdp else 61733965Sjdp { 61833965Sjdp Elf_Internal_Phdr *i_phdr; 61933965Sjdp unsigned int i; 62033965Sjdp 62133965Sjdp elf_tdata (abfd)->phdr = ((Elf_Internal_Phdr *) 62233965Sjdp bfd_alloc (abfd, 62333965Sjdp (i_ehdrp->e_phnum 62433965Sjdp * sizeof (Elf_Internal_Phdr)))); 62533965Sjdp if (elf_tdata (abfd)->phdr == NULL) 62633965Sjdp goto got_no_match; 62733965Sjdp if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) != 0) 62833965Sjdp goto got_no_match; 62933965Sjdp i_phdr = elf_tdata (abfd)->phdr; 63033965Sjdp for (i = 0; i < i_ehdrp->e_phnum; i++, i_phdr++) 63133965Sjdp { 63233965Sjdp Elf_External_Phdr x_phdr; 63333965Sjdp 63433965Sjdp if (bfd_read ((PTR) &x_phdr, sizeof x_phdr, 1, abfd) 63533965Sjdp != sizeof x_phdr) 63633965Sjdp goto got_no_match; 63733965Sjdp elf_swap_phdr_in (abfd, &x_phdr, i_phdr); 63833965Sjdp } 63933965Sjdp } 64033965Sjdp 64133965Sjdp /* Read in the string table containing the names of the sections. We 64233965Sjdp will need the base pointer to this table later. */ 64333965Sjdp /* We read this inline now, so that we don't have to go through 64433965Sjdp bfd_section_from_shdr with it (since this particular strtab is 64533965Sjdp used to find all of the ELF section names.) */ 64633965Sjdp 64733965Sjdp shstrtab = bfd_elf_get_str_section (abfd, i_ehdrp->e_shstrndx); 64833965Sjdp if (!shstrtab) 64933965Sjdp goto got_no_match; 65033965Sjdp 65133965Sjdp /* Once all of the section headers have been read and converted, we 65233965Sjdp can start processing them. Note that the first section header is 65333965Sjdp a dummy placeholder entry, so we ignore it. */ 65433965Sjdp 65533965Sjdp for (shindex = 1; shindex < i_ehdrp->e_shnum; shindex++) 65633965Sjdp { 65733965Sjdp if (! bfd_section_from_shdr (abfd, shindex)) 65833965Sjdp goto got_no_match; 65933965Sjdp } 66033965Sjdp 66133965Sjdp /* Let the backend double check the format and override global 66233965Sjdp information. */ 66333965Sjdp if (ebd->elf_backend_object_p) 66433965Sjdp { 66533965Sjdp if ((*ebd->elf_backend_object_p) (abfd) == false) 66633965Sjdp goto got_wrong_format_error; 66733965Sjdp } 66833965Sjdp 66933965Sjdp /* If we have created any reloc sections that are associated with 67033965Sjdp debugging sections, mark the reloc sections as debugging as well. */ 67133965Sjdp for (s = abfd->sections; s != NULL; s = s->next) 67233965Sjdp { 67333965Sjdp if ((elf_section_data (s)->this_hdr.sh_type == SHT_REL 67433965Sjdp || elf_section_data (s)->this_hdr.sh_type == SHT_RELA) 67533965Sjdp && elf_section_data (s)->this_hdr.sh_info > 0) 67633965Sjdp { 67733965Sjdp unsigned long targ_index; 67833965Sjdp asection *targ_sec; 67933965Sjdp 68033965Sjdp targ_index = elf_section_data (s)->this_hdr.sh_info; 68133965Sjdp targ_sec = bfd_section_from_elf_index (abfd, targ_index); 68233965Sjdp if (targ_sec != NULL 68333965Sjdp && (targ_sec->flags & SEC_DEBUGGING) != 0) 68433965Sjdp s->flags |= SEC_DEBUGGING; 68533965Sjdp } 68633965Sjdp } 68733965Sjdp 68833965Sjdp return (abfd->xvec); 68933965Sjdp 69033965Sjdpgot_wrong_format_error: 69133965Sjdp bfd_set_error (bfd_error_wrong_format); 69233965Sjdp goto got_no_match; 69333965Sjdpgot_no_match: 69433965Sjdp if (new_tdata != NULL 69533965Sjdp && new_tdata->elf_sect_ptr != NULL) 69633965Sjdp bfd_release (abfd, new_tdata->elf_sect_ptr); 69733965Sjdp if (i_shdrp != NULL) 69833965Sjdp bfd_release (abfd, i_shdrp); 69933965Sjdp if (new_tdata != NULL) 70033965Sjdp bfd_release (abfd, new_tdata); 70133965Sjdp elf_tdata (abfd) = preserved_tdata; 70233965Sjdp return (NULL); 70333965Sjdp} 70433965Sjdp 70533965Sjdp/* ELF .o/exec file writing */ 70633965Sjdp 70733965Sjdp/* Write out the relocs. */ 70833965Sjdp 70933965Sjdpstatic void 71033965Sjdpwrite_relocs (abfd, sec, data) 71133965Sjdp bfd *abfd; 71233965Sjdp asection *sec; 71333965Sjdp PTR data; 71433965Sjdp{ 71533965Sjdp boolean *failedp = (boolean *) data; 71633965Sjdp Elf_Internal_Shdr *rela_hdr; 71733965Sjdp Elf_External_Rela *outbound_relocas; 71833965Sjdp Elf_External_Rel *outbound_relocs; 71933965Sjdp unsigned int idx; 72033965Sjdp int use_rela_p = get_elf_backend_data (abfd)->use_rela_p; 72133965Sjdp asymbol *last_sym = 0; 72233965Sjdp int last_sym_idx = 0; 72333965Sjdp 72433965Sjdp /* If we have already failed, don't do anything. */ 72533965Sjdp if (*failedp) 72633965Sjdp return; 72733965Sjdp 72833965Sjdp if ((sec->flags & SEC_RELOC) == 0) 72933965Sjdp return; 73033965Sjdp 73133965Sjdp /* The linker backend writes the relocs out itself, and sets the 73233965Sjdp reloc_count field to zero to inhibit writing them here. Also, 73333965Sjdp sometimes the SEC_RELOC flag gets set even when there aren't any 73433965Sjdp relocs. */ 73533965Sjdp if (sec->reloc_count == 0) 73633965Sjdp return; 73733965Sjdp 73833965Sjdp rela_hdr = &elf_section_data (sec)->rel_hdr; 73933965Sjdp 74033965Sjdp rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count; 74133965Sjdp rela_hdr->contents = (PTR) bfd_alloc (abfd, rela_hdr->sh_size); 74233965Sjdp if (rela_hdr->contents == NULL) 74333965Sjdp { 74433965Sjdp *failedp = true; 74533965Sjdp return; 74633965Sjdp } 74733965Sjdp 74833965Sjdp /* orelocation has the data, reloc_count has the count... */ 74933965Sjdp if (use_rela_p) 75033965Sjdp { 75133965Sjdp outbound_relocas = (Elf_External_Rela *) rela_hdr->contents; 75233965Sjdp 75333965Sjdp for (idx = 0; idx < sec->reloc_count; idx++) 75433965Sjdp { 75533965Sjdp Elf_Internal_Rela dst_rela; 75633965Sjdp Elf_External_Rela *src_rela; 75733965Sjdp arelent *ptr; 75833965Sjdp asymbol *sym; 75933965Sjdp int n; 76033965Sjdp 76133965Sjdp ptr = sec->orelocation[idx]; 76233965Sjdp src_rela = outbound_relocas + idx; 76333965Sjdp 76433965Sjdp /* The address of an ELF reloc is section relative for an object 76533965Sjdp file, and absolute for an executable file or shared library. 76633965Sjdp The address of a BFD reloc is always section relative. */ 76733965Sjdp if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0) 76833965Sjdp dst_rela.r_offset = ptr->address; 76933965Sjdp else 77033965Sjdp dst_rela.r_offset = ptr->address + sec->vma; 77133965Sjdp 77233965Sjdp sym = *ptr->sym_ptr_ptr; 77333965Sjdp if (sym == last_sym) 77433965Sjdp n = last_sym_idx; 77533965Sjdp else if (bfd_is_abs_section (sym->section) && sym->value == 0) 77633965Sjdp n = STN_UNDEF; 77733965Sjdp else 77833965Sjdp { 77933965Sjdp last_sym = sym; 78033965Sjdp n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym); 78133965Sjdp if (n < 0) 78233965Sjdp { 78333965Sjdp *failedp = true; 78433965Sjdp return; 78533965Sjdp } 78633965Sjdp last_sym_idx = n; 78733965Sjdp } 78833965Sjdp 78933965Sjdp if ((*ptr->sym_ptr_ptr)->the_bfd != NULL 79033965Sjdp && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec 79133965Sjdp && ! _bfd_elf_validate_reloc (abfd, ptr)) 79233965Sjdp { 79333965Sjdp *failedp = true; 79433965Sjdp return; 79533965Sjdp } 79633965Sjdp 79733965Sjdp dst_rela.r_info = ELF_R_INFO (n, ptr->howto->type); 79833965Sjdp 79933965Sjdp dst_rela.r_addend = ptr->addend; 80033965Sjdp elf_swap_reloca_out (abfd, &dst_rela, src_rela); 80133965Sjdp } 80233965Sjdp } 80333965Sjdp else 80433965Sjdp /* REL relocations */ 80533965Sjdp { 80633965Sjdp outbound_relocs = (Elf_External_Rel *) rela_hdr->contents; 80733965Sjdp 80833965Sjdp for (idx = 0; idx < sec->reloc_count; idx++) 80933965Sjdp { 81033965Sjdp Elf_Internal_Rel dst_rel; 81133965Sjdp Elf_External_Rel *src_rel; 81233965Sjdp arelent *ptr; 81333965Sjdp int n; 81433965Sjdp asymbol *sym; 81533965Sjdp 81633965Sjdp ptr = sec->orelocation[idx]; 81733965Sjdp sym = *ptr->sym_ptr_ptr; 81833965Sjdp src_rel = outbound_relocs + idx; 81933965Sjdp 82033965Sjdp /* The address of an ELF reloc is section relative for an object 82133965Sjdp file, and absolute for an executable file or shared library. 82233965Sjdp The address of a BFD reloc is always section relative. */ 82333965Sjdp if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0) 82433965Sjdp dst_rel.r_offset = ptr->address; 82533965Sjdp else 82633965Sjdp dst_rel.r_offset = ptr->address + sec->vma; 82733965Sjdp 82833965Sjdp if (sym == last_sym) 82933965Sjdp n = last_sym_idx; 83033965Sjdp else 83133965Sjdp { 83233965Sjdp last_sym = sym; 83333965Sjdp n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym); 83433965Sjdp if (n < 0) 83533965Sjdp { 83633965Sjdp *failedp = true; 83733965Sjdp return; 83833965Sjdp } 83933965Sjdp last_sym_idx = n; 84033965Sjdp } 84133965Sjdp 84233965Sjdp if ((*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec 84333965Sjdp && ! _bfd_elf_validate_reloc (abfd, ptr)) 84433965Sjdp { 84533965Sjdp *failedp = true; 84633965Sjdp return; 84733965Sjdp } 84833965Sjdp 84933965Sjdp dst_rel.r_info = ELF_R_INFO (n, ptr->howto->type); 85033965Sjdp 85133965Sjdp elf_swap_reloc_out (abfd, &dst_rel, src_rel); 85233965Sjdp } 85333965Sjdp } 85433965Sjdp} 85533965Sjdp 85633965Sjdp/* Write out the program headers. */ 85733965Sjdp 85833965Sjdpint 85933965Sjdpelf_write_out_phdrs (abfd, phdr, count) 86033965Sjdp bfd *abfd; 86133965Sjdp const Elf_Internal_Phdr *phdr; 86233965Sjdp int count; 86333965Sjdp{ 86433965Sjdp while (count--) 86533965Sjdp { 86633965Sjdp Elf_External_Phdr extphdr; 86733965Sjdp elf_swap_phdr_out (abfd, phdr, &extphdr); 86833965Sjdp if (bfd_write (&extphdr, sizeof (Elf_External_Phdr), 1, abfd) 86933965Sjdp != sizeof (Elf_External_Phdr)) 87033965Sjdp return -1; 87133965Sjdp phdr++; 87233965Sjdp } 87333965Sjdp return 0; 87433965Sjdp} 87533965Sjdp 87633965Sjdp/* Write out the section headers and the ELF file header. */ 87733965Sjdp 87833965Sjdpboolean 87933965Sjdpelf_write_shdrs_and_ehdr (abfd) 88033965Sjdp bfd *abfd; 88133965Sjdp{ 88233965Sjdp Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ 88333965Sjdp Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */ 88433965Sjdp Elf_External_Shdr *x_shdrp; /* Section header table, external form */ 88533965Sjdp Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */ 88633965Sjdp unsigned int count; 88733965Sjdp 88833965Sjdp i_ehdrp = elf_elfheader (abfd); 88933965Sjdp i_shdrp = elf_elfsections (abfd); 89033965Sjdp 89133965Sjdp /* swap the header before spitting it out... */ 89233965Sjdp 89333965Sjdp#if DEBUG & 1 89433965Sjdp elf_debug_file (i_ehdrp); 89533965Sjdp#endif 89633965Sjdp elf_swap_ehdr_out (abfd, i_ehdrp, &x_ehdr); 89733965Sjdp if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 89833965Sjdp || (bfd_write ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) 89933965Sjdp != sizeof (x_ehdr))) 90033965Sjdp return false; 90133965Sjdp 90233965Sjdp /* at this point we've concocted all the ELF sections... */ 90333965Sjdp x_shdrp = (Elf_External_Shdr *) 90433965Sjdp bfd_alloc (abfd, sizeof (*x_shdrp) * (i_ehdrp->e_shnum)); 90533965Sjdp if (!x_shdrp) 90633965Sjdp return false; 90733965Sjdp 90833965Sjdp for (count = 0; count < i_ehdrp->e_shnum; count++) 90933965Sjdp { 91033965Sjdp#if DEBUG & 2 91133965Sjdp elf_debug_section (count, i_shdrp[count]); 91233965Sjdp#endif 91333965Sjdp elf_swap_shdr_out (abfd, i_shdrp[count], x_shdrp + count); 91433965Sjdp } 91533965Sjdp if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0 91633965Sjdp || (bfd_write ((PTR) x_shdrp, sizeof (*x_shdrp), i_ehdrp->e_shnum, abfd) 91733965Sjdp != sizeof (*x_shdrp) * i_ehdrp->e_shnum)) 91833965Sjdp return false; 91933965Sjdp 92033965Sjdp /* need to dump the string table too... */ 92133965Sjdp 92233965Sjdp return true; 92333965Sjdp} 92433965Sjdp 92533965Sjdplong 92633965Sjdpelf_slurp_symbol_table (abfd, symptrs, dynamic) 92733965Sjdp bfd *abfd; 92833965Sjdp asymbol **symptrs; /* Buffer for generated bfd symbols */ 92933965Sjdp boolean dynamic; 93033965Sjdp{ 93133965Sjdp Elf_Internal_Shdr *hdr; 93233965Sjdp Elf_Internal_Shdr *verhdr; 93338889Sjdp unsigned long symcount; /* Number of external ELF symbols */ 93433965Sjdp elf_symbol_type *sym; /* Pointer to current bfd symbol */ 93533965Sjdp elf_symbol_type *symbase; /* Buffer for generated bfd symbols */ 93633965Sjdp Elf_Internal_Sym i_sym; 93733965Sjdp Elf_External_Sym *x_symp = NULL; 93833965Sjdp Elf_External_Versym *x_versymp = NULL; 93933965Sjdp 94033965Sjdp /* Read each raw ELF symbol, converting from external ELF form to 94133965Sjdp internal ELF form, and then using the information to create a 94233965Sjdp canonical bfd symbol table entry. 94333965Sjdp 94433965Sjdp Note that we allocate the initial bfd canonical symbol buffer 94533965Sjdp based on a one-to-one mapping of the ELF symbols to canonical 94633965Sjdp symbols. We actually use all the ELF symbols, so there will be no 94733965Sjdp space left over at the end. When we have all the symbols, we 94833965Sjdp build the caller's pointer vector. */ 94933965Sjdp 95033965Sjdp if (! dynamic) 95133965Sjdp { 95233965Sjdp hdr = &elf_tdata (abfd)->symtab_hdr; 95333965Sjdp verhdr = NULL; 95433965Sjdp } 95533965Sjdp else 95633965Sjdp { 95733965Sjdp hdr = &elf_tdata (abfd)->dynsymtab_hdr; 95833965Sjdp if (elf_dynversym (abfd) == 0) 95933965Sjdp verhdr = NULL; 96033965Sjdp else 96133965Sjdp verhdr = &elf_tdata (abfd)->dynversym_hdr; 96233965Sjdp if ((elf_tdata (abfd)->dynverdef_section != 0 96333965Sjdp && elf_tdata (abfd)->verdef == NULL) 96433965Sjdp || (elf_tdata (abfd)->dynverref_section != 0 96533965Sjdp && elf_tdata (abfd)->verref == NULL)) 96633965Sjdp { 96733965Sjdp if (! _bfd_elf_slurp_version_tables (abfd)) 96833965Sjdp return -1; 96933965Sjdp } 97033965Sjdp } 97133965Sjdp 97233965Sjdp if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1) 97333965Sjdp return -1; 97433965Sjdp 97533965Sjdp symcount = hdr->sh_size / sizeof (Elf_External_Sym); 97633965Sjdp 97733965Sjdp if (symcount == 0) 97833965Sjdp sym = symbase = NULL; 97933965Sjdp else 98033965Sjdp { 98138889Sjdp unsigned long i; 98233965Sjdp 98333965Sjdp if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1) 98433965Sjdp return -1; 98533965Sjdp 98633965Sjdp symbase = ((elf_symbol_type *) 98733965Sjdp bfd_zalloc (abfd, symcount * sizeof (elf_symbol_type))); 98833965Sjdp if (symbase == (elf_symbol_type *) NULL) 98933965Sjdp return -1; 99033965Sjdp sym = symbase; 99133965Sjdp 99233965Sjdp /* Temporarily allocate room for the raw ELF symbols. */ 99333965Sjdp x_symp = ((Elf_External_Sym *) 99433965Sjdp bfd_malloc (symcount * sizeof (Elf_External_Sym))); 99533965Sjdp if (x_symp == NULL && symcount != 0) 99633965Sjdp goto error_return; 99733965Sjdp 99833965Sjdp if (bfd_read ((PTR) x_symp, sizeof (Elf_External_Sym), symcount, abfd) 99933965Sjdp != symcount * sizeof (Elf_External_Sym)) 100033965Sjdp goto error_return; 100133965Sjdp 100233965Sjdp /* Read the raw ELF version symbol information. */ 100333965Sjdp 100433965Sjdp if (verhdr != NULL 100533965Sjdp && verhdr->sh_size / sizeof (Elf_External_Versym) != symcount) 100633965Sjdp { 100733965Sjdp (*_bfd_error_handler) 100833965Sjdp ("%s: version count (%ld) does not match symbol count (%ld)", 100933965Sjdp abfd->filename, 101033965Sjdp (long) (verhdr->sh_size / sizeof (Elf_External_Versym)), 101133965Sjdp symcount); 101233965Sjdp 101333965Sjdp /* Slurp in the symbols without the version information, 101433965Sjdp since that is more helpful than just quitting. */ 101533965Sjdp verhdr = NULL; 101633965Sjdp } 101733965Sjdp 101833965Sjdp if (verhdr != NULL) 101933965Sjdp { 102033965Sjdp if (bfd_seek (abfd, verhdr->sh_offset, SEEK_SET) != 0) 102133965Sjdp goto error_return; 102233965Sjdp 102333965Sjdp x_versymp = (Elf_External_Versym *) bfd_malloc (verhdr->sh_size); 102433965Sjdp if (x_versymp == NULL && verhdr->sh_size != 0) 102533965Sjdp goto error_return; 102633965Sjdp 102733965Sjdp if (bfd_read ((PTR) x_versymp, 1, verhdr->sh_size, abfd) 102833965Sjdp != verhdr->sh_size) 102933965Sjdp goto error_return; 103033965Sjdp } 103133965Sjdp 103233965Sjdp /* Skip first symbol, which is a null dummy. */ 103333965Sjdp for (i = 1; i < symcount; i++) 103433965Sjdp { 103533965Sjdp elf_swap_symbol_in (abfd, x_symp + i, &i_sym); 103633965Sjdp memcpy (&sym->internal_elf_sym, &i_sym, sizeof (Elf_Internal_Sym)); 103733965Sjdp#ifdef ELF_KEEP_EXTSYM 103833965Sjdp memcpy (&sym->native_elf_sym, x_symp + i, sizeof (Elf_External_Sym)); 103933965Sjdp#endif 104033965Sjdp sym->symbol.the_bfd = abfd; 104133965Sjdp 104233965Sjdp sym->symbol.name = bfd_elf_string_from_elf_section (abfd, 104333965Sjdp hdr->sh_link, 104433965Sjdp i_sym.st_name); 104533965Sjdp 104633965Sjdp sym->symbol.value = i_sym.st_value; 104733965Sjdp 104833965Sjdp if (i_sym.st_shndx > 0 && i_sym.st_shndx < SHN_LORESERVE) 104933965Sjdp { 105033965Sjdp sym->symbol.section = section_from_elf_index (abfd, 105133965Sjdp i_sym.st_shndx); 105233965Sjdp if (sym->symbol.section == NULL) 105333965Sjdp { 105433965Sjdp /* This symbol is in a section for which we did not 105533965Sjdp create a BFD section. Just use bfd_abs_section, 105633965Sjdp although it is wrong. FIXME. */ 105733965Sjdp sym->symbol.section = bfd_abs_section_ptr; 105833965Sjdp } 105933965Sjdp } 106033965Sjdp else if (i_sym.st_shndx == SHN_ABS) 106133965Sjdp { 106233965Sjdp sym->symbol.section = bfd_abs_section_ptr; 106333965Sjdp } 106433965Sjdp else if (i_sym.st_shndx == SHN_COMMON) 106533965Sjdp { 106633965Sjdp sym->symbol.section = bfd_com_section_ptr; 106733965Sjdp /* Elf puts the alignment into the `value' field, and 106833965Sjdp the size into the `size' field. BFD wants to see the 106933965Sjdp size in the value field, and doesn't care (at the 107033965Sjdp moment) about the alignment. */ 107133965Sjdp sym->symbol.value = i_sym.st_size; 107233965Sjdp } 107333965Sjdp else if (i_sym.st_shndx == SHN_UNDEF) 107433965Sjdp { 107533965Sjdp sym->symbol.section = bfd_und_section_ptr; 107633965Sjdp } 107733965Sjdp else 107833965Sjdp sym->symbol.section = bfd_abs_section_ptr; 107933965Sjdp 108033965Sjdp /* If this is a relocateable file, then the symbol value is 108133965Sjdp already section relative. */ 108233965Sjdp if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0) 108333965Sjdp sym->symbol.value -= sym->symbol.section->vma; 108433965Sjdp 108533965Sjdp switch (ELF_ST_BIND (i_sym.st_info)) 108633965Sjdp { 108733965Sjdp case STB_LOCAL: 108833965Sjdp sym->symbol.flags |= BSF_LOCAL; 108933965Sjdp break; 109033965Sjdp case STB_GLOBAL: 109133965Sjdp if (i_sym.st_shndx != SHN_UNDEF 109233965Sjdp && i_sym.st_shndx != SHN_COMMON) 109333965Sjdp sym->symbol.flags |= BSF_GLOBAL; 109433965Sjdp break; 109533965Sjdp case STB_WEAK: 109633965Sjdp sym->symbol.flags |= BSF_WEAK; 109733965Sjdp break; 109833965Sjdp } 109933965Sjdp 110033965Sjdp switch (ELF_ST_TYPE (i_sym.st_info)) 110133965Sjdp { 110233965Sjdp case STT_SECTION: 110333965Sjdp sym->symbol.flags |= BSF_SECTION_SYM | BSF_DEBUGGING; 110433965Sjdp break; 110533965Sjdp case STT_FILE: 110633965Sjdp sym->symbol.flags |= BSF_FILE | BSF_DEBUGGING; 110733965Sjdp break; 110833965Sjdp case STT_FUNC: 110933965Sjdp sym->symbol.flags |= BSF_FUNCTION; 111033965Sjdp break; 111133965Sjdp case STT_OBJECT: 111233965Sjdp sym->symbol.flags |= BSF_OBJECT; 111333965Sjdp break; 111433965Sjdp } 111533965Sjdp 111633965Sjdp if (dynamic) 111733965Sjdp sym->symbol.flags |= BSF_DYNAMIC; 111833965Sjdp 111933965Sjdp if (x_versymp != NULL) 112033965Sjdp { 112133965Sjdp Elf_Internal_Versym iversym; 112233965Sjdp 112333965Sjdp _bfd_elf_swap_versym_in (abfd, x_versymp + i, &iversym); 112433965Sjdp sym->version = iversym.vs_vers; 112533965Sjdp } 112633965Sjdp 112733965Sjdp /* Do some backend-specific processing on this symbol. */ 112833965Sjdp { 112933965Sjdp struct elf_backend_data *ebd = get_elf_backend_data (abfd); 113033965Sjdp if (ebd->elf_backend_symbol_processing) 113133965Sjdp (*ebd->elf_backend_symbol_processing) (abfd, &sym->symbol); 113233965Sjdp } 113333965Sjdp 113433965Sjdp sym++; 113533965Sjdp } 113633965Sjdp } 113733965Sjdp 113833965Sjdp /* Do some backend-specific processing on this symbol table. */ 113933965Sjdp { 114033965Sjdp struct elf_backend_data *ebd = get_elf_backend_data (abfd); 114133965Sjdp if (ebd->elf_backend_symbol_table_processing) 114233965Sjdp (*ebd->elf_backend_symbol_table_processing) (abfd, symbase, symcount); 114333965Sjdp } 114433965Sjdp 114533965Sjdp /* We rely on the zalloc to clear out the final symbol entry. */ 114633965Sjdp 114733965Sjdp symcount = sym - symbase; 114833965Sjdp 114933965Sjdp /* Fill in the user's symbol pointer vector if needed. */ 115033965Sjdp if (symptrs) 115133965Sjdp { 115233965Sjdp long l = symcount; 115333965Sjdp 115433965Sjdp sym = symbase; 115533965Sjdp while (l-- > 0) 115633965Sjdp { 115733965Sjdp *symptrs++ = &sym->symbol; 115833965Sjdp sym++; 115933965Sjdp } 116033965Sjdp *symptrs = 0; /* Final null pointer */ 116133965Sjdp } 116233965Sjdp 116333965Sjdp if (x_versymp != NULL) 116433965Sjdp free (x_versymp); 116533965Sjdp if (x_symp != NULL) 116633965Sjdp free (x_symp); 116733965Sjdp return symcount; 116833965Sjdperror_return: 116933965Sjdp if (x_versymp != NULL) 117033965Sjdp free (x_versymp); 117133965Sjdp if (x_symp != NULL) 117233965Sjdp free (x_symp); 117333965Sjdp return -1; 117433965Sjdp} 117533965Sjdp 117633965Sjdp/* Read in and swap the external relocs. */ 117733965Sjdp 117833965Sjdpstatic boolean 117933965Sjdpelf_slurp_reloc_table (abfd, asect, symbols, dynamic) 118033965Sjdp bfd *abfd; 118133965Sjdp asection *asect; 118233965Sjdp asymbol **symbols; 118333965Sjdp boolean dynamic; 118433965Sjdp{ 118533965Sjdp struct elf_backend_data * const ebd = get_elf_backend_data (abfd); 118633965Sjdp struct bfd_elf_section_data * const d = elf_section_data (asect); 118733965Sjdp Elf_Internal_Shdr *rel_hdr; 118833965Sjdp bfd_size_type reloc_count; 118933965Sjdp PTR allocated = NULL; 119033965Sjdp bfd_byte *native_relocs; 119133965Sjdp arelent *relents; 119233965Sjdp arelent *relent; 119333965Sjdp unsigned int i; 119433965Sjdp int entsize; 119533965Sjdp 119633965Sjdp if (asect->relocation != NULL) 119733965Sjdp return true; 119833965Sjdp 119933965Sjdp if (! dynamic) 120033965Sjdp { 120133965Sjdp if ((asect->flags & SEC_RELOC) == 0 120233965Sjdp || asect->reloc_count == 0) 120333965Sjdp return true; 120433965Sjdp 120533965Sjdp rel_hdr = &d->rel_hdr; 120633965Sjdp reloc_count = asect->reloc_count; 120733965Sjdp 120833965Sjdp BFD_ASSERT (asect->rel_filepos == rel_hdr->sh_offset 120933965Sjdp && reloc_count == rel_hdr->sh_size / rel_hdr->sh_entsize); 121033965Sjdp } 121133965Sjdp else 121233965Sjdp { 121333965Sjdp if (asect->_raw_size == 0) 121433965Sjdp return true; 121533965Sjdp 121633965Sjdp rel_hdr = &d->this_hdr; 121733965Sjdp reloc_count = rel_hdr->sh_size / rel_hdr->sh_entsize; 121833965Sjdp } 121933965Sjdp 122033965Sjdp allocated = (PTR) bfd_malloc ((size_t) rel_hdr->sh_size); 122133965Sjdp if (allocated == NULL) 122233965Sjdp goto error_return; 122333965Sjdp 122433965Sjdp if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0 122533965Sjdp || (bfd_read (allocated, 1, rel_hdr->sh_size, abfd) 122633965Sjdp != rel_hdr->sh_size)) 122733965Sjdp goto error_return; 122833965Sjdp 122933965Sjdp native_relocs = (bfd_byte *) allocated; 123033965Sjdp 123133965Sjdp relents = (arelent *) bfd_alloc (abfd, reloc_count * sizeof (arelent)); 123233965Sjdp if (relents == NULL) 123333965Sjdp goto error_return; 123433965Sjdp 123533965Sjdp entsize = rel_hdr->sh_entsize; 123633965Sjdp BFD_ASSERT (entsize == sizeof (Elf_External_Rel) 123733965Sjdp || entsize == sizeof (Elf_External_Rela)); 123833965Sjdp 123933965Sjdp for (i = 0, relent = relents; 124033965Sjdp i < reloc_count; 124133965Sjdp i++, relent++, native_relocs += entsize) 124233965Sjdp { 124333965Sjdp Elf_Internal_Rela rela; 124433965Sjdp Elf_Internal_Rel rel; 124533965Sjdp 124633965Sjdp if (entsize == sizeof (Elf_External_Rela)) 124733965Sjdp elf_swap_reloca_in (abfd, (Elf_External_Rela *) native_relocs, &rela); 124833965Sjdp else 124933965Sjdp { 125033965Sjdp elf_swap_reloc_in (abfd, (Elf_External_Rel *) native_relocs, &rel); 125133965Sjdp rela.r_offset = rel.r_offset; 125233965Sjdp rela.r_info = rel.r_info; 125333965Sjdp rela.r_addend = 0; 125433965Sjdp } 125533965Sjdp 125633965Sjdp /* The address of an ELF reloc is section relative for an object 125733965Sjdp file, and absolute for an executable file or shared library. 125833965Sjdp The address of a normal BFD reloc is always section relative, 125933965Sjdp and the address of a dynamic reloc is absolute.. */ 126033965Sjdp if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic) 126133965Sjdp relent->address = rela.r_offset; 126233965Sjdp else 126333965Sjdp relent->address = rela.r_offset - asect->vma; 126433965Sjdp 126533965Sjdp if (ELF_R_SYM (rela.r_info) == 0) 126633965Sjdp relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; 126733965Sjdp else 126833965Sjdp { 126933965Sjdp asymbol **ps, *s; 127033965Sjdp 127133965Sjdp ps = symbols + ELF_R_SYM (rela.r_info) - 1; 127233965Sjdp s = *ps; 127333965Sjdp 127433965Sjdp /* Canonicalize ELF section symbols. FIXME: Why? */ 127533965Sjdp if ((s->flags & BSF_SECTION_SYM) == 0) 127633965Sjdp relent->sym_ptr_ptr = ps; 127733965Sjdp else 127833965Sjdp relent->sym_ptr_ptr = s->section->symbol_ptr_ptr; 127933965Sjdp } 128033965Sjdp 128133965Sjdp relent->addend = rela.r_addend; 128233965Sjdp 128333965Sjdp if (entsize == sizeof (Elf_External_Rela)) 128433965Sjdp (*ebd->elf_info_to_howto) (abfd, relent, &rela); 128533965Sjdp else 128633965Sjdp (*ebd->elf_info_to_howto_rel) (abfd, relent, &rel); 128733965Sjdp } 128833965Sjdp 128933965Sjdp asect->relocation = relents; 129033965Sjdp 129133965Sjdp if (allocated != NULL) 129233965Sjdp free (allocated); 129333965Sjdp 129433965Sjdp return true; 129533965Sjdp 129633965Sjdp error_return: 129733965Sjdp if (allocated != NULL) 129833965Sjdp free (allocated); 129933965Sjdp return false; 130033965Sjdp} 130133965Sjdp 130233965Sjdp#ifdef DEBUG 130333965Sjdpstatic void 130433965Sjdpelf_debug_section (num, hdr) 130533965Sjdp int num; 130633965Sjdp Elf_Internal_Shdr *hdr; 130733965Sjdp{ 130833965Sjdp fprintf (stderr, "\nSection#%d '%s' 0x%.8lx\n", num, 130933965Sjdp hdr->bfd_section != NULL ? hdr->bfd_section->name : "", 131033965Sjdp (long) hdr); 131133965Sjdp fprintf (stderr, 131233965Sjdp "sh_name = %ld\tsh_type = %ld\tsh_flags = %ld\n", 131333965Sjdp (long) hdr->sh_name, 131433965Sjdp (long) hdr->sh_type, 131533965Sjdp (long) hdr->sh_flags); 131633965Sjdp fprintf (stderr, 131733965Sjdp "sh_addr = %ld\tsh_offset = %ld\tsh_size = %ld\n", 131833965Sjdp (long) hdr->sh_addr, 131933965Sjdp (long) hdr->sh_offset, 132033965Sjdp (long) hdr->sh_size); 132133965Sjdp fprintf (stderr, 132233965Sjdp "sh_link = %ld\tsh_info = %ld\tsh_addralign = %ld\n", 132333965Sjdp (long) hdr->sh_link, 132433965Sjdp (long) hdr->sh_info, 132533965Sjdp (long) hdr->sh_addralign); 132633965Sjdp fprintf (stderr, "sh_entsize = %ld\n", 132733965Sjdp (long) hdr->sh_entsize); 132833965Sjdp fflush (stderr); 132933965Sjdp} 133033965Sjdp 133133965Sjdpstatic void 133233965Sjdpelf_debug_file (ehdrp) 133333965Sjdp Elf_Internal_Ehdr *ehdrp; 133433965Sjdp{ 133533965Sjdp fprintf (stderr, "e_entry = 0x%.8lx\n", (long) ehdrp->e_entry); 133633965Sjdp fprintf (stderr, "e_phoff = %ld\n", (long) ehdrp->e_phoff); 133733965Sjdp fprintf (stderr, "e_phnum = %ld\n", (long) ehdrp->e_phnum); 133833965Sjdp fprintf (stderr, "e_phentsize = %ld\n", (long) ehdrp->e_phentsize); 133933965Sjdp fprintf (stderr, "e_shoff = %ld\n", (long) ehdrp->e_shoff); 134033965Sjdp fprintf (stderr, "e_shnum = %ld\n", (long) ehdrp->e_shnum); 134133965Sjdp fprintf (stderr, "e_shentsize = %ld\n", (long) ehdrp->e_shentsize); 134233965Sjdp} 134333965Sjdp 134433965Sjdpstatic char * 134533965Sjdpelf_symbol_flags (flags) 134633965Sjdp flagword flags; 134733965Sjdp{ 134833965Sjdp static char buffer[1024]; 134933965Sjdp 135033965Sjdp buffer[0] = '\0'; 135133965Sjdp if (flags & BSF_LOCAL) 135233965Sjdp strcat (buffer, " local"); 135333965Sjdp 135433965Sjdp if (flags & BSF_GLOBAL) 135533965Sjdp strcat (buffer, " global"); 135633965Sjdp 135733965Sjdp if (flags & BSF_DEBUGGING) 135833965Sjdp strcat (buffer, " debug"); 135933965Sjdp 136033965Sjdp if (flags & BSF_FUNCTION) 136133965Sjdp strcat (buffer, " function"); 136233965Sjdp 136333965Sjdp if (flags & BSF_KEEP) 136433965Sjdp strcat (buffer, " keep"); 136533965Sjdp 136633965Sjdp if (flags & BSF_KEEP_G) 136733965Sjdp strcat (buffer, " keep_g"); 136833965Sjdp 136933965Sjdp if (flags & BSF_WEAK) 137033965Sjdp strcat (buffer, " weak"); 137133965Sjdp 137233965Sjdp if (flags & BSF_SECTION_SYM) 137333965Sjdp strcat (buffer, " section-sym"); 137433965Sjdp 137533965Sjdp if (flags & BSF_OLD_COMMON) 137633965Sjdp strcat (buffer, " old-common"); 137733965Sjdp 137833965Sjdp if (flags & BSF_NOT_AT_END) 137933965Sjdp strcat (buffer, " not-at-end"); 138033965Sjdp 138133965Sjdp if (flags & BSF_CONSTRUCTOR) 138233965Sjdp strcat (buffer, " constructor"); 138333965Sjdp 138433965Sjdp if (flags & BSF_WARNING) 138533965Sjdp strcat (buffer, " warning"); 138633965Sjdp 138733965Sjdp if (flags & BSF_INDIRECT) 138833965Sjdp strcat (buffer, " indirect"); 138933965Sjdp 139033965Sjdp if (flags & BSF_FILE) 139133965Sjdp strcat (buffer, " file"); 139233965Sjdp 139333965Sjdp if (flags & DYNAMIC) 139433965Sjdp strcat (buffer, " dynamic"); 139533965Sjdp 139633965Sjdp if (flags & ~(BSF_LOCAL 139733965Sjdp | BSF_GLOBAL 139833965Sjdp | BSF_DEBUGGING 139933965Sjdp | BSF_FUNCTION 140033965Sjdp | BSF_KEEP 140133965Sjdp | BSF_KEEP_G 140233965Sjdp | BSF_WEAK 140333965Sjdp | BSF_SECTION_SYM 140433965Sjdp | BSF_OLD_COMMON 140533965Sjdp | BSF_NOT_AT_END 140633965Sjdp | BSF_CONSTRUCTOR 140733965Sjdp | BSF_WARNING 140833965Sjdp | BSF_INDIRECT 140933965Sjdp | BSF_FILE 141033965Sjdp | BSF_DYNAMIC)) 141133965Sjdp strcat (buffer, " unknown-bits"); 141233965Sjdp 141333965Sjdp return buffer; 141433965Sjdp} 141533965Sjdp#endif 141633965Sjdp 141733965Sjdp#include "elfcore.h" 141833965Sjdp#include "elflink.h" 141933965Sjdp 142033965Sjdp/* Size-dependent data and functions. */ 142133965Sjdpconst struct elf_size_info NAME(_bfd_elf,size_info) = { 142233965Sjdp sizeof (Elf_External_Ehdr), 142333965Sjdp sizeof (Elf_External_Phdr), 142433965Sjdp sizeof (Elf_External_Shdr), 142533965Sjdp sizeof (Elf_External_Rel), 142633965Sjdp sizeof (Elf_External_Rela), 142733965Sjdp sizeof (Elf_External_Sym), 142833965Sjdp sizeof (Elf_External_Dyn), 142933965Sjdp sizeof (Elf_External_Note), 143033965Sjdp 143133965Sjdp ARCH_SIZE, FILE_ALIGN, 143233965Sjdp ELFCLASS, EV_CURRENT, 143333965Sjdp elf_write_out_phdrs, 143433965Sjdp elf_write_shdrs_and_ehdr, 143533965Sjdp write_relocs, 143633965Sjdp elf_swap_symbol_out, 143733965Sjdp elf_slurp_reloc_table, 143833965Sjdp elf_slurp_symbol_table, 143933965Sjdp elf_swap_dyn_in 144033965Sjdp}; 1441