xref: /dragonfly/contrib/gdb-7/bfd/elfcode.h (revision ef5ccd6c)
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