15796c8dcSSimon Schubert /* ELF executable support for BFD.
25796c8dcSSimon Schubert Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3*ef5ccd6cSJohn Marino 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
45796c8dcSSimon Schubert Free Software Foundation, Inc.
55796c8dcSSimon Schubert
65796c8dcSSimon Schubert Written by Fred Fish @ Cygnus Support, from information published
75796c8dcSSimon Schubert in "UNIX System V Release 4, Programmers Guide: ANSI C and
85796c8dcSSimon Schubert Programming Support Tools". Sufficient support for gdb.
95796c8dcSSimon Schubert
105796c8dcSSimon Schubert Rewritten by Mark Eichin @ Cygnus Support, from information
115796c8dcSSimon Schubert published in "System V Application Binary Interface", chapters 4
125796c8dcSSimon Schubert and 5, as well as the various "Processor Supplement" documents
135796c8dcSSimon Schubert derived from it. Added support for assembler and other object file
145796c8dcSSimon Schubert utilities. Further work done by Ken Raeburn (Cygnus Support), Michael
155796c8dcSSimon Schubert Meissner (Open Software Foundation), and Peter Hoogenboom (University
165796c8dcSSimon Schubert of Utah) to finish and extend this.
175796c8dcSSimon Schubert
185796c8dcSSimon Schubert This file is part of BFD, the Binary File Descriptor library.
195796c8dcSSimon Schubert
205796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify
215796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by
225796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or
235796c8dcSSimon Schubert (at your option) any later version.
245796c8dcSSimon Schubert
255796c8dcSSimon Schubert This program is distributed in the hope that it will be useful,
265796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of
275796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
285796c8dcSSimon Schubert GNU General Public License for more details.
295796c8dcSSimon Schubert
305796c8dcSSimon Schubert You should have received a copy of the GNU General Public License
315796c8dcSSimon Schubert along with this program; if not, write to the Free Software
325796c8dcSSimon Schubert Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
335796c8dcSSimon Schubert MA 02110-1301, USA. */
345796c8dcSSimon Schubert
355796c8dcSSimon Schubert
365796c8dcSSimon Schubert /* Problems and other issues to resolve.
375796c8dcSSimon Schubert
385796c8dcSSimon Schubert (1) BFD expects there to be some fixed number of "sections" in
395796c8dcSSimon Schubert the object file. I.E. there is a "section_count" variable in the
405796c8dcSSimon Schubert bfd structure which contains the number of sections. However, ELF
415796c8dcSSimon Schubert supports multiple "views" of a file. In particular, with current
425796c8dcSSimon Schubert implementations, executable files typically have two tables, a
435796c8dcSSimon Schubert program header table and a section header table, both of which
445796c8dcSSimon Schubert partition the executable.
455796c8dcSSimon Schubert
465796c8dcSSimon Schubert In ELF-speak, the "linking view" of the file uses the section header
475796c8dcSSimon Schubert table to access "sections" within the file, and the "execution view"
485796c8dcSSimon Schubert uses the program header table to access "segments" within the file.
495796c8dcSSimon Schubert "Segments" typically may contain all the data from one or more
505796c8dcSSimon Schubert "sections".
515796c8dcSSimon Schubert
525796c8dcSSimon Schubert Note that the section header table is optional in ELF executables,
535796c8dcSSimon Schubert but it is this information that is most useful to gdb. If the
545796c8dcSSimon Schubert section header table is missing, then gdb should probably try
555796c8dcSSimon Schubert to make do with the program header table. (FIXME)
565796c8dcSSimon Schubert
575796c8dcSSimon Schubert (2) The code in this file is compiled twice, once in 32-bit mode and
585796c8dcSSimon Schubert once in 64-bit mode. More of it should be made size-independent
595796c8dcSSimon Schubert and moved into elf.c.
605796c8dcSSimon Schubert
615796c8dcSSimon Schubert (3) ELF section symbols are handled rather sloppily now. This should
625796c8dcSSimon Schubert be cleaned up, and ELF section symbols reconciled with BFD section
635796c8dcSSimon Schubert symbols.
645796c8dcSSimon Schubert
655796c8dcSSimon Schubert (4) We need a published spec for 64-bit ELF. We've got some stuff here
665796c8dcSSimon Schubert that we're using for SPARC V9 64-bit chips, but don't assume that
675796c8dcSSimon Schubert it's cast in stone.
685796c8dcSSimon Schubert */
695796c8dcSSimon Schubert
705796c8dcSSimon Schubert #include "sysdep.h"
715796c8dcSSimon Schubert #include "bfd.h"
725796c8dcSSimon Schubert #include "libiberty.h"
735796c8dcSSimon Schubert #include "bfdlink.h"
745796c8dcSSimon Schubert #include "libbfd.h"
755796c8dcSSimon Schubert #include "elf-bfd.h"
765796c8dcSSimon Schubert
775796c8dcSSimon Schubert /* Renaming structures, typedefs, macros and functions to be size-specific. */
785796c8dcSSimon Schubert #define Elf_External_Ehdr NAME(Elf,External_Ehdr)
795796c8dcSSimon Schubert #define Elf_External_Sym NAME(Elf,External_Sym)
805796c8dcSSimon Schubert #define Elf_External_Shdr NAME(Elf,External_Shdr)
815796c8dcSSimon Schubert #define Elf_External_Phdr NAME(Elf,External_Phdr)
825796c8dcSSimon Schubert #define Elf_External_Rel NAME(Elf,External_Rel)
835796c8dcSSimon Schubert #define Elf_External_Rela NAME(Elf,External_Rela)
845796c8dcSSimon Schubert #define Elf_External_Dyn NAME(Elf,External_Dyn)
855796c8dcSSimon Schubert
865796c8dcSSimon Schubert #define elf_core_file_failing_command NAME(bfd_elf,core_file_failing_command)
875796c8dcSSimon Schubert #define elf_core_file_failing_signal NAME(bfd_elf,core_file_failing_signal)
885796c8dcSSimon Schubert #define elf_core_file_matches_executable_p \
895796c8dcSSimon Schubert NAME(bfd_elf,core_file_matches_executable_p)
90c50c785cSJohn Marino #define elf_core_file_pid NAME(bfd_elf,core_file_pid)
915796c8dcSSimon Schubert #define elf_object_p NAME(bfd_elf,object_p)
925796c8dcSSimon Schubert #define elf_core_file_p NAME(bfd_elf,core_file_p)
935796c8dcSSimon Schubert #define elf_get_symtab_upper_bound NAME(bfd_elf,get_symtab_upper_bound)
945796c8dcSSimon Schubert #define elf_get_dynamic_symtab_upper_bound \
955796c8dcSSimon Schubert NAME(bfd_elf,get_dynamic_symtab_upper_bound)
965796c8dcSSimon Schubert #define elf_swap_reloc_in NAME(bfd_elf,swap_reloc_in)
975796c8dcSSimon Schubert #define elf_swap_reloca_in NAME(bfd_elf,swap_reloca_in)
985796c8dcSSimon Schubert #define elf_swap_reloc_out NAME(bfd_elf,swap_reloc_out)
995796c8dcSSimon Schubert #define elf_swap_reloca_out NAME(bfd_elf,swap_reloca_out)
1005796c8dcSSimon Schubert #define elf_swap_symbol_in NAME(bfd_elf,swap_symbol_in)
1015796c8dcSSimon Schubert #define elf_swap_symbol_out NAME(bfd_elf,swap_symbol_out)
1025796c8dcSSimon Schubert #define elf_swap_phdr_in NAME(bfd_elf,swap_phdr_in)
1035796c8dcSSimon Schubert #define elf_swap_phdr_out NAME(bfd_elf,swap_phdr_out)
1045796c8dcSSimon Schubert #define elf_swap_dyn_in NAME(bfd_elf,swap_dyn_in)
1055796c8dcSSimon Schubert #define elf_swap_dyn_out NAME(bfd_elf,swap_dyn_out)
1065796c8dcSSimon Schubert #define elf_get_reloc_upper_bound NAME(bfd_elf,get_reloc_upper_bound)
1075796c8dcSSimon Schubert #define elf_canonicalize_reloc NAME(bfd_elf,canonicalize_reloc)
1085796c8dcSSimon Schubert #define elf_slurp_symbol_table NAME(bfd_elf,slurp_symbol_table)
1095796c8dcSSimon Schubert #define elf_canonicalize_symtab NAME(bfd_elf,canonicalize_symtab)
1105796c8dcSSimon Schubert #define elf_canonicalize_dynamic_symtab \
1115796c8dcSSimon Schubert NAME(bfd_elf,canonicalize_dynamic_symtab)
1125796c8dcSSimon Schubert #define elf_get_synthetic_symtab \
1135796c8dcSSimon Schubert NAME(bfd_elf,get_synthetic_symtab)
1145796c8dcSSimon Schubert #define elf_make_empty_symbol NAME(bfd_elf,make_empty_symbol)
1155796c8dcSSimon Schubert #define elf_get_symbol_info NAME(bfd_elf,get_symbol_info)
1165796c8dcSSimon Schubert #define elf_get_lineno NAME(bfd_elf,get_lineno)
1175796c8dcSSimon Schubert #define elf_set_arch_mach NAME(bfd_elf,set_arch_mach)
1185796c8dcSSimon Schubert #define elf_find_nearest_line NAME(bfd_elf,find_nearest_line)
1195796c8dcSSimon Schubert #define elf_sizeof_headers NAME(bfd_elf,sizeof_headers)
1205796c8dcSSimon Schubert #define elf_set_section_contents NAME(bfd_elf,set_section_contents)
1215796c8dcSSimon Schubert #define elf_no_info_to_howto NAME(bfd_elf,no_info_to_howto)
1225796c8dcSSimon Schubert #define elf_no_info_to_howto_rel NAME(bfd_elf,no_info_to_howto_rel)
1235796c8dcSSimon Schubert #define elf_find_section NAME(bfd_elf,find_section)
1245796c8dcSSimon Schubert #define elf_write_shdrs_and_ehdr NAME(bfd_elf,write_shdrs_and_ehdr)
1255796c8dcSSimon Schubert #define elf_write_out_phdrs NAME(bfd_elf,write_out_phdrs)
1265796c8dcSSimon Schubert #define elf_checksum_contents NAME(bfd_elf,checksum_contents)
1275796c8dcSSimon Schubert #define elf_write_relocs NAME(bfd_elf,write_relocs)
1285796c8dcSSimon Schubert #define elf_slurp_reloc_table NAME(bfd_elf,slurp_reloc_table)
1295796c8dcSSimon Schubert
1305796c8dcSSimon Schubert #if ARCH_SIZE == 64
1315796c8dcSSimon Schubert #define ELF_R_INFO(X,Y) ELF64_R_INFO(X,Y)
1325796c8dcSSimon Schubert #define ELF_R_SYM(X) ELF64_R_SYM(X)
1335796c8dcSSimon Schubert #define ELF_R_TYPE(X) ELF64_R_TYPE(X)
1345796c8dcSSimon Schubert #define ELFCLASS ELFCLASS64
1355796c8dcSSimon Schubert #define FILE_ALIGN 8
1365796c8dcSSimon Schubert #define LOG_FILE_ALIGN 3
1375796c8dcSSimon Schubert #endif
1385796c8dcSSimon Schubert #if ARCH_SIZE == 32
1395796c8dcSSimon Schubert #define ELF_R_INFO(X,Y) ELF32_R_INFO(X,Y)
1405796c8dcSSimon Schubert #define ELF_R_SYM(X) ELF32_R_SYM(X)
1415796c8dcSSimon Schubert #define ELF_R_TYPE(X) ELF32_R_TYPE(X)
1425796c8dcSSimon Schubert #define ELFCLASS ELFCLASS32
1435796c8dcSSimon Schubert #define FILE_ALIGN 4
1445796c8dcSSimon Schubert #define LOG_FILE_ALIGN 2
1455796c8dcSSimon Schubert #endif
1465796c8dcSSimon Schubert
1475796c8dcSSimon Schubert #if DEBUG & 2
1485796c8dcSSimon Schubert static void elf_debug_section (int, Elf_Internal_Shdr *);
1495796c8dcSSimon Schubert #endif
1505796c8dcSSimon Schubert #if DEBUG & 1
1515796c8dcSSimon Schubert static void elf_debug_file (Elf_Internal_Ehdr *);
1525796c8dcSSimon Schubert #endif
1535796c8dcSSimon Schubert
1545796c8dcSSimon Schubert /* Structure swapping routines */
1555796c8dcSSimon Schubert
1565796c8dcSSimon Schubert /* Should perhaps use put_offset, put_word, etc. For now, the two versions
1575796c8dcSSimon Schubert can be handled by explicitly specifying 32 bits or "the long type". */
1585796c8dcSSimon Schubert #if ARCH_SIZE == 64
1595796c8dcSSimon Schubert #define H_PUT_WORD H_PUT_64
1605796c8dcSSimon Schubert #define H_PUT_SIGNED_WORD H_PUT_S64
1615796c8dcSSimon Schubert #define H_GET_WORD H_GET_64
1625796c8dcSSimon Schubert #define H_GET_SIGNED_WORD H_GET_S64
1635796c8dcSSimon Schubert #endif
1645796c8dcSSimon Schubert #if ARCH_SIZE == 32
1655796c8dcSSimon Schubert #define H_PUT_WORD H_PUT_32
1665796c8dcSSimon Schubert #define H_PUT_SIGNED_WORD H_PUT_S32
1675796c8dcSSimon Schubert #define H_GET_WORD H_GET_32
1685796c8dcSSimon Schubert #define H_GET_SIGNED_WORD H_GET_S32
1695796c8dcSSimon Schubert #endif
1705796c8dcSSimon Schubert
1715796c8dcSSimon Schubert /* Translate an ELF symbol in external format into an ELF symbol in internal
1725796c8dcSSimon Schubert format. */
1735796c8dcSSimon Schubert
1745796c8dcSSimon Schubert bfd_boolean
elf_swap_symbol_in(bfd * abfd,const void * psrc,const void * pshn,Elf_Internal_Sym * dst)1755796c8dcSSimon Schubert elf_swap_symbol_in (bfd *abfd,
1765796c8dcSSimon Schubert const void *psrc,
1775796c8dcSSimon Schubert const void *pshn,
1785796c8dcSSimon Schubert Elf_Internal_Sym *dst)
1795796c8dcSSimon Schubert {
1805796c8dcSSimon Schubert const Elf_External_Sym *src = (const Elf_External_Sym *) psrc;
1815796c8dcSSimon Schubert const Elf_External_Sym_Shndx *shndx = (const Elf_External_Sym_Shndx *) pshn;
1825796c8dcSSimon Schubert int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
1835796c8dcSSimon Schubert
1845796c8dcSSimon Schubert dst->st_name = H_GET_32 (abfd, src->st_name);
1855796c8dcSSimon Schubert if (signed_vma)
1865796c8dcSSimon Schubert dst->st_value = H_GET_SIGNED_WORD (abfd, src->st_value);
1875796c8dcSSimon Schubert else
1885796c8dcSSimon Schubert dst->st_value = H_GET_WORD (abfd, src->st_value);
1895796c8dcSSimon Schubert dst->st_size = H_GET_WORD (abfd, src->st_size);
1905796c8dcSSimon Schubert dst->st_info = H_GET_8 (abfd, src->st_info);
1915796c8dcSSimon Schubert dst->st_other = H_GET_8 (abfd, src->st_other);
1925796c8dcSSimon Schubert dst->st_shndx = H_GET_16 (abfd, src->st_shndx);
1935796c8dcSSimon Schubert if (dst->st_shndx == (SHN_XINDEX & 0xffff))
1945796c8dcSSimon Schubert {
1955796c8dcSSimon Schubert if (shndx == NULL)
1965796c8dcSSimon Schubert return FALSE;
1975796c8dcSSimon Schubert dst->st_shndx = H_GET_32 (abfd, shndx->est_shndx);
1985796c8dcSSimon Schubert }
1995796c8dcSSimon Schubert else if (dst->st_shndx >= (SHN_LORESERVE & 0xffff))
2005796c8dcSSimon Schubert dst->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
201c50c785cSJohn Marino dst->st_target_internal = 0;
2025796c8dcSSimon Schubert return TRUE;
2035796c8dcSSimon Schubert }
2045796c8dcSSimon Schubert
2055796c8dcSSimon Schubert /* Translate an ELF symbol in internal format into an ELF symbol in external
2065796c8dcSSimon Schubert format. */
2075796c8dcSSimon Schubert
2085796c8dcSSimon Schubert void
elf_swap_symbol_out(bfd * abfd,const Elf_Internal_Sym * src,void * cdst,void * shndx)2095796c8dcSSimon Schubert elf_swap_symbol_out (bfd *abfd,
2105796c8dcSSimon Schubert const Elf_Internal_Sym *src,
2115796c8dcSSimon Schubert void *cdst,
2125796c8dcSSimon Schubert void *shndx)
2135796c8dcSSimon Schubert {
2145796c8dcSSimon Schubert unsigned int tmp;
2155796c8dcSSimon Schubert Elf_External_Sym *dst = (Elf_External_Sym *) cdst;
2165796c8dcSSimon Schubert H_PUT_32 (abfd, src->st_name, dst->st_name);
2175796c8dcSSimon Schubert H_PUT_WORD (abfd, src->st_value, dst->st_value);
2185796c8dcSSimon Schubert H_PUT_WORD (abfd, src->st_size, dst->st_size);
2195796c8dcSSimon Schubert H_PUT_8 (abfd, src->st_info, dst->st_info);
2205796c8dcSSimon Schubert H_PUT_8 (abfd, src->st_other, dst->st_other);
2215796c8dcSSimon Schubert tmp = src->st_shndx;
2225796c8dcSSimon Schubert if (tmp >= (SHN_LORESERVE & 0xffff) && tmp < SHN_LORESERVE)
2235796c8dcSSimon Schubert {
2245796c8dcSSimon Schubert if (shndx == NULL)
2255796c8dcSSimon Schubert abort ();
2265796c8dcSSimon Schubert H_PUT_32 (abfd, tmp, shndx);
2275796c8dcSSimon Schubert tmp = SHN_XINDEX & 0xffff;
2285796c8dcSSimon Schubert }
2295796c8dcSSimon Schubert H_PUT_16 (abfd, tmp, dst->st_shndx);
2305796c8dcSSimon Schubert }
2315796c8dcSSimon Schubert
2325796c8dcSSimon Schubert /* Translate an ELF file header in external format into an ELF file header in
2335796c8dcSSimon Schubert internal format. */
2345796c8dcSSimon Schubert
2355796c8dcSSimon Schubert static void
elf_swap_ehdr_in(bfd * abfd,const Elf_External_Ehdr * src,Elf_Internal_Ehdr * dst)2365796c8dcSSimon Schubert elf_swap_ehdr_in (bfd *abfd,
2375796c8dcSSimon Schubert const Elf_External_Ehdr *src,
2385796c8dcSSimon Schubert Elf_Internal_Ehdr *dst)
2395796c8dcSSimon Schubert {
2405796c8dcSSimon Schubert int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
2415796c8dcSSimon Schubert memcpy (dst->e_ident, src->e_ident, EI_NIDENT);
2425796c8dcSSimon Schubert dst->e_type = H_GET_16 (abfd, src->e_type);
2435796c8dcSSimon Schubert dst->e_machine = H_GET_16 (abfd, src->e_machine);
2445796c8dcSSimon Schubert dst->e_version = H_GET_32 (abfd, src->e_version);
2455796c8dcSSimon Schubert if (signed_vma)
2465796c8dcSSimon Schubert dst->e_entry = H_GET_SIGNED_WORD (abfd, src->e_entry);
2475796c8dcSSimon Schubert else
2485796c8dcSSimon Schubert dst->e_entry = H_GET_WORD (abfd, src->e_entry);
2495796c8dcSSimon Schubert dst->e_phoff = H_GET_WORD (abfd, src->e_phoff);
2505796c8dcSSimon Schubert dst->e_shoff = H_GET_WORD (abfd, src->e_shoff);
2515796c8dcSSimon Schubert dst->e_flags = H_GET_32 (abfd, src->e_flags);
2525796c8dcSSimon Schubert dst->e_ehsize = H_GET_16 (abfd, src->e_ehsize);
2535796c8dcSSimon Schubert dst->e_phentsize = H_GET_16 (abfd, src->e_phentsize);
2545796c8dcSSimon Schubert dst->e_phnum = H_GET_16 (abfd, src->e_phnum);
2555796c8dcSSimon Schubert dst->e_shentsize = H_GET_16 (abfd, src->e_shentsize);
2565796c8dcSSimon Schubert dst->e_shnum = H_GET_16 (abfd, src->e_shnum);
2575796c8dcSSimon Schubert dst->e_shstrndx = H_GET_16 (abfd, src->e_shstrndx);
2585796c8dcSSimon Schubert }
2595796c8dcSSimon Schubert
2605796c8dcSSimon Schubert /* Translate an ELF file header in internal format into an ELF file header in
2615796c8dcSSimon Schubert external format. */
2625796c8dcSSimon Schubert
2635796c8dcSSimon Schubert static void
elf_swap_ehdr_out(bfd * abfd,const Elf_Internal_Ehdr * src,Elf_External_Ehdr * dst)2645796c8dcSSimon Schubert elf_swap_ehdr_out (bfd *abfd,
2655796c8dcSSimon Schubert const Elf_Internal_Ehdr *src,
2665796c8dcSSimon Schubert Elf_External_Ehdr *dst)
2675796c8dcSSimon Schubert {
2685796c8dcSSimon Schubert unsigned int tmp;
2695796c8dcSSimon Schubert int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
2705796c8dcSSimon Schubert memcpy (dst->e_ident, src->e_ident, EI_NIDENT);
2715796c8dcSSimon Schubert /* note that all elements of dst are *arrays of unsigned char* already... */
2725796c8dcSSimon Schubert H_PUT_16 (abfd, src->e_type, dst->e_type);
2735796c8dcSSimon Schubert H_PUT_16 (abfd, src->e_machine, dst->e_machine);
2745796c8dcSSimon Schubert H_PUT_32 (abfd, src->e_version, dst->e_version);
2755796c8dcSSimon Schubert if (signed_vma)
2765796c8dcSSimon Schubert H_PUT_SIGNED_WORD (abfd, src->e_entry, dst->e_entry);
2775796c8dcSSimon Schubert else
2785796c8dcSSimon Schubert H_PUT_WORD (abfd, src->e_entry, dst->e_entry);
2795796c8dcSSimon Schubert H_PUT_WORD (abfd, src->e_phoff, dst->e_phoff);
2805796c8dcSSimon Schubert H_PUT_WORD (abfd, src->e_shoff, dst->e_shoff);
2815796c8dcSSimon Schubert H_PUT_32 (abfd, src->e_flags, dst->e_flags);
2825796c8dcSSimon Schubert H_PUT_16 (abfd, src->e_ehsize, dst->e_ehsize);
2835796c8dcSSimon Schubert H_PUT_16 (abfd, src->e_phentsize, dst->e_phentsize);
284cf7f2e2dSJohn Marino tmp = src->e_phnum;
285cf7f2e2dSJohn Marino if (tmp > PN_XNUM)
286cf7f2e2dSJohn Marino tmp = PN_XNUM;
287cf7f2e2dSJohn Marino H_PUT_16 (abfd, tmp, dst->e_phnum);
2885796c8dcSSimon Schubert H_PUT_16 (abfd, src->e_shentsize, dst->e_shentsize);
2895796c8dcSSimon Schubert tmp = src->e_shnum;
2905796c8dcSSimon Schubert if (tmp >= (SHN_LORESERVE & 0xffff))
2915796c8dcSSimon Schubert tmp = SHN_UNDEF;
2925796c8dcSSimon Schubert H_PUT_16 (abfd, tmp, dst->e_shnum);
2935796c8dcSSimon Schubert tmp = src->e_shstrndx;
2945796c8dcSSimon Schubert if (tmp >= (SHN_LORESERVE & 0xffff))
2955796c8dcSSimon Schubert tmp = SHN_XINDEX & 0xffff;
2965796c8dcSSimon Schubert H_PUT_16 (abfd, tmp, dst->e_shstrndx);
2975796c8dcSSimon Schubert }
2985796c8dcSSimon Schubert
2995796c8dcSSimon Schubert /* Translate an ELF section header table entry in external format into an
3005796c8dcSSimon Schubert ELF section header table entry in internal format. */
3015796c8dcSSimon Schubert
3025796c8dcSSimon Schubert static void
elf_swap_shdr_in(bfd * abfd,const Elf_External_Shdr * src,Elf_Internal_Shdr * dst)3035796c8dcSSimon Schubert elf_swap_shdr_in (bfd *abfd,
3045796c8dcSSimon Schubert const Elf_External_Shdr *src,
3055796c8dcSSimon Schubert Elf_Internal_Shdr *dst)
3065796c8dcSSimon Schubert {
3075796c8dcSSimon Schubert int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
3085796c8dcSSimon Schubert
3095796c8dcSSimon Schubert dst->sh_name = H_GET_32 (abfd, src->sh_name);
3105796c8dcSSimon Schubert dst->sh_type = H_GET_32 (abfd, src->sh_type);
3115796c8dcSSimon Schubert dst->sh_flags = H_GET_WORD (abfd, src->sh_flags);
3125796c8dcSSimon Schubert if (signed_vma)
3135796c8dcSSimon Schubert dst->sh_addr = H_GET_SIGNED_WORD (abfd, src->sh_addr);
3145796c8dcSSimon Schubert else
3155796c8dcSSimon Schubert dst->sh_addr = H_GET_WORD (abfd, src->sh_addr);
3165796c8dcSSimon Schubert dst->sh_offset = H_GET_WORD (abfd, src->sh_offset);
3175796c8dcSSimon Schubert dst->sh_size = H_GET_WORD (abfd, src->sh_size);
3185796c8dcSSimon Schubert dst->sh_link = H_GET_32 (abfd, src->sh_link);
3195796c8dcSSimon Schubert dst->sh_info = H_GET_32 (abfd, src->sh_info);
3205796c8dcSSimon Schubert dst->sh_addralign = H_GET_WORD (abfd, src->sh_addralign);
3215796c8dcSSimon Schubert dst->sh_entsize = H_GET_WORD (abfd, src->sh_entsize);
3225796c8dcSSimon Schubert dst->bfd_section = NULL;
3235796c8dcSSimon Schubert dst->contents = NULL;
3245796c8dcSSimon Schubert }
3255796c8dcSSimon Schubert
3265796c8dcSSimon Schubert /* Translate an ELF section header table entry in internal format into an
3275796c8dcSSimon Schubert ELF section header table entry in external format. */
3285796c8dcSSimon Schubert
3295796c8dcSSimon Schubert static void
elf_swap_shdr_out(bfd * abfd,const Elf_Internal_Shdr * src,Elf_External_Shdr * dst)3305796c8dcSSimon Schubert elf_swap_shdr_out (bfd *abfd,
3315796c8dcSSimon Schubert const Elf_Internal_Shdr *src,
3325796c8dcSSimon Schubert Elf_External_Shdr *dst)
3335796c8dcSSimon Schubert {
3345796c8dcSSimon Schubert /* note that all elements of dst are *arrays of unsigned char* already... */
3355796c8dcSSimon Schubert H_PUT_32 (abfd, src->sh_name, dst->sh_name);
3365796c8dcSSimon Schubert H_PUT_32 (abfd, src->sh_type, dst->sh_type);
3375796c8dcSSimon Schubert H_PUT_WORD (abfd, src->sh_flags, dst->sh_flags);
3385796c8dcSSimon Schubert H_PUT_WORD (abfd, src->sh_addr, dst->sh_addr);
3395796c8dcSSimon Schubert H_PUT_WORD (abfd, src->sh_offset, dst->sh_offset);
3405796c8dcSSimon Schubert H_PUT_WORD (abfd, src->sh_size, dst->sh_size);
3415796c8dcSSimon Schubert H_PUT_32 (abfd, src->sh_link, dst->sh_link);
3425796c8dcSSimon Schubert H_PUT_32 (abfd, src->sh_info, dst->sh_info);
3435796c8dcSSimon Schubert H_PUT_WORD (abfd, src->sh_addralign, dst->sh_addralign);
3445796c8dcSSimon Schubert H_PUT_WORD (abfd, src->sh_entsize, dst->sh_entsize);
3455796c8dcSSimon Schubert }
3465796c8dcSSimon Schubert
3475796c8dcSSimon Schubert /* Translate an ELF program header table entry in external format into an
3485796c8dcSSimon Schubert ELF program header table entry in internal format. */
3495796c8dcSSimon Schubert
3505796c8dcSSimon Schubert void
elf_swap_phdr_in(bfd * abfd,const Elf_External_Phdr * src,Elf_Internal_Phdr * dst)3515796c8dcSSimon Schubert elf_swap_phdr_in (bfd *abfd,
3525796c8dcSSimon Schubert const Elf_External_Phdr *src,
3535796c8dcSSimon Schubert Elf_Internal_Phdr *dst)
3545796c8dcSSimon Schubert {
3555796c8dcSSimon Schubert int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
3565796c8dcSSimon Schubert
3575796c8dcSSimon Schubert dst->p_type = H_GET_32 (abfd, src->p_type);
3585796c8dcSSimon Schubert dst->p_flags = H_GET_32 (abfd, src->p_flags);
3595796c8dcSSimon Schubert dst->p_offset = H_GET_WORD (abfd, src->p_offset);
3605796c8dcSSimon Schubert if (signed_vma)
3615796c8dcSSimon Schubert {
3625796c8dcSSimon Schubert dst->p_vaddr = H_GET_SIGNED_WORD (abfd, src->p_vaddr);
3635796c8dcSSimon Schubert dst->p_paddr = H_GET_SIGNED_WORD (abfd, src->p_paddr);
3645796c8dcSSimon Schubert }
3655796c8dcSSimon Schubert else
3665796c8dcSSimon Schubert {
3675796c8dcSSimon Schubert dst->p_vaddr = H_GET_WORD (abfd, src->p_vaddr);
3685796c8dcSSimon Schubert dst->p_paddr = H_GET_WORD (abfd, src->p_paddr);
3695796c8dcSSimon Schubert }
3705796c8dcSSimon Schubert dst->p_filesz = H_GET_WORD (abfd, src->p_filesz);
3715796c8dcSSimon Schubert dst->p_memsz = H_GET_WORD (abfd, src->p_memsz);
3725796c8dcSSimon Schubert dst->p_align = H_GET_WORD (abfd, src->p_align);
3735796c8dcSSimon Schubert }
3745796c8dcSSimon Schubert
3755796c8dcSSimon Schubert void
elf_swap_phdr_out(bfd * abfd,const Elf_Internal_Phdr * src,Elf_External_Phdr * dst)3765796c8dcSSimon Schubert elf_swap_phdr_out (bfd *abfd,
3775796c8dcSSimon Schubert const Elf_Internal_Phdr *src,
3785796c8dcSSimon Schubert Elf_External_Phdr *dst)
3795796c8dcSSimon Schubert {
3805796c8dcSSimon Schubert const struct elf_backend_data *bed;
3815796c8dcSSimon Schubert bfd_vma p_paddr;
3825796c8dcSSimon Schubert
3835796c8dcSSimon Schubert bed = get_elf_backend_data (abfd);
3845796c8dcSSimon Schubert p_paddr = bed->want_p_paddr_set_to_zero ? 0 : src->p_paddr;
3855796c8dcSSimon Schubert
3865796c8dcSSimon Schubert /* note that all elements of dst are *arrays of unsigned char* already... */
3875796c8dcSSimon Schubert H_PUT_32 (abfd, src->p_type, dst->p_type);
3885796c8dcSSimon Schubert H_PUT_WORD (abfd, src->p_offset, dst->p_offset);
3895796c8dcSSimon Schubert H_PUT_WORD (abfd, src->p_vaddr, dst->p_vaddr);
3905796c8dcSSimon Schubert H_PUT_WORD (abfd, p_paddr, dst->p_paddr);
3915796c8dcSSimon Schubert H_PUT_WORD (abfd, src->p_filesz, dst->p_filesz);
3925796c8dcSSimon Schubert H_PUT_WORD (abfd, src->p_memsz, dst->p_memsz);
3935796c8dcSSimon Schubert H_PUT_32 (abfd, src->p_flags, dst->p_flags);
3945796c8dcSSimon Schubert H_PUT_WORD (abfd, src->p_align, dst->p_align);
3955796c8dcSSimon Schubert }
3965796c8dcSSimon Schubert
3975796c8dcSSimon Schubert /* Translate an ELF reloc from external format to internal format. */
3985796c8dcSSimon Schubert void
elf_swap_reloc_in(bfd * abfd,const bfd_byte * s,Elf_Internal_Rela * dst)3995796c8dcSSimon Schubert elf_swap_reloc_in (bfd *abfd,
4005796c8dcSSimon Schubert const bfd_byte *s,
4015796c8dcSSimon Schubert Elf_Internal_Rela *dst)
4025796c8dcSSimon Schubert {
4035796c8dcSSimon Schubert const Elf_External_Rel *src = (const Elf_External_Rel *) s;
4045796c8dcSSimon Schubert dst->r_offset = H_GET_WORD (abfd, src->r_offset);
4055796c8dcSSimon Schubert dst->r_info = H_GET_WORD (abfd, src->r_info);
4065796c8dcSSimon Schubert dst->r_addend = 0;
4075796c8dcSSimon Schubert }
4085796c8dcSSimon Schubert
4095796c8dcSSimon Schubert void
elf_swap_reloca_in(bfd * abfd,const bfd_byte * s,Elf_Internal_Rela * dst)4105796c8dcSSimon Schubert elf_swap_reloca_in (bfd *abfd,
4115796c8dcSSimon Schubert const bfd_byte *s,
4125796c8dcSSimon Schubert Elf_Internal_Rela *dst)
4135796c8dcSSimon Schubert {
4145796c8dcSSimon Schubert const Elf_External_Rela *src = (const Elf_External_Rela *) s;
4155796c8dcSSimon Schubert dst->r_offset = H_GET_WORD (abfd, src->r_offset);
4165796c8dcSSimon Schubert dst->r_info = H_GET_WORD (abfd, src->r_info);
4175796c8dcSSimon Schubert dst->r_addend = H_GET_SIGNED_WORD (abfd, src->r_addend);
4185796c8dcSSimon Schubert }
4195796c8dcSSimon Schubert
4205796c8dcSSimon Schubert /* Translate an ELF reloc from internal format to external format. */
4215796c8dcSSimon Schubert void
elf_swap_reloc_out(bfd * abfd,const Elf_Internal_Rela * src,bfd_byte * d)4225796c8dcSSimon Schubert elf_swap_reloc_out (bfd *abfd,
4235796c8dcSSimon Schubert const Elf_Internal_Rela *src,
4245796c8dcSSimon Schubert bfd_byte *d)
4255796c8dcSSimon Schubert {
4265796c8dcSSimon Schubert Elf_External_Rel *dst = (Elf_External_Rel *) d;
4275796c8dcSSimon Schubert H_PUT_WORD (abfd, src->r_offset, dst->r_offset);
4285796c8dcSSimon Schubert H_PUT_WORD (abfd, src->r_info, dst->r_info);
4295796c8dcSSimon Schubert }
4305796c8dcSSimon Schubert
4315796c8dcSSimon Schubert void
elf_swap_reloca_out(bfd * abfd,const Elf_Internal_Rela * src,bfd_byte * d)4325796c8dcSSimon Schubert elf_swap_reloca_out (bfd *abfd,
4335796c8dcSSimon Schubert const Elf_Internal_Rela *src,
4345796c8dcSSimon Schubert bfd_byte *d)
4355796c8dcSSimon Schubert {
4365796c8dcSSimon Schubert Elf_External_Rela *dst = (Elf_External_Rela *) d;
4375796c8dcSSimon Schubert H_PUT_WORD (abfd, src->r_offset, dst->r_offset);
4385796c8dcSSimon Schubert H_PUT_WORD (abfd, src->r_info, dst->r_info);
4395796c8dcSSimon Schubert H_PUT_SIGNED_WORD (abfd, src->r_addend, dst->r_addend);
4405796c8dcSSimon Schubert }
4415796c8dcSSimon Schubert
4425796c8dcSSimon Schubert void
elf_swap_dyn_in(bfd * abfd,const void * p,Elf_Internal_Dyn * dst)4435796c8dcSSimon Schubert elf_swap_dyn_in (bfd *abfd,
4445796c8dcSSimon Schubert const void *p,
4455796c8dcSSimon Schubert Elf_Internal_Dyn *dst)
4465796c8dcSSimon Schubert {
4475796c8dcSSimon Schubert const Elf_External_Dyn *src = (const Elf_External_Dyn *) p;
4485796c8dcSSimon Schubert
4495796c8dcSSimon Schubert dst->d_tag = H_GET_WORD (abfd, src->d_tag);
4505796c8dcSSimon Schubert dst->d_un.d_val = H_GET_WORD (abfd, src->d_un.d_val);
4515796c8dcSSimon Schubert }
4525796c8dcSSimon Schubert
4535796c8dcSSimon Schubert void
elf_swap_dyn_out(bfd * abfd,const Elf_Internal_Dyn * src,void * p)4545796c8dcSSimon Schubert elf_swap_dyn_out (bfd *abfd,
4555796c8dcSSimon Schubert const Elf_Internal_Dyn *src,
4565796c8dcSSimon Schubert void *p)
4575796c8dcSSimon Schubert {
4585796c8dcSSimon Schubert Elf_External_Dyn *dst = (Elf_External_Dyn *) p;
4595796c8dcSSimon Schubert
4605796c8dcSSimon Schubert H_PUT_WORD (abfd, src->d_tag, dst->d_tag);
4615796c8dcSSimon Schubert H_PUT_WORD (abfd, src->d_un.d_val, dst->d_un.d_val);
4625796c8dcSSimon Schubert }
4635796c8dcSSimon Schubert
4645796c8dcSSimon Schubert /* ELF .o/exec file reading */
4655796c8dcSSimon Schubert
4665796c8dcSSimon Schubert /* Begin processing a given object.
4675796c8dcSSimon Schubert
4685796c8dcSSimon Schubert First we validate the file by reading in the ELF header and checking
4695796c8dcSSimon Schubert the magic number. */
4705796c8dcSSimon Schubert
4715796c8dcSSimon Schubert static inline bfd_boolean
elf_file_p(Elf_External_Ehdr * x_ehdrp)4725796c8dcSSimon Schubert elf_file_p (Elf_External_Ehdr *x_ehdrp)
4735796c8dcSSimon Schubert {
4745796c8dcSSimon Schubert return ((x_ehdrp->e_ident[EI_MAG0] == ELFMAG0)
4755796c8dcSSimon Schubert && (x_ehdrp->e_ident[EI_MAG1] == ELFMAG1)
4765796c8dcSSimon Schubert && (x_ehdrp->e_ident[EI_MAG2] == ELFMAG2)
4775796c8dcSSimon Schubert && (x_ehdrp->e_ident[EI_MAG3] == ELFMAG3));
4785796c8dcSSimon Schubert }
4795796c8dcSSimon Schubert
4805796c8dcSSimon Schubert /* Check to see if the file associated with ABFD matches the target vector
4815796c8dcSSimon Schubert that ABFD points to.
4825796c8dcSSimon Schubert
4835796c8dcSSimon Schubert Note that we may be called several times with the same ABFD, but different
4845796c8dcSSimon Schubert target vectors, most of which will not match. We have to avoid leaving
4855796c8dcSSimon Schubert any side effects in ABFD, or any data it points to (like tdata), if the
4865796c8dcSSimon Schubert file does not match the target vector. */
4875796c8dcSSimon Schubert
4885796c8dcSSimon Schubert const bfd_target *
elf_object_p(bfd * abfd)4895796c8dcSSimon Schubert elf_object_p (bfd *abfd)
4905796c8dcSSimon Schubert {
4915796c8dcSSimon Schubert Elf_External_Ehdr x_ehdr; /* Elf file header, external form */
4925796c8dcSSimon Schubert Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */
4935796c8dcSSimon Schubert Elf_External_Shdr x_shdr; /* Section header table entry, external form */
4945796c8dcSSimon Schubert Elf_Internal_Shdr i_shdr;
4955796c8dcSSimon Schubert Elf_Internal_Shdr *i_shdrp; /* Section header table, internal form */
4965796c8dcSSimon Schubert unsigned int shindex;
4975796c8dcSSimon Schubert const struct elf_backend_data *ebd;
4985796c8dcSSimon Schubert asection *s;
4995796c8dcSSimon Schubert bfd_size_type amt;
5005796c8dcSSimon Schubert const bfd_target *target;
5015796c8dcSSimon Schubert
5025796c8dcSSimon Schubert /* Read in the ELF header in external format. */
5035796c8dcSSimon Schubert
5045796c8dcSSimon Schubert if (bfd_bread (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr))
5055796c8dcSSimon Schubert {
5065796c8dcSSimon Schubert if (bfd_get_error () != bfd_error_system_call)
5075796c8dcSSimon Schubert goto got_wrong_format_error;
5085796c8dcSSimon Schubert else
5095796c8dcSSimon Schubert goto got_no_match;
5105796c8dcSSimon Schubert }
5115796c8dcSSimon Schubert
5125796c8dcSSimon Schubert /* Now check to see if we have a valid ELF file, and one that BFD can
5135796c8dcSSimon Schubert make use of. The magic number must match, the address size ('class')
5145796c8dcSSimon Schubert and byte-swapping must match our XVEC entry, and it must have a
5155796c8dcSSimon Schubert section header table (FIXME: See comments re sections at top of this
5165796c8dcSSimon Schubert file). */
5175796c8dcSSimon Schubert
5185796c8dcSSimon Schubert if (! elf_file_p (&x_ehdr)
5195796c8dcSSimon Schubert || x_ehdr.e_ident[EI_VERSION] != EV_CURRENT
5205796c8dcSSimon Schubert || x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
5215796c8dcSSimon Schubert goto got_wrong_format_error;
5225796c8dcSSimon Schubert
5235796c8dcSSimon Schubert /* Check that file's byte order matches xvec's */
5245796c8dcSSimon Schubert switch (x_ehdr.e_ident[EI_DATA])
5255796c8dcSSimon Schubert {
5265796c8dcSSimon Schubert case ELFDATA2MSB: /* Big-endian */
5275796c8dcSSimon Schubert if (! bfd_header_big_endian (abfd))
5285796c8dcSSimon Schubert goto got_wrong_format_error;
5295796c8dcSSimon Schubert break;
5305796c8dcSSimon Schubert case ELFDATA2LSB: /* Little-endian */
5315796c8dcSSimon Schubert if (! bfd_header_little_endian (abfd))
5325796c8dcSSimon Schubert goto got_wrong_format_error;
5335796c8dcSSimon Schubert break;
5345796c8dcSSimon Schubert case ELFDATANONE: /* No data encoding specified */
5355796c8dcSSimon Schubert default: /* Unknown data encoding specified */
5365796c8dcSSimon Schubert goto got_wrong_format_error;
5375796c8dcSSimon Schubert }
5385796c8dcSSimon Schubert
5395796c8dcSSimon Schubert target = abfd->xvec;
5405796c8dcSSimon Schubert
5415796c8dcSSimon Schubert /* Allocate an instance of the elf_obj_tdata structure and hook it up to
5425796c8dcSSimon Schubert the tdata pointer in the bfd. */
5435796c8dcSSimon Schubert
5445796c8dcSSimon Schubert if (! (*target->_bfd_set_format[bfd_object]) (abfd))
5455796c8dcSSimon Schubert goto got_no_match;
5465796c8dcSSimon Schubert
5475796c8dcSSimon Schubert /* Now that we know the byte order, swap in the rest of the header */
5485796c8dcSSimon Schubert i_ehdrp = elf_elfheader (abfd);
5495796c8dcSSimon Schubert elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
5505796c8dcSSimon Schubert #if DEBUG & 1
5515796c8dcSSimon Schubert elf_debug_file (i_ehdrp);
5525796c8dcSSimon Schubert #endif
5535796c8dcSSimon Schubert
5545796c8dcSSimon Schubert /* Reject ET_CORE (header indicates core file, not object file) */
5555796c8dcSSimon Schubert if (i_ehdrp->e_type == ET_CORE)
5565796c8dcSSimon Schubert goto got_wrong_format_error;
5575796c8dcSSimon Schubert
5585796c8dcSSimon Schubert /* If this is a relocatable file and there is no section header
5595796c8dcSSimon Schubert table, then we're hosed. */
5605796c8dcSSimon Schubert if (i_ehdrp->e_shoff == 0 && i_ehdrp->e_type == ET_REL)
5615796c8dcSSimon Schubert goto got_wrong_format_error;
5625796c8dcSSimon Schubert
5635796c8dcSSimon Schubert /* As a simple sanity check, verify that what BFD thinks is the
5645796c8dcSSimon Schubert size of each section header table entry actually matches the size
5655796c8dcSSimon Schubert recorded in the file, but only if there are any sections. */
5665796c8dcSSimon Schubert if (i_ehdrp->e_shentsize != sizeof (x_shdr) && i_ehdrp->e_shnum != 0)
5675796c8dcSSimon Schubert goto got_wrong_format_error;
5685796c8dcSSimon Schubert
5695796c8dcSSimon Schubert /* Further sanity check. */
5705796c8dcSSimon Schubert if (i_ehdrp->e_shoff == 0 && i_ehdrp->e_shnum != 0)
5715796c8dcSSimon Schubert goto got_wrong_format_error;
5725796c8dcSSimon Schubert
5735796c8dcSSimon Schubert ebd = get_elf_backend_data (abfd);
5745796c8dcSSimon Schubert if (ebd->s->arch_size != ARCH_SIZE)
5755796c8dcSSimon Schubert goto got_wrong_format_error;
5765796c8dcSSimon Schubert
5775796c8dcSSimon Schubert /* Check that the ELF e_machine field matches what this particular
5785796c8dcSSimon Schubert BFD format expects. */
5795796c8dcSSimon Schubert if (ebd->elf_machine_code != i_ehdrp->e_machine
5805796c8dcSSimon Schubert && (ebd->elf_machine_alt1 == 0
5815796c8dcSSimon Schubert || i_ehdrp->e_machine != ebd->elf_machine_alt1)
5825796c8dcSSimon Schubert && (ebd->elf_machine_alt2 == 0
583a45ae5f8SJohn Marino || i_ehdrp->e_machine != ebd->elf_machine_alt2)
584a45ae5f8SJohn Marino && ebd->elf_machine_code != EM_NONE)
5855796c8dcSSimon Schubert goto got_wrong_format_error;
5865796c8dcSSimon Schubert
5875796c8dcSSimon Schubert if (i_ehdrp->e_type == ET_EXEC)
5885796c8dcSSimon Schubert abfd->flags |= EXEC_P;
5895796c8dcSSimon Schubert else if (i_ehdrp->e_type == ET_DYN)
5905796c8dcSSimon Schubert abfd->flags |= DYNAMIC;
5915796c8dcSSimon Schubert
5925796c8dcSSimon Schubert if (i_ehdrp->e_phnum > 0)
5935796c8dcSSimon Schubert abfd->flags |= D_PAGED;
5945796c8dcSSimon Schubert
5955796c8dcSSimon Schubert if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0))
5965796c8dcSSimon Schubert {
5975796c8dcSSimon Schubert /* It's OK if this fails for the generic target. */
5985796c8dcSSimon Schubert if (ebd->elf_machine_code != EM_NONE)
5995796c8dcSSimon Schubert goto got_no_match;
6005796c8dcSSimon Schubert }
6015796c8dcSSimon Schubert
6025796c8dcSSimon Schubert if (ebd->elf_machine_code != EM_NONE
603a45ae5f8SJohn Marino && i_ehdrp->e_ident[EI_OSABI] != ebd->elf_osabi
604a45ae5f8SJohn Marino && ebd->elf_osabi != ELFOSABI_NONE)
6055796c8dcSSimon Schubert goto got_wrong_format_error;
6065796c8dcSSimon Schubert
6075796c8dcSSimon Schubert if (i_ehdrp->e_shoff != 0)
6085796c8dcSSimon Schubert {
6095796c8dcSSimon Schubert bfd_signed_vma where = i_ehdrp->e_shoff;
6105796c8dcSSimon Schubert
6115796c8dcSSimon Schubert if (where != (file_ptr) where)
6125796c8dcSSimon Schubert goto got_wrong_format_error;
6135796c8dcSSimon Schubert
6145796c8dcSSimon Schubert /* Seek to the section header table in the file. */
6155796c8dcSSimon Schubert if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
6165796c8dcSSimon Schubert goto got_no_match;
6175796c8dcSSimon Schubert
6185796c8dcSSimon Schubert /* Read the first section header at index 0, and convert to internal
6195796c8dcSSimon Schubert form. */
6205796c8dcSSimon Schubert if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr))
6215796c8dcSSimon Schubert goto got_no_match;
6225796c8dcSSimon Schubert elf_swap_shdr_in (abfd, &x_shdr, &i_shdr);
6235796c8dcSSimon Schubert
6245796c8dcSSimon Schubert /* If the section count is zero, the actual count is in the first
6255796c8dcSSimon Schubert section header. */
6265796c8dcSSimon Schubert if (i_ehdrp->e_shnum == SHN_UNDEF)
6275796c8dcSSimon Schubert {
6285796c8dcSSimon Schubert i_ehdrp->e_shnum = i_shdr.sh_size;
629*ef5ccd6cSJohn Marino if (i_ehdrp->e_shnum >= SHN_LORESERVE
630*ef5ccd6cSJohn Marino || i_ehdrp->e_shnum != i_shdr.sh_size
6315796c8dcSSimon Schubert || i_ehdrp->e_shnum == 0)
6325796c8dcSSimon Schubert goto got_wrong_format_error;
6335796c8dcSSimon Schubert }
6345796c8dcSSimon Schubert
6355796c8dcSSimon Schubert /* And similarly for the string table index. */
6365796c8dcSSimon Schubert if (i_ehdrp->e_shstrndx == (SHN_XINDEX & 0xffff))
6375796c8dcSSimon Schubert {
6385796c8dcSSimon Schubert i_ehdrp->e_shstrndx = i_shdr.sh_link;
6395796c8dcSSimon Schubert if (i_ehdrp->e_shstrndx != i_shdr.sh_link)
6405796c8dcSSimon Schubert goto got_wrong_format_error;
6415796c8dcSSimon Schubert }
6425796c8dcSSimon Schubert
643cf7f2e2dSJohn Marino /* And program headers. */
644cf7f2e2dSJohn Marino if (i_ehdrp->e_phnum == PN_XNUM && i_shdr.sh_info != 0)
645cf7f2e2dSJohn Marino {
646cf7f2e2dSJohn Marino i_ehdrp->e_phnum = i_shdr.sh_info;
647cf7f2e2dSJohn Marino if (i_ehdrp->e_phnum != i_shdr.sh_info)
648cf7f2e2dSJohn Marino goto got_wrong_format_error;
649cf7f2e2dSJohn Marino }
650cf7f2e2dSJohn Marino
6515796c8dcSSimon Schubert /* Sanity check that we can read all of the section headers.
6525796c8dcSSimon Schubert It ought to be good enough to just read the last one. */
6535796c8dcSSimon Schubert if (i_ehdrp->e_shnum != 1)
6545796c8dcSSimon Schubert {
6555796c8dcSSimon Schubert /* Check that we don't have a totally silly number of sections. */
6565796c8dcSSimon Schubert if (i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (x_shdr)
6575796c8dcSSimon Schubert || i_ehdrp->e_shnum > (unsigned int) -1 / sizeof (i_shdr))
6585796c8dcSSimon Schubert goto got_wrong_format_error;
6595796c8dcSSimon Schubert
6605796c8dcSSimon Schubert where += (i_ehdrp->e_shnum - 1) * sizeof (x_shdr);
6615796c8dcSSimon Schubert if (where != (file_ptr) where)
6625796c8dcSSimon Schubert goto got_wrong_format_error;
6635796c8dcSSimon Schubert if ((bfd_size_type) where <= i_ehdrp->e_shoff)
6645796c8dcSSimon Schubert goto got_wrong_format_error;
6655796c8dcSSimon Schubert
6665796c8dcSSimon Schubert if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
6675796c8dcSSimon Schubert goto got_no_match;
6685796c8dcSSimon Schubert if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr))
6695796c8dcSSimon Schubert goto got_no_match;
6705796c8dcSSimon Schubert
6715796c8dcSSimon Schubert /* Back to where we were. */
6725796c8dcSSimon Schubert where = i_ehdrp->e_shoff + sizeof (x_shdr);
6735796c8dcSSimon Schubert if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
6745796c8dcSSimon Schubert goto got_no_match;
6755796c8dcSSimon Schubert }
6765796c8dcSSimon Schubert }
6775796c8dcSSimon Schubert
6785796c8dcSSimon Schubert /* Allocate space for a copy of the section header table in
6795796c8dcSSimon Schubert internal form. */
6805796c8dcSSimon Schubert if (i_ehdrp->e_shnum != 0)
6815796c8dcSSimon Schubert {
6825796c8dcSSimon Schubert Elf_Internal_Shdr *shdrp;
6835796c8dcSSimon Schubert unsigned int num_sec;
6845796c8dcSSimon Schubert
6855796c8dcSSimon Schubert amt = sizeof (*i_shdrp) * i_ehdrp->e_shnum;
6865796c8dcSSimon Schubert i_shdrp = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
6875796c8dcSSimon Schubert if (!i_shdrp)
6885796c8dcSSimon Schubert goto got_no_match;
6895796c8dcSSimon Schubert num_sec = i_ehdrp->e_shnum;
6905796c8dcSSimon Schubert elf_numsections (abfd) = num_sec;
6915796c8dcSSimon Schubert amt = sizeof (i_shdrp) * num_sec;
6925796c8dcSSimon Schubert elf_elfsections (abfd) = (Elf_Internal_Shdr **) bfd_alloc (abfd, amt);
6935796c8dcSSimon Schubert if (!elf_elfsections (abfd))
6945796c8dcSSimon Schubert goto got_no_match;
6955796c8dcSSimon Schubert
6965796c8dcSSimon Schubert memcpy (i_shdrp, &i_shdr, sizeof (*i_shdrp));
6975796c8dcSSimon Schubert for (shdrp = i_shdrp, shindex = 0; shindex < num_sec; shindex++)
6985796c8dcSSimon Schubert elf_elfsections (abfd)[shindex] = shdrp++;
6995796c8dcSSimon Schubert
7005796c8dcSSimon Schubert /* Read in the rest of the section header table and convert it
7015796c8dcSSimon Schubert to internal form. */
7025796c8dcSSimon Schubert for (shindex = 1; shindex < i_ehdrp->e_shnum; shindex++)
7035796c8dcSSimon Schubert {
7045796c8dcSSimon Schubert if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr))
7055796c8dcSSimon Schubert goto got_no_match;
7065796c8dcSSimon Schubert elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex);
7075796c8dcSSimon Schubert
7085796c8dcSSimon Schubert /* Sanity check sh_link and sh_info. */
7095796c8dcSSimon Schubert if (i_shdrp[shindex].sh_link >= num_sec)
7105796c8dcSSimon Schubert {
711cf7f2e2dSJohn Marino /* PR 10478: Accept Solaris binaries with a sh_link
7125796c8dcSSimon Schubert field set to SHN_BEFORE or SHN_AFTER. */
7135796c8dcSSimon Schubert switch (ebd->elf_machine_code)
7145796c8dcSSimon Schubert {
715cf7f2e2dSJohn Marino case EM_386:
716cf7f2e2dSJohn Marino case EM_486:
717cf7f2e2dSJohn Marino case EM_X86_64:
7185796c8dcSSimon Schubert case EM_OLD_SPARCV9:
7195796c8dcSSimon Schubert case EM_SPARC32PLUS:
7205796c8dcSSimon Schubert case EM_SPARCV9:
7215796c8dcSSimon Schubert case EM_SPARC:
7225796c8dcSSimon Schubert if (i_shdrp[shindex].sh_link == (SHN_LORESERVE & 0xffff) /* SHN_BEFORE */
7235796c8dcSSimon Schubert || i_shdrp[shindex].sh_link == ((SHN_LORESERVE + 1) & 0xffff) /* SHN_AFTER */)
7245796c8dcSSimon Schubert break;
7255796c8dcSSimon Schubert /* Otherwise fall through. */
7265796c8dcSSimon Schubert default:
7275796c8dcSSimon Schubert goto got_wrong_format_error;
7285796c8dcSSimon Schubert }
7295796c8dcSSimon Schubert }
7305796c8dcSSimon Schubert
7315796c8dcSSimon Schubert if (((i_shdrp[shindex].sh_flags & SHF_INFO_LINK)
7325796c8dcSSimon Schubert || i_shdrp[shindex].sh_type == SHT_RELA
7335796c8dcSSimon Schubert || i_shdrp[shindex].sh_type == SHT_REL)
7345796c8dcSSimon Schubert && i_shdrp[shindex].sh_info >= num_sec)
7355796c8dcSSimon Schubert goto got_wrong_format_error;
7365796c8dcSSimon Schubert
7375796c8dcSSimon Schubert /* If the section is loaded, but not page aligned, clear
7385796c8dcSSimon Schubert D_PAGED. */
7395796c8dcSSimon Schubert if (i_shdrp[shindex].sh_size != 0
7405796c8dcSSimon Schubert && (i_shdrp[shindex].sh_flags & SHF_ALLOC) != 0
7415796c8dcSSimon Schubert && i_shdrp[shindex].sh_type != SHT_NOBITS
7425796c8dcSSimon Schubert && (((i_shdrp[shindex].sh_addr - i_shdrp[shindex].sh_offset)
7435796c8dcSSimon Schubert % ebd->minpagesize)
7445796c8dcSSimon Schubert != 0))
7455796c8dcSSimon Schubert abfd->flags &= ~D_PAGED;
7465796c8dcSSimon Schubert }
7475796c8dcSSimon Schubert }
7485796c8dcSSimon Schubert
7495796c8dcSSimon Schubert /* A further sanity check. */
7505796c8dcSSimon Schubert if (i_ehdrp->e_shnum != 0)
7515796c8dcSSimon Schubert {
7525796c8dcSSimon Schubert if (i_ehdrp->e_shstrndx >= elf_numsections (abfd))
7535796c8dcSSimon Schubert {
7545796c8dcSSimon Schubert /* PR 2257:
7555796c8dcSSimon Schubert We used to just goto got_wrong_format_error here
7565796c8dcSSimon Schubert but there are binaries in existance for which this test
7575796c8dcSSimon Schubert will prevent the binutils from working with them at all.
7585796c8dcSSimon Schubert So we are kind, and reset the string index value to 0
7595796c8dcSSimon Schubert so that at least some processing can be done. */
7605796c8dcSSimon Schubert i_ehdrp->e_shstrndx = SHN_UNDEF;
7615796c8dcSSimon Schubert _bfd_error_handler (_("warning: %s has a corrupt string table index - ignoring"), abfd->filename);
7625796c8dcSSimon Schubert }
7635796c8dcSSimon Schubert }
7645796c8dcSSimon Schubert else if (i_ehdrp->e_shstrndx != SHN_UNDEF)
7655796c8dcSSimon Schubert goto got_wrong_format_error;
7665796c8dcSSimon Schubert
7675796c8dcSSimon Schubert /* Read in the program headers. */
7685796c8dcSSimon Schubert if (i_ehdrp->e_phnum == 0)
7695796c8dcSSimon Schubert elf_tdata (abfd)->phdr = NULL;
7705796c8dcSSimon Schubert else
7715796c8dcSSimon Schubert {
7725796c8dcSSimon Schubert Elf_Internal_Phdr *i_phdr;
7735796c8dcSSimon Schubert unsigned int i;
7745796c8dcSSimon Schubert
7755796c8dcSSimon Schubert amt = i_ehdrp->e_phnum * sizeof (Elf_Internal_Phdr);
7765796c8dcSSimon Schubert elf_tdata (abfd)->phdr = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
7775796c8dcSSimon Schubert if (elf_tdata (abfd)->phdr == NULL)
7785796c8dcSSimon Schubert goto got_no_match;
7795796c8dcSSimon Schubert if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0)
7805796c8dcSSimon Schubert goto got_no_match;
7815796c8dcSSimon Schubert i_phdr = elf_tdata (abfd)->phdr;
7825796c8dcSSimon Schubert for (i = 0; i < i_ehdrp->e_phnum; i++, i_phdr++)
7835796c8dcSSimon Schubert {
7845796c8dcSSimon Schubert Elf_External_Phdr x_phdr;
7855796c8dcSSimon Schubert
7865796c8dcSSimon Schubert if (bfd_bread (&x_phdr, sizeof x_phdr, abfd) != sizeof x_phdr)
7875796c8dcSSimon Schubert goto got_no_match;
7885796c8dcSSimon Schubert elf_swap_phdr_in (abfd, &x_phdr, i_phdr);
7895796c8dcSSimon Schubert }
7905796c8dcSSimon Schubert }
7915796c8dcSSimon Schubert
7925796c8dcSSimon Schubert if (i_ehdrp->e_shstrndx != 0 && i_ehdrp->e_shoff != 0)
7935796c8dcSSimon Schubert {
7945796c8dcSSimon Schubert unsigned int num_sec;
7955796c8dcSSimon Schubert
7965796c8dcSSimon Schubert /* Once all of the section headers have been read and converted, we
7975796c8dcSSimon Schubert can start processing them. Note that the first section header is
7985796c8dcSSimon Schubert a dummy placeholder entry, so we ignore it. */
7995796c8dcSSimon Schubert num_sec = elf_numsections (abfd);
8005796c8dcSSimon Schubert for (shindex = 1; shindex < num_sec; shindex++)
8015796c8dcSSimon Schubert if (!bfd_section_from_shdr (abfd, shindex))
8025796c8dcSSimon Schubert goto got_no_match;
8035796c8dcSSimon Schubert
8045796c8dcSSimon Schubert /* Set up ELF sections for SHF_GROUP and SHF_LINK_ORDER. */
8055796c8dcSSimon Schubert if (! _bfd_elf_setup_sections (abfd))
8065796c8dcSSimon Schubert goto got_wrong_format_error;
8075796c8dcSSimon Schubert }
8085796c8dcSSimon Schubert
8095796c8dcSSimon Schubert /* Let the backend double check the format and override global
8105796c8dcSSimon Schubert information. */
8115796c8dcSSimon Schubert if (ebd->elf_backend_object_p)
8125796c8dcSSimon Schubert {
8135796c8dcSSimon Schubert if (! (*ebd->elf_backend_object_p) (abfd))
8145796c8dcSSimon Schubert goto got_wrong_format_error;
8155796c8dcSSimon Schubert }
8165796c8dcSSimon Schubert
8175796c8dcSSimon Schubert /* Remember the entry point specified in the ELF file header. */
8185796c8dcSSimon Schubert bfd_set_start_address (abfd, i_ehdrp->e_entry);
8195796c8dcSSimon Schubert
8205796c8dcSSimon Schubert /* If we have created any reloc sections that are associated with
8215796c8dcSSimon Schubert debugging sections, mark the reloc sections as debugging as well. */
8225796c8dcSSimon Schubert for (s = abfd->sections; s != NULL; s = s->next)
8235796c8dcSSimon Schubert {
8245796c8dcSSimon Schubert if ((elf_section_data (s)->this_hdr.sh_type == SHT_REL
8255796c8dcSSimon Schubert || elf_section_data (s)->this_hdr.sh_type == SHT_RELA)
8265796c8dcSSimon Schubert && elf_section_data (s)->this_hdr.sh_info > 0)
8275796c8dcSSimon Schubert {
8285796c8dcSSimon Schubert unsigned long targ_index;
8295796c8dcSSimon Schubert asection *targ_sec;
8305796c8dcSSimon Schubert
8315796c8dcSSimon Schubert targ_index = elf_section_data (s)->this_hdr.sh_info;
8325796c8dcSSimon Schubert targ_sec = bfd_section_from_elf_index (abfd, targ_index);
8335796c8dcSSimon Schubert if (targ_sec != NULL
8345796c8dcSSimon Schubert && (targ_sec->flags & SEC_DEBUGGING) != 0)
8355796c8dcSSimon Schubert s->flags |= SEC_DEBUGGING;
8365796c8dcSSimon Schubert }
8375796c8dcSSimon Schubert }
8385796c8dcSSimon Schubert return target;
8395796c8dcSSimon Schubert
8405796c8dcSSimon Schubert got_wrong_format_error:
8415796c8dcSSimon Schubert bfd_set_error (bfd_error_wrong_format);
8425796c8dcSSimon Schubert
8435796c8dcSSimon Schubert got_no_match:
8445796c8dcSSimon Schubert return NULL;
8455796c8dcSSimon Schubert }
8465796c8dcSSimon Schubert
8475796c8dcSSimon Schubert /* ELF .o/exec file writing */
8485796c8dcSSimon Schubert
8495796c8dcSSimon Schubert /* Write out the relocs. */
8505796c8dcSSimon Schubert
8515796c8dcSSimon Schubert void
elf_write_relocs(bfd * abfd,asection * sec,void * data)8525796c8dcSSimon Schubert elf_write_relocs (bfd *abfd, asection *sec, void *data)
8535796c8dcSSimon Schubert {
8545796c8dcSSimon Schubert bfd_boolean *failedp = (bfd_boolean *) data;
8555796c8dcSSimon Schubert Elf_Internal_Shdr *rela_hdr;
8565796c8dcSSimon Schubert bfd_vma addr_offset;
8575796c8dcSSimon Schubert void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
8585796c8dcSSimon Schubert size_t extsize;
8595796c8dcSSimon Schubert bfd_byte *dst_rela;
8605796c8dcSSimon Schubert unsigned int idx;
8615796c8dcSSimon Schubert asymbol *last_sym;
8625796c8dcSSimon Schubert int last_sym_idx;
8635796c8dcSSimon Schubert
8645796c8dcSSimon Schubert /* If we have already failed, don't do anything. */
8655796c8dcSSimon Schubert if (*failedp)
8665796c8dcSSimon Schubert return;
8675796c8dcSSimon Schubert
8685796c8dcSSimon Schubert if ((sec->flags & SEC_RELOC) == 0)
8695796c8dcSSimon Schubert return;
8705796c8dcSSimon Schubert
8715796c8dcSSimon Schubert /* The linker backend writes the relocs out itself, and sets the
8725796c8dcSSimon Schubert reloc_count field to zero to inhibit writing them here. Also,
8735796c8dcSSimon Schubert sometimes the SEC_RELOC flag gets set even when there aren't any
8745796c8dcSSimon Schubert relocs. */
8755796c8dcSSimon Schubert if (sec->reloc_count == 0)
8765796c8dcSSimon Schubert return;
8775796c8dcSSimon Schubert
8785796c8dcSSimon Schubert /* If we have opened an existing file for update, reloc_count may be
8795796c8dcSSimon Schubert set even though we are not linking. In that case we have nothing
8805796c8dcSSimon Schubert to do. */
8815796c8dcSSimon Schubert if (sec->orelocation == NULL)
8825796c8dcSSimon Schubert return;
8835796c8dcSSimon Schubert
884c50c785cSJohn Marino rela_hdr = elf_section_data (sec)->rela.hdr;
885c50c785cSJohn Marino if (rela_hdr == NULL)
886c50c785cSJohn Marino rela_hdr = elf_section_data (sec)->rel.hdr;
8875796c8dcSSimon Schubert
8885796c8dcSSimon Schubert rela_hdr->sh_size = rela_hdr->sh_entsize * sec->reloc_count;
8895796c8dcSSimon Schubert rela_hdr->contents = (unsigned char *) bfd_alloc (abfd, rela_hdr->sh_size);
8905796c8dcSSimon Schubert if (rela_hdr->contents == NULL)
8915796c8dcSSimon Schubert {
8925796c8dcSSimon Schubert *failedp = TRUE;
8935796c8dcSSimon Schubert return;
8945796c8dcSSimon Schubert }
8955796c8dcSSimon Schubert
8965796c8dcSSimon Schubert /* Figure out whether the relocations are RELA or REL relocations. */
8975796c8dcSSimon Schubert if (rela_hdr->sh_type == SHT_RELA)
8985796c8dcSSimon Schubert {
8995796c8dcSSimon Schubert swap_out = elf_swap_reloca_out;
9005796c8dcSSimon Schubert extsize = sizeof (Elf_External_Rela);
9015796c8dcSSimon Schubert }
9025796c8dcSSimon Schubert else if (rela_hdr->sh_type == SHT_REL)
9035796c8dcSSimon Schubert {
9045796c8dcSSimon Schubert swap_out = elf_swap_reloc_out;
9055796c8dcSSimon Schubert extsize = sizeof (Elf_External_Rel);
9065796c8dcSSimon Schubert }
9075796c8dcSSimon Schubert else
9085796c8dcSSimon Schubert /* Every relocation section should be either an SHT_RELA or an
9095796c8dcSSimon Schubert SHT_REL section. */
9105796c8dcSSimon Schubert abort ();
9115796c8dcSSimon Schubert
9125796c8dcSSimon Schubert /* The address of an ELF reloc is section relative for an object
9135796c8dcSSimon Schubert file, and absolute for an executable file or shared library.
9145796c8dcSSimon Schubert The address of a BFD reloc is always section relative. */
9155796c8dcSSimon Schubert addr_offset = 0;
9165796c8dcSSimon Schubert if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
9175796c8dcSSimon Schubert addr_offset = sec->vma;
9185796c8dcSSimon Schubert
9195796c8dcSSimon Schubert /* orelocation has the data, reloc_count has the count... */
9205796c8dcSSimon Schubert last_sym = 0;
9215796c8dcSSimon Schubert last_sym_idx = 0;
9225796c8dcSSimon Schubert dst_rela = rela_hdr->contents;
9235796c8dcSSimon Schubert
9245796c8dcSSimon Schubert for (idx = 0; idx < sec->reloc_count; idx++, dst_rela += extsize)
9255796c8dcSSimon Schubert {
9265796c8dcSSimon Schubert Elf_Internal_Rela src_rela;
9275796c8dcSSimon Schubert arelent *ptr;
9285796c8dcSSimon Schubert asymbol *sym;
9295796c8dcSSimon Schubert int n;
9305796c8dcSSimon Schubert
9315796c8dcSSimon Schubert ptr = sec->orelocation[idx];
9325796c8dcSSimon Schubert sym = *ptr->sym_ptr_ptr;
9335796c8dcSSimon Schubert if (sym == last_sym)
9345796c8dcSSimon Schubert n = last_sym_idx;
9355796c8dcSSimon Schubert else if (bfd_is_abs_section (sym->section) && sym->value == 0)
9365796c8dcSSimon Schubert n = STN_UNDEF;
9375796c8dcSSimon Schubert else
9385796c8dcSSimon Schubert {
9395796c8dcSSimon Schubert last_sym = sym;
9405796c8dcSSimon Schubert n = _bfd_elf_symbol_from_bfd_symbol (abfd, &sym);
9415796c8dcSSimon Schubert if (n < 0)
9425796c8dcSSimon Schubert {
9435796c8dcSSimon Schubert *failedp = TRUE;
9445796c8dcSSimon Schubert return;
9455796c8dcSSimon Schubert }
9465796c8dcSSimon Schubert last_sym_idx = n;
9475796c8dcSSimon Schubert }
9485796c8dcSSimon Schubert
9495796c8dcSSimon Schubert if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
9505796c8dcSSimon Schubert && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
9515796c8dcSSimon Schubert && ! _bfd_elf_validate_reloc (abfd, ptr))
9525796c8dcSSimon Schubert {
9535796c8dcSSimon Schubert *failedp = TRUE;
9545796c8dcSSimon Schubert return;
9555796c8dcSSimon Schubert }
9565796c8dcSSimon Schubert
9575796c8dcSSimon Schubert src_rela.r_offset = ptr->address + addr_offset;
9585796c8dcSSimon Schubert src_rela.r_info = ELF_R_INFO (n, ptr->howto->type);
9595796c8dcSSimon Schubert src_rela.r_addend = ptr->addend;
9605796c8dcSSimon Schubert (*swap_out) (abfd, &src_rela, dst_rela);
9615796c8dcSSimon Schubert }
9625796c8dcSSimon Schubert }
9635796c8dcSSimon Schubert
9645796c8dcSSimon Schubert /* Write out the program headers. */
9655796c8dcSSimon Schubert
9665796c8dcSSimon Schubert int
elf_write_out_phdrs(bfd * abfd,const Elf_Internal_Phdr * phdr,unsigned int count)9675796c8dcSSimon Schubert elf_write_out_phdrs (bfd *abfd,
9685796c8dcSSimon Schubert const Elf_Internal_Phdr *phdr,
9695796c8dcSSimon Schubert unsigned int count)
9705796c8dcSSimon Schubert {
9715796c8dcSSimon Schubert while (count--)
9725796c8dcSSimon Schubert {
9735796c8dcSSimon Schubert Elf_External_Phdr extphdr;
9745796c8dcSSimon Schubert elf_swap_phdr_out (abfd, phdr, &extphdr);
9755796c8dcSSimon Schubert if (bfd_bwrite (&extphdr, sizeof (Elf_External_Phdr), abfd)
9765796c8dcSSimon Schubert != sizeof (Elf_External_Phdr))
9775796c8dcSSimon Schubert return -1;
9785796c8dcSSimon Schubert phdr++;
9795796c8dcSSimon Schubert }
9805796c8dcSSimon Schubert return 0;
9815796c8dcSSimon Schubert }
9825796c8dcSSimon Schubert
9835796c8dcSSimon Schubert /* Write out the section headers and the ELF file header. */
9845796c8dcSSimon Schubert
9855796c8dcSSimon Schubert bfd_boolean
elf_write_shdrs_and_ehdr(bfd * abfd)9865796c8dcSSimon Schubert elf_write_shdrs_and_ehdr (bfd *abfd)
9875796c8dcSSimon Schubert {
9885796c8dcSSimon Schubert Elf_External_Ehdr x_ehdr; /* Elf file header, external form */
9895796c8dcSSimon Schubert Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */
9905796c8dcSSimon Schubert Elf_External_Shdr *x_shdrp; /* Section header table, external form */
9915796c8dcSSimon Schubert Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */
9925796c8dcSSimon Schubert unsigned int count;
9935796c8dcSSimon Schubert bfd_size_type amt;
9945796c8dcSSimon Schubert
9955796c8dcSSimon Schubert i_ehdrp = elf_elfheader (abfd);
9965796c8dcSSimon Schubert i_shdrp = elf_elfsections (abfd);
9975796c8dcSSimon Schubert
9985796c8dcSSimon Schubert /* swap the header before spitting it out... */
9995796c8dcSSimon Schubert
10005796c8dcSSimon Schubert #if DEBUG & 1
10015796c8dcSSimon Schubert elf_debug_file (i_ehdrp);
10025796c8dcSSimon Schubert #endif
10035796c8dcSSimon Schubert elf_swap_ehdr_out (abfd, i_ehdrp, &x_ehdr);
10045796c8dcSSimon Schubert amt = sizeof (x_ehdr);
10055796c8dcSSimon Schubert if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
10065796c8dcSSimon Schubert || bfd_bwrite (&x_ehdr, amt, abfd) != amt)
10075796c8dcSSimon Schubert return FALSE;
10085796c8dcSSimon Schubert
10095796c8dcSSimon Schubert /* Some fields in the first section header handle overflow of ehdr
10105796c8dcSSimon Schubert fields. */
1011cf7f2e2dSJohn Marino if (i_ehdrp->e_phnum >= PN_XNUM)
1012cf7f2e2dSJohn Marino i_shdrp[0]->sh_info = i_ehdrp->e_phnum;
10135796c8dcSSimon Schubert if (i_ehdrp->e_shnum >= (SHN_LORESERVE & 0xffff))
10145796c8dcSSimon Schubert i_shdrp[0]->sh_size = i_ehdrp->e_shnum;
10155796c8dcSSimon Schubert if (i_ehdrp->e_shstrndx >= (SHN_LORESERVE & 0xffff))
10165796c8dcSSimon Schubert i_shdrp[0]->sh_link = i_ehdrp->e_shstrndx;
10175796c8dcSSimon Schubert
10185796c8dcSSimon Schubert /* at this point we've concocted all the ELF sections... */
10195796c8dcSSimon Schubert amt = i_ehdrp->e_shnum;
10205796c8dcSSimon Schubert amt *= sizeof (*x_shdrp);
10215796c8dcSSimon Schubert x_shdrp = (Elf_External_Shdr *) bfd_alloc (abfd, amt);
10225796c8dcSSimon Schubert if (!x_shdrp)
10235796c8dcSSimon Schubert return FALSE;
10245796c8dcSSimon Schubert
10255796c8dcSSimon Schubert for (count = 0; count < i_ehdrp->e_shnum; i_shdrp++, count++)
10265796c8dcSSimon Schubert {
10275796c8dcSSimon Schubert #if DEBUG & 2
10285796c8dcSSimon Schubert elf_debug_section (count, *i_shdrp);
10295796c8dcSSimon Schubert #endif
10305796c8dcSSimon Schubert elf_swap_shdr_out (abfd, *i_shdrp, x_shdrp + count);
10315796c8dcSSimon Schubert }
10325796c8dcSSimon Schubert if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_shoff, SEEK_SET) != 0
10335796c8dcSSimon Schubert || bfd_bwrite (x_shdrp, amt, abfd) != amt)
10345796c8dcSSimon Schubert return FALSE;
10355796c8dcSSimon Schubert
10365796c8dcSSimon Schubert /* need to dump the string table too... */
10375796c8dcSSimon Schubert
10385796c8dcSSimon Schubert return TRUE;
10395796c8dcSSimon Schubert }
10405796c8dcSSimon Schubert
10415796c8dcSSimon Schubert bfd_boolean
elf_checksum_contents(bfd * abfd,void (* process)(const void *,size_t,void *),void * arg)10425796c8dcSSimon Schubert elf_checksum_contents (bfd *abfd,
10435796c8dcSSimon Schubert void (*process) (const void *, size_t, void *),
10445796c8dcSSimon Schubert void *arg)
10455796c8dcSSimon Schubert {
10465796c8dcSSimon Schubert Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
10475796c8dcSSimon Schubert Elf_Internal_Shdr **i_shdrp = elf_elfsections (abfd);
10485796c8dcSSimon Schubert Elf_Internal_Phdr *i_phdrp = elf_tdata (abfd)->phdr;
10495796c8dcSSimon Schubert unsigned int count, num;
10505796c8dcSSimon Schubert
10515796c8dcSSimon Schubert {
10525796c8dcSSimon Schubert Elf_External_Ehdr x_ehdr;
10535796c8dcSSimon Schubert Elf_Internal_Ehdr i_ehdr;
10545796c8dcSSimon Schubert
10555796c8dcSSimon Schubert i_ehdr = *i_ehdrp;
10565796c8dcSSimon Schubert i_ehdr.e_phoff = i_ehdr.e_shoff = 0;
10575796c8dcSSimon Schubert elf_swap_ehdr_out (abfd, &i_ehdr, &x_ehdr);
10585796c8dcSSimon Schubert (*process) (&x_ehdr, sizeof x_ehdr, arg);
10595796c8dcSSimon Schubert }
10605796c8dcSSimon Schubert
10615796c8dcSSimon Schubert num = i_ehdrp->e_phnum;
10625796c8dcSSimon Schubert for (count = 0; count < num; count++)
10635796c8dcSSimon Schubert {
10645796c8dcSSimon Schubert Elf_External_Phdr x_phdr;
10655796c8dcSSimon Schubert elf_swap_phdr_out (abfd, &i_phdrp[count], &x_phdr);
10665796c8dcSSimon Schubert (*process) (&x_phdr, sizeof x_phdr, arg);
10675796c8dcSSimon Schubert }
10685796c8dcSSimon Schubert
10695796c8dcSSimon Schubert num = elf_numsections (abfd);
10705796c8dcSSimon Schubert for (count = 0; count < num; count++)
10715796c8dcSSimon Schubert {
10725796c8dcSSimon Schubert Elf_Internal_Shdr i_shdr;
10735796c8dcSSimon Schubert Elf_External_Shdr x_shdr;
1074*ef5ccd6cSJohn Marino bfd_byte *contents, *free_contents;
10755796c8dcSSimon Schubert
10765796c8dcSSimon Schubert i_shdr = *i_shdrp[count];
10775796c8dcSSimon Schubert i_shdr.sh_offset = 0;
10785796c8dcSSimon Schubert
10795796c8dcSSimon Schubert elf_swap_shdr_out (abfd, &i_shdr, &x_shdr);
10805796c8dcSSimon Schubert (*process) (&x_shdr, sizeof x_shdr, arg);
10815796c8dcSSimon Schubert
1082*ef5ccd6cSJohn Marino /* Process the section's contents, if it has some.
1083*ef5ccd6cSJohn Marino PR ld/12451: Read them in if necessary. */
1084*ef5ccd6cSJohn Marino if (i_shdr.sh_type == SHT_NOBITS)
1085*ef5ccd6cSJohn Marino continue;
1086*ef5ccd6cSJohn Marino free_contents = NULL;
1087*ef5ccd6cSJohn Marino contents = i_shdr.contents;
1088*ef5ccd6cSJohn Marino if (contents == NULL)
1089*ef5ccd6cSJohn Marino {
1090*ef5ccd6cSJohn Marino asection *sec;
1091*ef5ccd6cSJohn Marino
1092*ef5ccd6cSJohn Marino sec = bfd_section_from_elf_index (abfd, count);
1093*ef5ccd6cSJohn Marino if (sec != NULL)
1094*ef5ccd6cSJohn Marino {
1095*ef5ccd6cSJohn Marino contents = sec->contents;
1096*ef5ccd6cSJohn Marino if (contents == NULL)
1097*ef5ccd6cSJohn Marino {
1098*ef5ccd6cSJohn Marino /* Force rereading from file. */
1099*ef5ccd6cSJohn Marino sec->flags &= ~SEC_IN_MEMORY;
1100*ef5ccd6cSJohn Marino if (!bfd_malloc_and_get_section (abfd, sec, &free_contents))
1101*ef5ccd6cSJohn Marino continue;
1102*ef5ccd6cSJohn Marino contents = free_contents;
1103*ef5ccd6cSJohn Marino }
1104*ef5ccd6cSJohn Marino }
1105*ef5ccd6cSJohn Marino }
1106*ef5ccd6cSJohn Marino if (contents != NULL)
1107*ef5ccd6cSJohn Marino {
1108*ef5ccd6cSJohn Marino (*process) (contents, i_shdr.sh_size, arg);
1109*ef5ccd6cSJohn Marino if (free_contents != NULL)
1110*ef5ccd6cSJohn Marino free (free_contents);
1111*ef5ccd6cSJohn Marino }
11125796c8dcSSimon Schubert }
11135796c8dcSSimon Schubert
11145796c8dcSSimon Schubert return TRUE;
11155796c8dcSSimon Schubert }
11165796c8dcSSimon Schubert
11175796c8dcSSimon Schubert long
elf_slurp_symbol_table(bfd * abfd,asymbol ** symptrs,bfd_boolean dynamic)11185796c8dcSSimon Schubert elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
11195796c8dcSSimon Schubert {
11205796c8dcSSimon Schubert Elf_Internal_Shdr *hdr;
11215796c8dcSSimon Schubert Elf_Internal_Shdr *verhdr;
11225796c8dcSSimon Schubert unsigned long symcount; /* Number of external ELF symbols */
11235796c8dcSSimon Schubert elf_symbol_type *sym; /* Pointer to current bfd symbol */
11245796c8dcSSimon Schubert elf_symbol_type *symbase; /* Buffer for generated bfd symbols */
11255796c8dcSSimon Schubert Elf_Internal_Sym *isym;
11265796c8dcSSimon Schubert Elf_Internal_Sym *isymend;
11275796c8dcSSimon Schubert Elf_Internal_Sym *isymbuf = NULL;
11285796c8dcSSimon Schubert Elf_External_Versym *xver;
11295796c8dcSSimon Schubert Elf_External_Versym *xverbuf = NULL;
11305796c8dcSSimon Schubert const struct elf_backend_data *ebd;
11315796c8dcSSimon Schubert bfd_size_type amt;
11325796c8dcSSimon Schubert
11335796c8dcSSimon Schubert /* Read each raw ELF symbol, converting from external ELF form to
11345796c8dcSSimon Schubert internal ELF form, and then using the information to create a
11355796c8dcSSimon Schubert canonical bfd symbol table entry.
11365796c8dcSSimon Schubert
11375796c8dcSSimon Schubert Note that we allocate the initial bfd canonical symbol buffer
11385796c8dcSSimon Schubert based on a one-to-one mapping of the ELF symbols to canonical
11395796c8dcSSimon Schubert symbols. We actually use all the ELF symbols, so there will be no
11405796c8dcSSimon Schubert space left over at the end. When we have all the symbols, we
11415796c8dcSSimon Schubert build the caller's pointer vector. */
11425796c8dcSSimon Schubert
11435796c8dcSSimon Schubert if (! dynamic)
11445796c8dcSSimon Schubert {
11455796c8dcSSimon Schubert hdr = &elf_tdata (abfd)->symtab_hdr;
11465796c8dcSSimon Schubert verhdr = NULL;
11475796c8dcSSimon Schubert }
11485796c8dcSSimon Schubert else
11495796c8dcSSimon Schubert {
11505796c8dcSSimon Schubert hdr = &elf_tdata (abfd)->dynsymtab_hdr;
11515796c8dcSSimon Schubert if (elf_dynversym (abfd) == 0)
11525796c8dcSSimon Schubert verhdr = NULL;
11535796c8dcSSimon Schubert else
11545796c8dcSSimon Schubert verhdr = &elf_tdata (abfd)->dynversym_hdr;
1155*ef5ccd6cSJohn Marino if ((elf_dynverdef (abfd) != 0
11565796c8dcSSimon Schubert && elf_tdata (abfd)->verdef == NULL)
1157*ef5ccd6cSJohn Marino || (elf_dynverref (abfd) != 0
11585796c8dcSSimon Schubert && elf_tdata (abfd)->verref == NULL))
11595796c8dcSSimon Schubert {
11605796c8dcSSimon Schubert if (!_bfd_elf_slurp_version_tables (abfd, FALSE))
11615796c8dcSSimon Schubert return -1;
11625796c8dcSSimon Schubert }
11635796c8dcSSimon Schubert }
11645796c8dcSSimon Schubert
11655796c8dcSSimon Schubert ebd = get_elf_backend_data (abfd);
11665796c8dcSSimon Schubert symcount = hdr->sh_size / sizeof (Elf_External_Sym);
11675796c8dcSSimon Schubert if (symcount == 0)
11685796c8dcSSimon Schubert sym = symbase = NULL;
11695796c8dcSSimon Schubert else
11705796c8dcSSimon Schubert {
11715796c8dcSSimon Schubert isymbuf = bfd_elf_get_elf_syms (abfd, hdr, symcount, 0,
11725796c8dcSSimon Schubert NULL, NULL, NULL);
11735796c8dcSSimon Schubert if (isymbuf == NULL)
11745796c8dcSSimon Schubert return -1;
11755796c8dcSSimon Schubert
11765796c8dcSSimon Schubert amt = symcount;
11775796c8dcSSimon Schubert amt *= sizeof (elf_symbol_type);
11785796c8dcSSimon Schubert symbase = (elf_symbol_type *) bfd_zalloc (abfd, amt);
11795796c8dcSSimon Schubert if (symbase == (elf_symbol_type *) NULL)
11805796c8dcSSimon Schubert goto error_return;
11815796c8dcSSimon Schubert
11825796c8dcSSimon Schubert /* Read the raw ELF version symbol information. */
11835796c8dcSSimon Schubert if (verhdr != NULL
11845796c8dcSSimon Schubert && verhdr->sh_size / sizeof (Elf_External_Versym) != symcount)
11855796c8dcSSimon Schubert {
11865796c8dcSSimon Schubert (*_bfd_error_handler)
11875796c8dcSSimon Schubert (_("%s: version count (%ld) does not match symbol count (%ld)"),
11885796c8dcSSimon Schubert abfd->filename,
11895796c8dcSSimon Schubert (long) (verhdr->sh_size / sizeof (Elf_External_Versym)),
11905796c8dcSSimon Schubert symcount);
11915796c8dcSSimon Schubert
11925796c8dcSSimon Schubert /* Slurp in the symbols without the version information,
11935796c8dcSSimon Schubert since that is more helpful than just quitting. */
11945796c8dcSSimon Schubert verhdr = NULL;
11955796c8dcSSimon Schubert }
11965796c8dcSSimon Schubert
11975796c8dcSSimon Schubert if (verhdr != NULL)
11985796c8dcSSimon Schubert {
11995796c8dcSSimon Schubert if (bfd_seek (abfd, verhdr->sh_offset, SEEK_SET) != 0)
12005796c8dcSSimon Schubert goto error_return;
12015796c8dcSSimon Schubert
12025796c8dcSSimon Schubert xverbuf = (Elf_External_Versym *) bfd_malloc (verhdr->sh_size);
12035796c8dcSSimon Schubert if (xverbuf == NULL && verhdr->sh_size != 0)
12045796c8dcSSimon Schubert goto error_return;
12055796c8dcSSimon Schubert
12065796c8dcSSimon Schubert if (bfd_bread (xverbuf, verhdr->sh_size, abfd) != verhdr->sh_size)
12075796c8dcSSimon Schubert goto error_return;
12085796c8dcSSimon Schubert }
12095796c8dcSSimon Schubert
12105796c8dcSSimon Schubert /* Skip first symbol, which is a null dummy. */
12115796c8dcSSimon Schubert xver = xverbuf;
12125796c8dcSSimon Schubert if (xver != NULL)
12135796c8dcSSimon Schubert ++xver;
12145796c8dcSSimon Schubert isymend = isymbuf + symcount;
12155796c8dcSSimon Schubert for (isym = isymbuf + 1, sym = symbase; isym < isymend; isym++, sym++)
12165796c8dcSSimon Schubert {
12175796c8dcSSimon Schubert memcpy (&sym->internal_elf_sym, isym, sizeof (Elf_Internal_Sym));
12185796c8dcSSimon Schubert sym->symbol.the_bfd = abfd;
12195796c8dcSSimon Schubert
12205796c8dcSSimon Schubert sym->symbol.name = bfd_elf_sym_name (abfd, hdr, isym, NULL);
12215796c8dcSSimon Schubert
12225796c8dcSSimon Schubert sym->symbol.value = isym->st_value;
12235796c8dcSSimon Schubert
12245796c8dcSSimon Schubert if (isym->st_shndx == SHN_UNDEF)
12255796c8dcSSimon Schubert {
12265796c8dcSSimon Schubert sym->symbol.section = bfd_und_section_ptr;
12275796c8dcSSimon Schubert }
12285796c8dcSSimon Schubert else if (isym->st_shndx == SHN_ABS)
12295796c8dcSSimon Schubert {
12305796c8dcSSimon Schubert sym->symbol.section = bfd_abs_section_ptr;
12315796c8dcSSimon Schubert }
12325796c8dcSSimon Schubert else if (isym->st_shndx == SHN_COMMON)
12335796c8dcSSimon Schubert {
12345796c8dcSSimon Schubert sym->symbol.section = bfd_com_section_ptr;
1235a45ae5f8SJohn Marino if ((abfd->flags & BFD_PLUGIN) != 0)
1236a45ae5f8SJohn Marino {
1237a45ae5f8SJohn Marino asection *xc = bfd_get_section_by_name (abfd, "COMMON");
1238a45ae5f8SJohn Marino
1239a45ae5f8SJohn Marino if (xc == NULL)
1240a45ae5f8SJohn Marino {
1241a45ae5f8SJohn Marino flagword flags = (SEC_ALLOC | SEC_IS_COMMON | SEC_KEEP
1242a45ae5f8SJohn Marino | SEC_EXCLUDE);
1243a45ae5f8SJohn Marino xc = bfd_make_section_with_flags (abfd, "COMMON", flags);
1244a45ae5f8SJohn Marino if (xc == NULL)
1245a45ae5f8SJohn Marino goto error_return;
1246a45ae5f8SJohn Marino }
1247a45ae5f8SJohn Marino sym->symbol.section = xc;
1248a45ae5f8SJohn Marino }
12495796c8dcSSimon Schubert /* Elf puts the alignment into the `value' field, and
12505796c8dcSSimon Schubert the size into the `size' field. BFD wants to see the
12515796c8dcSSimon Schubert size in the value field, and doesn't care (at the
12525796c8dcSSimon Schubert moment) about the alignment. */
12535796c8dcSSimon Schubert sym->symbol.value = isym->st_size;
12545796c8dcSSimon Schubert }
12555796c8dcSSimon Schubert else
12565796c8dcSSimon Schubert {
12575796c8dcSSimon Schubert sym->symbol.section
12585796c8dcSSimon Schubert = bfd_section_from_elf_index (abfd, isym->st_shndx);
12595796c8dcSSimon Schubert if (sym->symbol.section == NULL)
12605796c8dcSSimon Schubert {
12615796c8dcSSimon Schubert /* This symbol is in a section for which we did not
12625796c8dcSSimon Schubert create a BFD section. Just use bfd_abs_section,
12635796c8dcSSimon Schubert although it is wrong. FIXME. */
12645796c8dcSSimon Schubert sym->symbol.section = bfd_abs_section_ptr;
12655796c8dcSSimon Schubert }
12665796c8dcSSimon Schubert }
12675796c8dcSSimon Schubert
12685796c8dcSSimon Schubert /* If this is a relocatable file, then the symbol value is
12695796c8dcSSimon Schubert already section relative. */
12705796c8dcSSimon Schubert if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
12715796c8dcSSimon Schubert sym->symbol.value -= sym->symbol.section->vma;
12725796c8dcSSimon Schubert
12735796c8dcSSimon Schubert switch (ELF_ST_BIND (isym->st_info))
12745796c8dcSSimon Schubert {
12755796c8dcSSimon Schubert case STB_LOCAL:
12765796c8dcSSimon Schubert sym->symbol.flags |= BSF_LOCAL;
12775796c8dcSSimon Schubert break;
12785796c8dcSSimon Schubert case STB_GLOBAL:
12795796c8dcSSimon Schubert if (isym->st_shndx != SHN_UNDEF && isym->st_shndx != SHN_COMMON)
12805796c8dcSSimon Schubert sym->symbol.flags |= BSF_GLOBAL;
12815796c8dcSSimon Schubert break;
12825796c8dcSSimon Schubert case STB_WEAK:
12835796c8dcSSimon Schubert sym->symbol.flags |= BSF_WEAK;
12845796c8dcSSimon Schubert break;
12855796c8dcSSimon Schubert case STB_GNU_UNIQUE:
12865796c8dcSSimon Schubert sym->symbol.flags |= BSF_GNU_UNIQUE;
12875796c8dcSSimon Schubert break;
12885796c8dcSSimon Schubert }
12895796c8dcSSimon Schubert
12905796c8dcSSimon Schubert switch (ELF_ST_TYPE (isym->st_info))
12915796c8dcSSimon Schubert {
12925796c8dcSSimon Schubert case STT_SECTION:
12935796c8dcSSimon Schubert sym->symbol.flags |= BSF_SECTION_SYM | BSF_DEBUGGING;
12945796c8dcSSimon Schubert break;
12955796c8dcSSimon Schubert case STT_FILE:
12965796c8dcSSimon Schubert sym->symbol.flags |= BSF_FILE | BSF_DEBUGGING;
12975796c8dcSSimon Schubert break;
12985796c8dcSSimon Schubert case STT_FUNC:
12995796c8dcSSimon Schubert sym->symbol.flags |= BSF_FUNCTION;
13005796c8dcSSimon Schubert break;
13015796c8dcSSimon Schubert case STT_COMMON:
13025796c8dcSSimon Schubert /* FIXME: Do we have to put the size field into the value field
13035796c8dcSSimon Schubert as we do with symbols in SHN_COMMON sections (see above) ? */
13045796c8dcSSimon Schubert /* Fall through. */
13055796c8dcSSimon Schubert case STT_OBJECT:
13065796c8dcSSimon Schubert sym->symbol.flags |= BSF_OBJECT;
13075796c8dcSSimon Schubert break;
13085796c8dcSSimon Schubert case STT_TLS:
13095796c8dcSSimon Schubert sym->symbol.flags |= BSF_THREAD_LOCAL;
13105796c8dcSSimon Schubert break;
13115796c8dcSSimon Schubert case STT_RELC:
13125796c8dcSSimon Schubert sym->symbol.flags |= BSF_RELC;
13135796c8dcSSimon Schubert break;
13145796c8dcSSimon Schubert case STT_SRELC:
13155796c8dcSSimon Schubert sym->symbol.flags |= BSF_SRELC;
13165796c8dcSSimon Schubert break;
13175796c8dcSSimon Schubert case STT_GNU_IFUNC:
13185796c8dcSSimon Schubert sym->symbol.flags |= BSF_GNU_INDIRECT_FUNCTION;
13195796c8dcSSimon Schubert break;
13205796c8dcSSimon Schubert }
13215796c8dcSSimon Schubert
13225796c8dcSSimon Schubert if (dynamic)
13235796c8dcSSimon Schubert sym->symbol.flags |= BSF_DYNAMIC;
13245796c8dcSSimon Schubert
13255796c8dcSSimon Schubert if (xver != NULL)
13265796c8dcSSimon Schubert {
13275796c8dcSSimon Schubert Elf_Internal_Versym iversym;
13285796c8dcSSimon Schubert
13295796c8dcSSimon Schubert _bfd_elf_swap_versym_in (abfd, xver, &iversym);
13305796c8dcSSimon Schubert sym->version = iversym.vs_vers;
13315796c8dcSSimon Schubert xver++;
13325796c8dcSSimon Schubert }
13335796c8dcSSimon Schubert
13345796c8dcSSimon Schubert /* Do some backend-specific processing on this symbol. */
13355796c8dcSSimon Schubert if (ebd->elf_backend_symbol_processing)
13365796c8dcSSimon Schubert (*ebd->elf_backend_symbol_processing) (abfd, &sym->symbol);
13375796c8dcSSimon Schubert }
13385796c8dcSSimon Schubert }
13395796c8dcSSimon Schubert
13405796c8dcSSimon Schubert /* Do some backend-specific processing on this symbol table. */
13415796c8dcSSimon Schubert if (ebd->elf_backend_symbol_table_processing)
13425796c8dcSSimon Schubert (*ebd->elf_backend_symbol_table_processing) (abfd, symbase, symcount);
13435796c8dcSSimon Schubert
13445796c8dcSSimon Schubert /* We rely on the zalloc to clear out the final symbol entry. */
13455796c8dcSSimon Schubert
13465796c8dcSSimon Schubert symcount = sym - symbase;
13475796c8dcSSimon Schubert
13485796c8dcSSimon Schubert /* Fill in the user's symbol pointer vector if needed. */
13495796c8dcSSimon Schubert if (symptrs)
13505796c8dcSSimon Schubert {
13515796c8dcSSimon Schubert long l = symcount;
13525796c8dcSSimon Schubert
13535796c8dcSSimon Schubert sym = symbase;
13545796c8dcSSimon Schubert while (l-- > 0)
13555796c8dcSSimon Schubert {
13565796c8dcSSimon Schubert *symptrs++ = &sym->symbol;
13575796c8dcSSimon Schubert sym++;
13585796c8dcSSimon Schubert }
13595796c8dcSSimon Schubert *symptrs = 0; /* Final null pointer */
13605796c8dcSSimon Schubert }
13615796c8dcSSimon Schubert
13625796c8dcSSimon Schubert if (xverbuf != NULL)
13635796c8dcSSimon Schubert free (xverbuf);
13645796c8dcSSimon Schubert if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf)
13655796c8dcSSimon Schubert free (isymbuf);
13665796c8dcSSimon Schubert return symcount;
13675796c8dcSSimon Schubert
13685796c8dcSSimon Schubert error_return:
13695796c8dcSSimon Schubert if (xverbuf != NULL)
13705796c8dcSSimon Schubert free (xverbuf);
13715796c8dcSSimon Schubert if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf)
13725796c8dcSSimon Schubert free (isymbuf);
13735796c8dcSSimon Schubert return -1;
13745796c8dcSSimon Schubert }
13755796c8dcSSimon Schubert
13765796c8dcSSimon Schubert /* Read relocations for ASECT from REL_HDR. There are RELOC_COUNT of
13775796c8dcSSimon Schubert them. */
13785796c8dcSSimon Schubert
13795796c8dcSSimon Schubert static bfd_boolean
elf_slurp_reloc_table_from_section(bfd * abfd,asection * asect,Elf_Internal_Shdr * rel_hdr,bfd_size_type reloc_count,arelent * relents,asymbol ** symbols,bfd_boolean dynamic)13805796c8dcSSimon Schubert elf_slurp_reloc_table_from_section (bfd *abfd,
13815796c8dcSSimon Schubert asection *asect,
13825796c8dcSSimon Schubert Elf_Internal_Shdr *rel_hdr,
13835796c8dcSSimon Schubert bfd_size_type reloc_count,
13845796c8dcSSimon Schubert arelent *relents,
13855796c8dcSSimon Schubert asymbol **symbols,
13865796c8dcSSimon Schubert bfd_boolean dynamic)
13875796c8dcSSimon Schubert {
13885796c8dcSSimon Schubert const struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
13895796c8dcSSimon Schubert void *allocated = NULL;
13905796c8dcSSimon Schubert bfd_byte *native_relocs;
13915796c8dcSSimon Schubert arelent *relent;
13925796c8dcSSimon Schubert unsigned int i;
13935796c8dcSSimon Schubert int entsize;
13945796c8dcSSimon Schubert unsigned int symcount;
13955796c8dcSSimon Schubert
13965796c8dcSSimon Schubert allocated = bfd_malloc (rel_hdr->sh_size);
13975796c8dcSSimon Schubert if (allocated == NULL)
13985796c8dcSSimon Schubert goto error_return;
13995796c8dcSSimon Schubert
14005796c8dcSSimon Schubert if (bfd_seek (abfd, rel_hdr->sh_offset, SEEK_SET) != 0
14015796c8dcSSimon Schubert || (bfd_bread (allocated, rel_hdr->sh_size, abfd)
14025796c8dcSSimon Schubert != rel_hdr->sh_size))
14035796c8dcSSimon Schubert goto error_return;
14045796c8dcSSimon Schubert
14055796c8dcSSimon Schubert native_relocs = (bfd_byte *) allocated;
14065796c8dcSSimon Schubert
14075796c8dcSSimon Schubert entsize = rel_hdr->sh_entsize;
14085796c8dcSSimon Schubert BFD_ASSERT (entsize == sizeof (Elf_External_Rel)
14095796c8dcSSimon Schubert || entsize == sizeof (Elf_External_Rela));
14105796c8dcSSimon Schubert
14115796c8dcSSimon Schubert if (dynamic)
14125796c8dcSSimon Schubert symcount = bfd_get_dynamic_symcount (abfd);
14135796c8dcSSimon Schubert else
14145796c8dcSSimon Schubert symcount = bfd_get_symcount (abfd);
14155796c8dcSSimon Schubert
14165796c8dcSSimon Schubert for (i = 0, relent = relents;
14175796c8dcSSimon Schubert i < reloc_count;
14185796c8dcSSimon Schubert i++, relent++, native_relocs += entsize)
14195796c8dcSSimon Schubert {
14205796c8dcSSimon Schubert Elf_Internal_Rela rela;
14215796c8dcSSimon Schubert
14225796c8dcSSimon Schubert if (entsize == sizeof (Elf_External_Rela))
14235796c8dcSSimon Schubert elf_swap_reloca_in (abfd, native_relocs, &rela);
14245796c8dcSSimon Schubert else
14255796c8dcSSimon Schubert elf_swap_reloc_in (abfd, native_relocs, &rela);
14265796c8dcSSimon Schubert
14275796c8dcSSimon Schubert /* The address of an ELF reloc is section relative for an object
14285796c8dcSSimon Schubert file, and absolute for an executable file or shared library.
14295796c8dcSSimon Schubert The address of a normal BFD reloc is always section relative,
14305796c8dcSSimon Schubert and the address of a dynamic reloc is absolute.. */
14315796c8dcSSimon Schubert if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0 || dynamic)
14325796c8dcSSimon Schubert relent->address = rela.r_offset;
14335796c8dcSSimon Schubert else
14345796c8dcSSimon Schubert relent->address = rela.r_offset - asect->vma;
14355796c8dcSSimon Schubert
1436c50c785cSJohn Marino if (ELF_R_SYM (rela.r_info) == STN_UNDEF)
14375796c8dcSSimon Schubert relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
14385796c8dcSSimon Schubert else if (ELF_R_SYM (rela.r_info) > symcount)
14395796c8dcSSimon Schubert {
14405796c8dcSSimon Schubert (*_bfd_error_handler)
14415796c8dcSSimon Schubert (_("%s(%s): relocation %d has invalid symbol index %ld"),
14425796c8dcSSimon Schubert abfd->filename, asect->name, i, ELF_R_SYM (rela.r_info));
1443*ef5ccd6cSJohn Marino relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
14445796c8dcSSimon Schubert }
14455796c8dcSSimon Schubert else
14465796c8dcSSimon Schubert {
14475796c8dcSSimon Schubert asymbol **ps;
14485796c8dcSSimon Schubert
14495796c8dcSSimon Schubert ps = symbols + ELF_R_SYM (rela.r_info) - 1;
14505796c8dcSSimon Schubert
14515796c8dcSSimon Schubert relent->sym_ptr_ptr = ps;
14525796c8dcSSimon Schubert }
14535796c8dcSSimon Schubert
14545796c8dcSSimon Schubert relent->addend = rela.r_addend;
14555796c8dcSSimon Schubert
14565796c8dcSSimon Schubert if ((entsize == sizeof (Elf_External_Rela)
14575796c8dcSSimon Schubert && ebd->elf_info_to_howto != NULL)
14585796c8dcSSimon Schubert || ebd->elf_info_to_howto_rel == NULL)
14595796c8dcSSimon Schubert (*ebd->elf_info_to_howto) (abfd, relent, &rela);
14605796c8dcSSimon Schubert else
14615796c8dcSSimon Schubert (*ebd->elf_info_to_howto_rel) (abfd, relent, &rela);
14625796c8dcSSimon Schubert }
14635796c8dcSSimon Schubert
14645796c8dcSSimon Schubert if (allocated != NULL)
14655796c8dcSSimon Schubert free (allocated);
14665796c8dcSSimon Schubert
14675796c8dcSSimon Schubert return TRUE;
14685796c8dcSSimon Schubert
14695796c8dcSSimon Schubert error_return:
14705796c8dcSSimon Schubert if (allocated != NULL)
14715796c8dcSSimon Schubert free (allocated);
14725796c8dcSSimon Schubert return FALSE;
14735796c8dcSSimon Schubert }
14745796c8dcSSimon Schubert
14755796c8dcSSimon Schubert /* Read in and swap the external relocs. */
14765796c8dcSSimon Schubert
14775796c8dcSSimon Schubert bfd_boolean
elf_slurp_reloc_table(bfd * abfd,asection * asect,asymbol ** symbols,bfd_boolean dynamic)14785796c8dcSSimon Schubert elf_slurp_reloc_table (bfd *abfd,
14795796c8dcSSimon Schubert asection *asect,
14805796c8dcSSimon Schubert asymbol **symbols,
14815796c8dcSSimon Schubert bfd_boolean dynamic)
14825796c8dcSSimon Schubert {
14835796c8dcSSimon Schubert struct bfd_elf_section_data * const d = elf_section_data (asect);
14845796c8dcSSimon Schubert Elf_Internal_Shdr *rel_hdr;
14855796c8dcSSimon Schubert Elf_Internal_Shdr *rel_hdr2;
14865796c8dcSSimon Schubert bfd_size_type reloc_count;
14875796c8dcSSimon Schubert bfd_size_type reloc_count2;
14885796c8dcSSimon Schubert arelent *relents;
14895796c8dcSSimon Schubert bfd_size_type amt;
14905796c8dcSSimon Schubert
14915796c8dcSSimon Schubert if (asect->relocation != NULL)
14925796c8dcSSimon Schubert return TRUE;
14935796c8dcSSimon Schubert
14945796c8dcSSimon Schubert if (! dynamic)
14955796c8dcSSimon Schubert {
14965796c8dcSSimon Schubert if ((asect->flags & SEC_RELOC) == 0
14975796c8dcSSimon Schubert || asect->reloc_count == 0)
14985796c8dcSSimon Schubert return TRUE;
14995796c8dcSSimon Schubert
1500c50c785cSJohn Marino rel_hdr = d->rel.hdr;
1501c50c785cSJohn Marino reloc_count = rel_hdr ? NUM_SHDR_ENTRIES (rel_hdr) : 0;
1502c50c785cSJohn Marino rel_hdr2 = d->rela.hdr;
1503c50c785cSJohn Marino reloc_count2 = rel_hdr2 ? NUM_SHDR_ENTRIES (rel_hdr2) : 0;
15045796c8dcSSimon Schubert
15055796c8dcSSimon Schubert BFD_ASSERT (asect->reloc_count == reloc_count + reloc_count2);
1506c50c785cSJohn Marino BFD_ASSERT ((rel_hdr && asect->rel_filepos == rel_hdr->sh_offset)
15075796c8dcSSimon Schubert || (rel_hdr2 && asect->rel_filepos == rel_hdr2->sh_offset));
15085796c8dcSSimon Schubert
15095796c8dcSSimon Schubert }
15105796c8dcSSimon Schubert else
15115796c8dcSSimon Schubert {
15125796c8dcSSimon Schubert /* Note that ASECT->RELOC_COUNT tends not to be accurate in this
15135796c8dcSSimon Schubert case because relocations against this section may use the
15145796c8dcSSimon Schubert dynamic symbol table, and in that case bfd_section_from_shdr
15155796c8dcSSimon Schubert in elf.c does not update the RELOC_COUNT. */
15165796c8dcSSimon Schubert if (asect->size == 0)
15175796c8dcSSimon Schubert return TRUE;
15185796c8dcSSimon Schubert
15195796c8dcSSimon Schubert rel_hdr = &d->this_hdr;
15205796c8dcSSimon Schubert reloc_count = NUM_SHDR_ENTRIES (rel_hdr);
15215796c8dcSSimon Schubert rel_hdr2 = NULL;
15225796c8dcSSimon Schubert reloc_count2 = 0;
15235796c8dcSSimon Schubert }
15245796c8dcSSimon Schubert
15255796c8dcSSimon Schubert amt = (reloc_count + reloc_count2) * sizeof (arelent);
15265796c8dcSSimon Schubert relents = (arelent *) bfd_alloc (abfd, amt);
15275796c8dcSSimon Schubert if (relents == NULL)
15285796c8dcSSimon Schubert return FALSE;
15295796c8dcSSimon Schubert
1530c50c785cSJohn Marino if (rel_hdr
1531c50c785cSJohn Marino && !elf_slurp_reloc_table_from_section (abfd, asect,
15325796c8dcSSimon Schubert rel_hdr, reloc_count,
15335796c8dcSSimon Schubert relents,
15345796c8dcSSimon Schubert symbols, dynamic))
15355796c8dcSSimon Schubert return FALSE;
15365796c8dcSSimon Schubert
15375796c8dcSSimon Schubert if (rel_hdr2
15385796c8dcSSimon Schubert && !elf_slurp_reloc_table_from_section (abfd, asect,
15395796c8dcSSimon Schubert rel_hdr2, reloc_count2,
15405796c8dcSSimon Schubert relents + reloc_count,
15415796c8dcSSimon Schubert symbols, dynamic))
15425796c8dcSSimon Schubert return FALSE;
15435796c8dcSSimon Schubert
15445796c8dcSSimon Schubert asect->relocation = relents;
15455796c8dcSSimon Schubert return TRUE;
15465796c8dcSSimon Schubert }
15475796c8dcSSimon Schubert
15485796c8dcSSimon Schubert #if DEBUG & 2
15495796c8dcSSimon Schubert static void
elf_debug_section(int num,Elf_Internal_Shdr * hdr)15505796c8dcSSimon Schubert elf_debug_section (int num, Elf_Internal_Shdr *hdr)
15515796c8dcSSimon Schubert {
15525796c8dcSSimon Schubert fprintf (stderr, "\nSection#%d '%s' 0x%.8lx\n", num,
15535796c8dcSSimon Schubert hdr->bfd_section != NULL ? hdr->bfd_section->name : "",
15545796c8dcSSimon Schubert (long) hdr);
15555796c8dcSSimon Schubert fprintf (stderr,
15565796c8dcSSimon Schubert "sh_name = %ld\tsh_type = %ld\tsh_flags = %ld\n",
15575796c8dcSSimon Schubert (long) hdr->sh_name,
15585796c8dcSSimon Schubert (long) hdr->sh_type,
15595796c8dcSSimon Schubert (long) hdr->sh_flags);
15605796c8dcSSimon Schubert fprintf (stderr,
15615796c8dcSSimon Schubert "sh_addr = %ld\tsh_offset = %ld\tsh_size = %ld\n",
15625796c8dcSSimon Schubert (long) hdr->sh_addr,
15635796c8dcSSimon Schubert (long) hdr->sh_offset,
15645796c8dcSSimon Schubert (long) hdr->sh_size);
15655796c8dcSSimon Schubert fprintf (stderr,
15665796c8dcSSimon Schubert "sh_link = %ld\tsh_info = %ld\tsh_addralign = %ld\n",
15675796c8dcSSimon Schubert (long) hdr->sh_link,
15685796c8dcSSimon Schubert (long) hdr->sh_info,
15695796c8dcSSimon Schubert (long) hdr->sh_addralign);
15705796c8dcSSimon Schubert fprintf (stderr, "sh_entsize = %ld\n",
15715796c8dcSSimon Schubert (long) hdr->sh_entsize);
15725796c8dcSSimon Schubert fflush (stderr);
15735796c8dcSSimon Schubert }
15745796c8dcSSimon Schubert #endif
15755796c8dcSSimon Schubert
15765796c8dcSSimon Schubert #if DEBUG & 1
15775796c8dcSSimon Schubert static void
elf_debug_file(Elf_Internal_Ehdr * ehdrp)15785796c8dcSSimon Schubert elf_debug_file (Elf_Internal_Ehdr *ehdrp)
15795796c8dcSSimon Schubert {
15805796c8dcSSimon Schubert fprintf (stderr, "e_entry = 0x%.8lx\n", (long) ehdrp->e_entry);
15815796c8dcSSimon Schubert fprintf (stderr, "e_phoff = %ld\n", (long) ehdrp->e_phoff);
15825796c8dcSSimon Schubert fprintf (stderr, "e_phnum = %ld\n", (long) ehdrp->e_phnum);
15835796c8dcSSimon Schubert fprintf (stderr, "e_phentsize = %ld\n", (long) ehdrp->e_phentsize);
15845796c8dcSSimon Schubert fprintf (stderr, "e_shoff = %ld\n", (long) ehdrp->e_shoff);
15855796c8dcSSimon Schubert fprintf (stderr, "e_shnum = %ld\n", (long) ehdrp->e_shnum);
15865796c8dcSSimon Schubert fprintf (stderr, "e_shentsize = %ld\n", (long) ehdrp->e_shentsize);
15875796c8dcSSimon Schubert }
15885796c8dcSSimon Schubert #endif
15895796c8dcSSimon Schubert
15905796c8dcSSimon Schubert /* Create a new BFD as if by bfd_openr. Rather than opening a file,
15915796c8dcSSimon Schubert reconstruct an ELF file by reading the segments out of remote memory
15925796c8dcSSimon Schubert based on the ELF file header at EHDR_VMA and the ELF program headers it
15935796c8dcSSimon Schubert points to. If not null, *LOADBASEP is filled in with the difference
15945796c8dcSSimon Schubert between the VMAs from which the segments were read, and the VMAs the
15955796c8dcSSimon Schubert file headers (and hence BFD's idea of each section's VMA) put them at.
15965796c8dcSSimon Schubert
15975796c8dcSSimon Schubert The function TARGET_READ_MEMORY is called to copy LEN bytes from the
15985796c8dcSSimon Schubert remote memory at target address VMA into the local buffer at MYADDR; it
15995796c8dcSSimon Schubert should return zero on success or an `errno' code on failure. TEMPL must
16005796c8dcSSimon Schubert be a BFD for a target with the word size and byte order found in the
16015796c8dcSSimon Schubert remote memory. */
16025796c8dcSSimon Schubert
16035796c8dcSSimon Schubert bfd *
NAME(_bfd_elf,bfd_from_remote_memory)16045796c8dcSSimon Schubert NAME(_bfd_elf,bfd_from_remote_memory)
16055796c8dcSSimon Schubert (bfd *templ,
16065796c8dcSSimon Schubert bfd_vma ehdr_vma,
16075796c8dcSSimon Schubert bfd_vma *loadbasep,
1608*ef5ccd6cSJohn Marino int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type))
16095796c8dcSSimon Schubert {
16105796c8dcSSimon Schubert Elf_External_Ehdr x_ehdr; /* Elf file header, external form */
16115796c8dcSSimon Schubert Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */
16125796c8dcSSimon Schubert Elf_External_Phdr *x_phdrs;
16135796c8dcSSimon Schubert Elf_Internal_Phdr *i_phdrs, *last_phdr;
16145796c8dcSSimon Schubert bfd *nbfd;
16155796c8dcSSimon Schubert struct bfd_in_memory *bim;
16165796c8dcSSimon Schubert int contents_size;
16175796c8dcSSimon Schubert bfd_byte *contents;
16185796c8dcSSimon Schubert int err;
16195796c8dcSSimon Schubert unsigned int i;
16205796c8dcSSimon Schubert bfd_vma loadbase;
16215796c8dcSSimon Schubert bfd_boolean loadbase_set;
16225796c8dcSSimon Schubert
16235796c8dcSSimon Schubert /* Read in the ELF header in external format. */
16245796c8dcSSimon Schubert err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr, sizeof x_ehdr);
16255796c8dcSSimon Schubert if (err)
16265796c8dcSSimon Schubert {
16275796c8dcSSimon Schubert bfd_set_error (bfd_error_system_call);
16285796c8dcSSimon Schubert errno = err;
16295796c8dcSSimon Schubert return NULL;
16305796c8dcSSimon Schubert }
16315796c8dcSSimon Schubert
16325796c8dcSSimon Schubert /* Now check to see if we have a valid ELF file, and one that BFD can
16335796c8dcSSimon Schubert make use of. The magic number must match, the address size ('class')
16345796c8dcSSimon Schubert and byte-swapping must match our XVEC entry. */
16355796c8dcSSimon Schubert
16365796c8dcSSimon Schubert if (! elf_file_p (&x_ehdr)
16375796c8dcSSimon Schubert || x_ehdr.e_ident[EI_VERSION] != EV_CURRENT
16385796c8dcSSimon Schubert || x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
16395796c8dcSSimon Schubert {
16405796c8dcSSimon Schubert bfd_set_error (bfd_error_wrong_format);
16415796c8dcSSimon Schubert return NULL;
16425796c8dcSSimon Schubert }
16435796c8dcSSimon Schubert
16445796c8dcSSimon Schubert /* Check that file's byte order matches xvec's */
16455796c8dcSSimon Schubert switch (x_ehdr.e_ident[EI_DATA])
16465796c8dcSSimon Schubert {
16475796c8dcSSimon Schubert case ELFDATA2MSB: /* Big-endian */
16485796c8dcSSimon Schubert if (! bfd_header_big_endian (templ))
16495796c8dcSSimon Schubert {
16505796c8dcSSimon Schubert bfd_set_error (bfd_error_wrong_format);
16515796c8dcSSimon Schubert return NULL;
16525796c8dcSSimon Schubert }
16535796c8dcSSimon Schubert break;
16545796c8dcSSimon Schubert case ELFDATA2LSB: /* Little-endian */
16555796c8dcSSimon Schubert if (! bfd_header_little_endian (templ))
16565796c8dcSSimon Schubert {
16575796c8dcSSimon Schubert bfd_set_error (bfd_error_wrong_format);
16585796c8dcSSimon Schubert return NULL;
16595796c8dcSSimon Schubert }
16605796c8dcSSimon Schubert break;
16615796c8dcSSimon Schubert case ELFDATANONE: /* No data encoding specified */
16625796c8dcSSimon Schubert default: /* Unknown data encoding specified */
16635796c8dcSSimon Schubert bfd_set_error (bfd_error_wrong_format);
16645796c8dcSSimon Schubert return NULL;
16655796c8dcSSimon Schubert }
16665796c8dcSSimon Schubert
16675796c8dcSSimon Schubert elf_swap_ehdr_in (templ, &x_ehdr, &i_ehdr);
16685796c8dcSSimon Schubert
16695796c8dcSSimon Schubert /* The file header tells where to find the program headers.
16705796c8dcSSimon Schubert These are what we use to actually choose what to read. */
16715796c8dcSSimon Schubert
16725796c8dcSSimon Schubert if (i_ehdr.e_phentsize != sizeof (Elf_External_Phdr) || i_ehdr.e_phnum == 0)
16735796c8dcSSimon Schubert {
16745796c8dcSSimon Schubert bfd_set_error (bfd_error_wrong_format);
16755796c8dcSSimon Schubert return NULL;
16765796c8dcSSimon Schubert }
16775796c8dcSSimon Schubert
16785796c8dcSSimon Schubert x_phdrs = (Elf_External_Phdr *)
16795796c8dcSSimon Schubert bfd_malloc (i_ehdr.e_phnum * (sizeof *x_phdrs + sizeof *i_phdrs));
16805796c8dcSSimon Schubert if (x_phdrs == NULL)
16815796c8dcSSimon Schubert {
16825796c8dcSSimon Schubert bfd_set_error (bfd_error_no_memory);
16835796c8dcSSimon Schubert return NULL;
16845796c8dcSSimon Schubert }
16855796c8dcSSimon Schubert err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs,
16865796c8dcSSimon Schubert i_ehdr.e_phnum * sizeof x_phdrs[0]);
16875796c8dcSSimon Schubert if (err)
16885796c8dcSSimon Schubert {
16895796c8dcSSimon Schubert free (x_phdrs);
16905796c8dcSSimon Schubert bfd_set_error (bfd_error_system_call);
16915796c8dcSSimon Schubert errno = err;
16925796c8dcSSimon Schubert return NULL;
16935796c8dcSSimon Schubert }
16945796c8dcSSimon Schubert i_phdrs = (Elf_Internal_Phdr *) &x_phdrs[i_ehdr.e_phnum];
16955796c8dcSSimon Schubert
16965796c8dcSSimon Schubert contents_size = 0;
16975796c8dcSSimon Schubert last_phdr = NULL;
16985796c8dcSSimon Schubert loadbase = ehdr_vma;
16995796c8dcSSimon Schubert loadbase_set = FALSE;
17005796c8dcSSimon Schubert for (i = 0; i < i_ehdr.e_phnum; ++i)
17015796c8dcSSimon Schubert {
17025796c8dcSSimon Schubert elf_swap_phdr_in (templ, &x_phdrs[i], &i_phdrs[i]);
17035796c8dcSSimon Schubert if (i_phdrs[i].p_type == PT_LOAD)
17045796c8dcSSimon Schubert {
17055796c8dcSSimon Schubert bfd_vma segment_end;
17065796c8dcSSimon Schubert segment_end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz
17075796c8dcSSimon Schubert + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align;
17085796c8dcSSimon Schubert if (segment_end > (bfd_vma) contents_size)
17095796c8dcSSimon Schubert contents_size = segment_end;
17105796c8dcSSimon Schubert
17115796c8dcSSimon Schubert /* LOADADDR is the `Base address' from the gELF specification:
17125796c8dcSSimon Schubert `lowest p_vaddr value for a PT_LOAD segment' is P_VADDR from the
17135796c8dcSSimon Schubert first PT_LOAD as PT_LOADs are ordered by P_VADDR. */
17145796c8dcSSimon Schubert if (!loadbase_set && (i_phdrs[i].p_offset & -i_phdrs[i].p_align) == 0)
17155796c8dcSSimon Schubert {
17165796c8dcSSimon Schubert loadbase = ehdr_vma - (i_phdrs[i].p_vaddr & -i_phdrs[i].p_align);
17175796c8dcSSimon Schubert loadbase_set = TRUE;
17185796c8dcSSimon Schubert }
17195796c8dcSSimon Schubert
17205796c8dcSSimon Schubert last_phdr = &i_phdrs[i];
17215796c8dcSSimon Schubert }
17225796c8dcSSimon Schubert }
17235796c8dcSSimon Schubert if (last_phdr == NULL)
17245796c8dcSSimon Schubert {
17255796c8dcSSimon Schubert /* There were no PT_LOAD segments, so we don't have anything to read. */
17265796c8dcSSimon Schubert free (x_phdrs);
17275796c8dcSSimon Schubert bfd_set_error (bfd_error_wrong_format);
17285796c8dcSSimon Schubert return NULL;
17295796c8dcSSimon Schubert }
17305796c8dcSSimon Schubert
17315796c8dcSSimon Schubert /* Trim the last segment so we don't bother with zeros in the last page
17325796c8dcSSimon Schubert that are off the end of the file. However, if the extra bit in that
17335796c8dcSSimon Schubert page includes the section headers, keep them. */
17345796c8dcSSimon Schubert if ((bfd_vma) contents_size > last_phdr->p_offset + last_phdr->p_filesz
17355796c8dcSSimon Schubert && (bfd_vma) contents_size >= (i_ehdr.e_shoff
17365796c8dcSSimon Schubert + i_ehdr.e_shnum * i_ehdr.e_shentsize))
17375796c8dcSSimon Schubert {
17385796c8dcSSimon Schubert contents_size = last_phdr->p_offset + last_phdr->p_filesz;
17395796c8dcSSimon Schubert if ((bfd_vma) contents_size < (i_ehdr.e_shoff
17405796c8dcSSimon Schubert + i_ehdr.e_shnum * i_ehdr.e_shentsize))
17415796c8dcSSimon Schubert contents_size = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize;
17425796c8dcSSimon Schubert }
17435796c8dcSSimon Schubert else
17445796c8dcSSimon Schubert contents_size = last_phdr->p_offset + last_phdr->p_filesz;
17455796c8dcSSimon Schubert
17465796c8dcSSimon Schubert /* Now we know the size of the whole image we want read in. */
17475796c8dcSSimon Schubert contents = (bfd_byte *) bfd_zmalloc (contents_size);
17485796c8dcSSimon Schubert if (contents == NULL)
17495796c8dcSSimon Schubert {
17505796c8dcSSimon Schubert free (x_phdrs);
17515796c8dcSSimon Schubert bfd_set_error (bfd_error_no_memory);
17525796c8dcSSimon Schubert return NULL;
17535796c8dcSSimon Schubert }
17545796c8dcSSimon Schubert
17555796c8dcSSimon Schubert for (i = 0; i < i_ehdr.e_phnum; ++i)
17565796c8dcSSimon Schubert if (i_phdrs[i].p_type == PT_LOAD)
17575796c8dcSSimon Schubert {
17585796c8dcSSimon Schubert bfd_vma start = i_phdrs[i].p_offset & -i_phdrs[i].p_align;
17595796c8dcSSimon Schubert bfd_vma end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz
17605796c8dcSSimon Schubert + i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align;
17615796c8dcSSimon Schubert if (end > (bfd_vma) contents_size)
17625796c8dcSSimon Schubert end = contents_size;
17635796c8dcSSimon Schubert err = target_read_memory ((loadbase + i_phdrs[i].p_vaddr)
17645796c8dcSSimon Schubert & -i_phdrs[i].p_align,
17655796c8dcSSimon Schubert contents + start, end - start);
17665796c8dcSSimon Schubert if (err)
17675796c8dcSSimon Schubert {
17685796c8dcSSimon Schubert free (x_phdrs);
17695796c8dcSSimon Schubert free (contents);
17705796c8dcSSimon Schubert bfd_set_error (bfd_error_system_call);
17715796c8dcSSimon Schubert errno = err;
17725796c8dcSSimon Schubert return NULL;
17735796c8dcSSimon Schubert }
17745796c8dcSSimon Schubert }
17755796c8dcSSimon Schubert free (x_phdrs);
17765796c8dcSSimon Schubert
17775796c8dcSSimon Schubert /* If the segments visible in memory didn't include the section headers,
17785796c8dcSSimon Schubert then clear them from the file header. */
17795796c8dcSSimon Schubert if ((bfd_vma) contents_size < (i_ehdr.e_shoff
17805796c8dcSSimon Schubert + i_ehdr.e_shnum * i_ehdr.e_shentsize))
17815796c8dcSSimon Schubert {
17825796c8dcSSimon Schubert memset (&x_ehdr.e_shoff, 0, sizeof x_ehdr.e_shoff);
17835796c8dcSSimon Schubert memset (&x_ehdr.e_shnum, 0, sizeof x_ehdr.e_shnum);
17845796c8dcSSimon Schubert memset (&x_ehdr.e_shstrndx, 0, sizeof x_ehdr.e_shstrndx);
17855796c8dcSSimon Schubert }
17865796c8dcSSimon Schubert
17875796c8dcSSimon Schubert /* This will normally have been in the first PT_LOAD segment. But it
17885796c8dcSSimon Schubert conceivably could be missing, and we might have just changed it. */
17895796c8dcSSimon Schubert memcpy (contents, &x_ehdr, sizeof x_ehdr);
17905796c8dcSSimon Schubert
17915796c8dcSSimon Schubert /* Now we have a memory image of the ELF file contents. Make a BFD. */
17925796c8dcSSimon Schubert bim = (struct bfd_in_memory *) bfd_malloc (sizeof (struct bfd_in_memory));
17935796c8dcSSimon Schubert if (bim == NULL)
17945796c8dcSSimon Schubert {
17955796c8dcSSimon Schubert free (contents);
17965796c8dcSSimon Schubert bfd_set_error (bfd_error_no_memory);
17975796c8dcSSimon Schubert return NULL;
17985796c8dcSSimon Schubert }
17995796c8dcSSimon Schubert nbfd = _bfd_new_bfd ();
18005796c8dcSSimon Schubert if (nbfd == NULL)
18015796c8dcSSimon Schubert {
18025796c8dcSSimon Schubert free (bim);
18035796c8dcSSimon Schubert free (contents);
18045796c8dcSSimon Schubert bfd_set_error (bfd_error_no_memory);
18055796c8dcSSimon Schubert return NULL;
18065796c8dcSSimon Schubert }
18075796c8dcSSimon Schubert nbfd->filename = "<in-memory>";
18085796c8dcSSimon Schubert nbfd->xvec = templ->xvec;
18095796c8dcSSimon Schubert bim->size = contents_size;
18105796c8dcSSimon Schubert bim->buffer = contents;
18115796c8dcSSimon Schubert nbfd->iostream = bim;
18125796c8dcSSimon Schubert nbfd->flags = BFD_IN_MEMORY;
1813cf7f2e2dSJohn Marino nbfd->iovec = &_bfd_memory_iovec;
1814cf7f2e2dSJohn Marino nbfd->origin = 0;
18155796c8dcSSimon Schubert nbfd->direction = read_direction;
18165796c8dcSSimon Schubert nbfd->mtime = time (NULL);
18175796c8dcSSimon Schubert nbfd->mtime_set = TRUE;
18185796c8dcSSimon Schubert
18195796c8dcSSimon Schubert if (loadbasep)
18205796c8dcSSimon Schubert *loadbasep = loadbase;
18215796c8dcSSimon Schubert return nbfd;
18225796c8dcSSimon Schubert }
1823c50c785cSJohn Marino
1824c50c785cSJohn Marino /* Function for ELF_R_INFO. */
1825c50c785cSJohn Marino
1826c50c785cSJohn Marino bfd_vma
NAME(elf,r_info)1827c50c785cSJohn Marino NAME(elf,r_info) (bfd_vma sym, bfd_vma type)
1828c50c785cSJohn Marino {
1829c50c785cSJohn Marino return ELF_R_INFO (sym, type);
1830c50c785cSJohn Marino }
1831c50c785cSJohn Marino
1832c50c785cSJohn Marino /* Function for ELF_R_SYM. */
1833c50c785cSJohn Marino
1834c50c785cSJohn Marino bfd_vma
NAME(elf,r_sym)1835c50c785cSJohn Marino NAME(elf,r_sym) (bfd_vma r_info)
1836c50c785cSJohn Marino {
1837c50c785cSJohn Marino return ELF_R_SYM (r_info);
1838c50c785cSJohn Marino }
18395796c8dcSSimon Schubert
18405796c8dcSSimon Schubert #include "elfcore.h"
18415796c8dcSSimon Schubert
18425796c8dcSSimon Schubert /* Size-dependent data and functions. */
18435796c8dcSSimon Schubert const struct elf_size_info NAME(_bfd_elf,size_info) = {
18445796c8dcSSimon Schubert sizeof (Elf_External_Ehdr),
18455796c8dcSSimon Schubert sizeof (Elf_External_Phdr),
18465796c8dcSSimon Schubert sizeof (Elf_External_Shdr),
18475796c8dcSSimon Schubert sizeof (Elf_External_Rel),
18485796c8dcSSimon Schubert sizeof (Elf_External_Rela),
18495796c8dcSSimon Schubert sizeof (Elf_External_Sym),
18505796c8dcSSimon Schubert sizeof (Elf_External_Dyn),
18515796c8dcSSimon Schubert sizeof (Elf_External_Note),
18525796c8dcSSimon Schubert 4,
18535796c8dcSSimon Schubert 1,
18545796c8dcSSimon Schubert ARCH_SIZE, LOG_FILE_ALIGN,
18555796c8dcSSimon Schubert ELFCLASS, EV_CURRENT,
18565796c8dcSSimon Schubert elf_write_out_phdrs,
18575796c8dcSSimon Schubert elf_write_shdrs_and_ehdr,
18585796c8dcSSimon Schubert elf_checksum_contents,
18595796c8dcSSimon Schubert elf_write_relocs,
18605796c8dcSSimon Schubert elf_swap_symbol_in,
18615796c8dcSSimon Schubert elf_swap_symbol_out,
18625796c8dcSSimon Schubert elf_slurp_reloc_table,
18635796c8dcSSimon Schubert elf_slurp_symbol_table,
18645796c8dcSSimon Schubert elf_swap_dyn_in,
18655796c8dcSSimon Schubert elf_swap_dyn_out,
18665796c8dcSSimon Schubert elf_swap_reloc_in,
18675796c8dcSSimon Schubert elf_swap_reloc_out,
18685796c8dcSSimon Schubert elf_swap_reloca_in,
18695796c8dcSSimon Schubert elf_swap_reloca_out
18705796c8dcSSimon Schubert };
1871